mirror of
https://github.com/OneUptime/oneuptime.git
synced 2026-04-06 08:42:13 +02:00
Compare commits
1072 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
206c5023d7 | ||
|
|
8584726d22 | ||
|
|
ba7a2fb057 | ||
|
|
334ac4d623 | ||
|
|
e9dc7bcab9 | ||
|
|
ec1942af8f | ||
|
|
224eff0d3d | ||
|
|
937679d544 | ||
|
|
0af8d7359b | ||
|
|
e57963cad1 | ||
|
|
8a0b977a17 | ||
|
|
c4f8826084 | ||
|
|
c543e2ab90 | ||
|
|
f41978c16d | ||
|
|
1fcc5fc7b5 | ||
|
|
1e37f03792 | ||
|
|
15850380c4 | ||
|
|
284752631e | ||
|
|
2d843605c7 | ||
|
|
9512d97671 | ||
|
|
5140f92b1a | ||
|
|
7cda0565ba | ||
|
|
224824f1f1 | ||
|
|
72589c060e | ||
|
|
501e78aae1 | ||
|
|
62b309c18c | ||
|
|
4359b74f26 | ||
|
|
25fd18b958 | ||
|
|
5dfe813bc2 | ||
|
|
ca56f83f08 | ||
|
|
cef7df73bb | ||
|
|
901d9dd80c | ||
|
|
09e7e1811d | ||
|
|
f6df07b002 | ||
|
|
184ad1b2b8 | ||
|
|
82b17ebc8e | ||
|
|
4d1c557ee6 | ||
|
|
22d63c3c80 | ||
|
|
a865f987f8 | ||
|
|
fdb64c5cd9 | ||
|
|
e08d2bb8eb | ||
|
|
8f8c443a72 | ||
|
|
190df60a3f | ||
|
|
f374459c5a | ||
|
|
d42d95f28e | ||
|
|
c5f1621ac0 | ||
|
|
d788332221 | ||
|
|
d17cef4692 | ||
|
|
fd8eb66146 | ||
|
|
e6943d38d5 | ||
|
|
53c25a4a4f | ||
|
|
4eff4b91e9 | ||
|
|
b0cb902fab | ||
|
|
1af2ed32fc | ||
|
|
f9b0716769 | ||
|
|
7509dbb766 | ||
|
|
2d4a084aee | ||
|
|
03b9627da7 | ||
|
|
fba576b248 | ||
|
|
80a925d77d | ||
|
|
781c40e7c5 | ||
|
|
60430eb6f5 | ||
|
|
f12a793951 | ||
|
|
7d795408ed | ||
|
|
81c8758630 | ||
|
|
b925b876de | ||
|
|
815270cfbc | ||
|
|
5d4f8c623a | ||
|
|
84a76da280 | ||
|
|
c7ae1844c5 | ||
|
|
8636b5bc69 | ||
|
|
147e104bc4 | ||
|
|
52f2c8ad14 | ||
|
|
3c06af91ba | ||
|
|
fbcda678f8 | ||
|
|
1b019af98d | ||
|
|
c8a23df5b6 | ||
|
|
b4fb4f72b6 | ||
|
|
3208e99469 | ||
|
|
fdff20a2f9 | ||
|
|
b483cf1601 | ||
|
|
21df6c0b7c | ||
|
|
0408bf96db | ||
|
|
8e0b2dd8dd | ||
|
|
667b326c8b | ||
|
|
f5342d066c | ||
|
|
d67ee57bf0 | ||
|
|
9a6d8c9459 | ||
|
|
4c71eb7fca | ||
|
|
97f7a6e4ef | ||
|
|
23a79ca158 | ||
|
|
777adada5a | ||
|
|
1887f1d238 | ||
|
|
dcc25fa0c4 | ||
|
|
0c293c8362 | ||
|
|
585b7bc239 | ||
|
|
fc50511b7f | ||
|
|
006e398322 | ||
|
|
0e442f0134 | ||
|
|
7d01474d0f | ||
|
|
dbce4f90ab | ||
|
|
eccb035bf2 | ||
|
|
fad319016b | ||
|
|
9a09b6562d | ||
|
|
8dc689fd5a | ||
|
|
bbeaeb047e | ||
|
|
576c220b31 | ||
|
|
59ab24ba36 | ||
|
|
32e72a8817 | ||
|
|
d03ffc83b2 | ||
|
|
c88a59cddb | ||
|
|
c2305da404 | ||
|
|
36dcb1597f | ||
|
|
24f499bcc2 | ||
|
|
6a3f287822 | ||
|
|
37d2d8bedf | ||
|
|
e51c3c5c56 | ||
|
|
13ee850a67 | ||
|
|
fa586c0667 | ||
|
|
16a858d2e2 | ||
|
|
51f4f4c23c | ||
|
|
15a81ed14d | ||
|
|
c520d09351 | ||
|
|
14c6bdb3b4 | ||
|
|
ec9e6252a1 | ||
|
|
8fd03008b7 | ||
|
|
b1922ea4a9 | ||
|
|
63fcfbc6f6 | ||
|
|
cf5fceb981 | ||
|
|
c95f845a5c | ||
|
|
b42a69b154 | ||
|
|
b0ef3be85e | ||
|
|
07b72310fc | ||
|
|
3707ee7b9d | ||
|
|
f5bc142112 | ||
|
|
90e01e9fb8 | ||
|
|
93fc5b68ff | ||
|
|
54600cf358 | ||
|
|
ba90733f72 | ||
|
|
acc610e253 | ||
|
|
a4c17c7bf6 | ||
|
|
5f2479abce | ||
|
|
b2042baa04 | ||
|
|
cfba3386b7 | ||
|
|
06b34c4e9d | ||
|
|
074055aec4 | ||
|
|
5ef0b908d8 | ||
|
|
cbc9445b84 | ||
|
|
eebfb79b06 | ||
|
|
c0ff01e7f6 | ||
|
|
16a65fcb4c | ||
|
|
f62930abb1 | ||
|
|
379252bddf | ||
|
|
69eed8d7cf | ||
|
|
2a37f62a82 | ||
|
|
0fb652abf2 | ||
|
|
c4f058cbec | ||
|
|
3ca7d83d96 | ||
|
|
3787985d23 | ||
|
|
632ed7b782 | ||
|
|
3ae76dde91 | ||
|
|
dc6ce43e0d | ||
|
|
0ca9c2db9b | ||
|
|
552415713e | ||
|
|
f4c7304d38 | ||
|
|
12e90da3a1 | ||
|
|
6db5bea724 | ||
|
|
b3ac3771b1 | ||
|
|
4ca1def4c8 | ||
|
|
911872ac3c | ||
|
|
dab7f81073 | ||
|
|
c0d8155ad7 | ||
|
|
4e0d7e32b2 | ||
|
|
b527f47837 | ||
|
|
2b8b818bc7 | ||
|
|
01c3b9e8be | ||
|
|
c991cd859f | ||
|
|
62862a2ace | ||
|
|
ba5f3e7355 | ||
|
|
18bc817701 | ||
|
|
bcabf7daad | ||
|
|
7433ed39bc | ||
|
|
48cbd60ebc | ||
|
|
4544c1225e | ||
|
|
77c3b4f329 | ||
|
|
9cbfce967d | ||
|
|
c84cbe5575 | ||
|
|
b7965229f1 | ||
|
|
d661b2961c | ||
|
|
6c2f1acf39 | ||
|
|
ad53b442a0 | ||
|
|
526df139b1 | ||
|
|
c60eaccc90 | ||
|
|
f2d13ec4ad | ||
|
|
259659133e | ||
|
|
a35462b3c9 | ||
|
|
19b717019b | ||
|
|
0a688459ee | ||
|
|
f4ffc4f115 | ||
|
|
4825e57821 | ||
|
|
d574be9ab5 | ||
|
|
7a5c04cec4 | ||
|
|
aee2d10db6 | ||
|
|
aec8258939 | ||
|
|
38be1286c7 | ||
|
|
ebab1b2010 | ||
|
|
6ab771f3ee | ||
|
|
e874913d38 | ||
|
|
706f0ebb27 | ||
|
|
f83df55a9c | ||
|
|
e08ff80312 | ||
|
|
ec40c16eed | ||
|
|
16fe15ac22 | ||
|
|
507fad9490 | ||
|
|
81fa79ac57 | ||
|
|
5078e084a4 | ||
|
|
18508e763b | ||
|
|
27398d4b95 | ||
|
|
e781c6032a | ||
|
|
4f6e89550f | ||
|
|
435d0b2df3 | ||
|
|
1aa466d3f2 | ||
|
|
6852f89827 | ||
|
|
f20131668e | ||
|
|
bfcc0fa511 | ||
|
|
bf57922bde | ||
|
|
b80357d345 | ||
|
|
5b2bf8b31e | ||
|
|
f9b5079458 | ||
|
|
f366b5cdcc | ||
|
|
e9dd4ba84f | ||
|
|
b4230344c7 | ||
|
|
74ee0f6224 | ||
|
|
3f2c1ccef4 | ||
|
|
c869b49e23 | ||
|
|
0ce1a58600 | ||
|
|
2f8a436fd0 | ||
|
|
e6d544fabc | ||
|
|
878ab8566e | ||
|
|
fd98e2e1f3 | ||
|
|
cffdd4d7c2 | ||
|
|
503d028677 | ||
|
|
a3aaefe843 | ||
|
|
94d47bc54a | ||
|
|
579d635699 | ||
|
|
6526b6d59b | ||
|
|
22fe6a8859 | ||
|
|
b64cf8127b | ||
|
|
dc3d262b45 | ||
|
|
87497ba998 | ||
|
|
161536fb5b | ||
|
|
f0b2c92065 | ||
|
|
bd9638f402 | ||
|
|
99793c7a37 | ||
|
|
50b0b435cd | ||
|
|
d43b63c8f5 | ||
|
|
97b6f2702e | ||
|
|
ae5911c0b4 | ||
|
|
4d1dc9198a | ||
|
|
8cda8eff8e | ||
|
|
e43068d391 | ||
|
|
93eda19560 | ||
|
|
970f4e30bc | ||
|
|
db1d2d3dce | ||
|
|
91691a05d6 | ||
|
|
01ad5604ba | ||
|
|
27bb1d87b4 | ||
|
|
b6742c93d7 | ||
|
|
cb2a3619fc | ||
|
|
418c7f9da6 | ||
|
|
cbb716c102 | ||
|
|
1ce1058f72 | ||
|
|
133a46a3cf | ||
|
|
6a50b0a4cc | ||
|
|
ff9b2e4fd0 | ||
|
|
07ecf31473 | ||
|
|
f24e540fc6 | ||
|
|
ca93e786c9 | ||
|
|
f42b25ef9d | ||
|
|
3dcdb5f0c2 | ||
|
|
606c0cb69d | ||
|
|
b187773f99 | ||
|
|
1949946cd3 | ||
|
|
f3e4958d36 | ||
|
|
09b9454633 | ||
|
|
0cfc424116 | ||
|
|
4bccc7ce96 | ||
|
|
4ad1182a48 | ||
|
|
69e6e22e1f | ||
|
|
eaacaf7489 | ||
|
|
868ac191a9 | ||
|
|
912f1ecfc8 | ||
|
|
72ade144e5 | ||
|
|
db92624920 | ||
|
|
cbd7211690 | ||
|
|
8c217fcfe1 | ||
|
|
046f7dd0c2 | ||
|
|
ea2ae6e1e1 | ||
|
|
a29cf250b9 | ||
|
|
77ff3673cd | ||
|
|
222d3e8c84 | ||
|
|
d0280da995 | ||
|
|
957604636d | ||
|
|
2c8b559b08 | ||
|
|
541847b5fb | ||
|
|
a5a236e0cb | ||
|
|
53f3426543 | ||
|
|
dedf42ca84 | ||
|
|
2a1c300b04 | ||
|
|
58cf02b50a | ||
|
|
277180907a | ||
|
|
55924cac1f | ||
|
|
48d87d61ef | ||
|
|
d5220593dc | ||
|
|
553d2aaea5 | ||
|
|
52778bdb2d | ||
|
|
5b67f517d8 | ||
|
|
084b3b4bcc | ||
|
|
440c405023 | ||
|
|
d3fa233759 | ||
|
|
863756fa57 | ||
|
|
cf802c0d4a | ||
|
|
e7e0ca5172 | ||
|
|
9801232a8c | ||
|
|
cb4e18b472 | ||
|
|
69d0d1aac3 | ||
|
|
8932ebf52d | ||
|
|
fa21d220ac | ||
|
|
28204919a0 | ||
|
|
565da66333 | ||
|
|
6efb29faa1 | ||
|
|
10bef3fff0 | ||
|
|
cc47bced8a | ||
|
|
df4f47ce66 | ||
|
|
0c735578f8 | ||
|
|
8fb7ef1e2b | ||
|
|
97a326cb51 | ||
|
|
57cc4edcca | ||
|
|
f3ac74e59b | ||
|
|
849c3e560a | ||
|
|
3af8c91d5e | ||
|
|
31b9eac7ad | ||
|
|
4b432014f9 | ||
|
|
163f3db2ca | ||
|
|
b4fbd01894 | ||
|
|
c8f7c4eef6 | ||
|
|
490d3dd2b3 | ||
|
|
4b0374e134 | ||
|
|
2ce9462c3c | ||
|
|
801dca9be1 | ||
|
|
ad6ffb0ba4 | ||
|
|
5afeb8ecc4 | ||
|
|
bd29c33c19 | ||
|
|
89c484facf | ||
|
|
d7ff9ce800 | ||
|
|
3c26f4769d | ||
|
|
d609fc94ec | ||
|
|
4da25335b7 | ||
|
|
d6c9b48360 | ||
|
|
4776b0a331 | ||
|
|
b06947c912 | ||
|
|
768e54e61b | ||
|
|
94b0cd47f9 | ||
|
|
02e8c54725 | ||
|
|
9cc5dc56b1 | ||
|
|
4dac24bc8b | ||
|
|
32169d4a87 | ||
|
|
d49d4b79c3 | ||
|
|
622437c6e3 | ||
|
|
b0d160a227 | ||
|
|
81254c2234 | ||
|
|
aafa3b15b7 | ||
|
|
70fa8ae9fa | ||
|
|
696b6dc87d | ||
|
|
b2ece0f23b | ||
|
|
c4a0040f44 | ||
|
|
3af0e0f182 | ||
|
|
4900978f92 | ||
|
|
8c7c61519f | ||
|
|
471259e8a1 | ||
|
|
88ea284d68 | ||
|
|
f4482de562 | ||
|
|
a32e5a157b | ||
|
|
7e99352071 | ||
|
|
046688598a | ||
|
|
0ba3758eb3 | ||
|
|
ca29caddb7 | ||
|
|
035ad05659 | ||
|
|
515e6b1625 | ||
|
|
153908e406 | ||
|
|
8fae1b724b | ||
|
|
53e04ddb71 | ||
|
|
d757ed60eb | ||
|
|
0e0365007d | ||
|
|
c62a511e8f | ||
|
|
0fe0268df7 | ||
|
|
e50a5ef1e3 | ||
|
|
cdade5994e | ||
|
|
74b23054f8 | ||
|
|
52eea584c1 | ||
|
|
e695ffce09 | ||
|
|
85c00fa19b | ||
|
|
ec52dc0d70 | ||
|
|
737ee28528 | ||
|
|
58e1635d68 | ||
|
|
1443218abc | ||
|
|
f9a68300a7 | ||
|
|
e9208eef5f | ||
|
|
42ce4028a9 | ||
|
|
6c08f311fe | ||
|
|
6bc3f302ef | ||
|
|
16e2990a9f | ||
|
|
e8d698ebf4 | ||
|
|
ec71491bcb | ||
|
|
e5aefc9362 | ||
|
|
2373458f94 | ||
|
|
406c475da6 | ||
|
|
bba9b24f78 | ||
|
|
9fcce2cb2c | ||
|
|
40d99ccf5b | ||
|
|
9f5b9146d1 | ||
|
|
42caa72bbf | ||
|
|
a8c2999e7c | ||
|
|
53882dfeb9 | ||
|
|
2b243f2cac | ||
|
|
2fece456ef | ||
|
|
39848fd071 | ||
|
|
11ee56998f | ||
|
|
22cce216fe | ||
|
|
3ac00ef54a | ||
|
|
97e8f2de8e | ||
|
|
4a7f5ac910 | ||
|
|
93fae92467 | ||
|
|
4e749b4c29 | ||
|
|
24b71c42e6 | ||
|
|
11daa0b423 | ||
|
|
0028772b30 | ||
|
|
bb8b66bacc | ||
|
|
f4f96d2c01 | ||
|
|
81d03790c6 | ||
|
|
8a3c50371d | ||
|
|
cb6a92da40 | ||
|
|
4387d2d981 | ||
|
|
ebc2f6f56e | ||
|
|
463526deca | ||
|
|
4d59e9304b | ||
|
|
60ac93a0da | ||
|
|
26a1783fc7 | ||
|
|
ad4c98a492 | ||
|
|
3db9acc4b2 | ||
|
|
aebb1c85af | ||
|
|
a942a1415f | ||
|
|
aaf3b052b1 | ||
|
|
878b7a14be | ||
|
|
29078d584b | ||
|
|
b9372929de | ||
|
|
11c732d12b | ||
|
|
d46c864c31 | ||
|
|
6d0e563551 | ||
|
|
cb313fc3bd | ||
|
|
d63c66725f | ||
|
|
f4c003ec45 | ||
|
|
b4e1530e20 | ||
|
|
9b49b72b20 | ||
|
|
9480c1e46b | ||
|
|
151fe8c2c9 | ||
|
|
9ac253cbaa | ||
|
|
8514a48c8f | ||
|
|
656ed8153d | ||
|
|
70e6ce7714 | ||
|
|
7bd1c18be2 | ||
|
|
d8876e5000 | ||
|
|
fc503a11ab | ||
|
|
753603ff97 | ||
|
|
6c998fd661 | ||
|
|
8e4dbc7137 | ||
|
|
c58a29bf44 | ||
|
|
4c07a9edd1 | ||
|
|
b847b93268 | ||
|
|
4dd2705fc4 | ||
|
|
39d6c4db09 | ||
|
|
2404c34ab7 | ||
|
|
2c8b54f1ea | ||
|
|
10f6285d42 | ||
|
|
fd5d47a60c | ||
|
|
df8c521dc3 | ||
|
|
a1e519c318 | ||
|
|
ff9e576b27 | ||
|
|
8629985a1a | ||
|
|
ae8944d949 | ||
|
|
22690ad164 | ||
|
|
9c8ad1e2b2 | ||
|
|
5df20b858e | ||
|
|
f25f960f69 | ||
|
|
ddfdfed58b | ||
|
|
5cde6b4815 | ||
|
|
db2ff63951 | ||
|
|
19f22b6d1b | ||
|
|
913d487810 | ||
|
|
9d771b370f | ||
|
|
ae5e705418 | ||
|
|
887cb7c1d9 | ||
|
|
4e28436838 | ||
|
|
a00cc6d7e9 | ||
|
|
e146d56f50 | ||
|
|
692fb99baf | ||
|
|
be541c93bb | ||
|
|
95f20eae7c | ||
|
|
baf99f104f | ||
|
|
678bda8b37 | ||
|
|
48def92f92 | ||
|
|
ed5313b87d | ||
|
|
bdc62bb72b | ||
|
|
0e18d7ee5e | ||
|
|
7b173cfc16 | ||
|
|
4e98bd9e3a | ||
|
|
da036921b4 | ||
|
|
d67d245379 | ||
|
|
2b56184cad | ||
|
|
efe0bccd65 | ||
|
|
d7b200e2f7 | ||
|
|
d1a3b2b852 | ||
|
|
db2dbfcac7 | ||
|
|
a6d9c6493a | ||
|
|
a067e85283 | ||
|
|
e9feb06864 | ||
|
|
9c4799ff30 | ||
|
|
88c4b75c45 | ||
|
|
3d46de7fb6 | ||
|
|
c82f40443b | ||
|
|
ca32b8fa1d | ||
|
|
8ad344f1f9 | ||
|
|
407abd4146 | ||
|
|
fdc7887e48 | ||
|
|
59cd7afcc5 | ||
|
|
0070aa7ee7 | ||
|
|
e39474bc23 | ||
|
|
cb834adc6c | ||
|
|
434573e770 | ||
|
|
96fced64cf | ||
|
|
b12e8ad489 | ||
|
|
33f567570c | ||
|
|
015350acb2 | ||
|
|
9f52526e5a | ||
|
|
d41b9c4fc1 | ||
|
|
9a587623bf | ||
|
|
70136546be | ||
|
|
d683f26ca7 | ||
|
|
830ddd04f8 | ||
|
|
2e429a14d2 | ||
|
|
ed21325f5b | ||
|
|
372d6b5d3a | ||
|
|
ee2188d75a | ||
|
|
79db7d5702 | ||
|
|
5705f413cb | ||
|
|
f37601d923 | ||
|
|
2c705aca77 | ||
|
|
ee9767eecc | ||
|
|
39b0d6e7b6 | ||
|
|
e45ec0bf74 | ||
|
|
2f05ccdfc7 | ||
|
|
e1a0cd90e4 | ||
|
|
ca52106c23 | ||
|
|
d6932ee3fc | ||
|
|
62f1ac8945 | ||
|
|
668c6bf858 | ||
|
|
69e045d581 | ||
|
|
0faeeed8b5 | ||
|
|
031fe5425c | ||
|
|
61d3604a9d | ||
|
|
b375e8341d | ||
|
|
6c1c446f06 | ||
|
|
fd3694b93f | ||
|
|
261db0c748 | ||
|
|
ad8ebf43de | ||
|
|
fb24b39f27 | ||
|
|
753141e524 | ||
|
|
28906a3c09 | ||
|
|
81a39951fb | ||
|
|
7584bfd26c | ||
|
|
eff654c117 | ||
|
|
eb144ca195 | ||
|
|
eb04399147 | ||
|
|
5c6efc0f8e | ||
|
|
986bc78df6 | ||
|
|
727f923dbb | ||
|
|
c7622bb7f3 | ||
|
|
86a25a456a | ||
|
|
7f93e953ee | ||
|
|
2bc92729e5 | ||
|
|
cd4a139a3c | ||
|
|
eefccf6110 | ||
|
|
920352ac97 | ||
|
|
8fc4f61ffe | ||
|
|
1ec06ac333 | ||
|
|
8d9ec445b7 | ||
|
|
0e934ed3e5 | ||
|
|
ad6f59013e | ||
|
|
6fed662391 | ||
|
|
6a9704ba79 | ||
|
|
4c66d4c97e | ||
|
|
2f5c19ecb5 | ||
|
|
80b2474b03 | ||
|
|
0fe31f5371 | ||
|
|
f7cd616540 | ||
|
|
dfda71d779 | ||
|
|
f6dc0d9214 | ||
|
|
200dd1d98d | ||
|
|
640ce525c5 | ||
|
|
6a6780058c | ||
|
|
2f167bd7aa | ||
|
|
cbbc3c79d0 | ||
|
|
14dceebc9a | ||
|
|
2fbe8294eb | ||
|
|
3a57253720 | ||
|
|
c554627ab2 | ||
|
|
a9a0466e49 | ||
|
|
126927350d | ||
|
|
a5f2f4e338 | ||
|
|
b276e6dfc4 | ||
|
|
9f7f5d7a50 | ||
|
|
c6981cc130 | ||
|
|
cf0a76ce71 | ||
|
|
5ce3a5d876 | ||
|
|
b8b79e0d73 | ||
|
|
aa38ebf8ba | ||
|
|
e1d34054ab | ||
|
|
c22606d93c | ||
|
|
8c7aab22f1 | ||
|
|
45cbe8e357 | ||
|
|
74f797948e | ||
|
|
9cb3cf0d04 | ||
|
|
35a85a35a4 | ||
|
|
6f0b7a2145 | ||
|
|
e5ee57e234 | ||
|
|
2b186d8a2a | ||
|
|
0a711dbcfd | ||
|
|
d26b348f0d | ||
|
|
7ea8479779 | ||
|
|
72d2297a02 | ||
|
|
fae8968dde | ||
|
|
b9a10ebcad | ||
|
|
5a7c706829 | ||
|
|
adf7432663 | ||
|
|
2409e0fea8 | ||
|
|
f0fb3fabd0 | ||
|
|
340afdecc8 | ||
|
|
c7b5a544ee | ||
|
|
8d131b28bf | ||
|
|
d1131d32e8 | ||
|
|
2c4664b362 | ||
|
|
c784324b00 | ||
|
|
bfc5e29b71 | ||
|
|
ba30927de6 | ||
|
|
ae5f0983a6 | ||
|
|
49c70767b0 | ||
|
|
b6afa0d632 | ||
|
|
a2b8e721bf | ||
|
|
ac7b04e8ad | ||
|
|
b0eb75d6c7 | ||
|
|
784bebe1a4 | ||
|
|
638e323c4f | ||
|
|
f79f4c7627 | ||
|
|
5936805350 | ||
|
|
22c9d9228c | ||
|
|
9759911dba | ||
|
|
fa99ce9a3f | ||
|
|
983739cc03 | ||
|
|
b4f034d1a9 | ||
|
|
3bdc7407aa | ||
|
|
1829e1ec42 | ||
|
|
cb82bd7c6f | ||
|
|
48f5a735d2 | ||
|
|
17946c3c51 | ||
|
|
57c13add9c | ||
|
|
544bbb2d2f | ||
|
|
7126fdbdae | ||
|
|
aaf60f39ac | ||
|
|
687c5c341b | ||
|
|
0b37a63c84 | ||
|
|
4421227c5e | ||
|
|
91f8489b22 | ||
|
|
4fa048929c | ||
|
|
12df8275a5 | ||
|
|
8e76c5a90a | ||
|
|
08d13997fe | ||
|
|
e12ea14d85 | ||
|
|
80a46eb808 | ||
|
|
4dc5c55a41 | ||
|
|
67a94cca79 | ||
|
|
ee84a082dc | ||
|
|
a52b2be67e | ||
|
|
092d5ec270 | ||
|
|
7ce4cb9143 | ||
|
|
8a32c659e1 | ||
|
|
49c9987efd | ||
|
|
aa6d3523fc | ||
|
|
be8da5c8f9 | ||
|
|
c240f4d569 | ||
|
|
0d8f174675 | ||
|
|
8b11dcfe81 | ||
|
|
b4e56b18ce | ||
|
|
1fd68ef60f | ||
|
|
62d1679938 | ||
|
|
99af4fe826 | ||
|
|
4ec5c0d7f1 | ||
|
|
3023e22de3 | ||
|
|
5128e17205 | ||
|
|
d3bb9f26e9 | ||
|
|
a8026f470a | ||
|
|
3072bb8625 | ||
|
|
9a3127563d | ||
|
|
1ff254343f | ||
|
|
2f6f81385f | ||
|
|
b5929454b0 | ||
|
|
17b2012279 | ||
|
|
2d47b326b8 | ||
|
|
72b90f8414 | ||
|
|
a32120e5bd | ||
|
|
502f298a3a | ||
|
|
d8d5556f1a | ||
|
|
1e488ebfbe | ||
|
|
4cd4cc828f | ||
|
|
e5795034c6 | ||
|
|
2b2f9a74b6 | ||
|
|
fd98711ad8 | ||
|
|
cf4d8df7e5 | ||
|
|
0a91105e28 | ||
|
|
58bfec9c5a | ||
|
|
ce402c79d1 | ||
|
|
4ce79420ca | ||
|
|
c663fbd0a1 | ||
|
|
c8f24affc3 | ||
|
|
abb4f4724f | ||
|
|
3a268fc816 | ||
|
|
8cb398919a | ||
|
|
a63dd22d1e | ||
|
|
c793479f55 | ||
|
|
1d092240f9 | ||
|
|
625c96b91a | ||
|
|
a5686c01fb | ||
|
|
a8dc444714 | ||
|
|
508677867a | ||
|
|
a9a839f143 | ||
|
|
a299fca2ba | ||
|
|
396066bf0d | ||
|
|
9debdfafba | ||
|
|
49c4dff44b | ||
|
|
27a8434181 | ||
|
|
c8305ef7c0 | ||
|
|
2f332a64f3 | ||
|
|
fb5291e7c1 | ||
|
|
4034cf6ed8 | ||
|
|
8b37587800 | ||
|
|
03eb1dd1f2 | ||
|
|
ee91526239 | ||
|
|
970c537b96 | ||
|
|
35718ee7b5 | ||
|
|
310cd90714 | ||
|
|
513fa74c59 | ||
|
|
4ba6f714af | ||
|
|
7ab3ba7201 | ||
|
|
e5aa9c9496 | ||
|
|
455ca7b22d | ||
|
|
0b71c8b769 | ||
|
|
19b0a1f2a8 | ||
|
|
4f93dd0f04 | ||
|
|
60d0f188ad | ||
|
|
bd587b210e | ||
|
|
80dd33cd7f | ||
|
|
d675eca50c | ||
|
|
76712e8f89 | ||
|
|
fe68b009eb | ||
|
|
6c1bd10873 | ||
|
|
9a6960e154 | ||
|
|
05a288c761 | ||
|
|
a9f503da9d | ||
|
|
49d3655502 | ||
|
|
1cdcc639b4 | ||
|
|
7568c70b50 | ||
|
|
6259f81a91 | ||
|
|
f40c1daeb8 | ||
|
|
bb73ed14cd | ||
|
|
4b71a81f7c | ||
|
|
d6788c138b | ||
|
|
28f4a1f473 | ||
|
|
ccb4781c06 | ||
|
|
2e27347225 | ||
|
|
e9015f0eff | ||
|
|
6cf8560151 | ||
|
|
7d2e91d867 | ||
|
|
46e0210dcc | ||
|
|
02fc5502eb | ||
|
|
ce3131edaf | ||
|
|
ca4716133a | ||
|
|
9cb254f9d1 | ||
|
|
d51fbdf5f7 | ||
|
|
57b7b5b39e | ||
|
|
2e46ebd0e8 | ||
|
|
4ffe215665 | ||
|
|
e680346f1f | ||
|
|
4faa8d32f6 | ||
|
|
ab07ff0104 | ||
|
|
03dd6fef04 | ||
|
|
31c0ff7dea | ||
|
|
dca1d2c370 | ||
|
|
fc218a970a | ||
|
|
17509225ee | ||
|
|
447bac1d67 | ||
|
|
67b3b224a7 | ||
|
|
48fbf50973 | ||
|
|
a0acb24651 | ||
|
|
c958893d67 | ||
|
|
9e2bd15cf4 | ||
|
|
17e9ad4fcd | ||
|
|
4d5a49f11e | ||
|
|
2d9b9950dd | ||
|
|
c3c0fbc853 | ||
|
|
f970b02e9e | ||
|
|
987394be41 | ||
|
|
34b3dff108 | ||
|
|
b603241d57 | ||
|
|
8df01fc098 | ||
|
|
268305e6cd | ||
|
|
bbb53b3321 | ||
|
|
c79fa88ad1 | ||
|
|
35c5e57752 | ||
|
|
254a9de101 | ||
|
|
c844bf8e43 | ||
|
|
c0288716da | ||
|
|
51e7fa6c9a | ||
|
|
d9eb60017a | ||
|
|
e9d7b36198 | ||
|
|
7308945061 | ||
|
|
3f8e5e4e0a | ||
|
|
3f7d186db0 | ||
|
|
8cb91d94eb | ||
|
|
3337ad2a45 | ||
|
|
438fbf4368 | ||
|
|
ffca1acc9a | ||
|
|
846d5ce104 | ||
|
|
43a075436a | ||
|
|
8fe35d9a29 | ||
|
|
849eeac23a | ||
|
|
01a4cac559 | ||
|
|
b4cd4d2c02 | ||
|
|
329484fb87 | ||
|
|
ee54a324d7 | ||
|
|
ba2feffbee | ||
|
|
4b0b91396b | ||
|
|
f2c6321216 | ||
|
|
67447c0bd7 | ||
|
|
323646ebcd | ||
|
|
81e4b4435c | ||
|
|
842b0664c7 | ||
|
|
0bdab474de | ||
|
|
ef1b22e62b | ||
|
|
3d229a0030 | ||
|
|
e34599d18a | ||
|
|
aa7594f2a8 | ||
|
|
0626669b02 | ||
|
|
35b949e448 | ||
|
|
2bb4086fd1 | ||
|
|
03f9c36f06 | ||
|
|
9fe998a43d | ||
|
|
3841b655e5 | ||
|
|
5ec8ee6dcb | ||
|
|
a1c6121bee | ||
|
|
51c76aa1af | ||
|
|
40ee5d775b | ||
|
|
88f0e2af51 | ||
|
|
e702a0b0d2 | ||
|
|
cfc2f99248 | ||
|
|
f23bb3af41 | ||
|
|
2cdf1236be | ||
|
|
ed5a144735 | ||
|
|
e687a439e6 | ||
|
|
cfa20e2be6 | ||
|
|
9205764deb | ||
|
|
32275837ac | ||
|
|
34568a39f5 | ||
|
|
b7b41dfebb | ||
|
|
9b40011196 | ||
|
|
d644287a0c | ||
|
|
ea7dc0b918 | ||
|
|
c34639a3bb | ||
|
|
41ba37be80 | ||
|
|
954d5be113 | ||
|
|
21a857d912 | ||
|
|
cb0f7bbad5 | ||
|
|
c3c94f3634 | ||
|
|
955141d42e | ||
|
|
352c9ffb8e | ||
|
|
d543757a7d | ||
|
|
b3cfdbf45a | ||
|
|
c629921d01 | ||
|
|
008e0c50b1 | ||
|
|
fcf916bdfe | ||
|
|
9850bcf0e7 | ||
|
|
e1efeec9ec | ||
|
|
7e34393fc6 | ||
|
|
262fffd9ff | ||
|
|
35db6e95ad | ||
|
|
17208b5e26 | ||
|
|
896dce3430 | ||
|
|
d844fa9df2 | ||
|
|
48542c4323 | ||
|
|
f57047c778 | ||
|
|
e471787462 | ||
|
|
dc4721f878 | ||
|
|
4bd4dbf3c1 | ||
|
|
6c0c79dd25 | ||
|
|
a9548858b0 | ||
|
|
6804e94850 | ||
|
|
63736aed6c | ||
|
|
c848032fdc | ||
|
|
22c2231e22 | ||
|
|
7a063d741c | ||
|
|
8a9cc10ff0 | ||
|
|
2e43fa0c02 | ||
|
|
f51a1828ab | ||
|
|
805139055a | ||
|
|
42c85b16e7 | ||
|
|
a59742cddb | ||
|
|
ba426b5580 | ||
|
|
1945bbfd45 | ||
|
|
58debb9959 | ||
|
|
6485f474b2 | ||
|
|
301d7f124c | ||
|
|
985217d2bf | ||
|
|
20f46177cb | ||
|
|
0453d995ba | ||
|
|
8ab7fbc95d | ||
|
|
2d99850596 | ||
|
|
c77b8e2d57 | ||
|
|
e12f73cebf | ||
|
|
0351480152 | ||
|
|
62e81bee06 | ||
|
|
11b500058e | ||
|
|
0b94b0ff70 | ||
|
|
9bd8275321 | ||
|
|
a25a1ed0b9 | ||
|
|
accffbe443 | ||
|
|
414bfdfec1 | ||
|
|
cc7037b549 | ||
|
|
725f41ef1b | ||
|
|
e7682c826d | ||
|
|
5347bc29ea | ||
|
|
aa975633dd | ||
|
|
199ef2b009 | ||
|
|
f0f690f24a | ||
|
|
ef43088692 | ||
|
|
8f36524583 | ||
|
|
d738d1378c | ||
|
|
b402450eac | ||
|
|
130d7b1af3 | ||
|
|
070fd415ae | ||
|
|
d8b6cf98fe | ||
|
|
3a8451aea3 | ||
|
|
0de056c4e9 | ||
|
|
8e02cf56ef | ||
|
|
1296707e0d | ||
|
|
80b848f757 | ||
|
|
4b2a9c74c0 | ||
|
|
62ed9583fc | ||
|
|
8a2f9f9913 | ||
|
|
1a1be22b16 | ||
|
|
7e48cb2451 | ||
|
|
8fc2f93e94 | ||
|
|
1892d06cec | ||
|
|
32960b90f8 | ||
|
|
7bd5efee1c | ||
|
|
f1b4214379 | ||
|
|
ff0314ae9b | ||
|
|
591c89a320 | ||
|
|
60b1f3bcc5 | ||
|
|
7e796dff42 | ||
|
|
34817a1066 | ||
|
|
45bdadde87 | ||
|
|
753e017efd | ||
|
|
6b80d76fda | ||
|
|
7daa955528 | ||
|
|
ff9117ab05 | ||
|
|
4405c5fe10 | ||
|
|
98a1ae95b8 | ||
|
|
bcc06324c3 | ||
|
|
d7f2432a0c | ||
|
|
e75c16b6f8 | ||
|
|
c13291c33c | ||
|
|
824fb68395 | ||
|
|
e0795f24fc | ||
|
|
0d178843e4 | ||
|
|
b6f8dbabc5 | ||
|
|
78e97b815d | ||
|
|
9ff18d6df5 | ||
|
|
9fec234b07 | ||
|
|
5fa633959f | ||
|
|
0b4373edcc | ||
|
|
be09a9354d | ||
|
|
d6549cd861 | ||
|
|
3ab1758f17 | ||
|
|
138a42326f | ||
|
|
c6689d2a36 | ||
|
|
3376c2cb96 | ||
|
|
d6e7b5840b | ||
|
|
0319e43a21 | ||
|
|
d9be0a76e3 | ||
|
|
75748274c1 | ||
|
|
08893110bb | ||
|
|
1140eb7270 | ||
|
|
b526306780 | ||
|
|
dc235464f4 | ||
|
|
f0413ac917 | ||
|
|
b00ce0e894 | ||
|
|
2c90d8c0be | ||
|
|
7ccb5fca6f | ||
|
|
b65d452632 | ||
|
|
c040d60da9 | ||
|
|
6fe40bc630 | ||
|
|
c85d9b8372 | ||
|
|
58cfe477c2 | ||
|
|
6d5cb57813 | ||
|
|
4761c747a4 | ||
|
|
7ca8d20c4d | ||
|
|
59a77c6c15 | ||
|
|
099af1f5fe | ||
|
|
d06c657a16 | ||
|
|
1d9abe8af0 | ||
|
|
9bf46fbcf1 | ||
|
|
91adc172bd | ||
|
|
2d4bb56ffa | ||
|
|
01b677ec77 | ||
|
|
ed7708ba7c | ||
|
|
1d7980f3ba | ||
|
|
43069791da | ||
|
|
ccedb52acd | ||
|
|
f0d69b8ca0 | ||
|
|
4359e8fa30 | ||
|
|
b1162446db | ||
|
|
cf80324382 | ||
|
|
f4e372cfce | ||
|
|
b47e95f836 | ||
|
|
e4af38dfa9 | ||
|
|
e51ed0edc0 | ||
|
|
746b396e4f | ||
|
|
1d08ffb130 | ||
|
|
231493b335 | ||
|
|
1cbd9d2d26 | ||
|
|
661e1b8b4d | ||
|
|
4a0ff353e6 | ||
|
|
36cbc22327 | ||
|
|
bbd57c917e | ||
|
|
f72d5550cf | ||
|
|
5920b97c6c | ||
|
|
2c8019bfc6 | ||
|
|
d3e3b7d918 | ||
|
|
f2d02c4a5a | ||
|
|
209ac74643 | ||
|
|
2a6cb19405 | ||
|
|
62db38520f | ||
|
|
31a41fed60 | ||
|
|
55fd9a87b9 | ||
|
|
91ed99f256 | ||
|
|
6f4963cdb0 | ||
|
|
9b6667e6c7 | ||
|
|
b42b93844b | ||
|
|
ca63e6fbfb | ||
|
|
515b8ba94c | ||
|
|
e9bdf80f84 | ||
|
|
31bcfc7531 | ||
|
|
4046da0523 | ||
|
|
e728501ddb |
@@ -6,6 +6,7 @@ node_modules
|
||||
# dependencies
|
||||
/node_modules
|
||||
node_modules
|
||||
**/node_modules
|
||||
|
||||
.idea
|
||||
# testing
|
||||
@@ -53,4 +54,7 @@ tests/coverage
|
||||
|
||||
settings.json
|
||||
|
||||
GoSDK/tester/
|
||||
GoSDK/tester/
|
||||
|
||||
Llama/Models/*
|
||||
|
||||
|
||||
@@ -87,10 +87,11 @@
|
||||
],
|
||||
// https://www.npmjs.com/package/eslint-plugin-unused-imports
|
||||
"no-unused-vars": "off",
|
||||
"@typescript-eslint/no-unused-vars": "off",
|
||||
"@typescript-eslint/no-unused-vars": ["error", {"argsIgnorePattern": "^_"}],
|
||||
"@typescript-eslint/no-extra-non-null-assertion": "error",
|
||||
"@typescript-eslint/no-floating-promises":"error",
|
||||
"@typescript-eslint/await-thenable":"error",
|
||||
"@typescript-eslint/no-non-null-asserted-optional-chain": "error",
|
||||
"unused-imports/no-unused-imports": "error",
|
||||
"unused-imports/no-unused-vars": [
|
||||
"error",
|
||||
@@ -178,11 +179,13 @@
|
||||
"ignoreReadBeforeAssign": false
|
||||
}
|
||||
],
|
||||
"no-var": "error"
|
||||
"no-var": "error",
|
||||
"object-curly-spacing": ["error", "always"],
|
||||
"no-unneeded-ternary": "error"
|
||||
},
|
||||
"settings": {
|
||||
"react": {
|
||||
"version": "18.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -34,5 +34,8 @@ If applicable, add screenshots to help explain your problem.
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Deployment Type**
|
||||
Is this issue on SaaS (at https://oneuptime.com) or self hosted (the version that you deployed on your server)?
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
|
||||
20
.github/workflows/code-analysis.yml
vendored
20
.github/workflows/code-analysis.yml
vendored
@@ -1,20 +0,0 @@
|
||||
name: Code Analysis
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
jobs:
|
||||
sonarcloud:
|
||||
name: SonarCloud
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
- name: SonarCloud Scan
|
||||
uses: SonarSource/sonarcloud-github-action@master
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
142
.github/workflows/compile.yml
vendored
142
.github/workflows/compile.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
||||
- run: cd Model && npm install
|
||||
- run: cd CommonServer && npm install
|
||||
- run: cd CommonUI && npm install --force
|
||||
- run: cd Accounts && npm install && npm run compile
|
||||
- run: cd Accounts && npm install && npm run compile && npm run dep-check
|
||||
|
||||
compile-api-reference:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -37,21 +37,7 @@ jobs:
|
||||
- run: cd Common && npm install
|
||||
- run: cd Model && npm install
|
||||
- run: cd CommonServer && npm install
|
||||
- run: cd ApiReference && npm install && npm run compile
|
||||
|
||||
compile-link-shortener:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
- run: cd Common && npm install
|
||||
- run: cd Model && npm install
|
||||
- run: cd CommonServer && npm install
|
||||
- run: cd LinkShortener && npm install && npm run compile
|
||||
- run: cd ApiReference && npm install && npm run compile && npm run dep-check
|
||||
|
||||
compile-common-server:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -64,7 +50,7 @@ jobs:
|
||||
node-version: 18.3.0
|
||||
- run: cd Common && npm install
|
||||
- run: cd Model && npm install
|
||||
- run: cd CommonServer && npm install && npm run compile
|
||||
- run: cd CommonServer && npm install && npm run compile && npm run dep-check
|
||||
|
||||
compile-common-ui:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -77,7 +63,7 @@ jobs:
|
||||
node-version: 18.3.0
|
||||
- run: cd Common && npm install
|
||||
- run: cd Model && npm install
|
||||
- run: cd CommonUI && npm install --force && npm run compile
|
||||
- run: cd CommonUI && npm install --force && npm run compile && npm run dep-check
|
||||
|
||||
compile-common:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -89,7 +75,7 @@ jobs:
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
- run: cd Common && npm install
|
||||
- run: cd Model && npm install && npm run compile
|
||||
- run: cd Model && npm install && npm run compile && npm run dep-check
|
||||
|
||||
compile-dashboard-api:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -104,7 +90,7 @@ jobs:
|
||||
- run: cd Model && npm install
|
||||
- run: cd CommonServer && npm install
|
||||
- run: cd CommonUI && npm install --force
|
||||
- run: cd DashboardAPI && npm install && npm run compile
|
||||
- run: cd DashboardAPI && npm install && npm run compile && npm run dep-check
|
||||
|
||||
|
||||
compile-admin-dashboard:
|
||||
@@ -120,7 +106,7 @@ jobs:
|
||||
- run: cd Model && npm install
|
||||
- run: cd CommonServer && npm install
|
||||
- run: cd CommonUI && npm install --force
|
||||
- run: cd AdminDashboard && npm install && npm run compile
|
||||
- run: cd AdminDashboard && npm install && npm run compile && npm run dep-check
|
||||
|
||||
compile-dashboard:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -135,21 +121,7 @@ jobs:
|
||||
- run: cd Model && npm install
|
||||
- run: cd CommonServer && npm install
|
||||
- run: cd CommonUI && npm install --force
|
||||
- run: cd Dashboard && npm install && npm run compile
|
||||
|
||||
compile-file:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
- run: cd Common && npm install
|
||||
- run: cd Model && npm install
|
||||
- run: cd CommonServer && npm install
|
||||
- run: cd File && npm install && npm run compile
|
||||
- run: cd Dashboard && npm install && npm run compile && npm run dep-check
|
||||
|
||||
compile-home:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -163,63 +135,8 @@ jobs:
|
||||
- run: cd Common && npm install
|
||||
- run: cd Model && npm install
|
||||
- run: cd CommonServer && npm install
|
||||
- run: cd Home && npm install && npm run compile
|
||||
- run: cd Home && npm install && npm run compile && npm run dep-check
|
||||
|
||||
compile-identity:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
- run: cd Common && npm install
|
||||
- run: cd Model && npm install
|
||||
- run: cd CommonServer && npm install
|
||||
- run: cd Identity && npm install && npm run compile
|
||||
|
||||
compile-integrations:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
- run: cd Common && npm install
|
||||
- run: cd Model && npm install
|
||||
- run: cd CommonServer && npm install
|
||||
- run: cd Integration && npm install && npm run compile
|
||||
|
||||
compile-licensing:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
- run: cd Common && npm install
|
||||
- run: cd Model && npm install
|
||||
- run: cd CommonServer && npm install
|
||||
- run: cd Licensing && npm install && npm run compile
|
||||
|
||||
compile-notification:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
- run: cd Common && npm install
|
||||
- run: cd Model && npm install
|
||||
- run: cd CommonServer && npm install
|
||||
- run: cd Notification && npm install && npm run compile
|
||||
|
||||
compile-model:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -232,7 +149,18 @@ jobs:
|
||||
node-version: 18.3.0
|
||||
- run: cd Common && npm install
|
||||
- run: cd Model && npm install
|
||||
- run: cd Model && npm install && npm run compile
|
||||
- run: cd Model && npm install && npm run compile && npm run dep-check
|
||||
|
||||
compile-e2e:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
- run: cd E2E && npm install && npm run compile && npm run dep-check
|
||||
|
||||
compile-probe:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -246,9 +174,9 @@ jobs:
|
||||
- run: cd Common && npm install
|
||||
- run: cd Model && npm install
|
||||
- run: cd CommonServer && npm install
|
||||
- run: cd Probe && npm install && npm run compile
|
||||
- run: cd Probe && npm install && npm run compile && npm run dep-check
|
||||
|
||||
compile-probe-api:
|
||||
compile-ingestor:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
@@ -260,23 +188,9 @@ jobs:
|
||||
- run: cd Common && npm install
|
||||
- run: cd Model && npm install
|
||||
- run: cd CommonServer && npm install
|
||||
- run: cd ProbeAPI && npm install && npm run compile
|
||||
- run: cd Ingestor && npm install && npm run compile && npm run dep-check
|
||||
|
||||
|
||||
compile-realtime:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
- run: cd Common && npm install
|
||||
- run: cd Model && npm install
|
||||
- run: cd CommonServer && npm install
|
||||
- run: cd Realtime && npm install && npm run compile
|
||||
|
||||
compile-status-page:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
@@ -290,7 +204,7 @@ jobs:
|
||||
- run: cd Model && npm install
|
||||
- run: cd CommonServer && npm install
|
||||
- run: cd CommonUI && npm install --force
|
||||
- run: cd StatusPage && npm install && npm run compile
|
||||
- run: cd StatusPage && npm install && npm run compile && npm run dep-check
|
||||
|
||||
compile-workers:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -305,7 +219,7 @@ jobs:
|
||||
- run: cd Model && npm install
|
||||
- run: cd CommonServer && npm install
|
||||
- run: cd CommonUI && npm install --force
|
||||
- run: cd Workers && npm install && npm run compile
|
||||
- run: cd Workers && npm install && npm run compile && npm run dep-check
|
||||
|
||||
compile-workflow:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -319,7 +233,7 @@ jobs:
|
||||
- run: cd Common && npm install
|
||||
- run: cd Model && npm install
|
||||
- run: cd CommonServer && npm install
|
||||
- run: cd Workflow && npm install && npm run compile
|
||||
- run: cd Workflow && npm install && npm run compile && npm run dep-check
|
||||
|
||||
compile-test-server:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -333,4 +247,4 @@ jobs:
|
||||
- run: cd Common && npm install
|
||||
- run: cd Model && npm install
|
||||
- run: cd CommonServer && npm install
|
||||
- run: cd TestServer && npm install && npm run compile
|
||||
- run: cd TestServer && npm install && npm run compile && npm run dep-check
|
||||
100
.github/workflows/docker-build.yml
vendored
100
.github/workflows/docker-build.yml
vendored
@@ -25,7 +25,8 @@ jobs:
|
||||
- name: build docker image
|
||||
run: sudo docker build -f ./Accounts/Dockerfile .
|
||||
|
||||
docker-build-link-shortener:
|
||||
|
||||
docker-build-otel-collector:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
@@ -38,7 +39,7 @@ jobs:
|
||||
|
||||
# build image for accounts service
|
||||
- name: build docker image
|
||||
run: sudo docker build -f ./LinkShortener/Dockerfile .
|
||||
run: sudo docker build -f ./OTelCollector/Dockerfile .
|
||||
|
||||
docker-build-api-reference:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -101,21 +102,6 @@ jobs:
|
||||
- name: build docker image
|
||||
run: sudo docker build -f ./Dashboard/Dockerfile .
|
||||
|
||||
docker-build-file:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Preinstall
|
||||
run: npm run prerun
|
||||
|
||||
# build image for file
|
||||
- name: build docker image
|
||||
run: sudo docker build -f ./File/Dockerfile .
|
||||
|
||||
docker-build-haraka:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
@@ -147,67 +133,6 @@ jobs:
|
||||
- name: build docker image
|
||||
run: sudo docker build -f ./Home/Dockerfile .
|
||||
|
||||
docker-build-identity:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Preinstall
|
||||
run: npm run prerun
|
||||
|
||||
# build image for identity
|
||||
- name: build docker image
|
||||
run: sudo docker build -f ./Identity/Dockerfile .
|
||||
|
||||
docker-build-integrations:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Preinstall
|
||||
run: npm run prerun
|
||||
|
||||
# build image for licensing
|
||||
- name: build docker image
|
||||
run: sudo docker build -f ./Integration/Dockerfile .
|
||||
|
||||
docker-build-licensing:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Preinstall
|
||||
run: npm run prerun
|
||||
|
||||
# build image for licensing
|
||||
- name: build docker image
|
||||
run: sudo docker build -f ./Licensing/Dockerfile .
|
||||
|
||||
docker-build-notification:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Preinstall
|
||||
run: npm run prerun
|
||||
|
||||
# build image for mail service
|
||||
- name: build docker image
|
||||
run: sudo docker build -f ./Notification/Dockerfile .
|
||||
|
||||
|
||||
docker-build-probe:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
@@ -223,7 +148,7 @@ jobs:
|
||||
- name: build docker image
|
||||
run: sudo docker build -f ./Probe/Dockerfile .
|
||||
|
||||
docker-build-probe-api:
|
||||
docker-build-ingestor:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
@@ -236,22 +161,7 @@ jobs:
|
||||
|
||||
# build image probe api
|
||||
- name: build docker image
|
||||
run: sudo docker build -f ./ProbeAPI/Dockerfile .
|
||||
|
||||
docker-build-realtime:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Preinstall
|
||||
run: npm run prerun
|
||||
|
||||
# build image for home
|
||||
- name: build docker image
|
||||
run: sudo docker build -f ./Realtime/Dockerfile .
|
||||
run: sudo docker build -f ./Ingestor/Dockerfile .
|
||||
|
||||
docker-build-status-page:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
493
.github/workflows/release.yml
vendored
493
.github/workflows/release.yml
vendored
@@ -67,7 +67,6 @@ jobs:
|
||||
ssh-add - <<< '${{ secrets.HELM_CHART_GITHUB_REPO_DEPLOY_KEY }}'
|
||||
git clone git@github.com:OneUptime/helm-chart.git
|
||||
cd oneuptime/HelmChart/Public
|
||||
cp README.md oneuptime/README.md
|
||||
helm lint oneuptime
|
||||
helm package --sign --key 'key@oneuptime.com' --keyring ~/.gnupg/secring.gpg oneuptime --version 7.0.${{needs.generate-build-number.outputs.build_number}} --app-version 7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
echo "Helm Chart Package created successfully"
|
||||
@@ -76,7 +75,6 @@ jobs:
|
||||
echo "Copying the package to helm-chart repo"
|
||||
rm -r ../../helm-chart/oneuptime
|
||||
cp -r ./Public/* ../../helm-chart
|
||||
cp ./Public/README.md ../../helm-chart/oneuptime/README.md
|
||||
echo "Package copied successfully"
|
||||
cd .. && cd .. && cd helm-chart
|
||||
echo "Updating helm-chart repo"
|
||||
@@ -209,6 +207,68 @@ jobs:
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
otel-collector-docker-image-deploy:
|
||||
needs: generate-build-number
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Docker Meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
oneuptime/otel-collector
|
||||
ghcr.io/oneuptime/otel-collector
|
||||
tags: |
|
||||
type=raw,value=release,enable=true
|
||||
type=semver,value=7.0.${{needs.generate-build-number.outputs.build_number}},pattern={{version}},enable=true
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Generate Dockerfile from Dockerfile.tpl
|
||||
run: npm run prerun
|
||||
|
||||
# Build and deploy otel-collector.
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
file: ./OTelCollector/Dockerfile
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
build-args: |
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
|
||||
|
||||
workflow-docker-image-deploy:
|
||||
needs: generate-build-number
|
||||
runs-on: ubuntu-latest
|
||||
@@ -269,65 +329,6 @@ jobs:
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
link-shortener-docker-image-deploy:
|
||||
needs: generate-build-number
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Docker Meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
oneuptime/link-shortener
|
||||
ghcr.io/oneuptime/link-shortener
|
||||
tags: |
|
||||
type=raw,value=release,enable=true
|
||||
type=semver,value=7.0.${{needs.generate-build-number.outputs.build_number}},pattern={{version}},enable=true
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Generate Dockerfile from Dockerfile.tpl
|
||||
run: npm run prerun
|
||||
|
||||
# Build and deploy link-shortener.
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
file: ./LinkShortener/Dockerfile
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
build-args: |
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
workers-docker-image-deploy:
|
||||
needs: generate-build-number
|
||||
@@ -509,7 +510,7 @@ jobs:
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
realtime-docker-image-deploy:
|
||||
ingestor-docker-image-deploy:
|
||||
needs: generate-build-number
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -518,8 +519,8 @@ jobs:
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
oneuptime/realtime
|
||||
ghcr.io/oneuptime/realtime
|
||||
oneuptime/ingestor
|
||||
ghcr.io/oneuptime/ingestor
|
||||
tags: |
|
||||
type=raw,value=release,enable=true
|
||||
type=semver,value=7.0.${{needs.generate-build-number.outputs.build_number}},pattern={{version}},enable=true
|
||||
@@ -541,7 +542,7 @@ jobs:
|
||||
- name: Generate Dockerfile from Dockerfile.tpl
|
||||
run: npm run prerun
|
||||
|
||||
# Build and deploy realtime.
|
||||
# Build and deploy ingestor.
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2.2.0
|
||||
@@ -559,247 +560,7 @@ jobs:
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
file: ./Realtime/Dockerfile
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
build-args: |
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
probe-api-docker-image-deploy:
|
||||
needs: generate-build-number
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Docker Meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
oneuptime/probe-api
|
||||
ghcr.io/oneuptime/probe-api
|
||||
tags: |
|
||||
type=raw,value=release,enable=true
|
||||
type=semver,value=7.0.${{needs.generate-build-number.outputs.build_number}},pattern={{version}},enable=true
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Generate Dockerfile from Dockerfile.tpl
|
||||
run: npm run prerun
|
||||
|
||||
# Build and deploy probe-api.
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
file: ./ProbeAPI/Dockerfile
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
build-args: |
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
notification-docker-image-deploy:
|
||||
needs: generate-build-number
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Docker Meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
oneuptime/notification
|
||||
ghcr.io/oneuptime/notification
|
||||
tags: |
|
||||
type=raw,value=release,enable=true
|
||||
type=semver,value=7.0.${{needs.generate-build-number.outputs.build_number}},pattern={{version}},enable=true
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Generate Dockerfile from Dockerfile.tpl
|
||||
run: npm run prerun
|
||||
|
||||
# Build and deploy notification.
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
file: ./Notification/Dockerfile
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
build-args: |
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
licensing-docker-image-deploy:
|
||||
needs: generate-build-number
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Docker Meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
oneuptime/licensing
|
||||
ghcr.io/oneuptime/licensing
|
||||
tags: |
|
||||
type=raw,value=release,enable=true
|
||||
type=semver,value=7.0.${{needs.generate-build-number.outputs.build_number}},pattern={{version}},enable=true
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Generate Dockerfile from Dockerfile.tpl
|
||||
run: npm run prerun
|
||||
|
||||
# Build and deploy licensing.
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
file: ./Licensing/Dockerfile
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
build-args: |
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
integrations-docker-image-deploy:
|
||||
needs: generate-build-number
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Docker Meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
oneuptime/integrations
|
||||
ghcr.io/oneuptime/integrations
|
||||
tags: |
|
||||
type=raw,value=release,enable=true
|
||||
type=semver,value=7.0.${{needs.generate-build-number.outputs.build_number}},pattern={{version}},enable=true
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Generate Dockerfile from Dockerfile.tpl
|
||||
run: npm run prerun
|
||||
|
||||
# Build and deploy integrations.
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
file: ./Integration/Dockerfile
|
||||
file: ./Ingestor/Dockerfile
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
@@ -869,65 +630,6 @@ jobs:
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
identity-docker-image-deploy:
|
||||
needs: generate-build-number
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Docker Meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
oneuptime/identity
|
||||
ghcr.io/oneuptime/identity
|
||||
tags: |
|
||||
type=raw,value=release,enable=true
|
||||
type=semver,value=7.0.${{needs.generate-build-number.outputs.build_number}},pattern={{version}},enable=true
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Generate Dockerfile from Dockerfile.tpl
|
||||
run: npm run prerun
|
||||
|
||||
# Build and deploy identity.
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
file: ./Identity/Dockerfile
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
build-args: |
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
home-docker-image-deploy:
|
||||
needs: generate-build-number
|
||||
@@ -1050,67 +752,6 @@ jobs:
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
file-docker-image-deploy:
|
||||
needs: generate-build-number
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Docker Meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
oneuptime/file
|
||||
ghcr.io/oneuptime/file
|
||||
tags: |
|
||||
type=raw,value=release,enable=true
|
||||
type=semver,value=7.0.${{needs.generate-build-number.outputs.build_number}},pattern={{version}},enable=true
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Generate Dockerfile from Dockerfile.tpl
|
||||
run: npm run prerun
|
||||
|
||||
# Build and deploy file.
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
file: ./File/Dockerfile
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
build-args: |
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
|
||||
admin-dashboard-docker-image-deploy:
|
||||
needs: generate-build-number
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
388
.github/workflows/test-release.yaml
vendored
388
.github/workflows/test-release.yaml
vendored
@@ -202,7 +202,9 @@ jobs:
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
link-shortener-docker-image-deploy:
|
||||
|
||||
|
||||
otel-collector-docker-image-deploy:
|
||||
needs: generate-build-number
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -211,8 +213,8 @@ jobs:
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
oneuptime/link-shortener
|
||||
ghcr.io/oneuptime/link-shortener
|
||||
oneuptime/otel-collector
|
||||
ghcr.io/oneuptime/otel-collector
|
||||
tags: |
|
||||
type=raw,value=test,enable=true
|
||||
type=semver,value=7.0.${{needs.generate-build-number.outputs.build_number}}-test,pattern={{version}},enable=true
|
||||
@@ -235,7 +237,7 @@ jobs:
|
||||
- name: Generate Dockerfile from Dockerfile.tpl
|
||||
run: npm run prerun
|
||||
|
||||
# Build and deploy link-shortener.
|
||||
# Build and deploy otel-collector.
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2.2.0
|
||||
@@ -253,7 +255,7 @@ jobs:
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
file: ./LinkShortener/Dockerfile
|
||||
file: ./OTelCollector/Dockerfile
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
@@ -448,7 +450,7 @@ jobs:
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
realtime-docker-image-deploy:
|
||||
ingestor-docker-image-deploy:
|
||||
needs: generate-build-number
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -457,8 +459,8 @@ jobs:
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
oneuptime/realtime
|
||||
ghcr.io/oneuptime/realtime
|
||||
oneuptime/ingestor
|
||||
ghcr.io/oneuptime/ingestor
|
||||
tags: |
|
||||
type=raw,value=test,enable=true
|
||||
type=semver,value=7.0.${{needs.generate-build-number.outputs.build_number}}-test,pattern={{version}},enable=true
|
||||
@@ -481,7 +483,7 @@ jobs:
|
||||
- name: Generate Dockerfile from Dockerfile.tpl
|
||||
run: npm run prerun
|
||||
|
||||
# Build and deploy realtime.
|
||||
# Build and deploy ingestor.
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2.2.0
|
||||
@@ -499,251 +501,7 @@ jobs:
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
file: ./Realtime/Dockerfile
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
build-args: |
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
probe-api-docker-image-deploy:
|
||||
needs: generate-build-number
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Docker Meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
oneuptime/probe-api
|
||||
ghcr.io/oneuptime/probe-api
|
||||
tags: |
|
||||
type=raw,value=test,enable=true
|
||||
type=semver,value=7.0.${{needs.generate-build-number.outputs.build_number}}-test,pattern={{version}},enable=true
|
||||
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Generate Dockerfile from Dockerfile.tpl
|
||||
run: npm run prerun
|
||||
|
||||
# Build and deploy probe-api.
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
file: ./ProbeAPI/Dockerfile
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
build-args: |
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
notification-docker-image-deploy:
|
||||
needs: generate-build-number
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Docker Meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
oneuptime/notification
|
||||
ghcr.io/oneuptime/notification
|
||||
tags: |
|
||||
type=raw,value=test,enable=true
|
||||
type=semver,value=7.0.${{needs.generate-build-number.outputs.build_number}}-test,pattern={{version}},enable=true
|
||||
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Generate Dockerfile from Dockerfile.tpl
|
||||
run: npm run prerun
|
||||
|
||||
# Build and deploy notification.
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
file: ./Notification/Dockerfile
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
build-args: |
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
licensing-docker-image-deploy:
|
||||
needs: generate-build-number
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Docker Meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
oneuptime/licensing
|
||||
ghcr.io/oneuptime/licensing
|
||||
tags: |
|
||||
type=raw,value=test,enable=true
|
||||
type=semver,value=7.0.${{needs.generate-build-number.outputs.build_number}}-test,pattern={{version}},enable=true
|
||||
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Generate Dockerfile from Dockerfile.tpl
|
||||
run: npm run prerun
|
||||
|
||||
# Build and deploy licensing.
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
file: ./Licensing/Dockerfile
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
build-args: |
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
integrations-docker-image-deploy:
|
||||
needs: generate-build-number
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Docker Meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
oneuptime/integrations
|
||||
ghcr.io/oneuptime/integrations
|
||||
tags: |
|
||||
type=raw,value=test,enable=true
|
||||
type=semver,value=7.0.${{needs.generate-build-number.outputs.build_number}}-test,pattern={{version}},enable=true
|
||||
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Generate Dockerfile from Dockerfile.tpl
|
||||
run: npm run prerun
|
||||
|
||||
# Build and deploy integrations.
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
file: ./Integration/Dockerfile
|
||||
file: ./Ingestor/Dockerfile
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
@@ -814,67 +572,6 @@ jobs:
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
identity-docker-image-deploy:
|
||||
needs: generate-build-number
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Docker Meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
oneuptime/identity
|
||||
ghcr.io/oneuptime/identity
|
||||
tags: |
|
||||
type=raw,value=test,enable=true
|
||||
type=semver,value=7.0.${{needs.generate-build-number.outputs.build_number}}-test,pattern={{version}},enable=true
|
||||
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Generate Dockerfile from Dockerfile.tpl
|
||||
run: npm run prerun
|
||||
|
||||
# Build and deploy identity.
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
file: ./Identity/Dockerfile
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
build-args: |
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
home-docker-image-deploy:
|
||||
needs: generate-build-number
|
||||
runs-on: ubuntu-latest
|
||||
@@ -998,67 +695,6 @@ jobs:
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
file-docker-image-deploy:
|
||||
needs: generate-build-number
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Docker Meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
oneuptime/file
|
||||
ghcr.io/oneuptime/file
|
||||
tags: |
|
||||
type=raw,value=test,enable=true
|
||||
type=semver,value=7.0.${{needs.generate-build-number.outputs.build_number}}-test,pattern={{version}},enable=true
|
||||
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Generate Dockerfile from Dockerfile.tpl
|
||||
run: npm run prerun
|
||||
|
||||
# Build and deploy file.
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
file: ./File/Dockerfile
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
build-args: |
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
dashboard-docker-image-deploy:
|
||||
needs: generate-build-number
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
3
.github/workflows/test.common-server.yaml
vendored
3
.github/workflows/test.common-server.yaml
vendored
@@ -19,5 +19,6 @@ jobs:
|
||||
node-version: 18.3.0
|
||||
- run: cd Common && npm install
|
||||
- run: cd Model && npm install
|
||||
- run: cd CommonServer && npm install
|
||||
- run: cd CommonServer && bash test-setup.sh
|
||||
- run: export $(grep -v '^#' config.env | xargs) && cd CommonServer && npm install && npm run test
|
||||
- run: export $(grep -v '^#' config.env | xargs) && cd CommonServer && rm -rf build && npm run test
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Probe Api Test
|
||||
name: Ingestor Test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
@@ -17,5 +17,5 @@ jobs:
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.3.0
|
||||
- run: cd ProbeAPI && npm install && npm run test
|
||||
- run: cd Ingestor && npm install && npm run test
|
||||
|
||||
5
.github/workflows/test.probe.yaml
vendored
5
.github/workflows/test.probe.yaml
vendored
@@ -9,7 +9,7 @@ on:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: self-hosted # this needs to be self-hosted because ICMP checks are disbled in hosted runners
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
steps:
|
||||
@@ -19,5 +19,6 @@ jobs:
|
||||
node-version: 18.3.0
|
||||
- run: cd Common && npm install
|
||||
- run: cd CommonServer && npm install
|
||||
- run: cd Probe && npm install && npm run test
|
||||
- run: cd Probe && npm install
|
||||
- run: cd Probe && npm run test
|
||||
|
||||
9
.gitignore
vendored
9
.gitignore
vendored
@@ -13,7 +13,7 @@ node_modules
|
||||
|
||||
.idea
|
||||
# testing
|
||||
/coverage
|
||||
**/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
@@ -92,3 +92,10 @@ Haraka/dkim/keys/public_base64.txt
|
||||
.eslintcache
|
||||
|
||||
HelmChart/Values/*.values.yaml
|
||||
|
||||
Llama/Models/tokenizer*
|
||||
Llama/Models/llama*
|
||||
|
||||
Llama/__pycache__/*
|
||||
|
||||
Examples/otel-dotnet/obj
|
||||
117
.vscode/launch.json
vendored
117
.vscode/launch.json
vendored
@@ -55,20 +55,6 @@
|
||||
"restart": true,
|
||||
"autoAttachChildProcesses": true
|
||||
},
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"localRoot": "${workspaceFolder}/LinkShortener",
|
||||
"name": "Link Shortener: Debug with Docker",
|
||||
"port": 9826,
|
||||
"remoteRoot": "/usr/src/app",
|
||||
"request": "attach",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"type": "node",
|
||||
"restart": true,
|
||||
"autoAttachChildProcesses": true
|
||||
},
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"localRoot": "${workspaceFolder}/TestServer",
|
||||
@@ -99,8 +85,8 @@
|
||||
},
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"localRoot": "${workspaceFolder}/ProbeAPI",
|
||||
"name": "Probe API: Debug with Docker",
|
||||
"localRoot": "${workspaceFolder}/Ingestor",
|
||||
"name": "Ingestor: Debug with Docker",
|
||||
"port": 9932,
|
||||
"remoteRoot": "/usr/src/app",
|
||||
"request": "attach",
|
||||
@@ -125,34 +111,6 @@
|
||||
"restart": true,
|
||||
"autoAttachChildProcesses": true
|
||||
},
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"localRoot": "${workspaceFolder}/data-ingestor",
|
||||
"name": "Data Ingestor: Debug with Docker",
|
||||
"port": 9338,
|
||||
"remoteRoot": "/usr/src/app",
|
||||
"request": "attach",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"type": "node",
|
||||
"restart": true,
|
||||
"autoAttachChildProcesses": true
|
||||
},
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"localRoot": "${workspaceFolder}/Notification",
|
||||
"name": "Notification: Debug with Docker",
|
||||
"port": 9111,
|
||||
"remoteRoot": "/usr/src/app",
|
||||
"request": "attach",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"type": "node",
|
||||
"restart": true,
|
||||
"autoAttachChildProcesses": true
|
||||
},
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"localRoot": "${workspaceFolder}/Realtime",
|
||||
@@ -197,7 +155,7 @@
|
||||
},
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"localRoot": "${workspaceFolder}/ProbeAPI",
|
||||
"localRoot": "${workspaceFolder}/Ingestor",
|
||||
"name": "Probe API: Debug with Docker",
|
||||
"port": 9251,
|
||||
"remoteRoot": "/usr/src/app",
|
||||
@@ -209,20 +167,6 @@
|
||||
"restart": true,
|
||||
"autoAttachChildProcesses": true
|
||||
},
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"localRoot": "${workspaceFolder}/Identity",
|
||||
"name": "Identity: Debug with Docker",
|
||||
"port": 9132,
|
||||
"remoteRoot": "/usr/src/app",
|
||||
"request": "attach",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"type": "node",
|
||||
"restart": true,
|
||||
"autoAttachChildProcesses": true
|
||||
},
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"localRoot": "${workspaceFolder}/Identity",
|
||||
@@ -237,48 +181,6 @@
|
||||
"restart": true,
|
||||
"autoAttachChildProcesses": true
|
||||
},
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"localRoot": "${workspaceFolder}/Alert",
|
||||
"name": "Alert: Debug with Docker",
|
||||
"port": 9133,
|
||||
"remoteRoot": "/usr/src/app",
|
||||
"request": "attach",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"type": "node",
|
||||
"restart": true,
|
||||
"autoAttachChildProcesses": true
|
||||
},
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"localRoot": "${workspaceFolder}/Alert",
|
||||
"name": "Integration: Debug with Docker",
|
||||
"port": 9134,
|
||||
"remoteRoot": "/usr/src/app",
|
||||
"request": "attach",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"type": "node",
|
||||
"restart": true,
|
||||
"autoAttachChildProcesses": true
|
||||
},
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"localRoot": "${workspaceFolder}/licensing",
|
||||
"name": "Licensing: Debug with Docker",
|
||||
"port": 9233,
|
||||
"remoteRoot": "/usr/src/app",
|
||||
"request": "attach",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"type": "node",
|
||||
"restart": true,
|
||||
"autoAttachChildProcesses": true
|
||||
},
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"localRoot": "${workspaceFolder}/HttpTestServer",
|
||||
@@ -348,6 +250,19 @@
|
||||
"debug:test"
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Probe: Debug Tests",
|
||||
"type": "node",
|
||||
"restart": true,
|
||||
"autoAttachChildProcesses": true,
|
||||
"request": "launch",
|
||||
"cwd": "${workspaceRoot}/Probe",
|
||||
"runtimeExecutable": "npm",
|
||||
"runtimeArgs": [
|
||||
"run-script",
|
||||
"debug:test"
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Accounts: Debug Local Files",
|
||||
"type": "node",
|
||||
|
||||
35
Accounts/Dockerfile.tpl
Executable file → Normal file
35
Accounts/Dockerfile.tpl
Executable file → Normal file
@@ -3,12 +3,10 @@
|
||||
#
|
||||
|
||||
# Pull base image nodejs image.
|
||||
FROM node:current-alpine AS base
|
||||
FROM node:21.2-alpine3.18
|
||||
USER root
|
||||
RUN mkdir /tmp/npm && chmod 2777 /tmp/npm && chown 1000:1000 /tmp/npm && npm config set cache /tmp/npm --global
|
||||
|
||||
RUN npm config set fetch-retry-maxtimeout 6000000
|
||||
RUN npm config set fetch-retry-mintimeout 1000000
|
||||
|
||||
ARG GIT_SHA
|
||||
ARG APP_VERSION
|
||||
@@ -26,9 +24,6 @@ SHELL ["/bin/bash", "-c"]
|
||||
|
||||
RUN mkdir /usr/src
|
||||
|
||||
# Install common
|
||||
|
||||
FROM base AS common
|
||||
WORKDIR /usr/src/Common
|
||||
COPY ./Common/package*.json /usr/src/Common/
|
||||
RUN npm install
|
||||
@@ -36,9 +31,6 @@ COPY ./Common /usr/src/Common
|
||||
|
||||
|
||||
|
||||
# Install Model
|
||||
|
||||
FROM base AS model
|
||||
WORKDIR /usr/src/Model
|
||||
COPY ./Model/package*.json /usr/src/Model/
|
||||
RUN npm install
|
||||
@@ -46,9 +38,6 @@ COPY ./Model /usr/src/Model
|
||||
|
||||
|
||||
|
||||
# Install CommonServer
|
||||
|
||||
FROM base AS commonserver
|
||||
WORKDIR /usr/src/CommonServer
|
||||
COPY ./CommonServer/package*.json /usr/src/CommonServer/
|
||||
RUN npm install
|
||||
@@ -59,7 +48,6 @@ COPY ./CommonServer /usr/src/CommonServer
|
||||
|
||||
# Install CommonUI
|
||||
|
||||
FROM base AS commonui
|
||||
WORKDIR /usr/src/CommonUI
|
||||
COPY ./CommonUI/package*.json /usr/src/CommonUI/
|
||||
RUN npm install --force
|
||||
@@ -67,22 +55,6 @@ COPY ./CommonUI /usr/src/CommonUI
|
||||
|
||||
|
||||
|
||||
#SET ENV Variables
|
||||
# Install app
|
||||
FROM base AS app
|
||||
|
||||
WORKDIR /usr/src/Common
|
||||
COPY --from=common /usr/src/Common .
|
||||
|
||||
WORKDIR /usr/src/Model
|
||||
COPY --from=model /usr/src/Model .
|
||||
|
||||
WORKDIR /usr/src/CommonServer
|
||||
COPY --from=commonserver /usr/src/CommonServer .
|
||||
|
||||
WORKDIR /usr/src/CommonUI
|
||||
COPY --from=commonui /usr/src/CommonUI .
|
||||
|
||||
|
||||
ENV PRODUCTION=true
|
||||
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
|
||||
@@ -97,17 +69,20 @@ RUN npm install
|
||||
# - 3003: accounts
|
||||
EXPOSE 3003
|
||||
|
||||
|
||||
RUN npm i -D webpack-cli
|
||||
|
||||
{{ if eq .Env.ENVIRONMENT "development" }}
|
||||
RUN mkdir /usr/src/app/dev-env
|
||||
RUN touch /usr/src/app/dev-env/.env
|
||||
RUN npm i -D webpack-dev-server
|
||||
|
||||
#Run the app
|
||||
CMD [ "npm", "run", "dev" ]
|
||||
{{ else }}
|
||||
# Copy app source
|
||||
COPY ./Accounts /usr/src/app
|
||||
# Bundle app source
|
||||
|
||||
RUN npm run build
|
||||
#Run the app
|
||||
CMD [ "npm", "start" ]
|
||||
|
||||
@@ -14,11 +14,13 @@ const init: () => Promise<void> = async (): Promise<void> => {
|
||||
} catch (err) {
|
||||
logger.error('App Init Failed:');
|
||||
logger.error(err);
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
init().catch((err: Error) => {
|
||||
logger.error(err);
|
||||
logger.info('Exiting node process');
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
|
||||
25902
Accounts/package-lock.json
generated
25902
Accounts/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -2,31 +2,16 @@
|
||||
"name": "accounts",
|
||||
"version": "0.1.0",
|
||||
"private": false,
|
||||
"dependencies": {
|
||||
"Common": "file:../Common",
|
||||
"CommonServer": "file:../CommonServer",
|
||||
"CommonUI": "file:../CommonUI",
|
||||
"crypto-js": "^4.1.1",
|
||||
"formik": "^2.2.9",
|
||||
"Model": "file:../Model",
|
||||
"react": "^18.1.0",
|
||||
"react-dom": "^18.1.0",
|
||||
"react-router": "^6.3.0",
|
||||
"react-router-dom": "^6.3.0",
|
||||
"react-scripts": "5.0.1",
|
||||
"the-new-css-reset": "^1.7.3",
|
||||
"typescript": "^4.6.4",
|
||||
"use-async-effect": "^2.2.7"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "npx nodemon",
|
||||
"build": "webpack build --mode=production",
|
||||
"test": "",
|
||||
"compile": "tsc",
|
||||
"clear-modules": "rm -rf node_modules && rm package-lock.json && npm install",
|
||||
"start": "node --require ts-node/register Serve.ts",
|
||||
"audit": "npm audit --audit-level=low",
|
||||
"configure": "npx npm-force-resolutions || echo 'No package-lock.json file. Skipping force resolutions'",
|
||||
"dep-check": "depcheck ./ --skip-missing=true'"
|
||||
"dep-check": "npm install -g depcheck && depcheck ./ --skip-missing=true"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
@@ -40,27 +25,30 @@
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"Common": "file:../Common",
|
||||
"CommonServer": "file:../CommonServer",
|
||||
"CommonUI": "file:../CommonUI",
|
||||
"css-loader": "^6.8.1",
|
||||
"dotenv": "^16.3.1",
|
||||
"express": "^4.18.2",
|
||||
"file-loader": "^6.2.0",
|
||||
"Model": "file:../Model",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.1.0",
|
||||
"react-router-dom": "^6.18.0",
|
||||
"sass-loader": "^13.3.2",
|
||||
"style-loader": "^3.3.3",
|
||||
"ts-loader": "^9.5.1",
|
||||
"use-async-effect": "^2.2.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/jest-dom": "^5.16.4",
|
||||
"@testing-library/react": "^13.2.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"@types/jest": "^27.5.1",
|
||||
"@types/node": "^16.11.35",
|
||||
"@types/react": "^18.0.9",
|
||||
"@types/react": "^18.2.38",
|
||||
"@types/react-dom": "^18.0.4",
|
||||
"@types/react-router-dom": "^5.3.3",
|
||||
"css-loader": "^6.7.1",
|
||||
"customize-cra": "^1.0.0",
|
||||
"dotenv-webpack": "^7.1.0",
|
||||
"nodemon": "^2.0.20",
|
||||
"process": "0.11.10",
|
||||
"react-app-rewired": "^2.2.1",
|
||||
"sass": "^1.51.0",
|
||||
"sass-loader": "^12.6.0",
|
||||
"ts-loader": "^9.3.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"webpack": "^5.76.0",
|
||||
"webpack-cli": "^4.9.2",
|
||||
"webpack-dev-server": "^4.9.0"
|
||||
"webpack": "^5.76.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ const ForgotPassword: () => JSX.Element = () => {
|
||||
modelType={User}
|
||||
name="Forgot Password"
|
||||
id="login-form"
|
||||
apiUrl={apiUrl}
|
||||
createOrUpdateApiUrl={apiUrl}
|
||||
fields={[
|
||||
{
|
||||
field: {
|
||||
|
||||
@@ -87,7 +87,7 @@ const LoginPage: () => JSX.Element = () => {
|
||||
},
|
||||
},
|
||||
]}
|
||||
apiUrl={apiUrl}
|
||||
createOrUpdateApiUrl={apiUrl}
|
||||
formType={FormType.Create}
|
||||
submitButtonText={'Login'}
|
||||
onSuccess={(
|
||||
@@ -107,7 +107,7 @@ const LoginPage: () => JSX.Element = () => {
|
||||
maxPrimaryButtonWidth={true}
|
||||
footer={
|
||||
<div className="actions pointer text-center mt-4 hover:underline fw-semibold">
|
||||
<p>
|
||||
<div>
|
||||
{!showSsoTip && (
|
||||
<div
|
||||
onClick={() => {
|
||||
@@ -128,13 +128,13 @@ const LoginPage: () => JSX.Element = () => {
|
||||
your project.
|
||||
</div>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-10 text-center">
|
||||
<p className="text-muted mb-0 text-gray-500">
|
||||
<div className="text-muted mb-0 text-gray-500">
|
||||
Don't have an account?{' '}
|
||||
<Link
|
||||
to={new Route('/accounts/register')}
|
||||
@@ -142,7 +142,7 @@ const LoginPage: () => JSX.Element = () => {
|
||||
>
|
||||
Register.
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -47,19 +47,19 @@ const RegisterPage: () => JSX.Element = () => {
|
||||
|
||||
try {
|
||||
const reseller: ListResult<Reseller> =
|
||||
await ModelAPI.getList<Reseller>(
|
||||
Reseller,
|
||||
{
|
||||
await ModelAPI.getList<Reseller>({
|
||||
modelType: Reseller,
|
||||
query: {
|
||||
resellerId: resellerId,
|
||||
},
|
||||
1,
|
||||
0,
|
||||
{
|
||||
limit: 1,
|
||||
skip: 0,
|
||||
select: {
|
||||
hidePhoneNumberOnSignup: true,
|
||||
},
|
||||
{},
|
||||
{}
|
||||
);
|
||||
sort: {},
|
||||
requestOptions: {},
|
||||
});
|
||||
|
||||
if (reseller.data.length > 0) {
|
||||
setResller(reseller.data[0]);
|
||||
@@ -167,7 +167,7 @@ const RegisterPage: () => JSX.Element = () => {
|
||||
title: 'Confirm Password',
|
||||
overrideFieldKey: 'confirmPassword',
|
||||
required: true,
|
||||
forceShow: true,
|
||||
showEvenIfPermissionDoesNotExist: true,
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -209,7 +209,7 @@ const RegisterPage: () => JSX.Element = () => {
|
||||
initialValues={initialValues}
|
||||
maxPrimaryButtonWidth={true}
|
||||
fields={formFields}
|
||||
apiUrl={apiUrl}
|
||||
createOrUpdateApiUrl={apiUrl}
|
||||
onBeforeCreate={(item: User): Promise<User> => {
|
||||
const utmParams: Dictionary<string> =
|
||||
UserUtil.getUtmParams();
|
||||
|
||||
@@ -85,7 +85,7 @@ const RegisterPage: () => JSX.Element = () => {
|
||||
required: true,
|
||||
},
|
||||
]}
|
||||
apiUrl={apiUrl}
|
||||
createOrUpdateApiUrl={apiUrl}
|
||||
formType={FormType.Create}
|
||||
submitButtonText={'Reset Password'}
|
||||
onSuccess={() => {
|
||||
|
||||
@@ -30,15 +30,15 @@ const VerifyEmail: () => JSX.Element = () => {
|
||||
Navigation.getLastParam()?.toString().replace('/', '') || ''
|
||||
);
|
||||
|
||||
await ModelAPI.createOrUpdate<EmailVerificationToken>(
|
||||
emailverificationToken,
|
||||
EmailVerificationToken,
|
||||
FormType.Create,
|
||||
{},
|
||||
{
|
||||
await ModelAPI.createOrUpdate<EmailVerificationToken>({
|
||||
model: emailverificationToken,
|
||||
modelType: EmailVerificationToken,
|
||||
formType: FormType.Create,
|
||||
miscDataProps: {},
|
||||
requestOptions: {
|
||||
overrideRequestUrl: apiUrl,
|
||||
}
|
||||
);
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
setError(API.getFriendlyMessage(err));
|
||||
}
|
||||
|
||||
@@ -6,24 +6,25 @@ import Name from 'Common/Types/Name';
|
||||
import { DASHBOARD_URL } from 'CommonUI/src/Config';
|
||||
import { JSONObject } from 'Common/Types/JSON';
|
||||
import User from 'Model/Models/User';
|
||||
import JSONFunctions from 'Common/Types/JSONFunctions';
|
||||
import Analytics from 'CommonUI/src/Utils/Analytics';
|
||||
import BaseModel from 'Common/Models/BaseModel';
|
||||
|
||||
export default abstract class LoginUtil {
|
||||
public static login(value: JSONObject): void {
|
||||
const user: User = JSONFunctions.fromJSON(
|
||||
const user: User = BaseModel.fromJSON(
|
||||
value['user'] as JSONObject,
|
||||
User
|
||||
) as User;
|
||||
|
||||
const token: string = value['token'] as string;
|
||||
|
||||
UserUtil.setAccessToken(token);
|
||||
UserUtil.setEmail(user.email as Email);
|
||||
UserUtil.setUserId(user.id as ObjectID);
|
||||
UserUtil.setName(user.name || new Name(''));
|
||||
UserUtil.setIsMasterAdmin(user.isMasterAdmin as boolean);
|
||||
|
||||
if (user.profilePictureId) {
|
||||
UserUtil.setProfilePicId(user.profilePictureId);
|
||||
}
|
||||
|
||||
Analytics.userAuth(user.email!);
|
||||
|
||||
// go to dashboard, user should be logged in.
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
},
|
||||
"compilerOptions": {
|
||||
/* Visit https://aka.ms/tsconfig.json to read more about this file */
|
||||
|
||||
/* Projects */
|
||||
// "incremental": true, /* Enable incremental compilation */
|
||||
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
||||
@@ -15,43 +16,47 @@
|
||||
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */
|
||||
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
||||
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
||||
|
||||
/* Language and Environment */
|
||||
"target": "es2017" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
|
||||
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
||||
"jsx": "react" /* Specify what JSX code is generated. */,
|
||||
"experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
|
||||
"emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
||||
"experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
|
||||
"emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
||||
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */
|
||||
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
||||
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */
|
||||
// "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */
|
||||
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
||||
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
||||
|
||||
/* Modules */
|
||||
"module": "es2022" /* Specify what module code is generated. */,
|
||||
// "rootDir": "./", /* Specify the root folder within your source files. */
|
||||
"moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
|
||||
"moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
|
||||
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
||||
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
||||
"typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */
|
||||
"types": [
|
||||
"node"
|
||||
], /* Specify type package names to be included without being referenced in a source file. */
|
||||
"typeRoots": [
|
||||
"./node_modules/@types"
|
||||
], /* Specify multiple folders that act like `./node_modules/@types`. */
|
||||
"types": ["node"], /* Specify type package names to be included without being referenced in a source file. */
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
// "resolveJsonModule": true, /* Enable importing .json files */
|
||||
// "noResolve": true, /* Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project. */
|
||||
|
||||
/* JavaScript Support */
|
||||
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */
|
||||
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
|
||||
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */
|
||||
|
||||
/* Emit */
|
||||
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
||||
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
||||
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
||||
"sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
||||
"sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
||||
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */
|
||||
"outDir": "./build/dist", /* Specify an output folder for all emitted files. */
|
||||
"outDir": "./build/dist", /* Specify an output folder for all emitted files. */
|
||||
// "removeComments": true, /* Disable emitting comments. */
|
||||
// "noEmit": true, /* Disable emitting files from a compilation. */
|
||||
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
||||
@@ -69,34 +74,37 @@
|
||||
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
|
||||
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
||||
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
|
||||
|
||||
/* Interop Constraints */
|
||||
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
|
||||
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */,
|
||||
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
||||
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
|
||||
|
||||
/* Type Checking */
|
||||
"strict": true /* Enable all strict type-checking options. */,
|
||||
"noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */
|
||||
"strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */
|
||||
"strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
||||
"strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */
|
||||
"strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
||||
"noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */
|
||||
"useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
|
||||
"alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
|
||||
"noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */
|
||||
"noUnusedParameters": true, /* Raise an error when a function parameter isn't read */
|
||||
"exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
||||
"noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
||||
"noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
||||
"noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
|
||||
"noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
||||
"noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */
|
||||
"noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */
|
||||
"strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */
|
||||
"strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
||||
"strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */
|
||||
"strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
||||
"noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */
|
||||
"useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
|
||||
"alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
|
||||
"noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */
|
||||
"noUnusedParameters": true, /* Raise an error when a function parameter isn't read */
|
||||
"exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
||||
"noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
||||
"noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
||||
"noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
|
||||
"noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
||||
"noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */
|
||||
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
||||
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
||||
|
||||
/* Completeness */
|
||||
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
||||
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
require('ts-loader');
|
||||
require('file-loader');
|
||||
require('style-loader');
|
||||
require('css-loader');
|
||||
require('sass-loader');
|
||||
const path = require("path");
|
||||
const webpack = require("webpack");
|
||||
const dotenv = require('dotenv');
|
||||
|
||||
33
AdminDashboard/Dockerfile.tpl
Executable file → Normal file
33
AdminDashboard/Dockerfile.tpl
Executable file → Normal file
@@ -3,12 +3,10 @@
|
||||
#
|
||||
|
||||
# Pull base image nodejs image.
|
||||
FROM node:current-alpine AS base
|
||||
FROM node:21.2-alpine3.18
|
||||
USER root
|
||||
RUN mkdir /tmp/npm && chmod 2777 /tmp/npm && chown 1000:1000 /tmp/npm && npm config set cache /tmp/npm --global
|
||||
|
||||
RUN npm config set fetch-retry-maxtimeout 6000000
|
||||
RUN npm config set fetch-retry-mintimeout 1000000
|
||||
|
||||
ARG GIT_SHA
|
||||
ARG APP_VERSION
|
||||
@@ -26,18 +24,12 @@ SHELL ["/bin/bash", "-c"]
|
||||
|
||||
RUN mkdir /usr/src
|
||||
|
||||
# Install common
|
||||
|
||||
FROM base AS common
|
||||
WORKDIR /usr/src/Common
|
||||
COPY ./Common/package*.json /usr/src/Common/
|
||||
RUN npm install
|
||||
COPY ./Common /usr/src/Common
|
||||
|
||||
|
||||
# Install Model
|
||||
|
||||
FROM base AS model
|
||||
WORKDIR /usr/src/Model
|
||||
COPY ./Model/package*.json /usr/src/Model/
|
||||
RUN npm install
|
||||
@@ -45,9 +37,6 @@ COPY ./Model /usr/src/Model
|
||||
|
||||
|
||||
|
||||
# Install CommonServer
|
||||
|
||||
FROM base AS commonserver
|
||||
WORKDIR /usr/src/CommonServer
|
||||
COPY ./CommonServer/package*.json /usr/src/CommonServer/
|
||||
RUN npm install
|
||||
@@ -58,29 +47,12 @@ COPY ./CommonServer /usr/src/CommonServer
|
||||
|
||||
# Install CommonUI
|
||||
|
||||
FROM base AS commonui
|
||||
WORKDIR /usr/src/CommonUI
|
||||
COPY ./CommonUI/package*.json /usr/src/CommonUI/
|
||||
RUN npm install --force
|
||||
COPY ./CommonUI /usr/src/CommonUI
|
||||
|
||||
|
||||
#SET ENV Variables
|
||||
# Install app
|
||||
FROM base AS app
|
||||
|
||||
WORKDIR /usr/src/Common
|
||||
COPY --from=common /usr/src/Common .
|
||||
|
||||
WORKDIR /usr/src/Model
|
||||
COPY --from=model /usr/src/Model .
|
||||
|
||||
WORKDIR /usr/src/CommonServer
|
||||
COPY --from=commonserver /usr/src/CommonServer .
|
||||
|
||||
WORKDIR /usr/src/CommonUI
|
||||
COPY --from=commonui /usr/src/CommonUI .
|
||||
|
||||
|
||||
ENV PRODUCTION=true
|
||||
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
|
||||
@@ -95,10 +67,13 @@ RUN npm install
|
||||
# - 3158: AdminDashboard
|
||||
EXPOSE 3158
|
||||
|
||||
RUN npm i -D webpack-cli
|
||||
|
||||
{{ if eq .Env.ENVIRONMENT "development" }}
|
||||
#Run the app
|
||||
RUN mkdir /usr/src/app/dev-env
|
||||
RUN touch /usr/src/app/dev-env/.env
|
||||
RUN npm i -D webpack-dev-server
|
||||
CMD [ "npm", "run", "dev" ]
|
||||
{{ else }}
|
||||
# Copy app source
|
||||
|
||||
@@ -13,11 +13,13 @@ const init: () => Promise<void> = async (): Promise<void> => {
|
||||
} catch (err) {
|
||||
logger.error('App Init Failed:');
|
||||
logger.error(err);
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
init().catch((err: Error) => {
|
||||
logger.error(err);
|
||||
logger.info('Exiting node process');
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
|
||||
24002
AdminDashboard/package-lock.json
generated
24002
AdminDashboard/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -3,26 +3,16 @@
|
||||
"version": "0.1.0",
|
||||
"private": false,
|
||||
"dependencies": {
|
||||
"@headlessui/react": "^1.7.7",
|
||||
"@heroicons/react": "^2.0.13",
|
||||
"@stripe/react-stripe-js": "^1.15.0",
|
||||
"@stripe/stripe-js": "^1.44.1",
|
||||
"Common": "file:../Common",
|
||||
"CommonServer": "file:../CommonServer",
|
||||
"CommonUI": "file:../CommonUI",
|
||||
"dotenv": "^16.3.1",
|
||||
"file-loader": "^6.2.0",
|
||||
"Model": "file:../Model",
|
||||
"react": "^18.1.0",
|
||||
"react-dnd": "^16.0.1",
|
||||
"react-dnd-html5-backend": "^16.0.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.1.0",
|
||||
"react-icons": "^4.4.0",
|
||||
"react-router": "^6.3.0",
|
||||
"react-router-dom": "^6.3.0",
|
||||
"reactflow": "^11.5.3",
|
||||
"stripe": "^11.0.0",
|
||||
"the-new-css-reset": "^1.7.3",
|
||||
"typescript": "^4.6.4",
|
||||
"use-async-effect": "^2.2.6"
|
||||
"react-router-dom": "^6.18.0",
|
||||
"style-loader": "^3.3.3"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "npx nodemon",
|
||||
@@ -30,10 +20,11 @@
|
||||
"test": "react-app-rewired test",
|
||||
"eject": "webpack eject",
|
||||
"compile": "tsc",
|
||||
"clear-modules": "rm -rf node_modules && rm package-lock.json && npm install",
|
||||
"start": "node --require ts-node/register Serve.ts",
|
||||
"audit": "npm audit --audit-level=low",
|
||||
"configure": "npx npm-force-resolutions || echo 'No package-lock.json file. Skipping force resolutions'",
|
||||
"dep-check": "depcheck ./ --skip-missing=true'"
|
||||
"dep-check": "npm install -g depcheck && depcheck ./ --skip-missing=true"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
@@ -48,24 +39,17 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/jest-dom": "^5.16.4",
|
||||
"@testing-library/react": "^13.2.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"@types/jest": "^27.5.1",
|
||||
"@types/node": "^16.11.35",
|
||||
"@types/react": "^18.0.9",
|
||||
"@types/react": "^18.2.38",
|
||||
"@types/react-dom": "^18.0.4",
|
||||
"@types/react-router-dom": "^5.3.3",
|
||||
"css-loader": "^6.7.1",
|
||||
"customize-cra": "^1.0.0",
|
||||
"css-loader": "^6.8.1",
|
||||
"nodemon": "^2.0.20",
|
||||
"react-app-rewired": "^2.2.1",
|
||||
"sass": "^1.51.0",
|
||||
"sass-loader": "^12.6.0",
|
||||
"ts-loader": "^9.3.0",
|
||||
"ts-loader": "^9.5.1",
|
||||
"ts-node": "^10.9.1",
|
||||
"webpack": "^5.76.0",
|
||||
"webpack-cli": "^4.9.2",
|
||||
"webpack-dev-server": "^4.9.0"
|
||||
"webpack": "^5.76.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,14 +34,6 @@ const DashboardFooter: () => JSX.Element = () => {
|
||||
name: 'Dashboard',
|
||||
path: '/dashboard',
|
||||
},
|
||||
{
|
||||
name: 'Notification',
|
||||
path: '/notification',
|
||||
},
|
||||
{
|
||||
name: 'Identity Service',
|
||||
path: '/identity',
|
||||
},
|
||||
];
|
||||
|
||||
for (const app of apps) {
|
||||
|
||||
@@ -14,7 +14,7 @@ import ProjectUtil from 'CommonUI/src/Utils/Project';
|
||||
import { BILLING_ENABLED, getAllEnvVars } from 'CommonUI/src/Config';
|
||||
import SubscriptionPlan from 'Common/Types/Billing/SubscriptionPlan';
|
||||
import Field from 'CommonUI/src/Components/Forms/Types/Field';
|
||||
import { RadioButton } from 'CommonUI/src/Components/RadioButtons/RadioButtons';
|
||||
import { RadioButton } from 'CommonUI/src/Components/RadioButtons/GroupRadioButtons';
|
||||
import Toggle from 'CommonUI/src/Components/Toggle/Toggle';
|
||||
|
||||
export interface ComponentProps {
|
||||
|
||||
@@ -9,12 +9,21 @@ import UserUtil from 'CommonUI/src/Utils/User';
|
||||
import Navigation from 'CommonUI/src/Utils/Navigation';
|
||||
import { ACCOUNTS_URL } from 'CommonUI/src/Config';
|
||||
import UiAnalytics from 'CommonUI/src/Utils/Analytics';
|
||||
import ErrorMessage from 'CommonUI/src/Components/ErrorMessage/ErrorMessage';
|
||||
|
||||
const Logout: FunctionComponent = (): ReactElement => {
|
||||
useEffect(() => {
|
||||
const [error, setError] = React.useState<string | null>(null);
|
||||
|
||||
const logout: Function = async () => {
|
||||
UiAnalytics.logout();
|
||||
UserUtil.logout();
|
||||
await UserUtil.logout();
|
||||
Navigation.navigate(ACCOUNTS_URL);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
logout().catch((error: Error) => {
|
||||
setError(error.message || error.toString());
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
@@ -35,7 +44,8 @@ const Logout: FunctionComponent = (): ReactElement => {
|
||||
},
|
||||
]}
|
||||
>
|
||||
<PageLoader isVisible={true} />
|
||||
{!error ? <PageLoader isVisible={true} /> : <></>}
|
||||
{error ? <ErrorMessage error={error} /> : <></>}
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -17,7 +17,7 @@ import User from 'Model/Models/User';
|
||||
import { BILLING_ENABLED, getAllEnvVars } from 'CommonUI/src/Config';
|
||||
import Field from 'CommonUI/src/Components/Forms/Types/Field';
|
||||
import SubscriptionPlan from 'Common/Types/Billing/SubscriptionPlan';
|
||||
import { RadioButton } from 'CommonUI/src/Components/RadioButtons/RadioButtons';
|
||||
import { RadioButton } from 'CommonUI/src/Components/RadioButtons/GroupRadioButtons';
|
||||
import Toggle from 'CommonUI/src/Components/Toggle/Toggle';
|
||||
import AdminModelAPI from '../../Utils/ModelAPI';
|
||||
|
||||
|
||||
@@ -187,6 +187,7 @@ const Settings: FunctionComponent = (): ReactElement => {
|
||||
<Statusbubble
|
||||
text={'Connected'}
|
||||
color={Green}
|
||||
shouldAnimate={true}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -195,6 +196,7 @@ const Settings: FunctionComponent = (): ReactElement => {
|
||||
<Statusbubble
|
||||
text={'Disconnected'}
|
||||
color={Red}
|
||||
shouldAnimate={false}
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
||||
@@ -29,14 +29,14 @@ const Settings: FunctionComponent = (): ReactElement => {
|
||||
setIsLoading(true);
|
||||
|
||||
const globalConfig: GlobalConfig | null =
|
||||
await ModelAPI.getItem<GlobalConfig>(
|
||||
GlobalConfig,
|
||||
ObjectID.getZeroObjectID(),
|
||||
{
|
||||
await ModelAPI.getItem<GlobalConfig>({
|
||||
modelType: GlobalConfig,
|
||||
id: ObjectID.getZeroObjectID(),
|
||||
select: {
|
||||
_id: true,
|
||||
emailServerType: true,
|
||||
}
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
if (globalConfig) {
|
||||
setemailServerType(
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
||||
"typeRoots": [
|
||||
|
||||
"./node_modules/@types"
|
||||
], /* Specify multiple folders that act like `./node_modules/@types`. */
|
||||
"types": ["node"], /* Specify type package names to be included without being referenced in a source file. */
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
require('ts-loader');
|
||||
require('file-loader');
|
||||
require('style-loader');
|
||||
require('css-loader');
|
||||
require('sass-loader');
|
||||
const path = require("path");
|
||||
const webpack = require("webpack");
|
||||
const dotenv = require('dotenv');
|
||||
|
||||
22
ApiReference/Dockerfile.tpl
Executable file → Normal file
22
ApiReference/Dockerfile.tpl
Executable file → Normal file
@@ -1,10 +1,8 @@
|
||||
# Pull base image nodejs image.
|
||||
FROM node:current-alpine AS base
|
||||
FROM node:21.2-alpine3.18
|
||||
USER root
|
||||
RUN mkdir /tmp/npm && chmod 2777 /tmp/npm && chown 1000:1000 /tmp/npm && npm config set cache /tmp/npm --global
|
||||
|
||||
RUN npm config set fetch-retry-maxtimeout 6000000
|
||||
RUN npm config set fetch-retry-mintimeout 1000000
|
||||
|
||||
ARG GIT_SHA
|
||||
ARG APP_VERSION
|
||||
@@ -22,18 +20,12 @@ SHELL ["/bin/bash", "-c"]
|
||||
|
||||
RUN mkdir /usr/src
|
||||
|
||||
# Install common
|
||||
|
||||
FROM base AS common
|
||||
WORKDIR /usr/src/Common
|
||||
COPY ./Common/package*.json /usr/src/Common/
|
||||
RUN npm install
|
||||
COPY ./Common /usr/src/Common
|
||||
|
||||
|
||||
# Install Model
|
||||
|
||||
FROM base AS model
|
||||
WORKDIR /usr/src/Model
|
||||
COPY ./Model/package*.json /usr/src/Model/
|
||||
RUN npm install
|
||||
@@ -41,9 +33,6 @@ COPY ./Model /usr/src/Model
|
||||
|
||||
|
||||
|
||||
# Install CommonServer
|
||||
|
||||
FROM base AS commonserver
|
||||
WORKDIR /usr/src/CommonServer
|
||||
COPY ./CommonServer/package*.json /usr/src/CommonServer/
|
||||
RUN npm install
|
||||
@@ -52,16 +41,7 @@ COPY ./CommonServer /usr/src/CommonServer
|
||||
|
||||
|
||||
# Install app
|
||||
FROM base AS app
|
||||
|
||||
WORKDIR /usr/src/Common
|
||||
COPY --from=common /usr/src/Common .
|
||||
|
||||
WORKDIR /usr/src/Model
|
||||
COPY --from=model /usr/src/Model .
|
||||
|
||||
WORKDIR /usr/src/CommonServer
|
||||
COPY --from=commonserver /usr/src/CommonServer .
|
||||
|
||||
|
||||
ENV PRODUCTION=true
|
||||
|
||||
@@ -93,11 +93,13 @@ const init: () => Promise<void> = async (): Promise<void> => {
|
||||
} catch (err) {
|
||||
logger.error('App Init Failed:');
|
||||
logger.error(err);
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
init().catch((err: Error) => {
|
||||
logger.error(err);
|
||||
logger.info('Exiting node process');
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ColumnAccessControl } from 'Common/Types/Database/AccessControl/AccessControl';
|
||||
import { ColumnAccessControl } from 'Common/Types/BaseDatabase/AccessControl';
|
||||
import { getTableColumns } from 'Common/Types/Database/TableColumn';
|
||||
import Dictionary from 'Common/Types/Dictionary';
|
||||
import ObjectID from 'Common/Types/ObjectID';
|
||||
|
||||
11027
ApiReference/package-lock.json
generated
11027
ApiReference/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
32
ApiReference/package.json
Executable file → Normal file
32
ApiReference/package.json
Executable file → Normal file
@@ -5,51 +5,33 @@
|
||||
"configure": "npx npm-force-resolutions || echo 'No package-lock.json file. Skipping force resolutions'",
|
||||
"start": "node --require ts-node/register Index.ts",
|
||||
"compile": "tsc",
|
||||
"clear-modules": "rm -rf node_modules && rm package-lock.json && npm install",
|
||||
"dev": "npx nodemon",
|
||||
"test": "jest",
|
||||
"test": "jest --detectOpenHandles",
|
||||
"coverage": "jest --detectOpenHandles --coverage",
|
||||
"lighthouse-test": "jest --forceExit lighthouse-tests/test/index.test.js --env=node",
|
||||
"lighthouse": "start-server-and-test http://localhost:1444",
|
||||
"smoketest": "jest --forceExit smoketest/index.test.js --env=node",
|
||||
"audit": "npm audit --audit-level=low",
|
||||
"light-house": "node lighthouse.js --web",
|
||||
"light-house-mobile": "node lighthouse.js --mobile",
|
||||
"dep-check": "depcheck ./ --skip-missing=true --ignores='ejs,puppeteer'"
|
||||
"dep-check": "npm install -g depcheck && depcheck ./ --skip-missing=true"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/body-parser": "^1.19.2",
|
||||
"@types/cli-table": "^0.3.0",
|
||||
"@types/compression": "^1.7.2",
|
||||
"@types/ejs": "^3.1.1",
|
||||
"@types/minify": "^8.0.0",
|
||||
"@types/try-to-catch": "^3.0.0",
|
||||
"axios": "^0.26.1",
|
||||
"body-parser": "^1.19.2",
|
||||
"cli-table": "^0.3.11",
|
||||
"Common": "file:../Common",
|
||||
"CommonServer": "file:../CommonServer",
|
||||
"compression": "^1.7.4",
|
||||
"ejs": "^3.1.8",
|
||||
"express": "^4.18.1",
|
||||
"Model": "file:../Model",
|
||||
"ts-node": "^10.9.1",
|
||||
"xmlbuilder2": "^3.0.2"
|
||||
"ts-node": "^10.9.1"
|
||||
},
|
||||
"resolutions": {},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^27.5.1",
|
||||
"@types/node": "^17.0.22",
|
||||
"chrome-launcher": "^0.15.0",
|
||||
"commander": "^9.1.0",
|
||||
"depcheck": "^1.4.3",
|
||||
"jest": "^28.1.0",
|
||||
"lighthouse": "^9.5.0",
|
||||
"nodemon": "^2.0.20",
|
||||
"npm-force-resolutions": "0.0.10",
|
||||
"ora": "^6.1.0",
|
||||
|
||||
"start-server-and-test": "^1.14.0",
|
||||
"ts-jest": "^28.0.2",
|
||||
"ts-node-dev": "^1.1.8",
|
||||
"typescript": "^4.6.4"
|
||||
"typescript": "^5.3.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
42
Clickhouse/Docs/ClickhouseOps.md
Normal file
42
Clickhouse/Docs/ClickhouseOps.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# Some basic commands for Clickhouse
|
||||
|
||||
## Show tables in the database
|
||||
|
||||
```sql
|
||||
show tables from oneuptime
|
||||
```
|
||||
|
||||
## Show table structure
|
||||
|
||||
```sql
|
||||
DESCRIBE TABLE oneuptime.Span
|
||||
```
|
||||
|
||||
## Show table data
|
||||
|
||||
```sql
|
||||
select * from table_name
|
||||
```
|
||||
|
||||
## Delete table data
|
||||
|
||||
```sql
|
||||
truncate table_name
|
||||
```
|
||||
|
||||
## Delete table
|
||||
|
||||
```sql
|
||||
drop table oneuptime.table_name
|
||||
```
|
||||
|
||||
## Insert for nested data
|
||||
|
||||
```sql
|
||||
INSERT INTO opentelemetry_spans (trace_id, span_id, attributes.key, attributes.value) VALUES
|
||||
('trace1', 'span1', ['key1', 'key2'], ['value1', 'value2']),
|
||||
('trace2', 'span2', ['keyA', 'keyB'], ['valueA', 'valueB']);
|
||||
```
|
||||
|
||||
|
||||
|
||||
293
Common/AnalyticsModels/BaseModel.ts
Normal file
293
Common/AnalyticsModels/BaseModel.ts
Normal file
@@ -0,0 +1,293 @@
|
||||
import TableColumnType from '../Types/AnalyticsDatabase/TableColumnType';
|
||||
import AnalyticsTableColumn from '../Types/AnalyticsDatabase/TableColumn';
|
||||
import BadDataException from '../Types/Exception/BadDataException';
|
||||
import AnalyticsTableEngine from '../Types/AnalyticsDatabase/AnalyticsTableEngine';
|
||||
import ColumnBillingAccessControl from '../Types/BaseDatabase/ColumnBillingAccessControl';
|
||||
import TableBillingAccessControl from '../Types/BaseDatabase/TableBillingAccessControl';
|
||||
import { TableAccessControl } from '../Types/BaseDatabase/AccessControl';
|
||||
import EnableWorkflowOn from '../Types/BaseDatabase/EnableWorkflowOn';
|
||||
import ObjectID from '../Types/ObjectID';
|
||||
import CommonModel from './CommonModel';
|
||||
import Route from '../Types/API/Route';
|
||||
import { EnableRealtimeEventsOn } from '../Utils/Realtime';
|
||||
|
||||
export default class AnalyticsBaseModel extends CommonModel {
|
||||
public constructor(data: {
|
||||
tableName: string;
|
||||
singularName: string;
|
||||
pluralName: string;
|
||||
tableEngine?: AnalyticsTableEngine | undefined;
|
||||
tableColumns: Array<AnalyticsTableColumn>;
|
||||
crudApiPath: Route;
|
||||
allowAccessIfSubscriptionIsUnpaid?: boolean | undefined;
|
||||
tableBillingAccessControl?: TableBillingAccessControl | undefined;
|
||||
accessControl?: TableAccessControl | undefined;
|
||||
primaryKeys: Array<string>; // this should be the subset of tableColumns
|
||||
enableWorkflowOn?: EnableWorkflowOn | undefined;
|
||||
enableRealtimeEventsOn?: EnableRealtimeEventsOn | undefined;
|
||||
}) {
|
||||
super({
|
||||
tableColumns: data.tableColumns,
|
||||
});
|
||||
const columns: Array<AnalyticsTableColumn> = [...data.tableColumns];
|
||||
|
||||
this.tableName = data.tableName;
|
||||
|
||||
if (data.tableEngine) {
|
||||
this.tableEngine = data.tableEngine;
|
||||
}
|
||||
|
||||
columns.push(
|
||||
new AnalyticsTableColumn({
|
||||
key: '_id',
|
||||
title: 'ID',
|
||||
description: 'ID of this object',
|
||||
required: true,
|
||||
type: TableColumnType.ObjectID,
|
||||
})
|
||||
);
|
||||
|
||||
columns.push(
|
||||
new AnalyticsTableColumn({
|
||||
key: 'createdAt',
|
||||
title: 'Created',
|
||||
description: 'Date and Time when the object was created.',
|
||||
required: true,
|
||||
type: TableColumnType.Date,
|
||||
})
|
||||
);
|
||||
|
||||
columns.push(
|
||||
new AnalyticsTableColumn({
|
||||
key: 'updatedAt',
|
||||
title: 'Updated',
|
||||
description: 'Date and Time when the object was updated.',
|
||||
required: true,
|
||||
type: TableColumnType.Date,
|
||||
})
|
||||
);
|
||||
|
||||
if (!data.primaryKeys || data.primaryKeys.length === 0) {
|
||||
throw new BadDataException('Primary keys are required');
|
||||
}
|
||||
|
||||
// check if primary keys are subset of tableColumns
|
||||
|
||||
data.primaryKeys.forEach((primaryKey: string) => {
|
||||
const column: AnalyticsTableColumn | undefined = columns.find(
|
||||
(column: AnalyticsTableColumn) => {
|
||||
return column.key === primaryKey;
|
||||
}
|
||||
);
|
||||
|
||||
if (!column) {
|
||||
throw new BadDataException(
|
||||
'Primary key ' + primaryKey + ' is not part of tableColumns'
|
||||
);
|
||||
}
|
||||
|
||||
if (!column.required) {
|
||||
throw new BadDataException(
|
||||
'Primary key ' +
|
||||
primaryKey +
|
||||
' is not required. Primary keys must be required.'
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
this.primaryKeys = data.primaryKeys;
|
||||
this.tableColumns = columns;
|
||||
this.singularName = data.singularName;
|
||||
this.pluralName = data.pluralName;
|
||||
this.tableBillingAccessControl = data.tableBillingAccessControl;
|
||||
this.allowAccessIfSubscriptionIsUnpaid =
|
||||
data.allowAccessIfSubscriptionIsUnpaid || false;
|
||||
this.accessControl = data.accessControl;
|
||||
this.enableWorkflowOn = data.enableWorkflowOn;
|
||||
this.crudApiPath = data.crudApiPath;
|
||||
this.enableRealtimeEventsOn = data.enableRealtimeEventsOn;
|
||||
|
||||
// initialize Arrays.
|
||||
for (const column of this.tableColumns) {
|
||||
if (column.type === TableColumnType.NestedModel) {
|
||||
this.setColumnValue(column.key, []);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private _enableWorkflowOn: EnableWorkflowOn | undefined;
|
||||
public get enableWorkflowOn(): EnableWorkflowOn | undefined {
|
||||
return this._enableWorkflowOn;
|
||||
}
|
||||
public set enableWorkflowOn(v: EnableWorkflowOn | undefined) {
|
||||
this._enableWorkflowOn = v;
|
||||
}
|
||||
|
||||
private _accessControl: TableAccessControl | undefined;
|
||||
public get accessControl(): TableAccessControl | undefined {
|
||||
return this._accessControl;
|
||||
}
|
||||
public set accessControl(v: TableAccessControl | undefined) {
|
||||
this._accessControl = v;
|
||||
}
|
||||
|
||||
private _tableName: string = '';
|
||||
public get tableName(): string {
|
||||
return this._tableName;
|
||||
}
|
||||
public set tableName(v: string) {
|
||||
this._tableName = v;
|
||||
}
|
||||
|
||||
private _tableEngine: AnalyticsTableEngine = AnalyticsTableEngine.MergeTree;
|
||||
public get tableEngine(): AnalyticsTableEngine {
|
||||
return this._tableEngine;
|
||||
}
|
||||
public set tableEngine(v: AnalyticsTableEngine) {
|
||||
this._tableEngine = v;
|
||||
}
|
||||
|
||||
private _enableRealtimeEventsOn: EnableRealtimeEventsOn | undefined;
|
||||
public get enableRealtimeEventsOn(): EnableRealtimeEventsOn | undefined {
|
||||
return this._enableRealtimeEventsOn;
|
||||
}
|
||||
public set enableRealtimeEventsOn(v: EnableRealtimeEventsOn | undefined) {
|
||||
this._enableRealtimeEventsOn = v;
|
||||
}
|
||||
|
||||
private _primaryKeys: Array<string> = [];
|
||||
public get primaryKeys(): Array<string> {
|
||||
return this._primaryKeys;
|
||||
}
|
||||
public set primaryKeys(v: Array<string>) {
|
||||
this._primaryKeys = v;
|
||||
}
|
||||
|
||||
private _singularName: string = '';
|
||||
public get singularName(): string {
|
||||
return this._singularName;
|
||||
}
|
||||
public set singularName(v: string) {
|
||||
this._singularName = v;
|
||||
}
|
||||
|
||||
private _pluralName: string = '';
|
||||
public get pluralName(): string {
|
||||
return this._pluralName;
|
||||
}
|
||||
public set pluralName(v: string) {
|
||||
this._pluralName = v;
|
||||
}
|
||||
|
||||
private _tableBillingAccessControl: TableBillingAccessControl | undefined;
|
||||
public get tableBillingAccessControl():
|
||||
| TableBillingAccessControl
|
||||
| undefined {
|
||||
return this._tableBillingAccessControl;
|
||||
}
|
||||
public set tableBillingAccessControl(
|
||||
v: TableBillingAccessControl | undefined
|
||||
) {
|
||||
this._tableBillingAccessControl = v;
|
||||
}
|
||||
|
||||
private _allowAccessIfSubscriptionIsUnpaid: boolean = false;
|
||||
public get allowAccessIfSubscriptionIsUnpaid(): boolean {
|
||||
return this._allowAccessIfSubscriptionIsUnpaid;
|
||||
}
|
||||
public set allowAccessIfSubscriptionIsUnpaid(v: boolean) {
|
||||
this._allowAccessIfSubscriptionIsUnpaid = v;
|
||||
}
|
||||
|
||||
private _crudApiPath!: Route;
|
||||
public get crudApiPath(): Route {
|
||||
return this._crudApiPath;
|
||||
}
|
||||
public set crudApiPath(v: Route) {
|
||||
this._crudApiPath = v;
|
||||
}
|
||||
|
||||
public getTenantColumn(): AnalyticsTableColumn | null {
|
||||
const column: AnalyticsTableColumn | undefined = this.tableColumns.find(
|
||||
(column: AnalyticsTableColumn) => {
|
||||
return column.isTenantId;
|
||||
}
|
||||
);
|
||||
|
||||
if (!column) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return column;
|
||||
}
|
||||
|
||||
public getTenantColumnValue(): ObjectID | null {
|
||||
const column: AnalyticsTableColumn | null = this.getTenantColumn();
|
||||
|
||||
if (!column) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.getColumnValue(column.key) as ObjectID | null;
|
||||
}
|
||||
|
||||
public getRequiredColumns(): Array<AnalyticsTableColumn> {
|
||||
return this.tableColumns.filter((column: AnalyticsTableColumn) => {
|
||||
return column.required;
|
||||
});
|
||||
}
|
||||
|
||||
public isDefaultValueColumn(columnName: string): boolean {
|
||||
const column: AnalyticsTableColumn | null =
|
||||
this.getTableColumn(columnName);
|
||||
|
||||
if (!column) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return column.isDefaultValueColumn;
|
||||
}
|
||||
|
||||
public getColumnBillingAccessControl(
|
||||
columnName: string
|
||||
): ColumnBillingAccessControl | null {
|
||||
const column: AnalyticsTableColumn | null =
|
||||
this.getTableColumn(columnName);
|
||||
|
||||
if (!column) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return column.billingAccessControl || null;
|
||||
}
|
||||
|
||||
public get id(): ObjectID | undefined {
|
||||
return this.getColumnValue('_id') as ObjectID | undefined;
|
||||
}
|
||||
public set id(v: ObjectID | undefined) {
|
||||
this.setColumnValue('_id', v);
|
||||
}
|
||||
|
||||
public get _id(): ObjectID | undefined {
|
||||
return this.getColumnValue('_id') as ObjectID | undefined;
|
||||
}
|
||||
public set _id(v: ObjectID | undefined) {
|
||||
this.setColumnValue('_id', v);
|
||||
}
|
||||
|
||||
public get createdAt(): Date | undefined {
|
||||
return this.getColumnValue('createdAt') as Date | undefined;
|
||||
}
|
||||
|
||||
public set createdAt(v: Date | undefined) {
|
||||
this.setColumnValue('createdAt', v);
|
||||
}
|
||||
|
||||
public get updatedAt(): Date | undefined {
|
||||
return this.getColumnValue('updatedAt') as Date | undefined;
|
||||
}
|
||||
|
||||
public set updatedAt(v: Date | undefined) {
|
||||
this.setColumnValue('updatedAt', v);
|
||||
}
|
||||
}
|
||||
218
Common/AnalyticsModels/CommonModel.ts
Normal file
218
Common/AnalyticsModels/CommonModel.ts
Normal file
@@ -0,0 +1,218 @@
|
||||
// This model will be extended by BaseModel and Nested Mdoel
|
||||
|
||||
import AnalyticsTableColumn from '../Types/AnalyticsDatabase/TableColumn';
|
||||
import TableColumnType from '../Types/AnalyticsDatabase/TableColumnType';
|
||||
import OneUptimeDate from '../Types/Date';
|
||||
import BadDataException from '../Types/Exception/BadDataException';
|
||||
import { JSONArray, JSONObject, JSONValue } from '../Types/JSON';
|
||||
import JSONFunctions from '../Types/JSONFunctions';
|
||||
import ObjectID from '../Types/ObjectID';
|
||||
|
||||
export type RecordValue =
|
||||
| ObjectID
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| Date
|
||||
| Array<number>
|
||||
| Array<string>
|
||||
| Array<CommonModel>;
|
||||
|
||||
export type Record = Array<RecordValue | Record>;
|
||||
|
||||
export default class CommonModel {
|
||||
protected data: JSONObject = {};
|
||||
|
||||
private _tableColumns: Array<AnalyticsTableColumn> = [];
|
||||
public get tableColumns(): Array<AnalyticsTableColumn> {
|
||||
return this._tableColumns;
|
||||
}
|
||||
public set tableColumns(v: Array<AnalyticsTableColumn>) {
|
||||
this._tableColumns = v;
|
||||
}
|
||||
|
||||
public setColumnValue(
|
||||
columnName: string,
|
||||
value: JSONValue | Array<CommonModel>
|
||||
): void {
|
||||
const column: AnalyticsTableColumn | null =
|
||||
this.getTableColumn(columnName);
|
||||
|
||||
if (column) {
|
||||
if (
|
||||
column.type === TableColumnType.ObjectID &&
|
||||
typeof value === 'string'
|
||||
) {
|
||||
value = new ObjectID(value);
|
||||
}
|
||||
|
||||
if (
|
||||
column.type === TableColumnType.Date &&
|
||||
typeof value === 'string'
|
||||
) {
|
||||
value = OneUptimeDate.fromString(value);
|
||||
}
|
||||
|
||||
if (
|
||||
column.type === TableColumnType.JSON &&
|
||||
typeof value === 'string'
|
||||
) {
|
||||
value = JSON.parse(value);
|
||||
}
|
||||
|
||||
if (
|
||||
column.type === TableColumnType.Number &&
|
||||
typeof value === 'string'
|
||||
) {
|
||||
value = parseInt(value);
|
||||
}
|
||||
|
||||
// decimal
|
||||
if (
|
||||
column.type === TableColumnType.Decimal &&
|
||||
typeof value === 'string'
|
||||
) {
|
||||
value = parseFloat(value);
|
||||
}
|
||||
|
||||
return (this.data[columnName] = value as any);
|
||||
}
|
||||
throw new BadDataException('Column ' + columnName + ' does not exist');
|
||||
}
|
||||
|
||||
public constructor(data: { tableColumns: Array<AnalyticsTableColumn> }) {
|
||||
this.tableColumns = data.tableColumns;
|
||||
}
|
||||
|
||||
public getColumnValue<T extends RecordValue>(
|
||||
columnName: string
|
||||
): T | undefined {
|
||||
if (this.getTableColumn(columnName)) {
|
||||
return this.data[columnName] as T;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public getTableColumn(name: string): AnalyticsTableColumn | null {
|
||||
const column: AnalyticsTableColumn | undefined = this.tableColumns.find(
|
||||
(column: AnalyticsTableColumn) => {
|
||||
return column.key === name;
|
||||
}
|
||||
);
|
||||
|
||||
if (!column) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return column;
|
||||
}
|
||||
|
||||
public getTableColumns(): Array<AnalyticsTableColumn> {
|
||||
return this.tableColumns;
|
||||
}
|
||||
|
||||
public static fromJSON<T extends CommonModel>(
|
||||
json: JSONObject | JSONArray | CommonModel | Array<CommonModel>,
|
||||
type: { new (): T }
|
||||
): T | Array<T> {
|
||||
if (Array.isArray(json)) {
|
||||
const arr: Array<T> = [];
|
||||
|
||||
for (const item of json) {
|
||||
if (item instanceof CommonModel) {
|
||||
arr.push(item as T);
|
||||
continue;
|
||||
}
|
||||
|
||||
arr.push(new type().fromJSON(item) as T);
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
if (json instanceof CommonModel) {
|
||||
return json as T;
|
||||
}
|
||||
|
||||
return new type().fromJSON(json) as T;
|
||||
}
|
||||
|
||||
public static toJSON<T extends CommonModel>(
|
||||
model: T,
|
||||
_modelType: { new (): T }
|
||||
): JSONObject {
|
||||
return model.toJSON();
|
||||
}
|
||||
|
||||
public fromJSON(json: JSONObject): CommonModel {
|
||||
for (const key in json) {
|
||||
this.setColumnValue(key, json[key]);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public toJSON(): JSONObject {
|
||||
const json: JSONObject = {};
|
||||
|
||||
this.tableColumns.forEach((column: AnalyticsTableColumn) => {
|
||||
const recordValue: RecordValue | undefined = this.getColumnValue(
|
||||
column.key
|
||||
);
|
||||
|
||||
if (recordValue instanceof CommonModel) {
|
||||
json[column.key] = recordValue.toJSON();
|
||||
return;
|
||||
}
|
||||
|
||||
if (recordValue instanceof Array) {
|
||||
if (recordValue.length > 0 && column.nestedModelType) {
|
||||
json[column.key] = CommonModel.toJSONArray(
|
||||
recordValue as Array<CommonModel>,
|
||||
column.nestedModelType
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
json[column.key] = recordValue;
|
||||
});
|
||||
|
||||
return JSONFunctions.serialize(json);
|
||||
}
|
||||
|
||||
public static fromJSONArray<TBaseModel extends CommonModel>(
|
||||
jsonArray: Array<JSONObject | CommonModel>,
|
||||
modelType: { new (): CommonModel }
|
||||
): Array<TBaseModel> {
|
||||
const models: Array<CommonModel> = [];
|
||||
|
||||
jsonArray.forEach((json: JSONObject | CommonModel) => {
|
||||
if (json instanceof CommonModel) {
|
||||
models.push(json);
|
||||
return;
|
||||
}
|
||||
|
||||
const model: CommonModel = new modelType();
|
||||
model.fromJSON(json);
|
||||
models.push(model);
|
||||
});
|
||||
|
||||
return models as Array<TBaseModel>;
|
||||
}
|
||||
|
||||
public static toJSONArray(
|
||||
models: Array<CommonModel>,
|
||||
modelType: { new (): CommonModel }
|
||||
): Array<JSONObject> {
|
||||
const json: Array<JSONObject> = [];
|
||||
|
||||
models.forEach((model: CommonModel) => {
|
||||
json.push(this.toJSON(model, modelType));
|
||||
});
|
||||
|
||||
return json;
|
||||
}
|
||||
}
|
||||
8
Common/AnalyticsModels/NestedModel.ts
Normal file
8
Common/AnalyticsModels/NestedModel.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import AnalyticsTableColumn from '../Types/AnalyticsDatabase/TableColumn';
|
||||
import CommonModel from './CommonModel';
|
||||
|
||||
export default class NestedModel extends CommonModel {
|
||||
public constructor(data: { tableColumns: Array<AnalyticsTableColumn> }) {
|
||||
super(data);
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
import TableColumnType from '../Types/BaseDatabase/TableColumnType';
|
||||
import AnalyticsTableColumn from '../Types/AnalyticsDatabase/TableColumn';
|
||||
import BadDataException from '../Types/Exception/BadDataException';
|
||||
import AnalyticsTableEngine from '../Types/AnalyticsDatabase/AnalyticsTableEngine';
|
||||
|
||||
export default class AnalyticsDataModel {
|
||||
private _tableColumns: Array<AnalyticsTableColumn> = [];
|
||||
public get tableColumns(): Array<AnalyticsTableColumn> {
|
||||
return this._tableColumns;
|
||||
}
|
||||
public set tableColumns(v: Array<AnalyticsTableColumn>) {
|
||||
this._tableColumns = v;
|
||||
}
|
||||
|
||||
private _tableName: string = '';
|
||||
public get tableName(): string {
|
||||
return this._tableName;
|
||||
}
|
||||
public set tableName(v: string) {
|
||||
this._tableName = v;
|
||||
}
|
||||
|
||||
private _tableEngine: AnalyticsTableEngine = AnalyticsTableEngine.MergeTree;
|
||||
public get tableEngine(): AnalyticsTableEngine {
|
||||
return this._tableEngine;
|
||||
}
|
||||
public set tableEngine(v: AnalyticsTableEngine) {
|
||||
this._tableEngine = v;
|
||||
}
|
||||
|
||||
private _primaryKeys: Array<string> = [];
|
||||
public get primaryKeys(): Array<string> {
|
||||
return this._primaryKeys;
|
||||
}
|
||||
public set primaryKeys(v: Array<string>) {
|
||||
this._primaryKeys = v;
|
||||
}
|
||||
|
||||
public constructor(data: {
|
||||
tableName: string;
|
||||
tableEngine?: AnalyticsTableEngine | undefined;
|
||||
tableColumns: Array<AnalyticsTableColumn>;
|
||||
primaryKeys: Array<string>; // this should be the subset of tableColumns
|
||||
}) {
|
||||
const columns: Array<AnalyticsTableColumn> = [...data.tableColumns];
|
||||
|
||||
this.tableName = data.tableName;
|
||||
|
||||
if (data.tableEngine) {
|
||||
this.tableEngine = data.tableEngine;
|
||||
}
|
||||
|
||||
columns.push(
|
||||
new AnalyticsTableColumn({
|
||||
key: '_id',
|
||||
title: 'ID',
|
||||
description: 'ID of this object',
|
||||
required: true,
|
||||
type: TableColumnType.ObjectID,
|
||||
})
|
||||
);
|
||||
|
||||
columns.push(
|
||||
new AnalyticsTableColumn({
|
||||
key: 'createdAt',
|
||||
title: 'Created',
|
||||
description: 'Date and Time when the object was created.',
|
||||
required: true,
|
||||
type: TableColumnType.Date,
|
||||
})
|
||||
);
|
||||
|
||||
columns.push(
|
||||
new AnalyticsTableColumn({
|
||||
key: 'updatedAt',
|
||||
title: 'Updated',
|
||||
description: 'Date and Time when the object was updated.',
|
||||
required: true,
|
||||
type: TableColumnType.Date,
|
||||
})
|
||||
);
|
||||
|
||||
if (!data.primaryKeys || data.primaryKeys.length === 0) {
|
||||
throw new BadDataException('Primary keys are required');
|
||||
}
|
||||
|
||||
// check if primary keys are subset of tableColumns
|
||||
|
||||
data.primaryKeys.forEach((primaryKey: string) => {
|
||||
if (
|
||||
!columns.find((column: AnalyticsTableColumn) => {
|
||||
return column.key === primaryKey;
|
||||
})
|
||||
) {
|
||||
throw new BadDataException(
|
||||
'Primary key ' + primaryKey + ' is not part of tableColumns'
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
this.primaryKeys = data.primaryKeys;
|
||||
this.tableColumns = columns;
|
||||
}
|
||||
}
|
||||
@@ -21,24 +21,23 @@ import Email from '../Types/Email';
|
||||
import Phone from '../Types/Phone';
|
||||
import PositiveNumber from '../Types/PositiveNumber';
|
||||
import Route from '../Types/API/Route';
|
||||
import TableColumnType from '../Types/BaseDatabase/TableColumnType';
|
||||
import TableColumnType from '../Types/Database/TableColumnType';
|
||||
import Permission, {
|
||||
instanceOfUserTenantAccessPermission,
|
||||
PermissionHelper,
|
||||
UserPermission,
|
||||
UserTenantAccessPermission,
|
||||
} from '../Types/Permission';
|
||||
import {
|
||||
ColumnAccessControl,
|
||||
ColumnBillingAccessControl,
|
||||
} from '../Types/Database/AccessControl/AccessControl';
|
||||
import { ColumnAccessControl } from '../Types/BaseDatabase/AccessControl';
|
||||
import { getColumnAccessControlForAllColumns } from '../Types/Database/AccessControl/ColumnAccessControl';
|
||||
import BadDataException from '../Types/Exception/BadDataException';
|
||||
import { PlanSelect } from '../Types/Billing/SubscriptionPlan';
|
||||
import { EnableWorkflowOn } from '../Types/Model/EnableWorkflow';
|
||||
import EnableWorkflowOn from '../Types/BaseDatabase/EnableWorkflowOn';
|
||||
import IconProp from '../Types/Icon/IconProp';
|
||||
import Text from '../Types/Text';
|
||||
import { getColumnBillingAccessControlForAllColumns } from '../Types/Database/AccessControl/ColumnBillingAccessControl';
|
||||
import ColumnBillingAccessControl from '../Types/BaseDatabase/ColumnBillingAccessControl';
|
||||
import JSONFunctions from '../Types/JSONFunctions';
|
||||
|
||||
export type DbTypes =
|
||||
| string
|
||||
@@ -255,6 +254,10 @@ export default class BaseModel extends BaseEntity {
|
||||
(this as any)[columnName] = value;
|
||||
}
|
||||
|
||||
public removeValue(columnName: string): void {
|
||||
(this as any)[columnName] = undefined;
|
||||
}
|
||||
|
||||
public doesPermissionHaveConditions(
|
||||
permission: Permission
|
||||
): JSONObject | null {
|
||||
@@ -528,4 +531,180 @@ export default class BaseModel extends BaseEntity {
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public static toJSON(
|
||||
model: BaseModel,
|
||||
modelType: { new (): BaseModel }
|
||||
): JSONObject {
|
||||
const json: JSONObject = this.toJSONObject(model, modelType);
|
||||
return JSONFunctions.serialize(json);
|
||||
}
|
||||
|
||||
public static toJSONObject(
|
||||
model: BaseModel,
|
||||
modelType: { new (): BaseModel }
|
||||
): JSONObject {
|
||||
const json: JSONObject = {};
|
||||
|
||||
const vanillaModel: BaseModel = new modelType();
|
||||
|
||||
for (const key of vanillaModel.getTableColumns().columns) {
|
||||
if ((model as any)[key] === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const tableColumnMetadata: TableColumnMetadata =
|
||||
vanillaModel.getTableColumnMetadata(key);
|
||||
|
||||
if (tableColumnMetadata) {
|
||||
if (
|
||||
(model as any)[key] &&
|
||||
tableColumnMetadata.modelType &&
|
||||
tableColumnMetadata.type === TableColumnType.Entity &&
|
||||
(model as any)[key] instanceof BaseModel
|
||||
) {
|
||||
(json as any)[key] = this.toJSONObject(
|
||||
(model as any)[key],
|
||||
tableColumnMetadata.modelType
|
||||
);
|
||||
} else if (
|
||||
(model as any)[key] &&
|
||||
Array.isArray((model as any)[key]) &&
|
||||
(model as any)[key].length > 0 &&
|
||||
tableColumnMetadata.modelType &&
|
||||
tableColumnMetadata.type === TableColumnType.EntityArray
|
||||
) {
|
||||
(json as any)[key] = this.toJSONObjectArray(
|
||||
(model as any)[key] as Array<BaseModel>,
|
||||
tableColumnMetadata.modelType
|
||||
);
|
||||
} else {
|
||||
(json as any)[key] = (model as any)[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
public static toJSONObjectArray(
|
||||
list: Array<BaseModel>,
|
||||
modelType: { new (): BaseModel }
|
||||
): JSONArray {
|
||||
const array: JSONArray = [];
|
||||
|
||||
for (const item of list) {
|
||||
array.push(this.toJSONObject(item, modelType));
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
public static toJSONArray(
|
||||
list: Array<BaseModel>,
|
||||
modelType: { new (): BaseModel }
|
||||
): JSONArray {
|
||||
const array: JSONArray = [];
|
||||
|
||||
for (const item of list) {
|
||||
array.push(this.toJSON(item, modelType));
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
private static _fromJSON<T extends BaseModel>(
|
||||
json: JSONObject | T,
|
||||
type: { new (): T }
|
||||
): T {
|
||||
if (json instanceof BaseModel) {
|
||||
return json;
|
||||
}
|
||||
|
||||
json = JSONFunctions.deserialize(json);
|
||||
const baseModel: T = new type();
|
||||
|
||||
for (const key of Object.keys(json)) {
|
||||
const tableColumnMetadata: TableColumnMetadata =
|
||||
baseModel.getTableColumnMetadata(key);
|
||||
if (tableColumnMetadata) {
|
||||
if (
|
||||
json[key] &&
|
||||
tableColumnMetadata.modelType &&
|
||||
tableColumnMetadata.type === TableColumnType.Entity
|
||||
) {
|
||||
if (
|
||||
json[key] &&
|
||||
Array.isArray(json[key]) &&
|
||||
(json[key] as Array<any>).length > 0
|
||||
) {
|
||||
json[key] = (json[key] as Array<any>)[0];
|
||||
}
|
||||
|
||||
(baseModel as any)[key] = this.fromJSON(
|
||||
json[key] as JSONObject,
|
||||
tableColumnMetadata.modelType
|
||||
);
|
||||
} else if (
|
||||
json[key] &&
|
||||
tableColumnMetadata.modelType &&
|
||||
tableColumnMetadata.type === TableColumnType.EntityArray
|
||||
) {
|
||||
if (json[key] && !Array.isArray(json[key])) {
|
||||
json[key] = [json[key]];
|
||||
}
|
||||
|
||||
(baseModel as any)[key] = this.fromJSONArray(
|
||||
json[key] as JSONArray,
|
||||
tableColumnMetadata.modelType
|
||||
);
|
||||
} else {
|
||||
(baseModel as any)[key] = json[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return baseModel as T;
|
||||
}
|
||||
|
||||
public static fromJSON<T extends BaseModel>(
|
||||
json: JSONObject | JSONArray,
|
||||
type: { new (): T }
|
||||
): T | Array<T> {
|
||||
if (Array.isArray(json)) {
|
||||
const arr: Array<T> = [];
|
||||
|
||||
for (const item of json) {
|
||||
arr.push(this._fromJSON<T>(item, type));
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
return this._fromJSON<T>(json, type);
|
||||
}
|
||||
|
||||
public static fromJSONObject<T extends BaseModel>(
|
||||
json: JSONObject | T,
|
||||
type: { new (): T }
|
||||
): T {
|
||||
if (json instanceof BaseModel) {
|
||||
return json;
|
||||
}
|
||||
|
||||
return this.fromJSON<T>(json, type) as T;
|
||||
}
|
||||
|
||||
public static fromJSONArray<T extends BaseModel>(
|
||||
json: Array<JSONObject | T>,
|
||||
type: { new (): T }
|
||||
): Array<T> {
|
||||
const arr: Array<T> = [];
|
||||
|
||||
for (const item of json) {
|
||||
arr.push(this._fromJSON<T>(item, type));
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import ColumnLength from '../Types/Database/ColumnLength';
|
||||
import ColumnType from '../Types/Database/ColumnType';
|
||||
import SlugifyColumn from '../Types/Database/SlugifyColumn';
|
||||
import TableColumn from '../Types/Database/TableColumn';
|
||||
import TableColumnType from '../Types/BaseDatabase/TableColumnType';
|
||||
import TableColumnType from '../Types/Database/TableColumnType';
|
||||
import MimeType from '../Types/File/MimeType';
|
||||
import ObjectID from '../Types/ObjectID';
|
||||
import Permission from '../Types/Permission';
|
||||
|
||||
@@ -26,4 +26,6 @@ export const ApiReferenceRoute: Route = new Route('/reference');
|
||||
|
||||
export const AdminDashboardRoute: Route = new Route('/admin');
|
||||
|
||||
export const ProbeApiRoute: Route = new Route('/probe-api');
|
||||
export const IngestorRoute: Route = new Route('/ingestor');
|
||||
|
||||
export const RealtimeRoute: Route = new Route('/realtime/socket');
|
||||
|
||||
61
Common/Tests/Types/API/HTTPErrorResponse.test.ts
Normal file
61
Common/Tests/Types/API/HTTPErrorResponse.test.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import HTTPErrorResponse from '../../../Types/API/HTTPErrorResponse';
|
||||
|
||||
describe('HTTPErrorResponse', () => {
|
||||
it('should return an empty string when data is null', () => {
|
||||
const httpResponse: HTTPErrorResponse = new HTTPErrorResponse(
|
||||
404,
|
||||
{ data: null },
|
||||
{}
|
||||
);
|
||||
expect(httpResponse.message).toBe('');
|
||||
});
|
||||
|
||||
it('should return the message from the "data" property if present', () => {
|
||||
const httpResponse: HTTPErrorResponse = new HTTPErrorResponse(
|
||||
200,
|
||||
{ data: 'Data message' },
|
||||
{}
|
||||
);
|
||||
expect(httpResponse.message).toBe('Data message');
|
||||
});
|
||||
|
||||
it('should return the message from the "message" property if present', () => {
|
||||
const httpResponse: HTTPErrorResponse = new HTTPErrorResponse(
|
||||
200,
|
||||
{ message: 'Message message' },
|
||||
{}
|
||||
);
|
||||
expect(httpResponse.message).toBe('Message message');
|
||||
});
|
||||
|
||||
it('should return the message from the "error" property if no other message properties are present', () => {
|
||||
const httpResponse: HTTPErrorResponse = new HTTPErrorResponse(
|
||||
500,
|
||||
{ error: 'Error message' },
|
||||
{}
|
||||
);
|
||||
expect(httpResponse.message).toBe('Error message');
|
||||
});
|
||||
|
||||
it('should return an empty string when no relevant message properties are present', () => {
|
||||
const httpResponse: HTTPErrorResponse = new HTTPErrorResponse(
|
||||
204,
|
||||
{ otherProperty: 'Other message' },
|
||||
{}
|
||||
);
|
||||
expect(httpResponse.message).toBe('');
|
||||
});
|
||||
|
||||
it('should prioritize "data" > "message" > "error" when multiple message properties are present', () => {
|
||||
const httpResponse: HTTPErrorResponse = new HTTPErrorResponse(
|
||||
201,
|
||||
{
|
||||
data: 'Data message',
|
||||
message: 'Message message',
|
||||
error: 'Error message',
|
||||
},
|
||||
{}
|
||||
);
|
||||
expect(httpResponse.message).toBe('Data message');
|
||||
});
|
||||
});
|
||||
82
Common/Tests/Types/Database/Date.test.ts
Normal file
82
Common/Tests/Types/Database/Date.test.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import DatabaseDate from '../../../Types/Database/Date';
|
||||
import moment from 'moment';
|
||||
import InBetween from '../../../Types/Database/InBetween';
|
||||
import { JSONObject } from '../../../Types/JSON';
|
||||
|
||||
describe('DatabaseDate', () => {
|
||||
describe('asDateStartOfTheDayEndOfTheDayForDatabaseQuery', () => {
|
||||
it('should return InBetween object for a valid Date input', () => {
|
||||
const inputDate: Date = new Date('2023-10-24T12:00:00Z');
|
||||
const result: JSONObject =
|
||||
DatabaseDate.asDateStartOfTheDayEndOfTheDayForDatabaseQuery(
|
||||
inputDate
|
||||
).toJSON();
|
||||
|
||||
const expectedStart: string = moment(inputDate)
|
||||
.startOf('day')
|
||||
.format('YYYY-MM-DD HH:mm:ss');
|
||||
const expectedEnd: string = moment(inputDate)
|
||||
.endOf('day')
|
||||
.format('YYYY-MM-DD HH:mm:ss');
|
||||
expect(result).toEqual({
|
||||
startValue: expectedStart,
|
||||
endValue: expectedEnd,
|
||||
_type: 'InBetween',
|
||||
});
|
||||
});
|
||||
|
||||
it('should return InBetween object for a valid Date string input', () => {
|
||||
const inputDate: string = '2023-10-24T12:00:00Z';
|
||||
const result: JSONObject =
|
||||
DatabaseDate.asDateStartOfTheDayEndOfTheDayForDatabaseQuery(
|
||||
inputDate
|
||||
).toJSON();
|
||||
const expectedStart: string = moment(inputDate)
|
||||
.startOf('day')
|
||||
.format('YYYY-MM-DD HH:mm:ss');
|
||||
const expectedEnd: string = moment(inputDate)
|
||||
.endOf('day')
|
||||
.format('YYYY-MM-DD HH:mm:ss');
|
||||
expect(result).toEqual({
|
||||
startValue: expectedStart,
|
||||
endValue: expectedEnd,
|
||||
_type: 'InBetween',
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle invalid date string gracefully', () => {
|
||||
const inputDate: string = 'invalid-date';
|
||||
const result: JSONObject =
|
||||
DatabaseDate.asDateStartOfTheDayEndOfTheDayForDatabaseQuery(
|
||||
inputDate
|
||||
).toJSON();
|
||||
expect(result).toEqual({
|
||||
startValue: 'Invalid date',
|
||||
endValue: 'Invalid date',
|
||||
_type: 'InBetween',
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle empty string input gracefully', () => {
|
||||
const inputDate: string = '';
|
||||
const result: JSONObject =
|
||||
DatabaseDate.asDateStartOfTheDayEndOfTheDayForDatabaseQuery(
|
||||
inputDate
|
||||
).toJSON();
|
||||
expect(result).toEqual({
|
||||
startValue: 'Invalid date',
|
||||
endValue: 'Invalid date',
|
||||
_type: 'InBetween',
|
||||
});
|
||||
});
|
||||
|
||||
it('should be a type of InBetween', () => {
|
||||
const inputDate: string = '2023-10-24T12:00:00Z';
|
||||
const result: InBetween =
|
||||
DatabaseDate.asDateStartOfTheDayEndOfTheDayForDatabaseQuery(
|
||||
inputDate
|
||||
);
|
||||
expect(result).toBeInstanceOf(InBetween);
|
||||
});
|
||||
});
|
||||
});
|
||||
70
Common/Tests/Types/Database/EqualToOrNull.test.ts
Normal file
70
Common/Tests/Types/Database/EqualToOrNull.test.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import EqualToOrNull from '../../../Types/Database/EqualToOrNull';
|
||||
import BadDataException from '../../../Types/Exception/BadDataException';
|
||||
import { JSONObject } from '../../../Types/JSON';
|
||||
|
||||
describe('EqualToOrNull', () => {
|
||||
it('should create an EqualToOrNull object with a valid value', () => {
|
||||
const value: string = 'oneuptime';
|
||||
const equalObj: EqualToOrNull = new EqualToOrNull(value);
|
||||
expect(equalObj.value).toBe(value);
|
||||
});
|
||||
|
||||
it('should get the value property of an EqualToOrNull object', () => {
|
||||
const value: string = 'oneuptime';
|
||||
const equalObj: EqualToOrNull = new EqualToOrNull(value);
|
||||
expect(equalObj.value).toBe(value);
|
||||
});
|
||||
|
||||
it('should set the value property of an EqualToOrNull object', () => {
|
||||
const equalObj: EqualToOrNull = new EqualToOrNull('oldValue');
|
||||
equalObj.value = 'newValue';
|
||||
expect(equalObj.value).toBe('newValue');
|
||||
});
|
||||
|
||||
it('should return the correct string representation using toString method', () => {
|
||||
const equalObj: EqualToOrNull = new EqualToOrNull('oneuptime');
|
||||
expect(equalObj.toString()).toBe('oneuptime');
|
||||
});
|
||||
|
||||
it('should generate the correct JSON representation using toJSON method', () => {
|
||||
const equalObj: EqualToOrNull = new EqualToOrNull('oneuptime');
|
||||
const expectedJSON: JSONObject = {
|
||||
_type: 'EqualToOrNull',
|
||||
value: 'oneuptime',
|
||||
};
|
||||
expect(equalObj.toJSON()).toEqual(expectedJSON);
|
||||
});
|
||||
|
||||
it('should create an EqualToOrNull object from valid JSON input', () => {
|
||||
const jsonInput: JSONObject = {
|
||||
_type: 'EqualToOrNull',
|
||||
value: 'oneuptime',
|
||||
};
|
||||
const equalObj: EqualToOrNull = EqualToOrNull.fromJSON(jsonInput);
|
||||
expect(equalObj.value).toBe('oneuptime');
|
||||
});
|
||||
|
||||
it('should throw a BadDataException when using invalid JSON input', () => {
|
||||
const jsonInput: JSONObject = {
|
||||
_type: 'InvalidType',
|
||||
value: 'oneuptime',
|
||||
};
|
||||
expect(() => {
|
||||
return EqualToOrNull.fromJSON(jsonInput);
|
||||
}).toThrow(BadDataException);
|
||||
});
|
||||
|
||||
it('should be a type of EqualToOrNull', () => {
|
||||
const equalObj: EqualToOrNull = new EqualToOrNull('oneuptime');
|
||||
expect(equalObj).toBeInstanceOf(EqualToOrNull);
|
||||
});
|
||||
|
||||
it('should handle null value when using fromJSON method', () => {
|
||||
const jsonInput: JSONObject = {
|
||||
_type: 'EqualToOrNull',
|
||||
value: null,
|
||||
};
|
||||
const equalObj: EqualToOrNull = EqualToOrNull.fromJSON(jsonInput);
|
||||
expect(equalObj.value).toBeNull();
|
||||
});
|
||||
});
|
||||
80
Common/Tests/Types/Database/InBetween.test.ts
Normal file
80
Common/Tests/Types/Database/InBetween.test.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import InBetween from '../../../Types/Database/InBetween';
|
||||
import BadDataException from '../../../Types/Exception/BadDataException';
|
||||
import { JSONObject } from '../../../Types/JSON';
|
||||
|
||||
describe('InBetween', () => {
|
||||
it('should create an InBetween object with valid start and end values', () => {
|
||||
const startValue: number = 10;
|
||||
const endValue: number = 20;
|
||||
const betweenObj: InBetween = new InBetween(startValue, endValue);
|
||||
expect(betweenObj.startValue).toBe(10);
|
||||
expect(betweenObj.endValue).toBe(20);
|
||||
});
|
||||
|
||||
it('should generate the correct JSON representation using toJSON method', () => {
|
||||
const startValue: number = 10;
|
||||
const endValue: number = 20;
|
||||
const betweenObj: InBetween = new InBetween(startValue, endValue);
|
||||
const expectedJSON: JSONObject = {
|
||||
_type: 'InBetween',
|
||||
startValue: 10,
|
||||
endValue: 20,
|
||||
};
|
||||
expect(betweenObj.toJSON()).toEqual(expectedJSON);
|
||||
});
|
||||
|
||||
it('should create an InBetween object from valid JSON input', () => {
|
||||
const jsonInput: JSONObject = {
|
||||
_type: 'InBetween',
|
||||
startValue: 10,
|
||||
endValue: 20,
|
||||
};
|
||||
const betweenObj: InBetween = InBetween.fromJSON(jsonInput);
|
||||
expect(betweenObj.startValue).toBe(10);
|
||||
expect(betweenObj.endValue).toBe(20);
|
||||
});
|
||||
|
||||
it('should throw a BadDataException when using invalid JSON input', () => {
|
||||
const jsonInput: JSONObject = {
|
||||
_type: 'InvalidType',
|
||||
startValue: 10,
|
||||
endValue: 20,
|
||||
};
|
||||
expect(() => {
|
||||
return InBetween.fromJSON(jsonInput);
|
||||
}).toThrow(BadDataException);
|
||||
});
|
||||
|
||||
it('should return a string with start and end values matching', () => {
|
||||
const startValue: number = 15;
|
||||
const endValue: number = 15;
|
||||
const betweenObj: InBetween = new InBetween(startValue, endValue);
|
||||
expect(betweenObj.toString()).toBe('15');
|
||||
});
|
||||
|
||||
it('should return a string with start and end values different', () => {
|
||||
const startValue: number = 10;
|
||||
const endValue: number = 20;
|
||||
const betweenObj: InBetween = new InBetween(startValue, endValue);
|
||||
expect(betweenObj.toString()).toBe('10 - 20');
|
||||
});
|
||||
|
||||
it('should return the start value as a string', () => {
|
||||
const startValue: number = 10;
|
||||
const endValue: number = 20;
|
||||
const betweenObj: InBetween = new InBetween(startValue, endValue);
|
||||
expect(betweenObj.toStartValueString()).toBe('10');
|
||||
});
|
||||
|
||||
it('should return the end value as a string', () => {
|
||||
const startValue: number = 10;
|
||||
const endValue: number = 20;
|
||||
const betweenObj: InBetween = new InBetween(startValue, endValue);
|
||||
expect(betweenObj.toEndValueString()).toBe('20');
|
||||
});
|
||||
|
||||
it('should be a type of InBetween', () => {
|
||||
const inBetweenObj: InBetween = new InBetween(10, 15);
|
||||
expect(inBetweenObj).toBeInstanceOf(InBetween);
|
||||
});
|
||||
});
|
||||
52
Common/Tests/Types/JSONFunctions.test.ts
Normal file
52
Common/Tests/Types/JSONFunctions.test.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import BaseModel from '../../Models/BaseModel';
|
||||
import { JSONObject } from '../../Types/JSON';
|
||||
import JSONFunctions from '../../Types/JSONFunctions';
|
||||
|
||||
describe('JSONFunctions Class', () => {
|
||||
let baseModel: BaseModel;
|
||||
|
||||
beforeEach(() => {
|
||||
baseModel = new BaseModel();
|
||||
});
|
||||
|
||||
describe('isEmptyObject Method', () => {
|
||||
test('Returns true for an empty object', () => {
|
||||
const emptyObj: JSONObject = {};
|
||||
expect(JSONFunctions.isEmptyObject(emptyObj)).toBe(true);
|
||||
});
|
||||
|
||||
test('Returns false for a non-empty object', () => {
|
||||
const nonEmptyObj: JSONObject = { key: 'value' };
|
||||
expect(JSONFunctions.isEmptyObject(nonEmptyObj)).toBe(false);
|
||||
});
|
||||
|
||||
test('Returns true for null or undefined', () => {
|
||||
expect(JSONFunctions.isEmptyObject(null)).toBe(true);
|
||||
expect(JSONFunctions.isEmptyObject(undefined)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('toJSON and fromJSON Methods', () => {
|
||||
test('toJSON returns a valid JSON object', () => {
|
||||
const json: JSONObject = BaseModel.toJSON(baseModel, BaseModel);
|
||||
expect(json).toEqual(expect.objectContaining({}));
|
||||
});
|
||||
|
||||
test('toJSONObject returns a valid JSON object', () => {
|
||||
const json: JSONObject = BaseModel.toJSONObject(
|
||||
baseModel,
|
||||
BaseModel
|
||||
);
|
||||
expect(json).toEqual(expect.objectContaining({}));
|
||||
});
|
||||
|
||||
test('fromJSON returns a BaseModel instance', () => {
|
||||
const json: JSONObject = { name: 'oneuptime' };
|
||||
const result: BaseModel | BaseModel[] = BaseModel.fromJSON(
|
||||
json,
|
||||
BaseModel
|
||||
);
|
||||
expect(result).toBeInstanceOf(BaseModel);
|
||||
});
|
||||
});
|
||||
});
|
||||
44
Common/Tests/Types/SerializableObject.test.ts
Normal file
44
Common/Tests/Types/SerializableObject.test.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import NotImplementedException from '../../Types/Exception/NotImplementedException';
|
||||
import { JSONObject } from '../../Types/JSON';
|
||||
import SerializableObject from '../../Types/SerializableObject';
|
||||
|
||||
describe('SerializableObject Class', () => {
|
||||
let serializableObject: SerializableObject;
|
||||
|
||||
beforeEach(() => {
|
||||
serializableObject = new SerializableObject();
|
||||
});
|
||||
|
||||
test('Constructor initializes an instance of SerializableObject', () => {
|
||||
expect(serializableObject).toBeInstanceOf(SerializableObject);
|
||||
});
|
||||
|
||||
describe('toJSON Method', () => {
|
||||
test('Throws NotImplementedException when called', () => {
|
||||
expect(() => {
|
||||
return serializableObject.toJSON();
|
||||
}).toThrow(NotImplementedException);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fromJSON Method', () => {
|
||||
test('Throws NotImplementedException when called', () => {
|
||||
expect(() => {
|
||||
return SerializableObject.fromJSON({});
|
||||
}).toThrow(NotImplementedException);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fromJSON Instance Method', () => {
|
||||
test('Returns the result from the static fromJSON method', () => {
|
||||
const json: JSONObject = { key: 'value' };
|
||||
const expectedResult: SerializableObject = new SerializableObject();
|
||||
jest.spyOn(SerializableObject, 'fromJSON').mockReturnValue(
|
||||
expectedResult
|
||||
);
|
||||
const result: SerializableObject =
|
||||
serializableObject.fromJSON(json);
|
||||
expect(result).toBe(expectedResult);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -10,6 +10,7 @@ import axios, {
|
||||
AxiosStatic,
|
||||
AxiosRequestConfig,
|
||||
Method,
|
||||
AxiosHeaders,
|
||||
} from 'axios';
|
||||
import { expect, jest } from '@jest/globals';
|
||||
import HTTPResponse from '../../Types/API/HTTPResponse';
|
||||
@@ -51,13 +52,17 @@ function createAxiosResponse<T = any, D = any>(
|
||||
data = [] as T,
|
||||
status = 200,
|
||||
statusText = 'OK',
|
||||
config = {},
|
||||
config = {
|
||||
headers: DEFAULT_HEADERS as AxiosHeaders,
|
||||
},
|
||||
headers = DEFAULT_HEADERS,
|
||||
}: Partial<AxiosResponse<T, D>> = {
|
||||
data: [] as T,
|
||||
status: 200,
|
||||
statusText: 'OK',
|
||||
config: {},
|
||||
config: {
|
||||
headers: DEFAULT_HEADERS as AxiosHeaders,
|
||||
},
|
||||
headers: DEFAULT_HEADERS,
|
||||
}
|
||||
): AxiosResponse<T, D> {
|
||||
@@ -82,7 +87,9 @@ const mergedHeaders: Headers = {
|
||||
*/
|
||||
function createAxiosError<T = any, D = any>(
|
||||
{
|
||||
config = {},
|
||||
config = {
|
||||
headers: DEFAULT_HEADERS as AxiosHeaders,
|
||||
},
|
||||
isAxiosError = true,
|
||||
toJSON = () => {
|
||||
return {};
|
||||
@@ -91,7 +98,9 @@ function createAxiosError<T = any, D = any>(
|
||||
message = 'Something went wrong',
|
||||
response = createAxiosResponse(),
|
||||
}: Partial<AxiosError<T, D>> = {
|
||||
config: {},
|
||||
config: {
|
||||
headers: DEFAULT_HEADERS as AxiosHeaders,
|
||||
},
|
||||
isAxiosError: true,
|
||||
toJSON: () => {
|
||||
return {};
|
||||
@@ -219,7 +228,7 @@ describe('getErrorResponse', () => {
|
||||
// NOTE: Passing undefined will initialize the default parameter
|
||||
const axiosError: AxiosError<null, {}> = createAxiosError({
|
||||
response: null!,
|
||||
});
|
||||
}) as AxiosError<null, {}>;
|
||||
|
||||
// Use bracket notation property access to access private method
|
||||
expect(() => {
|
||||
@@ -279,7 +288,7 @@ describe('fetch', () => {
|
||||
data,
|
||||
}),
|
||||
message: 'An error occurred',
|
||||
});
|
||||
}) as AxiosError<undefined, {}>;
|
||||
|
||||
mockedAxios.mockRejectedValueOnce(mockedAxiosError);
|
||||
|
||||
@@ -349,6 +358,10 @@ const httpMethodTests: Array<HTTPMethodType> = [
|
||||
name: 'delete',
|
||||
method: HTTPMethod.DELETE,
|
||||
},
|
||||
{
|
||||
name: 'head',
|
||||
method: HTTPMethod.HEAD,
|
||||
},
|
||||
];
|
||||
|
||||
describe.each(httpMethodTests)('$name', ({ name, method }: HTTPMethodType) => {
|
||||
|
||||
85
Common/Tests/Utils/Analytics.test.ts
Normal file
85
Common/Tests/Utils/Analytics.test.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import Analytics from '../../Utils/Analytics';
|
||||
import Email from '../../Types/Email';
|
||||
import { JSONObject } from '../../Types/JSON';
|
||||
import posthog from 'posthog-js';
|
||||
|
||||
jest.mock('posthog-js', () => {
|
||||
return {
|
||||
init: jest.fn(),
|
||||
identify: jest.fn(),
|
||||
reset: jest.fn(),
|
||||
capture: jest.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
const apiHost: string = 'https://example.com';
|
||||
const apiKey: string = 'your-api-key';
|
||||
|
||||
describe('Analytics Class', () => {
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should initialize the Analytics class', () => {
|
||||
const analytics: Analytics = new Analytics(apiHost, apiKey);
|
||||
|
||||
expect(posthog.init).toHaveBeenCalledWith(apiKey, {
|
||||
api_host: apiHost,
|
||||
autocapture: false,
|
||||
});
|
||||
expect(analytics.isInitialized).toBe(true);
|
||||
});
|
||||
|
||||
it('should not initialize if apiHost and apiKey are not provided', () => {
|
||||
const analytics: Analytics = new Analytics('', '');
|
||||
|
||||
expect(posthog.init).not.toHaveBeenCalled();
|
||||
expect(analytics.isInitialized).toBe(false);
|
||||
});
|
||||
|
||||
it('should authenticate a user', () => {
|
||||
const analytics: Analytics = new Analytics(apiHost, apiKey);
|
||||
const email: Email = new Email('test@example.com');
|
||||
|
||||
analytics.userAuth(email);
|
||||
expect(posthog.identify).toHaveBeenCalledWith(email.toString());
|
||||
});
|
||||
|
||||
it('should not authenticate a user if not initialized', () => {
|
||||
const analytics: Analytics = new Analytics('', '');
|
||||
const email: Email = new Email('test@example.com');
|
||||
|
||||
analytics.userAuth(email);
|
||||
expect(posthog.identify).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should reset the user session on logout', () => {
|
||||
const analytics: Analytics = new Analytics(apiHost, apiKey);
|
||||
|
||||
analytics.logout();
|
||||
expect(posthog.reset).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not reset the user session if not initialized', () => {
|
||||
const analytics: Analytics = new Analytics('', '');
|
||||
|
||||
analytics.logout();
|
||||
expect(posthog.reset).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should capture an event with optional data', () => {
|
||||
const analytics: Analytics = new Analytics(apiHost, apiKey);
|
||||
const eventName: string = 'testEvent';
|
||||
const data: JSONObject = { key: 'value' };
|
||||
|
||||
analytics.capture(eventName, data);
|
||||
expect(posthog.capture).toHaveBeenCalledWith(eventName, data);
|
||||
});
|
||||
|
||||
it('should not capture an event if not initialized', () => {
|
||||
const analytics: Analytics = new Analytics('', '');
|
||||
|
||||
analytics.capture('testEvent');
|
||||
expect(posthog.capture).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
34
Common/Tests/Utils/CronTime.test.ts
Normal file
34
Common/Tests/Utils/CronTime.test.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import {
|
||||
EVERY_MINUTE,
|
||||
EVERY_DAY,
|
||||
EVERY_HOUR,
|
||||
EVERY_FIVE_MINUTE,
|
||||
EVERY_FIVE_SECONDS,
|
||||
EVERY_WEEK,
|
||||
} from '../../Utils/CronTime';
|
||||
|
||||
describe('CronTime', () => {
|
||||
test('should return every minute', () => {
|
||||
expect(EVERY_MINUTE).toEqual('* * * * *');
|
||||
});
|
||||
|
||||
test('should return every day', () => {
|
||||
expect(EVERY_DAY).toEqual('0 8 * * *');
|
||||
});
|
||||
|
||||
test('should return every hour', () => {
|
||||
expect(EVERY_HOUR).toEqual('1 * * * *');
|
||||
});
|
||||
|
||||
test('should return every five minute', () => {
|
||||
expect(EVERY_FIVE_MINUTE).toEqual('*/5 * * * *');
|
||||
});
|
||||
|
||||
test('should return every five seconds', () => {
|
||||
expect(EVERY_FIVE_SECONDS).toEqual('*/5 * * * * *');
|
||||
});
|
||||
|
||||
test('should return every week', () => {
|
||||
expect(EVERY_WEEK).toEqual('0 0 * * 0');
|
||||
});
|
||||
});
|
||||
38
Common/Tests/Utils/Faker.test.ts
Normal file
38
Common/Tests/Utils/Faker.test.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import Faker from '../../Utils/Faker';
|
||||
import Email from '../../Types/Email';
|
||||
import Name from '../../Types/Name';
|
||||
import Phone from '../../Types/Phone';
|
||||
|
||||
describe('Faker Class', () => {
|
||||
it('should generate a random name with alphanumeric characters', () => {
|
||||
expect(Faker.generateName()).toMatch(/^[a-zA-Z0-9]{10}$/);
|
||||
});
|
||||
|
||||
it('should generate a random company name', () => {
|
||||
expect(Faker.generateCompanyName()).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should generate a string of random numbers of specified length', () => {
|
||||
expect(Faker.randomNumbers(8)).toMatch(/^\d{8}$/);
|
||||
});
|
||||
|
||||
it('should generate a user full name', () => {
|
||||
const userFullName: Name = Faker.generateUserFullName();
|
||||
expect(userFullName).toHaveProperty('name');
|
||||
expect(userFullName.name).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should generate a valid email address', () => {
|
||||
const email: Email = Faker.generateEmail();
|
||||
expect(email.email).toMatch(
|
||||
/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,9}$/i
|
||||
);
|
||||
});
|
||||
|
||||
it('should generate a valid phone number', () => {
|
||||
const phone: Phone = Faker.generatePhone();
|
||||
expect(phone.phone).toMatch(
|
||||
/^[+]?[(]?[0-9]{3}[)]?[-\s.]?[0-9]{3}[-\s.]?[0-9]{4,7}$/
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,9 +1,12 @@
|
||||
import Slug from '../../Utils/Slug';
|
||||
describe('Slug.getSlug()', () => {
|
||||
test('should return empty string, if name is empty ', () => {
|
||||
test('should return empty string, if name is empty ', () => {
|
||||
expect(Slug.getSlug('')).toEqual('');
|
||||
expect(Slug.getSlug(' ')).toEqual('');
|
||||
});
|
||||
test('should generate a slug from a valid name when name is null', () => {
|
||||
expect(Slug.getSlug(null)).toMatch(/^[a-z0-9-]+$/);
|
||||
});
|
||||
test('should replaces spaces in nonEmpty with hyphen -', () => {
|
||||
expect(Slug.getSlug('this is slug')).toMatch(/this-is-slug/g);
|
||||
});
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
import BaseModel from '../../Models/BaseModel';
|
||||
import AnalyticsBaseModel from '../../AnalyticsModels/BaseModel';
|
||||
import { JSONArray, JSONObject, JSONObjectOrArray } from '../JSON';
|
||||
import JSONFunctions from '../JSONFunctions';
|
||||
import Typeof from '../Typeof';
|
||||
import Headers from './Headers';
|
||||
|
||||
export default class HTTPResponse<
|
||||
T extends JSONObjectOrArray | BaseModel | Array<BaseModel>
|
||||
T extends
|
||||
| JSONObjectOrArray
|
||||
| BaseModel
|
||||
| Array<BaseModel>
|
||||
| AnalyticsBaseModel
|
||||
| Array<AnalyticsBaseModel>
|
||||
> {
|
||||
private _statusCode: number = -1;
|
||||
public get statusCode(): number {
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
import TableColumnType from '../BaseDatabase/TableColumnType';
|
||||
import { ColumnAccessControl } from '../BaseDatabase/AccessControl';
|
||||
import ColumnBillingAccessControl from '../BaseDatabase/ColumnBillingAccessControl';
|
||||
import TableColumnType from '../AnalyticsDatabase/TableColumnType';
|
||||
import { JSONValue } from '../JSON';
|
||||
import NestedModel from '../../AnalyticsModels/NestedModel';
|
||||
|
||||
export default class AnalyticsTableColumn {
|
||||
private _key: string = 'id';
|
||||
|
||||
public get key(): string {
|
||||
return this._key;
|
||||
}
|
||||
@@ -33,7 +38,15 @@ export default class AnalyticsTableColumn {
|
||||
this._required = v;
|
||||
}
|
||||
|
||||
private _type: TableColumnType = TableColumnType.ShortText;
|
||||
private _isTenantId: boolean = false;
|
||||
public get isTenantId(): boolean {
|
||||
return this._isTenantId;
|
||||
}
|
||||
public set isTenantId(v: boolean) {
|
||||
this._isTenantId = v;
|
||||
}
|
||||
|
||||
private _type: TableColumnType = TableColumnType.Text;
|
||||
public get type(): TableColumnType {
|
||||
return this._type;
|
||||
}
|
||||
@@ -41,17 +54,110 @@ export default class AnalyticsTableColumn {
|
||||
this._type = v;
|
||||
}
|
||||
|
||||
private _forceGetDefaultValueOnCreate?:
|
||||
| (() => Date | string | number | boolean)
|
||||
| undefined;
|
||||
public get forceGetDefaultValueOnCreate():
|
||||
| (() => Date | string | number | boolean)
|
||||
| undefined {
|
||||
return this._forceGetDefaultValueOnCreate;
|
||||
}
|
||||
public set forceGetDefaultValueOnCreate(
|
||||
v: (() => Date | string | number | boolean) | undefined
|
||||
) {
|
||||
this._forceGetDefaultValueOnCreate = v;
|
||||
}
|
||||
|
||||
private _defaultValue: JSONValue | undefined;
|
||||
public get defaultValue(): JSONValue {
|
||||
return this._defaultValue;
|
||||
}
|
||||
public set defaultValue(v: JSONValue) {
|
||||
this._defaultValue = v;
|
||||
}
|
||||
|
||||
public get isDefaultValueColumn(): boolean {
|
||||
return Boolean(this.defaultValue !== undefined);
|
||||
}
|
||||
|
||||
private _billingAccessControl?: ColumnBillingAccessControl | undefined;
|
||||
public get billingAccessControl(): ColumnBillingAccessControl | undefined {
|
||||
return this._billingAccessControl;
|
||||
}
|
||||
public set billingAccessControl(v: ColumnBillingAccessControl | undefined) {
|
||||
this._billingAccessControl = v;
|
||||
}
|
||||
|
||||
private _allowAccessIfSubscriptionIsUnpaid: boolean = false;
|
||||
public get allowAccessIfSubscriptionIsUnpaid(): boolean {
|
||||
return this._allowAccessIfSubscriptionIsUnpaid;
|
||||
}
|
||||
public set allowAccessIfSubscriptionIsUnpaid(v: boolean) {
|
||||
this._allowAccessIfSubscriptionIsUnpaid = v;
|
||||
}
|
||||
|
||||
private _accessControl: ColumnAccessControl | undefined;
|
||||
public get accessControl(): ColumnAccessControl | undefined {
|
||||
return this._accessControl;
|
||||
}
|
||||
public set accessControl(v: ColumnAccessControl | undefined) {
|
||||
this._accessControl = v;
|
||||
}
|
||||
|
||||
private _nestedModel?: NestedModel | undefined;
|
||||
public get nestedModel(): NestedModel | undefined {
|
||||
return this._nestedModel;
|
||||
}
|
||||
public set nestedModel(v: NestedModel | undefined) {
|
||||
this._nestedModel = v;
|
||||
}
|
||||
|
||||
private _nestedModelType?: { new (): NestedModel } | undefined;
|
||||
public get nestedModelType(): { new (): NestedModel } | undefined {
|
||||
return this._nestedModelType;
|
||||
}
|
||||
public set nestedModelType(v: { new (): NestedModel } | undefined) {
|
||||
this._nestedModelType = v;
|
||||
}
|
||||
|
||||
public constructor(data: {
|
||||
key: string;
|
||||
nestedModelType?: { new (): NestedModel } | undefined;
|
||||
title: string;
|
||||
description: string;
|
||||
required: boolean;
|
||||
defaultValue?: JSONValue | undefined;
|
||||
type: TableColumnType;
|
||||
billingAccessControl?: ColumnBillingAccessControl | undefined;
|
||||
isTenantId?: boolean | undefined;
|
||||
accessControl?: ColumnAccessControl | undefined;
|
||||
allowAccessIfSubscriptionIsUnpaid?: boolean | undefined;
|
||||
forceGetDefaultValueOnCreate?:
|
||||
| (() => Date | string | number | boolean)
|
||||
| undefined;
|
||||
}) {
|
||||
if (
|
||||
data.type === TableColumnType.NestedModel &&
|
||||
!data.nestedModelType
|
||||
) {
|
||||
throw new Error('NestedModel is required when type is NestedModel');
|
||||
}
|
||||
|
||||
this.accessControl = data.accessControl;
|
||||
this.key = data.key;
|
||||
this.title = data.title;
|
||||
this.description = data.description;
|
||||
this.required = data.required;
|
||||
this.type = data.type;
|
||||
this.isTenantId = data.isTenantId || false;
|
||||
this.forceGetDefaultValueOnCreate = data.forceGetDefaultValueOnCreate;
|
||||
this.defaultValue = data.defaultValue;
|
||||
this.billingAccessControl = data.billingAccessControl;
|
||||
this.allowAccessIfSubscriptionIsUnpaid =
|
||||
data.allowAccessIfSubscriptionIsUnpaid || false;
|
||||
if (data.nestedModelType) {
|
||||
this.nestedModel = new data.nestedModelType();
|
||||
this.nestedModelType = data.nestedModelType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
15
Common/Types/AnalyticsDatabase/TableColumnType.ts
Normal file
15
Common/Types/AnalyticsDatabase/TableColumnType.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
enum ColumnType {
|
||||
ObjectID = 'Object ID',
|
||||
Date = 'Date',
|
||||
Boolean = 'Boolean',
|
||||
Number = 'Number',
|
||||
Text = 'Text',
|
||||
NestedModel = 'Nested Model',
|
||||
JSON = 'JSON',
|
||||
Decimal = 'Decimal',
|
||||
ArrayNumber = 'Array of Numbers',
|
||||
ArrayText = 'Array of Text',
|
||||
LongNumber = 'Long Number',
|
||||
}
|
||||
|
||||
export default ColumnType;
|
||||
11
Common/Types/BaseDatabase/AccessControl.ts
Normal file
11
Common/Types/BaseDatabase/AccessControl.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import Permission from '../Permission';
|
||||
|
||||
export interface ColumnAccessControl {
|
||||
read: Array<Permission>;
|
||||
create: Array<Permission>;
|
||||
update: Array<Permission>;
|
||||
}
|
||||
|
||||
export interface TableAccessControl extends ColumnAccessControl {
|
||||
delete: Array<Permission>;
|
||||
}
|
||||
7
Common/Types/BaseDatabase/ColumnBillingAccessControl.ts
Normal file
7
Common/Types/BaseDatabase/ColumnBillingAccessControl.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { PlanSelect } from '../Billing/SubscriptionPlan';
|
||||
|
||||
export default interface ColumnBillingAccessControl {
|
||||
create: PlanSelect;
|
||||
read: PlanSelect;
|
||||
update: PlanSelect;
|
||||
}
|
||||
@@ -20,4 +20,5 @@ export default interface DatabaseCommonInteractionProps {
|
||||
ignoreHooks?: boolean | undefined;
|
||||
currentPlan?: PlanSelect | undefined;
|
||||
isSubscriptionUnpaid?: boolean | undefined;
|
||||
isMasterAdmin?: boolean | undefined;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import Permission, { UserPermission } from '../Permission';
|
||||
import DatabaseCommonInteractionProps from './DatabaseCommonInteractionProps';
|
||||
|
||||
export default class DatabaseCommonInteractionPropsUtil {
|
||||
public static getUserPermissions(
|
||||
props: DatabaseCommonInteractionProps
|
||||
): Array<UserPermission> {
|
||||
// Check first if the user has Global Permissions.
|
||||
// Global permissions includes all the tenantId user has access to.
|
||||
// and it includes all the global permissions that applies to all the tenant, like PUBLIC.
|
||||
if (!props.userGlobalAccessPermission) {
|
||||
props.userGlobalAccessPermission = {
|
||||
globalPermissions: [Permission.Public],
|
||||
projectIds: [],
|
||||
_type: 'UserGlobalAccessPermission',
|
||||
};
|
||||
}
|
||||
|
||||
// If the PUBLIC Permission is not found in global permissions, include it.
|
||||
if (
|
||||
props.userGlobalAccessPermission &&
|
||||
!props.userGlobalAccessPermission.globalPermissions.includes(
|
||||
Permission.Public
|
||||
)
|
||||
) {
|
||||
props.userGlobalAccessPermission.globalPermissions.push(
|
||||
Permission.Public
|
||||
); // add public permission if not already.
|
||||
}
|
||||
|
||||
// If the CurrentUser Permission is not found in global permissions, include it.
|
||||
if (
|
||||
props.userId &&
|
||||
props.userGlobalAccessPermission &&
|
||||
!props.userGlobalAccessPermission.globalPermissions.includes(
|
||||
Permission.CurrentUser
|
||||
)
|
||||
) {
|
||||
props.userGlobalAccessPermission.globalPermissions.push(
|
||||
Permission.CurrentUser
|
||||
);
|
||||
}
|
||||
|
||||
let userPermissions: Array<UserPermission> = [];
|
||||
|
||||
// Include global permission in userPermissions.
|
||||
|
||||
if (props.userGlobalAccessPermission) {
|
||||
/// take global permissions.
|
||||
userPermissions =
|
||||
props.userGlobalAccessPermission.globalPermissions.map(
|
||||
(permission: Permission) => {
|
||||
return {
|
||||
permission: permission,
|
||||
labelIds: [],
|
||||
_type: 'UserPermission',
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (props.tenantId && props.userTenantAccessPermission) {
|
||||
// Include Tenant Permission in userPermissions.
|
||||
userPermissions = [
|
||||
...userPermissions,
|
||||
...(props.userTenantAccessPermission[props.tenantId.toString()]
|
||||
?.permissions || []),
|
||||
];
|
||||
}
|
||||
|
||||
return userPermissions;
|
||||
}
|
||||
}
|
||||
6
Common/Types/BaseDatabase/DatabaseType.ts
Normal file
6
Common/Types/BaseDatabase/DatabaseType.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
enum DatabaseType {
|
||||
Database = 'Database',
|
||||
AnalyticsDatabase = 'AnalyticsDatabase',
|
||||
}
|
||||
|
||||
export default DatabaseType;
|
||||
6
Common/Types/BaseDatabase/EnableWorkflowOn.ts
Normal file
6
Common/Types/BaseDatabase/EnableWorkflowOn.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export default interface EnableWorkflowOn {
|
||||
create?: boolean | undefined;
|
||||
update?: boolean | undefined;
|
||||
delete?: boolean | undefined;
|
||||
read?: boolean | undefined;
|
||||
}
|
||||
8
Common/Types/BaseDatabase/TableBillingAccessControl.ts
Normal file
8
Common/Types/BaseDatabase/TableBillingAccessControl.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { PlanSelect } from '../Billing/SubscriptionPlan';
|
||||
|
||||
export default interface TableBillingAccessControl {
|
||||
create: PlanSelect;
|
||||
read: PlanSelect;
|
||||
update: PlanSelect;
|
||||
delete: PlanSelect;
|
||||
}
|
||||
@@ -1,16 +1,16 @@
|
||||
export default class MeteredPlan {
|
||||
private priceId: string;
|
||||
private unitName: string;
|
||||
private pricePerUnit: number;
|
||||
private pricePerUnitInUSD: number;
|
||||
|
||||
public constructor(
|
||||
priceId: string,
|
||||
pricePerUnit: number,
|
||||
unitName: string
|
||||
) {
|
||||
this.priceId = priceId;
|
||||
this.pricePerUnit = pricePerUnit;
|
||||
this.unitName = unitName;
|
||||
public constructor(data: {
|
||||
priceId: string;
|
||||
pricePerUnitInUSD: number;
|
||||
unitName: string;
|
||||
}) {
|
||||
this.priceId = data.priceId;
|
||||
this.pricePerUnitInUSD = data.pricePerUnitInUSD;
|
||||
this.unitName = data.unitName;
|
||||
}
|
||||
|
||||
public getPriceId(): string {
|
||||
@@ -18,7 +18,7 @@ export default class MeteredPlan {
|
||||
}
|
||||
|
||||
public getPricePerUnit(): number {
|
||||
return this.pricePerUnit;
|
||||
return this.pricePerUnitInUSD;
|
||||
}
|
||||
|
||||
public getUnitName(): string {
|
||||
|
||||
@@ -8,4 +8,25 @@ enum SubscriptionStatus {
|
||||
Unpaid = 'unpaid',
|
||||
}
|
||||
|
||||
export class SubscriptionStatusUtil {
|
||||
public static isSubscriptionActive(
|
||||
status?: SubscriptionStatus | undefined
|
||||
): boolean {
|
||||
if (!status) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (
|
||||
status === SubscriptionStatus.Active ||
|
||||
status === SubscriptionStatus.Trialing
|
||||
);
|
||||
}
|
||||
|
||||
public static isSubscriptionInactive(
|
||||
status?: SubscriptionStatus | undefined
|
||||
): boolean {
|
||||
return !SubscriptionStatusUtil.isSubscriptionActive(status);
|
||||
}
|
||||
}
|
||||
|
||||
export default SubscriptionStatus;
|
||||
|
||||
@@ -1,18 +1,35 @@
|
||||
import Color from './Color';
|
||||
|
||||
export const Black: Color = new Color('#000000');
|
||||
export const White: Color = new Color('#ffffff');
|
||||
export const slate: Color = new Color('#564ab1');
|
||||
export const Purple: Color = new Color('#6f42c1');
|
||||
export const Pink: Color = new Color('#e83e8c');
|
||||
export const Red: Color = new Color('#fd625e');
|
||||
export const Orange: Color = new Color('#f1734f');
|
||||
export const Yellow: Color = new Color('#ffbf53');
|
||||
export const Green: Color = new Color('#2ab57d');
|
||||
export const Teal: Color = new Color('#050505');
|
||||
export const Cyan: Color = new Color('#4ba6ef');
|
||||
export const VeryLightGrey: Color = new Color('#c2c2c2');
|
||||
export const Grey: Color = new Color('#575757');
|
||||
export const LightGrey: Color = new Color('#908B8B');
|
||||
export const Moroon: Color = new Color('#b70400');
|
||||
export const Blue: Color = new Color('#3686be');
|
||||
export const Black: Color = Color.fromString('#000000');
|
||||
export const White: Color = Color.fromString('#ffffff');
|
||||
export const slate: Color = Color.fromString('#564ab1');
|
||||
export const Purple: Color = Color.fromString('#6f42c1');
|
||||
export const Pink: Color = Color.fromString('#e83e8c');
|
||||
export const Red: Color = Color.fromString('#fd625e');
|
||||
export const Orange: Color = Color.fromString('#f1734f');
|
||||
export const Yellow: Color = Color.fromString('#ffbf53');
|
||||
export const Green: Color = Color.fromString('#2ab57d');
|
||||
export const Teal: Color = Color.fromString('#050505');
|
||||
export const Cyan: Color = Color.fromString('#4ba6ef');
|
||||
export const VeryLightGrey: Color = Color.fromString('#c2c2c2');
|
||||
export const Grey: Color = Color.fromString('#575757');
|
||||
export const LightGrey: Color = Color.fromString('#908B8B');
|
||||
export const Moroon: Color = Color.fromString('#b70400');
|
||||
export const Blue: Color = Color.fromString('#3686be');
|
||||
|
||||
export const EventColorList: Color[] = [
|
||||
Color.fromString('#d50000'),
|
||||
Color.fromString('#e67c73'),
|
||||
Color.fromString('#f4511e'),
|
||||
Color.fromString('#f6bf26'),
|
||||
Color.fromString('#33b679'),
|
||||
Color.fromString('#0b8043'),
|
||||
|
||||
Color.fromString('#039be5'),
|
||||
Color.fromString('#3f51b5'),
|
||||
|
||||
Color.fromString('#65a30d'),
|
||||
Color.fromString('#8e24aa'),
|
||||
|
||||
Color.fromString('#616161'),
|
||||
];
|
||||
|
||||
12
Common/Types/Calendar/CalendarEvent.ts
Normal file
12
Common/Types/Calendar/CalendarEvent.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { JSONObject } from '../JSON';
|
||||
|
||||
export default interface CalendarEvent extends JSONObject {
|
||||
id: number;
|
||||
title: string;
|
||||
start: Date;
|
||||
end: Date;
|
||||
allDay?: boolean | undefined;
|
||||
desc?: string | undefined;
|
||||
color?: string | undefined;
|
||||
textColor?: string | undefined;
|
||||
}
|
||||
@@ -28,3 +28,14 @@ export interface CallRequestMessage {
|
||||
export default interface CallRequest extends CallRequestMessage {
|
||||
to: Phone;
|
||||
}
|
||||
|
||||
export const isHighRiskPhoneNumber: Function = (
|
||||
phoneNumber: Phone
|
||||
): boolean => {
|
||||
// Pakistan
|
||||
if (phoneNumber.toString().startsWith('+92')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
@@ -4,6 +4,7 @@ enum CodeType {
|
||||
HTML = 'html',
|
||||
JSON = 'json',
|
||||
Markdown = 'markdown',
|
||||
SQL = 'sql',
|
||||
// TODO add more mime types.
|
||||
}
|
||||
|
||||
|
||||
@@ -88,4 +88,17 @@ export default class Color extends DatabaseProperty {
|
||||
this._componentToHex(rgb.blue)
|
||||
);
|
||||
}
|
||||
|
||||
public static fromString(color: string): Color {
|
||||
return new Color(color);
|
||||
}
|
||||
|
||||
public static shouldUseDarkText(color: Color): boolean {
|
||||
const rgb: RGB = Color.colorToRgb(color);
|
||||
|
||||
if (rgb.red * 0.299 + rgb.green * 0.587 + rgb.blue * 0.114 > 186) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
34
Common/Types/Currency.ts
Normal file
34
Common/Types/Currency.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import BadDataException from './Exception/BadDataException';
|
||||
|
||||
export default class Currency {
|
||||
public static convertToDecimalPlaces(
|
||||
value: number,
|
||||
decimalPlaces: number = 2
|
||||
): number {
|
||||
if (decimalPlaces < 0) {
|
||||
throw new BadDataException(
|
||||
'decimalPlaces must be greater than or equal to 0.'
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof value === 'string') {
|
||||
value = parseFloat(value);
|
||||
}
|
||||
|
||||
if (decimalPlaces === 0) {
|
||||
return Math.ceil(value);
|
||||
}
|
||||
|
||||
value = value * Math.pow(10, decimalPlaces);
|
||||
|
||||
// convert to int.
|
||||
|
||||
value = Math.round(value);
|
||||
|
||||
// convert back to float.
|
||||
|
||||
value = value / Math.pow(10, decimalPlaces);
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import { PlanSelect } from '../../Billing/SubscriptionPlan';
|
||||
import Permission from '../../Permission';
|
||||
|
||||
export interface ColumnAccessControl {
|
||||
read: Array<Permission>;
|
||||
create: Array<Permission>;
|
||||
update: Array<Permission>;
|
||||
}
|
||||
|
||||
export interface TableAccessControl extends ColumnAccessControl {
|
||||
delete: Array<Permission>;
|
||||
}
|
||||
|
||||
export interface BillingAccessControl {
|
||||
create: PlanSelect;
|
||||
read: PlanSelect;
|
||||
update: PlanSelect;
|
||||
delete: PlanSelect;
|
||||
}
|
||||
|
||||
export interface ColumnBillingAccessControl {
|
||||
create: PlanSelect;
|
||||
read: PlanSelect;
|
||||
update: PlanSelect;
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import 'reflect-metadata';
|
||||
import BaseModel from '../../../Models/BaseModel';
|
||||
import Dictionary from '../../Dictionary';
|
||||
import { ReflectionMetadataType } from '../../Reflection';
|
||||
import { ColumnAccessControl } from './AccessControl';
|
||||
import { ColumnAccessControl } from '../../BaseDatabase/AccessControl';
|
||||
|
||||
const accessControlSymbol: Symbol = Symbol('ColumnAccessControl');
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import 'reflect-metadata';
|
||||
import BaseModel from '../../../Models/BaseModel';
|
||||
import Dictionary from '../../Dictionary';
|
||||
import { ReflectionMetadataType } from '../../Reflection';
|
||||
import { ColumnBillingAccessControl } from './AccessControl';
|
||||
import ColumnBillingAccessControl from '../../BaseDatabase/ColumnBillingAccessControl';
|
||||
|
||||
const accessControlSymbol: Symbol = Symbol('ColumnBillingAccessControl');
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { TableAccessControl } from './AccessControl';
|
||||
import { TableAccessControl } from '../../BaseDatabase/AccessControl';
|
||||
|
||||
export default (accessControl: TableAccessControl) => {
|
||||
return (ctr: Function) => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { BillingAccessControl } from './AccessControl';
|
||||
import TableBillingAccessControl from '../../BaseDatabase/TableBillingAccessControl';
|
||||
|
||||
export default (accessControl: BillingAccessControl) => {
|
||||
export default (accessControl: TableBillingAccessControl) => {
|
||||
return (ctr: Function) => {
|
||||
if (accessControl.create) {
|
||||
ctr.prototype.createBillingPlan = accessControl.create;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import TableColumnType from '../BaseDatabase/TableColumnType';
|
||||
import TableColumnType from './TableColumnType';
|
||||
|
||||
enum ColumnLength {
|
||||
Version = 30,
|
||||
|
||||
7
Common/Types/Database/EnableWorkflow.ts
Normal file
7
Common/Types/Database/EnableWorkflow.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import EnableWorkflowOn from '../BaseDatabase/EnableWorkflowOn';
|
||||
|
||||
export default (enableWorkflowOn: EnableWorkflowOn) => {
|
||||
return (ctr: Function) => {
|
||||
ctr.prototype.enableWorkflowOn = enableWorkflowOn;
|
||||
};
|
||||
};
|
||||
@@ -2,7 +2,7 @@ import 'reflect-metadata';
|
||||
import BaseModel from '../../Models/BaseModel';
|
||||
import Dictionary from '../Dictionary';
|
||||
import { ReflectionMetadataType } from '../Reflection';
|
||||
import TableColumnType from '../BaseDatabase/TableColumnType';
|
||||
import TableColumnType from './TableColumnType';
|
||||
|
||||
const tableColumn: Symbol = Symbol('TableColumn');
|
||||
|
||||
|
||||
@@ -1,10 +1,76 @@
|
||||
import InBetween from './Database/InBetween';
|
||||
import DayOfWeek, { DayOfWeekUtil } from './Day/DayOfWeek';
|
||||
import BadDataException from './Exception/BadDataException';
|
||||
import { JSONObject, ObjectType } from './JSON';
|
||||
import PositiveNumber from './PositiveNumber';
|
||||
import moment from 'moment-timezone';
|
||||
|
||||
export const Moment: typeof moment = moment;
|
||||
|
||||
export default class OneUptimeDate {
|
||||
public static moveDateToTheDayOfWeek(
|
||||
date: Date,
|
||||
moveToWeek: Date,
|
||||
dayOfWeek: DayOfWeek
|
||||
): Date {
|
||||
// date will be moved to the week of "moveToWeek" and then to the day of week "dayOfWeek"
|
||||
|
||||
date = this.fromString(date);
|
||||
date = this.keepTimeButMoveDay(date, moveToWeek);
|
||||
|
||||
// now move the date to the day of week
|
||||
|
||||
const dateDayOfWeek: DayOfWeek = this.getDayOfWeek(date);
|
||||
|
||||
if (dateDayOfWeek === dayOfWeek) {
|
||||
return date;
|
||||
}
|
||||
|
||||
const numberOfDayOfWeek: number =
|
||||
DayOfWeekUtil.getNumberOfDayOfWeek(dayOfWeek);
|
||||
|
||||
const dateDayOfWeekNumber: number =
|
||||
DayOfWeekUtil.getNumberOfDayOfWeek(dateDayOfWeek);
|
||||
|
||||
const difference: number = numberOfDayOfWeek - dateDayOfWeekNumber;
|
||||
|
||||
if (difference === 0) {
|
||||
return date;
|
||||
}
|
||||
|
||||
return this.addRemoveDays(date, difference);
|
||||
}
|
||||
|
||||
public static isOverlapping(
|
||||
start: Date,
|
||||
end: Date,
|
||||
start1: Date,
|
||||
end1: Date
|
||||
): unknown {
|
||||
start = this.fromString(start);
|
||||
end = this.fromString(end);
|
||||
start1 = this.fromString(start1);
|
||||
end1 = this.fromString(end1);
|
||||
|
||||
let isOverlapping: boolean =
|
||||
moment(start).isBetween(start1, end1) ||
|
||||
moment(end).isBetween(start1, end1) ||
|
||||
moment(start).isSame(start1) ||
|
||||
moment(end).isSame(end1);
|
||||
|
||||
if (!isOverlapping) {
|
||||
// check if the start1 and end1 are in between start and end
|
||||
|
||||
isOverlapping =
|
||||
moment(start1).isBetween(start, end) ||
|
||||
moment(end1).isBetween(start, end) ||
|
||||
moment(start1).isSame(start) ||
|
||||
moment(end1).isSame(end);
|
||||
}
|
||||
|
||||
return isOverlapping;
|
||||
}
|
||||
|
||||
public static getCurrentDate(): Date {
|
||||
return moment().toDate();
|
||||
}
|
||||
@@ -13,7 +79,139 @@ export default class OneUptimeDate {
|
||||
return moment(date).fromNow();
|
||||
}
|
||||
|
||||
public static toString(date: Date): string {
|
||||
public static toTimeString(date: Date | string): string {
|
||||
if (typeof date === 'string') {
|
||||
date = this.fromString(date);
|
||||
}
|
||||
|
||||
return moment(date).format('HH:mm');
|
||||
}
|
||||
|
||||
public static isSame(date1: Date, date2: Date): boolean {
|
||||
date1 = this.fromString(date1);
|
||||
date2 = this.fromString(date2);
|
||||
return moment(date1).isSame(date2);
|
||||
}
|
||||
|
||||
public static getDaysBetweenTwoDates(
|
||||
startDate: Date,
|
||||
endDate: Date
|
||||
): number {
|
||||
startDate = this.fromString(startDate);
|
||||
endDate = this.fromString(endDate);
|
||||
return moment(endDate).diff(moment(startDate), 'days');
|
||||
}
|
||||
|
||||
public static getDaysBetweenTwoDatesInclusive(
|
||||
startDate: Date,
|
||||
endDate: Date
|
||||
): number {
|
||||
return this.getDaysBetweenTwoDates(startDate, endDate) + 1;
|
||||
}
|
||||
|
||||
public static getHoursBetweenTwoDates(
|
||||
startDate: Date,
|
||||
endDate: Date
|
||||
): number {
|
||||
startDate = this.fromString(startDate);
|
||||
endDate = this.fromString(endDate);
|
||||
return moment(endDate).diff(moment(startDate), 'hours');
|
||||
}
|
||||
|
||||
public static getHoursBetweenTwoDatesInclusive(
|
||||
startDate: Date,
|
||||
endDate: Date
|
||||
): number {
|
||||
return this.getHoursBetweenTwoDates(startDate, endDate) + 1;
|
||||
}
|
||||
|
||||
public static getMinutesBetweenTwoDates(
|
||||
startDate: Date,
|
||||
endDate: Date
|
||||
): number {
|
||||
startDate = this.fromString(startDate);
|
||||
endDate = this.fromString(endDate);
|
||||
return moment(endDate).diff(moment(startDate), 'minutes');
|
||||
}
|
||||
|
||||
public static getMinutesBetweenTwoDatesInclusive(
|
||||
startDate: Date,
|
||||
endDate: Date
|
||||
): number {
|
||||
return this.getMinutesBetweenTwoDates(startDate, endDate) + 1;
|
||||
}
|
||||
|
||||
public static getSecondsBetweenTwoDates(
|
||||
startDate: Date,
|
||||
endDate: Date
|
||||
): number {
|
||||
startDate = this.fromString(startDate);
|
||||
endDate = this.fromString(endDate);
|
||||
return moment(endDate).diff(moment(startDate), 'seconds');
|
||||
}
|
||||
|
||||
public static getSecondsBetweenTwoDatesInclusive(
|
||||
startDate: Date,
|
||||
endDate: Date
|
||||
): number {
|
||||
return this.getSecondsBetweenTwoDates(startDate, endDate) + 1;
|
||||
}
|
||||
|
||||
public static getWeeksBetweenTwoDates(
|
||||
startDate: Date,
|
||||
endDate: Date
|
||||
): number {
|
||||
startDate = this.fromString(startDate);
|
||||
endDate = this.fromString(endDate);
|
||||
return moment(endDate).diff(moment(startDate), 'weeks');
|
||||
}
|
||||
|
||||
public static getWeeksBetweenTwoDatesInclusive(
|
||||
startDate: Date,
|
||||
endDate: Date
|
||||
): number {
|
||||
return this.getWeeksBetweenTwoDates(startDate, endDate) + 1;
|
||||
}
|
||||
|
||||
public static getMonthsBetweenTwoDates(
|
||||
startDate: Date,
|
||||
endDate: Date
|
||||
): number {
|
||||
startDate = this.fromString(startDate);
|
||||
endDate = this.fromString(endDate);
|
||||
return moment(endDate).diff(moment(startDate), 'months');
|
||||
}
|
||||
|
||||
public static getMonthsBetweenTwoDatesInclusive(
|
||||
startDate: Date,
|
||||
endDate: Date
|
||||
): number {
|
||||
return this.getMonthsBetweenTwoDates(startDate, endDate) + 1;
|
||||
}
|
||||
|
||||
public static getYearsBetweenTwoDates(
|
||||
startDate: Date,
|
||||
endDate: Date
|
||||
): number {
|
||||
startDate = this.fromString(startDate);
|
||||
endDate = this.fromString(endDate);
|
||||
return moment(endDate).diff(moment(startDate), 'years');
|
||||
}
|
||||
|
||||
public static getYearsBetweenTwoDatesInclusive(
|
||||
startDate: Date,
|
||||
endDate: Date
|
||||
): number {
|
||||
return this.getYearsBetweenTwoDates(startDate, endDate) + 1;
|
||||
}
|
||||
|
||||
public static toString(date: Date | undefined): string {
|
||||
if (!date) {
|
||||
return '';
|
||||
}
|
||||
|
||||
date = this.fromString(date);
|
||||
|
||||
return date.toISOString();
|
||||
}
|
||||
|
||||
@@ -21,6 +219,19 @@ export default class OneUptimeDate {
|
||||
return moment();
|
||||
}
|
||||
|
||||
public static keepTimeButMoveDay(keepTimeFor: Date, moveDayTo: Date): Date {
|
||||
keepTimeFor = this.fromString(keepTimeFor);
|
||||
moveDayTo = this.fromString(moveDayTo);
|
||||
return moment(moveDayTo)
|
||||
.set({
|
||||
hour: keepTimeFor.getHours(),
|
||||
minute: keepTimeFor.getMinutes(),
|
||||
second: keepTimeFor.getSeconds(),
|
||||
millisecond: keepTimeFor.getMilliseconds(),
|
||||
})
|
||||
.toDate();
|
||||
}
|
||||
|
||||
public static getOneMinAgo(): Date {
|
||||
return this.getSomeMinutesAgo(new PositiveNumber(1));
|
||||
}
|
||||
@@ -29,6 +240,10 @@ export default class OneUptimeDate {
|
||||
return this.getSomeDaysAgo(new PositiveNumber(1));
|
||||
}
|
||||
|
||||
public static fromUnixNano(timestamp: number): Date {
|
||||
return moment(timestamp / 1000000).toDate();
|
||||
}
|
||||
|
||||
public static getSecondsTo(date: Date): number {
|
||||
date = this.fromString(date);
|
||||
const dif: number = date.getTime() - this.getCurrentDate().getTime();
|
||||
@@ -81,11 +296,78 @@ export default class OneUptimeDate {
|
||||
};
|
||||
}
|
||||
|
||||
public static areOnTheSameDay(date1: Date, date2: Date): boolean {
|
||||
date1 = this.fromString(date1);
|
||||
date2 = this.fromString(date2);
|
||||
return moment(date1).isSame(date2, 'day');
|
||||
}
|
||||
|
||||
public static areOnTheSameMonth(date1: Date, date2: Date): boolean {
|
||||
date1 = this.fromString(date1);
|
||||
date2 = this.fromString(date2);
|
||||
return moment(date1).isSame(date2, 'month');
|
||||
}
|
||||
|
||||
public static areOnTheSameYear(date1: Date, date2: Date): boolean {
|
||||
date1 = this.fromString(date1);
|
||||
date2 = this.fromString(date2);
|
||||
return moment(date1).isSame(date2, 'year');
|
||||
}
|
||||
|
||||
public static areOnTheSameHour(date1: Date, date2: Date): boolean {
|
||||
date1 = this.fromString(date1);
|
||||
date2 = this.fromString(date2);
|
||||
return moment(date1).isSame(date2, 'hour');
|
||||
}
|
||||
|
||||
public static areOnTheSameMinute(date1: Date, date2: Date): boolean {
|
||||
date1 = this.fromString(date1);
|
||||
date2 = this.fromString(date2);
|
||||
return moment(date1).isSame(date2, 'minute');
|
||||
}
|
||||
|
||||
public static areOnTheSameSecond(date1: Date, date2: Date): boolean {
|
||||
date1 = this.fromString(date1);
|
||||
date2 = this.fromString(date2);
|
||||
return moment(date1).isSame(date2, 'second');
|
||||
}
|
||||
|
||||
public static areOnTheSameWeek(date1: Date, date2: Date): boolean {
|
||||
date1 = this.fromString(date1);
|
||||
date2 = this.fromString(date2);
|
||||
return moment(date1).isSame(date2, 'week');
|
||||
}
|
||||
|
||||
public static addRemoveMinutes(date: Date, minutes: number): Date {
|
||||
date = this.fromString(date);
|
||||
return moment(date).add(minutes, 'minutes').toDate();
|
||||
}
|
||||
|
||||
public static addRemoveDays(date: Date, days: number): Date {
|
||||
date = this.fromString(date);
|
||||
return moment(date).add(days, 'days').toDate();
|
||||
}
|
||||
|
||||
public static addRemoveHours(date: Date, hours: number): Date {
|
||||
date = this.fromString(date);
|
||||
return moment(date).add(hours, 'hours').toDate();
|
||||
}
|
||||
|
||||
public static addRemoveYears(date: Date, years: number): Date {
|
||||
date = this.fromString(date);
|
||||
return moment(date).add(years, 'years').toDate();
|
||||
}
|
||||
|
||||
public static addRemoveMonths(date: Date, months: number): Date {
|
||||
date = this.fromString(date);
|
||||
return moment(date).add(months, 'months').toDate();
|
||||
}
|
||||
|
||||
public static addRemoveWeeks(date: Date, weeks: number): Date {
|
||||
date = this.fromString(date);
|
||||
return moment(date).add(weeks, 'weeks').toDate();
|
||||
}
|
||||
|
||||
public static addRemoveSeconds(date: Date, seconds: number): Date {
|
||||
date = this.fromString(date);
|
||||
return moment(date).add(seconds, 'seconds').toDate();
|
||||
@@ -98,6 +380,10 @@ export default class OneUptimeDate {
|
||||
return days.positiveNumber * 24 * 60 * 60;
|
||||
}
|
||||
|
||||
public static getMillisecondsInDays(days: PositiveNumber | number): number {
|
||||
return this.getSecondsInDays(days) * 1000;
|
||||
}
|
||||
|
||||
public static getSomeHoursAgo(hours: PositiveNumber | number): Date {
|
||||
if (!(hours instanceof PositiveNumber)) {
|
||||
hours = new PositiveNumber(hours);
|
||||
@@ -221,7 +507,7 @@ export default class OneUptimeDate {
|
||||
let hasMins: boolean = false;
|
||||
if (hours !== '00') {
|
||||
hasHours = true;
|
||||
text += hours + ' hours';
|
||||
text += hours + ' hours ';
|
||||
}
|
||||
|
||||
if (mins !== '00' || hasHours) {
|
||||
@@ -231,7 +517,7 @@ export default class OneUptimeDate {
|
||||
text += ', ';
|
||||
}
|
||||
|
||||
text += mins + ' minutes';
|
||||
text += mins + ' minutes ';
|
||||
}
|
||||
|
||||
if (!(hasHours && hasMins)) {
|
||||
@@ -351,6 +637,51 @@ export default class OneUptimeDate {
|
||||
return moment(date).isAfter(startDate);
|
||||
}
|
||||
|
||||
public static isOnOrAfter(date: Date, startDate: Date): boolean {
|
||||
date = this.fromString(date);
|
||||
startDate = this.fromString(startDate);
|
||||
return moment(date).isSameOrAfter(startDate);
|
||||
}
|
||||
|
||||
public static getDayOfWeek(date: Date): DayOfWeek {
|
||||
const dayOfWeek: number = this.geyDayOfWeekAsNumber(date);
|
||||
|
||||
if (dayOfWeek === 1) {
|
||||
return DayOfWeek.Monday;
|
||||
} else if (dayOfWeek === 2) {
|
||||
return DayOfWeek.Tuesday;
|
||||
} else if (dayOfWeek === 3) {
|
||||
return DayOfWeek.Wednesday;
|
||||
} else if (dayOfWeek === 4) {
|
||||
return DayOfWeek.Thursday;
|
||||
} else if (dayOfWeek === 5) {
|
||||
return DayOfWeek.Friday;
|
||||
} else if (dayOfWeek === 6) {
|
||||
return DayOfWeek.Saturday;
|
||||
} else if (dayOfWeek === 7) {
|
||||
return DayOfWeek.Sunday;
|
||||
}
|
||||
|
||||
throw new BadDataException('Invalid day of week');
|
||||
}
|
||||
|
||||
public static geyDayOfWeekAsNumber(date: Date): number {
|
||||
date = this.fromString(date);
|
||||
return moment(date).isoWeekday();
|
||||
}
|
||||
|
||||
public static isOnOrBefore(date: Date, endDate: Date): boolean {
|
||||
date = this.fromString(date);
|
||||
endDate = this.fromString(endDate);
|
||||
return moment(date).isSameOrBefore(endDate);
|
||||
}
|
||||
|
||||
public static isEqualBySeconds(date: Date, startDate: Date): boolean {
|
||||
date = this.fromString(date);
|
||||
startDate = this.fromString(startDate);
|
||||
return moment(date).isSame(startDate, 'seconds');
|
||||
}
|
||||
|
||||
public static hasExpired(expirationDate: Date): boolean {
|
||||
expirationDate = this.fromString(expirationDate);
|
||||
return !moment(this.getCurrentDate()).isBefore(expirationDate);
|
||||
@@ -544,4 +875,37 @@ export default class OneUptimeDate {
|
||||
OneUptimeDate.getEndOfDay(formattedDate)
|
||||
);
|
||||
}
|
||||
|
||||
public static getDateWithCustomTime(data: {
|
||||
hours: number;
|
||||
minutes: number;
|
||||
seconds: number;
|
||||
}): Date {
|
||||
const hour: number = data.hours;
|
||||
const minutes: number = data.minutes;
|
||||
const seconds: number = data.seconds;
|
||||
|
||||
//validate the hour
|
||||
if (hour < 0 || hour > 23) {
|
||||
throw new BadDataException('Invalid hour');
|
||||
}
|
||||
|
||||
//validate the minutes
|
||||
if (minutes < 0 || minutes > 59) {
|
||||
throw new BadDataException('Invalid minutes');
|
||||
}
|
||||
|
||||
//validate the seconds
|
||||
if (seconds < 0 || seconds > 59) {
|
||||
throw new BadDataException('Invalid seconds');
|
||||
}
|
||||
|
||||
const date: Date = OneUptimeDate.getCurrentDate();
|
||||
|
||||
date.setHours(hour);
|
||||
date.setMinutes(minutes);
|
||||
date.setSeconds(seconds);
|
||||
|
||||
return date;
|
||||
}
|
||||
}
|
||||
|
||||
32
Common/Types/Day/DayOfWeek.ts
Normal file
32
Common/Types/Day/DayOfWeek.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
enum DayOfWeek {
|
||||
Sunday = 'Sunday',
|
||||
Monday = 'Monday',
|
||||
Tuesday = 'Tuesday',
|
||||
Wednesday = 'Wednesday',
|
||||
Thursday = 'Thursday',
|
||||
Friday = 'Friday',
|
||||
Saturday = 'Saturday',
|
||||
}
|
||||
|
||||
export class DayOfWeekUtil {
|
||||
public static getNumberOfDayOfWeek(dayOfWeek: DayOfWeek): number {
|
||||
switch (dayOfWeek) {
|
||||
case DayOfWeek.Sunday:
|
||||
return 0;
|
||||
case DayOfWeek.Monday:
|
||||
return 1;
|
||||
case DayOfWeek.Tuesday:
|
||||
return 2;
|
||||
case DayOfWeek.Wednesday:
|
||||
return 3;
|
||||
case DayOfWeek.Thursday:
|
||||
return 4;
|
||||
case DayOfWeek.Friday:
|
||||
return 5;
|
||||
case DayOfWeek.Saturday:
|
||||
return 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default DayOfWeek;
|
||||
46
Common/Types/DiskSize.ts
Normal file
46
Common/Types/DiskSize.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import BadDataException from './Exception/BadDataException';
|
||||
|
||||
export default class DiskSize {
|
||||
public static convertToDecimalPlaces(
|
||||
value: number,
|
||||
decimalPlaces: number = 2
|
||||
): number {
|
||||
if (decimalPlaces < 0) {
|
||||
throw new BadDataException(
|
||||
'decimalPlaces must be greater than or equal to 0.'
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof value === 'string') {
|
||||
value = parseFloat(value);
|
||||
}
|
||||
|
||||
if (decimalPlaces === 0) {
|
||||
return Math.ceil(value);
|
||||
}
|
||||
|
||||
value = value * Math.pow(10, decimalPlaces);
|
||||
|
||||
// convert to int.
|
||||
|
||||
value = Math.round(value);
|
||||
|
||||
// convert back to float.
|
||||
|
||||
value = value / Math.pow(10, decimalPlaces);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static byteSizeToGB(byteSize: number): number {
|
||||
return byteSize / 1024 / 1024 / 1024;
|
||||
}
|
||||
|
||||
public static byteSizeToMB(byteSize: number): number {
|
||||
return byteSize / 1024 / 1024;
|
||||
}
|
||||
|
||||
public static byteSizeToKB(byteSize: number): number {
|
||||
return byteSize / 1024;
|
||||
}
|
||||
}
|
||||
9
Common/Types/Events/EventInterval.ts
Normal file
9
Common/Types/Events/EventInterval.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
enum EventInterval {
|
||||
Hour = 'Hour',
|
||||
Day = 'Day',
|
||||
Week = 'Week',
|
||||
Month = 'Month',
|
||||
Year = 'Year',
|
||||
}
|
||||
|
||||
export default EventInterval;
|
||||
119
Common/Types/Events/Recurring.ts
Normal file
119
Common/Types/Events/Recurring.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
import { FindOperator } from 'typeorm';
|
||||
import DatabaseProperty from '../Database/DatabaseProperty';
|
||||
import EventInterval from './EventInterval';
|
||||
import BadDataException from '../Exception/BadDataException';
|
||||
import { JSONObject, ObjectType } from '../JSON';
|
||||
import JSONFunctions from '../JSONFunctions';
|
||||
import PositiveNumber from '../PositiveNumber';
|
||||
|
||||
export interface RecurringData extends JSONObject {
|
||||
intervalType: EventInterval;
|
||||
intervalCount: PositiveNumber;
|
||||
}
|
||||
|
||||
export default class Recurring extends DatabaseProperty {
|
||||
public static getDefaultRotationData(): RecurringData {
|
||||
return {
|
||||
intervalType: EventInterval.Day,
|
||||
intervalCount: new PositiveNumber(1),
|
||||
};
|
||||
}
|
||||
|
||||
private data: RecurringData = Recurring.getDefaultRotationData();
|
||||
|
||||
public get intervalType(): EventInterval {
|
||||
return this.data.intervalType;
|
||||
}
|
||||
public set intervalType(v: EventInterval) {
|
||||
this.data.intervalType = v;
|
||||
}
|
||||
|
||||
// intervalCount
|
||||
|
||||
public get intervalCount(): PositiveNumber {
|
||||
return this.data.intervalCount;
|
||||
}
|
||||
|
||||
public set intervalCount(v: PositiveNumber) {
|
||||
this.data.intervalCount = v;
|
||||
}
|
||||
|
||||
public constructor() {
|
||||
super();
|
||||
|
||||
this.data = Recurring.getDefaultRotationData();
|
||||
}
|
||||
|
||||
public static getDefault(): Recurring {
|
||||
return new Recurring();
|
||||
}
|
||||
|
||||
public override toJSON(): JSONObject {
|
||||
return JSONFunctions.serialize({
|
||||
_type: ObjectType.Recurring,
|
||||
value: {
|
||||
intervalType: this.intervalType,
|
||||
intervalCount: this.intervalCount.toJSON(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
public static override fromJSON(json: JSONObject | Recurring): Recurring {
|
||||
if (json instanceof Recurring) {
|
||||
return json;
|
||||
}
|
||||
|
||||
if (!json || json['_type'] !== ObjectType.Recurring) {
|
||||
throw new BadDataException('Invalid Rotation');
|
||||
}
|
||||
|
||||
if (!json['value']) {
|
||||
throw new BadDataException('Invalid Rotation');
|
||||
}
|
||||
|
||||
json = json['value'] as JSONObject;
|
||||
|
||||
let intervalType: EventInterval = EventInterval.Day;
|
||||
|
||||
if (json && json['intervalType']) {
|
||||
intervalType = json['intervalType'] as EventInterval;
|
||||
}
|
||||
|
||||
let intervalCount: PositiveNumber = new PositiveNumber(1);
|
||||
|
||||
if (json && json['intervalCount']) {
|
||||
intervalCount = PositiveNumber.fromJSON(json['intervalCount']);
|
||||
}
|
||||
|
||||
const rotation: Recurring = new Recurring();
|
||||
|
||||
rotation.data = {
|
||||
intervalType,
|
||||
intervalCount,
|
||||
};
|
||||
|
||||
return rotation;
|
||||
}
|
||||
|
||||
protected static override toDatabase(
|
||||
value: Recurring | FindOperator<Recurring>
|
||||
): JSONObject | null {
|
||||
if (value && value instanceof Recurring) {
|
||||
return (value as Recurring).toJSON();
|
||||
} else if (value) {
|
||||
return JSONFunctions.serialize(value as any);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected static override fromDatabase(
|
||||
value: JSONObject
|
||||
): Recurring | null {
|
||||
if (value) {
|
||||
return Recurring.fromJSON(value);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
11
Common/Types/HashCode.ts
Normal file
11
Common/Types/HashCode.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
export default class HashCode {
|
||||
public static fromString(text: string): number {
|
||||
let hash: number = 0;
|
||||
for (let i: number = 0; i < text.length; i++) {
|
||||
const code: number = text.charCodeAt(i);
|
||||
hash = (hash << 5) - hash + code;
|
||||
hash = hash & hash; // Convert to 32bit integer
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
@@ -10,12 +10,23 @@ enum IconProp {
|
||||
Settings = 'Settings',
|
||||
Criteria = 'Criteria',
|
||||
Notification = 'Notification',
|
||||
CursorArrowRays = 'CursorArrowRays',
|
||||
ArrowUpDown = 'ArrowUpDown',
|
||||
Cube = 'Cube',
|
||||
Squares = 'Squares',
|
||||
RectangleStack = 'RectangleStack',
|
||||
ChartBar = 'ChartBar',
|
||||
SquareStack = 'SquareStack',
|
||||
Calendar = 'Calendar',
|
||||
Help = 'Help',
|
||||
JSON = 'JSON',
|
||||
Signal = 'Signal',
|
||||
Stop = 'Stop',
|
||||
Database = 'Database',
|
||||
ChevronDown = 'ChevronDown',
|
||||
Pencil = 'Pencil',
|
||||
Flag = 'Flag',
|
||||
Copy = 'Copy',
|
||||
ChevronRight = 'ChevronRight',
|
||||
ChevronUp = 'ChevronUp',
|
||||
Play = 'Play',
|
||||
@@ -25,6 +36,7 @@ enum IconProp {
|
||||
Home = 'Home',
|
||||
Graph = 'Graph',
|
||||
Variable = 'Variable',
|
||||
ListBullet = 'ListBullet',
|
||||
Image = 'Image',
|
||||
Grid = 'Grid',
|
||||
More = 'More',
|
||||
|
||||
@@ -23,6 +23,8 @@ import EqualToOrNull from './Database/EqualToOrNull';
|
||||
import NotEqual from './Database/NotEqual';
|
||||
import { CheckOn, FilterType } from './Monitor/CriteriaFilter';
|
||||
import CallRequest from './Call/CallRequest';
|
||||
import PositiveNumber from './PositiveNumber';
|
||||
import StartAndEndTime from './Time/StartAndEndTime';
|
||||
|
||||
export enum ObjectType {
|
||||
ObjectID = 'ObjectID',
|
||||
@@ -30,7 +32,10 @@ export enum ObjectType {
|
||||
EqualToOrNull = 'EqualToOrNull',
|
||||
MonitorSteps = 'MonitorSteps',
|
||||
MonitorStep = 'MonitorStep',
|
||||
Recurring = 'Recurring',
|
||||
RestrictionTimes = 'RestrictionTimes',
|
||||
MonitorCriteria = 'MonitorCriteria',
|
||||
PositiveNumber = 'PositiveNumber',
|
||||
MonitorCriteriaInstance = 'MonitorCriteriaInstance',
|
||||
NotEqual = 'NotEqual',
|
||||
Email = 'Email',
|
||||
@@ -106,6 +111,8 @@ export type JSONValue =
|
||||
| Array<GreaterThan>
|
||||
| GreaterThanOrEqual
|
||||
| Array<GreaterThanOrEqual>
|
||||
| PositiveNumber
|
||||
| Array<PositiveNumber>
|
||||
| LessThan
|
||||
| Array<LessThan>
|
||||
| InBetween
|
||||
@@ -123,9 +130,12 @@ export type JSONValue =
|
||||
| Array<JSONValue>
|
||||
| Array<Permission>
|
||||
| Array<JSONValue>
|
||||
| Array<ObjectID>
|
||||
| CallRequest
|
||||
| undefined
|
||||
| null;
|
||||
| null
|
||||
| StartAndEndTime
|
||||
| Array<StartAndEndTime>;
|
||||
|
||||
export interface JSONObject {
|
||||
[x: string]: JSONValue;
|
||||
|
||||
@@ -3,8 +3,6 @@ import DatabaseProperty from './Database/DatabaseProperty';
|
||||
import OneUptimeDate from './Date';
|
||||
import BaseModel from '../Models/BaseModel';
|
||||
import { JSONArray, JSONObject, JSONValue, ObjectType } from './JSON';
|
||||
import { TableColumnMetadata } from '../Types/Database/TableColumn';
|
||||
import TableColumnType from './BaseDatabase/TableColumnType';
|
||||
import SerializableObject from './SerializableObject';
|
||||
import SerializableObjectDictionary from './SerializableObjectDictionary';
|
||||
import JSON5 from 'json5';
|
||||
@@ -20,182 +18,6 @@ export default class JSONFunctions {
|
||||
return Object.keys(obj).length === 0;
|
||||
}
|
||||
|
||||
public static toJSON(
|
||||
model: BaseModel,
|
||||
modelType: { new (): BaseModel }
|
||||
): JSONObject {
|
||||
const json: JSONObject = this.toJSONObject(model, modelType);
|
||||
return JSONFunctions.serialize(json);
|
||||
}
|
||||
|
||||
public static toJSONObject(
|
||||
model: BaseModel,
|
||||
modelType: { new (): BaseModel }
|
||||
): JSONObject {
|
||||
const json: JSONObject = {};
|
||||
|
||||
const vanillaModel: BaseModel = new modelType();
|
||||
|
||||
for (const key of vanillaModel.getTableColumns().columns) {
|
||||
if ((model as any)[key] === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const tableColumnMetadata: TableColumnMetadata =
|
||||
vanillaModel.getTableColumnMetadata(key);
|
||||
|
||||
if (tableColumnMetadata) {
|
||||
if (
|
||||
(model as any)[key] &&
|
||||
tableColumnMetadata.modelType &&
|
||||
tableColumnMetadata.type === TableColumnType.Entity &&
|
||||
(model as any)[key] instanceof BaseModel
|
||||
) {
|
||||
(json as any)[key] = this.toJSONObject(
|
||||
(model as any)[key],
|
||||
tableColumnMetadata.modelType
|
||||
);
|
||||
} else if (
|
||||
(model as any)[key] &&
|
||||
Array.isArray((model as any)[key]) &&
|
||||
(model as any)[key].length > 0 &&
|
||||
tableColumnMetadata.modelType &&
|
||||
tableColumnMetadata.type === TableColumnType.EntityArray
|
||||
) {
|
||||
(json as any)[key] = this.toJSONObjectArray(
|
||||
(model as any)[key] as Array<BaseModel>,
|
||||
tableColumnMetadata.modelType
|
||||
);
|
||||
} else {
|
||||
(json as any)[key] = (model as any)[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
public static toJSONObjectArray(
|
||||
list: Array<BaseModel>,
|
||||
modelType: { new (): BaseModel }
|
||||
): JSONArray {
|
||||
const array: JSONArray = [];
|
||||
|
||||
for (const item of list) {
|
||||
array.push(this.toJSONObject(item, modelType));
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
public static toJSONArray(
|
||||
list: Array<BaseModel>,
|
||||
modelType: { new (): BaseModel }
|
||||
): JSONArray {
|
||||
const array: JSONArray = [];
|
||||
|
||||
for (const item of list) {
|
||||
array.push(this.toJSON(item, modelType));
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
private static _fromJSON<T extends BaseModel>(
|
||||
json: JSONObject | T,
|
||||
type: { new (): T }
|
||||
): T {
|
||||
if (json instanceof BaseModel) {
|
||||
return json;
|
||||
}
|
||||
|
||||
json = JSONFunctions.deserialize(json);
|
||||
const baseModel: T = new type();
|
||||
|
||||
for (const key of Object.keys(json)) {
|
||||
const tableColumnMetadata: TableColumnMetadata =
|
||||
baseModel.getTableColumnMetadata(key);
|
||||
if (tableColumnMetadata) {
|
||||
if (
|
||||
json[key] &&
|
||||
tableColumnMetadata.modelType &&
|
||||
tableColumnMetadata.type === TableColumnType.Entity
|
||||
) {
|
||||
if (
|
||||
json[key] &&
|
||||
Array.isArray(json[key]) &&
|
||||
(json[key] as Array<any>).length > 0
|
||||
) {
|
||||
json[key] = (json[key] as Array<any>)[0];
|
||||
}
|
||||
|
||||
(baseModel as any)[key] = this.fromJSON(
|
||||
json[key] as JSONObject,
|
||||
tableColumnMetadata.modelType
|
||||
);
|
||||
} else if (
|
||||
json[key] &&
|
||||
tableColumnMetadata.modelType &&
|
||||
tableColumnMetadata.type === TableColumnType.EntityArray
|
||||
) {
|
||||
if (json[key] && !Array.isArray(json[key])) {
|
||||
json[key] = [json[key]];
|
||||
}
|
||||
|
||||
(baseModel as any)[key] = this.fromJSONArray(
|
||||
json[key] as JSONArray,
|
||||
tableColumnMetadata.modelType
|
||||
);
|
||||
} else {
|
||||
(baseModel as any)[key] = json[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return baseModel as T;
|
||||
}
|
||||
|
||||
public static fromJSON<T extends BaseModel>(
|
||||
json: JSONObject | JSONArray,
|
||||
type: { new (): T }
|
||||
): T | Array<T> {
|
||||
if (Array.isArray(json)) {
|
||||
const arr: Array<T> = [];
|
||||
|
||||
for (const item of json) {
|
||||
arr.push(this._fromJSON<T>(item, type));
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
return this._fromJSON<T>(json, type);
|
||||
}
|
||||
|
||||
public static fromJSONObject<T extends BaseModel>(
|
||||
json: JSONObject | T,
|
||||
type: { new (): T }
|
||||
): T {
|
||||
if (json instanceof BaseModel) {
|
||||
return json;
|
||||
}
|
||||
|
||||
return this.fromJSON<T>(json, type) as T;
|
||||
}
|
||||
|
||||
public static fromJSONArray<T extends BaseModel>(
|
||||
json: Array<JSONObject | T>,
|
||||
type: { new (): T }
|
||||
): Array<T> {
|
||||
const arr: Array<T> = [];
|
||||
|
||||
for (const item of json) {
|
||||
arr.push(this._fromJSON<T>(item, type));
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
public static toCompressedString(val: JSONValue): string {
|
||||
return JSON.stringify(val, null, 2);
|
||||
}
|
||||
@@ -262,7 +84,7 @@ export default class JSONFunctions {
|
||||
) {
|
||||
return val;
|
||||
} else if (val instanceof BaseModel) {
|
||||
return this.toJSON(val, BaseModel);
|
||||
return BaseModel.toJSON(val, BaseModel);
|
||||
} else if (typeof val === Typeof.Number) {
|
||||
return val;
|
||||
} else if (ArrayBuffer.isView(val)) {
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
export interface EnableWorkflowOn {
|
||||
create?: boolean | undefined;
|
||||
update?: boolean | undefined;
|
||||
delete?: boolean | undefined;
|
||||
read?: boolean | undefined;
|
||||
}
|
||||
|
||||
export default (enableWorkflowOn: EnableWorkflowOn) => {
|
||||
return (ctr: Function) => {
|
||||
ctr.prototype.enableWorkflowOn = enableWorkflowOn;
|
||||
};
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user