Compare commits
1567 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a3d9fe76d6 | |||
| 0f4f154637 | |||
| 7d112a208f | |||
| c867d39d8d | |||
| 83b6c939f7 | |||
| e1e4eb5d6f | |||
| a14c08f122 | |||
| 5fd50dcf45 | |||
| b2ac4ee245 | |||
| 0ad7c0546b | |||
| 748381fef3 | |||
| 7eb9e42210 | |||
| 36a4b67ef4 | |||
| 94b35e3d5f | |||
| c5aa82b76a | |||
| c2920e195f | |||
| 92a78a419e | |||
| 4f27c2b852 | |||
| ece5779b41 | |||
| 167aaa8491 | |||
| de622b055b | |||
| 7e88b930ec | |||
| c9adc2b852 | |||
| 91d3aba611 | |||
| 48bc11dcb5 | |||
| 9ee0b32cac | |||
| 4b6b74604b | |||
| 7ad3fc4751 | |||
| e604450cfb | |||
| 9cfbc83896 | |||
| 98b2f4ec35 | |||
| 47e30f2daf | |||
| 6c21da6959 | |||
| c5fe71d390 | |||
| d14ffcb736 | |||
| e694aca70b | |||
| 3c58cb1b9c | |||
| dc452cdadf | |||
| e855365cbb | |||
| cffa288227 | |||
| 89ddced342 | |||
| 7457328b59 | |||
| 44ff413810 | |||
| d174c2c2d8 | |||
| 480f4c9a8c | |||
| 7474cc5d8a | |||
| bda5c4f5dd | |||
| 4f5034c167 | |||
| 9470db1f4d | |||
| dfeb910ac9 | |||
| a5745795be | |||
| 98f2b5dd08 | |||
| f642c7570e | |||
| dca9ea24d7 | |||
| 43fd7b6000 | |||
| 1553ec3bd4 | |||
| 37d54811e0 | |||
| 0f2af6eb37 | |||
| 91546228fa | |||
| 5488ff06e0 | |||
| ef7f050bc5 | |||
| e5c94d9698 | |||
| 4d3e0ac5d9 | |||
| 0a2f0372be | |||
| e378fc3cfb | |||
| 75a1d74d9c | |||
| 1404685296 | |||
| 0ebed9b46f | |||
| af69352361 | |||
| 840e3b861f | |||
| a7cfe7fe04 | |||
| a324cf0fcd | |||
| 0919f4c85b | |||
| fd4cc6a1e8 | |||
| d6ae3d4f16 | |||
| 9c1819467a | |||
| 08410ef209 | |||
| 6cd3242454 | |||
| 986c1a7bc8 | |||
| a7703ec996 | |||
| 52d2eb3f59 | |||
| b19fed41ef | |||
| 82a4b2c769 | |||
| 1d52cde3b3 | |||
| aca4cc0ace | |||
| 8f9a78feb9 | |||
| 45484a43f1 | |||
| 63665e6e9c | |||
| 151665c880 | |||
| 15e475873e | |||
| f846af75e8 | |||
| 5c7ab3793f | |||
| a501f0cdef | |||
| 4b4c2606cd | |||
| 901e7581fe | |||
| 55fb233ce4 | |||
| dd77ee4a8e | |||
| a7ae6d7b47 | |||
| 34dfac8bb2 | |||
| 599f783c04 | |||
| c7f82d3d46 | |||
| 8b346c6b44 | |||
| e386764151 | |||
| c0acecc6e9 | |||
| a1724134ec | |||
| 530b830586 | |||
| 363a72c3ad | |||
| c1a6daf9d2 | |||
| 8a7a73678c | |||
| 6cc8c7cb9d | |||
| e2d1771a7a | |||
| 23f7dd6ee3 | |||
| 9884ace309 | |||
| 70284ac440 | |||
| f24caad997 | |||
| 32729350f6 | |||
| 4929d190a5 | |||
| 0e211dc91b | |||
| 8663ab2d28 | |||
| ba0ecaf70f | |||
| acb4f5924e | |||
| 46553a80ad | |||
| 417334d140 | |||
| e254657813 | |||
| b087df8d97 | |||
| 47eb74d5ba | |||
| f0ac047978 | |||
| e57e246991 | |||
| 6934cdd122 | |||
| aa7fb74312 | |||
| 0e2a77ced7 | |||
| 2d135d708e | |||
| 26d34f896b | |||
| 87c58cae83 | |||
| 8429067ae5 | |||
| 4d6957a6fa | |||
| 70c53248ae | |||
| 6e645cb054 | |||
| 28fecc6834 | |||
| 64c2faf538 | |||
| c514a4d503 | |||
| 391d04b45c | |||
| f974c00a63 | |||
| 9f0107c002 | |||
| 6ce82e915e | |||
| 864797fc99 | |||
| c741434e3c | |||
| 60fcb1a862 | |||
| 18dc6a3ff5 | |||
| da52dd006b | |||
| ed1655ed8f | |||
| 516c4e32be | |||
| 1e222d806e | |||
| bfb35b198d | |||
| 3a5f36155f | |||
| 82092fab76 | |||
| a432cb886d | |||
| 5fff8c6ba2 | |||
| e1de4f5c5f | |||
| b6145d6f1e | |||
| 3804a87cef | |||
| a7a6c664c8 | |||
| f075515607 | |||
| 84c15bbc69 | |||
| 54e70d490d | |||
| 67c3de1f5d | |||
| 7281b5b1d7 | |||
| 966eb01f1c | |||
| 5bdf072cdf | |||
| 59c3381962 | |||
| 1fa4216b18 | |||
| a98c953876 | |||
| bf995e5861 | |||
| 1b8470df38 | |||
| 98ded8ea30 | |||
| b72a50eb7e | |||
| 9c3f4fbb9d | |||
| 28c68308a9 | |||
| ea3b0c15ac | |||
| 38ce46adb0 | |||
| 0a9a0103dd | |||
| b7b370ff62 | |||
| 7b0c98ad2c | |||
| bfe25e70d6 | |||
| b2409df369 | |||
| e1d8549730 | |||
| 865cc081ce | |||
| 867d5a9eb5 | |||
| ac84b7604b | |||
| 8f860ad93e | |||
| f3b65700d7 | |||
| 8ec1856206 | |||
| 811d2162fc | |||
| 5e2cdca103 | |||
| 23fb5852ba | |||
| 75cbc0d29a | |||
| d08cd684c5 | |||
| 529b297ba6 | |||
| 32193eef49 | |||
| 1f97b90b2d | |||
| 0dd36260e9 | |||
| 3571d49987 | |||
| ad3489c491 | |||
| 2461fa2e25 | |||
| 60e49ba343 | |||
| a709381980 | |||
| c2805c8c1c | |||
| 0346cbe911 | |||
| 74a4d4455b | |||
| 3659e1c91f | |||
| 09da5c6968 | |||
| 2575efd28d | |||
| 78c1c8d2b1 | |||
| d5147f3dbb | |||
| 593580fbc1 | |||
| 67ca1cb638 | |||
| bcf5b64545 | |||
| e37ad663b3 | |||
| 4ce7582a46 | |||
| 1c371bb7bf | |||
| 17fdeb0734 | |||
| 5c6f0c32b3 | |||
| e630280673 | |||
| 7c87961adf | |||
| 0df5ceb7d2 | |||
| 54342f2592 | |||
| fbad558c37 | |||
| b27dfb290c | |||
| 063c930349 | |||
| c1f1e489a7 | |||
| 62960ed8de | |||
| 03305e04a7 | |||
| 4b294b1125 | |||
| 7122a21591 | |||
| 9682e571a2 | |||
| 2cefbfb8aa | |||
| 084062488c | |||
| 4dbe2b5297 | |||
| 0391e5bc3d | |||
| bcbd96c608 | |||
| 6a6633e151 | |||
| 5c4546a54c | |||
| 255e328340 | |||
| aaf9b085d7 | |||
| c7b14c9fab | |||
| 0436ba78e2 | |||
| 1085a1c221 | |||
| 494b33bd7a | |||
| 925e3a67da | |||
| 78026f7fa5 | |||
| 9d77cac4bb | |||
| 6747280964 | |||
| d7dbd79f7c | |||
| aec692c402 | |||
| 113bbead4a | |||
| 1361c196da | |||
| 987995ad68 | |||
| d24db7c053 | |||
| 25a9d52d86 | |||
| 946c632920 | |||
| 94bcbb80fd | |||
| ba58965770 | |||
| e50ddbf348 | |||
| e95f21fa9c | |||
| 7026b765bd | |||
| 53eedd2701 | |||
| 9886c58681 | |||
| 953f6da7d7 | |||
| da1efe880d | |||
| bd0b6dd4d2 | |||
| 1c049fe1fb | |||
| 10b1b87d55 | |||
| 3ec6a3b3f2 | |||
| 8da919d4cd | |||
| 5cd59b795b | |||
| e4dc30d1fb | |||
| 2013cee298 | |||
| 1f89a6304b | |||
| 580e0f9df7 | |||
| 2221c4548e | |||
| e06c226e84 | |||
| 11a4f0ef32 | |||
| ef15f299d2 | |||
| 1d333b9322 | |||
| 5302ed8653 | |||
| 2cf26a10c4 | |||
| deda1e4251 | |||
| c042bf2d15 | |||
| 8ced6aa205 | |||
| 3ca514c85b | |||
| 27b8e7d5ec | |||
| a2d77a3917 | |||
| c0549fe422 | |||
| 0dc8d6fd68 | |||
| cd97647818 | |||
| fcb5811f37 | |||
| a239ba2211 | |||
| e8dc96bcda | |||
| 096ad97a73 | |||
| a5a5517555 | |||
| d9b88a5d8d | |||
| 8493ea22eb | |||
| aebb87aa20 | |||
| 14e97cb24f | |||
| 26cc15b4a2 | |||
| 50ce606e12 | |||
| b052320f98 | |||
| ecb3cebc9f | |||
| 4a32dfc71b | |||
| c913929ff9 | |||
| d7d5b29b07 | |||
| 111a7f72f8 | |||
| 149abdef9b | |||
| 980848f35a | |||
| d1e0c86a71 | |||
| d3872ca8a3 | |||
| 003dec269a | |||
| e88092cde7 | |||
| 98422bd355 | |||
| af83b89812 | |||
| cffb1b8713 | |||
| 0b4895addf | |||
| 08646ea12a | |||
| 40beb7ceeb | |||
| e7963aa324 | |||
| d5894b9fb7 | |||
| 75c47a1113 | |||
| 97923b19bf | |||
| 879c89a285 | |||
| 718727462b | |||
| 63f2fd864a | |||
| 556dda5790 | |||
| aeaa8549e3 | |||
| 1a8a757912 | |||
| c69bb8acc9 | |||
| 4989d67b92 | |||
| b272d342b0 | |||
| 251b2853e0 | |||
| d381c9505f | |||
| eeb3b8f939 | |||
| ee40f32b0c | |||
| 02a69ea6d9 | |||
| d47bb5ecd4 | |||
| d2d6e2f554 | |||
| f48b4a6c62 | |||
| 07f7b7df1b | |||
| 26486f9d63 | |||
| 428aa970b9 | |||
| 2a8c532786 | |||
| 4381829d16 | |||
| 176d75768f | |||
| e28e363bd0 | |||
| 114ce1ea3a | |||
| 78215552bf | |||
| be4fe6ab77 | |||
| ab924f6b48 | |||
| e4bf2b4c9b | |||
| c49b1a46f8 | |||
| 6a56726734 | |||
| 8f6783792f | |||
| b5ab1d6b33 | |||
| 25fe1d03a7 | |||
| 90546ad4a7 | |||
| 939bbc3f2c | |||
| 02ee327595 | |||
| d8081277ee | |||
| 164a112e0c | |||
| 697bde7b53 | |||
| 2fd5244f85 | |||
| 354d925f94 | |||
| 88c74f020c | |||
| 9b7021b1cd | |||
| 30dbb23330 | |||
| b1696ed1cd | |||
| 61f1c99791 | |||
| bb9a559b80 | |||
| 5e20ea4975 | |||
| c5d7e30bed | |||
| de5f3a31ed | |||
| 7913c4135f | |||
| d49345de9c | |||
| 1dbfa71bde | |||
| d46b84f0d6 | |||
| 9d456992cf | |||
| 5dd62ad2aa | |||
| a293eeb398 | |||
| a6b6b5eb70 | |||
| 971af1df5f | |||
| 21641da0bf | |||
| a8d9c145e6 | |||
| bfafcb76ba | |||
| 52f74f1204 | |||
| 00c212ecb2 | |||
| e77d302a49 | |||
| 5183f3729c | |||
| e93102f105 | |||
| a4652689ec | |||
| ede1005087 | |||
| e97c7ed32e | |||
| 9230a2ab73 | |||
| 01ee66ec4f | |||
| 4c12cbd3cc | |||
| d8eeeaaef6 | |||
| 994dae2a7d | |||
| 51da6e928d | |||
| a328ad030e | |||
| ed7605eccd | |||
| de43880a1c | |||
| 32b1a5b22d | |||
| 795992fb42 | |||
| 339eab33c8 | |||
| 489f3aa19d | |||
| 888e284f84 | |||
| d151114f08 | |||
| 4f6a3c23ad | |||
| 4ed437fd4e | |||
| fa0b21ba81 | |||
| a96f1d0b49 | |||
| ac0aebd751 | |||
| 781cbb4668 | |||
| 56ca1911a1 | |||
| c20aec23a2 | |||
| a9cff01579 | |||
| 6af56a61b8 | |||
| 252db191a6 | |||
| 5e2776f264 | |||
| 7ec9fb2c44 | |||
| 34facb6b3b | |||
| 5bb2a1368e | |||
| 85a7bbca66 | |||
| 2b7f27bf8f | |||
| dd57945e7d | |||
| fa02b4fd56 | |||
| c8715eead5 | |||
| 37aae8c10e | |||
| a97ed02e15 | |||
| 38ebb2d06a | |||
| c765bfc946 | |||
| b00ac75f33 | |||
| 36730168c0 | |||
| 4339ece6f6 | |||
| 041c997e59 | |||
| 098ebb38dc | |||
| b99c38a070 | |||
| 07b42d8e74 | |||
| 062d168c97 | |||
| c9be5fb125 | |||
| 06c6716ee1 | |||
| e856d8fddf | |||
| 20339f70c1 | |||
| c2e6cf1eb0 | |||
| 8dfdca97cd | |||
| 6e8cdc24a3 | |||
| 461f1e39fa | |||
| 4892dbce5e | |||
| 9da32a13de | |||
| 9c6908da77 | |||
| ac081e6c86 | |||
| cc9744156c | |||
| 72a874c7f4 | |||
| 2809324b35 | |||
| 58e6c45c73 | |||
| 43aaf192a2 | |||
| c0574bc738 | |||
| 27e5d639ef | |||
| aa9fdd4fc9 | |||
| 7af6d9b2ce | |||
| 0e06d28335 | |||
| e3b86e4d41 | |||
| 5b1bfe7379 | |||
| 76d07b967e | |||
| 4b1932fe52 | |||
| a56de91b1e | |||
| 6b4fb616bc | |||
| d24670e14e | |||
| 13b3ae35ed | |||
| 6860e1f085 | |||
| 74fa1c6628 | |||
| 85f847a4f3 | |||
| 39df72d163 | |||
| 5ca8786802 | |||
| ca145967dc | |||
| 06a3ce7486 | |||
| 9f85b6154d | |||
| 732763689a | |||
| 0ea75f25f1 | |||
| eab27ce0bb | |||
| 29fd381989 | |||
| 06a845697a | |||
| b12587626d | |||
| b49988032e | |||
| a9b4152553 | |||
| 63720045f1 | |||
| aa7529192e | |||
| a162a15a27 | |||
| 457a73efae | |||
| 91c3dd982b | |||
| c171f93c93 | |||
| 0cf9ddb1cd | |||
| 2322537350 | |||
| 6ce50109da | |||
| abe7fdf34d | |||
| ecf2f5ed8c | |||
| 98b4934dd5 | |||
| 0bc7c544ad | |||
| 1f7ad9d418 | |||
| 4b9d3b3dbc | |||
| 571e332ed5 | |||
| d78d22b188 | |||
| d37638240a | |||
| ae7fd3f87b | |||
| e82e63b288 | |||
| 0149d4e27b | |||
| 9fc9c71b6f | |||
| b264f690d1 | |||
| c07e19c898 | |||
| b8e50737d2 | |||
| 082d0aa02f | |||
| ca26d0e450 | |||
| 8cbe021ffc | |||
| 7b39d8025b | |||
| 47bd35b151 | |||
| d7add54a3c | |||
| d3c937569b | |||
| 94ca613201 | |||
| 30f2f635be | |||
| 57f4d31c21 | |||
| 90e4fd7ff5 | |||
| 17835832f2 | |||
| 949817f597 | |||
| 23065f2c4b | |||
| b623b06cf0 | |||
| 55c86d8ec7 | |||
| e955617aa1 | |||
| 6304610713 | |||
| 47d20928e0 | |||
| c9a4d02e0d | |||
| 6513dfb42a | |||
| 3f0412453f | |||
| dcba319071 | |||
| d19851fc0c | |||
| d6eb06cb72 | |||
| 473080d7ee | |||
| c98a6adb09 | |||
| 2cd56d5041 | |||
| 982098672e | |||
| 445ecea3e6 | |||
| db977dfba4 | |||
| a3c12ab9f5 | |||
| 0f7e152650 | |||
| b55c7ba9a1 | |||
| 8256c9f7ad | |||
| 59727d7b0b | |||
| 2dd2210a73 | |||
| 25aafdbebc | |||
| cd5717169c | |||
| a38ad5a11e | |||
| 66d9b56976 | |||
| ac40bd1e17 | |||
| 16d2a9bf99 | |||
| b7e6838d26 | |||
| 21d23b5baa | |||
| 69a2941d57 | |||
| 3cc2abf8b9 | |||
| 6f4173650a | |||
| 0fcb8bdc0a | |||
| c0937cf412 | |||
| d9ab3aab0f | |||
| c8652de78b | |||
| 86dc4e2bd5 | |||
| 1b9c56a9b9 | |||
| 08ab504fac | |||
| 21c0842fae | |||
| 8d10feaa68 | |||
| df2171f253 | |||
| f5fcd94faf | |||
| 15c5dbef00 | |||
| 79df56c096 | |||
| d3fffd9530 | |||
| 527c9c8e6e | |||
| d285be45cb | |||
| 0dda9c73f6 | |||
| d07bf270e7 | |||
| eb24dd5d9e | |||
| ce693c7cd5 | |||
| 3198890269 | |||
| eacc93de43 | |||
| 9795740257 | |||
| 4548f5d8aa | |||
| 8dfd2fb519 | |||
| 83a40f83e1 | |||
| 5b2fcb3c6c | |||
| bcd9adb66d | |||
| 5e2dc114ab | |||
| 1ced4531be | |||
| 05fe39c0ae | |||
| 3769b2b3ea | |||
| f4d5480f6f | |||
| ddf3c0810b | |||
| 6afd6d0aa0 | |||
| 59fe92eb04 | |||
| 0550f32434 | |||
| b702cad549 | |||
| aa5c4d3c5e | |||
| 6a99445d97 | |||
| c9880ef47d | |||
| c16452dfcb | |||
| af802c02fc | |||
| 8028aafeff | |||
| b7469062a1 | |||
| 33b707aa68 | |||
| cd3a1bebff | |||
| 794dd5a797 | |||
| a1465432e8 | |||
| e1f8af0909 | |||
| 88918be329 | |||
| a3fc1dbff0 | |||
| 626c9825cc | |||
| c10a84fc79 | |||
| f14e4fe197 | |||
| 6eb218db5e | |||
| 0e77e053b0 | |||
| b9a4128a3d | |||
| 16f480e1f3 | |||
| 7c42511133 | |||
| 1b252a84c2 | |||
| bf833cadff | |||
| b6f872882a | |||
| a18d6fb441 | |||
| 922e703e81 | |||
| d7f5817b8b | |||
| 92a8a4bfa6 | |||
| b480151fc3 | |||
| 37bdbc1bd5 | |||
| 8eb669139b | |||
| b485e8cacc | |||
| c4bab61c47 | |||
| 72be417ff1 | |||
| 9be483d7a6 | |||
| 910f2cee2c | |||
| 1e47ace527 | |||
| 912b06b145 | |||
| 87d878e287 | |||
| be886d6bce | |||
| 0683deb47e | |||
| 114bb22e27 | |||
| c327ebc3df | |||
| 92cbd1c69c | |||
| 7242515e48 | |||
| 401d1a0ac2 | |||
| 863e042a37 | |||
| 39e6c45ec6 | |||
| 0d364d18c7 | |||
| 61444ea390 | |||
| 106a935efb | |||
| d175d8a853 | |||
| ce6d19a77a | |||
| 0a29273924 | |||
| 5ede64de58 | |||
| 224c6ad798 | |||
| 57b3a0dbe7 | |||
| f381f708e0 | |||
| 63bf149546 | |||
| cb5e671259 | |||
| 3e38173c4e | |||
| efacb643fc | |||
| 1bd153ea0b | |||
| bac3dc5f4c | |||
| 959a853d77 | |||
| 90bbdd563b | |||
| e3c6d05a0a | |||
| 930b3d4538 | |||
| 74b78141b4 | |||
| aa1108cd5b | |||
| f24b1a9db3 | |||
| 71b191e740 | |||
| 8f6341b903 | |||
| 161586db7e | |||
| 052262bef9 | |||
| a5a7144707 | |||
| d945e0426d | |||
| 926970c4eb | |||
| cce36e0f28 | |||
| 48c6dc5be5 | |||
| c641830825 | |||
| eba16cc15d | |||
| bd88b8411e | |||
| fc121e8750 | |||
| d4142fe56a | |||
| f76a3e72bb | |||
| 2d400ae7eb | |||
| edf1632cab | |||
| a648f1ee67 | |||
| d004e6e86c | |||
| fa321d3e8d | |||
| e1e53d323f | |||
| ccb18ca302 | |||
| e170f36bc6 | |||
| 4bd9cc51ee | |||
| 43ffbda1a4 | |||
| 8240485fd1 | |||
| 7f053c0567 | |||
| d2922eb0b7 | |||
| fec10d453f | |||
| 162040545d | |||
| f14577f8bf | |||
| e5720bd1be | |||
| 6d4959bac8 | |||
| d668128a34 | |||
| f2af38da4c | |||
| 4776d18fd7 | |||
| cdd0be7b78 | |||
| cd505abb22 | |||
| 28439c010f | |||
| e85f43beb1 | |||
| a06cbc0840 | |||
| adef9728f8 | |||
| ff1b688b6e | |||
| 3e7574a927 | |||
| f852ea90ad | |||
| d8f6247c32 | |||
| 9dc28393a5 | |||
| c442c98ecf | |||
| 71e0109927 | |||
| 9c7dd5ed1c | |||
| 83620848f2 | |||
| d548a5b4f3 | |||
| b6e5307755 | |||
| 4c5dc5a145 | |||
| 69ed9172b8 | |||
| 68551ae176 | |||
| c97d9d35ba | |||
| e86cc97cdf | |||
| 9bff8608c1 | |||
| a10fe6994a | |||
| 67e6a37b59 | |||
| 3075a56735 | |||
| 7e4a862cc3 | |||
| ed2078ee3b | |||
| f99c23a622 | |||
| 41e7317764 | |||
| e0a78c2399 | |||
| 95ad39d2d4 | |||
| b831f827b1 | |||
| c5d8413d9c | |||
| 4648ea3424 | |||
| e05bd6f231 | |||
| caadee7901 | |||
| 18c524117d | |||
| ad30fb8b04 | |||
| a8077965a9 | |||
| 532ab85ebb | |||
| 546227eb37 | |||
| 7ec3b262d3 | |||
| c435000d24 | |||
| eaa60c281e | |||
| cd7cf63144 | |||
| 6a704aa079 | |||
| d6b5a1cec8 | |||
| 9a24ad31cc | |||
| 9331630b54 | |||
| 904e869d7f | |||
| 307fa4f5e6 | |||
| 131d16d3ea | |||
| dbc54c45dd | |||
| a96a84d509 | |||
| 3eb8863f67 | |||
| 8737ab077b | |||
| 50bb6a1d19 | |||
| 4181b75af7 | |||
| 620705c87a | |||
| 50b7b93529 | |||
| 6f18f6bd5c | |||
| 01d256eeee | |||
| a1405412a8 | |||
| 58589b3a15 | |||
| 2983266fdf | |||
| e33df8f12d | |||
| 0e0e8e9d18 | |||
| 37f8b54752 | |||
| e9a086ad23 | |||
| 7c06a8ac41 | |||
| 70801d958e | |||
| cf3f95c952 | |||
| d708616a6a | |||
| 17711bc5c9 | |||
| 1e2474921b | |||
| 3f37b2b728 | |||
| 18b11df672 | |||
| c34f2d4da7 | |||
| d61792581a | |||
| 76d9a511b8 | |||
| 4248326697 | |||
| a540b38151 | |||
| 8fb5ef0c1d | |||
| 2da4979e59 | |||
| 0146e4a1dd | |||
| 34bdb72ffd | |||
| 2ef7c63047 | |||
| 95f5417761 | |||
| 4922ec4499 | |||
| 20d947a199 | |||
| c9444c5318 | |||
| 871dc90ee4 | |||
| d1925945b4 | |||
| 6625080fde | |||
| 1110609e39 | |||
| f21d2c7253 | |||
| 9c1d330945 | |||
| cd7800056c | |||
| 7ff4bec3bc | |||
| d305cf2167 | |||
| e77b83bd92 | |||
| 171d58658a | |||
| a6f6bc4c0a | |||
| f03cffe3f8 | |||
| 809dca184e | |||
| ecda226949 | |||
| ff1b58ebd8 | |||
| 5760ada3b4 | |||
| b74b6b3284 | |||
| e4cc4b6f58 | |||
| dd90851477 | |||
| da9b127468 | |||
| d6b05e44cb | |||
| 58c1b5b98d | |||
| c270cba8d6 | |||
| 58f1f749fc | |||
| 38d87a7c8f | |||
| 4e13598708 | |||
| 4177448d32 | |||
| e4911a6f82 | |||
| 159224700f | |||
| 696d4e7342 | |||
| ffb6cfaa4a | |||
| b8899fcafa | |||
| aba829c991 | |||
| 8f4c61c259 | |||
| a19648a6e8 | |||
| d5c0f7045e | |||
| 6f69205818 | |||
| 8166da548c | |||
| d54f7293b7 | |||
| 225520a765 | |||
| af1eccde8e | |||
| 5d37280643 | |||
| 80597039f5 | |||
| 2766aedc01 | |||
| da3e12cb7e | |||
| 8baff1b0d2 | |||
| 4ff5f9204e | |||
| 515339bbd8 | |||
| 943634b0e2 | |||
| 212b26b960 | |||
| c0b41987aa | |||
| b4ef640052 | |||
| db6b7f52eb | |||
| 55b4b9e02a | |||
| 4e6ae93b13 | |||
| c9a5fe5676 | |||
| a5adfb7c7f | |||
| 1794b86041 | |||
| f405124ce4 | |||
| 25060c1477 | |||
| 6ad218f354 | |||
| d1c52548b0 | |||
| 9dc847b72f | |||
| 5b04adb21f | |||
| 356d25e548 | |||
| a9958af818 | |||
| fb359b7f87 | |||
| 7f087819a6 | |||
| e836fa3d38 | |||
| 9a69f1108d | |||
| 2c5c58dc90 | |||
| cb50d2838a | |||
| aff7125914 | |||
| 45d82dce04 | |||
| 7a3b27227a | |||
| 7b50a19b2c | |||
| 741b942dea | |||
| f7ca64a49d | |||
| 2f7b3455e5 | |||
| 1568dfc183 | |||
| d3a5df0007 | |||
| c20cac621a | |||
| 74560c3289 | |||
| f94bf3f8ce | |||
| d26db7096d | |||
| afde0a7423 | |||
| cc930a3ff9 | |||
| 60ecdadc74 | |||
| 82fc1850cf | |||
| 88f937f73e | |||
| b3497c7306 | |||
| 366ab2e0cd | |||
| 98e4fabd2e | |||
| 716c3573fd | |||
| 842d8dd780 | |||
| c767dfb22e | |||
| f94901c3b2 | |||
| c9638aefe9 | |||
| 8bd4721686 | |||
| 808f7504c3 | |||
| 8ea7d3d5e8 | |||
| d4931890ae | |||
| f4a879a452 | |||
| 78521ffdb4 | |||
| 8ea3f80b97 | |||
| 0d8d87857c | |||
| 3a3a261d9c | |||
| 2e00daf63c | |||
| 1b8bb0c1fd | |||
| 5c33579544 | |||
| f8081ff09e | |||
| 01b7eeeecf | |||
| d2f4c374a9 | |||
| 07073eebe9 | |||
| 590a4ae476 | |||
| b553a81d47 | |||
| 7d4e53e413 | |||
| 839b0f6f5e | |||
| 893c5da4ef | |||
| f9b893edfa | |||
| b4fadb39bf | |||
| 310f8bf6f7 | |||
| 903a26a330 | |||
| 41ebd39810 | |||
| 281de5196e | |||
| a9ab864cbb | |||
| f3ff910821 | |||
| ba5179f1e8 | |||
| 05e8f6ed78 | |||
| 23150815a0 | |||
| a50f223fe3 | |||
| 9329345d98 | |||
| c71c32b363 | |||
| 5590aa7234 | |||
| 4a3491e0b5 | |||
| e8cb87ae3d | |||
| 2f6427af32 | |||
| 5564047001 | |||
| 22577c5f87 | |||
| 4dc2627da2 | |||
| 05aaf0de9f | |||
| 951bfa23f3 | |||
| 7ac6cfcf25 | |||
| 06055a7c4c | |||
| b33198d1bf | |||
| f826b9eb6e | |||
| 2b58121552 | |||
| 762547d0e9 | |||
| 727523eb3f | |||
| 5bbdb66eb2 | |||
| c6eff4f90d | |||
| 2559173c2c | |||
| 8adea132ef | |||
| 9d924f8d1c | |||
| 1b297fed90 | |||
| 2c2a93c440 | |||
| bb076cce5d | |||
| b16b02c3f1 | |||
| 3e0f834796 | |||
| 0af38c6e0e | |||
| 85f7011e03 | |||
| e8d5412e14 | |||
| 170cf4753e | |||
| 660e76145e | |||
| 31a6f7b621 | |||
| f6699ad93b | |||
| 6e508e4454 | |||
| 2b101844e9 | |||
| fb036935e6 | |||
| c3e09ddab0 | |||
| 36ae07074d | |||
| a4518ce261 | |||
| 861ea7ef94 | |||
| 541af0b77e | |||
| 3fd3de1828 | |||
| 3e2840ca15 | |||
| 839ec9a456 | |||
| bac8bd0006 | |||
| 8c1b51b7e9 | |||
| a71c4fe7ec | |||
| b9d4197b5c | |||
| ce7559087e | |||
| 110d87e512 | |||
| cd817714cd | |||
| 23db345756 | |||
| 16990bd0c3 | |||
| 2e3b770bea | |||
| 28f62623bf | |||
| c9f3e8cb9f | |||
| 6b751eb715 | |||
| 5d953da267 | |||
| e87ae31a51 | |||
| 9f029b892b | |||
| 40a9ced0f7 | |||
| 87fbd7e5da | |||
| bca5514a76 | |||
| 62ddbb20ac | |||
| 9d376961f4 | |||
| e77aa00bcd | |||
| 465330820d | |||
| ec9cbba67e | |||
| 8961ea6fc9 | |||
| ca7ca9da81 | |||
| 2a234f14df | |||
| 3ff97bf628 | |||
| 416d6f2aef | |||
| ecaafaca69 | |||
| fdb14cd49b | |||
| 070e955b89 | |||
| 9390ab3c6c | |||
| f67221ee01 | |||
| e09294d9aa | |||
| 5675acb71a | |||
| 0305a5dcef | |||
| 5f03340454 | |||
| 0f69ba46c5 | |||
| 71ecb6bd4e | |||
| 2b712cc808 | |||
| 3a68b7b554 | |||
| e41727a1fc | |||
| 857d0f3316 | |||
| 1f68f62689 | |||
| 09b43a8e95 | |||
| b8d765d229 | |||
| 06a919ff8d | |||
| ea1e7769b1 | |||
| d5e6f99819 | |||
| a5ab9726dd | |||
| 6464fc56d8 | |||
| 156e1b928c | |||
| edf17b8100 | |||
| 5ab980ce1a | |||
| f1d80fadc4 | |||
| d331d48ca2 | |||
| e740db11ed | |||
| 6cff7b3c30 | |||
| 88cdd2fcbf | |||
| 55896be694 | |||
| c4f17e42e1 | |||
| e8b11bd42a | |||
| a566fb3988 | |||
| de071b37eb | |||
| 7b4d408733 | |||
| 06478d89ea | |||
| 7cedf4c620 | |||
| ef1ea5eeee | |||
| 96f222db94 | |||
| 065eb9b878 | |||
| ed583d80a3 | |||
| 7752db3916 | |||
| e18254e4d8 | |||
| 555fc97e8f | |||
| f135adfdba | |||
| 72b766f32a | |||
| 5278861ccd | |||
| ebcf88070c | |||
| 273811bbb8 | |||
| 26b53e725d | |||
| 5434ec85e2 | |||
| 91f438aeff | |||
| 501f67ebe7 | |||
| be52fef0bb | |||
| 2c0cf40a15 | |||
| 8566070d9b | |||
| 8f4118a6b8 | |||
| 54c53f0b56 | |||
| eafcee8c67 | |||
| 5c8e1e0f4a | |||
| 76043d5876 | |||
| 936f3b0752 | |||
| 9380608781 | |||
| 544b75bcd5 | |||
| 2ae63d2323 | |||
| f24717a3a3 | |||
| f0f5558f3e | |||
| 3d8c732258 | |||
| f312237bd5 | |||
| 952dde3fef | |||
| e5387f6d06 | |||
| 93d6697b4e | |||
| bad2f3415a | |||
| d2f5d97282 | |||
| f8c3fef839 | |||
| 14b47a929f | |||
| 4b3c0466eb | |||
| 041397b137 | |||
| 6548c286a6 | |||
| ccf78285b6 | |||
| 5e9366fa92 | |||
| 0e30cb1439 | |||
| b8d86518e7 | |||
| 725399ac7c | |||
| ca18994092 | |||
| caefc438b9 | |||
| 0ece8c7dec | |||
| e7c42f3623 | |||
| 18faf89b89 | |||
| 3a750ae6a2 | |||
| 48c614d8c3 | |||
| c37d502c27 | |||
| 3fed7a081d | |||
| e75497d03b | |||
| 6d1421f1b7 | |||
| dd210be037 | |||
| 7c7d6ad548 | |||
| 2f471c0e3f | |||
| cff219674f | |||
| e35f9eb75b | |||
| ef1eff2ecb | |||
| 244ff61fb3 | |||
| 50e2623f19 | |||
| fd0b997c13 | |||
| 13d057e4f7 | |||
| d1a6be6ca6 | |||
| edece02c13 | |||
| d68cf4e44d | |||
| 9d85a58634 | |||
| c4a4cd0957 | |||
| 5af7615054 | |||
| a68a1334fc | |||
| dd3e38355c | |||
| 890461bcf8 | |||
| 750265cb79 | |||
| 004de824ba | |||
| fc43b35628 | |||
| 696653f945 | |||
| 157dca50e9 | |||
| 7d2130b229 | |||
| 2cc81211af | |||
| ea9a5b0eb0 | |||
| e60cee6a73 | |||
| a3ee60a464 | |||
| 28595cbeb3 | |||
| dbdbf5210e | |||
| a4876f6f14 | |||
| 9835ae7e50 | |||
| 59f763162c | |||
| a9412b418f | |||
| 742c5b76fe | |||
| 7a85fc0179 | |||
| 73e73ffe58 | |||
| 3c5523894d | |||
| 4b9c76d3db | |||
| 0a694eea8a | |||
| 87f48dad79 | |||
| 68ef50ca46 | |||
| 8b1da33ffe | |||
| 9a9b18a3ef | |||
| 83f69d89ff | |||
| 0bd7d23114 | |||
| 9b860a6aa6 | |||
| 4812519a4c | |||
| f3ce6ad467 | |||
| 78d9b48854 | |||
| b37d0eba04 | |||
| 5289b3f54c | |||
| 5c08fe0611 | |||
| 4bc9b70882 | |||
| 3f98f9ff39 | |||
| e78a7bfbf1 | |||
| b8b1412bf8 | |||
| a81d66ace3 | |||
| dcfd72b7e7 | |||
| 6467db4a21 | |||
| f2570c97f3 | |||
| 98ad518b5d | |||
| 7a5e17a345 | |||
| fde257c722 | |||
| 97357f082d | |||
| 6875bd82fc | |||
| b1f6cad741 | |||
| fb28fec60d | |||
| 500130be59 | |||
| 101173c87c | |||
| 4fb1b0dbd1 | |||
| 4270d5e8ec | |||
| fe9f1146ce | |||
| 6fce43a122 | |||
| a8a8f9b3e5 | |||
| 0dd0125e9f | |||
| d3d97b5924 | |||
| c8462fb50b | |||
| c99ca9edcc | |||
| fc7e96feb9 | |||
| 31dd7be296 | |||
| 2899373e42 | |||
| 7640c3d0ef | |||
| af7772f617 | |||
| a1670caf06 | |||
| 61e35b9773 | |||
| e4671ffdb3 | |||
| 3035f923cb | |||
| 97e83def48 | |||
| ba31deaebf | |||
| bd571dc93d | |||
| c1da8321ac | |||
| 0a1972b854 | |||
| 96f387e90b | |||
| e034fc1019 | |||
| d539912762 | |||
| 85b72af3bb | |||
| 3004f4b583 | |||
| 78dbd7eacd | |||
| add73e6f16 | |||
| 2c5a7d103d | |||
| f8f855d5d2 | |||
| f2c109116c | |||
| 41c63fab96 | |||
| de94651fca | |||
| 611c468b70 | |||
| fd2207e39e | |||
| 10564442e2 | |||
| a44307ca2d | |||
| cfea2ed954 | |||
| 62e59605ed | |||
| 2644b1b7ac | |||
| 6e4c6d0c54 | |||
| 2b7d950a9f | |||
| 5ece8d67f9 | |||
| 8511b67811 | |||
| a0a444e476 | |||
| 6fec92926d | |||
| 2cbefb261b | |||
| 4bebbb158c | |||
| 8fe2172c0a | |||
| f52ef2d57e | |||
| 3f1c005548 | |||
| 821bd2b2d8 | |||
| d8405feab3 | |||
| bd94437c05 | |||
| b290bdb473 | |||
| f8e2af4fd4 | |||
| 97c8dfa5b9 | |||
| 37cce68e2e | |||
| 1f87a71b98 | |||
| 5511ea1887 | |||
| e371081a1d | |||
| 70816b48e8 | |||
| 2c9fc7b4a7 | |||
| 3bb4652a49 | |||
| d5f8e01dd8 | |||
| 27e0517f9a | |||
| f59aeda28e | |||
| a8a69f8c36 | |||
| 4ae6b8328e | |||
| 6d4337e4ce | |||
| 3df928caf4 | |||
| faeb33fdc0 | |||
| bacdeb20eb | |||
| 781c426b2f | |||
| d5c9fb8dec | |||
| 78c372b9d8 | |||
| ea31069609 | |||
| 3f9a3e8f64 | |||
| 2f02715efd | |||
| c94fa64a33 | |||
| e2cb666b3c | |||
| 9f24e0145b | |||
| 41413471aa | |||
| f8a11166f0 | |||
| 27517b3b47 | |||
| 834c0d92b4 | |||
| e04215f0e1 | |||
| 9fa8d98ae8 | |||
| 31621f273b | |||
| 41f158dac1 | |||
| e5687f3a7c | |||
| 1a5b684e1f | |||
| bf70c487ca | |||
| 4e1d34ba77 | |||
| 3a75ad61f3 | |||
| c7db9ef481 | |||
| fb709c9eb0 | |||
| dfe4d2811a | |||
| 6e4d16749b | |||
| 75b2debf0a | |||
| ba9e124527 | |||
| d684ab0e5e | |||
| 2e8205f458 | |||
| 35855297eb | |||
| d365ecce46 | |||
| f4edc45507 | |||
| d165d81df0 | |||
| ba0eba7132 | |||
| 2b7f4281c2 | |||
| 0046575a4f | |||
| 58b88d66be | |||
| 57f1019e51 | |||
| b40168182a | |||
| 0ece662d8c | |||
| 9265e52d68 | |||
| 3a04166747 | |||
| 75bf58359c | |||
| e7f63e0460 | |||
| 1fdd1c6e88 | |||
| 391b9e91e9 | |||
| 1e67ca3794 | |||
| ceebf6dbe1 | |||
| 8d4f9fd953 | |||
| 1c3032068e | |||
| 7b4b72166f | |||
| 707e5bb8b0 | |||
| ad5d364c57 | |||
| 138fadf672 | |||
| 82eabc41fe | |||
| 3e6aab6b00 | |||
| 5396b3f1fb | |||
| b1ba887922 | |||
| 93a1c593fe | |||
| b7044248cb | |||
| ea5e2f660b | |||
| e9779a3d2f | |||
| 1c6ec0f8e3 | |||
| 84bd81e525 | |||
| a84cbee9db | |||
| 97b16c8c0c | |||
| 0a6a35b022 | |||
| 6565b4101b | |||
| fbbcc1172d | |||
| 53dc50c0dd | |||
| 7b56485c74 | |||
| cfc9b809fc | |||
| 4015e2566e | |||
| 1d474a967c | |||
| bffc34485a | |||
| 3bf22a8606 | |||
| 257ffa3cc4 | |||
| 0c104d5d29 | |||
| 2a59faec17 | |||
| 00534f7edd | |||
| 4006f03444 | |||
| beca5c6e45 | |||
| 69f781d3de | |||
| 3f3160406f | |||
| 8067cff9bd | |||
| 7d776bb2af | |||
| 880bb0d7cb | |||
| 3aea01fb78 | |||
| 7025f4701d | |||
| 9d98b06132 | |||
| 47cb83c1ff | |||
| 6ff8847251 | |||
| 9d9367d127 | |||
| ae7c1ae666 | |||
| 44fe3cb7bd | |||
| bc783eb511 | |||
| 0491bd5364 | |||
| cf47cccc97 | |||
| c65ab35107 | |||
| b8ea16f4d4 | |||
| b40b5f0c1c | |||
| b193e29fdb | |||
| 1b602c134f | |||
| e462c6d412 | |||
| d0c83f3c96 | |||
| 0547aa2095 | |||
| 322907b972 | |||
| 189b9a7ad6 | |||
| 1d02927f6b | |||
| 2ad739419a | |||
| 093ace1a89 | |||
| 4c982a762b | |||
| a30efd6e81 | |||
| 1c0fc0bff2 | |||
| 7da0c204df | |||
| a35421d8ab | |||
| 450ce53dcf | |||
| e80ccfcb19 | |||
| 9ad612bd78 | |||
| 288857999f | |||
| 217823652c | |||
| 268e1670c7 | |||
| ce7b155f72 | |||
| 2a71d84580 | |||
| 8f73dce934 | |||
| 5953e32988 | |||
| df74322b05 | |||
| 22d941ae45 | |||
| 4fd7c1c4e9 | |||
| ee1aa6d42c | |||
| 1343aba26e | |||
| 1483d84d8c | |||
| 02d58d66c9 | |||
| 2eb6ca28f7 | |||
| 7575a9ce02 | |||
| 039b832be2 | |||
| e0ed025507 | |||
| f2bd08f02a | |||
| 63314b54bc | |||
| 65165cd15f | |||
| d5ddbca067 | |||
| 517027e1fe | |||
| b843ccc898 | |||
| fffd81267d | |||
| 7d26dd5348 | |||
| a4d3189dac | |||
| ec02743f83 | |||
| 10e807751a | |||
| a8e827b5e2 | |||
| f0eaba5857 | |||
| 7516b056a5 | |||
| 312c3b8295 | |||
| 0a777dc909 | |||
| ec24376608 | |||
| c9f45da217 | |||
| 34cfbabf51 | |||
| f7e7a4c99c | |||
| 58c318b5cf | |||
| 10b1644d8d | |||
| 599f59fc39 | |||
| da4b8f6cb9 | |||
| 5f2e882ed9 | |||
| f20abe8878 | |||
| a6ab37f21c | |||
| 13fc3ee25e | |||
| 2268086eac | |||
| 9e9dec5389 | |||
| 11d193a6dd | |||
| f81207737c | |||
| 191c25a26b | |||
| 9c7727b7f3 | |||
| 8bea9b8312 | |||
| 805a063fa1 | |||
| 20a1cc89ae | |||
| 963994b1e5 | |||
| afcb226111 | |||
| 5b246fe44c | |||
| d79f82e9b8 | |||
| bdd9dc8c9d | |||
| 8bdd24aa1e | |||
| 13c0da5c8a | |||
| d31cfb15db | |||
| 8453bd3c26 | |||
| 457bf311c3 | |||
| ea2ec9ef54 | |||
| d0c84ea469 | |||
| cdec56b661 | |||
| 8bc2d7cb05 | |||
| 21f3de0a18 | |||
| 65b497c9f1 | |||
| f37f1e794e | |||
| 0096a40132 | |||
| b6b9b67836 | |||
| 2b80a98a96 | |||
| 8c5d47bfa0 | |||
| 00c0a0505f | |||
| 01ba8b4f3f | |||
| 919249215b | |||
| a62394a67c | |||
| 332fff279b | |||
| 27df4c435f | |||
| a9998ebca7 | |||
| 82a8baabef | |||
| 2af6d4ef29 | |||
| c2526c1e2d | |||
| 6021fa721e | |||
| 0bd59dc0f8 | |||
| 1af0c34ac0 | |||
| 77f5b6d0c8 | |||
| cb3fdf1112 | |||
| 482d3d9188 | |||
| bb4c64f478 | |||
| a9d6e42add | |||
| 5fa6cf8eca | |||
| 7c0de7b634 | |||
| 691f3238c5 | |||
| 43163c787d | |||
| a86693d950 | |||
| 6388129e27 | |||
| 7788806a8d | |||
| 30037dad83 | |||
| d49c7d5e45 | |||
| 502109cdcb | |||
| 3de775a163 | |||
| d4de917895 | |||
| 35cb718f1f | |||
| 60a72f4d45 | |||
| 6ae536d035 | |||
| 23daa7a91c | |||
| 771f93b5fa | |||
| 19826636c7 | |||
| 57ba9b52ba | |||
| 38c0d9bbc3 | |||
| 5fb3e0b941 | |||
| 9aa09d138a | |||
| f48efcc02d | |||
| 1703e9e8c6 | |||
| 940cf02935 | |||
| 355aefc62a | |||
| 0c0c9b2dad | |||
| d3df844917 | |||
| e227f1f182 | |||
| f97b49bc53 | |||
| 788b6def6c | |||
| 8550707485 | |||
| aa8dfa1c87 | |||
| 7b68dd0f47 | |||
| f4c9c880bc | |||
| cac3e6efec | |||
| d76786e344 | |||
| 171b967cc4 | |||
| b5766494e1 | |||
| b72af50a85 | |||
| 63b66fe301 | |||
| 244cb79774 | |||
| 8d20b7d19f | |||
| dc9da0b866 | |||
| 3b72a9751c | |||
| bb3cb23ee0 | |||
| 737436d7e7 | |||
| bccfa79bb6 | |||
| 6bf5c58ec1 | |||
| 151230098c | |||
| 5debd8e115 | |||
| 83633536db | |||
| c187d902d2 | |||
| e2547c7295 | |||
| 359557e321 | |||
| 94cccf9e17 | |||
| 13e4c2de03 | |||
| 844d7025fa | |||
| 0f01f35d19 | |||
| 505c219cfd | |||
| c40d745a3a | |||
| 13ee14c752 | |||
| 1d1e488755 | |||
| d9537e5fd4 | |||
| 5fc5497a9e | |||
| fd70df0f43 | |||
| c16d47473d | |||
| f5e2300460 | |||
| 73a3e8d498 | |||
| bb38b93927 | |||
| 979f2c7dac | |||
| 808b774ad1 | |||
| 38ce62185e | |||
| ac4e411d41 | |||
| fdc784f42d | |||
| edcaf585ea | |||
| cdafe7e5f2 | |||
| 40cfe63b6f | |||
| 2fee584da9 | |||
| 8b1d8d6d71 | |||
| f63b61681f | |||
| de4cea86da | |||
| c0ca84f347 | |||
| 9c5a2c79f5 | |||
| 8359746f47 | |||
| 516393856d | |||
| e7e57414b5 | |||
| 687669330d | |||
| d3147d3969 | |||
| ca8b7911a6 | |||
| 3d23a13c34 | |||
| cf8a104183 | |||
| bd7aa7884a | |||
| f2db514e45 | |||
| d35801dcc7 | |||
| 50f9e025c4 | |||
| 09fa3ce438 | |||
| bcf89b1f09 | |||
| 645a1d35e8 | |||
| 1154eff459 |
@@ -5,10 +5,14 @@ name: Electron app BETA
|
||||
'on':
|
||||
push:
|
||||
tags:
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+-beta.[0-9]+'
|
||||
- v[0-9]+.[0-9]+.[0-9]+-beta.[0-9]+
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: write
|
||||
jobs:
|
||||
build:
|
||||
runs-on: '${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
environment: dbgate-app
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -24,7 +28,7 @@ jobs:
|
||||
echo "PYTHON=/opt/homebrew/bin/python3.11" >> $GITHUB_ENV
|
||||
- name: Context
|
||||
env:
|
||||
GITHUB_CONTEXT: '${{ toJson(github) }}'
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
@@ -53,12 +57,6 @@ jobs:
|
||||
run: |
|
||||
|
||||
yarn setCurrentVersion
|
||||
- name: printSecrets
|
||||
run: |
|
||||
|
||||
yarn printSecrets
|
||||
env:
|
||||
GIST_UPLOAD_SECRET: '${{secrets.GIST_UPLOAD_SECRET}}'
|
||||
- name: fillPackagedPlugins
|
||||
run: |
|
||||
|
||||
@@ -66,21 +64,53 @@ jobs:
|
||||
- name: Install Snapcraft
|
||||
if: matrix.os == 'ubuntu-22.04'
|
||||
uses: samuelmeuli/action-snapcraft@v1
|
||||
- name: Publish
|
||||
- name: Publish Windows
|
||||
if: matrix.os == 'windows-2022'
|
||||
run: |
|
||||
|
||||
yarn run build:app
|
||||
- name: Publish MacOS
|
||||
if: matrix.os == 'macos-14'
|
||||
run: |
|
||||
|
||||
yarn run build:app
|
||||
env:
|
||||
GH_TOKEN: '${{ secrets.GH_TOKEN }}'
|
||||
WIN_CSC_LINK: '${{ secrets.WINCERT_2025 }}'
|
||||
WIN_CSC_KEY_PASSWORD: '${{ secrets.WINCERT_2025_PASSWORD }}'
|
||||
CSC_LINK: '${{ secrets.APPLECERT_CERTIFICATE }}'
|
||||
CSC_KEY_PASSWORD: '${{ secrets.APPLECERT_PASSWORD }}'
|
||||
APPLE_ID: '${{ secrets.APPLE_ID }}'
|
||||
APPLE_TEAM_ID: '${{ secrets.APPLE_TEAM_ID }}'
|
||||
APPLE_ID_PASSWORD: '${{ secrets.APPLE_ID_PASSWORD }}'
|
||||
SNAPCRAFT_STORE_CREDENTIALS: '${{secrets.SNAPCRAFT_LOGIN}}'
|
||||
APPLE_APP_SPECIFIC_PASSWORD: '${{secrets.APPLE_APP_SPECIFIC_PASSWORD}}'
|
||||
CSC_LINK: ${{ secrets.APPLECERT_CERTIFICATE }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.APPLECERT_PASSWORD }}
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||||
APPLE_APP_SPECIFIC_PASSWORD: ${{secrets.APPLE_APP_SPECIFIC_PASSWORD}}
|
||||
- name: Publish Linux
|
||||
if: matrix.os == 'ubuntu-22.04'
|
||||
run: |
|
||||
|
||||
yarn run build:app
|
||||
env:
|
||||
SNAPCRAFT_STORE_CREDENTIALS: ${{secrets.SNAPCRAFT_LOGIN}}
|
||||
- name: Azure login (OIDC)
|
||||
uses: azure/login@v2
|
||||
if: matrix.os == 'windows-2022'
|
||||
with:
|
||||
client-id: ${{ secrets.AZURE_TC_CLIENT_ID }}
|
||||
tenant-id: ${{ secrets.AZURE_TC_TENANT_ID }}
|
||||
allow-no-subscriptions: true
|
||||
- name: Sign Windows artifacts with Azure Trusted Signing
|
||||
uses: azure/trusted-signing-action@v0
|
||||
if: matrix.os == 'windows-2022'
|
||||
with:
|
||||
endpoint: https://wus3.codesigning.azure.net/
|
||||
trusted-signing-account-name: DbGate
|
||||
certificate-profile-name: DbGate-Release
|
||||
files-folder: app/dist
|
||||
files-folder-filter: exe
|
||||
timestamp-rfc3161: http://timestamp.acs.microsoft.com
|
||||
timestamp-digest: SHA256
|
||||
- name: Fix YML hashes
|
||||
if: matrix.os == 'windows-2022'
|
||||
run: |
|
||||
|
||||
yarn run fixYmlHashes
|
||||
- name: Copy artifacts
|
||||
run: |
|
||||
mkdir artifacts
|
||||
@@ -92,6 +122,7 @@ jobs:
|
||||
cp app/dist/*win*.exe artifacts/dbgate-beta.exe || true
|
||||
cp app/dist/*win_x64.zip artifacts/dbgate-windows-beta.zip || true
|
||||
cp app/dist/*win_arm64.zip artifacts/dbgate-windows-beta-arm64.zip || true
|
||||
cp app/dist/*win_arm64.exe artifacts/dbgate-windows-beta-arm64.exe || true
|
||||
cp app/dist/*-mac_universal.dmg artifacts/dbgate-beta.dmg || true
|
||||
cp app/dist/*-mac_x64.dmg artifacts/dbgate-beta-x64.dmg || true
|
||||
cp app/dist/*-mac_arm64.dmg artifacts/dbgate-beta-arm64.dmg || true
|
||||
@@ -111,16 +142,16 @@ jobs:
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: '${{ matrix.os }}'
|
||||
name: ${{ matrix.os }}
|
||||
path: artifacts
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: 'startsWith(github.ref, ''refs/tags/'')'
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
files: artifacts/**
|
||||
prerelease: true
|
||||
env:
|
||||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Print content of notarization-error.log
|
||||
if: failure() && matrix.os == 'macos-14'
|
||||
run: |
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# This file is generated. Do not edit manually
|
||||
# --------------------------------------------------------------------------------------------
|
||||
name: Electron app check build
|
||||
'on':
|
||||
push:
|
||||
tags:
|
||||
- check-[0-9]+-[0-9]+-[0-9]+.[0-9]+
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: write
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
environment: dbgate-app
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os:
|
||||
- macos-14
|
||||
- windows-2022
|
||||
- ubuntu-22.04
|
||||
steps:
|
||||
- name: Install python 3.11 (MacOS)
|
||||
if: matrix.os == 'macos-14'
|
||||
run: |
|
||||
brew install python@3.11
|
||||
echo "PYTHON=/opt/homebrew/bin/python3.11" >> $GITHUB_ENV
|
||||
- name: Context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: Use Node.js 22.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 22.x
|
||||
- name: adjustPackageJson
|
||||
run: |
|
||||
|
||||
node adjustPackageJson --community
|
||||
- name: yarn set timeout
|
||||
run: |
|
||||
|
||||
yarn config set network-timeout 100000
|
||||
- name: yarn install
|
||||
run: |
|
||||
|
||||
yarn install
|
||||
- name: setCurrentVersion
|
||||
run: |
|
||||
|
||||
yarn setCurrentVersion
|
||||
- name: fillPackagedPlugins
|
||||
run: |
|
||||
|
||||
yarn fillPackagedPlugins
|
||||
- name: Install Snapcraft
|
||||
if: matrix.os == 'ubuntu-22.04'
|
||||
uses: samuelmeuli/action-snapcraft@v1
|
||||
- name: Publish Windows
|
||||
if: matrix.os == 'windows-2022'
|
||||
run: |
|
||||
|
||||
yarn run build:app
|
||||
- name: Publish MacOS
|
||||
if: matrix.os == 'macos-14'
|
||||
run: |
|
||||
|
||||
yarn run build:app
|
||||
env:
|
||||
CSC_LINK: ${{ secrets.APPLECERT_CERTIFICATE }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.APPLECERT_PASSWORD }}
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||||
APPLE_APP_SPECIFIC_PASSWORD: ${{secrets.APPLE_APP_SPECIFIC_PASSWORD}}
|
||||
- name: Publish Linux
|
||||
if: matrix.os == 'ubuntu-22.04'
|
||||
run: |
|
||||
|
||||
yarn run build:app
|
||||
env:
|
||||
SNAPCRAFT_STORE_CREDENTIALS: ${{secrets.SNAPCRAFT_LOGIN}}
|
||||
- name: Azure login (OIDC)
|
||||
uses: azure/login@v2
|
||||
if: matrix.os == 'windows-2022'
|
||||
with:
|
||||
client-id: ${{ secrets.AZURE_TC_CLIENT_ID }}
|
||||
tenant-id: ${{ secrets.AZURE_TC_TENANT_ID }}
|
||||
allow-no-subscriptions: true
|
||||
- name: Sign Windows artifacts with Azure Trusted Signing
|
||||
uses: azure/trusted-signing-action@v0
|
||||
if: matrix.os == 'windows-2022'
|
||||
with:
|
||||
endpoint: https://wus3.codesigning.azure.net/
|
||||
trusted-signing-account-name: DbGate
|
||||
certificate-profile-name: DbGate-Release
|
||||
files-folder: app/dist
|
||||
files-folder-filter: exe
|
||||
timestamp-rfc3161: http://timestamp.acs.microsoft.com
|
||||
timestamp-digest: SHA256
|
||||
- name: Fix YML hashes
|
||||
if: matrix.os == 'windows-2022'
|
||||
run: |
|
||||
|
||||
yarn run fixYmlHashes
|
||||
- name: Copy artifacts
|
||||
run: |
|
||||
mkdir artifacts
|
||||
|
||||
cp app/dist/*.deb artifacts/dbgate-check.deb || true
|
||||
cp app/dist/*x86*.AppImage artifacts/dbgate-check.AppImage || true
|
||||
cp app/dist/*arm64*.AppImage artifacts/dbgate-check-arm64.AppImage || true
|
||||
cp app/dist/*armv7l*.AppImage artifacts/dbgate-check-armv7l.AppImage || true
|
||||
cp app/dist/*win*.exe artifacts/dbgate-check.exe || true
|
||||
cp app/dist/*win_x64.zip artifacts/dbgate-windows-check.zip || true
|
||||
cp app/dist/*win_arm64.zip artifacts/dbgate-windows-check-arm64.zip || true
|
||||
cp app/dist/*win_arm64.exe artifacts/dbgate-windows-check-arm64.exe || true
|
||||
cp app/dist/*-mac_universal.dmg artifacts/dbgate-check.dmg || true
|
||||
cp app/dist/*-mac_x64.dmg artifacts/dbgate-check-x64.dmg || true
|
||||
cp app/dist/*-mac_arm64.dmg artifacts/dbgate-check-arm64.dmg || true
|
||||
mv app/dist/*.snap artifacts/dbgate-check.snap || true
|
||||
|
||||
mv app/dist/*.exe artifacts/ || true
|
||||
mv app/dist/*.zip artifacts/ || true
|
||||
mv app/dist/*.tar.gz artifacts/ || true
|
||||
mv app/dist/*.AppImage artifacts/ || true
|
||||
mv app/dist/*.deb artifacts/ || true
|
||||
mv app/dist/*.snap artifacts/ || true
|
||||
mv app/dist/*.dmg artifacts/ || true
|
||||
mv app/dist/*.blockmap artifacts/ || true
|
||||
|
||||
mv app/dist/*.yml artifacts/ || true
|
||||
rm artifacts/builder-debug.yml
|
||||
- name: Print content of notarization-error.log
|
||||
if: failure() && matrix.os == 'macos-14'
|
||||
run: |
|
||||
|
||||
find . -type f -name "notarization-error.log" -exec echo "=== Start of {} ===" \; -exec cat {} \; -exec echo "=== End of {} ===" \;
|
||||
@@ -5,10 +5,14 @@ name: Electron app PREMIUM BETA
|
||||
'on':
|
||||
push:
|
||||
tags:
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+-premium-beta.[0-9]+'
|
||||
- v[0-9]+.[0-9]+.[0-9]+-premium-beta.[0-9]+
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: write
|
||||
jobs:
|
||||
build:
|
||||
runs-on: '${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
environment: dbgate-app
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -24,7 +28,7 @@ jobs:
|
||||
echo "PYTHON=/opt/homebrew/bin/python3.11" >> $GITHUB_ENV
|
||||
- name: Context
|
||||
env:
|
||||
GITHUB_CONTEXT: '${{ toJson(github) }}'
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
@@ -37,9 +41,9 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: '${{ secrets.GH_TOKEN }}'
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: a2f824dc711b510a5e8235d3faf4aafab1965184
|
||||
ref: f27a03d4aff5b00a009643df146a9c17bdbf7801
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
@@ -81,37 +85,67 @@ jobs:
|
||||
cd dbgate-merged
|
||||
|
||||
yarn setCurrentVersion
|
||||
- name: printSecrets
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
|
||||
yarn printSecrets
|
||||
env:
|
||||
GIST_UPLOAD_SECRET: '${{secrets.GIST_UPLOAD_SECRET}}'
|
||||
- name: fillPackagedPlugins
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
|
||||
yarn fillPackagedPlugins
|
||||
- name: Publish
|
||||
- name: Publish Windows
|
||||
if: matrix.os == 'windows-2022'
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
|
||||
yarn run build:app
|
||||
- name: Publish MacOS
|
||||
if: matrix.os == 'macos-14'
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
|
||||
yarn run build:app
|
||||
env:
|
||||
GH_TOKEN: '${{ secrets.GH_TOKEN }}'
|
||||
WIN_CSC_LINK: '${{ secrets.WINCERT_2025 }}'
|
||||
WIN_CSC_KEY_PASSWORD: '${{ secrets.WINCERT_2025_PASSWORD }}'
|
||||
CSC_LINK: '${{ secrets.APPLECERT_CERTIFICATE }}'
|
||||
CSC_KEY_PASSWORD: '${{ secrets.APPLECERT_PASSWORD }}'
|
||||
APPLE_ID: '${{ secrets.APPLE_ID }}'
|
||||
APPLE_TEAM_ID: '${{ secrets.APPLE_TEAM_ID }}'
|
||||
APPLE_ID_PASSWORD: '${{ secrets.APPLE_ID_PASSWORD }}'
|
||||
SNAPCRAFT_STORE_CREDENTIALS: '${{secrets.SNAPCRAFT_LOGIN}}'
|
||||
APPLE_APP_SPECIFIC_PASSWORD: '${{secrets.APPLE_APP_SPECIFIC_PASSWORD}}'
|
||||
CSC_LINK: ${{ secrets.APPLECERT_CERTIFICATE }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.APPLECERT_PASSWORD }}
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||||
APPLE_APP_SPECIFIC_PASSWORD: ${{secrets.APPLE_APP_SPECIFIC_PASSWORD}}
|
||||
- name: Publish Linux
|
||||
if: matrix.os == 'ubuntu-22.04'
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
|
||||
yarn run build:app
|
||||
env:
|
||||
SNAPCRAFT_STORE_CREDENTIALS: ${{secrets.SNAPCRAFT_LOGIN}}
|
||||
- name: Azure login (OIDC)
|
||||
uses: azure/login@v2
|
||||
if: matrix.os == 'windows-2022'
|
||||
with:
|
||||
client-id: ${{ secrets.AZURE_TC_CLIENT_ID }}
|
||||
tenant-id: ${{ secrets.AZURE_TC_TENANT_ID }}
|
||||
allow-no-subscriptions: true
|
||||
- name: Sign Windows artifacts with Azure Trusted Signing
|
||||
uses: azure/trusted-signing-action@v0
|
||||
if: matrix.os == 'windows-2022'
|
||||
with:
|
||||
endpoint: https://wus3.codesigning.azure.net/
|
||||
trusted-signing-account-name: DbGate
|
||||
certificate-profile-name: DbGate-Release
|
||||
files-folder: ../dbgate-merged/app/dist
|
||||
files-folder-filter: exe
|
||||
timestamp-rfc3161: http://timestamp.acs.microsoft.com
|
||||
timestamp-digest: SHA256
|
||||
- name: Fix YML hashes
|
||||
if: matrix.os == 'windows-2022'
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
|
||||
yarn run fixYmlHashes
|
||||
- name: Copy artifacts
|
||||
run: |
|
||||
mkdir artifacts
|
||||
@@ -123,6 +157,7 @@ jobs:
|
||||
cp ../dbgate-merged/app/dist/*win*.exe artifacts/dbgate-premium-beta.exe || true
|
||||
cp ../dbgate-merged/app/dist/*win_x64.zip artifacts/dbgate-windows-premium-beta.zip || true
|
||||
cp ../dbgate-merged/app/dist/*win_arm64.zip artifacts/dbgate-windows-premium-beta-arm64.zip || true
|
||||
cp ../dbgate-merged/app/dist/*win_arm64.exe artifacts/dbgate-windows-premium-beta-arm64.exe || true
|
||||
cp ../dbgate-merged/app/dist/*-mac_universal.dmg artifacts/dbgate-premium-beta.dmg || true
|
||||
cp ../dbgate-merged/app/dist/*-mac_x64.dmg artifacts/dbgate-premium-beta-x64.dmg || true
|
||||
cp ../dbgate-merged/app/dist/*-mac_arm64.dmg artifacts/dbgate-premium-beta-arm64.dmg || true
|
||||
@@ -142,16 +177,16 @@ jobs:
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: '${{ matrix.os }}'
|
||||
name: ${{ matrix.os }}
|
||||
path: artifacts
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: 'startsWith(github.ref, ''refs/tags/'')'
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
files: artifacts/**
|
||||
prerelease: true
|
||||
env:
|
||||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Print content of notarization-error.log
|
||||
if: failure() && matrix.os == 'macos-14'
|
||||
run: |
|
||||
|
||||
@@ -5,10 +5,14 @@ name: Electron app PREMIUM
|
||||
'on':
|
||||
push:
|
||||
tags:
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
- v[0-9]+.[0-9]+.[0-9]+
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: write
|
||||
jobs:
|
||||
build:
|
||||
runs-on: '${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
environment: dbgate-app
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -24,7 +28,7 @@ jobs:
|
||||
echo "PYTHON=/opt/homebrew/bin/python3.11" >> $GITHUB_ENV
|
||||
- name: Context
|
||||
env:
|
||||
GITHUB_CONTEXT: '${{ toJson(github) }}'
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
@@ -37,9 +41,9 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: '${{ secrets.GH_TOKEN }}'
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: a2f824dc711b510a5e8235d3faf4aafab1965184
|
||||
ref: f27a03d4aff5b00a009643df146a9c17bdbf7801
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
@@ -81,37 +85,67 @@ jobs:
|
||||
cd dbgate-merged
|
||||
|
||||
yarn setCurrentVersion
|
||||
- name: printSecrets
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
|
||||
yarn printSecrets
|
||||
env:
|
||||
GIST_UPLOAD_SECRET: '${{secrets.GIST_UPLOAD_SECRET}}'
|
||||
- name: fillPackagedPlugins
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
|
||||
yarn fillPackagedPlugins
|
||||
- name: Publish
|
||||
- name: Publish Windows
|
||||
if: matrix.os == 'windows-2022'
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
|
||||
yarn run build:app
|
||||
- name: Publish MacOS
|
||||
if: matrix.os == 'macos-14'
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
|
||||
yarn run build:app
|
||||
env:
|
||||
GH_TOKEN: '${{ secrets.GH_TOKEN }}'
|
||||
WIN_CSC_LINK: '${{ secrets.WINCERT_2025 }}'
|
||||
WIN_CSC_KEY_PASSWORD: '${{ secrets.WINCERT_2025_PASSWORD }}'
|
||||
CSC_LINK: '${{ secrets.APPLECERT_CERTIFICATE }}'
|
||||
CSC_KEY_PASSWORD: '${{ secrets.APPLECERT_PASSWORD }}'
|
||||
APPLE_ID: '${{ secrets.APPLE_ID }}'
|
||||
APPLE_TEAM_ID: '${{ secrets.APPLE_TEAM_ID }}'
|
||||
APPLE_ID_PASSWORD: '${{ secrets.APPLE_ID_PASSWORD }}'
|
||||
SNAPCRAFT_STORE_CREDENTIALS: '${{secrets.SNAPCRAFT_LOGIN}}'
|
||||
APPLE_APP_SPECIFIC_PASSWORD: '${{secrets.APPLE_APP_SPECIFIC_PASSWORD}}'
|
||||
CSC_LINK: ${{ secrets.APPLECERT_CERTIFICATE }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.APPLECERT_PASSWORD }}
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||||
APPLE_APP_SPECIFIC_PASSWORD: ${{secrets.APPLE_APP_SPECIFIC_PASSWORD}}
|
||||
- name: Publish Linux
|
||||
if: matrix.os == 'ubuntu-22.04'
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
|
||||
yarn run build:app
|
||||
env:
|
||||
SNAPCRAFT_STORE_CREDENTIALS: ${{secrets.SNAPCRAFT_LOGIN}}
|
||||
- name: Azure login (OIDC)
|
||||
uses: azure/login@v2
|
||||
if: matrix.os == 'windows-2022'
|
||||
with:
|
||||
client-id: ${{ secrets.AZURE_TC_CLIENT_ID }}
|
||||
tenant-id: ${{ secrets.AZURE_TC_TENANT_ID }}
|
||||
allow-no-subscriptions: true
|
||||
- name: Sign Windows artifacts with Azure Trusted Signing
|
||||
uses: azure/trusted-signing-action@v0
|
||||
if: matrix.os == 'windows-2022'
|
||||
with:
|
||||
endpoint: https://wus3.codesigning.azure.net/
|
||||
trusted-signing-account-name: DbGate
|
||||
certificate-profile-name: DbGate-Release
|
||||
files-folder: ../dbgate-merged/app/dist
|
||||
files-folder-filter: exe
|
||||
timestamp-rfc3161: http://timestamp.acs.microsoft.com
|
||||
timestamp-digest: SHA256
|
||||
- name: Fix YML hashes
|
||||
if: matrix.os == 'windows-2022'
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
|
||||
yarn run fixYmlHashes
|
||||
- name: Copy artifacts
|
||||
run: |
|
||||
mkdir artifacts
|
||||
@@ -123,6 +157,7 @@ jobs:
|
||||
cp ../dbgate-merged/app/dist/*win*.exe artifacts/dbgate-premium-latest.exe || true
|
||||
cp ../dbgate-merged/app/dist/*win_x64.zip artifacts/dbgate-windows-premium-latest.zip || true
|
||||
cp ../dbgate-merged/app/dist/*win_arm64.zip artifacts/dbgate-windows-premium-latest-arm64.zip || true
|
||||
cp ../dbgate-merged/app/dist/*win_arm64.exe artifacts/dbgate-windows-premium-latest-arm64.exe || true
|
||||
cp ../dbgate-merged/app/dist/*-mac_universal.dmg artifacts/dbgate-premium-latest.dmg || true
|
||||
cp ../dbgate-merged/app/dist/*-mac_x64.dmg artifacts/dbgate-premium-latest-x64.dmg || true
|
||||
cp ../dbgate-merged/app/dist/*-mac_arm64.dmg artifacts/dbgate-premium-latest-arm64.dmg || true
|
||||
@@ -142,16 +177,16 @@ jobs:
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: '${{ matrix.os }}'
|
||||
name: ${{ matrix.os }}
|
||||
path: artifacts
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: 'startsWith(github.ref, ''refs/tags/'')'
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
files: artifacts/**
|
||||
prerelease: false
|
||||
env:
|
||||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Print content of notarization-error.log
|
||||
if: failure() && matrix.os == 'macos-14'
|
||||
run: |
|
||||
|
||||
@@ -5,10 +5,14 @@ name: Electron app
|
||||
'on':
|
||||
push:
|
||||
tags:
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
- v[0-9]+.[0-9]+.[0-9]+
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: write
|
||||
jobs:
|
||||
build:
|
||||
runs-on: '${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
environment: dbgate-app
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -24,7 +28,7 @@ jobs:
|
||||
echo "PYTHON=/opt/homebrew/bin/python3.11" >> $GITHUB_ENV
|
||||
- name: Context
|
||||
env:
|
||||
GITHUB_CONTEXT: '${{ toJson(github) }}'
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
@@ -49,12 +53,6 @@ jobs:
|
||||
run: |
|
||||
|
||||
yarn setCurrentVersion
|
||||
- name: printSecrets
|
||||
run: |
|
||||
|
||||
yarn printSecrets
|
||||
env:
|
||||
GIST_UPLOAD_SECRET: '${{secrets.GIST_UPLOAD_SECRET}}'
|
||||
- name: fillPackagedPlugins
|
||||
run: |
|
||||
|
||||
@@ -62,24 +60,56 @@ jobs:
|
||||
- name: Install Snapcraft
|
||||
if: matrix.os == 'ubuntu-22.04'
|
||||
uses: samuelmeuli/action-snapcraft@v1
|
||||
- name: Publish
|
||||
- name: Publish Windows
|
||||
if: matrix.os == 'windows-2022'
|
||||
run: |
|
||||
|
||||
yarn run build:app
|
||||
- name: Publish MacOS
|
||||
if: matrix.os == 'macos-14'
|
||||
run: |
|
||||
|
||||
yarn run build:app
|
||||
env:
|
||||
GH_TOKEN: '${{ secrets.GH_TOKEN }}'
|
||||
WIN_CSC_LINK: '${{ secrets.WINCERT_2025 }}'
|
||||
WIN_CSC_KEY_PASSWORD: '${{ secrets.WINCERT_2025_PASSWORD }}'
|
||||
CSC_LINK: '${{ secrets.APPLECERT_CERTIFICATE }}'
|
||||
CSC_KEY_PASSWORD: '${{ secrets.APPLECERT_PASSWORD }}'
|
||||
APPLE_ID: '${{ secrets.APPLE_ID }}'
|
||||
APPLE_TEAM_ID: '${{ secrets.APPLE_TEAM_ID }}'
|
||||
APPLE_ID_PASSWORD: '${{ secrets.APPLE_ID_PASSWORD }}'
|
||||
SNAPCRAFT_STORE_CREDENTIALS: '${{secrets.SNAPCRAFT_LOGIN}}'
|
||||
APPLE_APP_SPECIFIC_PASSWORD: '${{secrets.APPLE_APP_SPECIFIC_PASSWORD}}'
|
||||
CSC_LINK: ${{ secrets.APPLECERT_CERTIFICATE }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.APPLECERT_PASSWORD }}
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||||
APPLE_APP_SPECIFIC_PASSWORD: ${{secrets.APPLE_APP_SPECIFIC_PASSWORD}}
|
||||
- name: Publish Linux
|
||||
if: matrix.os == 'ubuntu-22.04'
|
||||
run: |
|
||||
|
||||
yarn run build:app
|
||||
env:
|
||||
SNAPCRAFT_STORE_CREDENTIALS: ${{secrets.SNAPCRAFT_LOGIN}}
|
||||
- name: generatePadFile
|
||||
run: |
|
||||
yarn generatePadFile
|
||||
- name: Azure login (OIDC)
|
||||
uses: azure/login@v2
|
||||
if: matrix.os == 'windows-2022'
|
||||
with:
|
||||
client-id: ${{ secrets.AZURE_TC_CLIENT_ID }}
|
||||
tenant-id: ${{ secrets.AZURE_TC_TENANT_ID }}
|
||||
allow-no-subscriptions: true
|
||||
- name: Sign Windows artifacts with Azure Trusted Signing
|
||||
uses: azure/trusted-signing-action@v0
|
||||
if: matrix.os == 'windows-2022'
|
||||
with:
|
||||
endpoint: https://wus3.codesigning.azure.net/
|
||||
trusted-signing-account-name: DbGate
|
||||
certificate-profile-name: DbGate-Release
|
||||
files-folder: app/dist
|
||||
files-folder-filter: exe
|
||||
timestamp-rfc3161: http://timestamp.acs.microsoft.com
|
||||
timestamp-digest: SHA256
|
||||
- name: Fix YML hashes
|
||||
if: matrix.os == 'windows-2022'
|
||||
run: |
|
||||
|
||||
yarn run fixYmlHashes
|
||||
- name: Copy artifacts
|
||||
run: |
|
||||
mkdir artifacts
|
||||
@@ -91,6 +121,7 @@ jobs:
|
||||
cp app/dist/*win*.exe artifacts/dbgate-latest.exe || true
|
||||
cp app/dist/*win_x64.zip artifacts/dbgate-windows-latest.zip || true
|
||||
cp app/dist/*win_arm64.zip artifacts/dbgate-windows-latest-arm64.zip || true
|
||||
cp app/dist/*win_arm64.exe artifacts/dbgate-windows-latest-arm64.exe || true
|
||||
cp app/dist/*-mac_universal.dmg artifacts/dbgate-latest.dmg || true
|
||||
cp app/dist/*-mac_x64.dmg artifacts/dbgate-latest-x64.dmg || true
|
||||
cp app/dist/*-mac_arm64.dmg artifacts/dbgate-latest-arm64.dmg || true
|
||||
@@ -114,16 +145,16 @@ jobs:
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: '${{ matrix.os }}'
|
||||
name: ${{ matrix.os }}
|
||||
path: artifacts
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: 'startsWith(github.ref, ''refs/tags/'')'
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
files: artifacts/**
|
||||
prerelease: false
|
||||
env:
|
||||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Print content of notarization-error.log
|
||||
if: failure() && matrix.os == 'macos-14'
|
||||
run: |
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# This file is generated. Do not edit manually
|
||||
# --------------------------------------------------------------------------------------------
|
||||
name: AWS image PREMIUM
|
||||
name: Cloud images PREMIUM
|
||||
'on':
|
||||
push:
|
||||
tags:
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+-packer-beta.[0-9]+'
|
||||
- v[0-9]+.[0-9]+.[0-9]+
|
||||
- v[0-9]+.[0-9]+.[0-9]+-packer-beta.[0-9]+
|
||||
jobs:
|
||||
build:
|
||||
runs-on: '${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
@@ -17,15 +17,18 @@ jobs:
|
||||
steps:
|
||||
- name: Context
|
||||
env:
|
||||
GITHUB_CONTEXT: '${{ toJson(github) }}'
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: Use Node.js 18.x
|
||||
- name: Use Node.js 22.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 18.x
|
||||
node-version: 22.x
|
||||
- name: Install jq
|
||||
run: |
|
||||
sudo apt-get install jq -y
|
||||
- name: Setup `packer`
|
||||
uses: hashicorp/setup-packer@main
|
||||
with:
|
||||
@@ -34,9 +37,9 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: '${{ secrets.GH_TOKEN }}'
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: a2f824dc711b510a5e8235d3faf4aafab1965184
|
||||
ref: f27a03d4aff5b00a009643df146a9c17bdbf7801
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
@@ -63,13 +66,6 @@ jobs:
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
yarn setCurrentVersion
|
||||
- name: printSecrets
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
yarn printSecrets
|
||||
env:
|
||||
GIST_UPLOAD_SECRET: '${{secrets.GIST_UPLOAD_SECRET}}'
|
||||
- name: Prepare packer build
|
||||
run: |
|
||||
cd ..
|
||||
@@ -84,41 +80,56 @@ jobs:
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: '${{ matrix.os }}'
|
||||
name: ${{ matrix.os }}
|
||||
path: artifacts
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: 'startsWith(github.ref, ''refs/tags/'')'
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
files: artifacts/**
|
||||
prerelease: true
|
||||
env:
|
||||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||
- name: Run `packer init`
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run `packer init` for Azure
|
||||
run: |
|
||||
cd ../dbgate-merged/packer
|
||||
packer init ./azure-ubuntu.pkr.hcl
|
||||
- name: Run `packer build` for Azure
|
||||
run: |
|
||||
cd ../dbgate-merged/packer
|
||||
packer build ./azure-ubuntu.pkr.hcl
|
||||
- name: Run `packer init` for AWS
|
||||
run: |
|
||||
cd ../dbgate-merged/packer
|
||||
packer init ./aws-ubuntu.pkr.hcl
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: '${{secrets.AWS_ACCESS_KEY_ID}}'
|
||||
AWS_SECRET_ACCESS_KEY: '${{secrets.AWS_SECRET_ACCESS_KEY}}'
|
||||
AWS_DEFAULT_REGION: '${{secrets.AWS_DEFAULT_REGION}}'
|
||||
- name: Run `packer build`
|
||||
AWS_ACCESS_KEY_ID: ${{secrets.AWS_ACCESS_KEY_ID}}
|
||||
AWS_SECRET_ACCESS_KEY: ${{secrets.AWS_SECRET_ACCESS_KEY}}
|
||||
AWS_DEFAULT_REGION: ${{secrets.AWS_DEFAULT_REGION}}
|
||||
- name: Run `packer build` for AWS
|
||||
run: |
|
||||
cd ../dbgate-merged/packer
|
||||
packer build ./aws-ubuntu.pkr.hcl
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: '${{secrets.AWS_ACCESS_KEY_ID}}'
|
||||
AWS_SECRET_ACCESS_KEY: '${{secrets.AWS_SECRET_ACCESS_KEY}}'
|
||||
AWS_DEFAULT_REGION: '${{secrets.AWS_DEFAULT_REGION}}'
|
||||
- name: Install jq
|
||||
AWS_ACCESS_KEY_ID: ${{secrets.AWS_ACCESS_KEY_ID}}
|
||||
AWS_SECRET_ACCESS_KEY: ${{secrets.AWS_SECRET_ACCESS_KEY}}
|
||||
AWS_DEFAULT_REGION: ${{secrets.AWS_DEFAULT_REGION}}
|
||||
- name: Delete old Azure VMs
|
||||
run: |
|
||||
sudo apt-get install jq -y
|
||||
- name: Delete old AMIs
|
||||
cd ../dbgate-merged/packer
|
||||
chmod +x delete-old-azure-images.sh
|
||||
./delete-old-azure-images.sh
|
||||
env:
|
||||
AZURE_CLIENT_ID: ${{secrets.AZURE_CLIENT_ID}}
|
||||
AZURE_CLIENT_SECRET: ${{secrets.AZURE_CLIENT_SECRET}}
|
||||
AZURE_TENANT_ID: ${{secrets.AZURE_TENANT_ID}}
|
||||
AZURE_SUBSCRIPTION_ID: ${{secrets.AZURE_SUBSCRIPTION_ID}}
|
||||
- name: Delete old AMIs (AWS)
|
||||
run: |
|
||||
cd ../dbgate-merged/packer
|
||||
chmod +x delete-old-amis.sh
|
||||
./delete-old-amis.sh
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: '${{secrets.AWS_ACCESS_KEY_ID}}'
|
||||
AWS_SECRET_ACCESS_KEY: '${{secrets.AWS_SECRET_ACCESS_KEY}}'
|
||||
AWS_DEFAULT_REGION: '${{secrets.AWS_DEFAULT_REGION}}'
|
||||
AWS_ACCESS_KEY_ID: ${{secrets.AWS_ACCESS_KEY_ID}}
|
||||
AWS_SECRET_ACCESS_KEY: ${{secrets.AWS_SECRET_ACCESS_KEY}}
|
||||
AWS_DEFAULT_REGION: ${{secrets.AWS_DEFAULT_REGION}}
|
||||
@@ -5,11 +5,11 @@ name: Docker image PREMIUM
|
||||
'on':
|
||||
push:
|
||||
tags:
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+-premium-beta.[0-9]+'
|
||||
- v[0-9]+.[0-9]+.[0-9]+
|
||||
- v[0-9]+.[0-9]+.[0-9]+-premium-beta.[0-9]+
|
||||
jobs:
|
||||
build:
|
||||
runs-on: '${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
steps:
|
||||
- name: Context
|
||||
env:
|
||||
GITHUB_CONTEXT: '${{ toJson(github) }}'
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
@@ -34,17 +34,17 @@ jobs:
|
||||
|
||||
type=match,pattern=\d+.\d+.\d+,enable=${{ !contains(github.ref_name, '-docker.') && !contains(github.ref_name, '-beta.') }}
|
||||
type=raw,value=latest,enable=${{ !contains(github.ref_name, '-docker.') && !contains(github.ref_name, '-beta.') }}
|
||||
- name: Use Node.js 18.x
|
||||
- name: Use Node.js 22.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 18.x
|
||||
node-version: 22.x
|
||||
- name: Checkout dbgate/dbgate-pro
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: '${{ secrets.GH_TOKEN }}'
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: a2f824dc711b510a5e8235d3faf4aafab1965184
|
||||
ref: f27a03d4aff5b00a009643df146a9c17bdbf7801
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
@@ -76,31 +76,25 @@ jobs:
|
||||
cd dbgate-merged
|
||||
|
||||
yarn setCurrentVersion
|
||||
- name: printSecrets
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
|
||||
yarn printSecrets
|
||||
env:
|
||||
GIST_UPLOAD_SECRET: '${{secrets.GIST_UPLOAD_SECRET}}'
|
||||
- name: Prepare docker image
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
|
||||
yarn run prepare:docker
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: '${{ secrets.DOCKER_USERNAME }}'
|
||||
password: '${{ secrets.DOCKER_PASSWORD }}'
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
push: true
|
||||
context: ../dbgate-merged/docker
|
||||
tags: '${{ steps.meta.outputs.tags }}'
|
||||
platforms: 'linux/amd64,linux/arm64'
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
platforms: linux/amd64,linux/arm64
|
||||
|
||||
@@ -5,11 +5,11 @@ name: Docker image Community
|
||||
'on':
|
||||
push:
|
||||
tags:
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+-beta.[0-9]+'
|
||||
- v[0-9]+.[0-9]+.[0-9]+
|
||||
- v[0-9]+.[0-9]+.[0-9]+-beta.[0-9]+
|
||||
jobs:
|
||||
build:
|
||||
runs-on: '${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
steps:
|
||||
- name: Context
|
||||
env:
|
||||
GITHUB_CONTEXT: '${{ toJson(github) }}'
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
@@ -47,10 +47,10 @@ jobs:
|
||||
|
||||
type=match,pattern=\d+.\d+.\d+,suffix=-alpine,enable=${{ !contains(github.ref_name, '-docker.') && !contains(github.ref_name, '-beta.') }}
|
||||
type=raw,value=alpine,enable=${{ !contains(github.ref_name, '-docker.') && !contains(github.ref_name, '-beta.') }}
|
||||
- name: Use Node.js 18.x
|
||||
- name: Use Node.js 22.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 18.x
|
||||
node-version: 22.x
|
||||
- name: adjustPackageJson
|
||||
run: |
|
||||
|
||||
@@ -65,35 +65,31 @@ jobs:
|
||||
run: |
|
||||
|
||||
yarn setCurrentVersion
|
||||
- name: printSecrets
|
||||
run: |
|
||||
|
||||
yarn printSecrets
|
||||
env:
|
||||
GIST_UPLOAD_SECRET: '${{secrets.GIST_UPLOAD_SECRET}}'
|
||||
- name: Prepare docker image
|
||||
run: |
|
||||
|
||||
yarn run prepare:docker
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: '${{ secrets.DOCKER_USERNAME }}'
|
||||
password: '${{ secrets.DOCKER_PASSWORD }}'
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
push: true
|
||||
context: ./docker
|
||||
tags: '${{ steps.meta.outputs.tags }}'
|
||||
platforms: 'linux/amd64,linux/arm64,linux/arm/v7'
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
- name: Build and push alpine
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
push: true
|
||||
context: ./docker
|
||||
file: ./docker/Dockerfile-alpine
|
||||
tags: '${{ steps.alpmeta.outputs.tags }}'
|
||||
platforms: 'linux/amd64,linux/arm64,linux/arm/v7'
|
||||
tags: ${{ steps.alpmeta.outputs.tags }}
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
|
||||
@@ -5,11 +5,14 @@ name: NPM packages PREMIUM
|
||||
'on':
|
||||
push:
|
||||
tags:
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+-alpha.[0-9]+'
|
||||
- v[0-9]+.[0-9]+.[0-9]+
|
||||
- v[0-9]+.[0-9]+.[0-9]+-alpha.[0-9]+
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: write
|
||||
jobs:
|
||||
build:
|
||||
runs-on: '${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
@@ -17,22 +20,22 @@ jobs:
|
||||
steps:
|
||||
- name: Context
|
||||
env:
|
||||
GITHUB_CONTEXT: '${{ toJson(github) }}'
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: Use Node.js 18.x
|
||||
- name: Use Node.js 22.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 18.x
|
||||
node-version: 22.x
|
||||
- name: Checkout dbgate/dbgate-pro
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: '${{ secrets.GH_TOKEN }}'
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: a2f824dc711b510a5e8235d3faf4aafab1965184
|
||||
ref: f27a03d4aff5b00a009643df146a9c17bdbf7801
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
@@ -49,13 +52,8 @@ jobs:
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
node adjustNpmPackageJsonPremium
|
||||
- name: Configure NPM token
|
||||
env:
|
||||
NPM_TOKEN: '${{ secrets.NPM_TOKEN }}'
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
npm config set '//registry.npmjs.org/:_authToken' "${NPM_TOKEN}"
|
||||
- name: Update npm
|
||||
run: npm install -g npm@latest
|
||||
- name: Remove dbmodel - should be not published
|
||||
run: |
|
||||
cd ..
|
||||
@@ -71,30 +69,35 @@ jobs:
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
yarn setCurrentVersion
|
||||
- name: printSecrets
|
||||
- name: Compute npm dist-tag
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged
|
||||
yarn printSecrets
|
||||
env:
|
||||
GIST_UPLOAD_SECRET: '${{secrets.GIST_UPLOAD_SECRET}}'
|
||||
if [[ "${GITHUB_REF_NAME}" =~ -alpha\. ]]; then
|
||||
echo "NPM_TAG=alpha" >> $GITHUB_ENV
|
||||
else
|
||||
echo "NPM_TAG=latest" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Publish dbgate-api-premium
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged/packages/api
|
||||
npm publish
|
||||
npm publish --tag "$NPM_TAG"
|
||||
- name: Publish dbgate-web-premium
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged/packages/web
|
||||
npm publish
|
||||
npm publish --tag "$NPM_TAG"
|
||||
- name: Publish dbgate-serve-premium
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged/packages/serve
|
||||
npm publish
|
||||
npm publish --tag "$NPM_TAG"
|
||||
- name: Publish dbgate-plugin-cosmosdb
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged/plugins/dbgate-plugin-cosmosdb
|
||||
npm publish
|
||||
npm publish --tag "$NPM_TAG"
|
||||
- name: Publish dbgate-plugin-firestore
|
||||
run: |
|
||||
cd ..
|
||||
cd dbgate-merged/plugins/dbgate-plugin-firestore
|
||||
npm publish --tag "$NPM_TAG"
|
||||
|
||||
@@ -5,11 +5,14 @@ name: NPM packages
|
||||
'on':
|
||||
push:
|
||||
tags:
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+-alpha.[0-9]+'
|
||||
- v[0-9]+.[0-9]+.[0-9]+
|
||||
- v[0-9]+.[0-9]+.[0-9]+-alpha.[0-9]+
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: write
|
||||
jobs:
|
||||
build:
|
||||
runs-on: '${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
@@ -17,109 +20,116 @@ jobs:
|
||||
steps:
|
||||
- name: Context
|
||||
env:
|
||||
GITHUB_CONTEXT: '${{ toJson(github) }}'
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: Use Node.js 18.x
|
||||
- name: Use Node.js 22.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 18.x
|
||||
- name: Configure NPM token
|
||||
env:
|
||||
NPM_TOKEN: '${{ secrets.NPM_TOKEN }}'
|
||||
run: |
|
||||
npm config set '//registry.npmjs.org/:_authToken' "${NPM_TOKEN}"
|
||||
node-version: 22.x
|
||||
- name: Update npm
|
||||
run: npm install -g npm@latest
|
||||
- name: yarn install
|
||||
run: |
|
||||
yarn install
|
||||
- name: setCurrentVersion
|
||||
run: |
|
||||
yarn setCurrentVersion
|
||||
- name: printSecrets
|
||||
- name: Compute npm dist-tag
|
||||
run: |
|
||||
yarn printSecrets
|
||||
env:
|
||||
GIST_UPLOAD_SECRET: '${{secrets.GIST_UPLOAD_SECRET}}'
|
||||
if [[ "${GITHUB_REF_NAME}" =~ -alpha\. ]]; then
|
||||
echo "NPM_TAG=alpha" >> $GITHUB_ENV
|
||||
else
|
||||
echo "NPM_TAG=latest" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Publish types
|
||||
working-directory: packages/types
|
||||
run: |
|
||||
npm publish
|
||||
npm publish --tag "$NPM_TAG"
|
||||
- name: Publish tools
|
||||
working-directory: packages/tools
|
||||
run: |
|
||||
npm publish
|
||||
npm publish --tag "$NPM_TAG"
|
||||
- name: Publish sqltree
|
||||
working-directory: packages/sqltree
|
||||
run: |
|
||||
npm publish
|
||||
npm publish --tag "$NPM_TAG"
|
||||
|
||||
- name: Publish api
|
||||
working-directory: packages/api
|
||||
run: |
|
||||
npm publish
|
||||
npm publish --tag "$NPM_TAG"
|
||||
- name: Publish datalib
|
||||
working-directory: packages/datalib
|
||||
run: |
|
||||
npm publish
|
||||
npm publish --tag "$NPM_TAG"
|
||||
- name: Publish filterparser
|
||||
working-directory: packages/filterparser
|
||||
run: |
|
||||
npm publish
|
||||
npm publish --tag "$NPM_TAG"
|
||||
- name: Publish web
|
||||
working-directory: packages/web
|
||||
run: |
|
||||
npm publish
|
||||
npm publish --tag "$NPM_TAG"
|
||||
- name: Publish dbgate-serve
|
||||
working-directory: packages/serve
|
||||
run: |
|
||||
npm publish
|
||||
npm publish --tag "$NPM_TAG"
|
||||
- name: Publish dbmodel
|
||||
working-directory: packages/dbmodel
|
||||
run: |
|
||||
npm publish
|
||||
npm publish --tag "$NPM_TAG"
|
||||
- name: Publish dbgate-plugin-csv
|
||||
working-directory: plugins/dbgate-plugin-csv
|
||||
run: |
|
||||
npm publish
|
||||
npm publish --tag "$NPM_TAG"
|
||||
- name: Publish dbgate-plugin-xml
|
||||
working-directory: plugins/dbgate-plugin-xml
|
||||
run: |
|
||||
npm publish
|
||||
npm publish --tag "$NPM_TAG"
|
||||
- name: Publish dbgate-plugin-excel
|
||||
working-directory: plugins/dbgate-plugin-excel
|
||||
run: |
|
||||
npm publish
|
||||
npm publish --tag "$NPM_TAG"
|
||||
- name: Publish dbgate-plugin-mssql
|
||||
working-directory: plugins/dbgate-plugin-mssql
|
||||
run: |
|
||||
npm publish
|
||||
npm publish --tag "$NPM_TAG"
|
||||
- name: Publish dbgate-plugin-mysql
|
||||
working-directory: plugins/dbgate-plugin-mysql
|
||||
run: |
|
||||
npm publish
|
||||
npm publish --tag "$NPM_TAG"
|
||||
- name: Publish dbgate-plugin-mongo
|
||||
working-directory: plugins/dbgate-plugin-mongo
|
||||
run: |
|
||||
npm publish
|
||||
npm publish --tag "$NPM_TAG"
|
||||
- name: Publish dbgate-plugin-postgres
|
||||
working-directory: plugins/dbgate-plugin-postgres
|
||||
run: |
|
||||
npm publish
|
||||
npm publish --tag "$NPM_TAG"
|
||||
- name: Publish dbgate-plugin-sqlite
|
||||
working-directory: plugins/dbgate-plugin-sqlite
|
||||
run: |
|
||||
npm publish
|
||||
npm publish --tag "$NPM_TAG"
|
||||
- name: Publish dbgate-plugin-redis
|
||||
working-directory: plugins/dbgate-plugin-redis
|
||||
run: |
|
||||
npm publish
|
||||
npm publish --tag "$NPM_TAG"
|
||||
- name: Publish dbgate-plugin-oracle
|
||||
working-directory: plugins/dbgate-plugin-oracle
|
||||
run: |
|
||||
npm publish
|
||||
npm publish --tag "$NPM_TAG"
|
||||
- name: Publish dbgate-plugin-clickhouse
|
||||
working-directory: plugins/dbgate-plugin-clickhouse
|
||||
run: |
|
||||
npm publish
|
||||
npm publish --tag "$NPM_TAG"
|
||||
- name: Publish dbgate-plugin-dbf
|
||||
working-directory: plugins/dbgate-plugin-dbf
|
||||
run: |
|
||||
npm publish --tag "$NPM_TAG"
|
||||
- name: Publish dbgate-plugin-cassandra
|
||||
working-directory: plugins/dbgate-plugin-cassandra
|
||||
run: |
|
||||
npm publish --tag "$NPM_TAG"
|
||||
|
||||
@@ -30,8 +30,8 @@ jobs:
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: '${{ github.actor }}'
|
||||
password: '${{ secrets.GITHUB_TOKEN }}'
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Push mysql-ssh-login to GHCR
|
||||
run: |
|
||||
docker tag dbgate/mysql-ssh-login:latest ghcr.io/dbgate/mysql-ssh-login:latest
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# This file is generated. Do not edit manually
|
||||
# --------------------------------------------------------------------------------------------
|
||||
name: Diflow merge
|
||||
'on':
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
jobs:
|
||||
merge:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Use Node.js 22.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 22.x
|
||||
- name: Checkout dbgate/diflow
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: dbgate/diflow
|
||||
path: diflow
|
||||
- name: Diflow install
|
||||
run: |
|
||||
cd diflow
|
||||
npm install
|
||||
npm run build
|
||||
- name: Git config
|
||||
run: |
|
||||
git config --global user.email "info@dbgate.io"
|
||||
git config --global user.name "Diflow"
|
||||
- name: Diflow run
|
||||
run: |
|
||||
cd diflow
|
||||
node dist/diflow.js sync -r https://DIFLOW_GIT_SECRET@github.com/dbgate/dbgate-diflow-config.git -b master
|
||||
env:
|
||||
DIFLOW_GIT_SECRET: ${{ secrets.DIFLOW_GIT_SECRET }}
|
||||
@@ -13,10 +13,10 @@ jobs:
|
||||
e2e-tests:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Use Node.js 18.x
|
||||
- name: Use Node.js 22.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 18.x
|
||||
node-version: 22.x
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 1
|
||||
@@ -24,9 +24,9 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: '${{ secrets.GH_TOKEN }}'
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: a2f824dc711b510a5e8235d3faf4aafab1965184
|
||||
ref: f27a03d4aff5b00a009643df146a9c17bdbf7801
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
@@ -69,6 +69,17 @@ jobs:
|
||||
with:
|
||||
name: screenshots
|
||||
path: screenshots
|
||||
- name: Push E2E screenshots
|
||||
if: ${{ github.ref_name == 'master' }}
|
||||
run: |
|
||||
git config --global user.email "info@dbgate.info"
|
||||
git config --global user.name "GitHub Actions"
|
||||
git clone https://${{ secrets.DIFLOW_GIT_SECRET }}@github.com/dbgate/dbgate-img.git
|
||||
cp ../dbgate-merged/e2e-tests/screenshots/*.png dbgate-img/static/img
|
||||
cd dbgate-img/static/img
|
||||
git add .
|
||||
git commit --amend --no-edit
|
||||
git push --force
|
||||
services:
|
||||
postgres-cypress:
|
||||
image: postgres
|
||||
@@ -78,25 +89,25 @@ jobs:
|
||||
ports:
|
||||
- '16000:5432'
|
||||
mysql-cypress:
|
||||
image: 'mysql:8.0.18'
|
||||
image: mysql:8.0.18
|
||||
ports:
|
||||
- '16004:3306'
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: Pwd2020Db
|
||||
mysql-ssh-login:
|
||||
image: 'ghcr.io/dbgate/mysql-ssh-login:latest'
|
||||
image: ghcr.io/dbgate/mysql-ssh-login:latest
|
||||
ports:
|
||||
- '16012:22'
|
||||
mysql-ssh-keyfile:
|
||||
image: 'ghcr.io/dbgate/mysql-ssh-keyfile:latest'
|
||||
image: ghcr.io/dbgate/mysql-ssh-keyfile:latest
|
||||
ports:
|
||||
- '16008:22'
|
||||
dex:
|
||||
image: 'ghcr.io/dbgate/dex:latest'
|
||||
image: ghcr.io/dbgate/dex:latest
|
||||
ports:
|
||||
- '16009:5556'
|
||||
mongo:
|
||||
image: 'mongo:4.0.12'
|
||||
image: mongo:4.4.29
|
||||
env:
|
||||
MONGO_INITDB_ROOT_USERNAME: root
|
||||
MONGO_INITDB_ROOT_PASSWORD: Pwd2020Db
|
||||
@@ -106,3 +117,17 @@ jobs:
|
||||
image: redis
|
||||
ports:
|
||||
- '16011:6379'
|
||||
mssql:
|
||||
image: mcr.microsoft.com/mssql/server
|
||||
ports:
|
||||
- '16014:1433'
|
||||
env:
|
||||
ACCEPT_EULA: 'Y'
|
||||
SA_PASSWORD: Pwd2020Db
|
||||
MSSQL_PID: Express
|
||||
oracle:
|
||||
image: gvenzl/oracle-xe:21-slim
|
||||
env:
|
||||
ORACLE_PASSWORD: Pwd2020Db
|
||||
ports:
|
||||
- '16013:1521'
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# This file is generated. Do not edit manually
|
||||
# --------------------------------------------------------------------------------------------
|
||||
name: Update Workflows
|
||||
'on':
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- workflow-templates/**
|
||||
jobs:
|
||||
update-workflows:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
token: ${{ secrets.WORKFLOW_CHANGE_ACCESS_TOKEN }}
|
||||
- name: git pull
|
||||
run: |
|
||||
git pull
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 22
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
rm package.json
|
||||
rm yarn.lock
|
||||
yarn add -W js-yaml lodash
|
||||
- name: Run workflow generation
|
||||
run: |
|
||||
node common/processWorkflows.js
|
||||
- name: Git config
|
||||
run: |
|
||||
git config --global user.email "info@dbgate.io"
|
||||
git config --global user.name "CI workflows"
|
||||
- name: Commit changes
|
||||
run: |
|
||||
# Only commit if there are changes
|
||||
if [[ -n "$(git status --porcelain)" ]]; then
|
||||
git add .github/workflows
|
||||
git commit -m "chore: auto-update github workflows"
|
||||
else
|
||||
echo "No changes to commit"
|
||||
fi
|
||||
- name: Push changes
|
||||
uses: ad-m/github-push-action@v0.6.0
|
||||
with:
|
||||
github_token: ${{ secrets.WORKFLOW_CHANGE_ACCESS_TOKEN }}
|
||||
branch: master
|
||||
@@ -13,10 +13,10 @@ jobs:
|
||||
all-tests:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Use Node.js 18.x
|
||||
- name: Use Node.js 22.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 18.x
|
||||
node-version: 22.x
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 1
|
||||
@@ -37,22 +37,27 @@ jobs:
|
||||
run: |
|
||||
cd packages/datalib
|
||||
yarn test:ci
|
||||
- name: Tools tests
|
||||
if: always()
|
||||
run: |
|
||||
cd packages/tools
|
||||
yarn test:ci
|
||||
- uses: tanmen/jest-reporter@v1
|
||||
if: always()
|
||||
with:
|
||||
github-token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
result-file: integration-tests/result.json
|
||||
action-name: Integration tests
|
||||
- uses: tanmen/jest-reporter@v1
|
||||
if: always()
|
||||
with:
|
||||
github-token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
result-file: packages/filterparser/result.json
|
||||
action-name: Filter parser test results
|
||||
- uses: tanmen/jest-reporter@v1
|
||||
if: always()
|
||||
with:
|
||||
github-token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
result-file: packages/datalib/result.json
|
||||
action-name: Datalib (perspectives) test results
|
||||
services:
|
||||
@@ -64,7 +69,7 @@ jobs:
|
||||
ports:
|
||||
- '15000:5432'
|
||||
mysql-integr:
|
||||
image: 'mysql:8.0.18'
|
||||
image: mysql:8.0.18
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: Pwd2020Db
|
||||
ports:
|
||||
@@ -78,14 +83,33 @@ jobs:
|
||||
ports:
|
||||
- '15002:1433'
|
||||
clickhouse-integr:
|
||||
image: 'bitnami/clickhouse:24.8.4'
|
||||
image: bitnamilegacy/clickhouse:24.8.4
|
||||
env:
|
||||
CLICKHOUSE_ADMIN_PASSWORD: Pwd2020Db
|
||||
ports:
|
||||
- '15005:8123'
|
||||
oracle-integr:
|
||||
image: 'gvenzl/oracle-xe:21-slim'
|
||||
image: gvenzl/oracle-xe:21-slim
|
||||
env:
|
||||
ORACLE_PASSWORD: Pwd2020Db
|
||||
ports:
|
||||
- '15006:1521'
|
||||
cassandradb:
|
||||
image: cassandra:5.0.2
|
||||
ports:
|
||||
- '15942:9042'
|
||||
libsql:
|
||||
image: ghcr.io/tursodatabase/libsql-server:latest
|
||||
ports:
|
||||
- '8080:8080'
|
||||
firebird:
|
||||
image: firebirdsql/firebird:latest
|
||||
env:
|
||||
FIREBIRD_DATABASE: mydatabase.fdb
|
||||
FIREBIRD_USER: dbuser
|
||||
FIREBIRD_PASSWORD: dbpassword
|
||||
ISC_PASSWORD: masterkey
|
||||
FIREBIRD_TRACE: false
|
||||
FIREBIRD_USE_LEGACY_AUTH: true
|
||||
ports:
|
||||
- '3050:3050'
|
||||
|
||||
+3
-1
@@ -32,4 +32,6 @@ packages/api/src/packagedPluginsContent.js
|
||||
.VSCodeCounter
|
||||
|
||||
packages/web/public/*.html
|
||||
e2e-tests/screenshots/*.png
|
||||
e2e-tests/screenshots/*.png
|
||||
my_guitar_shop.db
|
||||
.aider*
|
||||
|
||||
Vendored
+40
-19
@@ -1,20 +1,41 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Launch API",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${workspaceFolder}/packages/api/src/index.js",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Debug App",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/packages/api/src/index.js",
|
||||
"envFile": "${workspaceFolder}/packages/api/.env",
|
||||
"args": ["--listen-api"],
|
||||
"console": "integratedTerminal",
|
||||
"restart": true,
|
||||
"runtimeExecutable": "node",
|
||||
"skipFiles": ["<node_internals>/**"]
|
||||
},
|
||||
{
|
||||
"name": "Debug App (Break on Start)",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/packages/api/src/index.js",
|
||||
"args": ["--listen-api"],
|
||||
"envFile": "${workspaceFolder}/.env",
|
||||
"console": "integratedTerminal",
|
||||
"restart": true,
|
||||
"runtimeExecutable": "node",
|
||||
"skipFiles": ["<node_internals>/**"],
|
||||
"stopOnEntry": true
|
||||
},
|
||||
{
|
||||
"name": "Attach to Process",
|
||||
"type": "node",
|
||||
"request": "attach",
|
||||
"port": 9229,
|
||||
"restart": true,
|
||||
"localRoot": "${workspaceFolder}",
|
||||
"remoteRoot": "${workspaceFolder}",
|
||||
"skipFiles": ["<node_internals>/**"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
+218
-1
@@ -8,6 +8,223 @@ Builds:
|
||||
- linux - application for linux
|
||||
- win - application for Windows
|
||||
|
||||
## 6.6.11
|
||||
- FIXED: Fixed theming on application startup
|
||||
- CHANGED: Improved licensing page
|
||||
|
||||
## 6.6.10
|
||||
- FIXED: License from environment variable is not refreshed #1245
|
||||
- FIXED: connection closing / reconnecting #1237
|
||||
- ADDED: retain history across multiple queries #1236
|
||||
- ADDED: load CSVs to temp tables #1235
|
||||
- FIXED: Not possible to scroll the data view horizontally by pressing shift and scroll mouse middle button on Mac #453
|
||||
- FIXED: Expired trial workflow (Premium)
|
||||
- ADDED: Column name collision resolving #1234 (MySQL)
|
||||
|
||||
## 6.6.8
|
||||
- CHANGED: Windows executable now uses Azure trusted signing certificate
|
||||
- CHANGED: NPM packages now use GitHub OIDC provenance signing for better security
|
||||
- CHANGED: Some features moved to Premium edition (master/detail views, FK lookups, column expansion, split view, advanced export/import, data archives, grouping, macros)
|
||||
|
||||
## 6.6.6
|
||||
- ADDED: Allow disable/re-enable filter #1174
|
||||
- ADDED: Close right side tabs #1219
|
||||
- ADDED: Ability disable execute current line in query editor #1209
|
||||
- ADDED: Support for Redis Cluster #1204 (Premium)
|
||||
|
||||
## 6.6.5
|
||||
- ADDED: SQL AI assistant - powered by database chat, could help you to write SQL queries (Premium)
|
||||
- ADDED: Explain SQL error (powered by AI) (Premium)
|
||||
- ADDED: Database chat (and SQL AI Assistant) now supports showing charts (Premium)
|
||||
- FIXED: Fxied editing new files and roles (Team Premium)
|
||||
- FIXED: Connection to standalone database could be now pinned
|
||||
- FIXED: Cannot open up large JSON file #1215
|
||||
|
||||
## 6.6.4
|
||||
- ADDED: AI Database chat now supports much more LLM models. (Premium)
|
||||
- ADDED: Possibility to use your own API key with OPENAI-compatible providers (OpenRouter, Antropic...)
|
||||
- ADDED: Possibility to use self-hosted own LLM (eg. Llama)
|
||||
- ADDED: Team files - save SQL files and define shared charts, assign roles and users to these objects (Team Premium)
|
||||
- FIXED: BUG: does no longer work with Cockroach DB #1202
|
||||
- FIXED: DbGate Web UI Connections do not display 'Databases' #1199
|
||||
- CHANGED: Redesign fof applications. Applications are now storted in single JSON file
|
||||
- ADDED: Application editor (Premium)
|
||||
- ADDED: Posibility to filter only tables with rows
|
||||
- FIXED: Fixed several issues with large Firebird databases
|
||||
- CHANGED: Community edition now supports shared folders in read-only mode
|
||||
|
||||
## 6.6.3
|
||||
- FIXED: Error “db.getCollection(…).renameCollection is not a function” when renaming collection in dbGate #1198
|
||||
- FIXED: Can't list databases from Azure SQL SERVER #1197
|
||||
- ADDED: Save zoom level in electron apps
|
||||
|
||||
## 6.6.2
|
||||
- ADDED: List of processes, ability to kill process (Server summary) #1178
|
||||
- ADDED: Database and table permissions (Team Premium edition)
|
||||
- ADDED: Redis search box - Scan all #1191
|
||||
- FIXED: Optimalized loading SQL server with descriptions #1187
|
||||
- CHANGED: Allow a much greater page size #1185
|
||||
- FIXED: Optimalized loading SQL server with descriptions #1187
|
||||
- FIXED: Executing queries for SQLite crash #1195
|
||||
|
||||
## 6.6.1
|
||||
- ADDED: Support for Mongo shell (Premium) - #1114
|
||||
- FIXED: Support for BLOB in Oracle #1181
|
||||
- ADDED: Connect to named SQL Server instance #340
|
||||
- ADDED: Support for SQL Server descriptions #1137
|
||||
- ADDED: Application log viewer
|
||||
- FIXED: Selecting default database in connection dialog
|
||||
- CHANGED: Improved logging system, added related database and connection to logs metadata
|
||||
|
||||
## 6.6.0
|
||||
- ADDED: Database chat - AI powered chatbot, which knows your database (Premium)
|
||||
- ADDED: Firestore support (Premium)
|
||||
- REMOVED: Query AI assistant (replaced by Database Chat) (Premium)
|
||||
- FIXED: Chart permissions were ignored (Premium)
|
||||
|
||||
## 6.5.6
|
||||
- ADDED: New object window - quick access to most common functions
|
||||
- ADDED: Possibility to disable split query by empty line #1162
|
||||
- ADDED: Possibility to opt out authentication #1152
|
||||
- FIXED: Separate schema mode now works in Team Premium edition
|
||||
- FIXED: Handled situation, when user enters expired license, which is already prolonged
|
||||
- FIXED: Fixed some minor problems of charts
|
||||
|
||||
## 6.5.5
|
||||
- ADDED: Administer cloud folder window
|
||||
- CHANGED: Cloud menu redesign
|
||||
- ADDED: Audit log (for Team Premium edition)
|
||||
- ADDED: Added new timeline chart type (line chart with time axis)
|
||||
- ADDED: Chart grouping (more measure determined from data)
|
||||
- CHANGED: Improved chart autodetection - string X axis (with bar type), COUNT as measure, split different measures
|
||||
- ADDED: Added chart data type detection
|
||||
- FIXED: Fixed chart displaying problems
|
||||
- FIXED: Fixed exporting chart to HTML
|
||||
- CHANGED: Choose COUNT measure without selecting underlying ID field (use virtual __count)
|
||||
- FIXED: Problems with authentification administration, especially for Postgres storage
|
||||
- CHANGED: Anonymous autentification (in Team Premium) is now by default disabled
|
||||
|
||||
## 6.5.3
|
||||
- CHANGED: Improved DbGate Cloud sign-in workflow
|
||||
- FIXED: Some fixes and error handling in new charts engine
|
||||
- ADDED: Charts - ability to choose aggregate function
|
||||
- CHANGED: Improved About window
|
||||
|
||||
## 6.5.2
|
||||
- CHANGED: Autodetecting charts is disabled by default #1145
|
||||
- CHANGED: Improved chart displaying workflow
|
||||
- ADDED: Ability to close chart
|
||||
|
||||
## 6.5.1
|
||||
- FIXED: DbGate Cloud e-mail sign-in method for desktop clients
|
||||
|
||||
## 6.5.0
|
||||
- ADDED: DbGate cloud - online storage for connections, SQL scripts and other objects
|
||||
- ADDED: Public knowledge base - common SQL scripts for specific DB engines (table sizes, index stats etc.)
|
||||
- ADDED: Query results could be visualised in charts (Premium)
|
||||
- REMOVED: Chart from selection, active charts - replaced by query result charts
|
||||
- ADDED: FirebirdSQL support
|
||||
- ADDED: SQL front matter - properties of SQL script
|
||||
- ADDED: Auto-execute SQL script on open (saved in SQL front matter)
|
||||
- CHANGED: Smaller widget icon panel
|
||||
- CHANGED: Applications and Single-connection mode removed from widget icon panel
|
||||
- CHANGED: Temporarily disabled MongoDB profiler support
|
||||
- FIXED: Pie chart distorted if settings change #838
|
||||
- FIXED: SQL server generated insert statement should exclude computed and timestamp columns #1111
|
||||
- ADDED: Added option "Show all columns when searching" #1118
|
||||
- ADDED: Copy cells/rows (e.g. column names) from Structure view #1119
|
||||
- ADDED: Setting "Show table aliases in code completion" #1122
|
||||
- FIXED: Vulnerability - check file paths in web version
|
||||
- FIXED: Very slow render of tables with very log cells
|
||||
|
||||
## 6.4.2
|
||||
|
||||
- ADDED: Source label to docker container #1105
|
||||
- FIXED: DbGate restart needed to take effect after trigger is created/deleted on mariadb #1112
|
||||
- ADDED: View PostgreSQL query console output #1108
|
||||
- FIXED: Single quote generete MySql error #1107
|
||||
- ADDED: Ability to limit query result count #1098
|
||||
- CHANGED: Correct processing of bigint columns #1087 #1055 #583
|
||||
- CHANGED: Improved and optimalized algorithm of loading redis keys #1062, #1034
|
||||
- FIXED: Fixed loading Redis keys with :: in key name
|
||||
|
||||
## 6.4.0
|
||||
- ADDED: DuckDB support
|
||||
- ADDED: Data deployer (Premium)
|
||||
- ADDED: Compare data between JSON lines file in archive and database table
|
||||
- CHANGED: Data Duplicator => Data Replicator (suitable for update, create and delete data, much more customizable)
|
||||
- REMOVED: Data duplicator GUI (replaced with Data Deployer)
|
||||
- ADDED: Exporting to ZIP file
|
||||
- ADDED: Download SQL and SQLite files
|
||||
- ADDED: Upload SQLite files
|
||||
- ADDED: Upload archive as ZIP folder (Premium)
|
||||
- ADDED: Compress, uncompress archive folder (Premium)
|
||||
- ADDED: Export connections and settings #357
|
||||
- ADDED: Filtering by MongoDB ObjectId works now also without ObjectId(...) wrapper
|
||||
- ADDED: Split queries using blank lines #1089
|
||||
- FIXED: JSON-to-Grid only works if there is no newline #1085
|
||||
- CHANGED: When running multiple commands in script, stop execution after first error #1070
|
||||
- FIXED: Selection rectangle remains visible after closing JSONB edit cell value form #1031
|
||||
- FIXED: Diplaying numeric FK column with right alignement #1021
|
||||
- ADDED: Additional arguments for MySQL and PostgreSQL backup #1092
|
||||
- CHANGED: Amazon and Azure instalations are not auto-upgraded by default
|
||||
|
||||
## 6.3.3
|
||||
- CHANGED: New administration UI, redesigned administration of users, connections and roles
|
||||
- ADDED: Encrypting passwords in team-premium edition
|
||||
- ADDED: Show scale bar on map #1090
|
||||
- FIXED: Fixed native backup/restore for MySQL+PostgreSQL over SSH tunnel #1092
|
||||
- CHANGED: Column mapping dialog - fixes and improvements for copying from one existing table into another
|
||||
- ADDED: Search in columns in table editor
|
||||
- ADDED: Line Wrap for JSON viewer #768
|
||||
|
||||
### 6.3.2
|
||||
- ADDED: "Use system theme" switch, use changed system theme without restart #1084
|
||||
- ADDED: "Skip SETNAME instruction" option for Redis #1077
|
||||
- FIXED: Clickhouse views are now available even for user with limited permissions #1076
|
||||
- ADDED: Multiple-token search delimited with comma (=OR) in structure search boxes
|
||||
- CHANGED: When filtering columns in data browser, data view shows only filtered columns
|
||||
- ADDED: Advanced settings for diagrams (Premium)
|
||||
- ADDED: Diagrams - zoom with Ctrl+mouse wheel
|
||||
- FIXED: Scrollable diagram exports + scroll by mouse drag
|
||||
- FIXED: Fixed many problems in diagrams when zoom is applied
|
||||
- FIXED: Correctly end connection process after succesful/unsuccesful connect
|
||||
|
||||
### 6.3.0
|
||||
- ADDED: Support for libSQL and Turso (Premium)
|
||||
- ADDED: Native backup and restore database for MySQL and PostgreSQL (Premium)
|
||||
- REMOVED: DbGate internal dump export for MySQL (replaced with call of mysqldump)
|
||||
- REMOVED: Import SQL dump with internal DbGate capabilities (replaced by calling of mysql and psql utilities)
|
||||
- FIXED: Many fixes in stream processing (imoprt/export), especialy for MongoDB
|
||||
- ADDED: Indicating progress of import/export tasks, better error reporting
|
||||
- CHANGED: #1060 - Changed shortcut for AI assistant
|
||||
- ADDED: /health endpoint with diagnostic info
|
||||
- FIXED: Linux Appimage crash => A JavaScript error occurred in the main process #1065 , #1067
|
||||
|
||||
### 6.2.1
|
||||
- ADDED: Commit/rollback and autocommit in scripts #1039
|
||||
- FIXED: Doesn't import all the records from MongoDB #1044
|
||||
- ADDED: Show server name alongside database name in title of the tab group #1041
|
||||
- ADDED: Can't open Sqlite through web #956
|
||||
- FIXED: Crashed after text input at columns search #1049
|
||||
- FIXED: Incorrect autojoin for foreign keys with more columns #1051
|
||||
- FIXED: Scroll in XML cell view, XML view respect themes
|
||||
- REMOVED: armv7l build for Linux (because of problems with glibc compatibility)
|
||||
- CHANGED: Upgraded to node:22 for docker builds
|
||||
- CHANGED: Upgraded SQLite engine version
|
||||
|
||||
### 6.2.0
|
||||
- ADDED: Query AI Assistant (Premium)
|
||||
- ADDED: Cassandra database support
|
||||
- ADDED: XML cell data view
|
||||
- FIXED: Filtering by value in Oracle #1009
|
||||
- FIXED: Operand type clash: uniqueidentifier is incompatible with int #565
|
||||
- FIXED: UX in administration
|
||||
- FIXED: Error reporting of broken connections (sometimes it caused infinite loading of data grid)
|
||||
- ADDED: Azure managed identity support (Team Premium)
|
||||
- ADDED: Expanded JSON cell view
|
||||
- CHANGED: Open real executed query, when datagrid shows loading error
|
||||
|
||||
### 6.1.6
|
||||
- FIXED: Hotfix build process for premium edition
|
||||
|
||||
@@ -306,7 +523,7 @@ Builds:
|
||||
- FIXED: Creating SQLite autoincrement column
|
||||
- FIXED: Better error reporting from exports/import/dulicator
|
||||
- CHANGED: Optimalizede OracleDB analysing algorithm
|
||||
- ADDED: Mutli column filter for perspectives
|
||||
- ADDED: Multi column filter for perspectives
|
||||
- FIXED: Fixed some scenarios using tables from different DBs
|
||||
- FIXED: Sessions with long-running queries are not killed
|
||||
|
||||
|
||||
@@ -15,10 +15,10 @@ But there are also many advanced features like schema compare, visual query desi
|
||||
DbGate is licensed under GPL-3.0 license and is free to use for any purpose.
|
||||
|
||||
* Try it online - [demo.dbgate.org](https://demo.dbgate.org) - online demo application
|
||||
* **Download** application for Windows, Linux or Mac from [dbgate.org](https://dbgate.org/download/)
|
||||
* **Download** application for Windows, Linux or Mac from [dbgate.io](https://www.dbgate.io/download/)
|
||||
* Looking for DbGate Community? **Download** from [dbgate.io](https://www.dbgate.io/download-community/)
|
||||
* Run web version as [NPM package](https://www.npmjs.com/package/dbgate-serve) or as [docker image](https://hub.docker.com/r/dbgate/dbgate)
|
||||
* Use nodeJs [scripting interface](https://dbgate.org/docs/scripting) ([API documentation](https://dbgate.org/docs/apidoc))
|
||||
* [Recommend DbGate](https://testimonial.to/dbgate) | [Rate on G2](https://www.g2.com/products/dbgate/reviews)
|
||||
* Use nodeJs [scripting interface](https://docs.dbgate.io/scripting) ([API documentation](https://docs.dbgate.io/apidoc))
|
||||
|
||||
## Supported databases
|
||||
* MySQL
|
||||
@@ -33,8 +33,11 @@ DbGate is licensed under GPL-3.0 license and is free to use for any purpose.
|
||||
* MariaDB
|
||||
* CosmosDB (Premium)
|
||||
* ClickHouse
|
||||
|
||||
<!-- Learn more about DbGate features at the [DbGate website](https://dbgate.org/), or try our online [demo application](https://demo.dbgate.org) -->
|
||||
* Apache Cassandra
|
||||
* libSQL/Turso (Premium)
|
||||
* DuckDB
|
||||
* Firebird
|
||||
* Firestore (Premium)
|
||||
|
||||
|
||||
<a href="https://raw.githubusercontent.com/dbgate/dbgate/master/img/screenshot1.png">
|
||||
@@ -77,6 +80,7 @@ DbGate is licensed under GPL-3.0 license and is free to use for any purpose.
|
||||
* Archives - backup your data in NDJSON files on local filesystem (or on DbGate server, when using web application)
|
||||
* NDJSON data viewer and editor - browse NDJSON data, edit data and structure directly on NDJSON files. Works also for big NDSON files
|
||||
* Charts, export chart to HTML page
|
||||
* AI powered database chat
|
||||
* Show GEO data on map, export map to HTML page
|
||||
* For detailed info, how to run DbGate in docker container, visit [docker hub](https://hub.docker.com/r/dbgate/dbgate)
|
||||
* Extensible plugin architecture
|
||||
@@ -85,11 +89,12 @@ DbGate is licensed under GPL-3.0 license and is free to use for any purpose.
|
||||
Any contributions are welcome. If you want to contribute without coding, consider following:
|
||||
|
||||
* Tell your friends about DbGate or share on social networks - when more people will use DbGate, it will grow to be better
|
||||
* Write review on [Slant.co](https://www.slant.co/improve/options/41086/~dbgate-review) or [G2](https://www.g2.com/products/dbgate/reviews)
|
||||
* Purchase a [DbGate Premium](https://www.dbgate.io/purchase/premium/) license
|
||||
* Create issue, if you find problem in app, or you have idea to new feature. If issue already exists, you could leave comment on it, to prioritise most wanted issues
|
||||
* Create some tutorial video on [youtube](https://www.youtube.com/playlist?list=PLCo7KjCVXhr0RfUSjM9wJMsp_ShL1q61A)
|
||||
* Become a backer on [GitHub sponsors](https://github.com/sponsors/dbgate) or [Open collective](https://opencollective.com/dbgate)
|
||||
* Where a small coding is acceptable for you, you could [create plugin](https://dbgate.org/docs/plugin-development). Plugins for new themes can be created actually without JS coding
|
||||
* Add a SQL script to [Public Knowledge Base](https://github.com/dbgate/dbgate-knowledge-base)
|
||||
* Where a small coding is acceptable for you, you could [create plugin](https://docs.dbgate.io/plugin-development). Plugins for new themes can be created actually without JS coding
|
||||
|
||||
Thank you!
|
||||
|
||||
@@ -184,4 +189,4 @@ yarn plugin # this compiles plugin and copies it into existing DbGate installati
|
||||
After restarting DbGate, you could use your new plugin from DbGate.
|
||||
|
||||
## Logging
|
||||
DbGate uses [pinomin logger](https://github.com/dbgate/pinomin). So by default, it produces JSON log messages into console and log files. If you want to see formatted logs, please use [pino-pretty](https://github.com/pinojs/pino-pretty) log formatter.
|
||||
DbGate uses [pinomin logger](https://github.com/dbgate/pinomin). So by default, it produces JSON log messages into console and log files. If you want to see formatted logs, please use [pino-pretty](https://github.com/pinojs/pino-pretty) log formatter.
|
||||
|
||||
@@ -43,6 +43,8 @@ function adjustFile(file, isApp = false) {
|
||||
|
||||
if (process.argv.includes('--community')) {
|
||||
delete json.optionalDependencies['mongodb-client-encryption'];
|
||||
delete json.dependencies['@mongosh/service-provider-node-driver'];
|
||||
delete json.dependencies['@mongosh/browser-runtime-electron'];
|
||||
}
|
||||
|
||||
if (isApp && process.argv.includes('--premium')) {
|
||||
|
||||
+2
-3
@@ -51,7 +51,6 @@
|
||||
"target": "AppImage",
|
||||
"arch": [
|
||||
"x64",
|
||||
"armv7l",
|
||||
"arm64"
|
||||
]
|
||||
},
|
||||
@@ -118,7 +117,7 @@
|
||||
"scripts": {
|
||||
"start": "cross-env ELECTRON_START_URL=http://localhost:5001 DEVMODE=1 electron .",
|
||||
"start:local": "cross-env electron .",
|
||||
"dist": "electron-builder",
|
||||
"dist": "electron-builder --publish never",
|
||||
"build": "cd ../packages/api && yarn build && cd ../web && yarn build && cd ../../app && yarn dist",
|
||||
"build:local": "cd ../packages/api && yarn build && cd ../web && yarn build && cd ../../app && yarn predist",
|
||||
"postinstall": "yarn rebuild && patch-package",
|
||||
@@ -129,7 +128,7 @@
|
||||
"devDependencies": {
|
||||
"copyfiles": "^2.2.0",
|
||||
"cross-env": "^6.0.3",
|
||||
"electron": "30.0.2",
|
||||
"electron": "38.6.0",
|
||||
"electron-builder": "25.1.8"
|
||||
}
|
||||
}
|
||||
|
||||
+17
-8
@@ -85,7 +85,7 @@ function formatKeyText(keyText) {
|
||||
return keyText.replace('CtrlOrCommand+', 'Ctrl+');
|
||||
}
|
||||
|
||||
function commandItem(item) {
|
||||
function commandItem(item, disableAll = false) {
|
||||
const id = item.command;
|
||||
const command = commands[id];
|
||||
if (item.skipInApp) {
|
||||
@@ -95,7 +95,7 @@ function commandItem(item) {
|
||||
id,
|
||||
label: command ? command.menuName || command.toolbarName || command.name : id,
|
||||
accelerator: formatKeyText(command ? command.keyText : undefined),
|
||||
enabled: command ? command.enabled : false,
|
||||
enabled: command ? command.enabled && !disableAll : false,
|
||||
click() {
|
||||
if (mainWindow) {
|
||||
mainWindow.webContents.send('run-command', id);
|
||||
@@ -107,14 +107,14 @@ function commandItem(item) {
|
||||
};
|
||||
}
|
||||
|
||||
function buildMenu() {
|
||||
function buildMenu(disableAll = false) {
|
||||
let template = _cloneDeepWith(mainMenuDefinition({ editMenu: true, isMac: isMac() }), item => {
|
||||
if (item.divider) {
|
||||
return { type: 'separator' };
|
||||
}
|
||||
|
||||
if (item.command) {
|
||||
return commandItem(item);
|
||||
return commandItem(item, disableAll);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -129,7 +129,7 @@ function buildMenu() {
|
||||
{
|
||||
label: 'DbGate',
|
||||
submenu: [
|
||||
commandItem({ command: 'about.show' }),
|
||||
commandItem({ command: 'about.show' }, disableAll),
|
||||
{ role: 'services' },
|
||||
{ role: 'hide' },
|
||||
{ role: 'hideOthers' },
|
||||
@@ -145,7 +145,10 @@ function buildMenu() {
|
||||
}
|
||||
|
||||
ipcMain.on('update-commands', async (event, arg) => {
|
||||
commands = JSON.parse(arg);
|
||||
const parsed = JSON.parse(arg);
|
||||
commands = parsed.commands;
|
||||
const isModalOpened = parsed.isModalOpened;
|
||||
const dbgatePage = parsed.dbgatePage;
|
||||
for (const key of Object.keys(commands)) {
|
||||
const menu = mainMenu.getMenuItemById(key);
|
||||
if (!menu) continue;
|
||||
@@ -153,14 +156,14 @@ ipcMain.on('update-commands', async (event, arg) => {
|
||||
|
||||
// rebuild menu
|
||||
if (menu.label != command.text || menu.accelerator != command.keyText) {
|
||||
mainMenu = buildMenu();
|
||||
mainMenu = buildMenu(isModalOpened || !!dbgatePage);
|
||||
|
||||
Menu.setApplicationMenu(mainMenu);
|
||||
// mainWindow.setMenu(mainMenu);
|
||||
return;
|
||||
}
|
||||
|
||||
menu.enabled = command.enabled;
|
||||
menu.enabled = command.enabled && !isModalOpened && !dbgatePage;
|
||||
}
|
||||
});
|
||||
ipcMain.on('quit-app', async (event, arg) => {
|
||||
@@ -212,6 +215,10 @@ ipcMain.on('app-started', async (event, arg) => {
|
||||
autoUpdater.checkForUpdates();
|
||||
}
|
||||
}
|
||||
|
||||
if (initialConfig['winZoomLevel'] != null) {
|
||||
mainWindow.webContents.zoomLevel = initialConfig['winZoomLevel'];
|
||||
}
|
||||
});
|
||||
ipcMain.on('window-action', async (event, arg) => {
|
||||
if (!mainWindow) {
|
||||
@@ -357,6 +364,7 @@ function createWindow() {
|
||||
title: isProApp() ? 'DbGate Premium' : 'DbGate',
|
||||
frame: useNativeMenu,
|
||||
titleBarStyle: useNativeMenu ? undefined : 'hidden',
|
||||
backgroundColor: electron.nativeTheme.shouldUseDarkColors ? '#111111' : undefined,
|
||||
...bounds,
|
||||
icon: os.platform() == 'win32' ? 'icon.ico' : path.resolve(__dirname, '../icon.png'),
|
||||
partition: isProApp() ? 'persist:dbgate-premium' : 'persist:dbgate',
|
||||
@@ -393,6 +401,7 @@ function createWindow() {
|
||||
JSON.stringify({
|
||||
winBounds: mainWindow.getBounds(),
|
||||
winIsMaximized: mainWindow.isMaximized(),
|
||||
winZoomLevel: mainWindow.webContents.zoomLevel,
|
||||
}),
|
||||
'utf-8'
|
||||
);
|
||||
|
||||
@@ -4,11 +4,13 @@ module.exports = ({ editMenu, isMac }) => [
|
||||
submenu: [
|
||||
{ command: 'new.connection', hideDisabled: true },
|
||||
{ command: 'new.sqliteDatabase', hideDisabled: true },
|
||||
{ command: 'new.duckdbDatabase', hideDisabled: true },
|
||||
{ divider: true },
|
||||
{ command: 'new.query', hideDisabled: true },
|
||||
{ command: 'new.queryDesign', hideDisabled: true },
|
||||
{ command: 'new.diagram', hideDisabled: true },
|
||||
{ command: 'new.perspective', hideDisabled: true },
|
||||
{ command: 'new.application', hideDisabled: true },
|
||||
{ command: 'new.shell', hideDisabled: true },
|
||||
{ command: 'new.jsonl', hideDisabled: true },
|
||||
{ command: 'new.modelTransform', hideDisabled: true },
|
||||
@@ -85,8 +87,10 @@ module.exports = ({ editMenu, isMac }) => [
|
||||
{ divider: true },
|
||||
{ command: 'folder.showLogs', hideDisabled: true },
|
||||
{ command: 'folder.showData', hideDisabled: true },
|
||||
{ command: 'new.gist', hideDisabled: true },
|
||||
{ command: 'app.resetSettings', hideDisabled: true },
|
||||
{ divider: true },
|
||||
{ command: 'app.exportConnections', hideDisabled: true },
|
||||
{ command: 'app.importConnections', hideDisabled: true },
|
||||
],
|
||||
},
|
||||
...(isMac
|
||||
@@ -104,6 +108,7 @@ module.exports = ({ editMenu, isMac }) => [
|
||||
{ command: 'app.openWeb', hideDisabled: true },
|
||||
{ command: 'app.openIssue', hideDisabled: true },
|
||||
{ command: 'app.openSponsoring', hideDisabled: true },
|
||||
// { command: 'app.giveFeedback', hideDisabled: true },
|
||||
{ divider: true },
|
||||
{ command: 'settings.commands', hideDisabled: true },
|
||||
{ command: 'tabs.changelog', hideDisabled: true },
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
|
||||
// this file is generated automatically by script fillNativeModules.js, do not edit it manually
|
||||
const content = {};
|
||||
|
||||
content['better-sqlite3'] = () => require('better-sqlite3');
|
||||
content['oracledb'] = () => require('oracledb');
|
||||
|
||||
|
||||
module.exports = content;
|
||||
+279
-224
@@ -16,9 +16,9 @@
|
||||
ajv-keywords "^3.4.1"
|
||||
|
||||
"@electron/asar@^3.2.7":
|
||||
version "3.2.17"
|
||||
resolved "https://registry.yarnpkg.com/@electron/asar/-/asar-3.2.17.tgz#91d28087aad80d1a1c8cc4e667c6476edf50f949"
|
||||
integrity sha512-OcWImUI686w8LkghQj9R2ynZ2ME693Ek6L1SiaAgqGKzBaTIZw3fHDqN82Rcl+EU1Gm9EgkJ5KLIY/q5DCRbbA==
|
||||
version "3.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@electron/asar/-/asar-3.4.1.tgz#4e9196a4b54fba18c56cd8d5cac67c5bdc588065"
|
||||
integrity sha512-i4/rNPRS84t0vSRa2HorerGRXWyF4vThfHesw0dmcWHp+cspK743UanA0suA5Q5y8kzY2y6YKrvbIUn69BCAiA==
|
||||
dependencies:
|
||||
commander "^5.0.0"
|
||||
glob "^7.1.6"
|
||||
@@ -98,6 +98,18 @@
|
||||
resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6"
|
||||
integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==
|
||||
|
||||
"@isaacs/balanced-match@^4.0.1":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz#3081dadbc3460661b751e7591d7faea5df39dd29"
|
||||
integrity sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==
|
||||
|
||||
"@isaacs/brace-expansion@^5.0.0":
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz#4b3dabab7d8e75a429414a96bd67bf4c1d13e0f3"
|
||||
integrity sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==
|
||||
dependencies:
|
||||
"@isaacs/balanced-match" "^4.0.1"
|
||||
|
||||
"@isaacs/cliui@^8.0.2":
|
||||
version "8.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550"
|
||||
@@ -202,16 +214,23 @@
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/ms@*":
|
||||
version "0.7.34"
|
||||
resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433"
|
||||
integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/ms/-/ms-2.1.0.tgz#052aa67a48eccc4309d7f0191b7e41434b90bb78"
|
||||
integrity sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==
|
||||
|
||||
"@types/node@*", "@types/node@^20.9.0":
|
||||
version "20.12.10"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.12.10.tgz#8f0c3f12b0f075eee1fe20c1afb417e9765bef76"
|
||||
integrity sha512-Eem5pH9pmWBHoGAT8Dr5fdc5rYA+4NAovdM4EktRPVAAiJhmWWfQrA0cFhAbOsQdSfIHjAud6YdkbL69+zSKjw==
|
||||
"@types/node@*":
|
||||
version "24.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-24.10.0.tgz#6b79086b0dfc54e775a34ba8114dcc4e0221f31f"
|
||||
integrity sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==
|
||||
dependencies:
|
||||
undici-types "~5.26.4"
|
||||
undici-types "~7.16.0"
|
||||
|
||||
"@types/node@^22.7.7":
|
||||
version "22.19.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.19.0.tgz#849606ef3920850583a4e7ee0930987c35ad80be"
|
||||
integrity sha512-xpr/lmLPQEj+TUnHmR+Ab91/glhJvsqcjB+yY0Ix9GO70H6Lb4FHH5GeqdOE5btAx7eIMwuHkp4H2MSkLcqWbA==
|
||||
dependencies:
|
||||
undici-types "~6.21.0"
|
||||
|
||||
"@types/plist@^3.0.1":
|
||||
version "3.0.5"
|
||||
@@ -229,9 +248,9 @@
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/verror@^1.10.3":
|
||||
version "1.10.10"
|
||||
resolved "https://registry.yarnpkg.com/@types/verror/-/verror-1.10.10.tgz#d5a4b56abac169bfbc8b23d291363a682e6fa087"
|
||||
integrity sha512-l4MM0Jppn18hb9xmM6wwD1uTdShpf9Pn80aXTStnK1C94gtPvJcV2FrDmbOQUAQfJ1cKZHktkQUDwEqaAKXMMg==
|
||||
version "1.10.11"
|
||||
resolved "https://registry.yarnpkg.com/@types/verror/-/verror-1.10.11.tgz#d3d6b418978c8aa202d41e5bb3483227b6ecc1bb"
|
||||
integrity sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg==
|
||||
|
||||
"@types/yauzl@^2.9.1":
|
||||
version "2.10.3"
|
||||
@@ -241,9 +260,9 @@
|
||||
"@types/node" "*"
|
||||
|
||||
"@xmldom/xmldom@^0.8.8":
|
||||
version "0.8.10"
|
||||
resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz#a1337ca426aa61cef9fe15b5b28e340a72f6fa99"
|
||||
integrity sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==
|
||||
version "0.8.11"
|
||||
resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.11.tgz#b79de2d67389734c57c52595f7a7305e30c2d608"
|
||||
integrity sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==
|
||||
|
||||
"@yarnpkg/lockfile@^1.1.0":
|
||||
version "1.1.0"
|
||||
@@ -263,14 +282,14 @@ agent-base@6, agent-base@^6.0.2:
|
||||
debug "4"
|
||||
|
||||
agent-base@^7.1.0, agent-base@^7.1.2:
|
||||
version "7.1.3"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.3.tgz#29435eb821bc4194633a5b89e5bc4703bafc25a1"
|
||||
integrity sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==
|
||||
version "7.1.4"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.4.tgz#e3cd76d4c548ee895d3c3fd8dc1f6c5b9032e7a8"
|
||||
integrity sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==
|
||||
|
||||
agentkeepalive@^4.2.1:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923"
|
||||
integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.6.0.tgz#35f73e94b3f40bf65f105219c623ad19c136ea6a"
|
||||
integrity sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==
|
||||
dependencies:
|
||||
humanize-ms "^1.2.1"
|
||||
|
||||
@@ -303,9 +322,9 @@ ansi-regex@^5.0.1:
|
||||
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
|
||||
|
||||
ansi-regex@^6.0.1:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.1.0.tgz#95ec409c69619d6cb1b8b34f14b660ef28ebd654"
|
||||
integrity sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==
|
||||
version "6.2.2"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.2.2.tgz#60216eea464d864597ce2832000738a0589650c1"
|
||||
integrity sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==
|
||||
|
||||
ansi-styles@^4.0.0, ansi-styles@^4.1.0:
|
||||
version "4.3.0"
|
||||
@@ -315,9 +334,9 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
|
||||
color-convert "^2.0.1"
|
||||
|
||||
ansi-styles@^6.1.0:
|
||||
version "6.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5"
|
||||
integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==
|
||||
version "6.2.3"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.3.tgz#c044d5dcc521a076413472597a1acb1f103c4041"
|
||||
integrity sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==
|
||||
|
||||
app-builder-bin@5.0.0-alpha.10:
|
||||
version "5.0.0-alpha.10"
|
||||
@@ -363,9 +382,9 @@ app-builder-lib@25.1.8:
|
||||
temp-file "^3.4.0"
|
||||
|
||||
"aproba@^1.0.3 || ^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc"
|
||||
integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.1.0.tgz#75500a190313d95c64e871e7e4284c6ac219f0b1"
|
||||
integrity sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==
|
||||
|
||||
are-we-there-yet@^3.0.0:
|
||||
version "3.0.1"
|
||||
@@ -395,10 +414,10 @@ async-exit-hook@^2.0.1:
|
||||
resolved "https://registry.yarnpkg.com/async-exit-hook/-/async-exit-hook-2.0.1.tgz#8bd8b024b0ec9b1c01cccb9af9db29bd717dfaf3"
|
||||
integrity sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==
|
||||
|
||||
async@^3.2.3:
|
||||
version "3.2.5"
|
||||
resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66"
|
||||
integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==
|
||||
async@^3.2.6:
|
||||
version "3.2.6"
|
||||
resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce"
|
||||
integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==
|
||||
|
||||
asynckit@^0.4.0:
|
||||
version "0.4.0"
|
||||
@@ -447,33 +466,33 @@ boolean@^3.0.1:
|
||||
integrity sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.11"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
|
||||
version "1.1.12"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.12.tgz#ab9b454466e5a8cc3a187beaad580412a9c5b843"
|
||||
integrity sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
concat-map "0.0.1"
|
||||
|
||||
brace-expansion@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
|
||||
integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.2.tgz#54fc53237a613d854c7bd37463aad17df87214e7"
|
||||
integrity sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
|
||||
braces@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
|
||||
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
|
||||
braces@^3.0.3:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789"
|
||||
integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==
|
||||
dependencies:
|
||||
fill-range "^7.0.1"
|
||||
fill-range "^7.1.1"
|
||||
|
||||
buffer-crc32@~0.2.3:
|
||||
version "0.2.13"
|
||||
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
|
||||
integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==
|
||||
|
||||
buffer-equal-constant-time@1.0.1:
|
||||
buffer-equal-constant-time@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
|
||||
integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==
|
||||
@@ -499,10 +518,10 @@ builder-util-runtime@9.2.10:
|
||||
debug "^4.3.4"
|
||||
sax "^1.2.4"
|
||||
|
||||
builder-util-runtime@9.2.5:
|
||||
version "9.2.5"
|
||||
resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-9.2.5.tgz#0afdffa0adb5c84c14926c7dd2cf3c6e96e9be83"
|
||||
integrity sha512-HjIDfhvqx/8B3TDN4GbABQcgpewTU4LMRTQPkVpKYV3lsuxEJoIfvg09GyWTNmfVNSUAYf+fbTN//JX4TH20pg==
|
||||
builder-util-runtime@9.3.1:
|
||||
version "9.3.1"
|
||||
resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-9.3.1.tgz#0daedde0f6d381f2a00a50a407b166fe7dca1a67"
|
||||
integrity sha512-2/egrNDDnRaxVwK3A+cJq6UOlqOdedGA7JPqCeJjN2Zjk1/QB/6QUi3b714ScIGS7HafFXTyzJEOr5b44I3kvQ==
|
||||
dependencies:
|
||||
debug "^4.3.4"
|
||||
sax "^1.2.4"
|
||||
@@ -571,7 +590,15 @@ cacheable-request@^7.0.2:
|
||||
normalize-url "^6.0.1"
|
||||
responselike "^2.0.0"
|
||||
|
||||
chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2:
|
||||
call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6"
|
||||
integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==
|
||||
dependencies:
|
||||
es-errors "^1.3.0"
|
||||
function-bind "^1.1.2"
|
||||
|
||||
chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
|
||||
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
|
||||
@@ -744,9 +771,9 @@ cross-env@^6.0.3:
|
||||
cross-spawn "^7.0.0"
|
||||
|
||||
cross-spawn@^6.0.5:
|
||||
version "6.0.5"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
|
||||
integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
|
||||
version "6.0.6"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.6.tgz#30d0efa0712ddb7eb5a76e1e8721bffafa6b5d57"
|
||||
integrity sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==
|
||||
dependencies:
|
||||
nice-try "^1.0.4"
|
||||
path-key "^2.0.1"
|
||||
@@ -754,26 +781,19 @@ cross-spawn@^6.0.5:
|
||||
shebang-command "^1.2.0"
|
||||
which "^1.2.9"
|
||||
|
||||
cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.3:
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
||||
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
|
||||
cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.3, cross-spawn@^7.0.6:
|
||||
version "7.0.6"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f"
|
||||
integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==
|
||||
dependencies:
|
||||
path-key "^3.1.0"
|
||||
shebang-command "^2.0.0"
|
||||
which "^2.0.1"
|
||||
|
||||
debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.4:
|
||||
version "4.3.4"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
|
||||
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
|
||||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
debug@^4.3.3:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a"
|
||||
integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==
|
||||
debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.3, debug@^4.3.4:
|
||||
version "4.4.3"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a"
|
||||
integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==
|
||||
dependencies:
|
||||
ms "^2.1.3"
|
||||
|
||||
@@ -825,9 +845,9 @@ delegates@^1.0.0:
|
||||
integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==
|
||||
|
||||
detect-libc@^2.0.1:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700"
|
||||
integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.1.2.tgz#689c5dcdc1900ef5583a4cb9f6d7b473742074ad"
|
||||
integrity sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==
|
||||
|
||||
detect-node@^2.0.4:
|
||||
version "2.1.0"
|
||||
@@ -878,9 +898,18 @@ dotenv-expand@^11.0.6:
|
||||
dotenv "^16.4.5"
|
||||
|
||||
dotenv@^16.4.5:
|
||||
version "16.4.7"
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.7.tgz#0e20c5b82950140aa99be360a8a5f52335f53c26"
|
||||
integrity sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==
|
||||
version "16.6.1"
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.6.1.tgz#773f0e69527a8315c7285d5ee73c4459d20a8020"
|
||||
integrity sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==
|
||||
|
||||
dunder-proto@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a"
|
||||
integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==
|
||||
dependencies:
|
||||
call-bind-apply-helpers "^1.0.1"
|
||||
es-errors "^1.3.0"
|
||||
gopd "^1.2.0"
|
||||
|
||||
eastasianwidth@^0.2.0:
|
||||
version "0.2.0"
|
||||
@@ -936,11 +965,11 @@ electron-publish@25.1.7:
|
||||
mime "^2.5.2"
|
||||
|
||||
electron-updater@^6.3.4:
|
||||
version "6.3.4"
|
||||
resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-6.3.4.tgz#3934bc89875bb524c2cbbd11041114e97c0c2496"
|
||||
integrity sha512-uZUo7p1Y53G4tl6Cgw07X1yF8Jlz6zhaL7CQJDZ1fVVkOaBfE2cWtx80avwDVi8jHp+I/FWawrMgTAeCCNIfAg==
|
||||
version "6.6.2"
|
||||
resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-6.6.2.tgz#3e65e044f1a99b00d61e200e24de8e709c69ce99"
|
||||
integrity sha512-Cr4GDOkbAUqRHP5/oeOmH/L2Bn6+FQPxVLZtPbcmKZC63a1F3uu5EefYOssgZXG3u/zBlubbJ5PJdITdMVggbw==
|
||||
dependencies:
|
||||
builder-util-runtime "9.2.5"
|
||||
builder-util-runtime "9.3.1"
|
||||
fs-extra "^10.1.0"
|
||||
js-yaml "^4.1.0"
|
||||
lazy-val "^1.0.5"
|
||||
@@ -949,13 +978,13 @@ electron-updater@^6.3.4:
|
||||
semver "^7.6.3"
|
||||
tiny-typed-emitter "^2.1.0"
|
||||
|
||||
electron@30.0.2:
|
||||
version "30.0.2"
|
||||
resolved "https://registry.yarnpkg.com/electron/-/electron-30.0.2.tgz#95ba019216bf8be9f3097580123e33ea37497733"
|
||||
integrity sha512-zv7T+GG89J/hyWVkQsLH4Y/rVEfqJG5M/wOBIGNaDdqd8UV9/YZPdS7CuFeaIj0H9LhCt95xkIQNpYB/3svOkQ==
|
||||
electron@38.6.0:
|
||||
version "38.6.0"
|
||||
resolved "https://registry.yarnpkg.com/electron/-/electron-38.6.0.tgz#c862bff41d42776e307bf5cc92503dda23612339"
|
||||
integrity sha512-68OFNxJlrEStA+t8k5atzf4frJddvRR1N1oalr49Ll8YZ0+0nEsDhw4UNhTCoZKTjSYcxFF/4rt+sco+OlnB3g==
|
||||
dependencies:
|
||||
"@electron/get" "^2.0.0"
|
||||
"@types/node" "^20.9.0"
|
||||
"@types/node" "^22.7.7"
|
||||
extract-zip "^2.0.1"
|
||||
|
||||
emoji-regex@^8.0.0:
|
||||
@@ -976,9 +1005,9 @@ encoding@^0.1.13:
|
||||
iconv-lite "^0.6.2"
|
||||
|
||||
end-of-stream@^1.1.0:
|
||||
version "1.4.4"
|
||||
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
|
||||
integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
|
||||
version "1.4.5"
|
||||
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.5.tgz#7344d711dea40e0b74abc2ed49778743ccedb08c"
|
||||
integrity sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==
|
||||
dependencies:
|
||||
once "^1.4.0"
|
||||
|
||||
@@ -992,27 +1021,42 @@ err-code@^2.0.2:
|
||||
resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9"
|
||||
integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==
|
||||
|
||||
es-define-property@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845"
|
||||
integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==
|
||||
dependencies:
|
||||
get-intrinsic "^1.2.4"
|
||||
es-define-property@^1.0.0, es-define-property@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa"
|
||||
integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==
|
||||
|
||||
es-errors@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
|
||||
integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
|
||||
|
||||
es-object-atoms@^1.0.0, es-object-atoms@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1"
|
||||
integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==
|
||||
dependencies:
|
||||
es-errors "^1.3.0"
|
||||
|
||||
es-set-tostringtag@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz#f31dbbe0c183b00a6d26eb6325c810c0fd18bd4d"
|
||||
integrity sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==
|
||||
dependencies:
|
||||
es-errors "^1.3.0"
|
||||
get-intrinsic "^1.2.6"
|
||||
has-tostringtag "^1.0.2"
|
||||
hasown "^2.0.2"
|
||||
|
||||
es6-error@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d"
|
||||
integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==
|
||||
|
||||
escalade@^3.1.1:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27"
|
||||
integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5"
|
||||
integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==
|
||||
|
||||
escape-string-regexp@^4.0.0:
|
||||
version "4.0.0"
|
||||
@@ -1020,9 +1064,9 @@ escape-string-regexp@^4.0.0:
|
||||
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
|
||||
|
||||
exponential-backoff@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6"
|
||||
integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.3.tgz#51cf92c1c0493c766053f9d3abee4434c244d2f6"
|
||||
integrity sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==
|
||||
|
||||
extract-zip@^2.0.1:
|
||||
version "2.0.1"
|
||||
@@ -1064,10 +1108,10 @@ filelist@^1.0.4:
|
||||
dependencies:
|
||||
minimatch "^5.0.1"
|
||||
|
||||
fill-range@^7.0.1:
|
||||
version "7.0.1"
|
||||
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
|
||||
integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
|
||||
fill-range@^7.1.1:
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292"
|
||||
integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==
|
||||
dependencies:
|
||||
to-regex-range "^5.0.1"
|
||||
|
||||
@@ -1079,20 +1123,22 @@ find-yarn-workspace-root@^2.0.0:
|
||||
micromatch "^4.0.2"
|
||||
|
||||
foreground-child@^3.1.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.0.tgz#0ac8644c06e431439f8561db8ecf29a7b5519c77"
|
||||
integrity sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.1.tgz#32e8e9ed1b68a3497befb9ac2b6adf92a638576f"
|
||||
integrity sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==
|
||||
dependencies:
|
||||
cross-spawn "^7.0.0"
|
||||
cross-spawn "^7.0.6"
|
||||
signal-exit "^4.0.1"
|
||||
|
||||
form-data@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
|
||||
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
|
||||
version "4.0.4"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.4.tgz#784cdcce0669a9d68e94d11ac4eea98088edd2c4"
|
||||
integrity sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==
|
||||
dependencies:
|
||||
asynckit "^0.4.0"
|
||||
combined-stream "^1.0.8"
|
||||
es-set-tostringtag "^2.1.0"
|
||||
hasown "^2.0.2"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
fs-extra@^10.0.0, fs-extra@^10.1.0:
|
||||
@@ -1105,9 +1151,9 @@ fs-extra@^10.0.0, fs-extra@^10.1.0:
|
||||
universalify "^2.0.0"
|
||||
|
||||
fs-extra@^11.1.1:
|
||||
version "11.2.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b"
|
||||
integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==
|
||||
version "11.3.2"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.3.2.tgz#c838aeddc6f4a8c74dd15f85e11fe5511bfe02a4"
|
||||
integrity sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==
|
||||
dependencies:
|
||||
graceful-fs "^4.2.0"
|
||||
jsonfile "^6.0.1"
|
||||
@@ -1168,16 +1214,29 @@ get-caller-file@^2.0.5:
|
||||
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
|
||||
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
|
||||
|
||||
get-intrinsic@^1.1.3, get-intrinsic@^1.2.4:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd"
|
||||
integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==
|
||||
get-intrinsic@^1.2.6:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01"
|
||||
integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==
|
||||
dependencies:
|
||||
call-bind-apply-helpers "^1.0.2"
|
||||
es-define-property "^1.0.1"
|
||||
es-errors "^1.3.0"
|
||||
es-object-atoms "^1.1.1"
|
||||
function-bind "^1.1.2"
|
||||
has-proto "^1.0.1"
|
||||
has-symbols "^1.0.3"
|
||||
hasown "^2.0.0"
|
||||
get-proto "^1.0.1"
|
||||
gopd "^1.2.0"
|
||||
has-symbols "^1.1.0"
|
||||
hasown "^2.0.2"
|
||||
math-intrinsics "^1.1.0"
|
||||
|
||||
get-proto@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1"
|
||||
integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==
|
||||
dependencies:
|
||||
dunder-proto "^1.0.1"
|
||||
es-object-atoms "^1.0.0"
|
||||
|
||||
get-stream@^5.1.0:
|
||||
version "5.2.0"
|
||||
@@ -1241,12 +1300,10 @@ globalthis@^1.0.1:
|
||||
define-properties "^1.2.1"
|
||||
gopd "^1.0.1"
|
||||
|
||||
gopd@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c"
|
||||
integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==
|
||||
dependencies:
|
||||
get-intrinsic "^1.1.3"
|
||||
gopd@^1.0.1, gopd@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1"
|
||||
integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==
|
||||
|
||||
got@^11.7.0, got@^11.8.5:
|
||||
version "11.8.6"
|
||||
@@ -1282,22 +1339,24 @@ has-property-descriptors@^1.0.0:
|
||||
dependencies:
|
||||
es-define-property "^1.0.0"
|
||||
|
||||
has-proto@^1.0.1:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd"
|
||||
integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==
|
||||
has-symbols@^1.0.3, has-symbols@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338"
|
||||
integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==
|
||||
|
||||
has-symbols@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
|
||||
integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
|
||||
has-tostringtag@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc"
|
||||
integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==
|
||||
dependencies:
|
||||
has-symbols "^1.0.3"
|
||||
|
||||
has-unicode@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
|
||||
integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==
|
||||
|
||||
hasown@^2.0.0:
|
||||
hasown@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
|
||||
integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
|
||||
@@ -1312,9 +1371,9 @@ hosted-git-info@^4.1.0:
|
||||
lru-cache "^6.0.0"
|
||||
|
||||
http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a"
|
||||
integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz#205f4db64f8562b76a4ff9235aa5279839a09dd5"
|
||||
integrity sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==
|
||||
|
||||
http-proxy-agent@^5.0.0:
|
||||
version "5.0.0"
|
||||
@@ -1412,13 +1471,10 @@ inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1,
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
ip-address@^9.0.5:
|
||||
version "9.0.5"
|
||||
resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-9.0.5.tgz#117a960819b08780c3bd1f14ef3c1cc1d3f3ea5a"
|
||||
integrity sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==
|
||||
dependencies:
|
||||
jsbn "1.1.0"
|
||||
sprintf-js "^1.1.3"
|
||||
ip-address@^10.0.1:
|
||||
version "10.1.0"
|
||||
resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-10.1.0.tgz#d8dcffb34d0e02eb241427444a6e23f5b0595aa4"
|
||||
integrity sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==
|
||||
|
||||
is-ci@^2.0.0:
|
||||
version "2.0.0"
|
||||
@@ -1487,9 +1543,9 @@ isbinaryfile@^4.0.8:
|
||||
integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==
|
||||
|
||||
isbinaryfile@^5.0.0:
|
||||
version "5.0.4"
|
||||
resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-5.0.4.tgz#2a2edefa76cafa66613fe4c1ea52f7f031017bdf"
|
||||
integrity sha512-YKBKVkKhty7s8rxddb40oOkuP0NbaeXrQvLin6QMHL7Ypiy2RW9LwOVrVgZRyOrhQlayMd9t+D8yDy8MKFTSDQ==
|
||||
version "5.0.6"
|
||||
resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-5.0.6.tgz#01eac28867aeffaebaee7eaf21d1dd3a67d7c0c7"
|
||||
integrity sha512-I+NmIfBHUl+r2wcDd6JwE9yWje/PIVY/R5/CmV8dXLZd5K+L9X2klAOwfAHNnondLXkbHyTAleQAWonpTJBTtw==
|
||||
|
||||
isexe@^2.0.0:
|
||||
version "2.0.0"
|
||||
@@ -1506,14 +1562,13 @@ jackspeak@^3.1.2:
|
||||
"@pkgjs/parseargs" "^0.11.0"
|
||||
|
||||
jake@^10.8.5:
|
||||
version "10.9.1"
|
||||
resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.1.tgz#8dc96b7fcc41cb19aa502af506da4e1d56f5e62b"
|
||||
integrity sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==
|
||||
version "10.9.4"
|
||||
resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.4.tgz#d626da108c63d5cfb00ab5c25fadc7e0084af8e6"
|
||||
integrity sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==
|
||||
dependencies:
|
||||
async "^3.2.3"
|
||||
chalk "^4.0.2"
|
||||
async "^3.2.6"
|
||||
filelist "^1.0.4"
|
||||
minimatch "^3.1.2"
|
||||
picocolors "^1.1.1"
|
||||
|
||||
js-yaml@^4.1.0:
|
||||
version "4.1.0"
|
||||
@@ -1522,11 +1577,6 @@ js-yaml@^4.1.0:
|
||||
dependencies:
|
||||
argparse "^2.0.1"
|
||||
|
||||
jsbn@1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040"
|
||||
integrity sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==
|
||||
|
||||
json-buffer@3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
|
||||
@@ -1555,9 +1605,9 @@ jsonfile@^4.0.0:
|
||||
graceful-fs "^4.1.6"
|
||||
|
||||
jsonfile@^6.0.1:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
|
||||
integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.2.0.tgz#7c265bd1b65de6977478300087c99f1c84383f62"
|
||||
integrity sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==
|
||||
dependencies:
|
||||
universalify "^2.0.0"
|
||||
optionalDependencies:
|
||||
@@ -1580,11 +1630,11 @@ jsonwebtoken@^9.0.2:
|
||||
semver "^7.5.4"
|
||||
|
||||
jwa@^1.4.1:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a"
|
||||
integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==
|
||||
version "1.4.2"
|
||||
resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.2.tgz#16011ac6db48de7b102777e57897901520eec7b9"
|
||||
integrity sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==
|
||||
dependencies:
|
||||
buffer-equal-constant-time "1.0.1"
|
||||
buffer-equal-constant-time "^1.0.1"
|
||||
ecdsa-sig-formatter "1.0.11"
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
@@ -1729,12 +1779,17 @@ matcher@^3.0.0:
|
||||
dependencies:
|
||||
escape-string-regexp "^4.0.0"
|
||||
|
||||
math-intrinsics@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9"
|
||||
integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==
|
||||
|
||||
micromatch@^4.0.2:
|
||||
version "4.0.5"
|
||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6"
|
||||
integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==
|
||||
version "4.0.8"
|
||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202"
|
||||
integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==
|
||||
dependencies:
|
||||
braces "^3.0.2"
|
||||
braces "^3.0.3"
|
||||
picomatch "^2.3.1"
|
||||
|
||||
mime-db@1.52.0:
|
||||
@@ -1770,13 +1825,13 @@ mimic-response@^3.1.0:
|
||||
integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==
|
||||
|
||||
minimatch@^10.0.0:
|
||||
version "10.0.1"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.0.1.tgz#ce0521856b453c86e25f2c4c0d03e6ff7ddc440b"
|
||||
integrity sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==
|
||||
version "10.1.1"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.1.1.tgz#e6e61b9b0c1dcab116b5a7d1458e8b6ae9e73a55"
|
||||
integrity sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==
|
||||
dependencies:
|
||||
brace-expansion "^2.0.1"
|
||||
"@isaacs/brace-expansion" "^5.0.0"
|
||||
|
||||
minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
|
||||
minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
||||
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
|
||||
@@ -1871,11 +1926,6 @@ mkdirp@^1.0.3, mkdirp@^1.0.4:
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
|
||||
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
||||
|
||||
ms@2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||
|
||||
ms@^2.0.0, ms@^2.1.1, ms@^2.1.3:
|
||||
version "2.1.3"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
||||
@@ -1892,9 +1942,9 @@ nice-try@^1.0.4:
|
||||
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
|
||||
|
||||
node-abi@^3.45.0:
|
||||
version "3.71.0"
|
||||
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.71.0.tgz#52d84bbcd8575efb71468fbaa1f9a49b2c242038"
|
||||
integrity sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw==
|
||||
version "3.80.0"
|
||||
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.80.0.tgz#d7390951f27caa129cceeec01e1c20fc9f07581c"
|
||||
integrity sha512-LyPuZJcI9HVwzXK1GPxWNzrr+vr8Hp/3UqlmWxxh8p54U1ZbclOqbSog9lWHaCX+dBaiGi6n/hIX+mKu74GmPA==
|
||||
dependencies:
|
||||
semver "^7.3.5"
|
||||
|
||||
@@ -1904,9 +1954,9 @@ node-addon-api@^1.6.3:
|
||||
integrity sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==
|
||||
|
||||
node-api-version@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/node-api-version/-/node-api-version-0.2.0.tgz#5177441da2b1046a4d4547ab9e0972eed7b1ac1d"
|
||||
integrity sha512-fthTTsi8CxaBXMaBAD7ST2uylwvsnYxh2PfaScwpMhos6KlSFajXQPcM4ogNE1q2s3Lbz9GCGqeIHC+C6OZnKg==
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/node-api-version/-/node-api-version-0.2.1.tgz#19bad54f6d65628cbee4e607a325e4488ace2de9"
|
||||
integrity sha512-2xP/IGGMmmSQpI1+O/k72jF/ykvZ89JeuKX3TLJAYPDVLUalrshrLHkeVcCCZqG/eEa635cr8IBYzgnDvM2O8Q==
|
||||
dependencies:
|
||||
semver "^7.3.5"
|
||||
|
||||
@@ -2081,6 +2131,11 @@ pend@~1.2.0:
|
||||
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
|
||||
integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==
|
||||
|
||||
picocolors@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
|
||||
integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
|
||||
|
||||
picomatch@^2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
|
||||
@@ -2119,9 +2174,9 @@ promise-retry@^2.0.1:
|
||||
retry "^0.12.0"
|
||||
|
||||
pump@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
|
||||
integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.3.tgz#151d979f1a29668dc0025ec589a455b53282268d"
|
||||
integrity sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==
|
||||
dependencies:
|
||||
end-of-stream "^1.1.0"
|
||||
once "^1.3.1"
|
||||
@@ -2261,9 +2316,9 @@ sanitize-filename@^1.6.3:
|
||||
truncate-utf8-bytes "^1.0.0"
|
||||
|
||||
sax@^1.2.4:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/sax/-/sax-1.3.0.tgz#a5dbe77db3be05c9d1ee7785dbd3ea9de51593d0"
|
||||
integrity sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/sax/-/sax-1.4.3.tgz#fcebae3b756cdc8428321805f4b70f16ec0ab5db"
|
||||
integrity sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==
|
||||
|
||||
semver-compare@^1.0.0:
|
||||
version "1.0.0"
|
||||
@@ -2280,15 +2335,10 @@ semver@^6.2.0:
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
|
||||
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
|
||||
|
||||
semver@^7.3.2:
|
||||
version "7.6.1"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.1.tgz#60bfe090bf907a25aa8119a72b9f90ef7ca281b2"
|
||||
integrity sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA==
|
||||
|
||||
semver@^7.3.5, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4, semver@^7.6.3:
|
||||
version "7.6.3"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143"
|
||||
integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==
|
||||
semver@^7.3.2, semver@^7.3.5, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4, semver@^7.6.3:
|
||||
version "7.7.3"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.3.tgz#4b5f4143d007633a8dc671cd0a6ef9147b8bb946"
|
||||
integrity sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==
|
||||
|
||||
serialize-error@^7.0.1:
|
||||
version "7.0.1"
|
||||
@@ -2372,11 +2422,11 @@ socks-proxy-agent@^7.0.0:
|
||||
socks "^2.6.2"
|
||||
|
||||
socks@^2.6.2:
|
||||
version "2.8.3"
|
||||
resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.3.tgz#1ebd0f09c52ba95a09750afe3f3f9f724a800cb5"
|
||||
integrity sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==
|
||||
version "2.8.7"
|
||||
resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.7.tgz#e2fb1d9a603add75050a2067db8c381a0b5669ea"
|
||||
integrity sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==
|
||||
dependencies:
|
||||
ip-address "^9.0.5"
|
||||
ip-address "^10.0.1"
|
||||
smart-buffer "^4.2.0"
|
||||
|
||||
source-map-support@^0.5.19:
|
||||
@@ -2392,7 +2442,7 @@ source-map@^0.6.0:
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
||||
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
||||
|
||||
sprintf-js@^1.1.2, sprintf-js@^1.1.3:
|
||||
sprintf-js@^1.1.2:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.3.tgz#4914b903a2f8b685d17fdf78a70e917e872e444a"
|
||||
integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==
|
||||
@@ -2454,9 +2504,9 @@ string_decoder@~1.1.1:
|
||||
ansi-regex "^5.0.1"
|
||||
|
||||
strip-ansi@^7.0.1:
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
|
||||
integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==
|
||||
version "7.1.2"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.2.tgz#132875abde678c7ea8d691533f2e7e22bb744dba"
|
||||
integrity sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==
|
||||
dependencies:
|
||||
ansi-regex "^6.0.1"
|
||||
|
||||
@@ -2522,9 +2572,9 @@ tmp@^0.0.33:
|
||||
os-tmpdir "~1.0.2"
|
||||
|
||||
tmp@^0.2.0:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.3.tgz#eb783cc22bc1e8bebd0671476d46ea4eb32a79ae"
|
||||
integrity sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==
|
||||
version "0.2.5"
|
||||
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.5.tgz#b06bcd23f0f3c8357b426891726d16015abfd8f8"
|
||||
integrity sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==
|
||||
|
||||
to-regex-range@^5.0.1:
|
||||
version "5.0.1"
|
||||
@@ -2546,14 +2596,19 @@ type-fest@^0.13.1:
|
||||
integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==
|
||||
|
||||
typescript@^5.4.3:
|
||||
version "5.7.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.7.2.tgz#3169cf8c4c8a828cde53ba9ecb3d2b1d5dd67be6"
|
||||
integrity sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==
|
||||
version "5.9.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.3.tgz#5b4f59e15310ab17a216f5d6cf53ee476ede670f"
|
||||
integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==
|
||||
|
||||
undici-types@~5.26.4:
|
||||
version "5.26.5"
|
||||
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
|
||||
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
|
||||
undici-types@~6.21.0:
|
||||
version "6.21.0"
|
||||
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb"
|
||||
integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==
|
||||
|
||||
undici-types@~7.16.0:
|
||||
version "7.16.0"
|
||||
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.16.0.tgz#ffccdff36aea4884cbfce9a750a0580224f58a46"
|
||||
integrity sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==
|
||||
|
||||
unique-filename@^2.0.0:
|
||||
version "2.0.1"
|
||||
@@ -2592,9 +2647,9 @@ uri-js@^4.2.2:
|
||||
punycode "^2.1.0"
|
||||
|
||||
utf8-byte-length@^1.0.1:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz#f45f150c4c66eee968186505ab93fcbb8ad6bf61"
|
||||
integrity sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA==
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz#f9f63910d15536ee2b2d5dd4665389715eac5c1e"
|
||||
integrity sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==
|
||||
|
||||
util-deprecate@^1.0.1, util-deprecate@~1.0.1:
|
||||
version "1.0.2"
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
#!/usr/bin/env node
|
||||
// assign-dbgm-codes.mjs
|
||||
import fs from 'fs/promises';
|
||||
import path from 'path';
|
||||
|
||||
const PLACEHOLDER = 'DBGM-00000';
|
||||
const CODE_RE = /DBGM-(\d{5})/g;
|
||||
const JS_TS_RE = /\.(mjs|cjs|js|ts|jsx|tsx)$/i;
|
||||
|
||||
const IGNORE_DIRS = new Set([
|
||||
'node_modules',
|
||||
'.git',
|
||||
'.hg',
|
||||
'.svn',
|
||||
'dist',
|
||||
'build',
|
||||
'out',
|
||||
'.next',
|
||||
'.turbo',
|
||||
'.cache',
|
||||
]);
|
||||
const IGNORE_FILES = ['assign-dbgm-codes.mjs', 'package.json', 'README.md'];
|
||||
|
||||
// --- CLI ---
|
||||
const args = process.argv.slice(2);
|
||||
const dryRun = args.includes('--dry');
|
||||
const rootArg = args.find(a => a !== '--dry') || process.cwd();
|
||||
const root = path.resolve(rootArg);
|
||||
|
||||
// --- helpers ---
|
||||
async function* walk(dir) {
|
||||
const entries = await fs.readdir(dir, { withFileTypes: true });
|
||||
for (const e of entries) {
|
||||
if (e.isDirectory()) {
|
||||
if (IGNORE_DIRS.has(e.name)) continue;
|
||||
yield* walk(path.join(dir, e.name));
|
||||
} else if (e.isFile()) {
|
||||
if (JS_TS_RE.test(e.name) && !IGNORE_FILES.includes(e.name)) yield path.join(dir, e.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function formatCode(n) {
|
||||
return `DBGM-${String(n).padStart(5, '0')}`;
|
||||
}
|
||||
|
||||
// Find the smallest positive integer not in `taken`
|
||||
function makeNextCodeFn(taken) {
|
||||
let n = 1;
|
||||
// advance n to first free
|
||||
while (taken.has(n)) n++;
|
||||
return () => {
|
||||
const code = n;
|
||||
taken.add(code);
|
||||
// move n to next free for next call
|
||||
do {
|
||||
n++;
|
||||
} while (taken.has(n));
|
||||
return formatCode(code);
|
||||
};
|
||||
}
|
||||
|
||||
// --- main ---
|
||||
(async () => {
|
||||
console.log(`Scanning: ${root} ${dryRun ? '(dry run)' : ''}`);
|
||||
|
||||
// 1) Collect all taken codes across the repo
|
||||
const taken = new Set(); // numeric parts only
|
||||
const files = [];
|
||||
for await (const file of walk(root)) files.push(file);
|
||||
|
||||
await Promise.all(
|
||||
files.map(async file => {
|
||||
try {
|
||||
const text = await fs.readFile(file, 'utf8');
|
||||
for (const m of text.matchAll(CODE_RE)) {
|
||||
const num = Number(m[1]);
|
||||
if (Number.isInteger(num) && num > 0) taken.add(num);
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(`! Failed to read ${file}: ${err.message}`);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
console.log(`Found ${taken.size} occupied code(s).`);
|
||||
|
||||
// 2) Replace placeholders with next available unique code
|
||||
const nextCode = makeNextCodeFn(taken);
|
||||
|
||||
let filesChanged = 0;
|
||||
let placeholdersReplaced = 0;
|
||||
|
||||
for (const file of files) {
|
||||
let text;
|
||||
try {
|
||||
text = await fs.readFile(file, 'utf8');
|
||||
} catch (err) {
|
||||
console.warn(`! Failed to read ${file}: ${err.message}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!text.includes(PLACEHOLDER)) continue;
|
||||
|
||||
let countInFile = 0;
|
||||
const updated = text.replaceAll(PLACEHOLDER, () => {
|
||||
countInFile++;
|
||||
return nextCode();
|
||||
});
|
||||
|
||||
if (countInFile > 0) {
|
||||
placeholdersReplaced += countInFile;
|
||||
filesChanged++;
|
||||
console.log(`${dryRun ? '[dry]' : '[write]'} ${file} — ${countInFile} replacement(s)`);
|
||||
if (!dryRun) {
|
||||
try {
|
||||
await fs.writeFile(file, updated, 'utf8');
|
||||
} catch (err) {
|
||||
console.warn(`! Failed to write ${file}: ${err.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`Done. Files changed: ${filesChanged}, placeholders replaced: ${placeholdersReplaced}.`);
|
||||
})().catch(err => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -0,0 +1,110 @@
|
||||
import fs from 'node:fs/promises';
|
||||
import { createHash } from 'node:crypto';
|
||||
import path from 'node:path';
|
||||
import process from 'node:process';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import YAML from 'yaml';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
async function sha512Base64(filePath) {
|
||||
const buf = await fs.readFile(filePath);
|
||||
const h = createHash('sha512');
|
||||
h.update(buf);
|
||||
return h.digest('base64');
|
||||
}
|
||||
|
||||
async function fileSize(filePath) {
|
||||
const st = await fs.stat(filePath);
|
||||
return st.size;
|
||||
}
|
||||
|
||||
async function fixOneYaml(ymlPath, distDir) {
|
||||
let raw;
|
||||
try {
|
||||
raw = await fs.readFile(ymlPath, 'utf8');
|
||||
} catch (e) {
|
||||
console.error(`✗ Cannot read ${ymlPath}:`, e.message);
|
||||
return;
|
||||
}
|
||||
|
||||
let doc;
|
||||
try {
|
||||
doc = YAML.parse(raw);
|
||||
} catch (e) {
|
||||
console.error(`✗ Cannot parse YAML ${ymlPath}:`, e.message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!doc || !Array.isArray(doc.files)) {
|
||||
console.warn(`! ${path.basename(ymlPath)} has no 'files' array — skipped.`);
|
||||
return;
|
||||
}
|
||||
|
||||
let changed = false;
|
||||
|
||||
// Update each files[i].sha512 and files[i].size based on files[i].url
|
||||
for (const entry of doc.files) {
|
||||
if (!entry?.url) continue;
|
||||
|
||||
const target = path.resolve(distDir, entry.url);
|
||||
try {
|
||||
const [hash, size] = await Promise.all([sha512Base64(target), fileSize(target)]);
|
||||
if (entry.sha512 !== hash || entry.size !== size) {
|
||||
console.log(`• ${path.basename(ymlPath)}: refresh ${entry.url}`);
|
||||
entry.sha512 = hash;
|
||||
entry.size = size;
|
||||
changed = true;
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(
|
||||
`! Missing or unreadable file for ${entry.url} (referenced by ${path.basename(ymlPath)}): ${e.message}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Update top-level sha512 for the primary "path" file if present
|
||||
if (doc.path) {
|
||||
const primary = path.resolve(distDir, doc.path);
|
||||
try {
|
||||
const hash = await sha512Base64(primary);
|
||||
if (doc.sha512 !== hash) {
|
||||
console.log(`• ${path.basename(ymlPath)}: refresh top-level sha512 for path=${doc.path}`);
|
||||
doc.sha512 = hash;
|
||||
changed = true;
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(`! Primary 'path' file not found for ${path.basename(ymlPath)}: ${doc.path} (${e.message})`);
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
const out = YAML.stringify(doc);
|
||||
await fs.writeFile(ymlPath, out, 'utf8');
|
||||
console.log(`✓ Updated ${path.basename(ymlPath)}`);
|
||||
} else {
|
||||
console.log(`= No changes for ${path.basename(ymlPath)}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const distDir = path.resolve(process.argv[2] ?? path.join(__dirname, '..', 'app', 'dist'));
|
||||
const entries = await fs.readdir(distDir);
|
||||
const ymls = entries.filter(f => f.toLowerCase().endsWith('.yml'));
|
||||
|
||||
if (ymls.length === 0) {
|
||||
console.warn(`No .yml files found in ${distDir}`);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`Scanning ${distDir}`);
|
||||
for (const y of ymls) {
|
||||
await fixOneYaml(path.join(distDir, y), distDir);
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(err => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
//@ts-check
|
||||
const { getDefaultTranslations, getLanguageTranslations } = require('./helpers');
|
||||
|
||||
/**
|
||||
* @param {string} language
|
||||
*/
|
||||
function getMissingTranslations(language) {
|
||||
const source = getDefaultTranslations();
|
||||
/** @type {Record<string, string>} */
|
||||
let target;
|
||||
|
||||
try {
|
||||
target = getLanguageTranslations(language);
|
||||
} catch {
|
||||
console.log(`Language ${language} not found, creating a new one`);
|
||||
target = {};
|
||||
}
|
||||
|
||||
let added = 0;
|
||||
let removed = 0;
|
||||
|
||||
for (const key in source) {
|
||||
if (!target[key]) {
|
||||
target[key] = `*** ${source[key]}`;
|
||||
added++;
|
||||
}
|
||||
}
|
||||
|
||||
for (const key in target) {
|
||||
if (!source[key]) {
|
||||
delete target[key];
|
||||
removed++;
|
||||
}
|
||||
}
|
||||
|
||||
const newLength = Object.keys(target).length;
|
||||
|
||||
return { result: target, stats: { added, removed, newLength } };
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getMissingTranslations,
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
// @ts-check
|
||||
//
|
||||
const defaultLanguage = 'en';
|
||||
|
||||
/** @typedef {{ extensions: string[], directories: string[] }} ExtractConfig
|
||||
|
||||
/** @type {ExtractConfig} */
|
||||
const defaultExtractConfig = {
|
||||
extensions: ['.js', '.ts', '.svelte'],
|
||||
directories: ['app', 'packages/web'],
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
defaultLanguage,
|
||||
defaultExtractConfig,
|
||||
};
|
||||
@@ -0,0 +1,85 @@
|
||||
//@ts-check
|
||||
const fs = require('fs');
|
||||
const { promisify } = require('util');
|
||||
|
||||
const { getFiles } = require('./helpers');
|
||||
|
||||
const readFilePromise = promisify(fs.readFile);
|
||||
|
||||
const translationRegex = /_t\(\s*['"]([^'"]+)['"]\s*,\s*\{\s*defaultMessage\s*:\s*(?:'([^'\\]*(?:\\.[^'\\]*)*)'|"([^"\\]*(?:\\.[^"\\]*)*)"|\`([^`\\]*(?:\\.[^`\\]*)*(?:\{[^}]*\}[^`\\]*(?:\\.[^`\\]*)*)*)\`)(?:\s*,\s*[^}]*)*\s*\}/g;
|
||||
|
||||
/**
|
||||
* @param {string} file
|
||||
*
|
||||
* @returns {Promise<Record<string, string>>}
|
||||
*/
|
||||
async function extractTranslationsFromFile(file) {
|
||||
/** @type {Record<string, string>} */
|
||||
const translations = {};
|
||||
const content = await readFilePromise(file, 'utf-8');
|
||||
let match;
|
||||
|
||||
while ((match = translationRegex.exec(content)) !== null) {
|
||||
const [_, key, singleQuotedText, doubleQuotedText, templateLiteral] = match;
|
||||
const defaultText = singleQuotedText || doubleQuotedText || templateLiteral;
|
||||
translations[key] = defaultText;
|
||||
}
|
||||
|
||||
return translations;
|
||||
}
|
||||
|
||||
/** @typedef {{ ignoreDuplicates?: boolean }} ExtractOptions */
|
||||
|
||||
/**
|
||||
* @param {string[]} directories
|
||||
* @param {string[]} extensions
|
||||
* @param {ExtractOptions} options
|
||||
*
|
||||
* @returns {Promise<Record<string, string>>}
|
||||
*/
|
||||
async function extractAllTranslations(directories, extensions, options = {}) {
|
||||
const { ignoreDuplicates } = options;
|
||||
|
||||
try {
|
||||
/** @type {Record<string, string>} */
|
||||
const allTranslations = {};
|
||||
/** @type {Record<string, string[]>} */
|
||||
const translationKeyToFiles = {};
|
||||
|
||||
for (const dir of directories) {
|
||||
const files = await getFiles(dir, extensions);
|
||||
|
||||
for (const file of files) {
|
||||
const fileTranslations = await extractTranslationsFromFile(file);
|
||||
|
||||
for (const key in fileTranslations) {
|
||||
if (!translationKeyToFiles[key]) {
|
||||
translationKeyToFiles[key] = [];
|
||||
}
|
||||
|
||||
translationKeyToFiles[key].push(file);
|
||||
|
||||
if (!ignoreDuplicates && allTranslations[key] && allTranslations[key] !== fileTranslations[key]) {
|
||||
console.error(
|
||||
`Different translations for the same key [${key}] found. ${file}: ${
|
||||
fileTranslations[key]
|
||||
}. Previous value: ${allTranslations[key]} was found in ${translationKeyToFiles[key].join(', ')}`
|
||||
);
|
||||
throw new Error(`Duplicate translation key found: ${key}`);
|
||||
}
|
||||
|
||||
allTranslations[key] = fileTranslations[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allTranslations;
|
||||
} catch (error) {
|
||||
console.error('Error extracting translations:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
module.exports = {
|
||||
extractTranslationsFromFile,
|
||||
extractAllTranslations,
|
||||
};
|
||||
@@ -0,0 +1,198 @@
|
||||
//@ts-check
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const { defaultLanguage } = require('./constants');
|
||||
const sortJsonKeysAlphabetically = require('./sortJsonKeysAlphabetically');
|
||||
|
||||
/**
|
||||
* @param {string} file
|
||||
* @param {string[]} extensions
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function hasValidExtension(file, extensions) {
|
||||
return extensions.includes(path.extname(file).toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} dir
|
||||
* @param {string[]} extensions
|
||||
*
|
||||
* @returns {Promise<string[]>}
|
||||
*/
|
||||
async function getFiles(dir, extensions) {
|
||||
const files = await fs.promises.readdir(dir);
|
||||
const allFiles = await Promise.all(
|
||||
files.map(async file => {
|
||||
const filePath = path.join(dir, file);
|
||||
const stats = await fs.promises.stat(filePath);
|
||||
|
||||
if (stats.isDirectory()) {
|
||||
return getFiles(filePath, extensions);
|
||||
} else if (stats.isFile() && hasValidExtension(file, extensions)) {
|
||||
const slashPath = filePath.replace(/\\/g, '/');
|
||||
if (slashPath.includes('/node_modules/') || slashPath.includes('/build/') || slashPath.includes('/dist/')) {
|
||||
return null;
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
return null;
|
||||
})
|
||||
);
|
||||
|
||||
const validFiles = /** @type {string[]} */ (allFiles.flat().filter(file => file !== null));
|
||||
|
||||
return validFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string | string[]} value
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
function formatDefaultValue(value) {
|
||||
if (Array.isArray(value)) {
|
||||
return value.join(', ');
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
const scriptDir = getScriptDir();
|
||||
/** @param {string} file
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
function resolveFile(file) {
|
||||
if (path.isAbsolute(file)) {
|
||||
return file;
|
||||
}
|
||||
|
||||
return path.resolve(scriptDir, '..', '..', file);
|
||||
}
|
||||
|
||||
/** @param {string[]} dirs
|
||||
*
|
||||
* @returns {string[]}
|
||||
*/
|
||||
function resolveDirs(dirs) {
|
||||
return dirs.map(resolveFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string[]} extensions
|
||||
*
|
||||
* @returns {string[]}
|
||||
*/
|
||||
function resolveExtensions(extensions) {
|
||||
return extensions.map(ext => (ext.startsWith('.') ? ext : `.${ext}`));
|
||||
}
|
||||
|
||||
function getScriptDir() {
|
||||
if (require.main?.filename) {
|
||||
return path.dirname(require.main.filename);
|
||||
}
|
||||
|
||||
if ('pkg' in process && process.pkg) {
|
||||
return path.dirname(process.execPath);
|
||||
}
|
||||
|
||||
return __dirname;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} file
|
||||
*/
|
||||
function ensureFileDirExists(file) {
|
||||
const dir = path.dirname(file);
|
||||
|
||||
if (!fs.existsSync(dir)) {
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Record<string, string>} existingTranslations - Previously extracted translations
|
||||
* @param {Record<string, string>} newTranslations - Newly extracted translations
|
||||
* @returns {{ added: string[], removed: string[], updated: string[] }} Translation changes
|
||||
*/
|
||||
const getTranslationChanges = (existingTranslations, newTranslations) => {
|
||||
const existingKeys = new Set(Object.keys(existingTranslations || {}));
|
||||
const newKeys = new Set(Object.keys(newTranslations));
|
||||
|
||||
const added = [...newKeys].filter(key => !existingKeys.has(key));
|
||||
const removed = [...existingKeys].filter(key => !newKeys.has(key));
|
||||
const updated = [...newKeys].filter(
|
||||
key => existingKeys.has(key) && existingTranslations[key] !== newTranslations[key]
|
||||
);
|
||||
|
||||
return { added, removed, updated };
|
||||
};
|
||||
|
||||
function getDefaultTranslations() {
|
||||
return getLanguageTranslations(defaultLanguage);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} language
|
||||
*
|
||||
* @returns {Record<string, string>}
|
||||
*/
|
||||
function getLanguageTranslations(language) {
|
||||
const file = resolveFile(`translations/${language}.json`);
|
||||
const content = fs.readFileSync(file, 'utf-8');
|
||||
|
||||
return JSON.parse(content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} language
|
||||
* @param {Record<string, string>} translations
|
||||
*/
|
||||
function setLanguageTranslations(language, translations) {
|
||||
const file = resolveFile(`translations/${language}.json`);
|
||||
const sorted = sortJsonKeysAlphabetically(translations);
|
||||
|
||||
fs.writeFileSync(file, JSON.stringify(sorted, null, 2));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} language
|
||||
* @param {Record<string, string>} newTranslations
|
||||
*/
|
||||
function updateLanguageTranslations(language, newTranslations) {
|
||||
const translations = getLanguageTranslations(language);
|
||||
const updatedTranslations = { ...translations, ...newTranslations };
|
||||
const sorted = sortJsonKeysAlphabetically(updatedTranslations);
|
||||
|
||||
setLanguageTranslations(language, sorted);
|
||||
}
|
||||
|
||||
function getAllLanguages() {
|
||||
const dir = resolveFile('translations');
|
||||
|
||||
const files = fs.readdirSync(dir);
|
||||
const languages = files.filter(file => file.endsWith('.json')).map(file => file.replace('.json', ''));
|
||||
|
||||
return languages;
|
||||
}
|
||||
|
||||
function getAllNonDefaultLanguages() {
|
||||
return getAllLanguages().filter(language => language !== defaultLanguage);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
hasValidExtension,
|
||||
getFiles,
|
||||
formatDefaultValue,
|
||||
resolveFile,
|
||||
resolveDirs,
|
||||
resolveExtensions,
|
||||
ensureFileDirExists,
|
||||
getTranslationChanges,
|
||||
getDefaultTranslations,
|
||||
getLanguageTranslations,
|
||||
setLanguageTranslations,
|
||||
updateLanguageTranslations,
|
||||
getAllLanguages,
|
||||
getAllNonDefaultLanguages,
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
const { program } = require('./program');
|
||||
|
||||
program.parse();
|
||||
@@ -0,0 +1,163 @@
|
||||
//@ts-check
|
||||
const fs = require('fs');
|
||||
const { program } = require('commander');
|
||||
const {
|
||||
resolveDirs,
|
||||
resolveExtensions,
|
||||
getTranslationChanges,
|
||||
setLanguageTranslations,
|
||||
getAllNonDefaultLanguages,
|
||||
updateLanguageTranslations,
|
||||
getDefaultTranslations,
|
||||
} = require('./helpers');
|
||||
const { extractAllTranslations } = require('./extract');
|
||||
const { getMissingTranslations } = require('./addMissing');
|
||||
const { defaultLanguage, defaultExtractConfig } = require('./constants');
|
||||
const { removeUnusedAllTranslations, removeUnusedForSignelLanguage } = require('./removeUnused');
|
||||
|
||||
/**
|
||||
* @typedef {import('./constants').ExtractConfig & { verbose?: boolean, ignoreUnused?: boolean }} ExtractOptions
|
||||
*/
|
||||
|
||||
program.name('dbgate-translations-cli').description('CLI tool for managing translation').version('1.0.0');
|
||||
|
||||
program
|
||||
.command('extract')
|
||||
.description('Extract translation keys from source files')
|
||||
.option('-d, --directories <directories...>', 'directories to search', defaultExtractConfig.directories)
|
||||
.option('-e, --extensions <extensions...>', 'file extensions to process', defaultExtractConfig.extensions)
|
||||
.option('-r, --ignoreUnused', 'Ignore unused keys in the output file')
|
||||
.option('-v, --verbose', 'verbose mode')
|
||||
.action(async (/** @type {ExtractOptions} */ options) => {
|
||||
try {
|
||||
const { directories, extensions, verbose, ignoreUnused } = options;
|
||||
|
||||
const resolvedRirectories = resolveDirs(directories);
|
||||
const resolvedExtensions = resolveExtensions(extensions);
|
||||
|
||||
const extractedTranslations = await extractAllTranslations(resolvedRirectories, resolvedExtensions);
|
||||
const defaultTranslations = getDefaultTranslations();
|
||||
|
||||
const { added, removed, updated } = getTranslationChanges(defaultTranslations, extractedTranslations);
|
||||
|
||||
console.log('\nTranslation changes:');
|
||||
console.log(`- Added: ${added.length} keys`);
|
||||
console.log(`- ${ignoreUnused ? 'Unused' : 'Removed'}: ${removed.length} keys`);
|
||||
console.log(`- Updated: ${updated.length} keys`);
|
||||
console.log(`- Total: ${Object.keys(extractedTranslations).length} keys`);
|
||||
|
||||
if (verbose) {
|
||||
if (added.length > 0) {
|
||||
console.log('\nNew keys:');
|
||||
added.forEach(key => console.log(` + ${key}`));
|
||||
}
|
||||
|
||||
if (removed.length > 0) {
|
||||
console.log('\nRemoved keys:');
|
||||
removed.forEach(key => console.log(` - ${key}`));
|
||||
}
|
||||
|
||||
if (updated.length > 0) {
|
||||
console.log('\nUpdated keys:');
|
||||
updated.forEach(key => {
|
||||
console.log(` ~ ${key}`);
|
||||
console.log(` Old: ${defaultLanguage[key]}`);
|
||||
console.log(` New: ${extractedTranslations[key]}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (ignoreUnused) {
|
||||
console.log('New translations were saved. Unused keys are kept.\n');
|
||||
updateLanguageTranslations(defaultLanguage, extractedTranslations);
|
||||
|
||||
if (verbose) {
|
||||
console.log('\nUnused keys:');
|
||||
for (const key of removed) {
|
||||
console.log(`${key}: "${defaultTranslations[key]}"`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log('Unused keys were removed.\n');
|
||||
setLanguageTranslations(defaultLanguage, extractedTranslations);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
console.error('Error during extraction:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
const ALL_LANGUAGES = 'all';
|
||||
|
||||
/**
|
||||
* @param {string} target
|
||||
*/
|
||||
function addMissingTranslations(target) {
|
||||
console.log(`Adding missing keys for language: ${target}`);
|
||||
const { result, stats } = getMissingTranslations(target);
|
||||
console.log(`Added: ${stats.added}, Removed: ${stats.removed}, Total: ${stats.newLength}`);
|
||||
setLanguageTranslations(target, result);
|
||||
console.log(`New translations for ${target} were saved.`);
|
||||
}
|
||||
|
||||
program
|
||||
.command('add-missing')
|
||||
.description('Add missing keys for a langauge to the translation file')
|
||||
.option('-t, --target <target>', 'language to add missing translations to', ALL_LANGUAGES)
|
||||
.action(options => {
|
||||
try {
|
||||
const { target } = options;
|
||||
const languages = getAllNonDefaultLanguages();
|
||||
|
||||
if (target === ALL_LANGUAGES) {
|
||||
console.log('Adding missing keys for all languages\n');
|
||||
for (const language of languages) {
|
||||
addMissingTranslations(language);
|
||||
console.log();
|
||||
}
|
||||
} else {
|
||||
addMissingTranslations(target);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
console.error('Error during add-missing:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
program
|
||||
.command('remove-unused')
|
||||
.description('Remove unused keys from the translation files')
|
||||
.option('-t, --target <target>', 'language to add missing translations to', ALL_LANGUAGES)
|
||||
.action(async options => {
|
||||
try {
|
||||
const { target } = options;
|
||||
if (target === ALL_LANGUAGES) {
|
||||
console.log('Removing unused keys from all languages\n');
|
||||
await removeUnusedAllTranslations();
|
||||
} else {
|
||||
await removeUnusedForSignelLanguage(target);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
console.error('Error during add-missing:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
program
|
||||
.command('check')
|
||||
.description('Check if there are multiple default values for the same key')
|
||||
.action(async () => {
|
||||
try {
|
||||
await extractAllTranslations(defaultExtractConfig.directories, defaultExtractConfig.extensions);
|
||||
console.log('No problems found while extracting translations.');
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
console.error('Error during check:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = { program };
|
||||
@@ -0,0 +1,46 @@
|
||||
// @ts-check
|
||||
const { defaultExtractConfig } = require('./constants');
|
||||
const { extractAllTranslations } = require('./extract');
|
||||
const { getLanguageTranslations, getAllLanguages, setLanguageTranslations } = require('./helpers');
|
||||
|
||||
const { directories, extensions } = defaultExtractConfig;
|
||||
|
||||
/**
|
||||
* @param {string} language
|
||||
* @param {Record<string, string>} source
|
||||
*/
|
||||
function getUsedTranslations(language, source) {
|
||||
const languageTranslations = getLanguageTranslations(language);
|
||||
|
||||
for (const key in languageTranslations) {
|
||||
if (!(key in source)) {
|
||||
delete languageTranslations[key];
|
||||
}
|
||||
}
|
||||
|
||||
return languageTranslations;
|
||||
}
|
||||
|
||||
async function removeUnusedAllTranslations() {
|
||||
const source = await extractAllTranslations(directories, extensions);
|
||||
const languages = getAllLanguages();
|
||||
|
||||
for (const language of languages) {
|
||||
const newTranslations = getUsedTranslations(language, source);
|
||||
setLanguageTranslations(language, newTranslations);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} language
|
||||
*/
|
||||
async function removeUnusedForSignelLanguage(language) {
|
||||
const source = await extractAllTranslations(directories, extensions);
|
||||
const newTranslations = getUsedTranslations(language, source);
|
||||
setLanguageTranslations(language, newTranslations);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
removeUnusedAllTranslations,
|
||||
removeUnusedForSignelLanguage,
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
// @ts-check
|
||||
|
||||
/**
|
||||
* @param {object|string} json
|
||||
* @returns {object}
|
||||
*/
|
||||
function sortJsonKeysAlphabetically(json) {
|
||||
const obj = typeof json === 'string' ? JSON.parse(json) : json;
|
||||
|
||||
if (obj === null || typeof obj !== 'object' || Array.isArray(obj)) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
const sortedObj = Object.keys(obj)
|
||||
.sort()
|
||||
.reduce((result, key) => {
|
||||
result[key] = obj[key];
|
||||
return result;
|
||||
}, {});
|
||||
|
||||
return sortedObj;
|
||||
}
|
||||
|
||||
module.exports = sortJsonKeysAlphabetically;
|
||||
@@ -14,12 +14,16 @@ const volatilePackages = [
|
||||
'ioredis',
|
||||
'node-redis-dump2',
|
||||
'better-sqlite3',
|
||||
'libsql',
|
||||
'@azure/cosmos',
|
||||
'@aws-sdk/rds-signer',
|
||||
'activedirectory2',
|
||||
'axios',
|
||||
'ssh2',
|
||||
'wkx',
|
||||
'@duckdb/node-api',
|
||||
'@mongosh/browser-runtime-electron',
|
||||
'@mongosh/service-provider-node-driver',
|
||||
];
|
||||
|
||||
module.exports = volatilePackages;
|
||||
|
||||
+23
-22
@@ -1,6 +1,6 @@
|
||||
# this compose file is for testing purposes only
|
||||
# use it for testing docker containsers built on local machine
|
||||
version: "3"
|
||||
version: '3'
|
||||
services:
|
||||
dbgate:
|
||||
build: docker
|
||||
@@ -15,31 +15,31 @@ services:
|
||||
|
||||
volumes:
|
||||
- dbgate-data:/root/.dbgate
|
||||
|
||||
|
||||
# environment:
|
||||
# WEB_ROOT: /dbgate
|
||||
|
||||
# CONNECTIONS: mssql
|
||||
# LABEL_mssql: MS Sql
|
||||
# SERVER_mssql: mssql
|
||||
# USER_mssql: sa
|
||||
# PORT_mssql: 1433
|
||||
# PASSWORD_mssql: Pwd2020Db
|
||||
# ENGINE_mssql: mssql@dbgate-plugin-mssql
|
||||
# proxy:
|
||||
# # image: nginx
|
||||
# build: test/nginx
|
||||
# ports:
|
||||
# - 8082:80
|
||||
# CONNECTIONS: mssql
|
||||
# LABEL_mssql: MS Sql
|
||||
# SERVER_mssql: mssql
|
||||
# USER_mssql: sa
|
||||
# PORT_mssql: 1433
|
||||
# PASSWORD_mssql: Pwd2020Db
|
||||
# ENGINE_mssql: mssql@dbgate-plugin-mssql
|
||||
proxy:
|
||||
# image: nginx
|
||||
build: test/nginx
|
||||
ports:
|
||||
- 8082:80
|
||||
|
||||
# volumes:
|
||||
# - /home/jena/test/chinook:/mnt/sqt
|
||||
# environment:
|
||||
# CONNECTIONS: sqlite
|
||||
volumes:
|
||||
- /home/jena/test/chinook:/mnt/sqt
|
||||
environment:
|
||||
CONNECTIONS: sqlite
|
||||
|
||||
# LABEL_sqlite: sqt
|
||||
# FILE_sqlite: /mnt/sqt/Chinook.db
|
||||
# ENGINE_sqlite: sqlite@dbgate-plugin-sqlite
|
||||
LABEL_sqlite: sqt
|
||||
FILE_sqlite: /mnt/sqt/Chinook.db
|
||||
ENGINE_sqlite: sqlite@dbgate-plugin-sqlite
|
||||
|
||||
# mssql:
|
||||
# image: mcr.microsoft.com/mssql/server
|
||||
@@ -51,4 +51,5 @@ services:
|
||||
|
||||
volumes:
|
||||
dbgate-data:
|
||||
driver: local
|
||||
driver: local
|
||||
|
||||
|
||||
+4
-13
@@ -1,21 +1,12 @@
|
||||
FROM ubuntu:22.04
|
||||
FROM node:22
|
||||
|
||||
LABEL org.opencontainers.image.source="https://github.com/dbgate/dbgate"
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
gnupg \
|
||||
iputils-ping \
|
||||
iproute2 \
|
||||
unixodbc \
|
||||
gcc \
|
||||
g++ \
|
||||
make
|
||||
|
||||
RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | gpg --dearmor -o /usr/share/keyrings/nodesource-archive-keyring.gpg \
|
||||
&& echo "deb [signed-by=/usr/share/keyrings/nodesource-archive-keyring.gpg] https://deb.nodesource.com/node_18.x jammy main" | tee /etc/apt/sources.list.d/nodesource.list \
|
||||
&& echo "deb-src [signed-by=/usr/share/keyrings/nodesource-archive-keyring.gpg] https://deb.nodesource.com/node_18.x jammy main" | tee -a /etc/apt/sources.list.d/nodesource.list \
|
||||
&& apt-get update && apt-get install -y nodejs \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& npm install -g yarn
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /home/dbgate-docker
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
FROM node:18-alpine
|
||||
|
||||
LABEL org.opencontainers.image.source="https://github.com/dbgate/dbgate"
|
||||
|
||||
WORKDIR /home/dbgate-docker
|
||||
|
||||
RUN apk --no-cache upgrade \
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
mysql: true,
|
||||
postgres: true,
|
||||
mssql: true,
|
||||
oracle: true,
|
||||
sqlite: true,
|
||||
mongo: true
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
const fs = require('fs');
|
||||
|
||||
const baseDir = path.join(os.homedir(), '.dbgate');
|
||||
|
||||
function clearTestingData() {
|
||||
if (fs.existsSync(path.join(baseDir, 'connections-e2etests.jsonl'))) {
|
||||
fs.unlinkSync(path.join(baseDir, 'connections-e2etests.jsonl'));
|
||||
}
|
||||
if (fs.existsSync(path.join(baseDir, 'settings-e2etests.json'))) {
|
||||
fs.unlinkSync(path.join(baseDir, 'settings-e2etests.json'));
|
||||
}
|
||||
if (fs.existsSync(path.join(baseDir, 'files-e2etests'))) {
|
||||
fs.rmdirSync(path.join(baseDir, 'files-e2etests'), { recursive: true });
|
||||
}
|
||||
if (fs.existsSync(path.join(baseDir, 'archive-e2etests'))) {
|
||||
fs.rmdirSync(path.join(baseDir, 'archive-e2etests'), { recursive: true });
|
||||
}
|
||||
if (fs.existsSync(path.join(__dirname, 'tmpdata', 'my_guitar_shop.db'))) {
|
||||
fs.unlinkSync(path.join(__dirname, 'tmpdata', 'my_guitar_shop.db'));
|
||||
}
|
||||
}
|
||||
|
||||
clearTestingData();
|
||||
@@ -1,6 +1,5 @@
|
||||
const { defineConfig } = require('cypress');
|
||||
const killPort = require('kill-port');
|
||||
const { clearTestingData } = require('./e2eTestTools');
|
||||
const waitOn = require('wait-on');
|
||||
const { exec } = require('child_process');
|
||||
const fs = require('fs');
|
||||
@@ -8,17 +7,22 @@ const path = require('path');
|
||||
|
||||
module.exports = defineConfig({
|
||||
e2e: {
|
||||
// baseUrl: 'http://localhost:3000',
|
||||
// trashAssetsBeforeRuns: false,
|
||||
chromeWebSecurity: false,
|
||||
|
||||
setupNodeEvents(on, config) {
|
||||
// implement node event listeners here
|
||||
|
||||
on('before:spec', async details => {
|
||||
await clearTestingData();
|
||||
// console.log('********************* DETAILS *********************', JSON.stringify(details));
|
||||
|
||||
if (config.isInteractive) {
|
||||
await killPort(3000);
|
||||
try {
|
||||
await killPort(3000);
|
||||
} catch (e) {
|
||||
console.warn('Error killing process on port 3000:', e.message);
|
||||
}
|
||||
switch (details.fileName) {
|
||||
case 'add-connection':
|
||||
serverProcess = exec('yarn start:add-connection');
|
||||
@@ -35,6 +39,15 @@ module.exports = defineConfig({
|
||||
case 'team':
|
||||
serverProcess = exec('yarn start:team');
|
||||
break;
|
||||
case 'multi-sql':
|
||||
serverProcess = exec('yarn start:multi-sql');
|
||||
break;
|
||||
case 'cloud':
|
||||
serverProcess = exec('yarn start:cloud');
|
||||
break;
|
||||
case 'charts':
|
||||
serverProcess = exec('yarn start:charts');
|
||||
break;
|
||||
}
|
||||
|
||||
await waitOn({ resources: ['http://localhost:3000'] });
|
||||
|
||||
@@ -13,16 +13,22 @@ describe('Add connection', () => {
|
||||
it('adds connection', () => {
|
||||
// cy.get('[data-testid=ConnectionList_buttonNewConnection]').click();
|
||||
cy.get('[data-testid=ConnectionDriverFields_connectionType]').select('MySQL');
|
||||
cy.themeshot('connection');
|
||||
cy.themeshot('new-connection');
|
||||
cy.get('[data-testid=ConnectionDriverFields_user]').clear().type('root');
|
||||
cy.get('[data-testid=ConnectionDriverFields_password]').clear().type('Pwd2020Db');
|
||||
cy.get('[data-testid=ConnectionDriverFields_port]').clear().type('16004');
|
||||
cy.get('[data-testid=ConnectionDriverFields_displayName]').clear().type('test-mysql-1');
|
||||
|
||||
// test connection
|
||||
cy.get('[data-testid=ConnectionTab_buttonTest]').click();
|
||||
cy.testid('ConnectionTab_buttonTest').click();
|
||||
cy.contains('Connected:');
|
||||
|
||||
cy.testid('ConnectionTab_tabSshTunnel').click();
|
||||
cy.testid('ConnectionTab_tabControlContent').themeshot('connection-sshtunnel-window', { padding: 50 });
|
||||
|
||||
cy.testid('ConnectionTab_tabSsl').click();
|
||||
cy.testid('ConnectionTab_tabControlContent').themeshot('connection-ssl-window', { padding: 50 });
|
||||
|
||||
// save and connect
|
||||
cy.get('[data-testid=ConnectionTab_buttonSave]').click();
|
||||
cy.get('[data-testid=ConnectionTab_buttonConnect]').click();
|
||||
@@ -106,4 +112,24 @@ describe('Add connection', () => {
|
||||
|
||||
cy.contains('performance_schema');
|
||||
});
|
||||
|
||||
it('export connections', () => {
|
||||
cy.testid('WidgetIconPanel_menu').click();
|
||||
cy.contains('Tools').click();
|
||||
cy.contains('Export connections').click();
|
||||
cy.themeshot('export-connections');
|
||||
});
|
||||
|
||||
it('configure LLM provider', () => {
|
||||
cy.testid('WidgetIconPanel_settings').click();
|
||||
cy.contains('Settings').click();
|
||||
cy.contains('AI').click();
|
||||
cy.testid('AiSupportedProvidersInfo_add_OpenRouter').click();
|
||||
cy.testid('AiProviderCard_apikey_OpenRouter').clear().type('xxx');
|
||||
cy.testid('AiProviderCard_testButton_OpenRouter').click();
|
||||
cy.testid('AiProviderCard_statusValid_OpenRouter').should('exist');
|
||||
cy.testid('AiProviderCard_editButton_OpenRouter').click();
|
||||
cy.wait(1000);
|
||||
cy.themeshot('llm-providers-settings');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,18 +15,23 @@ beforeEach(() => {
|
||||
describe('Data browser data', () => {
|
||||
it('Export window', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').rightclick();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.contains('Album').rightclick();
|
||||
cy.contains('Export').click();
|
||||
cy.contains('Export advanced').click();
|
||||
cy.wait(1000);
|
||||
// cy.testid('SourceTargetConfig_buttonCurrentArchive_target').click();
|
||||
cy.testid('FormTablesSelect_buttonAll_tables').click();
|
||||
// cy.testid('FormTablesSelect_buttonAll_tables').click();
|
||||
// cy.testid('SourceTargetConfig_tablesSelect_source').click();
|
||||
// cy.find('.listContainer').contains('Album').click();
|
||||
// cy.find('.listContainer').contains('Track').click();
|
||||
// cy.wait(4000);
|
||||
// cy.contains('All tables').click();
|
||||
cy.contains('Run').click();
|
||||
cy.contains('Finished job script');
|
||||
cy.contains('Album.csv');
|
||||
cy.testid('WidgetIconPanel_database').click();
|
||||
cy.themeshot('exportcsv');
|
||||
cy.themeshot('configure-export-csv');
|
||||
});
|
||||
|
||||
it('Data archive editor - macros', () => {
|
||||
@@ -37,7 +42,7 @@ describe('Data browser data', () => {
|
||||
cy.contains('Out Of Exile').click({ shiftKey: true });
|
||||
cy.contains('Change text case').click();
|
||||
cy.contains('AUDIOSLAVE');
|
||||
cy.themeshot('freetable');
|
||||
cy.themeshot('data-archive-macros');
|
||||
});
|
||||
|
||||
it('Load table data', () => {
|
||||
@@ -76,11 +81,25 @@ describe('Data browser data', () => {
|
||||
cy.contains('Aerosmith').should('not.exist');
|
||||
});
|
||||
|
||||
it('Data filter', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.contains('Album').click();
|
||||
cy.testid('DataFilterControl_input_Title').type('Rock{enter}');
|
||||
cy.contains('Rows: 7');
|
||||
cy.testid('DataFilterControl_input_AlbumId').type('>10xxx{enter}');
|
||||
cy.contains('Rows: 7');
|
||||
cy.testid('DataFilterControl_filtermenu_Title').click();
|
||||
// hide what is not needed
|
||||
cy.testid('WidgetIconPanel_database').click();
|
||||
cy.testid('DataGrid_itemReferences').click();
|
||||
cy.themeshot('data-browser-filter');
|
||||
cy.testid('DataGridCore_button_clearFilters').click();
|
||||
cy.contains('Rows: 347');
|
||||
});
|
||||
|
||||
it('Data grid screenshots', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.window().then(win => {
|
||||
win.__changeCurrentTheme('theme-dark');
|
||||
});
|
||||
|
||||
cy.contains('MyChinook').click();
|
||||
|
||||
@@ -95,16 +114,25 @@ describe('Data browser data', () => {
|
||||
cy.contains('PgChinook').click();
|
||||
cy.contains('customer').click();
|
||||
cy.contains('Leonie').click();
|
||||
cy.themeshot('datagrid');
|
||||
cy.themeshot('common-data-browser');
|
||||
|
||||
cy.contains('invoice').click();
|
||||
cy.contains('invoice_line (invoice_id)').click();
|
||||
cy.themeshot('masterdetail');
|
||||
cy.themeshot('data-browser-master-detail');
|
||||
|
||||
cy.contains('9, Place Louis Barthou').click();
|
||||
cy.contains('Switch to form').click();
|
||||
cy.contains('Switch to table'); // test that we are in form view
|
||||
cy.themeshot('formview');
|
||||
cy.themeshot('data-browser-form-view');
|
||||
});
|
||||
|
||||
it('Column search', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.contains('Customer').click();
|
||||
cy.testid('ColumnManager_searchColumns').clear().type('name,id{enter}');
|
||||
cy.contains('Company').should('not.exist');
|
||||
cy.themeshot('data-browser-column-search');
|
||||
});
|
||||
|
||||
it('SQL Gen', () => {
|
||||
@@ -112,7 +140,7 @@ describe('Data browser data', () => {
|
||||
cy.contains('PgChinook').rightclick();
|
||||
cy.contains('SQL Generator').click();
|
||||
cy.contains('Check all').click();
|
||||
cy.themeshot('sqlgen');
|
||||
cy.themeshot('sql-generator');
|
||||
});
|
||||
|
||||
it('Macros in DB', () => {
|
||||
@@ -127,7 +155,7 @@ describe('Data browser data', () => {
|
||||
cy.testid('DataGrid_itemMacros').click();
|
||||
cy.contains('Change text case').click();
|
||||
cy.contains('NIELSEN');
|
||||
cy.themeshot('macros');
|
||||
cy.themeshot('data-browser-macros');
|
||||
});
|
||||
|
||||
it('Perspectives', () => {
|
||||
@@ -143,7 +171,7 @@ describe('Data browser data', () => {
|
||||
// check track is loaded
|
||||
cy.contains('Put The Finger On You');
|
||||
|
||||
cy.themeshot('perspective1');
|
||||
cy.themeshot('perspective-designer');
|
||||
});
|
||||
|
||||
it('Query editor - code completion', () => {
|
||||
@@ -152,24 +180,26 @@ describe('Data browser data', () => {
|
||||
cy.contains('Customer').rightclick();
|
||||
cy.contains('SQL template').click();
|
||||
cy.contains('CREATE TABLE').click();
|
||||
cy.wait(1000);
|
||||
cy.get('body').realPress('PageDown');
|
||||
cy.get('body').realType('select * from Album where Album.');
|
||||
// code completion
|
||||
cy.contains('ArtistId');
|
||||
cy.themeshot('query');
|
||||
cy.themeshot('query-editor-code-completion');
|
||||
});
|
||||
|
||||
it('Query editor - join wizard', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.testid('TabsPanel_buttonNewQuery').click();
|
||||
cy.testid('TabsPanel_buttonNewObject').click();
|
||||
cy.testid('NewObjectModal_query').click();
|
||||
cy.wait(1000);
|
||||
cy.get('body').realType('select * from Invoice');
|
||||
cy.get('body').realPress('{enter}');
|
||||
cy.get('body').realPress(['Control', 'j']);
|
||||
// JOIN wizard
|
||||
cy.contains('INNER JOIN Customer ON Invoice.CustomerId = Customer.CustomerId');
|
||||
cy.themeshot('joinwizard');
|
||||
cy.themeshot('query-editor-join-wizard');
|
||||
});
|
||||
|
||||
it('Mongo JSON data view', () => {
|
||||
@@ -186,7 +216,7 @@ describe('Data browser data', () => {
|
||||
cy.testid('WidgetIconPanel_cell-data').click();
|
||||
// test JSON view
|
||||
cy.contains('Country: "Brazil"');
|
||||
cy.themeshot('mongoquery');
|
||||
cy.themeshot('mongo-query-json-view');
|
||||
});
|
||||
|
||||
it('SQL preview', () => {
|
||||
@@ -196,7 +226,7 @@ describe('Data browser data', () => {
|
||||
cy.contains('Show SQL').click();
|
||||
// index should be part of create script
|
||||
cy.contains('CREATE INDEX `IFK_CustomerSupportRepId`');
|
||||
cy.themeshot('sqlpreview');
|
||||
cy.themeshot('sql-preview-create-index');
|
||||
});
|
||||
|
||||
it('Query designer', () => {
|
||||
@@ -205,7 +235,7 @@ describe('Data browser data', () => {
|
||||
cy.testid('WidgetIconPanel_file').click();
|
||||
cy.contains('customer').click();
|
||||
// cy.contains('left join').rightclick();
|
||||
cy.themeshot('querydesigner');
|
||||
cy.themeshot('query-designer');
|
||||
});
|
||||
|
||||
it('Database diagram', () => {
|
||||
@@ -216,24 +246,24 @@ describe('Data browser data', () => {
|
||||
cy.testid('WidgetIconPanel_file').click();
|
||||
// check diagram is shown
|
||||
cy.contains('MediaTypeId');
|
||||
cy.themeshot('diagram');
|
||||
cy.themeshot('database-diagram');
|
||||
});
|
||||
|
||||
it('Charts', () => {
|
||||
cy.testid('WidgetIconPanel_file').click();
|
||||
cy.contains('pie-chart').click();
|
||||
cy.contains('line-chart').click();
|
||||
cy.testid('TabsPanel_buttonSplit').click();
|
||||
cy.testid('WidgetIconPanel_file').click();
|
||||
cy.themeshot('charts');
|
||||
});
|
||||
// it('Charts', () => {
|
||||
// cy.testid('WidgetIconPanel_file').click();
|
||||
// cy.contains('pie-chart').click();
|
||||
// cy.contains('line-chart').click();
|
||||
// cy.testid('TabsPanel_buttonSplit').click();
|
||||
// cy.testid('WidgetIconPanel_file').click();
|
||||
// cy.themeshot('view-split-charts');
|
||||
// });
|
||||
|
||||
it('Keyboard configuration', () => {
|
||||
cy.testid('WidgetIconPanel_settings').click();
|
||||
cy.contains('Keyboard shortcuts').click();
|
||||
cy.contains('dataForm.refresh').click();
|
||||
cy.testid('CommandModal_keyboardButton').click();
|
||||
cy.themeshot('keyboard');
|
||||
cy.themeshot('keyboard-configuration');
|
||||
});
|
||||
|
||||
it('Command palette', () => {
|
||||
@@ -244,7 +274,15 @@ describe('Data browser data', () => {
|
||||
// cy.realPress('F1');
|
||||
cy.realPress('PageDown');
|
||||
cy.realPress('PageDown');
|
||||
cy.testid('CommandPalette_main').themeshot('commandpalette', { padding: 50 });
|
||||
cy.testid('CommandPalette_main').themeshot('command-palette', { padding: 50 });
|
||||
});
|
||||
|
||||
it('About window', () => {
|
||||
cy.contains('Connections');
|
||||
cy.testid('WidgetIconPanel_menu').click();
|
||||
cy.contains('Help').click();
|
||||
cy.contains('About').click();
|
||||
cy.testid('ModalBase_window').themeshot('about-window', { padding: 50 });
|
||||
});
|
||||
|
||||
it('Show map', () => {
|
||||
@@ -257,7 +295,7 @@ describe('Data browser data', () => {
|
||||
cy.contains('13.9').click({ shiftKey: true });
|
||||
cy.testid('WidgetIconPanel_cell-data').click();
|
||||
cy.wait(2000);
|
||||
cy.themeshot('map');
|
||||
cy.themeshot('cell-map-view');
|
||||
});
|
||||
|
||||
it('Search in connections', () => {
|
||||
@@ -269,17 +307,18 @@ describe('Data browser data', () => {
|
||||
cy.contains('Album').click();
|
||||
cy.testid('SqlObjectList_searchMenuDropDown').click();
|
||||
cy.contains('Column name').click();
|
||||
cy.themeshot('connsearch');
|
||||
cy.themeshot('search-in-connections');
|
||||
});
|
||||
|
||||
it('Plugin tab', () => {
|
||||
cy.testid('WidgetIconPanel_plugins').click();
|
||||
cy.testid('WidgetIconPanel_settings').click();
|
||||
cy.contains('Manage plugins').click();
|
||||
cy.contains('dbgate-plugin-theme-total-white').click();
|
||||
// text from plugin markdown
|
||||
cy.contains('Total white theme');
|
||||
// wait for load logos
|
||||
cy.wait(2000);
|
||||
cy.themeshot('plugin');
|
||||
cy.themeshot('view-plugin-tab');
|
||||
});
|
||||
|
||||
it('Edit mongo data JSON', () => {
|
||||
@@ -306,7 +345,7 @@ describe('Data browser data', () => {
|
||||
cy.contains('Helena').rightclick();
|
||||
cy.contains('Delete document').click();
|
||||
cy.contains('Save').click();
|
||||
cy.themeshot('mongosave');
|
||||
cy.themeshot('save-changes-mongodb');
|
||||
});
|
||||
|
||||
it('Edit mongo data JSON', () => {
|
||||
@@ -320,7 +359,7 @@ describe('Data browser data', () => {
|
||||
cy.testid('ColumnManagerRow_checkbox__id').click();
|
||||
cy.testid('DataFilterControl_input_countries.1').type('EXISTS{enter}');
|
||||
cy.testid('WidgetIconPanel_cell-data').click();
|
||||
cy.themeshot('collection');
|
||||
cy.themeshot('mongodb-json-cell-view');
|
||||
});
|
||||
|
||||
it('Table structure editor', () => {
|
||||
@@ -329,10 +368,10 @@ describe('Data browser data', () => {
|
||||
cy.contains('Customer').rightclick();
|
||||
cy.contains('Open structure').click();
|
||||
cy.contains('varchar(40)');
|
||||
cy.themeshot('structure');
|
||||
cy.themeshot('table-structure-editor');
|
||||
cy.contains('EmployeeId').click();
|
||||
cy.contains('Ref column - Employee');
|
||||
cy.themeshot('fkeditor');
|
||||
cy.themeshot('foreign-key-editor');
|
||||
});
|
||||
|
||||
it('Compare database', () => {
|
||||
@@ -344,22 +383,104 @@ describe('Data browser data', () => {
|
||||
cy.testid('CompareModelTab_gridObjects_Customer_Customer').click();
|
||||
cy.testid('WidgetIconPanel_database').click();
|
||||
cy.testid('CompareModelTab_tabDdl').click();
|
||||
cy.themeshot('dbcompare');
|
||||
cy.themeshot('compare-database-models');
|
||||
cy.contains('Settings').click();
|
||||
cy.testid('CompareModelTab_tabOperations').click();
|
||||
cy.themeshot('comparesettings');
|
||||
cy.themeshot('compare-database-settings');
|
||||
});
|
||||
|
||||
it.only('Query editor - AI assistant', () => {
|
||||
it('Modify data', () => {
|
||||
// TODO FIX: delete references cascade not working
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.testid('TabsPanel_buttonNewQuery').click();
|
||||
cy.testid('QueryTab_switchAiAssistantButton').click();
|
||||
cy.testid('QueryAiAssistant_promptInput').type('album names');
|
||||
cy.testid('QueryAiAssistant_queryFromQuestionButton').click();
|
||||
cy.contains('Use this').click();
|
||||
cy.testid('QueryTab_executeButton').click();
|
||||
cy.contains('Balls to the Wall');
|
||||
cy.themeshot('aiassistant');
|
||||
cy.contains('Employee').click();
|
||||
cy.contains('Rows: 8');
|
||||
|
||||
cy.contains('Laura').click();
|
||||
cy.contains('Laura').click();
|
||||
cy.get('body').realType('Jane');
|
||||
// cy.contains('Peacock').click();
|
||||
// cy.testid('TableDataTab_deleteSelectedRows').click();
|
||||
cy.contains('King').click();
|
||||
cy.testid('TableDataTab_deleteSelectedRows').click();
|
||||
cy.testid('TableDataTab_insertNewRow').click();
|
||||
cy.get('body').realType('Novak');
|
||||
cy.get('body').realPress('{enter}');
|
||||
cy.realPress(['ArrowRight']);
|
||||
cy.get('body').realType('Karel');
|
||||
cy.testid('TableDataTab_save').click();
|
||||
cy.contains('INSERT INTO `Employee`');
|
||||
cy.contains("SET `FirstName`='Jane'");
|
||||
cy.contains('DELETE FROM `Employee`');
|
||||
cy.themeshot('data-browser-save-changes');
|
||||
|
||||
// cy.testid('ConfirmSqlModal_okButton').click();
|
||||
// cy.contains('Cannot delete or update a parent row')
|
||||
// cy.testid('ConfirmSqlModal_okButton').click();
|
||||
|
||||
// cy.testid('TableDataTab_save').click();
|
||||
// cy.testid('ConfirmSqlModal_deleteReferencesCascade').click();
|
||||
// cy.testid('ConfirmSqlModal_okButton').click();
|
||||
|
||||
cy.testid('ConfirmSqlModal_okButton').click();
|
||||
|
||||
cy.contains('Novak');
|
||||
cy.contains('Rows: 8');
|
||||
});
|
||||
|
||||
it('Export menu', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.contains('Album').click();
|
||||
cy.testid('DataFilterControl_input_ArtistId').type('22{enter}');
|
||||
// cy.contains('Presence').rightclick();
|
||||
// cy.contains('Coda').rightclick();
|
||||
// cy.testid('DropDownMenu-container-0').contains('Export').click();
|
||||
cy.contains('Export').click();
|
||||
// cy.wait(1000);
|
||||
cy.themeshot('data-browser-export-menu');
|
||||
});
|
||||
|
||||
it('MySQL native backup', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').rightclick();
|
||||
cy.contains('Create database backup').click();
|
||||
cy.contains('Customer');
|
||||
cy.themeshot('mysql-backup-configuration');
|
||||
});
|
||||
|
||||
it('View table YAML model', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').rightclick();
|
||||
cy.contains('Export DB model').click();
|
||||
cy.testid('ExportDbModelModal_archiveFolder').select('(Create new)');
|
||||
cy.testid('InputTextModal_value').clear().type('test-model');
|
||||
cy.testid('InputTextModal_ok').click();
|
||||
cy.testid('ModalBase_window').themeshot('export-database-model-window', { padding: 50 });
|
||||
cy.testid('ExportDbModelModal_exportButton').click();
|
||||
cy.contains('Album').click();
|
||||
cy.contains('autoIncrement');
|
||||
cy.themeshot('database-model-table-yaml');
|
||||
});
|
||||
|
||||
it('Data replicator', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.testid('WidgetIconPanel_archive').click();
|
||||
cy.contains('chinook-archive').rightclick();
|
||||
cy.contains('Data deployer').click();
|
||||
cy.contains('Dry run').click();
|
||||
cy.testid('TableControl_row_2_checkbox').click();
|
||||
cy.testid('TableControl_row_2').click();
|
||||
cy.testid('DataDeploySettings_find_checkbox').click();
|
||||
cy.testid('DataDeploySettings_create_checkbox').click();
|
||||
cy.testid('WidgetIconPanel_archive').click();
|
||||
cy.themeshot('data-deployer');
|
||||
cy.testid('DataDeployTab_importIntoDb').click();
|
||||
cy.testid('ConfirmDataDeployModal_okButton').click();
|
||||
cy.contains('Replicated Customer, inserted 59 rows');
|
||||
cy.contains('Finished job script');
|
||||
cy.testid('DataDeployTab_importIntoDb').click();
|
||||
cy.themeshot('data-replicator');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
Cypress.on('uncaught:exception', (err, runnable) => {
|
||||
// if the error message matches the one about WorkerGlobalScope importScripts
|
||||
if (err.message.includes("Failed to execute 'importScripts' on 'WorkerGlobalScope'")) {
|
||||
// return false to let Cypress know we intentionally want to ignore this error
|
||||
return false;
|
||||
}
|
||||
// otherwise let Cypress throw the error
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.visit('http://localhost:3000');
|
||||
cy.viewport(1250, 900);
|
||||
});
|
||||
|
||||
describe('Charts', () => {
|
||||
it('Auto detect chart', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('charts_sample').click();
|
||||
cy.testid('WidgetIconPanel_file').click();
|
||||
cy.contains('chart1').click();
|
||||
cy.contains('department_name');
|
||||
// cy.testid('QueryTab_executeButton').click();
|
||||
// cy.testid('QueryTab_openChartButton').click();
|
||||
cy.testid('chart-canvas').should($c => expect($c[0].toDataURL()).to.match(/^data:image\/png;base64/));
|
||||
cy.themeshot('choose-detected-chart');
|
||||
});
|
||||
|
||||
it('Two line charts', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.testid('TabsPanel_buttonNewObject').click();
|
||||
cy.testid('NewObjectModal_query').click();
|
||||
cy.wait(1000);
|
||||
cy.get('body').realType('SELECT InvoiceDate, Total from Invoice');
|
||||
cy.contains('Execute').click();
|
||||
cy.contains('Open chart').click();
|
||||
cy.testid('chart-canvas').should($c => expect($c[0].toDataURL()).to.match(/^data:image\/png;base64/));
|
||||
cy.themeshot('two-line-charts');
|
||||
});
|
||||
|
||||
it('Invoice naive autodetection', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.testid('TabsPanel_buttonNewObject').click();
|
||||
cy.testid('NewObjectModal_query').click();
|
||||
cy.wait(1000);
|
||||
cy.get('body').realType('SELECT * from Invoice');
|
||||
cy.contains('Execute').click();
|
||||
cy.contains('Open chart').click();
|
||||
cy.testid('chart-canvas').should($c => expect($c[0].toDataURL()).to.match(/^data:image\/png;base64/));
|
||||
cy.themeshot('chart-naive-autodetection');
|
||||
});
|
||||
|
||||
it('Invoice by country - grouped chart', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.testid('TabsPanel_buttonNewObject').click();
|
||||
cy.testid('NewObjectModal_query').click();
|
||||
cy.wait(1000);
|
||||
cy.get('body').realType(
|
||||
"SELECT InvoiceDate, Total, BillingCountry from Invoice where BillingCountry in ('USA', 'Canada', 'Brazil', 'France', 'Germany')"
|
||||
);
|
||||
cy.contains('Execute').click();
|
||||
cy.contains('Open chart').click();
|
||||
cy.testid('ChartSelector_chart_1').click();
|
||||
cy.testid('JslChart_customizeButton').click();
|
||||
|
||||
cy.testid('chart-canvas').should($c => expect($c[0].toDataURL()).to.match(/^data:image\/png;base64/));
|
||||
cy.themeshot('chart-grouped-autodetected');
|
||||
|
||||
cy.testid('ChartDefinitionEditor_chartTypeSelect').select('Bar');
|
||||
cy.testid('ChartDefinitionEditor_xAxisTransformSelect').select('Date (Year)');
|
||||
|
||||
cy.testid('chart-canvas').should($c => expect($c[0].toDataURL()).to.match(/^data:image\/png;base64/));
|
||||
cy.themeshot('chart-grouped-bars');
|
||||
});
|
||||
|
||||
it('Public Knowledge base - show chart', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.testid('WidgetIconPanel_cloud-public').click();
|
||||
cy.testid('public-cloud-file-tag-mysql/folder-MySQL/tag-premium/top-tables-row-count.sql').click();
|
||||
cy.testid('chart-canvas').should($c => expect($c[0].toDataURL()).to.match(/^data:image\/png;base64/));
|
||||
cy.themeshot('public-knowledge-base-tables-sizes');
|
||||
});
|
||||
|
||||
it('Auto detect chart', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.contains('Invoice').rightclick();
|
||||
cy.contains('SQL template').click();
|
||||
cy.contains('SELECT').click();
|
||||
cy.testid('QueryTab_detectChartButton').click();
|
||||
cy.testid('QueryTab_executeButton').click();
|
||||
cy.contains('Chart 1').click();
|
||||
cy.testid('ChartSelector_chart_0').click();
|
||||
cy.testid('JslChart_customizeButton').click();
|
||||
cy.testid('ChartDefinitionEditor_chartTypeSelect').select('Bar');
|
||||
cy.testid('ChartDefinitionEditor_chartTypeSelect').select('Line');
|
||||
cy.testid('chart-canvas').should($c => expect($c[0].toDataURL()).to.match(/^data:image\/png;base64/));
|
||||
cy.themeshot('query-result-chart');
|
||||
});
|
||||
|
||||
it('New object window', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.contains('Invoice').click();
|
||||
cy.testid('WidgetIconPanel_addButton').click();
|
||||
cy.contains('Compare database');
|
||||
cy.themeshot('new-object-window');
|
||||
});
|
||||
|
||||
it.only('Database chat - charts', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.testid('TabsPanel_buttonNewObject').click();
|
||||
cy.testid('NewObjectModal_databaseChat').click();
|
||||
cy.wait(1000);
|
||||
cy.get('body').realType('show me chart of most popular genres');
|
||||
cy.get('body').realPress('{enter}');
|
||||
cy.testid('DatabaseChatTab_executeAllQueries', { timeout: 30000 }).click();
|
||||
cy.testid('chart-canvas', { timeout: 30000 }).should($c => expect($c[0].toDataURL()).to.match(/^data:image\/png;base64/));
|
||||
cy.themeshot('database-chat-chart');
|
||||
});
|
||||
|
||||
it('Database chat', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.testid('TabsPanel_buttonNewObject').click();
|
||||
cy.testid('NewObjectModal_databaseChat').click();
|
||||
cy.wait(1000);
|
||||
cy.get('body').realType('find most popular artist');
|
||||
cy.get('body').realPress('{enter}');
|
||||
cy.testid('DatabaseChatTab_executeAllQueries', { timeout: 30000 }).click();
|
||||
cy.wait(30000);
|
||||
// cy.contains('Iron Maiden');
|
||||
cy.themeshot('database-chat');
|
||||
|
||||
// cy.testid('DatabaseChatTab_promptInput').click();
|
||||
// cy.get('body').realType('I need top 10 songs with the biggest income');
|
||||
// cy.get('body').realPress('{enter}');
|
||||
// cy.contains('Hot Girl', { timeout: 20000 });
|
||||
// cy.wait(1000);
|
||||
// cy.themeshot('database-chat');
|
||||
});
|
||||
|
||||
it('Explain query error', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.testid('TabsPanel_buttonNewObject').click();
|
||||
cy.testid('NewObjectModal_query').click();
|
||||
cy.wait(1000);
|
||||
cy.get('body').realType('select * from Invoice2');
|
||||
cy.contains('Execute').click();
|
||||
cy.testid('MessageViewRow-explainErrorButton-1').click();
|
||||
cy.testid('ChatCodeRenderer_useSqlButton', { timeout: 30000 });
|
||||
cy.themeshot('explain-query-error');
|
||||
|
||||
// cy.testid('TabsPanel_buttonNewObject').click();
|
||||
// cy.testid('NewObjectModal_databaseChat').click();
|
||||
// cy.wait(1000);
|
||||
// cy.get('body').realType('show me chart of most popular genres');
|
||||
// cy.get('body').realPress('{enter}');
|
||||
// cy.testid('DatabaseChatTab_executeAllQueries', { timeout: 30000 }).click();
|
||||
// cy.wait(5000);
|
||||
// cy.testid('chart-canvas').should($c => expect($c[0].toDataURL()).to.match(/^data:image\/png;base64/));
|
||||
// cy.themeshot('database-chat-chart');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,56 @@
|
||||
Cypress.on('uncaught:exception', (err, runnable) => {
|
||||
// if the error message matches the one about WorkerGlobalScope importScripts
|
||||
if (err.message.includes("Failed to execute 'importScripts' on 'WorkerGlobalScope'")) {
|
||||
// return false to let Cypress know we intentionally want to ignore this error
|
||||
return false;
|
||||
}
|
||||
// otherwise let Cypress throw the error
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.visit('http://localhost:3000');
|
||||
cy.viewport(1250, 900);
|
||||
});
|
||||
|
||||
describe('Cloud tests', () => {
|
||||
it('Private cloud', () => {
|
||||
cy.testid('WidgetIconPanel_cloudAccount');
|
||||
cy.window().then(win => {
|
||||
win.__loginToCloudTest('dbgate.test@gmail.com');
|
||||
});
|
||||
cy.contains('dbgate.test@gmail.com');
|
||||
|
||||
// cy.testid('WidgetIconPanel_cloudAccount').click();
|
||||
|
||||
// cy.origin('https://identity.dbgate.io', () => {
|
||||
// cy.contains('Sign in with GitHub').click();
|
||||
// });
|
||||
|
||||
// cy.origin('https://github.com', () => {
|
||||
// cy.get('#login_field').type('dbgatetest');
|
||||
// cy.get('#password').type('Pwd2020Db');
|
||||
// cy.get('input[type="submit"]').click();
|
||||
// });
|
||||
|
||||
// cy.wait(3000);
|
||||
|
||||
// cy.location('origin').then(origin => {
|
||||
// if (origin === 'https://github.com') {
|
||||
// // Still on github.com → an authorization step is waiting
|
||||
// cy.origin('https://github.com', () => {
|
||||
// // Try once, don't wait the full default timeout
|
||||
// cy.get('button[data-octo-click="oauth_application_authorization"]', { timeout: 500, log: false }).click(); // if the button exists it will be clicked
|
||||
// // if not, the short timeout elapses and we drop out
|
||||
// });
|
||||
// } else {
|
||||
// // Already back on localhost – nothing to authorize
|
||||
// cy.log('OAuth redirect skipped the Authorize screen');
|
||||
// }
|
||||
// });
|
||||
|
||||
cy.contains('Testing Connections').rightclick();
|
||||
cy.contains('Administrate access').click();
|
||||
cy.contains('User email');
|
||||
cy.themeshot('administer-shared-folder');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,203 @@
|
||||
const localconfig = require('../../.localconfig');
|
||||
const { formatQueryWithoutParams } = require('dbgate-tools');
|
||||
|
||||
global.DBGATE_PACKAGES = {
|
||||
'dbgate-tools': require('dbgate-tools'),
|
||||
};
|
||||
|
||||
function requireEngineDriver(engine) {
|
||||
const [shortName, packageName] = engine.split('@');
|
||||
const plugin = require(`../../../plugins/${packageName}/src/frontend/index`);
|
||||
if (plugin.drivers) {
|
||||
return plugin.drivers.find(x => x.engine == engine);
|
||||
}
|
||||
throw new Error(`Could not find engine driver ${engine}`);
|
||||
}
|
||||
|
||||
Cypress.on('uncaught:exception', (err, runnable) => {
|
||||
// if the error message matches the one about WorkerGlobalScope importScripts
|
||||
if (err.message.includes("Failed to execute 'importScripts' on 'WorkerGlobalScope'")) {
|
||||
// return false to let Cypress know we intentionally want to ignore this error
|
||||
return false;
|
||||
}
|
||||
// otherwise let Cypress throw the error
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.visit('http://localhost:3000');
|
||||
cy.viewport(1250, 900);
|
||||
});
|
||||
|
||||
function multiTest(testProps, testDefinition) {
|
||||
if (localconfig.mysql) {
|
||||
it('MySQL', () => testDefinition('MySql-connection', 'my_guitar_shop', 'mysql@dbgate-plugin-mysql'));
|
||||
}
|
||||
if (localconfig.postgres) {
|
||||
it('Postgres', () => testDefinition('Postgres-connection', 'my_guitar_shop', 'postgres@dbgate-plugin-postgres'));
|
||||
}
|
||||
if (localconfig.mssql) {
|
||||
it('Mssql', () => testDefinition('Mssql-connection', 'my_guitar_shop', 'mssql@dbgate-plugin-mssql'));
|
||||
}
|
||||
if (localconfig.oracle) {
|
||||
it('Oracle', () =>
|
||||
testDefinition('Oracle-connection', 'C##MY_GUITAR_SHOP', 'oracle@dbgate-plugin-oracle', {
|
||||
implicitTransactions: true,
|
||||
}));
|
||||
}
|
||||
if (localconfig.sqlite) {
|
||||
it('Sqlite', () => testDefinition('Sqlite-connection', null, 'sqlite@dbgate-plugin-sqlite'));
|
||||
}
|
||||
if (localconfig.mongo && !testProps.skipMongo) {
|
||||
it('MongoDB', () => testDefinition('Mongo-connection', 'my_guitar_shop', 'mongo@dbgate-plugin-mongo'));
|
||||
}
|
||||
}
|
||||
|
||||
describe('Transactions', () => {
|
||||
multiTest({ skipMongo: true }, (connectionName, databaseName, engine, options = {}) => {
|
||||
const driver = requireEngineDriver(engine);
|
||||
const implicitTransactions = options.implicitTransactions ?? false;
|
||||
|
||||
cy.contains(connectionName).click();
|
||||
if (databaseName) cy.contains(databaseName).click();
|
||||
cy.testid('TabsPanel_buttonNewObject').click();
|
||||
cy.testid('NewObjectModal_query').click();
|
||||
cy.wait(1000);
|
||||
cy.get('body').type(
|
||||
formatQueryWithoutParams(driver, "INSERT INTO ~categories (~category_id, ~category_name) VALUES (5, 'test');")
|
||||
);
|
||||
|
||||
// rollback
|
||||
if (!implicitTransactions) {
|
||||
cy.testid('QueryTab_beginTransactionButton').click();
|
||||
cy.contains('Begin Transaction finished');
|
||||
}
|
||||
cy.testid('QueryTab_executeButton').click();
|
||||
cy.contains('Query execution finished');
|
||||
cy.testid('QueryTab_rollbackTransactionButton').click();
|
||||
cy.contains('Rollback Transaction finished');
|
||||
|
||||
// should contain 4 rows
|
||||
cy.testid('SqlObjectList_container').contains('categories').click();
|
||||
cy.contains('Guitars').click();
|
||||
cy.testid('TableDataTab_refreshGrid').click();
|
||||
cy.contains('Rows: 4');
|
||||
|
||||
// commit
|
||||
cy.contains('Query #1').click();
|
||||
if (!implicitTransactions) {
|
||||
cy.testid('QueryTab_beginTransactionButton').click();
|
||||
cy.contains('Begin Transaction finished');
|
||||
}
|
||||
cy.testid('QueryTab_executeButton').click();
|
||||
cy.contains('Query execution finished');
|
||||
cy.testid('QueryTab_commitTransactionButton').click();
|
||||
cy.contains('Commit Transaction finished');
|
||||
|
||||
// should contain 5 rows
|
||||
cy.testid('SqlObjectList_container').contains('categories').click();
|
||||
cy.contains('Guitars').click();
|
||||
cy.testid('TableDataTab_refreshGrid').click();
|
||||
cy.contains('Rows: 5');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Backup table', () => {
|
||||
multiTest({ skipMongo: true }, (connectionName, databaseName, engine, options = {}) => {
|
||||
cy.contains(connectionName).click();
|
||||
if (databaseName) cy.contains(databaseName).click();
|
||||
cy.contains('customers').rightclick();
|
||||
cy.contains('Create table backup').click();
|
||||
cy.testid('ConfirmSqlModal_okButton').click();
|
||||
cy.contains('_customers').click();
|
||||
cy.contains('Rows: 8').should('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Truncate table', () => {
|
||||
multiTest({ skipMongo: true }, (connectionName, databaseName, engine, options = {}) => {
|
||||
cy.contains(connectionName).click();
|
||||
if (databaseName) cy.contains(databaseName).click();
|
||||
cy.contains('order_items').rightclick();
|
||||
cy.contains('Truncate table').click();
|
||||
cy.testid('ConfirmSqlModal_okButton').click();
|
||||
cy.contains('order_items').click();
|
||||
cy.contains('No rows loaded').should('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Drop table', () => {
|
||||
multiTest({ skipMongo: true }, (connectionName, databaseName, engine, options = {}) => {
|
||||
cy.contains(connectionName).click();
|
||||
if (databaseName) cy.contains(databaseName).click();
|
||||
cy.contains('order_items').rightclick();
|
||||
cy.contains('Drop table').click();
|
||||
cy.testid('ConfirmSqlModal_okButton').click();
|
||||
cy.contains('order_items').should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Import CSV', () => {
|
||||
multiTest({}, (connectionName, databaseName, engine, options = {}) => {
|
||||
cy.contains(connectionName).click();
|
||||
if (databaseName) cy.contains(databaseName).click();
|
||||
cy.testid('ConnectionList_container')
|
||||
.contains(databaseName ?? connectionName)
|
||||
.rightclick();
|
||||
cy.contains('Import').click();
|
||||
|
||||
cy.get('input[type=file]').selectFile('cypress/fixtures/customers-20.csv', { force: true });
|
||||
cy.contains('customers-20');
|
||||
cy.testid('ImportExportTab_preview_content').contains('50ddd99fAdF48B3').should('be.visible');
|
||||
|
||||
cy.testid('ImportExportTab_executeButton').click();
|
||||
cy.contains('20 rows written').should('be.visible');
|
||||
|
||||
cy.testid('SqlObjectList_refreshButton').click();
|
||||
cy.testid('SqlObjectList_container').contains('customers-20').click();
|
||||
cy.contains('Rows: 20').should('be.visible');
|
||||
|
||||
// cy.get('table tbody tr')
|
||||
// .eq(1)
|
||||
// .within(() => {
|
||||
// cy.get('select').select('Append data');
|
||||
// });
|
||||
});
|
||||
});
|
||||
|
||||
describe('Import CSV - source error', () => {
|
||||
multiTest({}, (connectionName, databaseName, engine, options = {}) => {
|
||||
cy.contains(connectionName).click();
|
||||
if (databaseName) cy.contains(databaseName).click();
|
||||
cy.testid('ConnectionList_container')
|
||||
.contains(databaseName ?? connectionName)
|
||||
.rightclick();
|
||||
cy.contains('Import').click();
|
||||
|
||||
cy.get('input[type=file]').selectFile('cypress/fixtures/customers-20-err.csv', { force: true });
|
||||
cy.contains('customers-20-err');
|
||||
cy.testid('ImportExportTab_preview_content').contains('Invalid Closing Quote').should('be.visible');
|
||||
|
||||
cy.testid('ImportExportTab_executeButton').click();
|
||||
cy.testid('ImportExportConfigurator_errorInfoIcon_customers-20-err').click();
|
||||
|
||||
cy.testid('ErrorMessageModal_message').contains('Invalid Closing Quote').should('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Import CSV - target error', () => {
|
||||
multiTest({}, (connectionName, databaseName, engine, options = {}) => {
|
||||
cy.contains(connectionName).click();
|
||||
if (databaseName) cy.contains(databaseName).click();
|
||||
cy.testid('ConnectionList_container')
|
||||
.contains(databaseName ?? connectionName)
|
||||
.rightclick();
|
||||
cy.contains('Import').click();
|
||||
|
||||
cy.get('input[type=file]').selectFile('cypress/fixtures/customers-20.csv', { force: true });
|
||||
cy.contains('customers-20');
|
||||
cy.testid('ImportExportConfigurator_targetName_customers-20').clear().type('system."]`');
|
||||
cy.testid('ImportExportTab_executeButton').click();
|
||||
cy.testid('ImportExportConfigurator_errorInfoIcon_customers-20').click();
|
||||
cy.testid('ErrorMessageModal_message').should('be.visible');
|
||||
});
|
||||
});
|
||||
@@ -45,36 +45,36 @@ describe('Run as portal', () => {
|
||||
cy.get('[data-testid=InputTextModal_ok]').click();
|
||||
});
|
||||
|
||||
it('Import Chinook MySQL', () => {
|
||||
cy.visit('http://localhost:3000');
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.get('[data-testid=DatabaseAppObject_Chinook]').rightclick();
|
||||
cy.contains('Chinook').rightclick();
|
||||
cy.contains('Restore/import SQL dump').click();
|
||||
cy.get('#uploadFileButton').selectFile('data/chinook-mysql.sql', { force: true });
|
||||
cy.wait(500);
|
||||
cy.get('[data-testid=ImportDatabaseDumpModal_runImport]').click();
|
||||
cy.contains('Importing database');
|
||||
cy.contains('Finished job script');
|
||||
cy.get('[data-testid=RunScriptModal_close]').click();
|
||||
cy.contains('Chinook').click();
|
||||
cy.contains('Album');
|
||||
});
|
||||
// it('Import Chinook MySQL', () => {
|
||||
// cy.visit('http://localhost:3000');
|
||||
// cy.contains('MySql-connection').click();
|
||||
// cy.get('[data-testid=DatabaseAppObject_Chinook]').rightclick();
|
||||
// cy.contains('Chinook').rightclick();
|
||||
// cy.contains('Restore/import SQL dump').click();
|
||||
// cy.get('#uploadFileButton').selectFile('data/chinook-mysql.sql', { force: true });
|
||||
// cy.wait(500);
|
||||
// cy.get('[data-testid=ImportDatabaseDumpModal_runImport]').click();
|
||||
// cy.contains('Importing database');
|
||||
// cy.contains('Finished job script');
|
||||
// cy.get('[data-testid=RunScriptModal_close]').click();
|
||||
// cy.contains('Chinook').click();
|
||||
// cy.contains('Album');
|
||||
// });
|
||||
|
||||
it('Import Chinook Postgres', () => {
|
||||
cy.visit('http://localhost:3000');
|
||||
cy.contains('Postgres-connection').click();
|
||||
cy.get('[data-testid=DatabaseAppObject_Chinook]').rightclick();
|
||||
cy.contains('Restore/import SQL dump').click();
|
||||
cy.get('#uploadFileButton').selectFile('data/chinook-postgres.sql', { force: true });
|
||||
cy.wait(500);
|
||||
cy.get('[data-testid=ImportDatabaseDumpModal_runImport]').click();
|
||||
cy.contains('Importing database');
|
||||
cy.contains('Finished job script');
|
||||
cy.get('[data-testid=RunScriptModal_close]').click();
|
||||
cy.contains('Chinook').click();
|
||||
cy.contains('album');
|
||||
});
|
||||
// it('Import Chinook Postgres', () => {
|
||||
// cy.visit('http://localhost:3000');
|
||||
// cy.contains('Postgres-connection').click();
|
||||
// cy.get('[data-testid=DatabaseAppObject_Chinook]').rightclick();
|
||||
// cy.contains('Restore/import SQL dump').click();
|
||||
// cy.get('#uploadFileButton').selectFile('data/chinook-postgres.sql', { force: true });
|
||||
// cy.wait(500);
|
||||
// cy.get('[data-testid=ImportDatabaseDumpModal_runImport]').click();
|
||||
// cy.contains('Importing database');
|
||||
// cy.contains('Finished job script');
|
||||
// cy.get('[data-testid=RunScriptModal_close]').click();
|
||||
// cy.contains('Chinook').click();
|
||||
// cy.contains('album');
|
||||
// });
|
||||
|
||||
it('Open ask pwd connection', () => {
|
||||
cy.visit('http://localhost:3000');
|
||||
@@ -83,7 +83,7 @@ describe('Run as portal', () => {
|
||||
cy.testid('DatabaseLoginModal_password').clear().type('Pwd2020Db');
|
||||
cy.testid('DatabaseLoginModal_connect').click();
|
||||
cy.contains('Chinook').click();
|
||||
cy.contains('album');
|
||||
// cy.contains('album');
|
||||
});
|
||||
|
||||
// it('import chinook DB', () => {
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
Cypress.on('uncaught:exception', (err, runnable) => {
|
||||
// if the error message matches the one about WorkerGlobalScope importScripts
|
||||
if (err.message.includes("Failed to execute 'importScripts' on 'WorkerGlobalScope'")) {
|
||||
// return false to let Cypress know we intentionally want to ignore this error
|
||||
return false;
|
||||
}
|
||||
// otherwise let Cypress throw the error
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.visit('http://localhost:3000');
|
||||
cy.viewport(1250, 900);
|
||||
@@ -11,21 +20,27 @@ describe('Team edition tests', () => {
|
||||
|
||||
cy.testid('AdminMenuWidget_itemConnections').click();
|
||||
cy.contains('New connection').click();
|
||||
cy.contains('New connection').click();
|
||||
cy.contains('New connection').click();
|
||||
cy.testid('ConnectionDriverFields_connectionType').select('PostgreSQL');
|
||||
cy.themeshot('connadmin');
|
||||
cy.contains('not granted').should('not.exist');
|
||||
cy.themeshot('connection-administration');
|
||||
|
||||
cy.testid('AdminMenuWidget_itemRoles').click();
|
||||
cy.contains('Permissions').click();
|
||||
cy.themeshot('roleadmin');
|
||||
cy.contains('logged-user').click();
|
||||
cy.contains('not granted').should('not.exist');
|
||||
cy.themeshot('role-administration');
|
||||
|
||||
cy.testid('AdminMenuWidget_itemUsers').click();
|
||||
cy.contains('New user').click();
|
||||
cy.contains('not granted').should('not.exist');
|
||||
cy.themeshot('user-administration');
|
||||
|
||||
cy.testid('AdminMenuWidget_itemAuthentication').click();
|
||||
cy.contains('Add authentication').click();
|
||||
cy.contains('Use database login').click();
|
||||
cy.contains('Add authentication').click();
|
||||
cy.contains('OAuth 2.0').click();
|
||||
cy.themeshot('authadmin');
|
||||
cy.contains('not granted').should('not.exist');
|
||||
cy.themeshot('authentication-administration');
|
||||
});
|
||||
|
||||
it('OAuth authentication', () => {
|
||||
@@ -77,6 +92,60 @@ describe('Team edition tests', () => {
|
||||
cy.testid('LoginPage_submitLogin').click();
|
||||
cy.testid('AdminMenuWidget_itemUsers').click();
|
||||
cy.contains('test@example.com');
|
||||
cy.contains('Rows: 1');
|
||||
});
|
||||
|
||||
it('Audit logging', () => {
|
||||
cy.testid('LoginPage_linkAdmin').click();
|
||||
cy.testid('LoginPage_password').type('adminpwd');
|
||||
cy.testid('LoginPage_submitLogin').click();
|
||||
|
||||
cy.testid('AdminMenuWidget_itemAuditLog').click();
|
||||
cy.contains('Audit log is not enabled');
|
||||
cy.testid('AdminMenuWidget_itemSettings').click();
|
||||
cy.testid('AdminSettingsTab_auditLogCheckbox').click();
|
||||
cy.testid('AdminMenuWidget_itemAuditLog').click();
|
||||
cy.contains('No data for selected date');
|
||||
|
||||
cy.testid('AdminMenuWidget_itemConnections').click();
|
||||
cy.contains('Open table').click();
|
||||
cy.contains('displayName');
|
||||
cy.get('.toolstrip').contains('Export').click();
|
||||
cy.contains('CSV file').click();
|
||||
|
||||
cy.testid('AdminMenuWidget_itemUsers').click();
|
||||
cy.contains('Open table').click();
|
||||
cy.contains('login');
|
||||
cy.get('.toolstrip').contains('Export').click();
|
||||
cy.contains('XML file').click();
|
||||
|
||||
cy.testid('AdminMenuWidget_itemAuditLog').click();
|
||||
cy.testid('AdminAuditLogTab_refreshButton').click();
|
||||
cy.contains('Exporting query').click();
|
||||
cy.themeshot('auditlog');
|
||||
});
|
||||
|
||||
it('Edit database permissions', () => {
|
||||
cy.testid('LoginPage_linkAdmin').click();
|
||||
cy.testid('LoginPage_password').type('adminpwd');
|
||||
cy.testid('LoginPage_submitLogin').click();
|
||||
|
||||
cy.testid('AdminMenuWidget_itemRoles').click();
|
||||
cy.testid('AdminRolesTab_table').contains('superadmin').click();
|
||||
cy.testid('AdminRolesTab_databases').click();
|
||||
|
||||
cy.testid('AdminDatabasesPermissionsGrid_addButton').click();
|
||||
cy.testid('AdminDatabasesPermissionsGrid_addButton').click();
|
||||
cy.testid('AdminDatabasesPermissionsGrid_addButton').click();
|
||||
|
||||
cy.testid('AdminListOrRegexEditor_1_regexInput').type('^Chinook[\\d]*$');
|
||||
cy.testid('AdminListOrRegexEditor_2_listSwitch').click();
|
||||
cy.testid('AdminListOrRegexEditor_2_listInput').type('Nortwind\nSales');
|
||||
cy.testid('AdminDatabasesPermissionsGrid_roleSelect_0').select('-2');
|
||||
cy.testid('AdminDatabasesPermissionsGrid_roleSelect_1').select('-3');
|
||||
cy.testid('AdminDatabasesPermissionsGrid_roleSelect_2').select('-4');
|
||||
|
||||
cy.contains('not granted').should('not.exist');
|
||||
|
||||
cy.themeshot('database-permissions');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
Index,Customer Id,First Name,Last Name,Company,City,Country,Phone 1,Phone 2,Email,Subscription Date,Website
|
||||
1,50ddd99fAdF48B3,Jessica,Navarro,"Tran, Odom and Graham",Port Terranceview,Jersey,(883)287-7947,479-044-3187,wmcintyre@myers.net,2023-03-11,http://pennington.com/
|
||||
"2,BD1AB97979DDcDe,Preston,Andrews,"Townsend, Lawrence and Davenport",Harringtonmouth,Croatia,188-270-5676x63873,001-428-148-4270,bradley63@jacobs.net,2023-11-15,http://burke.com/
|
||||
3,0FDDD9aCa501acE,Melissa,Mckay,Rivas-Cooke,Oliviabury,Cook Islands,8257631531,001-650-689-5600x927,ugalloway@maxwell-mcclain.com,2025-01-25,https://patrick.com/
|
||||
4,A7dA284B7c4AfaD,Frank,Livingston,"Lambert, Garner and Mathews",Mallorytown,Faroe Islands,766.182.6201x689,+1-476-912-2027x4370,tracie00@webster.biz,2021-03-27,https://www.hart.com/
|
||||
5,38bb1624e4f8211,Ross,Mendoza,Cook and Sons,New Perry,Bolivia,001-440-468-2236,165.562.4328x9274,austincarmen@abbott.com,2024-12-12,http://harmon.com/
|
||||
6,55c9Fda2BABFE1a,Jane,Tate,Knapp PLC,West Kathyshire,Morocco,001-606-447-0584x07975,(003)872-1307x285,carlosgomez@mcpherson-ramos.biz,2021-09-13,http://www.yu.com/
|
||||
7,A15eccAc67cCc5b,Tanya,Chung,Frost Inc,South Julieburgh,United States of America,778-360-8301x268,+1-034-169-4237,onewton@crosby.com,2024-10-01,http://www.gill-velez.biz/
|
||||
8,aFdab04acACaf90,Jackson,Moyer,Bowen Ltd,Port Triciabury,Bahrain,001-187-882-2891x169,154.903.2525,gabriela16@mejia.org,2023-06-20,http://www.david.biz/
|
||||
9,A2EaeAd3c6529B9,Kelly,Douglas,Phillips PLC,Weissberg,Qatar,767.177.3199x5576,5156730935,wigginsmercedes@tanner.com,2021-06-30,https://gonzalez.net/
|
||||
10,188175A5641d080,Mariah,Riddle,"Mata, Fuller and Good",Choiton,Namibia,092-993-3559x342,190.937.3937,eileen32@greer.biz,2021-04-17,http://www.bowen.info/
|
||||
11,B2BA817C7bC09f0,Kristine,Pennington,"Koch, Diaz and Valdez",Port Rachael,Suriname,877.152.6488x921,790-804-9979x3290,tonya00@flynn.com,2024-03-28,https://www.rocha.net/
|
||||
12,fFAD70B5Febc43a,Robert,Adams,Bender-Wolfe,Billfort,Tanzania,219-696-1912x93626,518-969-4058,jeffersoncolton@moss-ashley.com,2022-07-31,https://www.alvarez.com/
|
||||
13,9a44524E1261Ed6,Franklin,Costa,Werner Group,North Bradley,Cook Islands,(895)448-4681x1999,648-345-3083x88242,marksmith@novak.com,2024-12-03,http://thornton.com/
|
||||
14,0C360EfE17D06cc,Dan,Ballard,Sampson-Huff,Michaelchester,Sao Tome and Principe,+1-803-469-5237x2580,(729)574-6101x0605,molly54@acevedo.info,2022-10-24,https://www.sloan-gonzales.biz/
|
||||
15,fb5cE8cb1eF2954,Clifford,Moyer,Fry-Whitehead,Lake Gary,Japan,(504)263-0450,247.514.1614x551,rhonda34@orr.com,2020-03-08,https://norton.com/
|
||||
16,3e53DcaD1cB0054,Tonya,Durham,"Lowe, West and Reynolds",South Sylviaton,Brunei Darussalam,(613)893-8183,(461)399-6120,kiara96@meadows.biz,2022-08-04,https://www.reeves.com/
|
||||
17,83fDDE5812EbEde,Dale,Bishop,Shaw-Ray,Lake Miranda,Congo,(082)202-9241,+1-413-610-1854x79378,bhoward@hodges.biz,2023-05-08,http://www.escobar.com/
|
||||
18,8dB7ACe2C5758cE,Priscilla,Mills,Pope PLC,North Cliffordshire,South Georgia and the South Sandwich Islands,+1-465-802-4573x30191,044-393-6049x598,nathaniel28@hess.com,2020-09-08,https://www.watts.org/
|
||||
19,c1092ebDaF2ceED,Alice,Bond,Chan-Liu,West Wesley,Lithuania,+1-333-285-8515,(715)759-3158x77103,jose92@peters.com,2024-05-30,http://www.marquez.com/
|
||||
20,4d0c95579D095aF,Cole,Compton,Calderon PLC,Robertaville,Saudi Arabia,029.862.3387x470,001-319-474-2394,sspence@dorsey.com,2020-08-02,http://hamilton.net/
|
||||
|
Can't render this file because it contains an unexpected character in line 3 and column 36.
|
@@ -0,0 +1,21 @@
|
||||
Index,Customer Id,First Name,Last Name,Company,City,Country,Phone 1,Phone 2,Email,Subscription Date,Website
|
||||
1,50ddd99fAdF48B3,Jessica,Navarro,"Tran, Odom and Graham",Port Terranceview,Jersey,(883)287-7947,479-044-3187,wmcintyre@myers.net,2023-03-11,http://pennington.com/
|
||||
2,BD1AB97979DDcDe,Preston,Andrews,"Townsend, Lawrence and Davenport",Harringtonmouth,Croatia,188-270-5676x63873,001-428-148-4270,bradley63@jacobs.net,2023-11-15,http://burke.com/
|
||||
3,0FDDD9aCa501acE,Melissa,Mckay,Rivas-Cooke,Oliviabury,Cook Islands,8257631531,001-650-689-5600x927,ugalloway@maxwell-mcclain.com,2025-01-25,https://patrick.com/
|
||||
4,A7dA284B7c4AfaD,Frank,Livingston,"Lambert, Garner and Mathews",Mallorytown,Faroe Islands,766.182.6201x689,+1-476-912-2027x4370,tracie00@webster.biz,2021-03-27,https://www.hart.com/
|
||||
5,38bb1624e4f8211,Ross,Mendoza,Cook and Sons,New Perry,Bolivia,001-440-468-2236,165.562.4328x9274,austincarmen@abbott.com,2024-12-12,http://harmon.com/
|
||||
6,55c9Fda2BABFE1a,Jane,Tate,Knapp PLC,West Kathyshire,Morocco,001-606-447-0584x07975,(003)872-1307x285,carlosgomez@mcpherson-ramos.biz,2021-09-13,http://www.yu.com/
|
||||
7,A15eccAc67cCc5b,Tanya,Chung,Frost Inc,South Julieburgh,United States of America,778-360-8301x268,+1-034-169-4237,onewton@crosby.com,2024-10-01,http://www.gill-velez.biz/
|
||||
8,aFdab04acACaf90,Jackson,Moyer,Bowen Ltd,Port Triciabury,Bahrain,001-187-882-2891x169,154.903.2525,gabriela16@mejia.org,2023-06-20,http://www.david.biz/
|
||||
9,A2EaeAd3c6529B9,Kelly,Douglas,Phillips PLC,Weissberg,Qatar,767.177.3199x5576,5156730935,wigginsmercedes@tanner.com,2021-06-30,https://gonzalez.net/
|
||||
10,188175A5641d080,Mariah,Riddle,"Mata, Fuller and Good",Choiton,Namibia,092-993-3559x342,190.937.3937,eileen32@greer.biz,2021-04-17,http://www.bowen.info/
|
||||
11,B2BA817C7bC09f0,Kristine,Pennington,"Koch, Diaz and Valdez",Port Rachael,Suriname,877.152.6488x921,790-804-9979x3290,tonya00@flynn.com,2024-03-28,https://www.rocha.net/
|
||||
12,fFAD70B5Febc43a,Robert,Adams,Bender-Wolfe,Billfort,Tanzania,219-696-1912x93626,518-969-4058,jeffersoncolton@moss-ashley.com,2022-07-31,https://www.alvarez.com/
|
||||
13,9a44524E1261Ed6,Franklin,Costa,Werner Group,North Bradley,Cook Islands,(895)448-4681x1999,648-345-3083x88242,marksmith@novak.com,2024-12-03,http://thornton.com/
|
||||
14,0C360EfE17D06cc,Dan,Ballard,Sampson-Huff,Michaelchester,Sao Tome and Principe,+1-803-469-5237x2580,(729)574-6101x0605,molly54@acevedo.info,2022-10-24,https://www.sloan-gonzales.biz/
|
||||
15,fb5cE8cb1eF2954,Clifford,Moyer,Fry-Whitehead,Lake Gary,Japan,(504)263-0450,247.514.1614x551,rhonda34@orr.com,2020-03-08,https://norton.com/
|
||||
16,3e53DcaD1cB0054,Tonya,Durham,"Lowe, West and Reynolds",South Sylviaton,Brunei Darussalam,(613)893-8183,(461)399-6120,kiara96@meadows.biz,2022-08-04,https://www.reeves.com/
|
||||
17,83fDDE5812EbEde,Dale,Bishop,Shaw-Ray,Lake Miranda,Congo,(082)202-9241,+1-413-610-1854x79378,bhoward@hodges.biz,2023-05-08,http://www.escobar.com/
|
||||
18,8dB7ACe2C5758cE,Priscilla,Mills,Pope PLC,North Cliffordshire,South Georgia and the South Sandwich Islands,+1-465-802-4573x30191,044-393-6049x598,nathaniel28@hess.com,2020-09-08,https://www.watts.org/
|
||||
19,c1092ebDaF2ceED,Alice,Bond,Chan-Liu,West Wesley,Lithuania,+1-333-285-8515,(715)759-3158x77103,jose92@peters.com,2024-05-30,http://www.marquez.com/
|
||||
20,4d0c95579D095aF,Cole,Compton,Calderon PLC,Robertaville,Saudi Arabia,029.862.3387x470,001-319-474-2394,sspence@dorsey.com,2020-08-02,http://hamilton.net/
|
||||
|
@@ -42,3 +42,11 @@ beforeEach(() => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Cypress.Screenshot.defaults({
|
||||
// onBeforeScreenshot() {
|
||||
// if (window.Chart) {
|
||||
// Object.values(window.Chart.instances).forEach(c => c.resize());
|
||||
// }
|
||||
// },
|
||||
// });
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{"__isStreamHeader":true,"pureName":"departments","schemaName":"dbo","objectId":1205579333,"createDate":"2025-06-12T10:30:34.083Z","modifyDate":"2025-06-12T10:30:34.120Z","contentHash":"2025-06-12T10:30:34.120Z","columns":[{"columnName":"id","dataType":"int","notNull":true,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false},{"columnName":"name","dataType":"varchar(100)","notNull":true,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false}],"primaryKey":{"constraintName":"PK__departme__3213E83FE8E7043D","schemaName":"dbo","pureName":"departments","constraintType":"primaryKey","columns":[{"columnName":"id"}]},"foreignKeys":[],"indexes":[],"uniques":[],"engine":"mssql@dbgate-plugin-mssql"}
|
||||
{"id":1,"name":"IT"}
|
||||
{"id":2,"name":"Marketing"}
|
||||
{"id":3,"name":"Finance"}
|
||||
{"id":4,"name":"Human Resources"}
|
||||
{"id":5,"name":"Research and Development"}
|
||||
@@ -0,0 +1,12 @@
|
||||
name: departments
|
||||
columns:
|
||||
- name: id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
- name: name
|
||||
type: varchar(100)
|
||||
default: null
|
||||
notNull: true
|
||||
primaryKey:
|
||||
- id
|
||||
@@ -0,0 +1,39 @@
|
||||
{"__isStreamHeader":true,"pureName":"employee_project","schemaName":"dbo","objectId":1333579789,"createDate":"2025-06-12T10:30:34.133Z","modifyDate":"2025-06-12T10:30:34.133Z","contentHash":"2025-06-12T10:30:34.133Z","columns":[{"columnName":"employee_id","dataType":"int","notNull":true,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false},{"columnName":"project_id","dataType":"int","notNull":true,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false},{"columnName":"role","dataType":"varchar(50)","notNull":false,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false}],"primaryKey":{"constraintName":"PK__employee__2EE9924949ED9668","schemaName":"dbo","pureName":"employee_project","constraintType":"primaryKey","columns":[{"columnName":"employee_id"},{"columnName":"project_id"}]},"foreignKeys":[{"constraintName":"FK__employee___emplo__5165187F","constraintType":"foreignKey","schemaName":"dbo","pureName":"employee_project","refSchemaName":"dbo","refTableName":"employees","updateAction":"NO ACTION","deleteAction":"NO ACTION","columns":[{"columnName":"employee_id","refColumnName":"id"}]},{"constraintName":"FK__employee___proje__52593CB8","constraintType":"foreignKey","schemaName":"dbo","pureName":"employee_project","refSchemaName":"dbo","refTableName":"projects","updateAction":"NO ACTION","deleteAction":"NO ACTION","columns":[{"columnName":"project_id","refColumnName":"id"}]}],"indexes":[],"uniques":[],"engine":"mssql@dbgate-plugin-mssql"}
|
||||
{"employee_id":1,"project_id":6,"role":"Manager"}
|
||||
{"employee_id":1,"project_id":8,"role":"Developer"}
|
||||
{"employee_id":2,"project_id":7,"role":"Tester"}
|
||||
{"employee_id":2,"project_id":8,"role":"Developer"}
|
||||
{"employee_id":3,"project_id":4,"role":"Analyst"}
|
||||
{"employee_id":3,"project_id":6,"role":"Developer"}
|
||||
{"employee_id":4,"project_id":2,"role":"Manager"}
|
||||
{"employee_id":4,"project_id":4,"role":"Analyst"}
|
||||
{"employee_id":4,"project_id":5,"role":"Analyst"}
|
||||
{"employee_id":5,"project_id":5,"role":"Tester"}
|
||||
{"employee_id":6,"project_id":1,"role":"Analyst"}
|
||||
{"employee_id":6,"project_id":6,"role":"Tester"}
|
||||
{"employee_id":6,"project_id":9,"role":"Manager"}
|
||||
{"employee_id":7,"project_id":8,"role":"Manager"}
|
||||
{"employee_id":8,"project_id":10,"role":"Analyst"}
|
||||
{"employee_id":9,"project_id":2,"role":"Analyst"}
|
||||
{"employee_id":9,"project_id":6,"role":"Analyst"}
|
||||
{"employee_id":9,"project_id":7,"role":"Developer"}
|
||||
{"employee_id":10,"project_id":2,"role":"Manager"}
|
||||
{"employee_id":10,"project_id":6,"role":"Analyst"}
|
||||
{"employee_id":11,"project_id":1,"role":"Tester"}
|
||||
{"employee_id":12,"project_id":4,"role":"Tester"}
|
||||
{"employee_id":13,"project_id":2,"role":"Developer"}
|
||||
{"employee_id":13,"project_id":3,"role":"Analyst"}
|
||||
{"employee_id":13,"project_id":7,"role":"Developer"}
|
||||
{"employee_id":14,"project_id":3,"role":"Developer"}
|
||||
{"employee_id":14,"project_id":9,"role":"Manager"}
|
||||
{"employee_id":15,"project_id":1,"role":"Developer"}
|
||||
{"employee_id":15,"project_id":5,"role":"Manager"}
|
||||
{"employee_id":16,"project_id":3,"role":"Tester"}
|
||||
{"employee_id":16,"project_id":5,"role":"Developer"}
|
||||
{"employee_id":17,"project_id":6,"role":"Analyst"}
|
||||
{"employee_id":18,"project_id":1,"role":"Tester"}
|
||||
{"employee_id":18,"project_id":5,"role":"Tester"}
|
||||
{"employee_id":18,"project_id":6,"role":"Manager"}
|
||||
{"employee_id":19,"project_id":6,"role":"Analyst"}
|
||||
{"employee_id":20,"project_id":2,"role":"Developer"}
|
||||
{"employee_id":20,"project_id":4,"role":"Developer"}
|
||||
@@ -0,0 +1,18 @@
|
||||
name: employee_project
|
||||
columns:
|
||||
- name: employee_id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
references: employees
|
||||
- name: project_id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
references: projects
|
||||
- name: role
|
||||
type: varchar(50)
|
||||
default: null
|
||||
primaryKey:
|
||||
- employee_id
|
||||
- project_id
|
||||
@@ -0,0 +1,21 @@
|
||||
{"__isStreamHeader":true,"pureName":"employees","schemaName":"dbo","objectId":1237579447,"createDate":"2025-06-12T10:30:34.113Z","modifyDate":"2025-06-12T12:35:22.140Z","contentHash":"2025-06-12T12:35:22.140Z","columns":[{"columnName":"id","dataType":"int","notNull":true,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false},{"columnName":"name","dataType":"varchar(100)","notNull":true,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false},{"columnName":"email","dataType":"varchar(100)","notNull":true,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false},{"columnName":"hire_date","dataType":"date","notNull":true,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false},{"columnName":"department_id","dataType":"int","notNull":false,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false}],"primaryKey":{"constraintName":"PK__employee__3213E83FE576E55A","schemaName":"dbo","pureName":"employees","constraintType":"primaryKey","columns":[{"columnName":"id"}]},"foreignKeys":[{"constraintName":"FK__employees__depar__4CA06362","constraintType":"foreignKey","schemaName":"dbo","pureName":"employees","refSchemaName":"dbo","refTableName":"departments","updateAction":"NO ACTION","deleteAction":"NO ACTION","columns":[{"columnName":"department_id","refColumnName":"id"}]}],"indexes":[],"uniques":[{"constraintName":"UQ__employee__AB6E6164E18D883F","columns":[{"columnName":"email"}]}],"engine":"mssql@dbgate-plugin-mssql"}
|
||||
{"id":1,"name":"John Smith","email":"john.smith@example.com","hire_date":"2018-07-09T00:00:00.000Z","department_id":2}
|
||||
{"id":2,"name":"Jane Garcia","email":"jane.garcia@example.com","hire_date":"2019-10-13T00:00:00.000Z","department_id":5}
|
||||
{"id":3,"name":"Grace Smith","email":"grace.smith@example.com","hire_date":"2019-03-16T00:00:00.000Z","department_id":1}
|
||||
{"id":4,"name":"Charlie Williams","email":"charlie.williams@example.com","hire_date":"2020-10-18T00:00:00.000Z","department_id":2}
|
||||
{"id":5,"name":"Eve Brown","email":"eve.brown@example.com","hire_date":"2018-04-12T00:00:00.000Z","department_id":4}
|
||||
{"id":6,"name":"Alice Moore","email":"alice.moore@example.com","hire_date":"2019-04-20T00:00:00.000Z","department_id":2}
|
||||
{"id":7,"name":"Eve Williams","email":"eve.williams@example.com","hire_date":"2020-04-26T00:00:00.000Z","department_id":4}
|
||||
{"id":8,"name":"Eve Jones","email":"eve.jones@example.com","hire_date":"2022-10-04T00:00:00.000Z","department_id":3}
|
||||
{"id":9,"name":"Diana Miller","email":"diana.miller@example.com","hire_date":"2021-03-28T00:00:00.000Z","department_id":1}
|
||||
{"id":10,"name":"Diana Smith","email":"diana.smith@example.com","hire_date":"2018-04-12T00:00:00.000Z","department_id":2}
|
||||
{"id":11,"name":"Hank Johnson","email":"hank.johnson@example.com","hire_date":"2020-09-16T00:00:00.000Z","department_id":2}
|
||||
{"id":12,"name":"Frank Miller","email":"frank.miller@example.com","hire_date":"2023-01-12T00:00:00.000Z","department_id":4}
|
||||
{"id":13,"name":"Jane Brown","email":"jane.brown@example.com","hire_date":"2023-05-07T00:00:00.000Z","department_id":3}
|
||||
{"id":14,"name":"Grace Davis","email":"grace.davis@example.com","hire_date":"2019-08-22T00:00:00.000Z","department_id":3}
|
||||
{"id":15,"name":"Jane Black","email":"jane.black@example.com","hire_date":"2019-04-28T00:00:00.000Z","department_id":2}
|
||||
{"id":16,"name":"Charlie Smith","email":"charlie.smith@example.com","hire_date":"2019-06-12T00:00:00.000Z","department_id":5}
|
||||
{"id":17,"name":"Eve Johnson","email":"eve.johnson@example.com","hire_date":"2020-11-07T00:00:00.000Z","department_id":5}
|
||||
{"id":18,"name":"Jane Johnson","email":"jane.johnson@example.com","hire_date":"2020-04-06T00:00:00.000Z","department_id":2}
|
||||
{"id":19,"name":"Hank Brown","email":"hank.brown@example.com","hire_date":"2023-05-10T00:00:00.000Z","department_id":2}
|
||||
{"id":20,"name":"Frank Jones","email":"frank.jones@example.com","hire_date":"2020-10-26T00:00:00.000Z","department_id":1}
|
||||
@@ -0,0 +1,28 @@
|
||||
name: employees
|
||||
columns:
|
||||
- name: id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
- name: name
|
||||
type: varchar(100)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: email
|
||||
type: varchar(100)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: hire_date
|
||||
type: date
|
||||
default: null
|
||||
notNull: true
|
||||
- name: department_id
|
||||
type: int
|
||||
default: null
|
||||
references: departments
|
||||
primaryKey:
|
||||
- id
|
||||
uniques:
|
||||
- name: UQ__employee__AB6E6164E18D883F
|
||||
columns:
|
||||
- email
|
||||
@@ -0,0 +1,141 @@
|
||||
{"__isStreamHeader":true,"pureName":"finance_reports","schemaName":"dbo","objectId":338100245,"createDate":"2025-06-23T12:15:08.727Z","modifyDate":"2025-06-23T12:15:08.750Z","contentHash":"2025-06-23T12:15:08.750Z","columns":[{"columnName":"id","dataType":"int","notNull":true,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false},{"columnName":"date","dataType":"date","notNull":true,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false},{"columnName":"profit","dataType":"money","notNull":true,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false}],"foreignKeys":[{"constraintName":"project_id","constraintType":"foreignKey","schemaName":"dbo","pureName":"finance_reports","refSchemaName":"dbo","refTableName":"projects","updateAction":"NO ACTION","deleteAction":"NO ACTION","columns":[{"columnName":"id","refColumnName":"id"}]}],"indexes":[],"uniques":[],"engine":"mssql@dbgate-plugin-mssql"}
|
||||
{"id":1,"date":"2022-01-01T00:00:00.000Z","profit":73923.4}
|
||||
{"id":1,"date":"2022-01-31T00:00:00.000Z","profit":21837.75}
|
||||
{"id":1,"date":"2022-03-02T00:00:00.000Z","profit":67859.8}
|
||||
{"id":1,"date":"2022-04-01T00:00:00.000Z","profit":77403.3}
|
||||
{"id":1,"date":"2022-05-01T00:00:00.000Z","profit":84083.19}
|
||||
{"id":1,"date":"2022-05-31T00:00:00.000Z","profit":30040.55}
|
||||
{"id":1,"date":"2022-06-30T00:00:00.000Z","profit":50947.14}
|
||||
{"id":1,"date":"2022-07-30T00:00:00.000Z","profit":63345.62}
|
||||
{"id":1,"date":"2022-08-29T00:00:00.000Z","profit":23819.45}
|
||||
{"id":1,"date":"2022-09-28T00:00:00.000Z","profit":-25919.19}
|
||||
{"id":1,"date":"2022-10-28T00:00:00.000Z","profit":27967.6}
|
||||
{"id":1,"date":"2022-11-27T00:00:00.000Z","profit":-37402.36}
|
||||
{"id":1,"date":"2022-12-27T00:00:00.000Z","profit":94528.8}
|
||||
{"id":1,"date":"2023-01-26T00:00:00.000Z","profit":29491.03}
|
||||
{"id":1,"date":"2023-02-25T00:00:00.000Z","profit":81541.29}
|
||||
{"id":2,"date":"2022-01-01T00:00:00.000Z","profit":18070.94}
|
||||
{"id":2,"date":"2022-01-31T00:00:00.000Z","profit":-40609.87}
|
||||
{"id":2,"date":"2022-03-02T00:00:00.000Z","profit":42435.51}
|
||||
{"id":2,"date":"2022-04-01T00:00:00.000Z","profit":-11915.15}
|
||||
{"id":2,"date":"2022-05-01T00:00:00.000Z","profit":-37417.4}
|
||||
{"id":2,"date":"2022-05-31T00:00:00.000Z","profit":23028.66}
|
||||
{"id":2,"date":"2022-06-30T00:00:00.000Z","profit":-6895.49}
|
||||
{"id":2,"date":"2022-07-30T00:00:00.000Z","profit":63114.54}
|
||||
{"id":2,"date":"2022-08-29T00:00:00.000Z","profit":94646.99}
|
||||
{"id":2,"date":"2022-09-28T00:00:00.000Z","profit":99560.77}
|
||||
{"id":2,"date":"2022-10-28T00:00:00.000Z","profit":62216.22}
|
||||
{"id":2,"date":"2022-11-27T00:00:00.000Z","profit":85094.32}
|
||||
{"id":2,"date":"2022-12-27T00:00:00.000Z","profit":-23378.37}
|
||||
{"id":2,"date":"2023-01-26T00:00:00.000Z","profit":47635.86}
|
||||
{"id":2,"date":"2023-02-25T00:00:00.000Z","profit":33727.72}
|
||||
{"id":3,"date":"2022-01-01T00:00:00.000Z","profit":33088.03}
|
||||
{"id":3,"date":"2022-01-31T00:00:00.000Z","profit":66668.91}
|
||||
{"id":3,"date":"2022-03-02T00:00:00.000Z","profit":5344.27}
|
||||
{"id":3,"date":"2022-04-01T00:00:00.000Z","profit":22122.99}
|
||||
{"id":3,"date":"2022-05-01T00:00:00.000Z","profit":27342.01}
|
||||
{"id":3,"date":"2022-05-31T00:00:00.000Z","profit":55479.42}
|
||||
{"id":3,"date":"2022-06-30T00:00:00.000Z","profit":35956.11}
|
||||
{"id":3,"date":"2022-07-30T00:00:00.000Z","profit":9667.12}
|
||||
{"id":3,"date":"2022-08-29T00:00:00.000Z","profit":63430.18}
|
||||
{"id":3,"date":"2022-09-28T00:00:00.000Z","profit":-4883.41}
|
||||
{"id":3,"date":"2022-10-28T00:00:00.000Z","profit":38902.8}
|
||||
{"id":3,"date":"2022-11-27T00:00:00.000Z","profit":-25500.13}
|
||||
{"id":3,"date":"2022-12-27T00:00:00.000Z","profit":65074.21}
|
||||
{"id":3,"date":"2023-01-26T00:00:00.000Z","profit":12570.27}
|
||||
{"id":3,"date":"2023-02-25T00:00:00.000Z","profit":35418.36}
|
||||
{"id":4,"date":"2022-01-01T00:00:00.000Z","profit":68282.98}
|
||||
{"id":4,"date":"2022-01-31T00:00:00.000Z","profit":77778.99}
|
||||
{"id":4,"date":"2022-03-02T00:00:00.000Z","profit":95490.49}
|
||||
{"id":4,"date":"2022-04-01T00:00:00.000Z","profit":-44466.37}
|
||||
{"id":4,"date":"2022-05-01T00:00:00.000Z","profit":40215.71}
|
||||
{"id":4,"date":"2022-05-31T00:00:00.000Z","profit":-31228.87}
|
||||
{"id":4,"date":"2022-06-30T00:00:00.000Z","profit":60667.69}
|
||||
{"id":4,"date":"2022-07-30T00:00:00.000Z","profit":71439.16}
|
||||
{"id":4,"date":"2022-08-29T00:00:00.000Z","profit":-25077.4}
|
||||
{"id":4,"date":"2022-09-28T00:00:00.000Z","profit":-36128.2}
|
||||
{"id":4,"date":"2022-10-28T00:00:00.000Z","profit":36727.68}
|
||||
{"id":4,"date":"2022-11-27T00:00:00.000Z","profit":-24207.2}
|
||||
{"id":4,"date":"2022-12-27T00:00:00.000Z","profit":63846.96}
|
||||
{"id":5,"date":"2022-01-01T00:00:00.000Z","profit":21648.3}
|
||||
{"id":5,"date":"2022-01-31T00:00:00.000Z","profit":59263.22}
|
||||
{"id":5,"date":"2022-03-02T00:00:00.000Z","profit":49154.51}
|
||||
{"id":5,"date":"2022-04-01T00:00:00.000Z","profit":34787.48}
|
||||
{"id":5,"date":"2022-05-01T00:00:00.000Z","profit":-24120.19}
|
||||
{"id":5,"date":"2022-05-31T00:00:00.000Z","profit":98437.86}
|
||||
{"id":5,"date":"2022-06-30T00:00:00.000Z","profit":18614.77}
|
||||
{"id":5,"date":"2022-07-30T00:00:00.000Z","profit":17680.34}
|
||||
{"id":5,"date":"2022-08-29T00:00:00.000Z","profit":74406.86}
|
||||
{"id":5,"date":"2022-09-28T00:00:00.000Z","profit":61845.3}
|
||||
{"id":5,"date":"2022-10-28T00:00:00.000Z","profit":-37889.59}
|
||||
{"id":5,"date":"2022-11-27T00:00:00.000Z","profit":76651.05}
|
||||
{"id":5,"date":"2022-12-27T00:00:00.000Z","profit":58739.6}
|
||||
{"id":5,"date":"2023-01-26T00:00:00.000Z","profit":82605.85}
|
||||
{"id":6,"date":"2022-01-01T00:00:00.000Z","profit":-5206.8}
|
||||
{"id":6,"date":"2022-01-31T00:00:00.000Z","profit":27498.27}
|
||||
{"id":6,"date":"2022-03-02T00:00:00.000Z","profit":-2939.84}
|
||||
{"id":6,"date":"2022-04-01T00:00:00.000Z","profit":-37261.08}
|
||||
{"id":6,"date":"2022-05-01T00:00:00.000Z","profit":37069.04}
|
||||
{"id":6,"date":"2022-05-31T00:00:00.000Z","profit":524.88}
|
||||
{"id":6,"date":"2022-06-30T00:00:00.000Z","profit":-29620.85}
|
||||
{"id":6,"date":"2022-07-30T00:00:00.000Z","profit":35540.81}
|
||||
{"id":6,"date":"2022-08-29T00:00:00.000Z","profit":20608.94}
|
||||
{"id":6,"date":"2022-09-28T00:00:00.000Z","profit":34809.33}
|
||||
{"id":6,"date":"2022-10-28T00:00:00.000Z","profit":-44949.05}
|
||||
{"id":6,"date":"2022-11-27T00:00:00.000Z","profit":-22524.26}
|
||||
{"id":6,"date":"2022-12-27T00:00:00.000Z","profit":37841.58}
|
||||
{"id":7,"date":"2022-01-01T00:00:00.000Z","profit":6903.17}
|
||||
{"id":7,"date":"2022-01-31T00:00:00.000Z","profit":58480.84}
|
||||
{"id":7,"date":"2022-03-02T00:00:00.000Z","profit":48217.34}
|
||||
{"id":7,"date":"2022-04-01T00:00:00.000Z","profit":73592.44}
|
||||
{"id":7,"date":"2022-05-01T00:00:00.000Z","profit":-21831.18}
|
||||
{"id":7,"date":"2022-05-31T00:00:00.000Z","profit":-40926.16}
|
||||
{"id":7,"date":"2022-06-30T00:00:00.000Z","profit":62299.5}
|
||||
{"id":7,"date":"2022-07-30T00:00:00.000Z","profit":95376.53}
|
||||
{"id":7,"date":"2022-08-29T00:00:00.000Z","profit":-13317.36}
|
||||
{"id":7,"date":"2022-09-28T00:00:00.000Z","profit":81565.05}
|
||||
{"id":7,"date":"2022-10-28T00:00:00.000Z","profit":77420.52}
|
||||
{"id":7,"date":"2022-11-27T00:00:00.000Z","profit":-12052.47}
|
||||
{"id":7,"date":"2022-12-27T00:00:00.000Z","profit":37742.07}
|
||||
{"id":7,"date":"2023-01-26T00:00:00.000Z","profit":-8057.99}
|
||||
{"id":8,"date":"2022-01-01T00:00:00.000Z","profit":27213.73}
|
||||
{"id":8,"date":"2022-01-31T00:00:00.000Z","profit":34271.75}
|
||||
{"id":8,"date":"2022-03-02T00:00:00.000Z","profit":-44549.47}
|
||||
{"id":8,"date":"2022-04-01T00:00:00.000Z","profit":15236.34}
|
||||
{"id":8,"date":"2022-05-01T00:00:00.000Z","profit":-27759.81}
|
||||
{"id":8,"date":"2022-05-31T00:00:00.000Z","profit":7955.12}
|
||||
{"id":8,"date":"2022-06-30T00:00:00.000Z","profit":-34484.38}
|
||||
{"id":8,"date":"2022-07-30T00:00:00.000Z","profit":-49758.7}
|
||||
{"id":8,"date":"2022-08-29T00:00:00.000Z","profit":-41990.86}
|
||||
{"id":8,"date":"2022-09-28T00:00:00.000Z","profit":58123.01}
|
||||
{"id":8,"date":"2022-10-28T00:00:00.000Z","profit":30128.78}
|
||||
{"id":8,"date":"2022-11-27T00:00:00.000Z","profit":-10151.17}
|
||||
{"id":8,"date":"2022-12-27T00:00:00.000Z","profit":54048.33}
|
||||
{"id":8,"date":"2023-01-26T00:00:00.000Z","profit":-43123.17}
|
||||
{"id":9,"date":"2022-01-01T00:00:00.000Z","profit":61031.83}
|
||||
{"id":9,"date":"2022-01-31T00:00:00.000Z","profit":68577.58}
|
||||
{"id":9,"date":"2022-03-02T00:00:00.000Z","profit":88698.97}
|
||||
{"id":9,"date":"2022-04-01T00:00:00.000Z","profit":8906.03}
|
||||
{"id":9,"date":"2022-05-01T00:00:00.000Z","profit":28824.73}
|
||||
{"id":9,"date":"2022-05-31T00:00:00.000Z","profit":88280.34}
|
||||
{"id":9,"date":"2022-06-30T00:00:00.000Z","profit":35266.09}
|
||||
{"id":9,"date":"2022-07-30T00:00:00.000Z","profit":-38025.36}
|
||||
{"id":9,"date":"2022-08-29T00:00:00.000Z","profit":-12118.53}
|
||||
{"id":9,"date":"2022-09-28T00:00:00.000Z","profit":-27265.86}
|
||||
{"id":9,"date":"2022-10-28T00:00:00.000Z","profit":56870.57}
|
||||
{"id":9,"date":"2022-11-27T00:00:00.000Z","profit":88078.95}
|
||||
{"id":9,"date":"2022-12-27T00:00:00.000Z","profit":-24059.67}
|
||||
{"id":9,"date":"2023-01-26T00:00:00.000Z","profit":-13301.43}
|
||||
{"id":10,"date":"2022-01-01T00:00:00.000Z","profit":-22479.23}
|
||||
{"id":10,"date":"2022-01-31T00:00:00.000Z","profit":8106.27}
|
||||
{"id":10,"date":"2022-03-02T00:00:00.000Z","profit":69372.19}
|
||||
{"id":10,"date":"2022-04-01T00:00:00.000Z","profit":-11895.74}
|
||||
{"id":10,"date":"2022-05-01T00:00:00.000Z","profit":-33206.5}
|
||||
{"id":10,"date":"2022-05-31T00:00:00.000Z","profit":56073.34}
|
||||
{"id":10,"date":"2022-06-30T00:00:00.000Z","profit":67488.3}
|
||||
{"id":10,"date":"2022-07-30T00:00:00.000Z","profit":48529.23}
|
||||
{"id":10,"date":"2022-08-29T00:00:00.000Z","profit":28680.2}
|
||||
{"id":10,"date":"2022-09-28T00:00:00.000Z","profit":59311.16}
|
||||
{"id":10,"date":"2022-10-28T00:00:00.000Z","profit":25315.78}
|
||||
{"id":10,"date":"2022-11-27T00:00:00.000Z","profit":36116.38}
|
||||
{"id":10,"date":"2022-12-27T00:00:00.000Z","profit":-42040.4}
|
||||
@@ -0,0 +1,15 @@
|
||||
name: finance_reports
|
||||
columns:
|
||||
- name: id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
references: projects
|
||||
- name: date
|
||||
type: date
|
||||
default: null
|
||||
notNull: true
|
||||
- name: profit
|
||||
type: money
|
||||
default: null
|
||||
notNull: true
|
||||
@@ -0,0 +1,11 @@
|
||||
{"__isStreamHeader":true,"pureName":"projects","schemaName":"dbo","objectId":1301579675,"createDate":"2025-06-12T10:30:34.127Z","modifyDate":"2025-06-23T12:15:08.750Z","contentHash":"2025-06-23T12:15:08.750Z","columns":[{"columnName":"id","dataType":"int","notNull":true,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false},{"columnName":"name","dataType":"varchar(100)","notNull":true,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false},{"columnName":"start_date","dataType":"date","notNull":false,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false},{"columnName":"end_date","dataType":"date","notNull":false,"autoIncrement":false,"defaultValue":null,"defaultConstraint":null,"computedExpression":null,"hasAutoValue":false}],"primaryKey":{"constraintName":"PK__projects__3213E83F26A7ED11","schemaName":"dbo","pureName":"projects","constraintType":"primaryKey","columns":[{"columnName":"id"}]},"foreignKeys":[],"indexes":[],"uniques":[],"engine":"mssql@dbgate-plugin-mssql"}
|
||||
{"id":1,"name":"Apollo Upgrade","start_date":"2020-04-27T00:00:00.000Z","end_date":"2020-10-19T00:00:00.000Z"}
|
||||
{"id":2,"name":"Market Expansion","start_date":"2022-08-04T00:00:00.000Z","end_date":"2023-06-20T00:00:00.000Z"}
|
||||
{"id":3,"name":"AI Integration","start_date":"2020-05-11T00:00:00.000Z","end_date":"2021-07-10T00:00:00.000Z"}
|
||||
{"id":4,"name":"Cost Reduction","start_date":"2022-01-08T00:00:00.000Z","end_date":"2022-07-12T00:00:00.000Z"}
|
||||
{"id":5,"name":"Cloud Migration","start_date":"2021-01-11T00:00:00.000Z","end_date":"2021-05-27T00:00:00.000Z"}
|
||||
{"id":6,"name":"Customer Portal","start_date":"2021-07-13T00:00:00.000Z","end_date":"2022-09-22T00:00:00.000Z"}
|
||||
{"id":7,"name":"Data Lake","start_date":"2021-02-25T00:00:00.000Z","end_date":"2021-08-21T00:00:00.000Z"}
|
||||
{"id":8,"name":"UX Overhaul","start_date":"2021-05-20T00:00:00.000Z","end_date":"2022-09-10T00:00:00.000Z"}
|
||||
{"id":9,"name":"Security Hardening","start_date":"2021-05-28T00:00:00.000Z","end_date":"2022-07-28T00:00:00.000Z"}
|
||||
{"id":10,"name":"Mobile App Revamp","start_date":"2021-11-17T00:00:00.000Z","end_date":"2022-06-04T00:00:00.000Z"}
|
||||
@@ -0,0 +1,18 @@
|
||||
name: projects
|
||||
columns:
|
||||
- name: id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
- name: name
|
||||
type: varchar(100)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: start_date
|
||||
type: date
|
||||
default: null
|
||||
- name: end_date
|
||||
type: date
|
||||
default: null
|
||||
primaryKey:
|
||||
- id
|
||||
@@ -0,0 +1,23 @@
|
||||
-- >>>
|
||||
-- autoExecute: true
|
||||
-- splitterInitialValue: 20%
|
||||
-- selected-chart: 1
|
||||
-- <<<
|
||||
|
||||
SELECT
|
||||
d.name AS department_name,
|
||||
FORMAT(fr.date, 'yyyy-MM') AS month,
|
||||
SUM(fr.profit) AS total_monthly_profit
|
||||
FROM
|
||||
departments d
|
||||
JOIN
|
||||
employees e ON d.id = e.department_id
|
||||
JOIN
|
||||
employee_project ep ON e.id = ep.employee_id
|
||||
JOIN
|
||||
finance_reports fr ON ep.project_id = fr.id
|
||||
GROUP BY
|
||||
d.name, FORMAT(fr.date, 'yyyy-MM')
|
||||
ORDER BY
|
||||
d.name, month;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
{"__isStreamHeader":true,"pureName":"addresses","tableRowCount":"12","tableEngine":"InnoDB","objectComment":"","modifyDate":"2025-02-03 02:56:32","objectId":"addresses","contentHash":"2025-02-03 02:56:32","columns":[{"notNull":true,"autoIncrement":true,"columnName":"address_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"customer_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"line1","columnComment":"","dataType":"varchar(60)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":false,"autoIncrement":false,"columnName":"line2","columnComment":"","dataType":"varchar(60)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"city","columnComment":"","dataType":"varchar(40)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"state","columnComment":"","dataType":"varchar(2)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"zip_code","columnComment":"","dataType":"varchar(10)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"phone","columnComment":"","dataType":"varchar(12)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"disabled","columnComment":"","dataType":"tinyint","defaultValue":"0","isUnsigned":false,"isZerofill":false}],"primaryKey":{"constraintName":"PRIMARY","pureName":"addresses","constraintType":"primaryKey","columns":[{"columnName":"address_id"}]},"foreignKeys":[{"constraintName":"addresses_fk_customers","constraintType":"foreignKey","pureName":"addresses","refTableName":"customers","updateAction":"NO ACTION","deleteAction":"NO ACTION","columns":[{"columnName":"customer_id","refColumnName":"customer_id"}]}],"indexes":[{"constraintName":"addresses_fk_customers","indexType":"BTREE","isUnique":false,"columns":[{"columnName":"customer_id","isDescending":0}]}],"uniques":[],"engine":"mysql@dbgate-plugin-mysql"}
|
||||
{"address_id":1,"customer_id":1,"line1":"100 East Ridgewood Ave.","line2":"","city":"Paramus","state":"NJ","zip_code":"07652","phone":"201-653-4472","disabled":0}
|
||||
{"address_id":2,"customer_id":1,"line1":"21 Rosewood Rd.","line2":"","city":"Woodcliff Lake","state":"NJ","zip_code":"07677","phone":"201-653-4472","disabled":0}
|
||||
{"address_id":3,"customer_id":2,"line1":"16285 Wendell St.","line2":"","city":"Omaha","state":"NE","zip_code":"68135","phone":"402-896-2576","disabled":0}
|
||||
{"address_id":4,"customer_id":3,"line1":"19270 NW Cornell Rd.","line2":"","city":"Beaverton","state":"OR","zip_code":"97006","phone":"503-654-1291","disabled":0}
|
||||
{"address_id":5,"customer_id":4,"line1":"186 Vermont St.","line2":"Apt. 2","city":"San Francisco","state":"CA","zip_code":"94110","phone":"415-292-6651","disabled":0}
|
||||
{"address_id":6,"customer_id":4,"line1":"1374 46th Ave.","line2":"","city":"San Francisco","state":"CA","zip_code":"94129","phone":"415-292-6651","disabled":0}
|
||||
{"address_id":7,"customer_id":5,"line1":"6982 Palm Ave.","line2":"","city":"Fresno","state":"CA","zip_code":"93711","phone":"559-431-2398","disabled":0}
|
||||
{"address_id":8,"customer_id":6,"line1":"23 Mountain View St.","line2":"","city":"Denver","state":"CO","zip_code":"80208","phone":"303-912-3852","disabled":0}
|
||||
{"address_id":9,"customer_id":7,"line1":"7361 N. 41st St.","line2":"Apt. B","city":"New York","state":"NY","zip_code":"10012","phone":"212-335-2093","disabled":0}
|
||||
{"address_id":10,"customer_id":7,"line1":"3829 Broadway Ave.","line2":"Suite 2","city":"New York","state":"NY","zip_code":"10012","phone":"212-239-1208","disabled":0}
|
||||
{"address_id":11,"customer_id":8,"line1":"2381 Buena Vista St.","line2":"","city":"Los Angeles","state":"CA","zip_code":"90023","phone":"213-772-5033","disabled":0}
|
||||
{"address_id":12,"customer_id":8,"line1":"291 W. Hollywood Blvd.","line2":"","city":"Los Angeles","state":"CA","zip_code":"90024","phone":"213-391-2938","disabled":0}
|
||||
@@ -0,0 +1,46 @@
|
||||
name: addresses
|
||||
columns:
|
||||
- name: address_id
|
||||
type: int
|
||||
default: null
|
||||
autoIncrement: true
|
||||
notNull: true
|
||||
- name: customer_id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
references: customers
|
||||
- name: line1
|
||||
type: varchar(60)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: line2
|
||||
type: varchar(60)
|
||||
default: null
|
||||
- name: city
|
||||
type: varchar(40)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: state
|
||||
type: varchar(2)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: zip_code
|
||||
type: varchar(10)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: phone
|
||||
type: varchar(12)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: disabled
|
||||
type: int
|
||||
default: 0
|
||||
notNull: true
|
||||
primaryKey:
|
||||
- address_id
|
||||
indexes:
|
||||
- name: addresses_fk_customers
|
||||
unique: false
|
||||
columns:
|
||||
- customer_id
|
||||
@@ -0,0 +1,4 @@
|
||||
{"__isStreamHeader":true,"pureName":"administrators","tableRowCount":"3","tableEngine":"InnoDB","objectComment":"","modifyDate":"2025-02-03 02:56:33","objectId":"administrators","contentHash":"2025-02-03 02:56:33","columns":[{"notNull":true,"autoIncrement":true,"columnName":"admin_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"email_address","columnComment":"","dataType":"varchar(255)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"password","columnComment":"","dataType":"varchar(255)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"first_name","columnComment":"","dataType":"varchar(255)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"last_name","columnComment":"","dataType":"varchar(255)","defaultValue":null,"isUnsigned":false,"isZerofill":false}],"primaryKey":{"constraintName":"PRIMARY","pureName":"administrators","constraintType":"primaryKey","columns":[{"columnName":"admin_id"}]},"foreignKeys":[],"indexes":[],"uniques":[],"engine":"mysql@dbgate-plugin-mysql"}
|
||||
{"admin_id":1,"email_address":"admin@myguitarshop.com","password":"6a718fbd768c2378b511f8249b54897f940e9022","first_name":"Admin","last_name":"User"}
|
||||
{"admin_id":2,"email_address":"joel@murach.com","password":"971e95957d3b74d70d79c20c94e9cd91b85f7aae","first_name":"Joel","last_name":"Murach"}
|
||||
{"admin_id":3,"email_address":"mike@murach.com","password":"3f2975c819cefc686282456aeae3a137bf896ee8","first_name":"Mike","last_name":"Murach"}
|
||||
@@ -0,0 +1,25 @@
|
||||
name: administrators
|
||||
columns:
|
||||
- name: admin_id
|
||||
type: int
|
||||
default: null
|
||||
autoIncrement: true
|
||||
notNull: true
|
||||
- name: email_address
|
||||
type: varchar(255)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: password
|
||||
type: varchar(255)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: first_name
|
||||
type: varchar(255)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: last_name
|
||||
type: varchar(255)
|
||||
default: null
|
||||
notNull: true
|
||||
primaryKey:
|
||||
- admin_id
|
||||
@@ -0,0 +1,5 @@
|
||||
{"__isStreamHeader":true,"pureName":"categories","tableRowCount":"4","tableEngine":"InnoDB","objectComment":"","modifyDate":"2025-02-03 02:56:32","objectId":"categories","contentHash":"2025-02-03 02:56:32","columns":[{"notNull":true,"autoIncrement":true,"columnName":"category_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"category_name","columnComment":"","dataType":"varchar(255)","defaultValue":null,"isUnsigned":false,"isZerofill":false}],"primaryKey":{"constraintName":"PRIMARY","pureName":"categories","constraintType":"primaryKey","columns":[{"columnName":"category_id"}]},"foreignKeys":[],"indexes":[],"uniques":[{"constraintName":"category_name","columns":[{"columnName":"category_name"}]}],"engine":"mysql@dbgate-plugin-mysql"}
|
||||
{"category_id":2,"category_name":"Basses"}
|
||||
{"category_id":3,"category_name":"Drums"}
|
||||
{"category_id":1,"category_name":"Guitars"}
|
||||
{"category_id":4,"category_name":"Keyboards"}
|
||||
@@ -0,0 +1,12 @@
|
||||
name: categories
|
||||
columns:
|
||||
- name: category_id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
- name: category_name
|
||||
type: varchar(255)
|
||||
default: null
|
||||
notNull: true
|
||||
primaryKey:
|
||||
- category_id
|
||||
@@ -0,0 +1,9 @@
|
||||
{"__isStreamHeader":true,"pureName":"customers","tableRowCount":"8","tableEngine":"InnoDB","objectComment":"","modifyDate":"2025-02-03 02:56:32","objectId":"customers","contentHash":"2025-02-03 02:56:32","columns":[{"notNull":true,"autoIncrement":true,"columnName":"customer_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"email_address","columnComment":"","dataType":"varchar(255)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"password","columnComment":"","dataType":"varchar(60)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"first_name","columnComment":"","dataType":"varchar(60)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"last_name","columnComment":"","dataType":"varchar(60)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":false,"autoIncrement":false,"columnName":"shipping_address_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":false,"autoIncrement":false,"columnName":"billing_address_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false}],"primaryKey":{"constraintName":"PRIMARY","pureName":"customers","constraintType":"primaryKey","columns":[{"columnName":"customer_id"}]},"foreignKeys":[],"indexes":[],"uniques":[{"constraintName":"email_address","columns":[{"columnName":"email_address"}]}],"engine":"mysql@dbgate-plugin-mysql"}
|
||||
{"customer_id":1,"email_address":"allan.sherwood@yahoo.com","password":"650215acec746f0e32bdfff387439eefc1358737","first_name":"Allan","last_name":"Sherwood","shipping_address_id":1,"billing_address_id":2}
|
||||
{"customer_id":2,"email_address":"barryz@gmail.com","password":"3f563468d42a448cb1e56924529f6e7bbe529cc7","first_name":"Barry","last_name":"Zimmer","shipping_address_id":3,"billing_address_id":3}
|
||||
{"customer_id":3,"email_address":"christineb@solarone.com","password":"ed19f5c0833094026a2f1e9e6f08a35d26037066","first_name":"Christine","last_name":"Brown","shipping_address_id":4,"billing_address_id":4}
|
||||
{"customer_id":4,"email_address":"david.goldstein@hotmail.com","password":"b444ac06613fc8d63795be9ad0beaf55011936ac","first_name":"David","last_name":"Goldstein","shipping_address_id":5,"billing_address_id":6}
|
||||
{"customer_id":5,"email_address":"erinv@gmail.com","password":"109f4b3c50d7b0df729d299bc6f8e9ef9066971f","first_name":"Erin","last_name":"Valentino","shipping_address_id":7,"billing_address_id":7}
|
||||
{"customer_id":6,"email_address":"frankwilson@sbcglobal.net","password":"3ebfa301dc59196f18593c45e519287a23297589","first_name":"Frank Lee","last_name":"Wilson","shipping_address_id":8,"billing_address_id":8}
|
||||
{"customer_id":7,"email_address":"gary_hernandez@yahoo.com","password":"1ff2b3704aede04eecb51e50ca698efd50a1379b","first_name":"Gary","last_name":"Hernandez","shipping_address_id":9,"billing_address_id":10}
|
||||
{"customer_id":8,"email_address":"heatheresway@mac.com","password":"911ddc3b8f9a13b5499b6bc4638a2b4f3f68bf23","first_name":"Heather","last_name":"Esway","shipping_address_id":11,"billing_address_id":12}
|
||||
@@ -0,0 +1,31 @@
|
||||
name: customers
|
||||
columns:
|
||||
- name: customer_id
|
||||
type: int
|
||||
default: null
|
||||
autoIncrement: true
|
||||
notNull: true
|
||||
- name: email_address
|
||||
type: varchar(255)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: password
|
||||
type: varchar(60)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: first_name
|
||||
type: varchar(60)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: last_name
|
||||
type: varchar(60)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: shipping_address_id
|
||||
type: int
|
||||
default: null
|
||||
- name: billing_address_id
|
||||
type: int
|
||||
default: null
|
||||
primaryKey:
|
||||
- customer_id
|
||||
@@ -0,0 +1,13 @@
|
||||
{"__isStreamHeader":true,"pureName":"order_items","tableRowCount":"12","tableEngine":"InnoDB","objectComment":"","modifyDate":"2025-02-03 02:56:33","objectId":"order_items","contentHash":"2025-02-03 02:56:33","columns":[{"notNull":true,"autoIncrement":true,"columnName":"item_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"order_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"product_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"item_price","columnComment":"","dataType":"decimal(10,2)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"discount_amount","columnComment":"","dataType":"decimal(10,2)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"quantity","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false}],"primaryKey":{"constraintName":"PRIMARY","pureName":"order_items","constraintType":"primaryKey","columns":[{"columnName":"item_id"}]},"foreignKeys":[{"constraintName":"items_fk_products","constraintType":"foreignKey","pureName":"order_items","refTableName":"products","updateAction":"NO ACTION","deleteAction":"NO ACTION","columns":[{"columnName":"product_id","refColumnName":"product_id"}]},{"constraintName":"items_fk_orders","constraintType":"foreignKey","pureName":"order_items","refTableName":"orders","updateAction":"NO ACTION","deleteAction":"NO ACTION","columns":[{"columnName":"order_id","refColumnName":"order_id"}]}],"indexes":[{"constraintName":"items_fk_orders","indexType":"BTREE","isUnique":false,"columns":[{"columnName":"order_id","isDescending":0}]},{"constraintName":"items_fk_products","indexType":"BTREE","isUnique":false,"columns":[{"columnName":"product_id","isDescending":0}]}],"uniques":[],"engine":"mysql@dbgate-plugin-mysql"}
|
||||
{"item_id":1,"order_id":1,"product_id":2,"item_price":"1199.00","discount_amount":"359.70","quantity":1}
|
||||
{"item_id":2,"order_id":2,"product_id":4,"item_price":"489.99","discount_amount":"186.20","quantity":1}
|
||||
{"item_id":3,"order_id":3,"product_id":3,"item_price":"2517.00","discount_amount":"1308.84","quantity":1}
|
||||
{"item_id":4,"order_id":3,"product_id":6,"item_price":"415.00","discount_amount":"161.85","quantity":1}
|
||||
{"item_id":5,"order_id":4,"product_id":2,"item_price":"1199.00","discount_amount":"359.70","quantity":2}
|
||||
{"item_id":6,"order_id":5,"product_id":5,"item_price":"299.00","discount_amount":"0.00","quantity":1}
|
||||
{"item_id":7,"order_id":6,"product_id":5,"item_price":"299.00","discount_amount":"0.00","quantity":1}
|
||||
{"item_id":8,"order_id":7,"product_id":1,"item_price":"699.00","discount_amount":"209.70","quantity":1}
|
||||
{"item_id":9,"order_id":7,"product_id":7,"item_price":"799.99","discount_amount":"240.00","quantity":1}
|
||||
{"item_id":10,"order_id":7,"product_id":9,"item_price":"699.99","discount_amount":"210.00","quantity":1}
|
||||
{"item_id":11,"order_id":8,"product_id":10,"item_price":"799.99","discount_amount":"120.00","quantity":1}
|
||||
{"item_id":12,"order_id":9,"product_id":1,"item_price":"699.00","discount_amount":"209.70","quantity":1}
|
||||
@@ -0,0 +1,40 @@
|
||||
name: order_items
|
||||
columns:
|
||||
- name: item_id
|
||||
type: int
|
||||
default: null
|
||||
autoIncrement: true
|
||||
notNull: true
|
||||
- name: order_id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
references: orders
|
||||
- name: product_id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
references: products
|
||||
- name: item_price
|
||||
type: decimal(10,2)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: discount_amount
|
||||
type: decimal(10,2)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: quantity
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
primaryKey:
|
||||
- item_id
|
||||
indexes:
|
||||
- name: items_fk_orders
|
||||
unique: false
|
||||
columns:
|
||||
- order_id
|
||||
- name: items_fk_products
|
||||
unique: false
|
||||
columns:
|
||||
- product_id
|
||||
@@ -0,0 +1,10 @@
|
||||
{"__isStreamHeader":true,"pureName":"orders","tableRowCount":"9","tableEngine":"InnoDB","objectComment":"","modifyDate":"2025-02-03T02:56:32","objectId":"orders","contentHash":"2025-02-03 02:56:32","columns":[{"notNull":true,"autoIncrement":true,"columnName":"order_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"customer_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"order_date","columnComment":"","dataType":"datetime","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"ship_amount","columnComment":"","dataType":"decimal(10,2)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"tax_amount","columnComment":"","dataType":"decimal(10,2)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":false,"autoIncrement":false,"columnName":"ship_date","columnComment":"","dataType":"datetime","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"ship_address_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"card_type","columnComment":"","dataType":"varchar(50)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"card_number","columnComment":"","dataType":"char(16)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"card_expires","columnComment":"","dataType":"char(7)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"billing_address_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false}],"primaryKey":{"constraintName":"PRIMARY","pureName":"orders","constraintType":"primaryKey","columns":[{"columnName":"order_id"}]},"foreignKeys":[{"constraintName":"orders_fk_customers","constraintType":"foreignKey","pureName":"orders","refTableName":"customers","updateAction":"NO ACTION","deleteAction":"NO ACTION","columns":[{"columnName":"customer_id","refColumnName":"customer_id"}]}],"indexes":[{"constraintName":"orders_fk_customers","indexType":"BTREE","isUnique":false,"columns":[{"columnName":"customer_id","isDescending":0}]}],"uniques":[],"engine":"mysql@dbgate-plugin-mysql"}
|
||||
{"order_id":1,"customer_id":1,"order_date":"2018-03-28T09:40:28","ship_amount":"5.00","tax_amount":"32.32","ship_date":"2018-03-30T15:32:51","ship_address_id":1,"card_type":"Visa","card_number":"4111111111111111","card_expires":"04/2020","billing_address_id":2}
|
||||
{"order_id":2,"customer_id":2,"order_date":"2018-03-28T11:23:20","ship_amount":"5.00","tax_amount":"0.00","ship_date":"2018-03-29T12:52:14","ship_address_id":3,"card_type":"Visa","card_number":"4012888888881881","card_expires":"08/2019","billing_address_id":3}
|
||||
{"order_id":3,"customer_id":1,"order_date":"2018-03-29T09:44:58","ship_amount":"10.00","tax_amount":"89.92","ship_date":"2018-03-31T09:11:41","ship_address_id":1,"card_type":"Visa","card_number":"4111111111111111","card_expires":"04/2017","billing_address_id":2}
|
||||
{"order_id":4,"customer_id":3,"order_date":"2018-03-30T15:22:31","ship_amount":"5.00","tax_amount":"0.00","ship_date":"2018-04-03T16:32:21","ship_address_id":4,"card_type":"American Express","card_number":"378282246310005","card_expires":"04/2016","billing_address_id":4}
|
||||
{"order_id":5,"customer_id":4,"order_date":"2018-03-31T05:43:11","ship_amount":"5.00","tax_amount":"0.00","ship_date":"2018-04-02T14:21:12","ship_address_id":5,"card_type":"Visa","card_number":"4111111111111111","card_expires":"04/2019","billing_address_id":6}
|
||||
{"order_id":6,"customer_id":5,"order_date":"2018-03-31T18:37:22","ship_amount":"5.00","tax_amount":"0.00","ship_date":null,"ship_address_id":7,"card_type":"Discover","card_number":"6011111111111117","card_expires":"04/2019","billing_address_id":7}
|
||||
{"order_id":7,"customer_id":6,"order_date":"2018-04-01T23:11:12","ship_amount":"15.00","tax_amount":"0.00","ship_date":"2018-04-03T10:21:35","ship_address_id":8,"card_type":"MasterCard","card_number":"5555555555554444","card_expires":"04/2019","billing_address_id":8}
|
||||
{"order_id":8,"customer_id":7,"order_date":"2018-04-02T11:26:38","ship_amount":"5.00","tax_amount":"0.00","ship_date":null,"ship_address_id":9,"card_type":"Visa","card_number":"4012888888881881","card_expires":"04/2019","billing_address_id":10}
|
||||
{"order_id":9,"customer_id":4,"order_date":"2018-04-03T12:22:31","ship_amount":"5.00","tax_amount":"0.00","ship_date":null,"ship_address_id":5,"card_type":"Visa","card_number":"4111111111111111","card_expires":"04/2019","billing_address_id":6}
|
||||
@@ -0,0 +1,54 @@
|
||||
name: orders
|
||||
columns:
|
||||
- name: order_id
|
||||
type: int
|
||||
default: null
|
||||
autoIncrement: true
|
||||
notNull: true
|
||||
- name: customer_id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
references: customers
|
||||
- name: order_date
|
||||
type: datetime
|
||||
default: null
|
||||
notNull: true
|
||||
- name: ship_amount
|
||||
type: decimal(10,2)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: tax_amount
|
||||
type: decimal(10,2)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: ship_date
|
||||
type: datetime
|
||||
default: null
|
||||
- name: ship_address_id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
- name: card_type
|
||||
type: varchar(50)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: card_number
|
||||
type: char(16)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: card_expires
|
||||
type: char(7)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: billing_address_id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
primaryKey:
|
||||
- order_id
|
||||
indexes:
|
||||
- name: orders_fk_customers
|
||||
unique: false
|
||||
columns:
|
||||
- customer_id
|
||||
@@ -0,0 +1,11 @@
|
||||
{"__isStreamHeader":true,"pureName":"products","tableRowCount":"10","tableEngine":"InnoDB","objectComment":"","modifyDate":"2025-02-03 02:56:32","objectId":"products","contentHash":"2025-02-03 02:56:32","columns":[{"notNull":true,"autoIncrement":true,"columnName":"product_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"category_id","columnComment":"","dataType":"int","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"product_code","columnComment":"","dataType":"varchar(10)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"product_name","columnComment":"","dataType":"varchar(255)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"description","columnComment":"","dataType":"text","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"list_price","columnComment":"","dataType":"decimal(10,2)","defaultValue":null,"isUnsigned":false,"isZerofill":false},{"notNull":true,"autoIncrement":false,"columnName":"discount_percent","columnComment":"","dataType":"decimal(10,2)","defaultValue":"0.00","isUnsigned":false,"isZerofill":false},{"notNull":false,"autoIncrement":false,"columnName":"date_added","columnComment":"","dataType":"datetime","defaultValue":null,"isUnsigned":false,"isZerofill":false}],"primaryKey":{"constraintName":"PRIMARY","pureName":"products","constraintType":"primaryKey","columns":[{"columnName":"product_id"}]},"foreignKeys":[{"constraintName":"products_fk_categories","constraintType":"foreignKey","pureName":"products","refTableName":"categories","updateAction":"NO ACTION","deleteAction":"NO ACTION","columns":[{"columnName":"category_id","refColumnName":"category_id"}]}],"indexes":[{"constraintName":"products_fk_categories","indexType":"BTREE","isUnique":false,"columns":[{"columnName":"category_id","isDescending":0}]}],"uniques":[{"constraintName":"product_code","columns":[{"columnName":"product_code"}]}],"engine":"mysql@dbgate-plugin-mysql"}
|
||||
{"product_id":1,"category_id":1,"product_code":"strat","product_name":"Fender Stratocaster","description":"The Fender Stratocaster is the electric guitar design that changed the world. New features include a tinted neck, parchment pickguard and control knobs, and a '70s-style logo. Includes select alder body, 21-fret maple neck with your choice of a rosewood or maple fretboard, 3 single-coil pickups, vintage-style tremolo, and die-cast tuning keys. This guitar features a thicker bridge block for increased sustain and a more stable point of contact with the strings. At this low price, why play anything but the real thing?\r\n\r\nFeatures:\r\n\r\n* New features:\r\n* Thicker bridge block\r\n* 3-ply parchment pick guard\r\n* Tinted neck","list_price":"699.00","discount_percent":"30.00","date_added":"2017-10-30T09:32:40"}
|
||||
{"product_id":2,"category_id":1,"product_code":"les_paul","product_name":"Gibson Les Paul","description":"This Les Paul guitar offers a carved top and humbucking pickups. It has a simple yet elegant design. Cutting-yet-rich tone?the hallmark of the Les Paul?pours out of the 490R and 498T Alnico II magnet humbucker pickups, which are mounted on a carved maple top with a mahogany back. The faded finish models are equipped with BurstBucker Pro pickups and a mahogany top. This guitar includes a Gibson hardshell case (Faded and satin finish models come with a gig bag) and a limited lifetime warranty.\r\n\r\nFeatures:\r\n\r\n* Carved maple top and mahogany back (Mahogany top on faded finish models)\r\n* Mahogany neck, '59 Rounded Les Paul\r\n* Rosewood fingerboard (Ebony on Alpine white)\r\n* Tune-O-Matic bridge with stopbar\r\n* Chrome or gold hardware\r\n* 490R and 498T Alnico 2 magnet humbucker pickups (BurstBucker Pro on faded finish models)\r\n* 2 volume and 2 tone knobs, 3-way switch","list_price":"1199.00","discount_percent":"30.00","date_added":"2017-12-05T16:33:13"}
|
||||
{"product_id":3,"category_id":1,"product_code":"sg","product_name":"Gibson SG","description":"This Gibson SG electric guitar takes the best of the '62 original and adds the longer and sturdier neck joint of the late '60s models. All the classic features you'd expect from a historic guitar. Hot humbuckers go from rich, sweet lightning to warm, tingling waves of sustain. A silky-fast rosewood fretboard plays like a dream. The original-style beveled mahogany body looks like a million bucks. Plus, Tune-O-Matic bridge and chrome hardware. Limited lifetime warranty. Includes hardshell case.\r\n\r\nFeatures:\r\n\r\n* Double-cutaway beveled mahogany body\r\n* Set mahogany neck with rounded '50s profile\r\n* Bound rosewood fingerboard with trapezoid inlays\r\n* Tune-O-Matic bridge with stopbar tailpiece\r\n* Chrome hardware\r\n* 490R humbucker in the neck position\r\n* 498T humbucker in the bridge position\r\n* 2 volume knobs, 2 tone knobs, 3-way switch\r\n* 24-3/4\" scale","list_price":"2517.00","discount_percent":"52.00","date_added":"2018-02-04T11:04:31"}
|
||||
{"product_id":4,"category_id":1,"product_code":"fg700s","product_name":"Yamaha FG700S","description":"The Yamaha FG700S solid top acoustic guitar has the ultimate combo for projection and pure tone. The expertly braced spruce top speaks clearly atop the rosewood body. It has a rosewood fingerboard, rosewood bridge, die-cast tuners, body and neck binding, and a tortoise pickguard.\r\n\r\nFeatures:\r\n\r\n* Solid Sitka spruce top\r\n* Rosewood back and sides\r\n* Rosewood fingerboard\r\n* Rosewood bridge\r\n* White/black body and neck binding\r\n* Die-cast tuners\r\n* Tortoise pickguard\r\n* Limited lifetime warranty","list_price":"489.99","discount_percent":"38.00","date_added":"2018-06-01T11:12:59"}
|
||||
{"product_id":5,"category_id":1,"product_code":"washburn","product_name":"Washburn D10S","description":"The Washburn D10S acoustic guitar is superbly crafted with a solid spruce top and mahogany back and sides for exceptional tone. A mahogany neck and rosewood fingerboard make fretwork a breeze, while chrome Grover-style machines keep you perfectly tuned. The Washburn D10S comes with a limited lifetime warranty.\r\n\r\nFeatures:\r\n\r\n * Spruce top\r\n * Mahogany back, sides\r\n * Mahogany neck Rosewood fingerboard\r\n * Chrome Grover-style machines","list_price":"299.00","discount_percent":"0.00","date_added":"2018-07-30T13:58:35"}
|
||||
{"product_id":6,"category_id":1,"product_code":"rodriguez","product_name":"Rodriguez Caballero 11","description":"Featuring a carefully chosen, solid Canadian cedar top and laminated bubinga back and sides, the Caballero 11 classical guitar is a beauty to behold and play. The headstock and fretboard are of Indian rosewood. Nickel-plated tuners and Silver-plated frets are installed to last a lifetime. The body binding and wood rosette are exquisite.\r\n\r\nThe Rodriguez Guitar is hand crafted and glued to create precise balances. From the invisible careful sanding, even inside the body, that ensures the finished instrument's purity of tone, to the beautifully unique rosette inlays around the soundhole and on the back of the neck, each guitar is a credit to its luthier and worthy of being handed down from one generation to another.\r\n\r\nThe tone, resonance and beauty of fine guitars are all dependent upon the wood from which they are made. The wood used in the construction of Rodriguez guitars is carefully chosen and aged to guarantee the highest quality. No wood is purchased before the tree has been cut down, and at least 2 years must elapse before the tree is turned into lumber. The wood has to be well cut from the log. The grain must be close and absolutely vertical. The shop is totally free from humidity.","list_price":"415.00","discount_percent":"39.00","date_added":"2018-07-30T14:12:41"}
|
||||
{"product_id":7,"category_id":2,"product_code":"precision","product_name":"Fender Precision","description":"The Fender Precision bass guitar delivers the sound, look, and feel today's bass players demand. This bass features that classic P-Bass old-school design. Each Precision bass boasts contemporary features and refinements that make it an excellent value. Featuring an alder body and a split single-coil pickup, this classic electric bass guitar lives up to its Fender legacy.\r\n\r\nFeatures:\r\n\r\n* Body: Alder\r\n* Neck: Maple, modern C shape, tinted satin urethane finish\r\n* Fingerboard: Rosewood or maple (depending on color)\r\n* 9-1/2\" Radius (241 mm)\r\n* Frets: 20 Medium-jumbo frets\r\n* Pickups: 1 Standard Precision Bass split single-coil pickup (Mid)\r\n* Controls: Volume, Tone\r\n* Bridge: Standard vintage style with single groove saddles\r\n* Machine heads: Standard\r\n* Hardware: Chrome\r\n* Pickguard: 3-Ply Parchment\r\n* Scale Length: 34\" (864 mm)\r\n* Width at Nut: 1-5/8\" (41.3 mm)\r\n* Unique features: Knurled chrome P Bass knobs, Fender transition logo","list_price":"799.99","discount_percent":"30.00","date_added":"2018-06-01T11:29:35"}
|
||||
{"product_id":8,"category_id":2,"product_code":"hofner","product_name":"Hofner Icon","description":"With authentic details inspired by the original, the Hofner Icon makes the legendary violin bass available to the rest of us. Don't get the idea that this a just a \"nowhere man\" look-alike. This quality instrument features a real spruce top and beautiful flamed maple back and sides. The semi-hollow body and set neck will give you the warm, round tone you expect from the violin bass.\r\n\r\nFeatures:\r\n\r\n* Authentic details inspired by the original\r\n* Spruce top\r\n* Flamed maple back and sides\r\n* Set neck\r\n* Rosewood fretboard\r\n* 30\" scale\r\n* 22 frets\r\n* Dot inlay","list_price":"499.99","discount_percent":"25.00","date_added":"2018-07-30T14:18:33"}
|
||||
{"product_id":9,"category_id":3,"product_code":"ludwig","product_name":"Ludwig 5-piece Drum Set with Cymbals","description":"This product includes a Ludwig 5-piece drum set and a Zildjian starter cymbal pack.\r\n\r\nWith the Ludwig drum set, you get famous Ludwig quality. This set features a bass drum, two toms, a floor tom, and a snare?each with a wrapped finish. Drum hardware includes LA214FP bass pedal, snare stand, cymbal stand, hi-hat stand, and a throne.\r\n\r\nWith the Zildjian cymbal pack, you get a 14\" crash, 18\" crash/ride, and a pair of 13\" hi-hats. Sound grooves and round hammer strikes in a simple circular pattern on the top surface of these cymbals magnify the basic sound of the distinctive alloy.\r\n\r\nFeatures:\r\n\r\n* Famous Ludwig quality\r\n* Wrapped finishes\r\n* 22\" x 16\" kick drum\r\n* 12\" x 10\" and 13\" x 11\" toms\r\n* 16\" x 16\" floor tom\r\n* 14\" x 6-1/2\" snare drum kick pedal\r\n* Snare stand\r\n* Straight cymbal stand hi-hat stand\r\n* FREE throne","list_price":"699.99","discount_percent":"30.00","date_added":"2018-07-30T12:46:40"}
|
||||
{"product_id":10,"category_id":3,"product_code":"tama","product_name":"Tama 5-Piece Drum Set with Cymbals","description":"The Tama 5-piece Drum Set is the most affordable Tama drum kit ever to incorporate so many high-end features.\r\n\r\nWith over 40 years of experience, Tama knows what drummers really want. Which is why, no matter how long you've been playing the drums, no matter what budget you have to work with, Tama has the set you need, want, and can afford. Every aspect of the modern drum kit was exhaustively examined and reexamined and then improved before it was accepted as part of the Tama design. Which is why, if you start playing Tama now as a beginner, you'll still enjoy playing it when you've achieved pro-status. That's how good these groundbreaking new drums are.\r\n\r\nOnly Tama comes with a complete set of genuine Meinl HCS cymbals. These high-quality brass cymbals are made in Germany and are sonically matched so they sound great together. They are even lathed for a more refined tonal character. The set includes 14\" hi-hats, 16\" crash cymbal, and a 20\" ride cymbal.\r\n\r\nFeatures:\r\n\r\n* 100% poplar 6-ply/7.5mm shells\r\n* Precise bearing edges\r\n* 100% glued finishes\r\n* Original small lugs\r\n* Drum heads\r\n* Accu-tune bass drum hoops\r\n* Spur brackets\r\n* Tom holder\r\n* Tom brackets","list_price":"799.99","discount_percent":"15.00","date_added":"2018-07-30T13:14:15"}
|
||||
@@ -0,0 +1,42 @@
|
||||
name: products
|
||||
columns:
|
||||
- name: product_id
|
||||
type: int
|
||||
default: null
|
||||
autoIncrement: true
|
||||
notNull: true
|
||||
- name: category_id
|
||||
type: int
|
||||
default: null
|
||||
notNull: true
|
||||
references: categories
|
||||
- name: product_code
|
||||
type: varchar(10)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: product_name
|
||||
type: varchar(255)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: description
|
||||
type: text
|
||||
default: null
|
||||
notNull: true
|
||||
- name: list_price
|
||||
type: decimal(10,2)
|
||||
default: null
|
||||
notNull: true
|
||||
- name: discount_percent
|
||||
type: decimal(10,2)
|
||||
default: '0.00'
|
||||
notNull: true
|
||||
- name: date_added
|
||||
type: datetime
|
||||
default: null
|
||||
primaryKey:
|
||||
- product_id
|
||||
indexes:
|
||||
- name: products_fk_categories
|
||||
unique: false
|
||||
columns:
|
||||
- category_id
|
||||
@@ -21,7 +21,7 @@ services:
|
||||
build: containers/mysql-ssh-login
|
||||
restart: always
|
||||
ports:
|
||||
- 16005:3306
|
||||
- 16017:3306
|
||||
- "16012:22"
|
||||
|
||||
mysql-ssh-keyfile:
|
||||
@@ -37,7 +37,7 @@ services:
|
||||
- "16009:5556"
|
||||
|
||||
mongo:
|
||||
image: mongo:4.0.12
|
||||
image: mongo:4.4.29
|
||||
restart: always
|
||||
environment:
|
||||
MONGO_INITDB_ROOT_USERNAME: root
|
||||
@@ -49,3 +49,20 @@ services:
|
||||
image: redis
|
||||
ports:
|
||||
- 16011:6379
|
||||
|
||||
mssql:
|
||||
image: mcr.microsoft.com/mssql/server
|
||||
restart: always
|
||||
ports:
|
||||
- 16014:1433
|
||||
environment:
|
||||
- ACCEPT_EULA=Y
|
||||
- SA_PASSWORD=Pwd2020Db
|
||||
- MSSQL_PID=Express
|
||||
|
||||
oracle:
|
||||
image: gvenzl/oracle-xe:21-slim
|
||||
environment:
|
||||
ORACLE_PASSWORD: Pwd2020Db
|
||||
ports:
|
||||
- 16013:1521
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
const fs = require('fs');
|
||||
|
||||
const baseDir = path.join(os.homedir(), '.dbgate');
|
||||
|
||||
// function createTimeStamp() {
|
||||
// const now = new Date();
|
||||
// const year = now.getFullYear();
|
||||
// const month = String(now.getMonth() + 1).padStart(2, '0'); // měsíc je 0-indexovaný
|
||||
// const day = String(now.getDate()).padStart(2, '0');
|
||||
// const hours = String(now.getHours()).padStart(2, '0');
|
||||
// const minutes = String(now.getMinutes()).padStart(2, '0');
|
||||
// const seconds = String(now.getSeconds()).padStart(2, '0');
|
||||
|
||||
// // Poskládáme datum a čas do názvu souboru
|
||||
// const ts = `${year}-${month}-${day}_${hours}-${minutes}-${seconds}`;
|
||||
// return ts;
|
||||
// }
|
||||
|
||||
function clearTestingData() {
|
||||
if (fs.existsSync(path.join(baseDir, 'connections-e2etests.jsonl'))) {
|
||||
fs.unlinkSync(path.join(baseDir, 'connections-e2etests.jsonl'));
|
||||
}
|
||||
if (fs.existsSync(path.join(baseDir, 'files-e2etests'))) {
|
||||
fs.rmdirSync(path.join(baseDir, 'files-e2etests'), { recursive: true });
|
||||
}
|
||||
if (fs.existsSync(path.join(baseDir, 'archive-e2etests'))) {
|
||||
fs.rmdirSync(path.join(baseDir, 'archive-e2etests'), { recursive: true });
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
clearTestingData,
|
||||
};
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
CONNECTIONS=mysql
|
||||
|
||||
LABEL_mysql=MySql-connection
|
||||
SERVER_mysql=localhost
|
||||
USER_mysql=root
|
||||
PASSWORD_mysql=Pwd2020Db
|
||||
PORT_mysql=16004
|
||||
ENGINE_mysql=mysql@dbgate-plugin-mysql
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
ALLOW_DBGATE_PRIVATE_CLOUD=1
|
||||
REDIRECT_TO_DBGATE_CLOUD_LOGIN=1
|
||||
Vendored
+45
@@ -0,0 +1,45 @@
|
||||
CONNECTIONS=mysql,postgres,mssql,oracle,sqlite,mongo
|
||||
LOG_CONNECTION_SENSITIVE_VALUES=true
|
||||
|
||||
LABEL_mysql=MySql-connection
|
||||
SERVER_mysql=localhost
|
||||
USER_mysql=root
|
||||
PASSWORD_mysql=Pwd2020Db
|
||||
PORT_mysql=16004
|
||||
ENGINE_mysql=mysql@dbgate-plugin-mysql
|
||||
DBCONFIG_mysql=[{"name":"MyChinook","connectionColor":"cyan"}]
|
||||
|
||||
LABEL_postgres=Postgres-connection
|
||||
SERVER_postgres=localhost
|
||||
USER_postgres=postgres
|
||||
PASSWORD_postgres=Pwd2020Db
|
||||
PORT_postgres=16000
|
||||
ENGINE_postgres=postgres@dbgate-plugin-postgres
|
||||
DBCONFIG_postgres=[{"name":"PgChinook","connectionColor":"red"}]
|
||||
|
||||
LABEL_oracle=Oracle-connection
|
||||
SERVER_oracle=localhost
|
||||
USER_oracle=system
|
||||
PASSWORD_oracle=Pwd2020Db
|
||||
PORT_oracle=16013
|
||||
ENGINE_oracle=oracle@dbgate-plugin-oracle
|
||||
SERVICE_NAME_oracle=xe
|
||||
|
||||
LABEL_mssql=Mssql-connection
|
||||
SERVER_mssql=localhost
|
||||
USER_mssql=sa
|
||||
PASSWORD_mssql=Pwd2020Db
|
||||
PORT_mssql=16014
|
||||
ENGINE_mssql=mssql@dbgate-plugin-mssql
|
||||
|
||||
LABEL_sqlite=Sqlite-connection
|
||||
FILE_sqlite=%%E2E_TEST_DATA_DIRECTORY%%/my_guitar_shop.db
|
||||
ENGINE_sqlite=sqlite@dbgate-plugin-sqlite
|
||||
|
||||
LABEL_mongo=Mongo-connection
|
||||
SERVER_mongo=localhost
|
||||
USER_mongo=root
|
||||
PASSWORD_mongo=Pwd2020Db
|
||||
PORT_mongo=16010
|
||||
ENGINE_mongo=mongo@dbgate-plugin-mongo
|
||||
|
||||
@@ -195,6 +195,11 @@ async function run() {
|
||||
path.join(baseDir, 'archive-e2etests', 'default')
|
||||
);
|
||||
|
||||
await copyFolder(
|
||||
path.resolve(path.join(__dirname, '../data/chinook-jsonl')),
|
||||
path.join(baseDir, 'archive-e2etests', 'chinook-archive')
|
||||
);
|
||||
|
||||
await copyFolder(
|
||||
path.resolve(path.join(__dirname, '../data/files/query')),
|
||||
path.join(baseDir, 'files-e2etests', 'query')
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
const fs = require('fs');
|
||||
|
||||
const baseDir = path.join(os.homedir(), '.dbgate');
|
||||
|
||||
const dbgateApi = require('dbgate-api');
|
||||
dbgateApi.initializeApiEnvironment();
|
||||
const dbgatePluginMysql = require('dbgate-plugin-mysql');
|
||||
dbgateApi.registerPlugins(dbgatePluginMysql);
|
||||
|
||||
async function copyFolder(source, target) {
|
||||
if (!fs.existsSync(target)) {
|
||||
fs.mkdirSync(target, { recursive: true });
|
||||
}
|
||||
for (const file of fs.readdirSync(source)) {
|
||||
fs.copyFileSync(path.join(source, file), path.join(target, file));
|
||||
}
|
||||
}
|
||||
|
||||
async function initMySqlDatabase(dbname, inputFile) {
|
||||
await dbgateApi.executeQuery({
|
||||
connection: {
|
||||
server: process.env.SERVER_mysql,
|
||||
user: process.env.USER_mysql,
|
||||
password: process.env.PASSWORD_mysql,
|
||||
port: process.env.PORT_mysql,
|
||||
engine: 'mysql@dbgate-plugin-mysql',
|
||||
},
|
||||
sql: `drop database if exists ${dbname}`,
|
||||
});
|
||||
|
||||
await dbgateApi.executeQuery({
|
||||
connection: {
|
||||
server: process.env.SERVER_mysql,
|
||||
user: process.env.USER_mysql,
|
||||
password: process.env.PASSWORD_mysql,
|
||||
port: process.env.PORT_mysql,
|
||||
engine: 'mysql@dbgate-plugin-mysql',
|
||||
},
|
||||
sql: `create database ${dbname}`,
|
||||
});
|
||||
|
||||
await dbgateApi.importDatabase({
|
||||
connection: {
|
||||
server: process.env.SERVER_mysql,
|
||||
user: process.env.USER_mysql,
|
||||
password: process.env.PASSWORD_mysql,
|
||||
port: process.env.PORT_mysql,
|
||||
database: dbname,
|
||||
engine: 'mysql@dbgate-plugin-mysql',
|
||||
},
|
||||
inputFile,
|
||||
});
|
||||
}
|
||||
|
||||
async function run() {
|
||||
const connection = {
|
||||
server: process.env.SERVER_mysql,
|
||||
user: process.env.USER_mysql,
|
||||
password: process.env.PASSWORD_mysql,
|
||||
port: process.env.PORT_mysql,
|
||||
engine: 'mysql@dbgate-plugin-mysql',
|
||||
};
|
||||
|
||||
try {
|
||||
await dbgateApi.executeQuery({
|
||||
connection,
|
||||
sql: 'drop database if exists charts_sample',
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Failed to drop database', err);
|
||||
}
|
||||
|
||||
await dbgateApi.executeQuery({
|
||||
connection,
|
||||
sql: 'create database charts_sample',
|
||||
});
|
||||
|
||||
await dbgateApi.importDbFromFolder({
|
||||
connection: {
|
||||
...connection,
|
||||
database: 'charts_sample',
|
||||
},
|
||||
folder: path.resolve(path.join(__dirname, '../data/charts-sample')),
|
||||
});
|
||||
|
||||
await copyFolder(
|
||||
path.resolve(path.join(__dirname, '../data/files/sql')),
|
||||
path.join(baseDir, 'files-e2etests', 'sql')
|
||||
);
|
||||
|
||||
await initMySqlDatabase('MyChinook', path.resolve(path.join(__dirname, '../data/chinook-mysql.sql')));
|
||||
}
|
||||
|
||||
dbgateApi.runScript(run);
|
||||
@@ -0,0 +1,130 @@
|
||||
const path = require('path');
|
||||
const localconfig = require('../.localconfig');
|
||||
|
||||
const dbgateApi = require('dbgate-api');
|
||||
dbgateApi.initializeApiEnvironment();
|
||||
const dbgatePluginMysql = require('dbgate-plugin-mysql');
|
||||
dbgateApi.registerPlugins(dbgatePluginMysql);
|
||||
const dbgatePluginPostgres = require('dbgate-plugin-postgres');
|
||||
dbgateApi.registerPlugins(dbgatePluginPostgres);
|
||||
|
||||
async function createDb(connection, dropDbSql, createDbSql, database = 'my_guitar_shop', { dropDatabaseName } = {}) {
|
||||
if (dropDbSql) {
|
||||
try {
|
||||
await dbgateApi.executeQuery({
|
||||
connection,
|
||||
sql: dropDbSql,
|
||||
database: dropDatabaseName,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Failed to drop database', err);
|
||||
}
|
||||
}
|
||||
|
||||
if (createDbSql) {
|
||||
await dbgateApi.executeQuery({
|
||||
connection,
|
||||
sql: createDbSql,
|
||||
});
|
||||
}
|
||||
|
||||
await dbgateApi.importDbFromFolder({
|
||||
connection: {
|
||||
...connection,
|
||||
database,
|
||||
},
|
||||
folder: path.resolve(path.join(__dirname, '../data/my-guitar-shop')),
|
||||
});
|
||||
}
|
||||
|
||||
async function run() {
|
||||
if (localconfig.postgres) {
|
||||
await createDb(
|
||||
{
|
||||
server: process.env.SERVER_postgres,
|
||||
user: process.env.USER_postgres,
|
||||
password: process.env.PASSWORD_postgres,
|
||||
port: process.env.PORT_postgres,
|
||||
engine: 'postgres@dbgate-plugin-postgres',
|
||||
},
|
||||
'drop database if exists my_guitar_shop',
|
||||
'create database my_guitar_shop'
|
||||
);
|
||||
}
|
||||
|
||||
if (localconfig.mysql) {
|
||||
await createDb(
|
||||
{
|
||||
server: process.env.SERVER_mysql,
|
||||
user: process.env.USER_mysql,
|
||||
password: process.env.PASSWORD_mysql,
|
||||
port: process.env.PORT_mysql,
|
||||
engine: 'mysql@dbgate-plugin-mysql',
|
||||
},
|
||||
'drop database if exists my_guitar_shop',
|
||||
'create database my_guitar_shop'
|
||||
);
|
||||
}
|
||||
|
||||
if (localconfig.mssql) {
|
||||
await createDb(
|
||||
{
|
||||
server: process.env.SERVER_mssql,
|
||||
user: process.env.USER_mssql,
|
||||
password: process.env.PASSWORD_mssql,
|
||||
port: process.env.PORT_mssql,
|
||||
engine: 'mssql@dbgate-plugin-mssql',
|
||||
},
|
||||
'drop database if exists my_guitar_shop',
|
||||
'create database my_guitar_shop'
|
||||
);
|
||||
}
|
||||
|
||||
if (localconfig.oracle) {
|
||||
await createDb(
|
||||
{
|
||||
server: process.env.SERVER_oracle,
|
||||
user: process.env.USER_oracle,
|
||||
password: process.env.PASSWORD_oracle,
|
||||
port: process.env.PORT_oracle,
|
||||
engine: 'oracle@dbgate-plugin-oracle',
|
||||
},
|
||||
'DROP USER c##my_guitar_shop CASCADE',
|
||||
'CREATE USER c##my_guitar_shop IDENTIFIED BY my_guitar_shop DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp QUOTA 10M ON users',
|
||||
'C##my_guitar_shop'
|
||||
);
|
||||
}
|
||||
|
||||
if (localconfig.sqlite) {
|
||||
await createDb(
|
||||
{
|
||||
databaseFile: process.env.FILE_sqlite.replace(
|
||||
'%%E2E_TEST_DATA_DIRECTORY%%',
|
||||
path.join(path.dirname(__dirname), 'tmpdata')
|
||||
),
|
||||
singleDatabase: true,
|
||||
engine: 'sqlite@dbgate-plugin-sqlite',
|
||||
},
|
||||
null,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
if (localconfig.mongo) {
|
||||
await createDb(
|
||||
{
|
||||
server: process.env.SERVER_mongo,
|
||||
user: process.env.USER_mongo,
|
||||
password: process.env.PASSWORD_mongo,
|
||||
port: process.env.PORT_mongo,
|
||||
engine: 'mongo@dbgate-plugin-mongo',
|
||||
},
|
||||
'db.dropDatabase()',
|
||||
null,
|
||||
'my_guitar_shop',
|
||||
{ dropDatabaseName: 'my_guitar_shop' }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
dbgateApi.runScript(run);
|
||||
+15
-6
@@ -20,20 +20,29 @@
|
||||
"cy:run:oauth": "cypress run --spec cypress/e2e/oauth.cy.js",
|
||||
"cy:run:browse-data": "cypress run --spec cypress/e2e/browse-data.cy.js",
|
||||
"cy:run:team": "cypress run --spec cypress/e2e/team.cy.js",
|
||||
"cy:run:multi-sql": "cypress run --spec cypress/e2e/multi-sql.cy.js",
|
||||
"cy:run:cloud": "cypress run --spec cypress/e2e/cloud.cy.js",
|
||||
"cy:run:charts": "cypress run --spec cypress/e2e/charts.cy.js",
|
||||
|
||||
"start:add-connection": "cd .. && node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:portal": "cd .. && env-cmd -f e2e-tests/env/portal/.env node e2e-tests/init/portal.js && env-cmd -f e2e-tests/env/portal/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:oauth": "cd .. && env-cmd -f e2e-tests/env/oauth/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:browse-data": "cd .. && env-cmd -f e2e-tests/env/browse-data/.env node e2e-tests/init/browse-data.js && env-cmd -f e2e-tests/env/browse-data/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:team": "cd .. && env-cmd -f e2e-tests/env/team/.env node e2e-tests/init/team.js && env-cmd -f e2e-tests/env/team/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:add-connection": "node clearTestingData && cd .. && node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:portal": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/portal/.env node e2e-tests/init/portal.js && env-cmd -f e2e-tests/env/portal/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:oauth": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/oauth/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:browse-data": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/browse-data/.env node e2e-tests/init/browse-data.js && env-cmd -f e2e-tests/env/browse-data/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:team": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/team/.env node e2e-tests/init/team.js && env-cmd -f e2e-tests/env/team/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:multi-sql": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/multi-sql/.env node e2e-tests/init/multi-sql.js && env-cmd -f e2e-tests/env/multi-sql/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:cloud": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/cloud/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:charts": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/charts/.env node e2e-tests/init/charts.js && env-cmd -f e2e-tests/env/charts/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
|
||||
"test:add-connection": "start-server-and-test start:add-connection http://localhost:3000 cy:run:add-connection",
|
||||
"test:portal": "start-server-and-test start:portal http://localhost:3000 cy:run:portal",
|
||||
"test:oauth": "start-server-and-test start:oauth http://localhost:3000 cy:run:oauth",
|
||||
"test:browse-data": "start-server-and-test start:browse-data http://localhost:3000 cy:run:browse-data",
|
||||
"test:team": "start-server-and-test start:team http://localhost:3000 cy:run:team",
|
||||
"test:multi-sql": "start-server-and-test start:multi-sql http://localhost:3000 cy:run:multi-sql",
|
||||
"test:cloud": "start-server-and-test start:cloud http://localhost:3000 cy:run:cloud",
|
||||
"test:charts": "start-server-and-test start:charts http://localhost:3000 cy:run:charts",
|
||||
|
||||
"test": "yarn test:add-connection && yarn test:portal && yarn test:oauth && yarn test:browse-data && yarn test:team",
|
||||
"test": "yarn test:add-connection && yarn test:portal && yarn test:oauth && yarn test:browse-data && yarn test:team && yarn test:multi-sql && yarn test:cloud && yarn test:charts",
|
||||
"test:ci": "yarn test"
|
||||
},
|
||||
"dependencies": {}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Folder with screenshots
|
||||
@@ -29,7 +29,7 @@ async function testDatabaseDiff(conn, driver, mangle, createObject = null) {
|
||||
driver,
|
||||
`create table ~t2 (
|
||||
~id int not null primary key,
|
||||
~t1_id int null references ~t1(~id)
|
||||
~t1_id int ${driver.dialect.implicitNullDeclaration ? '' : 'null'} references ~t1(~id)
|
||||
)`
|
||||
);
|
||||
|
||||
@@ -52,7 +52,7 @@ async function testDatabaseDiff(conn, driver, mangle, createObject = null) {
|
||||
}
|
||||
|
||||
describe('Alter database', () => {
|
||||
test.each(engines.filter(x => !x.skipReferences).map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(x => !x.skipReferences && !x.skipDropReferences).map(engine => [engine.label, engine]))(
|
||||
'Drop referenced table - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testDatabaseDiff(conn, driver, db => {
|
||||
@@ -76,26 +76,23 @@ describe('Alter database', () => {
|
||||
})
|
||||
);
|
||||
|
||||
const objectsSupportingRename = flatSource(x => x.supportRenameSqlObject);
|
||||
if (objectsSupportingRename.length > 0) {
|
||||
test.each(objectsSupportingRename)(
|
||||
'Rename object - %s - %s',
|
||||
testWrapper(async (conn, driver, type, object, engine) => {
|
||||
for (const sql of initSql) await runCommandOnDriver(conn, driver, sql);
|
||||
test.each(flatSource(x => x.supportRenameSqlObject))(
|
||||
'Rename object - %s - %s',
|
||||
testWrapper(async (conn, driver, type, object, engine) => {
|
||||
for (const sql of initSql) await runCommandOnDriver(conn, driver, sql);
|
||||
|
||||
await runCommandOnDriver(conn, driver, object.create1);
|
||||
await runCommandOnDriver(conn, driver, object.create1);
|
||||
|
||||
const structure = extendDatabaseInfo(await driver.analyseFull(conn));
|
||||
const structure = extendDatabaseInfo(await driver.analyseFull(conn));
|
||||
|
||||
const dmp = driver.createDumper();
|
||||
dmp.renameSqlObject(structure[type][0], 'renamed1');
|
||||
const dmp = driver.createDumper();
|
||||
dmp.renameSqlObject(structure[type][0], 'renamed1');
|
||||
|
||||
await driver.query(conn, dmp.s);
|
||||
await driver.query(conn, dmp.s);
|
||||
|
||||
const structure2 = await driver.analyseFull(conn);
|
||||
expect(structure2[type].length).toEqual(1);
|
||||
expect(structure2[type][0].pureName).toEqual('renamed1');
|
||||
})
|
||||
);
|
||||
}
|
||||
const structure2 = await driver.analyseFull(conn);
|
||||
expect(structure2[type].length).toEqual(1);
|
||||
expect(structure2[type][0].pureName).toEqual('renamed1');
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const stableStringify = require('json-stable-stringify');
|
||||
const _ = require('lodash');
|
||||
const fp = require('lodash/fp');
|
||||
const { testWrapper } = require('../tools');
|
||||
const { testWrapper, removeNotNull, transformSqlForEngine } = require('../tools');
|
||||
const engines = require('../engines');
|
||||
const crypto = require('crypto');
|
||||
const {
|
||||
@@ -19,6 +19,7 @@ function pickImportantTableInfo(engine, table) {
|
||||
pureName: table.pureName,
|
||||
columns: table.columns
|
||||
.filter(x => x.columnName != 'rowid')
|
||||
.sort((a, b) => a.columnName.localeCompare(b.columnName))
|
||||
.map(fp.pick(props))
|
||||
.map(props => _.omitBy(props, x => x == null))
|
||||
.map(props =>
|
||||
@@ -33,36 +34,38 @@ function checkTableStructure(engine, t1, t2) {
|
||||
}
|
||||
|
||||
async function testTableDiff(engine, conn, driver, mangle) {
|
||||
await driver.query(conn, formatQueryWithoutParams(driver, `create table ~t0 (~id int not null primary key)`));
|
||||
const initQuery = formatQueryWithoutParams(driver, `create table ~t0 (~id int not null primary key)`);
|
||||
await driver.query(conn, transformSqlForEngine(engine, initQuery));
|
||||
|
||||
await driver.query(
|
||||
conn,
|
||||
formatQueryWithoutParams(
|
||||
driver,
|
||||
`create table ~t1 (
|
||||
const query = formatQueryWithoutParams(
|
||||
driver,
|
||||
`create table ~t1 (
|
||||
~col_pk int not null primary key,
|
||||
~col_std int,
|
||||
~col_def int default 12,
|
||||
~col_def int ${engine.skipDefaultValue ? '' : 'default 12'},
|
||||
${engine.skipReferences ? '' : '~col_fk int references ~t0(~id),'}
|
||||
~col_idx int,
|
||||
~col_uq int ${engine.skipUnique ? '' : 'unique'} ,
|
||||
~col_ref int ${engine.skipUnique ? '' : 'unique'}
|
||||
)`
|
||||
)
|
||||
);
|
||||
|
||||
await driver.query(conn, transformSqlForEngine(engine, query));
|
||||
|
||||
if (!engine.skipIndexes) {
|
||||
await driver.query(conn, formatQueryWithoutParams(driver, `create index ~idx1 on ~t1(~col_idx)`));
|
||||
const query = formatQueryWithoutParams(driver, `create index ~idx1 on ~t1(~col_idx)`);
|
||||
await driver.query(conn, transformSqlForEngine(engine, query));
|
||||
}
|
||||
|
||||
if (!engine.skipReferences) {
|
||||
await driver.query(
|
||||
conn,
|
||||
formatQueryWithoutParams(
|
||||
driver,
|
||||
`create table ~t2 (~id int not null primary key, ~fkval int null references ~t1(~col_ref))`
|
||||
)
|
||||
const query = formatQueryWithoutParams(
|
||||
driver,
|
||||
`create table ~t2 (~id int not null primary key, ~fkval int ${
|
||||
driver.dialect.implicitNullDeclaration ? '' : 'null'
|
||||
} references ~t1(~col_ref))`
|
||||
);
|
||||
|
||||
await driver.query(conn, transformSqlForEngine(engine, query));
|
||||
}
|
||||
|
||||
const tget = x => x.tables.find(y => y.pureName == 't1');
|
||||
@@ -89,14 +92,12 @@ const TESTED_COLUMNS = ['col_pk', 'col_std', 'col_def', 'col_fk', 'col_ref', 'co
|
||||
// const TESTED_COLUMNS = ['col_std'];
|
||||
// const TESTED_COLUMNS = ['col_ref'];
|
||||
|
||||
function engines_columns_source() {
|
||||
function createEnginesColumnsSource(engines) {
|
||||
return _.flatten(
|
||||
engines.map(engine =>
|
||||
TESTED_COLUMNS.filter(col => !col.endsWith('_pk') || !engine.skipPkColumnTesting).map(column => [
|
||||
engine.label,
|
||||
column,
|
||||
engine,
|
||||
])
|
||||
TESTED_COLUMNS.filter(col => col.endsWith('_pk') || !engine.skipNonPkRename)
|
||||
.filter(col => !col.endsWith('_pk') || !engine.skipPkColumnTesting)
|
||||
.map(column => [engine.label, column, engine])
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -117,14 +118,43 @@ describe('Alter table', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines_columns_source())(
|
||||
test.each(engines.filter(i => i.supportTableComments).map(engine => [engine.label, engine]))(
|
||||
'Add comment to table - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testTableDiff(engine, conn, driver, tbl => {
|
||||
tbl.objectComment = 'Added table comment';
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(i => i.supportColumnComments).map(engine => [engine.label, engine]))(
|
||||
'Add comment to column - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testTableDiff(engine, conn, driver, tbl => {
|
||||
tbl.columns.push({
|
||||
columnName: 'added',
|
||||
columnComment: 'Added column comment',
|
||||
dataType: 'int',
|
||||
pairingId: crypto.randomUUID(),
|
||||
notNull: false,
|
||||
autoIncrement: false,
|
||||
});
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
test.each(
|
||||
createEnginesColumnsSource(engines.filter(x => !x.skipDropColumn)).filter(
|
||||
([_label, col, engine]) => !engine.skipPkDrop || !col.endsWith('_pk')
|
||||
)
|
||||
)(
|
||||
'Drop column - %s - %s',
|
||||
testWrapper(async (conn, driver, column, engine) => {
|
||||
await testTableDiff(engine, conn, driver, tbl => (tbl.columns = tbl.columns.filter(x => x.columnName != column)));
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines_columns_source())(
|
||||
test.each(createEnginesColumnsSource(engines.filter(x => !x.skipNullable && !x.skipChangeNullability)))(
|
||||
'Change nullability - %s - %s',
|
||||
testWrapper(async (conn, driver, column, engine) => {
|
||||
await testTableDiff(
|
||||
@@ -136,7 +166,7 @@ describe('Alter table', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines_columns_source())(
|
||||
test.each(createEnginesColumnsSource(engines.filter(x => !x.skipRenameColumn)))(
|
||||
'Rename column - %s - %s',
|
||||
testWrapper(async (conn, driver, column, engine) => {
|
||||
await testTableDiff(
|
||||
@@ -157,7 +187,7 @@ describe('Alter table', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(x => !x.skipDefaultValue).map(engine => [engine.label, engine]))(
|
||||
'Add default value - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testTableDiff(engine, conn, driver, tbl => {
|
||||
@@ -166,7 +196,7 @@ describe('Alter table', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(x => !x.skipDefaultValue).map(engine => [engine.label, engine]))(
|
||||
'Unset default value - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testTableDiff(engine, conn, driver, tbl => {
|
||||
@@ -175,7 +205,7 @@ describe('Alter table', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(x => !x.skipDefaultValue).map(engine => [engine.label, engine]))(
|
||||
'Change default value - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testTableDiff(engine, conn, driver, tbl => {
|
||||
|
||||
@@ -1,160 +0,0 @@
|
||||
const engines = require('../engines');
|
||||
const stream = require('stream');
|
||||
const { testWrapper } = require('../tools');
|
||||
const dataDuplicator = require('dbgate-api/src/shell/dataDuplicator');
|
||||
const { runCommandOnDriver, runQueryOnDriver } = require('dbgate-tools');
|
||||
|
||||
describe('Data duplicator', () => {
|
||||
test.each(engines.filter(x => !x.skipDataDuplicator).map(engine => [engine.label, engine]))(
|
||||
'Insert simple data - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
runCommandOnDriver(conn, driver, dmp =>
|
||||
dmp.createTable({
|
||||
pureName: 't1',
|
||||
columns: [
|
||||
{ columnName: 'id', dataType: 'int', autoIncrement: true, notNull: true },
|
||||
{ columnName: 'val', dataType: 'varchar(50)' },
|
||||
],
|
||||
primaryKey: {
|
||||
columns: [{ columnName: 'id' }],
|
||||
},
|
||||
})
|
||||
);
|
||||
runCommandOnDriver(conn, driver, dmp =>
|
||||
dmp.createTable({
|
||||
pureName: 't2',
|
||||
columns: [
|
||||
{ columnName: 'id', dataType: 'int', autoIncrement: true, notNull: true },
|
||||
{ columnName: 'val', dataType: 'varchar(50)' },
|
||||
{ columnName: 'valfk', dataType: 'int', notNull: true },
|
||||
],
|
||||
primaryKey: {
|
||||
columns: [{ columnName: 'id' }],
|
||||
},
|
||||
foreignKeys: [{ refTableName: 't1', columns: [{ columnName: 'valfk', refColumnName: 'id' }] }],
|
||||
})
|
||||
);
|
||||
|
||||
const gett1 = () =>
|
||||
stream.Readable.from([
|
||||
{ __isStreamHeader: true, __isDynamicStructure: true },
|
||||
{ id: 1, val: 'v1' },
|
||||
{ id: 2, val: 'v2' },
|
||||
{ id: 3, val: 'v3' },
|
||||
]);
|
||||
const gett2 = () =>
|
||||
stream.Readable.from([
|
||||
{ __isStreamHeader: true, __isDynamicStructure: true },
|
||||
{ id: 1, val: 'v1', valfk: 1 },
|
||||
{ id: 2, val: 'v2', valfk: 2 },
|
||||
{ id: 3, val: 'v3', valfk: 3 },
|
||||
]);
|
||||
|
||||
await dataDuplicator({
|
||||
systemConnection: conn,
|
||||
driver,
|
||||
items: [
|
||||
{
|
||||
name: 't1',
|
||||
operation: 'copy',
|
||||
openStream: gett1,
|
||||
},
|
||||
{
|
||||
name: 't2',
|
||||
operation: 'copy',
|
||||
openStream: gett2,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
await dataDuplicator({
|
||||
systemConnection: conn,
|
||||
driver,
|
||||
items: [
|
||||
{
|
||||
name: 't1',
|
||||
operation: 'copy',
|
||||
openStream: gett1,
|
||||
},
|
||||
{
|
||||
name: 't2',
|
||||
operation: 'copy',
|
||||
openStream: gett2,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const res1 = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select count(*) as ~cnt from ~t1`));
|
||||
expect(res1.rows[0].cnt.toString()).toEqual('6');
|
||||
|
||||
const res2 = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select count(*) as ~cnt from ~t2`));
|
||||
expect(res2.rows[0].cnt.toString()).toEqual('6');
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(x => !x.skipDataDuplicator).map(engine => [engine.label, engine]))(
|
||||
'Skip nullable weak refs - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
runCommandOnDriver(conn, driver, dmp =>
|
||||
dmp.createTable({
|
||||
pureName: 't1',
|
||||
columns: [
|
||||
{ columnName: 'id', dataType: 'int', notNull: true },
|
||||
{ columnName: 'val', dataType: 'varchar(50)' },
|
||||
],
|
||||
primaryKey: {
|
||||
columns: [{ columnName: 'id' }],
|
||||
},
|
||||
})
|
||||
);
|
||||
runCommandOnDriver(conn, driver, dmp =>
|
||||
dmp.createTable({
|
||||
pureName: 't2',
|
||||
columns: [
|
||||
{ columnName: 'id', dataType: 'int', autoIncrement: true, notNull: true },
|
||||
{ columnName: 'val', dataType: 'varchar(50)' },
|
||||
{ columnName: 'valfk', dataType: 'int', notNull: false },
|
||||
],
|
||||
primaryKey: {
|
||||
columns: [{ columnName: 'id' }],
|
||||
},
|
||||
foreignKeys: [{ refTableName: 't1', columns: [{ columnName: 'valfk', refColumnName: 'id' }] }],
|
||||
})
|
||||
);
|
||||
runCommandOnDriver(conn, driver, dmp => dmp.put("insert into ~t1 (~id, ~val) values (1, 'first')"));
|
||||
|
||||
const gett2 = () =>
|
||||
stream.Readable.from([
|
||||
{ __isStreamHeader: true, __isDynamicStructure: true },
|
||||
{ id: 1, val: 'v1', valfk: 1 },
|
||||
{ id: 2, val: 'v2', valfk: 2 },
|
||||
]);
|
||||
|
||||
await dataDuplicator({
|
||||
systemConnection: conn,
|
||||
driver,
|
||||
items: [
|
||||
{
|
||||
name: 't2',
|
||||
operation: 'copy',
|
||||
openStream: gett2,
|
||||
},
|
||||
],
|
||||
options: {
|
||||
setNullForUnresolvedNullableRefs: true,
|
||||
},
|
||||
});
|
||||
|
||||
const res1 = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select count(*) as ~cnt from ~t1`));
|
||||
expect(res1.rows[0].cnt.toString()).toEqual('1');
|
||||
|
||||
const res2 = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select count(*) as ~cnt from ~t2`));
|
||||
expect(res2.rows[0].cnt.toString()).toEqual('2');
|
||||
|
||||
const res3 = await runQueryOnDriver(conn, driver, dmp =>
|
||||
dmp.put(`select count(*) as ~cnt from ~t2 where ~valfk is not null`)
|
||||
);
|
||||
expect(res3.rows[0].cnt.toString()).toEqual('1');
|
||||
})
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,306 @@
|
||||
const engines = require('../engines');
|
||||
const stream = require('stream');
|
||||
const { testWrapper } = require('../tools');
|
||||
const dataReplicator = require('dbgate-api/src/shell/dataReplicator');
|
||||
const deployDb = require('dbgate-api/src/shell/deployDb');
|
||||
const storageModel = require('dbgate-api/src/storageModel');
|
||||
const { runCommandOnDriver, runQueryOnDriver, adaptDatabaseInfo } = require('dbgate-tools');
|
||||
|
||||
describe('Data replicator', () => {
|
||||
test.each(engines.filter(x => !x.skipDataReplicator).map(engine => [engine.label, engine]))(
|
||||
'Insert simple data - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
runCommandOnDriver(conn, driver, dmp =>
|
||||
dmp.createTable({
|
||||
pureName: 't1',
|
||||
columns: [
|
||||
{ columnName: 'id', dataType: 'int', autoIncrement: true, notNull: true },
|
||||
{ columnName: 'val', dataType: 'varchar(50)' },
|
||||
],
|
||||
primaryKey: {
|
||||
columns: [{ columnName: 'id' }],
|
||||
},
|
||||
})
|
||||
);
|
||||
runCommandOnDriver(conn, driver, dmp =>
|
||||
dmp.createTable({
|
||||
pureName: 't2',
|
||||
columns: [
|
||||
{ columnName: 'id', dataType: 'int', autoIncrement: true, notNull: true },
|
||||
{ columnName: 'val', dataType: 'varchar(50)' },
|
||||
{ columnName: 'valfk', dataType: 'int', notNull: true },
|
||||
],
|
||||
primaryKey: {
|
||||
columns: [{ columnName: 'id' }],
|
||||
},
|
||||
foreignKeys: [{ refTableName: 't1', columns: [{ columnName: 'valfk', refColumnName: 'id' }] }],
|
||||
})
|
||||
);
|
||||
|
||||
const gett1 = () =>
|
||||
stream.Readable.from([
|
||||
{ __isStreamHeader: true, __isDynamicStructure: true },
|
||||
{ id: 1, val: 'v1' },
|
||||
{ id: 2, val: 'v2' },
|
||||
{ id: 3, val: 'v3' },
|
||||
]);
|
||||
const gett2 = () =>
|
||||
stream.Readable.from([
|
||||
{ __isStreamHeader: true, __isDynamicStructure: true },
|
||||
{ id: 1, val: 'v1', valfk: 1 },
|
||||
{ id: 2, val: 'v2', valfk: 2 },
|
||||
{ id: 3, val: 'v3', valfk: 3 },
|
||||
]);
|
||||
|
||||
await dataReplicator({
|
||||
systemConnection: conn,
|
||||
driver,
|
||||
items: [
|
||||
{
|
||||
name: 't1',
|
||||
createNew: true,
|
||||
openStream: gett1,
|
||||
},
|
||||
{
|
||||
name: 't2',
|
||||
createNew: true,
|
||||
openStream: gett2,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
await dataReplicator({
|
||||
systemConnection: conn,
|
||||
driver,
|
||||
items: [
|
||||
{
|
||||
name: 't1',
|
||||
createNew: true,
|
||||
openStream: gett1,
|
||||
},
|
||||
{
|
||||
name: 't2',
|
||||
createNew: true,
|
||||
openStream: gett2,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const res1 = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select count(*) as ~cnt from ~t1`));
|
||||
expect(res1.rows[0].cnt.toString()).toEqual('6');
|
||||
|
||||
const res2 = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select count(*) as ~cnt from ~t2`));
|
||||
expect(res2.rows[0].cnt.toString()).toEqual('6');
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(x => !x.skipDataReplicator).map(engine => [engine.label, engine]))(
|
||||
'Skip nullable weak refs - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
runCommandOnDriver(conn, driver, dmp =>
|
||||
dmp.createTable({
|
||||
pureName: 't1',
|
||||
columns: [
|
||||
{ columnName: 'id', dataType: 'int', notNull: true },
|
||||
{ columnName: 'val', dataType: 'varchar(50)' },
|
||||
],
|
||||
primaryKey: {
|
||||
columns: [{ columnName: 'id' }],
|
||||
},
|
||||
})
|
||||
);
|
||||
runCommandOnDriver(conn, driver, dmp =>
|
||||
dmp.createTable({
|
||||
pureName: 't2',
|
||||
columns: [
|
||||
{ columnName: 'id', dataType: 'int', autoIncrement: true, notNull: true },
|
||||
{ columnName: 'val', dataType: 'varchar(50)' },
|
||||
{ columnName: 'valfk', dataType: 'int', notNull: false },
|
||||
],
|
||||
primaryKey: {
|
||||
columns: [{ columnName: 'id' }],
|
||||
},
|
||||
foreignKeys: [{ refTableName: 't1', columns: [{ columnName: 'valfk', refColumnName: 'id' }] }],
|
||||
})
|
||||
);
|
||||
runCommandOnDriver(conn, driver, dmp => dmp.put("insert into ~t1 (~id, ~val) values (1, 'first')"));
|
||||
|
||||
await dataReplicator({
|
||||
systemConnection: conn,
|
||||
driver,
|
||||
items: [
|
||||
{
|
||||
name: 't2',
|
||||
createNew: true,
|
||||
jsonArray: [
|
||||
{ id: 1, val: 'v1', valfk: 1 },
|
||||
{ id: 2, val: 'v2', valfk: 2 },
|
||||
],
|
||||
},
|
||||
],
|
||||
options: {
|
||||
setNullForUnresolvedNullableRefs: true,
|
||||
},
|
||||
});
|
||||
|
||||
const res1 = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select count(*) as ~cnt from ~t1`));
|
||||
expect(res1.rows[0].cnt.toString()).toEqual('1');
|
||||
|
||||
const res2 = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select count(*) as ~cnt from ~t2`));
|
||||
expect(res2.rows[0].cnt.toString()).toEqual('2');
|
||||
|
||||
const res3 = await runQueryOnDriver(conn, driver, dmp =>
|
||||
dmp.put(`select count(*) as ~cnt from ~t2 where ~valfk is not null`)
|
||||
);
|
||||
expect(res3.rows[0].cnt.toString()).toEqual('1');
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(x => !x.skipDataReplicator).map(engine => [engine.label, engine]))(
|
||||
'Import storage DB - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await deployDb({
|
||||
systemConnection: conn,
|
||||
driver,
|
||||
loadedDbModel: adaptDatabaseInfo(storageModel, driver),
|
||||
targetSchema: engine.defaultSchemaName,
|
||||
});
|
||||
|
||||
async function queryValue(sql) {
|
||||
const res1 = await runQueryOnDriver(conn, driver, dmp => dmp.put(sql));
|
||||
return res1.rows[0].val?.toString();
|
||||
}
|
||||
|
||||
expect(await queryValue(`select count(*) as ~val from ~auth_methods`)).toEqual('2');
|
||||
expect(
|
||||
await queryValue(
|
||||
`select ~is_disabled as ~val from ~auth_methods where ~amoid='790ca4d2-7f01-4800-955b-d691b890cc50'`
|
||||
)
|
||||
).toBeTruthy();
|
||||
|
||||
const DB1 = {
|
||||
auth_methods: [
|
||||
{ id: -1, name: 'Anonymous', amoid: '790ca4d2-7f01-4800-955b-d691b890cc50', is_disabled: 0 },
|
||||
{ id: 10, name: 'OAuth', amoid: '4269b660-54b6-11ef-a3aa-a9021250bf4b' },
|
||||
],
|
||||
auth_methods_config: [{ id: 20, auth_method_id: 10, key: 'oauthClient', value: 'dbgate' }],
|
||||
config: [
|
||||
{ group: 'admin', key: 'encyptKey', value: '1234' },
|
||||
{ group: 'admin', key: 'adminPasswordState', value: 'set' },
|
||||
{ group: 'license', key: 'licenseKey', value: '123467' },
|
||||
],
|
||||
roles: [
|
||||
{ id: -3, name: 'superadmin' },
|
||||
{ id: -2, name: 'logged-user' },
|
||||
{ id: -1, name: 'anonymous-user' },
|
||||
],
|
||||
role_permissions: [
|
||||
{ id: 14, role_id: -1, permission: 'perm1' },
|
||||
{ id: 29, role_id: -1, permission: 'perm2' },
|
||||
{ id: 1, role_id: -1, permission: 'perm3' },
|
||||
],
|
||||
};
|
||||
|
||||
const DB2 = {
|
||||
auth_methods: [{ id: 10, name: 'My Auth', amoid: 'myauth1' }],
|
||||
auth_methods_config: [{ id: 20, auth_method_id: 10, key: 'my authClient', value: 'mydbgate' }],
|
||||
config: [],
|
||||
roles: [{ id: 1, name: 'test' }],
|
||||
role_permissions: [{ id: 14, role_id: 1, permission: 'permxx' }],
|
||||
};
|
||||
|
||||
function createDuplConfig(db) {
|
||||
return {
|
||||
systemConnection: conn,
|
||||
driver,
|
||||
items: [
|
||||
{
|
||||
name: 'auth_methods',
|
||||
findExisting: true,
|
||||
updateExisting: true,
|
||||
createNew: true,
|
||||
matchColumns: ['amoid'],
|
||||
jsonArray: db.auth_methods,
|
||||
},
|
||||
{
|
||||
name: 'auth_methods_config',
|
||||
findExisting: true,
|
||||
updateExisting: true,
|
||||
createNew: true,
|
||||
matchColumns: ['auth_method_id', 'key'],
|
||||
jsonArray: db.auth_methods_config,
|
||||
},
|
||||
{
|
||||
name: 'config',
|
||||
findExisting: true,
|
||||
updateExisting: true,
|
||||
createNew: true,
|
||||
matchColumns: ['group', 'key'],
|
||||
jsonArray: db.config,
|
||||
},
|
||||
{
|
||||
name: 'roles',
|
||||
findExisting: true,
|
||||
updateExisting: true,
|
||||
createNew: true,
|
||||
matchColumns: ['name'],
|
||||
jsonArray: db.roles,
|
||||
},
|
||||
{
|
||||
name: 'role_permissions',
|
||||
findExisting: true,
|
||||
updateExisting: true,
|
||||
createNew: true,
|
||||
deleteMissing: true,
|
||||
matchColumns: ['role_id', 'permission'],
|
||||
deleteRestrictionColumns: ['role_id'],
|
||||
jsonArray: db.role_permissions,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
await dataReplicator(createDuplConfig(DB1));
|
||||
|
||||
expect(
|
||||
await queryValue(
|
||||
`select ~is_disabled as ~val from ~auth_methods where ~amoid='790ca4d2-7f01-4800-955b-d691b890cc50'`
|
||||
)
|
||||
).toEqual('0');
|
||||
|
||||
expect(await queryValue(`select count(*) as ~val from ~auth_methods`)).toEqual('3');
|
||||
expect(await queryValue(`select count(*) as ~val from ~auth_methods_config`)).toEqual('1');
|
||||
expect(await queryValue(`select count(*) as ~val from ~config`)).toEqual('3');
|
||||
expect(await queryValue(`select ~value as ~val from ~auth_methods_config`)).toEqual('dbgate');
|
||||
expect(
|
||||
await queryValue(`select ~value as ~val from ~config where ~group='license' and ~key='licenseKey'`)
|
||||
).toEqual('123467');
|
||||
expect(await queryValue(`select count(*) as ~val from ~role_permissions`)).toEqual('3');
|
||||
|
||||
DB1.auth_methods_config[0].value = 'dbgate2';
|
||||
DB1.config[2].value = '567';
|
||||
DB1.role_permissions.splice(2, 1);
|
||||
|
||||
await dataReplicator(createDuplConfig(DB1));
|
||||
expect(await queryValue(`select count(*) as ~val from ~auth_methods_config`)).toEqual('1');
|
||||
expect(await queryValue(`select count(*) as ~val from ~config`)).toEqual('3');
|
||||
expect(await queryValue(`select ~value as ~val from ~auth_methods_config`)).toEqual('dbgate2');
|
||||
expect(
|
||||
await queryValue(`select ~value as ~val from ~config where ~group='license' and ~key='licenseKey'`)
|
||||
).toEqual('567');
|
||||
expect(await queryValue(`select count(*) as ~val from ~role_permissions`)).toEqual('2');
|
||||
|
||||
// now add DB2
|
||||
await dataReplicator(createDuplConfig(DB2));
|
||||
|
||||
expect(await queryValue(`select count(*) as ~val from ~auth_methods`)).toEqual('4');
|
||||
expect(await queryValue(`select count(*) as ~val from ~auth_methods_config`)).toEqual('2');
|
||||
expect(await queryValue(`select count(*) as ~val from ~role_permissions`)).toEqual('3');
|
||||
|
||||
DB1.role_permissions.splice(1, 1);
|
||||
await dataReplicator(createDuplConfig(DB1));
|
||||
expect(await queryValue(`select count(*) as ~val from ~role_permissions`)).toEqual('2');
|
||||
}),
|
||||
15 * 1000
|
||||
);
|
||||
});
|
||||
@@ -1,11 +1,12 @@
|
||||
const engines = require('../engines');
|
||||
const stream = require('stream');
|
||||
const path = require('path');
|
||||
const { testWrapper } = require('../tools');
|
||||
const tableWriter = require('dbgate-api/src/shell/tableWriter');
|
||||
const tableReader = require('dbgate-api/src/shell/tableReader');
|
||||
const copyStream = require('dbgate-api/src/shell/copyStream');
|
||||
const importDatabase = require('dbgate-api/src/shell/importDatabase');
|
||||
const fakeObjectReader = require('dbgate-api/src/shell/fakeObjectReader');
|
||||
const importDbFromFolder = require('dbgate-api/src/shell/importDbFromFolder');
|
||||
const { runQueryOnDriver, runCommandOnDriver } = require('dbgate-tools');
|
||||
|
||||
function createImportStream() {
|
||||
@@ -50,7 +51,33 @@ describe('DB Import/export', () => {
|
||||
await copyStream(reader, writer);
|
||||
|
||||
const res = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select count(*) as ~cnt from ~t1`));
|
||||
expect(res.rows[0].cnt.toString()).toEqual('6');
|
||||
const cnt = parseInt(res.rows[0].cnt.toString());
|
||||
expect(cnt).toEqual(6);
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
`Import to existing table - %s`,
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await runQueryOnDriver(conn, driver, dmp =>
|
||||
dmp.put(
|
||||
`create table ~t1 (~id int primary key, ~country %s)`,
|
||||
engine.useTextTypeForStrings ? 'text' : 'varchar(50)'
|
||||
)
|
||||
);
|
||||
|
||||
const reader = createImportStream();
|
||||
const writer = await tableWriter({
|
||||
systemConnection: conn,
|
||||
driver,
|
||||
pureName: 't1',
|
||||
createIfNotExists: true,
|
||||
});
|
||||
await copyStream(reader, writer);
|
||||
|
||||
const res = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select count(*) as ~cnt from ~t1`));
|
||||
const cnt = parseInt(res.rows[0].cnt.toString());
|
||||
expect(cnt).toEqual(6);
|
||||
})
|
||||
);
|
||||
|
||||
@@ -78,45 +105,56 @@ describe('DB Import/export', () => {
|
||||
await copyStream(reader2, writer2);
|
||||
|
||||
const res1 = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select count(*) as ~cnt from ~t1`));
|
||||
expect(res1.rows[0].cnt.toString()).toEqual('6');
|
||||
const cnt = parseInt(res1.rows[0].cnt.toString());
|
||||
expect(cnt).toEqual(6);
|
||||
|
||||
const res2 = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select count(*) as ~cnt from ~t2`));
|
||||
expect(res2.rows[0].cnt.toString()).toEqual('6');
|
||||
const cnt2 = parseInt(res2.rows[0].cnt.toString());
|
||||
expect(cnt2).toEqual(6);
|
||||
})
|
||||
);
|
||||
const enginesWithDumpFile = engines.filter(x => x.dumpFile);
|
||||
const hasEnginesWithDumpFile = enginesWithDumpFile.length > 0;
|
||||
|
||||
test.each(engines.filter(x => x.dumpFile).map(engine => [engine.label, engine]))(
|
||||
'Import SQL dump - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
// const reader = await fakeObjectReader({ delay: 10 });
|
||||
// const reader = await fakeObjectReader();
|
||||
await importDatabase({
|
||||
systemConnection: conn,
|
||||
driver,
|
||||
inputFile: engine.dumpFile,
|
||||
});
|
||||
if (hasEnginesWithDumpFile) {
|
||||
test.each(enginesWithDumpFile.filter(x => x.dumpFile).map(engine => [engine.label, engine]))(
|
||||
'Import SQL dump - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
// const reader = await fakeObjectReader({ delay: 10 });
|
||||
// const reader = await fakeObjectReader();
|
||||
await importDatabase({
|
||||
systemConnection: conn,
|
||||
driver,
|
||||
inputFile: engine.dumpFile,
|
||||
});
|
||||
|
||||
const structure = await driver.analyseFull(conn);
|
||||
const structure = await driver.analyseFull(conn);
|
||||
|
||||
for (const check of engine.dumpChecks || []) {
|
||||
const res = await driver.query(conn, check.sql);
|
||||
expect(res.rows[0].res.toString()).toEqual(check.res);
|
||||
}
|
||||
for (const check of engine.dumpChecks || []) {
|
||||
const res = await driver.query(conn, check.sql);
|
||||
expect(res.rows[0].res.toString()).toEqual(check.res);
|
||||
}
|
||||
|
||||
// const res1 = await driver.query(conn, `select count(*) as cnt from t1`);
|
||||
// expect(res1.rows[0].cnt.toString()).toEqual('6');
|
||||
// const res1 = await driver.query(conn, `select count(*) as cnt from t1`);
|
||||
// expect(res1.rows[0].cnt.toString()).toEqual('6');
|
||||
|
||||
// const res2 = await driver.query(conn, `select count(*) as cnt from t2`);
|
||||
// expect(res2.rows[0].cnt.toString()).toEqual('6');
|
||||
})
|
||||
);
|
||||
// const res2 = await driver.query(conn, `select count(*) as cnt from t2`);
|
||||
// expect(res2.rows[0].cnt.toString()).toEqual('6');
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
'Export one table - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
// const reader = await fakeObjectReader({ delay: 10 });
|
||||
// const reader = await fakeObjectReader();
|
||||
await runCommandOnDriver(conn, driver, 'create table ~t1 (~id int primary key, ~country varchar(100))');
|
||||
await runCommandOnDriver(
|
||||
conn,
|
||||
driver,
|
||||
`create table ~t1 (~id int primary key, ~country ${engine.useTextTypeForStrings ? 'text' : 'varchar(100)'})`
|
||||
);
|
||||
|
||||
const data = [
|
||||
[1, 'Czechia'],
|
||||
[2, 'Austria'],
|
||||
@@ -138,7 +176,28 @@ describe('DB Import/export', () => {
|
||||
const writer = createExportStream();
|
||||
await copyStream(reader, writer);
|
||||
|
||||
expect(writer.resultArray.filter(x => !x.__isStreamHeader).map(row => [row.id, row.country])).toEqual(data);
|
||||
const result = writer.resultArray.filter(x => !x.__isStreamHeader).map(row => [row.id, row.country]);
|
||||
|
||||
if (engine.forceSortResults) {
|
||||
result.sort((a, b) => a[0] - b[0]);
|
||||
}
|
||||
|
||||
expect(result).toEqual(data);
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(engine => !engine.skipImportModel).map(engine => [engine.label, engine]))(
|
||||
'Import guitar shop - schema + data - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await importDbFromFolder({
|
||||
systemConnection: conn,
|
||||
driver,
|
||||
folder: path.join(__dirname, '../../e2e-tests/data/my-guitar-shop'),
|
||||
});
|
||||
|
||||
const res1 = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select count(*) as ~cnt from ~categories`));
|
||||
const cnt1 = parseInt(res1.rows[0].cnt.toString());
|
||||
expect(cnt1).toEqual(4);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
@@ -106,7 +106,9 @@ async function testDatabaseDeploy(engine, conn, driver, dbModelsYaml, options) {
|
||||
|
||||
for (const loadedDbModel of dbModelsYaml) {
|
||||
if (_.isString(loadedDbModel)) {
|
||||
await driver.script(conn, formatQueryWithoutParams(driver, loadedDbModel));
|
||||
await driver.script(conn, formatQueryWithoutParams(driver, loadedDbModel), {
|
||||
useTransaction: engine.runDeployInTransaction,
|
||||
});
|
||||
} else {
|
||||
const { sql, isEmpty } = await generateDeploySql({
|
||||
systemConnection: conn.isPreparedOnly ? undefined : conn,
|
||||
@@ -131,6 +133,7 @@ async function testDatabaseDeploy(engine, conn, driver, dbModelsYaml, options) {
|
||||
driver,
|
||||
loadedDbModel: convertModelToEngine(loadedDbModel, driver),
|
||||
dbdiffOptionsExtra,
|
||||
useTransaction: engine.runDeployInTransaction,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -149,7 +152,7 @@ async function testDatabaseDeploy(engine, conn, driver, dbModelsYaml, options) {
|
||||
}
|
||||
|
||||
describe('Deploy database', () => {
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(i => !i.skipDeploy).map(engine => [engine.label, engine]))(
|
||||
'Deploy database simple - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testDatabaseDeploy(engine, conn, driver, [
|
||||
@@ -167,7 +170,7 @@ describe('Deploy database', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(i => !i.skipDeploy).map(engine => [engine.label, engine]))(
|
||||
'Deploy database simple - %s - not connected',
|
||||
testWrapperPrepareOnly(async (conn, driver, engine) => {
|
||||
await testDatabaseDeploy(engine, conn, driver, [
|
||||
@@ -185,7 +188,7 @@ describe('Deploy database', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(i => !i.skipDeploy).map(engine => [engine.label, engine]))(
|
||||
'Deploy database simple twice - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testDatabaseDeploy(
|
||||
@@ -219,7 +222,7 @@ describe('Deploy database', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(i => !i.skipDeploy).map(engine => [engine.label, engine]))(
|
||||
'Add column - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testDatabaseDeploy(engine, conn, driver, [
|
||||
@@ -250,7 +253,7 @@ describe('Deploy database', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(i => !i.skipDeploy).map(engine => [engine.label, engine]))(
|
||||
'Dont drop column - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testDatabaseDeploy(
|
||||
@@ -287,7 +290,12 @@ describe('Deploy database', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(x => !x.skipReferences).map(engine => [engine.label, engine]))(
|
||||
test.each(
|
||||
engines
|
||||
.filter(i => !i.skipDeploy)
|
||||
.filter(x => !x.skipReferences)
|
||||
.map(engine => [engine.label, engine])
|
||||
)(
|
||||
'Foreign keys - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testDatabaseDeploy(
|
||||
@@ -343,7 +351,12 @@ describe('Deploy database', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(x => !x.skipDataModifications).map(engine => [engine.label, engine]))(
|
||||
test.each(
|
||||
engines
|
||||
.filter(i => !i.skipDeploy)
|
||||
.filter(x => !x.skipDataModifications)
|
||||
.map(engine => [engine.label, engine])
|
||||
)(
|
||||
'Deploy preloaded data - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testDatabaseDeploy(engine, conn, driver, [
|
||||
@@ -372,7 +385,12 @@ describe('Deploy database', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(x => !x.skipDataModifications).map(engine => [engine.label, engine]))(
|
||||
test.each(
|
||||
engines
|
||||
.filter(i => !i.skipDeploy)
|
||||
.filter(x => !x.skipDataModifications)
|
||||
.map(engine => [engine.label, engine])
|
||||
)(
|
||||
'Deploy preloaded data - update - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testDatabaseDeploy(engine, conn, driver, [
|
||||
@@ -448,7 +466,12 @@ describe('Deploy database', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(x => !x.skipChangeColumn).map(engine => [engine.label, engine]))(
|
||||
test.each(
|
||||
engines
|
||||
.filter(i => !i.skipDeploy)
|
||||
.filter(x => !x.skipChangeColumn && !x.skipNullability)
|
||||
.map(engine => [engine.label, engine])
|
||||
)(
|
||||
'Change column to NOT NULL column with default - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testDatabaseDeploy(engine, conn, driver, [
|
||||
@@ -566,7 +589,7 @@ describe('Deploy database', () => {
|
||||
text: 'create view ~_deleted_v1 as select * from ~t1',
|
||||
};
|
||||
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(i => !i.skipDeploy).map(engine => [engine.label, engine]))(
|
||||
'Dont remove column - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testDatabaseDeploy(engine, conn, driver, [[T1], [T1_NO_VAL]], {
|
||||
@@ -576,7 +599,7 @@ describe('Deploy database', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(i => !i.skipDeploy).map(engine => [engine.label, engine]))(
|
||||
'Dont remove table - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testDatabaseDeploy(engine, conn, driver, [[T1], []], {
|
||||
@@ -586,7 +609,7 @@ describe('Deploy database', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(i => !i.skipDeploy && !i.skipRenameTable).map(engine => [engine.label, engine]))(
|
||||
'Mark table removed - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testDatabaseDeploy(engine, conn, driver, [[T1], [], []], {
|
||||
@@ -597,7 +620,12 @@ describe('Deploy database', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(engine => engine.supportRenameSqlObject).map(engine => [engine.label, engine]))(
|
||||
test.each(
|
||||
engines
|
||||
.filter(i => !i.skipDeploy)
|
||||
.filter(engine => engine.supportRenameSqlObject)
|
||||
.map(engine => [engine.label, engine])
|
||||
)(
|
||||
'Mark view removed - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testDatabaseDeploy(engine, conn, driver, [[T1, V1], [T1], [T1]], {
|
||||
@@ -608,7 +636,7 @@ describe('Deploy database', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(i => !i.skipDeploy).map(engine => [engine.label, engine]))(
|
||||
'Mark column removed - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testDatabaseDeploy(engine, conn, driver, [[T1], [T1_NO_VAL]], {
|
||||
@@ -619,7 +647,7 @@ describe('Deploy database', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(i => !i.skipDeploy).map(engine => [engine.label, engine]))(
|
||||
'Undelete table - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testDatabaseDeploy(
|
||||
@@ -641,7 +669,12 @@ describe('Deploy database', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(engine => engine.supportRenameSqlObject).map(engine => [engine.label, engine]))(
|
||||
test.each(
|
||||
engines
|
||||
.filter(i => !i.skipDeploy)
|
||||
.filter(engine => engine.supportRenameSqlObject)
|
||||
.map(engine => [engine.label, engine])
|
||||
)(
|
||||
'Undelete view - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testDatabaseDeploy(engine, conn, driver, [[T1, V1], [T1], [T1, V1]], {
|
||||
@@ -652,7 +685,7 @@ describe('Deploy database', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(i => !i.skipDeploy).map(engine => [engine.label, engine]))(
|
||||
'Undelete column - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testDatabaseDeploy(engine, conn, driver, [[T1], [T1_NO_VAL], [T1]], {
|
||||
@@ -662,7 +695,7 @@ describe('Deploy database', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(i => !i.skipDeploy).map(engine => [engine.label, engine]))(
|
||||
'View redeploy - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testDatabaseDeploy(
|
||||
@@ -683,7 +716,7 @@ describe('Deploy database', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(i => !i.skipDeploy).map(engine => [engine.label, engine]))(
|
||||
'Change view - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testDatabaseDeploy(
|
||||
@@ -703,7 +736,12 @@ describe('Deploy database', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(x => !x.skipDataModifications).map(engine => [engine.label, engine]))(
|
||||
test.each(
|
||||
engines
|
||||
.filter(i => !i.skipDeploy)
|
||||
.filter(x => !x.skipDataModifications)
|
||||
.map(engine => [engine.label, engine])
|
||||
)(
|
||||
'Script drived deploy - basic predeploy - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testDatabaseDeploy(engine, conn, driver, [
|
||||
@@ -723,7 +761,12 @@ describe('Deploy database', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(x => !x.skipDataModifications).map(engine => [engine.label, engine]))(
|
||||
test.each(
|
||||
engines
|
||||
.filter(i => !i.skipDeploy)
|
||||
.filter(x => !x.skipDataModifications)
|
||||
.map(engine => [engine.label, engine])
|
||||
)(
|
||||
'Script drived deploy - install+uninstall - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testDatabaseDeploy(engine, conn, driver, [
|
||||
@@ -782,7 +825,7 @@ describe('Deploy database', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(i => !i.skipDeploy && !i.skipRenameTable).map(engine => [engine.label, engine]))(
|
||||
'Mark table removed, one remains - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testDatabaseDeploy(engine, conn, driver, [[T1, T2], [T2], [T2]], {
|
||||
|
||||
@@ -20,7 +20,11 @@ function flatSourceParameters() {
|
||||
}
|
||||
|
||||
function flatSourceTriggers() {
|
||||
return _.flatten(engines.map(engine => (engine.triggers || []).map(trigger => [engine.label, trigger, engine])));
|
||||
return _.flatten(
|
||||
engines
|
||||
.filter(engine => !engine.skipTriggers)
|
||||
.map(engine => (engine.triggers || []).map(trigger => [engine.label, trigger, engine]))
|
||||
);
|
||||
}
|
||||
|
||||
function flatSourceSchedulerEvents() {
|
||||
|
||||
@@ -49,6 +49,32 @@ class StreamHandler {
|
||||
}
|
||||
}
|
||||
|
||||
class BinaryTestStreamHandler {
|
||||
constructor(resolve, reject, expectedValue) {
|
||||
this.resolve = resolve;
|
||||
this.reject = reject;
|
||||
this.expectedValue = expectedValue;
|
||||
this.rowsReceived = [];
|
||||
}
|
||||
row(row) {
|
||||
try {
|
||||
this.rowsReceived.push(row);
|
||||
if (this.expectedValue) {
|
||||
expect(row).toEqual(this.expectedValue);
|
||||
}
|
||||
} catch (error) {
|
||||
this.reject(error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
recordset(columns) {}
|
||||
done(result) {
|
||||
this.resolve(this.rowsReceived);
|
||||
}
|
||||
info(msg) {}
|
||||
}
|
||||
|
||||
|
||||
function executeStreamItem(driver, conn, sql) {
|
||||
return new Promise(resolve => {
|
||||
const handler = new StreamHandler(resolve);
|
||||
@@ -73,7 +99,9 @@ describe('Query', () => {
|
||||
await runCommandOnDriver(conn, driver, dmp => dmp.put(sql));
|
||||
}
|
||||
|
||||
const res = await runQueryOnDriver(conn, driver, dmp => dmp.put('SELECT ~id FROM ~t1 ORDER BY ~id'));
|
||||
const res = await runQueryOnDriver(conn, driver, dmp =>
|
||||
dmp.put(`SELECT ~id FROM ~t1 ${engine.skipOrderBy ? '' : 'ORDER BY ~id'}`)
|
||||
);
|
||||
expect(res.columns).toEqual([
|
||||
expect.objectContaining({
|
||||
columnName: 'id',
|
||||
@@ -98,7 +126,11 @@ describe('Query', () => {
|
||||
await runCommandOnDriver(conn, driver, dmp => dmp.put(sql));
|
||||
}
|
||||
|
||||
const results = await executeStream(driver, conn, 'SELECT ~id FROM ~t1 ORDER BY ~id');
|
||||
const results = await executeStream(
|
||||
driver,
|
||||
conn,
|
||||
`SELECT ~id FROM ~t1 ${engine.skipOrderBy ? '' : 'ORDER BY ~id'}`
|
||||
);
|
||||
expect(results.length).toEqual(1);
|
||||
const res = results[0];
|
||||
|
||||
@@ -107,7 +139,7 @@ describe('Query', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(i => !i.skipOrderBy).map(engine => [engine.label, engine]))(
|
||||
'More queries - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
for (const sql of initSql) {
|
||||
@@ -137,7 +169,9 @@ describe('Query', () => {
|
||||
const results = await executeStream(
|
||||
driver,
|
||||
conn,
|
||||
'CREATE TABLE ~t1 (~id int primary key); INSERT INTO ~t1 (~id) VALUES (1); INSERT INTO ~t1 (~id) VALUES (2); SELECT ~id FROM ~t1 ORDER BY ~id; '
|
||||
`CREATE TABLE ~t1 (~id int primary key); INSERT INTO ~t1 (~id) VALUES (1); INSERT INTO ~t1 (~id) VALUES (2); SELECT ~id FROM ~t1 ${
|
||||
engine.skipOrderBy ? '' : 'ORDER BY ~id'
|
||||
}; `
|
||||
);
|
||||
expect(results.length).toEqual(1);
|
||||
|
||||
@@ -175,12 +209,12 @@ describe('Query', () => {
|
||||
{ discardResult: true }
|
||||
);
|
||||
const res = await runQueryOnDriver(conn, driver, dmp => dmp.put('SELECT COUNT(*) AS ~cnt FROM ~t1'));
|
||||
// console.log(res);
|
||||
expect(res.rows[0].cnt == 3).toBeTruthy();
|
||||
const cnt = parseInt(res.rows[0].cnt);
|
||||
expect(cnt).toEqual(3);
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(x => !x.skipDataDuplicator).map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(x => !x.skipDataReplicator).map(engine => [engine.label, engine]))(
|
||||
'Select scope identity - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await runCommandOnDriver(conn, driver, dmp =>
|
||||
@@ -188,7 +222,7 @@ describe('Query', () => {
|
||||
pureName: 't1',
|
||||
columns: [
|
||||
{ columnName: 'id', dataType: 'int', notNull: true, autoIncrement: true },
|
||||
{ columnName: 'val', dataType: 'varchar(50)' },
|
||||
{ columnName: 'val', dataType: engine.useTextTypeForStrings ? 'text' : 'varchar(50)' },
|
||||
],
|
||||
primaryKey: {
|
||||
columns: [{ columnName: 'id' }],
|
||||
@@ -215,4 +249,51 @@ describe('Query', () => {
|
||||
expect(row[keys[0]] == 1).toBeTruthy();
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(x => x.binaryDataType).map(engine => [engine.label, engine]))(
|
||||
'Binary - %s',
|
||||
testWrapper(async (dbhan, driver, engine) => {
|
||||
await runCommandOnDriver(dbhan, driver, dmp =>
|
||||
dmp.createTable({
|
||||
pureName: 't1',
|
||||
columns: [
|
||||
{ columnName: 'id', dataType: 'int', notNull: true, autoIncrement: true },
|
||||
{ columnName: 'val', dataType: engine.binaryDataType },
|
||||
],
|
||||
primaryKey: {
|
||||
columns: [{ columnName: 'id' }],
|
||||
},
|
||||
})
|
||||
);
|
||||
const structure = await driver.analyseFull(dbhan);
|
||||
const table = structure.tables.find(x => x.pureName == 't1');
|
||||
|
||||
const dmp = driver.createDumper();
|
||||
dmp.putCmd("INSERT INTO ~t1 (~val) VALUES (%v)", {
|
||||
$binary: { base64: 'iVBORw0KWgo=' },
|
||||
});
|
||||
await driver.query(dbhan, dmp.s, {discardResult: true});
|
||||
|
||||
const dmp2 = driver.createDumper();
|
||||
dmp2.put('SELECT ~val FROM ~t1');
|
||||
const res = await driver.query(dbhan, dmp2.s);
|
||||
|
||||
const row = res.rows[0];
|
||||
const keys = Object.keys(row);
|
||||
expect(keys.length).toEqual(1);
|
||||
expect(row[keys[0]]).toEqual({$binary: {base64: 'iVBORw0KWgo='}});
|
||||
|
||||
const res2 = await driver.readQuery(dbhan, dmp2.s);
|
||||
const rows = await Array.fromAsync(res2);
|
||||
const rowsVal = rows.filter(r => r.val != null);
|
||||
|
||||
expect(rowsVal.length).toEqual(1);
|
||||
expect(rowsVal[0].val).toEqual({$binary: {base64: 'iVBORw0KWgo='}});
|
||||
|
||||
const res3 = await new Promise((resolve, reject) => {
|
||||
const handler = new BinaryTestStreamHandler(resolve, reject, {val: {$binary: {base64: 'iVBORw0KWgo='}}});
|
||||
driver.stream(dbhan, dmp2.s, handler);
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
@@ -2,12 +2,37 @@ const { runCommandOnDriver } = require('dbgate-tools');
|
||||
const engines = require('../engines');
|
||||
const { testWrapper } = require('../tools');
|
||||
|
||||
const t1Sql = 'CREATE TABLE ~t1 (~id int not null primary key, ~val1 varchar(50))';
|
||||
/**
|
||||
* @param {import('dbgate-types').TestEngineInfo} engine
|
||||
*/
|
||||
const t1Sql = engine =>
|
||||
`CREATE TABLE ~t1 (~id int ${engine.skipNullability ? '' : 'not null'} primary key, ~val1 ${
|
||||
engine.useTextTypeForStrings ? 'text' : 'varchar(50)'
|
||||
})`;
|
||||
|
||||
const ix1Sql = 'CREATE index ~ix1 ON ~t1(~val1, ~id)';
|
||||
|
||||
/**
|
||||
* @param {import('dbgate-types').TestEngineInfo} engine
|
||||
*/
|
||||
const t2Sql = engine =>
|
||||
`CREATE TABLE ~t2 (~id int not null primary key, ~val2 varchar(50) ${engine.skipUnique ? '' : 'unique'})`;
|
||||
const t3Sql = 'CREATE TABLE ~t3 (~id int not null primary key, ~valfk int, foreign key (~valfk) references ~t2(~id))';
|
||||
const t4Sql = 'CREATE TABLE ~t4 (~id int not null primary key, ~valdef int default 12 not null)';
|
||||
`CREATE TABLE ~t2 (~id int ${engine.skipNullability ? '' : 'not null'} primary key, ~val2 ${
|
||||
engine.useTextTypeForStrings ? 'text' : 'varchar(50)'
|
||||
} ${engine.skipUnique ? '' : 'unique'})`;
|
||||
/**
|
||||
* @param {import('dbgate-types').TestEngineInfo} engine
|
||||
*/
|
||||
const t3Sql = engine =>
|
||||
`CREATE TABLE ~t3 (~id int ${
|
||||
engine.skipNullability ? '' : 'not null'
|
||||
} primary key, ~valfk int, foreign key (~valfk) references ~t2(~id))`;
|
||||
/**
|
||||
* @param {import('dbgate-types').TestEngineInfo} engine
|
||||
*/
|
||||
const t4Sql = engine =>
|
||||
`CREATE TABLE ~t4 (~id int ${engine.skipNullability ? '' : 'not null'} primary key, ~valdef int default 12 ${
|
||||
engine.skipNullability ? '' : 'not null'
|
||||
})`;
|
||||
// const fkSql = 'ALTER TABLE t3 ADD FOREIGN KEY (valfk) REFERENCES t2(id)'
|
||||
|
||||
const txMatch = (engine, tname, vcolname, nextcol, defaultValue) =>
|
||||
@@ -22,12 +47,12 @@ const txMatch = (engine, tname, vcolname, nextcol, defaultValue) =>
|
||||
expect.objectContaining({
|
||||
columnName: vcolname,
|
||||
...(engine.skipNullability ? {} : { notNull: !!defaultValue }),
|
||||
...(defaultValue
|
||||
...(defaultValue && !engine.skipDefaultValue
|
||||
? { defaultValue }
|
||||
: {
|
||||
dataType: engine.skipStringLength
|
||||
? expect.stringMatching(/.*string|char.*/i)
|
||||
: expect.stringMatching(/.*char.*\(50\)/i),
|
||||
? expect.stringMatching(/.*string|char.*|text/i)
|
||||
: expect.stringMatching(/.*char.*\(50\)|text/i),
|
||||
}),
|
||||
}),
|
||||
...(nextcol
|
||||
@@ -36,8 +61,8 @@ const txMatch = (engine, tname, vcolname, nextcol, defaultValue) =>
|
||||
columnName: 'nextcol',
|
||||
...(engine.skipNullability ? {} : { notNull: false }),
|
||||
dataType: engine.skipStringLength
|
||||
? expect.stringMatching(/.*string.*|char.*/i)
|
||||
: expect.stringMatching(/.*char.*\(50\).*/i),
|
||||
? expect.stringMatching(/.*string.*|char.*|text/i)
|
||||
: expect.stringMatching(/.*char.*\(50\).*|text/i),
|
||||
}),
|
||||
]
|
||||
: []),
|
||||
@@ -60,17 +85,16 @@ describe('Table analyse', () => {
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
'Table structure - full analysis - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await runCommandOnDriver(conn, driver, dmp => dmp.put(t1Sql));
|
||||
await runCommandOnDriver(conn, driver, dmp => dmp.put(t1Sql(engine)));
|
||||
|
||||
const structure = await driver.analyseFull(conn);
|
||||
console.log(JSON.stringify(structure, null, 2));
|
||||
|
||||
expect(structure.tables.length).toEqual(1);
|
||||
expect(structure.tables[0]).toEqual(t1Match(engine));
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(x => !x.skipIncrementalAnalysis).map(engine => [engine.label, engine]))(
|
||||
'Table add - incremental analysis - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await runCommandOnDriver(conn, driver, dmp => dmp.put(t2Sql(engine)));
|
||||
@@ -79,7 +103,7 @@ describe('Table analyse', () => {
|
||||
expect(structure1.tables.length).toEqual(1);
|
||||
expect(structure1.tables[0]).toEqual(t2Match(engine));
|
||||
|
||||
await runCommandOnDriver(conn, driver, dmp => dmp.put(t1Sql));
|
||||
await runCommandOnDriver(conn, driver, dmp => dmp.put(t1Sql(engine)));
|
||||
const structure2 = await driver.analyseIncremental(conn, structure1);
|
||||
|
||||
expect(structure2.tables.length).toEqual(2);
|
||||
@@ -88,10 +112,10 @@ describe('Table analyse', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(x => !x.skipIncrementalAnalysis).map(engine => [engine.label, engine]))(
|
||||
'Table remove - incremental analysis - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await runCommandOnDriver(conn, driver, dmp => dmp.put(t1Sql));
|
||||
await runCommandOnDriver(conn, driver, dmp => dmp.put(t1Sql(engine)));
|
||||
await runCommandOnDriver(conn, driver, dmp => dmp.put(t2Sql(engine)));
|
||||
const structure1 = await driver.analyseFull(conn);
|
||||
expect(structure1.tables.length).toEqual(2);
|
||||
@@ -106,17 +130,21 @@ describe('Table analyse', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(x => !x.skipIncrementalAnalysis).map(engine => [engine.label, engine]))(
|
||||
'Table change - incremental analysis - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await runCommandOnDriver(conn, driver, dmp => dmp.put(t1Sql));
|
||||
await runCommandOnDriver(conn, driver, dmp => dmp.put(t1Sql(engine)));
|
||||
await runCommandOnDriver(conn, driver, dmp => dmp.put(t2Sql(engine)));
|
||||
const structure1 = await driver.analyseFull(conn);
|
||||
|
||||
if (engine.dbSnapshotBySeconds) await new Promise(resolve => setTimeout(resolve, 1100));
|
||||
|
||||
await runCommandOnDriver(conn, driver, dmp =>
|
||||
dmp.put(`ALTER TABLE ~t2 ADD ${engine.alterTableAddColumnSyntax ? 'COLUMN' : ''} ~nextcol varchar(50)`)
|
||||
dmp.put(
|
||||
`ALTER TABLE ~t2 ADD ${engine.alterTableAddColumnSyntax ? 'COLUMN' : ''} ~nextcol ${
|
||||
engine.useTextTypeForStrings ? 'text' : 'varchar(50)'
|
||||
}`
|
||||
)
|
||||
);
|
||||
const structure2 = await driver.analyseIncremental(conn, structure1);
|
||||
|
||||
@@ -124,14 +152,25 @@ describe('Table analyse', () => {
|
||||
|
||||
expect(structure2.tables.length).toEqual(2);
|
||||
expect(structure2.tables.find(x => x.pureName == 't1')).toEqual(t1Match(engine));
|
||||
expect(structure2.tables.find(x => x.pureName == 't2')).toEqual(t2NextColMatch(engine));
|
||||
|
||||
const t2 = structure2.tables.find(x => x.pureName == 't2');
|
||||
const t2ColumnsOrder = ['id', 'val2', 'nextcol'];
|
||||
const t2Enchanted = engine.forceSortStructureColumns
|
||||
? {
|
||||
...t2,
|
||||
columns: t2.columns.sort(
|
||||
(a, b) => t2ColumnsOrder.indexOf(a.columnName) - t2ColumnsOrder.indexOf(b.columnName)
|
||||
),
|
||||
}
|
||||
: t2;
|
||||
expect(t2Enchanted).toEqual(t2NextColMatch(engine));
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(x => !x.skipIndexes).map(engine => [engine.label, engine]))(
|
||||
'Index - full analysis - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await runCommandOnDriver(conn, driver, dmp => dmp.put(t1Sql));
|
||||
await runCommandOnDriver(conn, driver, dmp => dmp.put(t1Sql(engine)));
|
||||
await runCommandOnDriver(conn, driver, dmp => dmp.put(ix1Sql));
|
||||
const structure = await driver.analyseFull(conn);
|
||||
|
||||
@@ -161,7 +200,7 @@ describe('Table analyse', () => {
|
||||
'Foreign key - full analysis - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await runCommandOnDriver(conn, driver, dmp => dmp.put(t2Sql(engine)));
|
||||
await runCommandOnDriver(conn, driver, dmp => dmp.put(t3Sql));
|
||||
await runCommandOnDriver(conn, driver, dmp => dmp.put(t3Sql(engine)));
|
||||
// await driver.query(conn, fkSql);
|
||||
|
||||
const structure = await driver.analyseFull(conn);
|
||||
@@ -177,10 +216,10 @@ describe('Table analyse', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
test.each(engines.filter(engine => !engine.skipDefaultValue).map(engine => [engine.label, engine]))(
|
||||
'Table structure - default value - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await runCommandOnDriver(conn, driver, dmp => dmp.put(t4Sql));
|
||||
await runCommandOnDriver(conn, driver, dmp => dmp.put(t4Sql(engine)));
|
||||
|
||||
const structure = await driver.analyseFull(conn);
|
||||
|
||||
|
||||
@@ -24,8 +24,10 @@ function checkTableStructure2(t1, t2) {
|
||||
expect(t2).toEqual(createExpector(omitTableSpecificInfo(t1)));
|
||||
}
|
||||
|
||||
async function testTableCreate(conn, driver, table) {
|
||||
await runCommandOnDriver(conn, driver, dmp => dmp.put('create table ~t0 (~id int not null primary key)'));
|
||||
async function testTableCreate(engine, conn, driver, table) {
|
||||
await runCommandOnDriver(conn, driver, dmp =>
|
||||
dmp.put(`create table ~t0 (~id int ${engine.skipNullability ? '' : 'not null'} primary key)`)
|
||||
);
|
||||
|
||||
const dmp = driver.createDumper();
|
||||
const table1 = {
|
||||
@@ -47,12 +49,46 @@ describe('Table create', () => {
|
||||
test.each(engines.map(engine => [engine.label, engine]))(
|
||||
'Simple table - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testTableCreate(conn, driver, {
|
||||
await testTableCreate(engine, conn, driver, {
|
||||
columns: [
|
||||
{
|
||||
columnName: 'col1',
|
||||
dataType: 'int',
|
||||
notNull: true,
|
||||
...(engine.skipNullability ? {} : { notNull: true }),
|
||||
},
|
||||
],
|
||||
primaryKey: {
|
||||
columns: [{ columnName: 'col1' }],
|
||||
},
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
test.each(
|
||||
engines.filter(i => i.supportTableComments || i.supportColumnComments).map(engine => [engine.label, engine])
|
||||
)(
|
||||
'Simple table with comment - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testTableCreate(engine, conn, driver, {
|
||||
...(engine.supportTableComments && {
|
||||
schemaName: 'dbo',
|
||||
objectComment: 'table comment',
|
||||
}),
|
||||
...(engine.defaultSchemaName && {
|
||||
schemaName: engine.defaultSchemaName,
|
||||
}),
|
||||
columns: [
|
||||
{
|
||||
columnName: 'col1',
|
||||
dataType: 'int',
|
||||
pureName: 'tested',
|
||||
...(engine.skipNullability ? {} : { notNull: true }),
|
||||
...(engine.supportColumnComments && {
|
||||
columnComment: 'column comment',
|
||||
}),
|
||||
...(engine.defaultSchemaName && {
|
||||
schemaName: engine.defaultSchemaName,
|
||||
}),
|
||||
},
|
||||
],
|
||||
primaryKey: {
|
||||
@@ -65,7 +101,7 @@ describe('Table create', () => {
|
||||
test.each(engines.filter(x => !x.skipIndexes).map(engine => [engine.label, engine]))(
|
||||
'Table with index - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testTableCreate(conn, driver, {
|
||||
await testTableCreate(engine, conn, driver, {
|
||||
columns: [
|
||||
{
|
||||
columnName: 'col1',
|
||||
@@ -95,7 +131,7 @@ describe('Table create', () => {
|
||||
test.each(engines.filter(x => !x.skipReferences).map(engine => [engine.label, engine]))(
|
||||
'Table with foreign key - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testTableCreate(conn, driver, {
|
||||
await testTableCreate(engine, conn, driver, {
|
||||
columns: [
|
||||
{
|
||||
columnName: 'col1',
|
||||
@@ -125,7 +161,7 @@ describe('Table create', () => {
|
||||
test.each(engines.filter(x => !x.skipUnique).map(engine => [engine.label, engine]))(
|
||||
'Table with unique - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testTableCreate(conn, driver, {
|
||||
await testTableCreate(engine, conn, driver, {
|
||||
columns: [
|
||||
{
|
||||
columnName: 'col1',
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user