Compare commits

...

110 Commits

Author SHA1 Message Date
eb2bdf34e8 chore(deps): update node.js to v20.14.0 (#109)
All checks were successful
ci/woodpecker/push/test Pipeline was successful
Reviewed-on: #109
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-05-31 06:49:13 +00:00
7604489d29 chore(deps): update caddy docker tag to v2.8.1 (#110)
Some checks failed
ci/woodpecker/push/test Pipeline failed
Reviewed-on: #110
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-05-31 06:49:06 +00:00
29196585ab chore(deps): update dependency axios to v1.7.2 (#108)
All checks were successful
ci/woodpecker/push/test Pipeline was successful
Reviewed-on: #108
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-05-22 04:12:57 +00:00
6e0842b4f9 chore(deps): update dependency axios to v1.7.1 (#107)
All checks were successful
ci/woodpecker/push/test Pipeline was successful
Reviewed-on: #107
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-05-21 04:21:38 +00:00
2708918862 chore(deps): update dependency @types/lodash to v4.17.4 (#105)
All checks were successful
ci/woodpecker/push/test Pipeline was successful
Reviewed-on: #105
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-05-19 05:43:48 +00:00
73189203f3 chore(deps): update dependency eslint-config-prettier to v9.1.0 (#89)
All checks were successful
ci/woodpecker/push/test Pipeline was successful
Reviewed-on: #89
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-05-18 05:55:49 +00:00
ce584fd292 chore(deps): update dependency typescript to v5.4.5 (#99)
Some checks failed
ci/woodpecker/push/test Pipeline failed
Reviewed-on: #99
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-05-18 05:55:33 +00:00
a6f4d4616e chore(deps): update node.js to v20.13.1 (#106)
Some checks failed
ci/woodpecker/push/test Pipeline failed
Reviewed-on: #106
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-05-18 05:55:19 +00:00
50a42f91f0 chore(deps): update commitlint monorepo to v19.3.0 (#102)
Some checks failed
ci/woodpecker/push/test Pipeline failed
Reviewed-on: #102
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-05-18 05:55:07 +00:00
9797bbb9d9 chore(deps): update dependency @types/jquery to v3.5.30 (#104)
All checks were successful
ci/woodpecker/push/test Pipeline was successful
Reviewed-on: #104
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-05-17 03:38:07 +00:00
c5005680b4 chore(deps): update dependency @types/lodash to v4.17.3 (#66)
Some checks failed
ci/woodpecker/push/test Pipeline failed
Reviewed-on: #66
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-05-17 03:38:00 +00:00
99ef0c40de
chore: update README.md
All checks were successful
ci/woodpecker/push/test Pipeline was successful
ci/woodpecker/tag/docker Pipeline was successful
ci/woodpecker/tag/deployment Pipeline was successful
2024-04-05 07:41:58 +02:00
cab4709463
chore(deps): update dependency date-fns to v3
All checks were successful
ci/woodpecker/push/test Pipeline was successful
2024-04-05 06:38:20 +02:00
82b864946b chore(deps): update dependency husky to v9 (#98)
All checks were successful
ci/woodpecker/push/test Pipeline was successful
Reviewed-on: #98
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-04-04 03:50:40 +00:00
b43139bcbb
chore: caddy - enable file listings
All checks were successful
ci/woodpecker/push/test Pipeline was successful
2024-04-03 07:59:17 +02:00
81274707d3
chore: update README.md
All checks were successful
ci/woodpecker/push/test Pipeline was successful
2024-04-03 07:55:30 +02:00
f2ed75e4c8
chore: delete manifest.tmpl
All checks were successful
ci/woodpecker/push/test Pipeline was successful
ci/woodpecker/tag/docker Pipeline was successful
ci/woodpecker/tag/deployment Pipeline was successful
2024-04-03 07:44:06 +02:00
dc5f4a03de
chore: add linux/arm64 to docker buildx config
All checks were successful
ci/woodpecker/push/test Pipeline was successful
2024-04-03 07:41:07 +02:00
8496747ac8
chore: update README.md
All checks were successful
ci/woodpecker/push/test Pipeline was successful
2024-04-03 07:38:16 +02:00
a637e66258
chore: rename docs folder -> assets
All checks were successful
ci/woodpecker/push/test Pipeline was successful
2024-04-03 07:32:24 +02:00
0fbea77850
feat: specify timeout for api requests
All checks were successful
ci/woodpecker/push/test Pipeline was successful
2024-04-03 07:29:27 +02:00
0d034710b5
refactor: extended tribe profile - use /api/v2
All checks were successful
ci/woodpecker/push/test Pipeline was successful
2024-04-03 07:18:14 +02:00
998deef3aa
refactor: extended player profile - use /api/v2
All checks were successful
ci/woodpecker/push/test Pipeline was successful
2024-04-03 06:46:29 +02:00
a740a589be chore(deps): update dependency @types/jquery to v3.5.29 (#82)
All checks were successful
ci/woodpecker/push/test Pipeline was successful
Reviewed-on: #82
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-04-03 03:52:57 +00:00
8bffd2647b chore(deps): update commitlint monorepo to v19 (major) (#96)
All checks were successful
ci/woodpecker/push/test Pipeline was successful
Reviewed-on: #96
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-04-03 03:52:19 +00:00
af3fffae43
refactor: extended village profile - use /api/v2
All checks were successful
ci/woodpecker/push/test Pipeline was successful
2024-04-02 08:24:02 +02:00
a2fb6425a0
refactor: extended map popup - use /api/v2
All checks were successful
ci/woodpecker/push/test Pipeline was successful
2024-04-02 07:29:59 +02:00
93fa246f14 chore(deps): update dependency axios to v1.6.8 (#94)
All checks were successful
ci/woodpecker/push/test Pipeline was successful
Reviewed-on: #94
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-04-02 03:42:08 +00:00
fc9d1be2fe
chore: update README.md [skip ci] 2024-04-01 09:52:38 +02:00
aaabe449d5
chore: new domain - twhelp.app
All checks were successful
ci/woodpecker/push/test Pipeline was successful
2024-04-01 09:48:09 +02:00
ac571326c3
feat: /api/v2 - generate client
All checks were successful
ci/woodpecker/push/test Pipeline was successful
2024-04-01 09:45:33 +02:00
cceeb270c4 chore(deps): update commitlint monorepo to v18.6.1 (#92)
All checks were successful
ci/woodpecker/push/test Pipeline was successful
Reviewed-on: #92
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-04-01 07:22:44 +00:00
f94fd27432
chore: update ci/cd pipelines
All checks were successful
ci/woodpecker/push/test Pipeline was successful
2024-04-01 09:21:56 +02:00
1ddcbb66ed chore(deps): update dependency prettier to v3.2.5 (#93)
All checks were successful
ci/woodpecker/push/test Pipeline was successful
Reviewed-on: #93
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-04-01 07:17:41 +00:00
d099601b69 chore(deps): update dependency typescript to v5.4.3 (#88)
Some checks failed
ci/woodpecker/push/test Pipeline failed
Reviewed-on: #88
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-04-01 07:17:31 +00:00
ff364a93ea chore(deps): update node.js to v20 (#79)
All checks were successful
ci/woodpecker/push/test Pipeline was successful
Reviewed-on: #79
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-04-01 07:14:37 +00:00
f38e3d6954 chore(deps): update dependency @types/node to v18.19.14 (#81)
All checks were successful
ci/woodpecker/push/test Pipeline was successful
Reviewed-on: #81
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-02-02 06:39:01 +00:00
2bfc8b1c84 chore(deps): update dependency axios to v1.6.7 (#91)
Some checks failed
ci/woodpecker/push/test Pipeline failed
Reviewed-on: #91
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-02-02 06:38:48 +00:00
c2fd244639 chore(deps): update caddy docker tag to v2.7.6 (#90)
All checks were successful
ci/woodpecker/push/test Pipeline was successful
Reviewed-on: #90
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-01-13 08:48:23 +00:00
e69cf46abe chore(deps): update commitlint monorepo to v18.4.4 (#86)
All checks were successful
ci/woodpecker/push/test Pipeline was successful
Reviewed-on: #86
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-01-13 08:19:14 +00:00
56944664ac chore(deps): update commitlint monorepo to v18.4.1 (#85)
All checks were successful
ci/woodpecker/push/test Pipeline was successful
Reviewed-on: #85
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-11-16 04:20:25 +00:00
0427e0dd60 chore(deps): update dependency axios to v1.6.2 (#84)
Some checks failed
ci/woodpecker/push/test Pipeline failed
Reviewed-on: #84
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-11-16 04:20:13 +00:00
a6a68cd530 chore(deps): update parcel monorepo to v2.10.3 (#83)
Some checks failed
ci/woodpecker/push/test Pipeline failed
Reviewed-on: #83
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-11-16 04:20:03 +00:00
4bd12132f9 chore(deps): update commitlint monorepo to v18 (major) (#76)
All checks were successful
ci/woodpecker/push/test Pipeline was successful
Reviewed-on: #76
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-11-14 06:34:44 +00:00
d66e2de08d chore(deps): update dependency prettier to v3.1.0 (#77)
Some checks failed
ci/woodpecker/push/test Pipeline failed
Reviewed-on: #77
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-11-14 06:34:32 +00:00
00397f0aaf chore(deps): update dependency axios to v1.6.1 (#78)
Some checks failed
ci/woodpecker/push/test Pipeline failed
Reviewed-on: #78
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-11-14 06:34:25 +00:00
483ffa3ef7
chore: bump script versions
All checks were successful
ci/woodpecker/push/test Pipeline was successful
ci/woodpecker/tag/docker Pipeline was successful
ci/woodpecker/tag/deploy Pipeline was successful
2023-10-30 09:35:57 +01:00
54e5faeb44
chore: update alpine/k8s docker tag to v1.26.9
All checks were successful
ci/woodpecker/push/test Pipeline was successful
2023-10-30 09:34:38 +01:00
b7f08832d9 chore(deps): update dependency eslint-config-prettier to v9 (#58)
All checks were successful
ci/woodpecker/push/test Pipeline was successful
Reviewed-on: #58
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-10-30 08:33:43 +00:00
cfc26dd822 chore(deps): update dependency @types/jquery to v3.5.25 (#71)
Some checks failed
ci/woodpecker/push/test Pipeline failed
Reviewed-on: #71
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-10-30 08:33:36 +00:00
0cae454104 chore(deps): update dependency @types/node to v18.18.7 (#72)
Some checks failed
ci/woodpecker/push/test Pipeline failed
Reviewed-on: #72
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-10-30 08:33:24 +00:00
58dbb8433d chore(deps): update parcel monorepo to v2.10.1 (#75)
Some checks failed
ci/woodpecker/push/test Pipeline failed
Reviewed-on: #75
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-10-30 08:33:11 +00:00
4adc41cb7e chore(deps): update dependency prettier to v3 (#52)
Some checks failed
ci/woodpecker/push/test Pipeline failed
Reviewed-on: #52
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-10-30 08:32:56 +00:00
0bd3692516 chore(deps): update commitlint monorepo to v17.8.1 (#70)
All checks were successful
ci/woodpecker/push/test Pipeline was successful
Reviewed-on: #70
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-10-22 05:28:21 +00:00
fabfcf55e4 chore(deps): update dependency axios to v1.5.1 (#74)
Some checks failed
ci/woodpecker/push/test Pipeline failed
Reviewed-on: #74
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-10-22 05:28:12 +00:00
754ead62a3 chore(deps): update caddy docker tag to v2.7.5 (#73)
All checks were successful
ci/woodpecker/push/test Pipeline was successful
Reviewed-on: #73
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-10-21 04:48:37 +00:00
2f1e6e2bff chore(deps): update dependency @types/jquery to v3.5.21 (#65)
All checks were successful
ci/woodpecker/push/test Pipeline was successful
Reviewed-on: #65
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-10-07 03:34:56 +00:00
156c13e5e1 chore(deps): update dependency @types/node to v18.18.3 (#50)
Some checks failed
ci/woodpecker/push/test Pipeline failed
Reviewed-on: #50
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-10-07 03:34:38 +00:00
fe800229a5 chore(deps): update node.js to v18.18 (#68)
Some checks failed
ci/woodpecker/push/test Pipeline failed
Reviewed-on: #68
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-10-07 03:34:25 +00:00
24b5c4d24d
chore: remove unnecessary group [skip ci] 2023-09-09 07:23:05 +02:00
41614f5054
chore: bump user scripts versions
All checks were successful
ci/woodpecker/push/test Pipeline was successful
ci/woodpecker/tag/docker Pipeline was successful
ci/woodpecker/tag/deploy Pipeline was successful
2023-09-09 07:04:42 +02:00
4e54a84ff5 feat: migrate from drone to woodpecker (#67)
All checks were successful
ci/woodpecker/push/test Pipeline was successful
Reviewed-on: #67
2023-09-09 05:03:30 +00:00
900c173702 chore(deps): update dependency axios to v1.5.0 (#64)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #64
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-09-09 04:38:16 +00:00
03e151d4e1 chore(deps): update dependency typescript to v5.2.2 (#63)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #63
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-08-25 03:32:36 +00:00
26965f9f73
fix: metadata are added more than once to the output
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-19 07:55:46 +02:00
3140f56ae9 chore(deps): update commitlint monorepo to v17.7.1 (#59)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #59
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-08-19 05:46:10 +00:00
b53acc0499 chore(deps): update caddy docker tag to v2.7.4 (#61)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #61
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-08-18 08:18:53 +00:00
5952c4e0fb chore(deps): update caddy docker tag to v2.7.3 (#60)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #60
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-08-15 04:52:50 +00:00
7ab3ce1955 chore(deps): update dependency eslint-config-prettier to v8.10.0 (#56)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #56
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-08-05 04:29:25 +00:00
f868086570 chore(deps): update caddy docker tag to v2.7.2 (#57)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #57
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-08-05 04:29:14 +00:00
1987c99761 chore(deps): update typescript-eslint monorepo to v5.62.0 (#51)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #51
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-07-21 03:19:30 +00:00
9e21d30c77 chore(deps): update commitlint monorepo to v17.6.7 (#54)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #54
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-07-20 03:43:48 +00:00
b05d0413b1
feat: ci/cd - email notifications
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-01 14:14:58 +02:00
3f3e836177
chore: bump script versions
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
2023-07-01 09:52:57 +02:00
b3e6edb08e chore(deps): update dependency typescript to v5.1.6 (#49)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #49
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-06-30 03:28:03 +00:00
59e5933167 chore(deps): update dependency typescript to v5.1.5 (#48)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #48
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-06-29 03:34:22 +00:00
d609f87550 chore(deps): update parcel monorepo to v2.9.3 (#46)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #46
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-06-26 03:32:38 +00:00
83f142ad97 chore(deps): update commitlint monorepo to v17.6.6 (#45)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #45
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-06-25 14:12:57 +00:00
7bb73e9dce chore(deps): update typescript-eslint monorepo to v5.60.0 (#44)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #44
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-06-20 03:45:40 +00:00
4e8422c435 chore(deps): update parcel monorepo to v2.9.2 (#42)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #42
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-06-10 04:03:09 +00:00
56fbe86774
chore: update alpine/k8s to v1.26.5
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-09 06:59:27 +02:00
c26c7ebbc9 chore(deps): update dependency @types/lodash to v4.14.195 (#37)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #37
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-06-08 05:53:15 +00:00
8dc4faa06f chore(deps): update typescript-eslint monorepo to v5.59.9 (#41)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #41
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-06-06 03:23:11 +00:00
a968d42e8a
chore: bump typescript to v5.1.3 and remove npm-run-all from devDependencies
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-02 08:12:06 +02:00
0ff002ce1a
chore(deps): update parcel monorepo to v2.9.1
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-02 08:05:32 +02:00
24a9b7113f chore(deps): update commitlint monorepo to v17.6.5 (#39)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #39
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-06-02 03:20:49 +00:00
4a30e57fbf chore(deps): update typescript-eslint monorepo to v5.59.8 (#36)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #36
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-05-30 03:36:03 +00:00
31f276a981 chore(deps): update typescript-eslint monorepo to v5.59.6 (#35)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #35
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-05-16 04:01:48 +00:00
773d95e923 chore(deps): update typescript-eslint monorepo to v5.59.5 (#34)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #34
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-05-12 06:14:47 +00:00
9f33b32632 chore(deps): update dependency typescript to v5.0.4 (#30)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #30
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-05-07 06:11:38 +00:00
da32822563 chore(deps): update typescript-eslint monorepo to v5.59.2 (#32)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #32
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-05-07 06:11:29 +00:00
11cd008009 chore(deps): update commitlint monorepo to v17.6.3 (#33)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #33
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-05-07 06:11:19 +00:00
c6b51673d6 chore(deps): update dependency date-fns to v2.30.0 (#31)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #31
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-05-07 06:11:10 +00:00
b03bae4cd9
refactor: replace deprecated endpoints
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
2023-05-07 08:03:51 +02:00
c29f987caa
chore: update alpine/k8s docker tag to v1.26.4 [skip ci] 2023-05-01 06:54:04 +02:00
f2dd3d10a8 chore(deps): update dependency typescript to v5 (#14)
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
Reviewed-on: #14
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-04-30 04:27:40 +00:00
40c4fb7e7c chore(deps): update typescript-eslint monorepo to v5.59.1 (#22)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #22
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-04-30 04:27:16 +00:00
75b1d6987d chore(deps): update dependency @types/lodash to v4.14.194 (#23)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #23
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-04-29 04:09:03 +00:00
85ad186242 chore(deps): update dependency prettier to v2.8.8 (#29)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #29
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-04-29 04:08:51 +00:00
7763f8246d chore(deps): update dependency axios to v1.4.0 (#27)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #27
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-04-29 04:08:44 +00:00
8ecfce7ac9 chore(deps): update dependency axios to v1.3.5 (#25)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #25
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-04-16 14:06:53 +00:00
5c76bd3f14 chore(deps): update commitlint monorepo to v17.6.1 (#26)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #26
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-04-16 14:06:45 +00:00
dad998978c chore(deps): update dependency @commitlint/cli to v17.5.1 (#18)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #18
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-04-04 11:59:41 +00:00
0e1b744f5a chore(deps): update dependency eslint-config-prettier to v8.8.0 (#21)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #21
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-04-04 11:59:28 +00:00
5545e6617a chore(deps): update dependency axios to v1.3.4 (#20)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #20
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-04-04 11:59:18 +00:00
1d8480d90e chore(deps): update node.js to v16.20 (#24)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #24
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-03-31 03:45:06 +00:00
95ed638c2a chore(deps): update dependency @types/jquery to v3.5.16 (#15)
All checks were successful
continuous-integration/drone/push Build is passing
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [@types/jquery](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/jquery) ([source](https://github.com/DefinitelyTyped/DefinitelyTyped)) | devDependencies | patch | [`3.5.14` -> `3.5.16`](https://renovatebot.com/diffs/npm/@types%2fjquery/3.5.14/3.5.16) |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNS4yMC4wIiwidXBkYXRlZEluVmVyIjoiMzUuMjAuMCJ9-->

Co-authored-by: Renovate <renovate@dwysokinski.me>
Reviewed-on: #15
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-03-25 11:49:45 +00:00
3257e748e9 chore(deps): update dependency typescript to v4.9.5 (#17)
All checks were successful
continuous-integration/drone/push Build is passing
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [typescript](https://www.typescriptlang.org/) ([source](https://github.com/Microsoft/TypeScript)) | devDependencies | patch | [`4.9.4` -> `4.9.5`](https://renovatebot.com/diffs/npm/typescript/4.9.4/4.9.5) |

---

### Release Notes

<details>
<summary>Microsoft/TypeScript</summary>

### [`v4.9.5`](https://github.com/microsoft/TypeScript/releases/tag/v4.9.5): TypeScript 4.9.5

[Compare Source](https://github.com/Microsoft/TypeScript/compare/v4.9.4...v4.9.5)

For release notes, check out the [release announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-4-9/).

Downloads are available on:

-   [npm](https://www.npmjs.com/package/typescript)
-   [NuGet package](https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild)

#### Changes:

-   [`69e88ef`](69e88ef551) Port ignore deprecations to 4.9 ([#&#8203;52419](https://github.com/Microsoft/TypeScript/issues/52419))
-   [`daf4e81`](daf4e817a1) Port timestamp fix to 4.9 ([#&#8203;52426](https://github.com/Microsoft/TypeScript/issues/52426))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNS4yMC4wIiwidXBkYXRlZEluVmVyIjoiMzUuMjAuMCJ9-->

Co-authored-by: Renovate <renovate@dwysokinski.me>
Reviewed-on: #17
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-03-25 11:49:22 +00:00
6b037c00fd chore(deps): update dependency prettier to v2.8.7 (#16)
All checks were successful
continuous-integration/drone/push Build is passing
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [prettier](https://prettier.io) ([source](https://github.com/prettier/prettier)) | devDependencies | patch | [`2.8.3` -> `2.8.7`](https://renovatebot.com/diffs/npm/prettier/2.8.3/2.8.7) |

---

### Release Notes

<details>
<summary>prettier/prettier</summary>

### [`v2.8.7`](https://github.com/prettier/prettier/blob/HEAD/CHANGELOG.md#&#8203;287)

[Compare Source](https://github.com/prettier/prettier/compare/2.8.6...2.8.7)

[diff](https://github.com/prettier/prettier/compare/2.8.6...2.8.7)

##### Allow multiple decorators on same getter/setter ([#&#8203;14584](https://github.com/prettier/prettier/pull/14584) by [@&#8203;fisker](https://github.com/fisker))

<!-- prettier-ignore -->

```ts
// Input
class A {
  @&#8203;decorator()
  get foo () {}

  @&#8203;decorator()
  set foo (value) {}
}

// Prettier 2.8.6
SyntaxError: Decorators cannot be applied to multiple get/set accessors of the same name. (5:3)
  3 |   get foo () {}
  4 |
> 5 |   @&#8203;decorator()
    |   ^^^^^^^^^^^^
  6 |   set foo (value) {}
  7 | }

// Prettier 2.8.7
class A {
  @&#8203;decorator()
  get foo() {}

  @&#8203;decorator()
  set foo(value) {}
}
```

### [`v2.8.6`](https://github.com/prettier/prettier/blob/HEAD/CHANGELOG.md#&#8203;286)

[Compare Source](https://github.com/prettier/prettier/compare/2.8.5...2.8.6)

[diff](https://github.com/prettier/prettier/compare/2.8.5...2.8.6)

##### Allow decorators on private members and class expressions ([#&#8203;14548](https://github.com/prettier/prettier/pull/14548) by [@&#8203;fisker](https://github.com/fisker))

<!-- prettier-ignore -->

```ts
// Input
class A {
  @&#8203;decorator()
  #privateMethod () {}
}

// Prettier 2.8.5
SyntaxError: Decorators are not valid here. (2:3)
  1 | class A {
> 2 |   @&#8203;decorator()
    |   ^^^^^^^^^^^^
  3 |   #privateMethod () {}
  4 | }

// Prettier 2.8.6
class A {
  @&#8203;decorator()
  #privateMethod() {}
}
```

### [`v2.8.5`](https://github.com/prettier/prettier/blob/HEAD/CHANGELOG.md#&#8203;285)

[Compare Source](https://github.com/prettier/prettier/compare/2.8.4...2.8.5)

[diff](https://github.com/prettier/prettier/compare/2.8.4...2.8.5)

##### Support TypeScript 5.0 ([#&#8203;14391](https://github.com/prettier/prettier/pull/14391) by [@&#8203;fisker](https://github.com/fisker), [#&#8203;13819](https://github.com/prettier/prettier/pull/13819) by [@&#8203;fisker](https://github.com/fisker), [@&#8203;sosukesuzuki](https://github.com/sosukesuzuki))

TypeScript 5.0 introduces two new syntactic features:

-   `const` modifiers for type parameters
-   `export type *` declarations

##### Add missing parentheses for decorator ([#&#8203;14393](https://github.com/prettier/prettier/pull/14393) by [@&#8203;fisker](https://github.com/fisker))

<!-- prettier-ignore -->

```jsx
// Input
class Person {
  @&#8203;(myDecoratorArray[0])
  greet() {}
}

// Prettier 2.8.4
class Person {
  @&#8203;myDecoratorArray[0]
  greet() {}
}

// Prettier 2.8.5
class Person {
  @&#8203;(myDecoratorArray[0])
  greet() {}
}
```

##### Add parentheses for `TypeofTypeAnnotation` to improve readability ([#&#8203;14458](https://github.com/prettier/prettier/pull/14458) by [@&#8203;fisker](https://github.com/fisker))

<!-- prettier-ignore -->

```tsx
// Input
type A = (typeof node.children)[];

// Prettier 2.8.4
type A = typeof node.children[];

// Prettier 2.8.5
type A = (typeof node.children)[];
```

##### Support `max_line_length=off` when parsing `.editorconfig` ([#&#8203;14516](https://github.com/prettier/prettier/pull/14516) by [@&#8203;josephfrazier](https://github.com/josephfrazier))

If an .editorconfig file is in your project and it sets `max_line_length=off` for the file you're formatting,
it will be interpreted as a `printWidth` of `Infinity` rather than being ignored
(which previously resulted in the default `printWidth` of 80 being applied, if not overridden by Prettier-specific configuration).

<!-- prettier-ignore -->

```html
<!-- Input -->
<div className='HelloWorld' title={`You are visitor number ${ num }`} onMouseOver={onMouseOver}/>

<!-- Prettier 2.8.4 -->
<div
  className="HelloWorld"
  title={`You are visitor number ${num}`}
  onMouseOver={onMouseOver}
/>;

<!-- Prettier 2.8.5 -->
<div className="HelloWorld" title={`You are visitor number ${num}`} onMouseOver={onMouseOver} />;
```

### [`v2.8.4`](https://github.com/prettier/prettier/blob/HEAD/CHANGELOG.md#&#8203;284)

[Compare Source](https://github.com/prettier/prettier/compare/2.8.3...2.8.4)

[diff](https://github.com/prettier/prettier/compare/2.8.3...2.8.4)

##### Fix leading comments in mapped types with `readonly` ([#&#8203;13427](https://github.com/prettier/prettier/pull/13427) by [@&#8203;thorn0](https://github.com/thorn0), [@&#8203;sosukesuzuki](https://github.com/sosukesuzuki))

<!-- prettier-ignore -->

```tsx
// Input
type Type = {
  // comment
  readonly [key in Foo];
};

// Prettier 2.8.3
type Type = {
  readonly // comment
  [key in Foo];
};

// Prettier 2.8.4
type Type = {
  // comment
  readonly [key in Foo];
};
```

##### Group params in opening block statements ([#&#8203;14067](https://github.com/prettier/prettier/pull/14067) by [@&#8203;jamescdavis](https://github.com/jamescdavis))

This is a follow-up to [#&#8203;13930](https://github.com/prettier/prettier/issues/13930) to establish wrapping consistency between opening block statements and else blocks by
grouping params in opening blocks. This causes params to break to a new line together and not be split across lines
unless the length of params exceeds the print width. This also updates the else block wrapping to behave exactly the
same as opening blocks.

<!-- prettier-ignore -->

```hbs
{{! Input }}
{{#block param param param param param param param param param param as |blockParam|}}
  Hello
{{else block param param param param param param param param param param as |blockParam|}}
  There
{{/block}}

{{! Prettier 2.8.3 }}
{{#block
  param
  param
  param
  param
  param
  param
  param
  param
  param
  param
  as |blockParam|
}}
  Hello
{{else block param
param
param
param
param
param
param
param
param
param}}
  There
{{/block}}

{{! Prettier 2.8.4 }}
{{#block
  param param param param param param param param param param
  as |blockParam|
}}
  Hello
{{else block
  param param param param param param param param param param
  as |blockParam|
}}
  There
{{/block}}
```

##### Ignore files in `.sl/` ([#&#8203;14206](https://github.com/prettier/prettier/pull/14206) by [@&#8203;bolinfest](https://github.com/bolinfest))

In [Sapling SCM](https://sapling-scm.com/), `.sl/` is the folder where it stores its state, analogous to `.git/` in Git. It should be ignored in Prettier like the other SCM folders.

##### Recognize `@satisfies` in Closure-style type casts ([#&#8203;14262](https://github.com/prettier/prettier/pull/14262) by [@&#8203;fisker](https://github.com/fisker))

<!-- prettier-ignore -->

```jsx
// Input
const a = /** @&#8203;satisfies {Record<string, string>} */ ({hello: 1337});
const b = /** @&#8203;type {Record<string, string>} */ ({hello: 1337});

// Prettier 2.8.3
const a = /** @&#8203;satisfies {Record<string, string>} */ { hello: 1337 };
const b = /** @&#8203;type {Record<string, string>} */ ({ hello: 1337 });

// Prettier 2.8.4
const a = /** @&#8203;satisfies {Record<string, string>} */ ({hello: 1337});
const b = /** @&#8203;type {Record<string, string>} */ ({hello: 1337});
```

##### Fix parens in inferred function return types with `extends` ([#&#8203;14279](https://github.com/prettier/prettier/pull/14279) by [@&#8203;fisker](https://github.com/fisker))

<!-- prettier-ignore -->

```ts
// Input
type Foo<T> = T extends ((a) => a is infer R extends string) ? R : never;

// Prettier 2.8.3 (First format)
type Foo<T> = T extends (a) => a is infer R extends string ? R : never;

// Prettier 2.8.3 (Second format)
SyntaxError: '?' expected.

// Prettier 2.8.4
type Foo<T> = T extends ((a) => a is infer R extends string) ? R : never;
```

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNS4yMC4wIiwidXBkYXRlZEluVmVyIjoiMzUuMjAuMCJ9-->

Co-authored-by: Renovate <renovate@dwysokinski.me>
Reviewed-on: #16
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-03-25 11:49:01 +00:00
418e6f2c99 feat: add commitlint (#13)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #13
2023-02-20 08:27:42 +00:00
35 changed files with 2205 additions and 2206 deletions

View File

@ -1,111 +0,0 @@
---
kind: pipeline
type: docker
name: build
platform:
os: linux
arch: amd64
steps:
- name: build
image: node:16-bullseye
commands:
- yarn && yarn build
trigger:
event:
- push
- pull_request
branch:
- master
---
kind: pipeline
type: docker
name: linux-amd64
platform:
os: linux
arch: amd64
steps:
- name: publish
image: plugins/docker
settings:
username:
from_secret: docker_username
password:
from_secret: docker_password
registry: gitea.dwysokinski.me
repo: gitea.dwysokinski.me/twhelp-packages/scripts
auto_tag: true
auto_tag_suffix: linux-amd64
dockerfile: Dockerfile
trigger:
event:
- tag
---
kind: pipeline
type: docker
name: manifest
steps:
- name: manifest
image: plugins/manifest
settings:
auto_tag: "true"
ignore_missing: "true"
spec: manifest.tmpl
username:
from_secret: docker_username
password:
from_secret: docker_password
- name: manifest-latest
image: plugins/manifest
settings:
tags: latest
ignore_missing: "true"
spec: manifest.tmpl
username:
from_secret: docker_username
password:
from_secret: docker_password
trigger:
event:
- tag
depends_on:
- linux-amd64
---
kind: pipeline
type: docker
name: deploy
steps:
- name: deploy-k8s
image: alpine/k8s:1.25.6
environment:
KUBECONFIG:
from_secret: kubeconfig
commands:
- "mkdir ~/.kube && echo \"$KUBECONFIG\" > ~/.kube/twhelp"
- "cd ./k8s/overlays/prod && kustomize edit set image scripts=gitea.dwysokinski.me/twhelp-packages/scripts:${DRONE_TAG##v} && cd ../../.."
- kustomize build ./k8s/overlays/prod | kubectl --kubeconfig ~/.kube/twhelp apply -n twhelp -f -
trigger:
event:
- tag
depends_on:
- manifest
---
kind: signature
hmac: 41f8c71c00cee8f0932228f9fcb449b50b36d93899bbc2decdf1fcced338caae
...

2
.env
View File

@ -1 +1 @@
TWHELP_API_BASE_URL=https://tribalwarshelp.com TWHELP_API_BASE_URL=https://twhelp.app/api

View File

@ -3,4 +3,6 @@ dist
.parcel-cache .parcel-cache
k8s k8s
.prettierrc.js .prettierrc.js
.terserrc.js commitlint.config.js
postbuild.js
src/lib/twhelp

1
.husky/commit-msg Executable file
View File

@ -0,0 +1 @@
npx --no -- commitlint --edit ${1}

View File

@ -1,3 +0,0 @@
module.exports = {
singleQuote: true,
};

4
.prettierrc.json Normal file
View File

@ -0,0 +1,4 @@
{
"singleQuote": true,
"trailingComma": "es5"
}

View File

@ -0,0 +1,34 @@
when:
event: [tag]
ref: refs/tags/v*
steps:
deploy:
image: alpine/k8s:1.27.11
secrets:
- kubeconfig
commands:
- "mkdir ~/.kube && echo \"$KUBECONFIG\" > ~/.kube/twhelp"
- "cd ./k8s/overlays/prod && kustomize edit set image scripts=gitea.dwysokinski.me/twhelp-packages/scripts:${CI_COMMIT_TAG##v} && cd ../../.."
- kustomize build ./k8s/overlays/prod | kubectl --kubeconfig ~/.kube/twhelp apply -n twhelp -f -
email:
image: deblan/woodpecker-email
settings:
dsn:
from_secret: email_dsn
from:
address:
from_secret: email_from_address
name: Woodpecker
recipients:
- notifications@twhelp.app
recipients_only: true
content:
subject:
"[deployment - {{ pipeline.status }}] {{ repo.full_name }} ({{ commit.tag }})"
when:
status: [success, failure]
depends_on:
- docker

16
.woodpecker/docker.yml Normal file
View File

@ -0,0 +1,16 @@
when:
event: [tag]
ref: refs/tags/v*
steps:
publish:
image: woodpeckerci/plugin-docker-buildx
settings:
platforms: linux/amd64,linux/arm64
repo: gitea.dwysokinski.me/twhelp-packages/scripts
registry: gitea.dwysokinski.me
auto_tag: true
username:
from_secret: docker_username
password:
from_secret: docker_password

15
.woodpecker/test.yml Normal file
View File

@ -0,0 +1,15 @@
when:
- event: [pull_request]
- event: push
branch:
- ${CI_REPO_DEFAULT_BRANCH}
variables:
- &node_image 'node:20'
steps:
test-build:
image: *node_image
pull: true
commands:
- yarn && yarn build

View File

@ -1,6 +1,6 @@
:80 { :80 {
root * /var/www root * /var/www
file_server file_server browse
header -Server header -Server
header Cache-Control max-age=3600 header Cache-Control max-age=3600
header *.js Content-type "text/javascript; charset=UTF-8" header *.js Content-type "text/javascript; charset=UTF-8"

View File

@ -1,4 +1,4 @@
FROM node:16.19-alpine as build-deps FROM --platform=$BUILDPLATFORM node:20.14-alpine as build-deps
WORKDIR /app WORKDIR /app
COPY package.json yarn.lock ./ COPY package.json yarn.lock ./
@ -8,7 +8,7 @@ COPY . ./
ENV NODE_ENV=production ENV NODE_ENV=production
RUN yarn build RUN yarn build
FROM caddy:2.6.4-alpine FROM caddy:2.8.1-alpine
COPY --from=build-deps /app/dist /var/www COPY --from=build-deps /app/dist /var/www
COPY Caddyfile /etc/caddy/Caddyfile COPY Caddyfile /etc/caddy/Caddyfile

View File

@ -1,6 +1,31 @@
# Tribal Wars - scripts <div align="center">
<picture>
<img alt="TWHelp logo" src="assets/white_logo_full.png" width="50%">
</picture>
</div>
This repo contains a variety of scripts for [Tribal Wars](https://www.tribalwars.net/en-dk/). <br>
<h1 align="center"><a href="https://www.tribalwars.net/en-dk/">Tribal Wars</a> scripts to enhance your gameplay</h1>
<div align="center">
[![License](https://img.shields.io/badge/License-MIT-green)](#license)
[![CI/CD](https://woodpecker.dwysokinski.me/api/badges/10/status.svg)](https://woodpecker.dwysokinski.me/repos/10)
</div>
<p align="center">
<a href="https://twhelp.app/api/v2/swagger/">API</a>
·
<a href="https://gitea.dwysokinski.me/twhelp/scripts">Scripts</a>
·
<a href="https://gitea.dwysokinski.me/twhelp/dcbot">Discord Bot</a>
·
<a href="mailto:contact@twhelp.app">Report Bug</a>
·
<a href="mailto:contact@twhelp.app">Request Feature</a>
</p>
## Scripts ## Scripts
@ -8,70 +33,71 @@ This repo contains a variety of scripts for [Tribal Wars](https://www.tribalwars
This script adds additional info and actions on a player overview. This script adds additional info and actions on a player overview.
![img.png](docs/extended-player-profile.png) ![img.png](assets/extended-player-profile.png)
#### Installation #### Installation
[User script](https://scripts.tribalwarshelp.com/extended-player-profile.user.js) [User script](https://scripts.twhelp.app/extended-player-profile.user.js)
Quick bar: Quick bar:
```javascript ```javascript
javascript: javascript:
$.getScript('https://scripts.tribalwarshelp.com/extended-player-profile.quickbar.js') $.getScript('https://scripts.twhelp.app/extended-player-profile.quickbar.js?_='+~~(Date.now()/9e6))
``` ```
### Extended tribe profile ### Extended tribe profile
This script adds additional info and actions on a tribe overview. This script adds additional info and actions on a tribe overview.
![img.png](docs/extended-tribe-profile.png) ![img.png](assets/extended-tribe-profile.png)
#### Installation #### Installation
[User script](https://scripts.tribalwarshelp.com/extended-tribe-profile.user.js) [User script](https://scripts.twhelp.app/extended-tribe-profile.user.js)
Quick bar: Quick bar:
```javascript ```javascript
javascript: javascript:
$.getScript('https://scripts.tribalwarshelp.com/extended-tribe-profile.quickbar.js') $.getScript('https://scripts.twhelp.app/extended-tribe-profile.quickbar.js?_='+~~(Date.now()/9e6))
``` ```
### Extended map popup ### Extended map popup
This script extends the map popup with additional info. This script extends the map popup with additional info.
![img.png](docs/extended-map-popup.png) ![img.png](assets/extended-map-popup.png)
#### Installation #### Installation
[User script](https://scripts.tribalwarshelp.com/extended-map-popup.user.js) [User script](https://scripts.twhelp.app/extended-map-popup.user.js)
Quick bar: Quick bar:
```javascript ```javascript
javascript: javascript:
$.getScript('https://scripts.tribalwarshelp.com/extended-map-popup.quickbar.js') $.getScript('https://scripts.twhelp.app/extended-map-popup.quickbar.js?_='+~~(Date.now()/9e6))
``` ```
### Extended village profile ### Extended village profile
This script adds additional info and actions on a village overview. This script adds additional info and actions on a village overview.
![img.png](docs/extended-village-profile.png) ![img.png](assets/extended-village-profile.png)
#### Installation #### Installation
[User script](https://scripts.tribalwarshelp.com/extended-village-profile.user.js) [User script](https://scripts.twhelp.app/extended-village-profile.user.js)
Quick bar: Quick bar:
```javascript ```javascript
javascript: javascript:
$.getScript('https://scripts.tribalwarshelp.com/extended-village-profile.quickbar.js') $.getScript('https://scripts.twhelp.app/extended-village-profile.quickbar.js?_='+~~(Date.now()/9e6))
``` ```
## Contributing
If you would like to contribute to the software, please contact me via [email](mailto:contact@twhelp.app).
## License ## License
Distributed under the MIT License. See ``LICENSE`` for more information. This project is licensed under the MIT license. See the [LICENSE](LICENSE) file for the full license text.
## Contact
Dawid Wysokiński - [contact@dwysokinski.me](mailto:contact@dwysokinski.me)

View File

Before

Width:  |  Height:  |  Size: 204 KiB

After

Width:  |  Height:  |  Size: 204 KiB

View File

Before

Width:  |  Height:  |  Size: 196 KiB

After

Width:  |  Height:  |  Size: 196 KiB

View File

Before

Width:  |  Height:  |  Size: 452 KiB

After

Width:  |  Height:  |  Size: 452 KiB

View File

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

BIN
assets/white_logo_full.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

3
commitlint.config.js Normal file
View File

@ -0,0 +1,3 @@
module.exports = {
extends: ['@commitlint/config-conventional'],
};

View File

@ -18,3 +18,13 @@ spec:
name: scripts-caddy-service name: scripts-caddy-service
port: port:
number: 80 number: 80
- host: scripts.twhelp.app
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: scripts-caddy-service
port:
number: 80

View File

@ -1,13 +0,0 @@
image: gitea.dwysokinski.me/twhelp-packages/scripts:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}latest{{/if}}
{{#if build.tags}}
tags:
{{#each build.tags}}
- {{this}}
{{/each}}
{{/if}}
manifests:
-
image: gitea.dwysokinski.me/twhelp-packages/scripts:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-amd64
platform:
architecture: amd64
os: linux

View File

@ -3,16 +3,10 @@
"version": "0.1.0", "version": "0.1.0",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"build-single": "PUBLIC_URL=https://scripts.tribalwarshelp.com parcel build", "prepare": "husky",
"build:extended-player-profile-user": "PREAMBLE=extended-player-profile yarn build-single ./src/extended-player-profile.user.ts", "generate-client": "openapi --input src/lib/twhelp/openapi3.json --output src/lib/twhelp/generated --name TWHelpClient --useOptions --client axios",
"build:extended-player-profile-quickbar": "yarn build-single ./src/extended-player-profile.quickbar.ts", "build": "rm -rf dist && yarn generate-client && parcel build ./src/*.user.ts ./src/*.quickbar.ts",
"build:extended-map-popup-user": "PREAMBLE=extended-map-popup yarn build-single ./src/extended-map-popup.user.ts", "postbuild": "PUBLIC_URL=https://scripts.twhelp.app node postbuild.js",
"build:extended-map-popup-quickbar": "yarn build-single ./src/extended-map-popup.quickbar.ts",
"build:extended-village-profile-user": "PREAMBLE=extended-village-profile yarn build-single ./src/extended-village-profile.user.ts",
"build:extended-village-profile-quickbar": "yarn build-single ./src/extended-village-profile.quickbar.ts",
"build:extended-tribe-profile-user": "PREAMBLE=extended-tribe-profile yarn build-single ./src/extended-tribe-profile.user.ts",
"build:extended-tribe-profile-quickbar": "yarn build-single ./src/extended-tribe-profile.quickbar.ts",
"build": "npm-run-all build:*",
"lint": "eslint src/**/*.ts" "lint": "eslint src/**/*.ts"
}, },
"targets": { "targets": {
@ -27,27 +21,30 @@
"url": "https://dwysokinski.me/" "url": "https://dwysokinski.me/"
}, },
"browserslist": [ "browserslist": [
"since 2017-06" "since 2020-01"
], ],
"devDependencies": { "devDependencies": {
"@parcel/validator-eslint": "^2.8.3", "@commitlint/cli": "^19.0.0",
"@parcel/validator-typescript": "^2.8.3", "@commitlint/config-conventional": "^19.0.0",
"@parcel/validator-eslint": "^2.12.0",
"@parcel/validator-typescript": "^2.12.0",
"@types/jquery": "^3.5.14", "@types/jquery": "^3.5.14",
"@types/lodash": "^4.14.191", "@types/lodash": "^4.14.191",
"@types/node": "^18.11.17", "@types/node": "^20.0.0",
"@typescript-eslint/eslint-plugin": "^5.50.0", "@typescript-eslint/eslint-plugin": "^5.50.0",
"@typescript-eslint/parser": "^5.50.0", "@typescript-eslint/parser": "^5.50.0",
"buffer": "^5.5.0", "buffer": "^5.5.0",
"eslint": "^7.32.0", "eslint": "^7.32.0",
"eslint-config-prettier": "^8.6.0", "eslint-config-prettier": "^9.0.0",
"npm-run-all": "^4.1.5", "husky": "^9.0.0",
"parcel": "^2.8.3", "openapi-typescript-codegen": "^0.28.0",
"prettier": "^2.8.3", "parcel": "^2.12.0",
"typescript": "^4.9.4" "prettier": "^3.0.0",
"typescript": "^5.0.0"
}, },
"dependencies": { "dependencies": {
"axios": "^1.2.2", "axios": "^1.2.2",
"date-fns": "^2.29.3", "date-fns": "^3.0.0",
"lodash": "^4.17.21" "lodash": "^4.17.21"
} }
} }

View File

@ -1,9 +1,15 @@
const preambles = { const fs = require('fs');
const path = require('path');
const FILE_SUFFIX = '.user.js';
const DIST_DIR = 'dist';
const metadata = {
'extended-player-profile': `// ==UserScript== 'extended-player-profile': `// ==UserScript==
// @name Extended player profile // @name Extended player profile
// @version 1.1.2 // @version 1.2.0
// @description Adds additional info and actions on a player overview. // @description Adds additional info and actions on a player overview.
// @author Dawid Wysokiński - Kichiyaki - contact@dwysokinski.me // @author Dawid Wysokiński - Kichiyaki - contact@twhelp.app
// @match https://*/game.php?*screen=info_player* // @match https://*/game.php?*screen=info_player*
// @downloadURL ${process.env.PUBLIC_URL}/extended-player-profile.user.js // @downloadURL ${process.env.PUBLIC_URL}/extended-player-profile.user.js
// @updateURL ${process.env.PUBLIC_URL}/extended-player-profile.user.js // @updateURL ${process.env.PUBLIC_URL}/extended-player-profile.user.js
@ -13,9 +19,9 @@ const preambles = {
// ==/UserScript==`, // ==/UserScript==`,
'extended-map-popup': `// ==UserScript== 'extended-map-popup': `// ==UserScript==
// @name Extended map popup // @name Extended map popup
// @version 1.0.2 // @version 1.1.0
// @description Extends the map popup with additional info. // @description Extends the map popup with additional info.
// @author Dawid Wysokiński - Kichiyaki - contact@dwysokinski.me // @author Dawid Wysokiński - Kichiyaki - contact@twhelp.app
// @match https://*/game.php?*screen=map* // @match https://*/game.php?*screen=map*
// @downloadURL ${process.env.PUBLIC_URL}/extended-map-popup.user.js // @downloadURL ${process.env.PUBLIC_URL}/extended-map-popup.user.js
// @updateURL ${process.env.PUBLIC_URL}/extended-map-popup.user.js // @updateURL ${process.env.PUBLIC_URL}/extended-map-popup.user.js
@ -25,9 +31,9 @@ const preambles = {
// ==/UserScript==`, // ==/UserScript==`,
'extended-village-profile': `// ==UserScript== 'extended-village-profile': `// ==UserScript==
// @name Extended village profile // @name Extended village profile
// @version 1.0.1 // @version 1.1.0
// @description Adds additional info and actions on a village overview. // @description Adds additional info and actions on a village overview.
// @author Dawid Wysokiński - Kichiyaki - contact@dwysokinski.me // @author Dawid Wysokiński - Kichiyaki - contact@twhelp.app
// @match https://*/game.php?*screen=info_village* // @match https://*/game.php?*screen=info_village*
// @downloadURL ${process.env.PUBLIC_URL}/extended-village-profile.user.js // @downloadURL ${process.env.PUBLIC_URL}/extended-village-profile.user.js
// @updateURL ${process.env.PUBLIC_URL}/extended-village-profile.user.js // @updateURL ${process.env.PUBLIC_URL}/extended-village-profile.user.js
@ -37,9 +43,9 @@ const preambles = {
// ==/UserScript==`, // ==/UserScript==`,
'extended-tribe-profile': `// ==UserScript== 'extended-tribe-profile': `// ==UserScript==
// @name Extended tribe profile // @name Extended tribe profile
// @version 1.0.0 // @version 1.1.0
// @description Adds additional info and actions on a tribe overview. // @description Adds additional info and actions on a tribe overview.
// @author Dawid Wysokiński - Kichiyaki - contact@dwysokinski.me // @author Dawid Wysokiński - Kichiyaki - contact@twhelp.app
// @match https://*/game.php?*screen=info_ally* // @match https://*/game.php?*screen=info_ally*
// @downloadURL ${process.env.PUBLIC_URL}/extended-tribe-profile.user.js // @downloadURL ${process.env.PUBLIC_URL}/extended-tribe-profile.user.js
// @updateURL ${process.env.PUBLIC_URL}/extended-tribe-profile.user.js // @updateURL ${process.env.PUBLIC_URL}/extended-tribe-profile.user.js
@ -49,11 +55,12 @@ const preambles = {
// ==/UserScript==`, // ==/UserScript==`,
}; };
const preamble = preambles[process.env.PREAMBLE]; Object.entries(metadata).forEach(([name, m]) => {
module.exports = preamble const p = path.join('.', DIST_DIR, `${name}${FILE_SUFFIX}`);
? { const data = fs.readFileSync(p);
output: { const fd = fs.openSync(p, 'w+');
preamble: preamble, const insert = Buffer.from(`${m}\n`);
}, fs.writeSync(fd, insert, 0, insert.length, 0);
} fs.writeSync(fd, data, 0, data.length, insert.length);
: {}; fs.closeSync(fd);
});

View File

@ -15,48 +15,54 @@ export type DialogTableColumn<T> = {
accessor: (row: T, index: number, rows: T[]) => string; accessor: (row: T, index: number, rows: T[]) => string;
}; };
export type Cursor = {
next?: string;
self?: string;
};
export type LoadDataResult<T> = { export type LoadDataResult<T> = {
cursor?: Cursor;
data: T[]; data: T[];
total: number;
}; };
export class DialogTable<T> { export class DialogTable<T> {
prevPageId: string; private readonly prevPageId: string;
selectId: string; private readonly nextPageId: string;
nextPageId: string;
private readonly prevCursors: Cursor[] = [];
constructor( constructor(
private readonly id: string, private readonly id: string,
private readonly columns: DialogTableColumn<T>[], private readonly columns: DialogTableColumn<T>[],
private readonly limit: number, private readonly limit: number,
private readonly loadData: ( private readonly loadData: (
page: number, cursor: string | undefined,
limit: number limit: number
) => Promise<LoadDataResult<T>> ) => Promise<LoadDataResult<T>>
) { ) {
this.prevPageId = `${this.id}_page_prev`; this.prevPageId = `${this.id}_page_prev`;
this.selectId = `${this.id}_page_select`;
this.nextPageId = `${this.id}_page_next`; this.nextPageId = `${this.id}_page_next`;
} }
public async render() { public async render() {
await this.renderPage(1); await this.renderPage();
} }
private async renderPage(page: number) { private async renderPage(pageCursor?: string) {
window.Dialog.show(`${this.id}_loading`, `<p>${t('Loading')}...</p>`); window.Dialog.show(this.id, `<p>${t('Loading')}...</p>`);
try { try {
const { data, total } = await this.loadData(page, this.limit); const { data, cursor } = await this.loadData(pageCursor, this.limit);
window.Dialog.show( window.Dialog.show(
this.id, this.id,
` `
${this.buildPagination(page, total)} ${this.buildPagination(cursor)}
${this.buildTable(data)} ${this.buildTable(data)}
` `
); );
this.addEventListeners(page); this.addEventListeners(cursor);
} catch (err) { } catch (err) {
console.error(err); console.error(err);
window.Dialog.close(); window.Dialog.close();
@ -64,31 +70,17 @@ export class DialogTable<T> {
} }
} }
private buildPagination(page: number, total: number): string { private buildPagination(cursor?: Cursor): string {
const maxPage = Math.ceil(total / this.limit);
const pageOpts = [];
for (let i = 1; i <= (page > maxPage ? page : maxPage); i++) {
pageOpts.push(
`<option${
i === page ? ' disabled selected' : ''
} value="${i}">${i}</option>`
);
}
return ` return `
<div style="display: flex; flex-direction: row; align-items: center; justify-content: center; margin-bottom: 10px"> <div style="display: flex; flex-direction: row; align-items: center; justify-content: center; margin-bottom: 10px">
<button title="${t( <button title="${t(
'Previous page' 'Previous page'
)}" style="margin-right: 5px" class="btn" id="${this.prevPageId}"${ )}" style="margin-right: 5px" class="btn" id="${this.prevPageId}"${
page <= 1 ? ' disabled' : '' this.prevCursors.length === 0 ? ' disabled' : ''
}>&lt;</button> }>&lt;</button>
<select style="margin-right: 5px" id="${this.selectId}">
${pageOpts.join('')}
</select>
<button title="${t('Next page')}" class="btn" id="${ <button title="${t('Next page')}" class="btn" id="${
this.nextPageId this.nextPageId
}"${page >= maxPage ? ' disabled' : ''}>&gt;</button> }"${!cursor?.next ? ' disabled' : ''}>&gt;</button>
</div> </div>
`; `;
} }
@ -116,27 +108,25 @@ export class DialogTable<T> {
`; `;
} }
private addEventListeners(page: number) { private addEventListeners(cursor?: Cursor) {
document document
.querySelector('#' + this.prevPageId) .querySelector('#' + this.prevPageId)
?.addEventListener('click', () => { ?.addEventListener('click', () => {
this.renderPage(page - 1); const prev = this.prevCursors.pop();
}); if (!prev) {
document
.querySelector('#' + this.selectId)
?.addEventListener('change', (e: Event) => {
if (!(e.currentTarget instanceof HTMLSelectElement)) {
return; return;
} }
this.renderPage(prev.self);
this.renderPage(parseInt(e.currentTarget.value));
}); });
document document
.querySelector('#' + this.nextPageId) .querySelector('#' + this.nextPageId)
?.addEventListener('click', () => { ?.addEventListener('click', () => {
this.renderPage(page + 1); if (!cursor) {
return;
}
this.prevCursors.push(cursor);
this.renderPage(cursor.next);
}); });
} }
} }

View File

@ -1,13 +1,14 @@
import addSeconds from 'date-fns/addSeconds'; import { addSeconds } from 'date-fns/addSeconds';
import {
Ennoblement,
ServerConfig,
TWHelpClient,
UnitInfo,
} from './lib/twhelp';
import { Cache, InMemoryStorage } from './lib/cache'; import { Cache, InMemoryStorage } from './lib/cache';
import { calcDistance, calcLoyalty } from './lib/tw'; import { calcDistance, calcLoyalty } from './lib/tw';
import { createTranslationFunc } from './utils'; import { createTranslationFunc } from './utils';
import {
TWHelpClient,
Ennoblement,
UnitInfo,
ServerConfig,
AxiosHttpRequestWithTimeout,
} from './lib/twhelp';
declare global { declare global {
interface Window { interface Window {
@ -43,25 +44,41 @@ const t = createTranslationFunc({
class TWHelpConnector { class TWHelpConnector {
private static readonly SERVER_CONFIG_CACHE_KEY = private static readonly SERVER_CONFIG_CACHE_KEY =
'extended_map_popup_server_config'; 'extended_map_popup_server_config_v2';
private static readonly UNIT_INFO_CACHE_KEY = 'extended_map_popup_unit_info'; private static readonly UNIT_INFO_CACHE_KEY =
'extended_map_popup_unit_info_v2';
private static readonly VILLAGE_CACHE_KEY_PREFIX = private static readonly VILLAGE_CACHE_KEY_PREFIX =
'extended_map_popup_village_'; 'extended_map_popup_village_v2_';
private readonly localStorageCache = new Cache(localStorage); private readonly localStorageCache = new Cache(localStorage);
private readonly inMemoryCache = new Cache(new InMemoryStorage()); private readonly inMemoryCache = new Cache(new InMemoryStorage());
private readonly client: TWHelpClient;
constructor( constructor(
private readonly client: TWHelpClient, readonly baseUrl: string,
private readonly version: string, private readonly version: string,
private readonly server: string private readonly server: string
) {} ) {
this.client = new TWHelpClient(
{
BASE: baseUrl,
},
AxiosHttpRequestWithTimeout
);
}
serverConfig() { serverConfig() {
return this.localStorageCache.load( return this.localStorageCache.load(
TWHelpConnector.SERVER_CONFIG_CACHE_KEY, TWHelpConnector.SERVER_CONFIG_CACHE_KEY,
3600, 3600,
() => { async () => {
return this.client.serverConfig(this.version, this.server); return (
await this.client.servers.getServerConfig({
serverKey: this.server,
versionCode: this.version,
})
).data;
} }
); );
} }
@ -70,8 +87,13 @@ class TWHelpConnector {
return this.localStorageCache.load( return this.localStorageCache.load(
TWHelpConnector.UNIT_INFO_CACHE_KEY, TWHelpConnector.UNIT_INFO_CACHE_KEY,
3600, 3600,
() => { async () => {
return this.client.unitInfo(this.version, this.server); return (
await this.client.servers.getUnitInfo({
serverKey: this.server,
versionCode: this.version,
})
).data;
} }
); );
} }
@ -84,15 +106,14 @@ class TWHelpConnector {
} }
return this.inMemoryCache.load(key, 86400, async () => { return this.inMemoryCache.load(key, 86400, async () => {
const ennoblements = await this.client.villageEnnoblements( const ennoblements =
this.version, await this.client.ennoblements.listVillageEnnoblements({
this.server, versionCode: this.version,
id, serverKey: this.server,
{
limit: 1,
sort: ['createdAt:DESC'], sort: ['createdAt:DESC'],
} villageId: id,
); limit: 1,
});
return ennoblements.data.length > 0 ? ennoblements.data[0] : null; return ennoblements.data.length > 0 ? ennoblements.data[0] : null;
}); });
} }
@ -245,9 +266,9 @@ class Popup {
class ExtendedMapPopup { class ExtendedMapPopup {
connector: TWHelpConnector; connector: TWHelpConnector;
constructor(client: TWHelpClient) { constructor(baseApiUrl: string) {
this.connector = new TWHelpConnector( this.connector = new TWHelpConnector(
client, baseApiUrl,
window.game_data.market, window.game_data.market,
window.game_data.world window.game_data.world
); );
@ -273,9 +294,7 @@ class ExtendedMapPopup {
return; return;
} }
await new ExtendedMapPopup( await new ExtendedMapPopup(process.env.TWHELP_API_BASE_URL ?? '')
new TWHelpClient(process.env.TWHELP_API_BASE_URL ?? '')
)
.run() .run()
.catch((err) => { .catch((err) => {
console.log(err); console.log(err);

View File

@ -1,10 +1,16 @@
// Extended player profile // Extended player profile
import { Player, PlayerSnapshot, TWHelpClient } from './lib/twhelp';
import { DialogTable } from './common/dialog-table';
import { InADayClient } from './lib/tw'; import { InADayClient } from './lib/tw';
import { createTranslationFunc } from './utils'; import { createTranslationFunc } from './utils';
import { buildURL } from './lib/twstats'; import { buildURL } from './lib/twstats';
import {
TWHelpClient,
PlayerSnapshot,
Player,
AxiosHttpRequestWithTimeout,
} from './lib/twhelp';
import { DialogTable } from './common/dialog-table';
import { Cache } from './lib/cache';
const t = createTranslationFunc({ const t = createTranslationFunc({
pl_PL: { pl_PL: {
@ -59,62 +65,98 @@ const t = createTranslationFunc({
}); });
class TWHelpConnector { class TWHelpConnector {
private readonly client: TWHelpClient;
constructor( constructor(
private readonly client: TWHelpClient, readonly baseUrl: string,
private readonly version: string, private readonly version: string,
private readonly server: string, private readonly server: string,
private readonly id: number private readonly id: number
) {} ) {
this.client = new TWHelpClient(
{
BASE: baseUrl,
},
AxiosHttpRequestWithTimeout
);
}
player() { async player() {
return this.client.player(this.version, this.server, this.id); return (
await this.client.players.getPlayer({
versionCode: this.version,
serverKey: this.server,
playerId: this.id,
})
).data;
} }
async latestSnapshot() { async latestSnapshot() {
const history = await this.playerHistory(1, 1); const snapshot = await this.playerSnapshots(undefined, 1);
return history.data.length > 0 ? history.data[0] : null; return snapshot.data.length > 0 ? snapshot.data[0] : null;
} }
playerTribeChanges(page: number, limit: number) { playerTribeChanges(cursor: string | undefined, limit: number) {
return this.client.playerTribeChanges(this.version, this.server, this.id, { return this.client.tribeChanges.listPlayerTribeChanges({
offset: (page - 1) * limit, versionCode: this.version,
serverKey: this.server,
playerId: this.id,
limit, limit,
sort: ['createdAt:desc', 'id:asc'], cursor,
sort: ['createdAt:DESC'],
}); });
} }
playerEnnoblements(page: number, limit: number) { playerEnnoblements(cursor: string | undefined, limit: number) {
return this.client.playerEnnoblements(this.version, this.server, this.id, { return this.client.ennoblements.listPlayerEnnoblements({
offset: (page - 1) * limit, versionCode: this.version,
serverKey: this.server,
playerId: this.id,
limit, limit,
sort: ['createdAt:desc'], cursor,
sort: ['createdAt:DESC'],
}); });
} }
playerHistory(page: number, limit: number) { playerSnapshots(cursor: string | undefined, limit: number) {
return this.client.playerHistory(this.version, this.server, this.id, { return this.client.snapshots.listPlayerPlayerSnapshots({
offset: (page - 1) * limit, versionCode: this.version,
serverKey: this.server,
playerId: this.id,
limit, limit,
sort: ['date:desc'], cursor,
sort: ['date:DESC'],
}); });
} }
playerOtherServers(page: number, limit: number) { playerOtherServers(cursor: string | undefined, limit: number) {
return this.client.playerOtherServers(this.version, this.server, this.id, { return this.client.players.listVersionPlayers({
offset: (page - 1) * limit, versionCode: this.version,
limit, limit,
cursor,
id: [this.id],
}); });
} }
} }
class InADayConnector { class InADayConnector {
constructor( private static readonly CACHE_KEY_PREFIX =
private readonly client: InADayClient, 'extended_player_profile_in_a_day_';
private readonly name: string
) {} private readonly cache = new Cache(localStorage);
private readonly client = new InADayClient();
constructor(private readonly name: string) {}
player() { player() {
return this.client.player(this.name); return this.cache.load(
InADayConnector.CACHE_KEY_PREFIX + this.name,
600,
() => {
return this.client.player(this.name);
}
);
} }
} }
@ -160,20 +202,20 @@ class UI {
<tr> <tr>
<td>${t('Best rank')}:</td> <td>${t('Best rank')}:</td>
<td>${this.player.bestRank} (${new Date( <td>${this.player.bestRank} (${new Date(
this.player.bestRankAt this.player.bestRankAt
).toLocaleString()})</td> ).toLocaleString()})</td>
</tr> </tr>
<tr> <tr>
<td>${t('Most points')}:</td> <td>${t('Most points')}:</td>
<td>${this.player.mostPoints.toLocaleString()} (${new Date( <td>${this.player.mostPoints.toLocaleString()} (${new Date(
this.player.mostPointsAt this.player.mostPointsAt
).toLocaleString()})</td> ).toLocaleString()})</td>
</tr> </tr>
<tr> <tr>
<td>${t('Most villages')}:</td> <td>${t('Most villages')}:</td>
<td>${this.player.mostVillages.toLocaleString()} (${new Date( <td>${this.player.mostVillages.toLocaleString()} (${new Date(
this.player.mostVillagesAt this.player.mostVillagesAt
).toLocaleString()})</td> ).toLocaleString()})</td>
</tr> </tr>
` `
); );
@ -204,38 +246,54 @@ class UI {
}, },
{ {
header: t('ODA'), header: t('ODA'),
value: this.player.scoreAtt - (this.latestSnapshot?.scoreAtt ?? 0), value:
this.player.opponentsDefeated.scoreAtt -
(this.latestSnapshot?.opponentsDefeated.scoreAtt ?? 0),
}, },
{ {
header: t('ODA - rank'), header: t('ODA - rank'),
value: this.player.rankAtt - (this.latestSnapshot?.rankAtt ?? 0), value:
this.player.opponentsDefeated.rankAtt -
(this.latestSnapshot?.opponentsDefeated.rankAtt ?? 0),
rank: true, rank: true,
}, },
{ {
header: t('ODD'), header: t('ODD'),
value: this.player.scoreDef - (this.latestSnapshot?.scoreDef ?? 0), value:
this.player.opponentsDefeated.scoreDef -
(this.latestSnapshot?.opponentsDefeated.scoreDef ?? 0),
}, },
{ {
header: t('ODD - rank'), header: t('ODD - rank'),
value: this.player.rankDef - (this.latestSnapshot?.rankDef ?? 0), value:
this.player.opponentsDefeated.rankDef -
(this.latestSnapshot?.opponentsDefeated.rankDef ?? 0),
rank: true, rank: true,
}, },
{ {
header: t('ODS'), header: t('ODS'),
value: this.player.scoreSup - (this.latestSnapshot?.scoreSup ?? 0), value:
this.player.opponentsDefeated.scoreSup -
(this.latestSnapshot?.opponentsDefeated.scoreSup ?? 0),
}, },
{ {
header: t('ODS - rank'), header: t('ODS - rank'),
value: this.player.rankSup - (this.latestSnapshot?.rankSup ?? 0), value:
this.player.opponentsDefeated.rankSup -
(this.latestSnapshot?.opponentsDefeated.rankSup ?? 0),
rank: true, rank: true,
}, },
{ {
header: t('OD'), header: t('OD'),
value: this.player.scoreTotal - (this.latestSnapshot?.scoreTotal ?? 0), value:
this.player.opponentsDefeated.scoreTotal -
(this.latestSnapshot?.opponentsDefeated.scoreTotal ?? 0),
}, },
{ {
header: t('OD - rank'), header: t('OD - rank'),
value: this.player.rankTotal - (this.latestSnapshot?.rankTotal ?? 0), value:
this.player.opponentsDefeated.rankTotal -
(this.latestSnapshot?.opponentsDefeated.rankTotal ?? 0),
rank: true, rank: true,
}, },
]; ];
@ -364,8 +422,8 @@ class UI {
}, },
], ],
30, 30,
(page: number, limit: number) => { (cursor: string | undefined, limit: number) => {
return this.twhelpConnector.playerOtherServers(page, limit); return this.twhelpConnector.playerOtherServers(cursor, limit);
} }
).render(); ).render();
} }
@ -454,8 +512,8 @@ class UI {
}, },
], ],
30, 30,
(page: number, limit: number) => { (cursor: string | undefined, limit: number) => {
return this.twhelpConnector.playerTribeChanges(page, limit); return this.twhelpConnector.playerTribeChanges(cursor, limit);
} }
).render(); ).render();
} }
@ -473,8 +531,8 @@ class UI {
{ {
header: t('Tribe'), header: t('Tribe'),
accessor: (s) => accessor: (s) =>
s.tribe s.player.tribe
? `<a href="${s.tribe.profileUrl}">${s.tribe.tag}</a>` ? `<a href="${s.player.tribe.profileUrl}">${s.player.tribe.tag}</a>`
: '-', : '-',
}, },
{ {
@ -489,29 +547,29 @@ class UI {
{ {
header: t('OD'), header: t('OD'),
accessor: (s) => accessor: (s) =>
`${s.scoreTotal.toLocaleString()} (<strong>${ `${s.opponentsDefeated.scoreTotal.toLocaleString()} (<strong>${
s.rankTotal s.opponentsDefeated.rankTotal
}</strong>)`, }</strong>)`,
}, },
{ {
header: t('ODA'), header: t('ODA'),
accessor: (s) => accessor: (s) =>
`${s.scoreAtt.toLocaleString()} (<strong>${s.rankAtt}</strong>)`, `${s.opponentsDefeated.scoreAtt.toLocaleString()} (<strong>${s.opponentsDefeated.rankAtt}</strong>)`,
}, },
{ {
header: t('ODD'), header: t('ODD'),
accessor: (s) => accessor: (s) =>
`${s.scoreDef.toLocaleString()} (<strong>${s.rankDef}</strong>)`, `${s.opponentsDefeated.scoreDef.toLocaleString()} (<strong>${s.opponentsDefeated.rankDef}</strong>)`,
}, },
{ {
header: t('ODS'), header: t('ODS'),
accessor: (s) => accessor: (s) =>
`${s.scoreSup.toLocaleString()} (<strong>${s.rankSup}</strong>)`, `${s.opponentsDefeated.scoreSup.toLocaleString()} (<strong>${s.opponentsDefeated.rankSup}</strong>)`,
}, },
], ],
30, 30,
(page: number, limit: number) => { (cursor: string | undefined, limit: number) => {
return this.twhelpConnector.playerHistory(page, limit); return this.twhelpConnector.playerSnapshots(cursor, limit);
} }
).render(); ).render();
} }
@ -563,8 +621,8 @@ class UI {
}, },
], ],
30, 30,
(page: number, limit: number) => { (cursor: string | undefined, limit: number) => {
return this.twhelpConnector.playerEnnoblements(page, limit); return this.twhelpConnector.playerEnnoblements(cursor, limit);
} }
).render(); ).render();
} }
@ -574,18 +632,15 @@ class ExtendedPlayerProfile {
private readonly twhelpConnector: TWHelpConnector; private readonly twhelpConnector: TWHelpConnector;
private readonly inADayConnector: InADayConnector; private readonly inADayConnector: InADayConnector;
constructor(twhelpClient: TWHelpClient, inADayClient: InADayClient) { constructor(apiBaseUrl: string) {
this.twhelpConnector = new TWHelpConnector( this.twhelpConnector = new TWHelpConnector(
twhelpClient, apiBaseUrl,
window.game_data.market, window.game_data.market,
window.game_data.world, window.game_data.world,
this.getPlayerId() this.getPlayerId()
); );
this.inADayConnector = new InADayConnector( this.inADayConnector = new InADayConnector(this.getPlayerName());
inADayClient,
this.getPlayerName()
);
} }
async run() { async run() {
@ -627,10 +682,7 @@ class ExtendedPlayerProfile {
return; return;
} }
await new ExtendedPlayerProfile( await new ExtendedPlayerProfile(process.env.TWHELP_API_BASE_URL ?? '')
new TWHelpClient(process.env.TWHELP_API_BASE_URL ?? ''),
new InADayClient()
)
.run() .run()
.catch((err) => { .catch((err) => {
console.log(err); console.log(err);

View File

@ -1,7 +1,13 @@
import { Player, Tribe, TribeSnapshot, TWHelpClient } from './lib/twhelp'; import {
AxiosHttpRequestWithTimeout,
Player,
Tribe,
TribeSnapshot,
TWHelpClient,
} from './lib/twhelp';
import { createTranslationFunc } from './utils'; import { createTranslationFunc } from './utils';
import { DialogTable } from './common/dialog-table';
import { buildURL } from './lib/twstats'; import { buildURL } from './lib/twstats';
import { DialogTable } from './common/dialog-table';
const t = createTranslationFunc({ const t = createTranslationFunc({
pl_PL: { pl_PL: {
@ -44,47 +50,75 @@ const t = createTranslationFunc({
}); });
class TWHelpConnector { class TWHelpConnector {
private readonly client: TWHelpClient;
constructor( constructor(
private readonly client: TWHelpClient, baseUrl: string,
private readonly version: string, private readonly version: string,
private readonly server: string, private readonly server: string,
private readonly id: number private readonly id: number
) {} ) {
this.client = new TWHelpClient(
{
BASE: baseUrl,
},
AxiosHttpRequestWithTimeout
);
}
tribe() { async tribe() {
return this.client.tribe(this.version, this.server, this.id); return (
await this.client.tribes.getTribe({
versionCode: this.version,
serverKey: this.server,
tribeId: this.id,
})
).data;
} }
tribeMembers() { tribeMembers() {
return this.client.tribeMembers(this.version, this.server, this.id); return this.client.tribes.listTribeMembers({
versionCode: this.version,
serverKey: this.server,
tribeId: this.id,
});
} }
async latestSnapshot() { async latestSnapshot() {
const history = await this.tribeHistory(1, 1); const snapshot = await this.tribeSnapshots(undefined, 1);
return history.data.length > 0 ? history.data[0] : null; return snapshot.data.length > 0 ? snapshot.data[0] : null;
} }
tribeHistory(page: number, limit: number) { tribeSnapshots(cursor: string | undefined, limit: number) {
return this.client.tribeHistory(this.version, this.server, this.id, { return this.client.snapshots.listTribeTribeSnapshots({
offset: (page - 1) * limit, versionCode: this.version,
serverKey: this.server,
tribeId: this.id,
cursor,
limit, limit,
sort: ['date:desc'], sort: ['date:DESC'],
}); });
} }
tribeTribeChanges(page: number, limit: number) { memberChanges(cursor: string | undefined, limit: number) {
return this.client.tribeTribeChanges(this.version, this.server, this.id, { return this.client.tribeChanges.listTribeMemberChanges({
offset: (page - 1) * limit, versionCode: this.version,
serverKey: this.server,
tribeId: this.id,
cursor,
limit, limit,
sort: ['createdAt:desc'], sort: ['createdAt:DESC'],
}); });
} }
tribeEnnoblements(page: number, limit: number) { tribeEnnoblements(cursor: string | undefined, limit: number) {
return this.client.tribeEnnoblements(this.version, this.server, this.id, { return this.client.ennoblements.listTribeEnnoblements({
offset: (page - 1) * limit, versionCode: this.version,
serverKey: this.server,
tribeId: this.id,
cursor,
limit, limit,
sort: ['createdAt:desc'], sort: ['createdAt:DESC'],
}); });
} }
} }
@ -133,20 +167,20 @@ class UI {
<tr> <tr>
<td>${t('Best rank')}:</td> <td>${t('Best rank')}:</td>
<td>${this.tribe.bestRank} (${new Date( <td>${this.tribe.bestRank} (${new Date(
this.tribe.bestRankAt this.tribe.bestRankAt
).toLocaleString()})</td> ).toLocaleString()})</td>
</tr> </tr>
<tr> <tr>
<td>${t('Most points')}:</td> <td>${t('Most points')}:</td>
<td>${this.tribe.mostPoints.toLocaleString()} (${new Date( <td>${this.tribe.mostPoints.toLocaleString()} (${new Date(
this.tribe.mostPointsAt this.tribe.mostPointsAt
).toLocaleString()})</td> ).toLocaleString()})</td>
</tr> </tr>
<tr> <tr>
<td>${t('Most villages')}:</td> <td>${t('Most villages')}:</td>
<td>${this.tribe.mostVillages.toLocaleString()} (${new Date( <td>${this.tribe.mostVillages.toLocaleString()} (${new Date(
this.tribe.mostVillagesAt this.tribe.mostVillagesAt
).toLocaleString()})</td> ).toLocaleString()})</td>
</tr> </tr>
` `
); );
@ -185,29 +219,41 @@ class UI {
}, },
{ {
header: t('ODA'), header: t('ODA'),
value: this.tribe.scoreAtt - (this.latestSnapshot?.scoreAtt ?? 0), value:
this.tribe.opponentsDefeated.scoreAtt -
(this.latestSnapshot?.opponentsDefeated.scoreAtt ?? 0),
}, },
{ {
header: t('ODA - rank'), header: t('ODA - rank'),
value: this.tribe.rankAtt - (this.latestSnapshot?.rankAtt ?? 0), value:
this.tribe.opponentsDefeated.rankAtt -
(this.latestSnapshot?.opponentsDefeated.rankAtt ?? 0),
rank: true, rank: true,
}, },
{ {
header: t('ODD'), header: t('ODD'),
value: this.tribe.scoreDef - (this.latestSnapshot?.scoreDef ?? 0), value:
this.tribe.opponentsDefeated.scoreDef -
(this.latestSnapshot?.opponentsDefeated.scoreDef ?? 0),
}, },
{ {
header: t('ODD - rank'), header: t('ODD - rank'),
value: this.tribe.rankDef - (this.latestSnapshot?.rankDef ?? 0), value:
this.tribe.opponentsDefeated.rankDef -
(this.latestSnapshot?.opponentsDefeated.rankDef ?? 0),
rank: true, rank: true,
}, },
{ {
header: t('OD'), header: t('OD'),
value: this.tribe.scoreTotal - (this.latestSnapshot?.scoreTotal ?? 0), value:
this.tribe.opponentsDefeated.scoreTotal -
(this.latestSnapshot?.opponentsDefeated.scoreTotal ?? 0),
}, },
{ {
header: t('OD - rank'), header: t('OD - rank'),
value: this.tribe.rankTotal - (this.latestSnapshot?.rankTotal ?? 0), value:
this.tribe.opponentsDefeated.rankTotal -
(this.latestSnapshot?.opponentsDefeated.rankTotal ?? 0),
rank: true, rank: true,
}, },
]; ];
@ -231,10 +277,10 @@ class UI {
r.value, r.value,
r.rank r.rank
)}">${ )}">${
r.customFormat r.customFormat
? r.customFormat(r.value) ? r.customFormat(r.value)
: Math.abs(r.value).toLocaleString() : Math.abs(r.value).toLocaleString()
}</td> }</td>
</tr> </tr>
` `
) )
@ -323,8 +369,8 @@ class UI {
}, },
], ],
30, 30,
(page: number, limit: number) => { (cursor: string | undefined, limit: number) => {
return this.twhelpConnector.tribeTribeChanges(page, limit); return this.twhelpConnector.memberChanges(cursor, limit);
} }
).render(); ).render();
} }
@ -359,24 +405,24 @@ class UI {
{ {
header: t('OD'), header: t('OD'),
accessor: (s) => accessor: (s) =>
`${s.scoreTotal.toLocaleString()} (<strong>${ `${s.opponentsDefeated.scoreTotal.toLocaleString()} (<strong>${
s.rankTotal s.opponentsDefeated.rankTotal
}</strong>)`, }</strong>)`,
}, },
{ {
header: t('ODA'), header: t('ODA'),
accessor: (s) => accessor: (s) =>
`${s.scoreAtt.toLocaleString()} (<strong>${s.rankAtt}</strong>)`, `${s.opponentsDefeated.scoreAtt.toLocaleString()} (<strong>${s.opponentsDefeated.rankAtt}</strong>)`,
}, },
{ {
header: t('ODD'), header: t('ODD'),
accessor: (s) => accessor: (s) =>
`${s.scoreDef.toLocaleString()} (<strong>${s.rankDef}</strong>)`, `${s.opponentsDefeated.scoreDef.toLocaleString()} (<strong>${s.opponentsDefeated.rankDef}</strong>)`,
}, },
], ],
30, 30,
(page: number, limit: number) => { (cursor: string | undefined, limit: number) => {
return this.twhelpConnector.tribeHistory(page, limit); return this.twhelpConnector.tribeSnapshots(cursor, limit);
} }
).render(); ).render();
} }
@ -428,8 +474,8 @@ class UI {
}, },
], ],
30, 30,
(page: number, limit: number) => { (cursor: string | undefined, limit: number) => {
return this.twhelpConnector.tribeEnnoblements(page, limit); return this.twhelpConnector.tribeEnnoblements(cursor, limit);
} }
).render(); ).render();
} }
@ -477,10 +523,10 @@ class UI {
const member = this.members.find((m) => m.id === id); const member = this.members.find((m) => m.id === id);
[ [
(member?.rankAtt ?? 0).toString(), (member?.opponentsDefeated.rankAtt ?? 0).toString(),
(member?.rankDef ?? 0).toString(), (member?.opponentsDefeated.rankDef ?? 0).toString(),
(member?.rankSup ?? 0).toString(), (member?.opponentsDefeated.rankSup ?? 0).toString(),
(member?.rankTotal ?? 0).toString(), (member?.opponentsDefeated.rankTotal ?? 0).toString(),
member?.lastActivityAt member?.lastActivityAt
? new Date(member.lastActivityAt).toLocaleString() ? new Date(member.lastActivityAt).toLocaleString()
: '-', : '-',
@ -501,9 +547,9 @@ class UI {
class ExtendedTribeProfile { class ExtendedTribeProfile {
private readonly twhelpConnector: TWHelpConnector; private readonly twhelpConnector: TWHelpConnector;
constructor(twhelpClient: TWHelpClient) { constructor(apiBaseUrl: string) {
this.twhelpConnector = new TWHelpConnector( this.twhelpConnector = new TWHelpConnector(
twhelpClient, apiBaseUrl,
window.game_data.market, window.game_data.market,
window.game_data.world, window.game_data.world,
this.getTribeId() this.getTribeId()
@ -543,9 +589,7 @@ class ExtendedTribeProfile {
return; return;
} }
await new ExtendedTribeProfile( await new ExtendedTribeProfile(process.env.TWHELP_API_BASE_URL ?? '')
new TWHelpClient(process.env.TWHELP_API_BASE_URL ?? '')
)
.run() .run()
.catch((err) => { .catch((err) => {
console.log(err); console.log(err);

View File

@ -1,8 +1,13 @@
import { Ennoblement, ServerConfig, TWHelpClient } from './lib/twhelp';
import { createTranslationFunc } from './utils'; import { createTranslationFunc } from './utils';
import { DialogTable } from './common/dialog-table';
import { calcLoyalty } from './lib/tw'; import { calcLoyalty } from './lib/tw';
import { Cache } from './lib/cache'; import { Cache } from './lib/cache';
import {
TWHelpClient,
Ennoblement,
ServerConfig,
AxiosHttpRequestWithTimeout,
} from './lib/twhelp';
import { DialogTable } from './common/dialog-table';
const t = createTranslationFunc({ const t = createTranslationFunc({
pl_PL: { pl_PL: {
@ -22,32 +27,47 @@ const t = createTranslationFunc({
class TWHelpConnector { class TWHelpConnector {
private static SERVER_CONFIG_CACHE_KEY = private static SERVER_CONFIG_CACHE_KEY =
'extended_village_profile_server_config'; 'extended_village_profile_server_config_v2';
private cache = new Cache(localStorage); private cache = new Cache(localStorage);
private client: TWHelpClient;
constructor( constructor(
private readonly client: TWHelpClient, readonly baseUrl: string,
private readonly version: string, private readonly version: string,
private readonly server: string, private readonly server: string,
private readonly id: number private readonly id: number
) {} ) {
this.client = new TWHelpClient(
{
BASE: baseUrl,
},
AxiosHttpRequestWithTimeout
);
}
serverConfig() { serverConfig() {
return this.cache.load( return this.cache.load(
TWHelpConnector.SERVER_CONFIG_CACHE_KEY, TWHelpConnector.SERVER_CONFIG_CACHE_KEY,
3600, 3600,
() => { async () => {
return this.client.serverConfig(this.version, this.server); return (
await this.client.servers.getServerConfig({
versionCode: this.version,
serverKey: this.server,
})
).data;
} }
); );
} }
async latestEnnoblement() { async latestEnnoblement() {
const ennoblements = await this.client.villageEnnoblements( const ennoblements = await this.client.ennoblements.listVillageEnnoblements(
this.version,
this.server,
this.id,
{ {
versionCode: this.version,
serverKey: this.server,
villageId: this.id,
limit: 1, limit: 1,
sort: ['createdAt:DESC'], sort: ['createdAt:DESC'],
} }
@ -55,11 +75,14 @@ class TWHelpConnector {
return ennoblements.data.length > 0 ? ennoblements.data[0] : null; return ennoblements.data.length > 0 ? ennoblements.data[0] : null;
} }
villageEnnoblements(page: number, limit: number) { villageEnnoblements(cursor: string | undefined, limit: number) {
return this.client.villageEnnoblements(this.version, this.server, this.id, { return this.client.ennoblements.listVillageEnnoblements({
offset: (page - 1) * limit, cursor,
limit, versionCode: this.version,
sort: ['createdAt:desc'], serverKey: this.server,
villageId: this.id,
limit: limit,
sort: ['createdAt:DESC'],
}); });
} }
} }
@ -138,7 +161,7 @@ class UI {
private async showEnnoblements(e: Event) { private async showEnnoblements(e: Event) {
e.preventDefault(); e.preventDefault();
await new DialogTable( await new DialogTable<Ennoblement>(
DialogId.ENNOBLEMENTS, DialogId.ENNOBLEMENTS,
[ [
{ {
@ -182,8 +205,8 @@ class UI {
}, },
], ],
30, 30,
(page: number, limit: number) => { async (cursor, limit) => {
return this.connector.villageEnnoblements(page, limit); return this.connector.villageEnnoblements(cursor, limit);
} }
).render(); ).render();
} }
@ -191,9 +214,9 @@ class UI {
class ExtendedVillageProfile { class ExtendedVillageProfile {
connector: TWHelpConnector; connector: TWHelpConnector;
constructor(client: TWHelpClient) { constructor(apiBaseUrl: string) {
this.connector = new TWHelpConnector( this.connector = new TWHelpConnector(
client, apiBaseUrl,
window.game_data.market, window.game_data.market,
window.game_data.world, window.game_data.world,
this.getVillageId() this.getVillageId()
@ -226,9 +249,7 @@ class ExtendedVillageProfile {
return; return;
} }
await new ExtendedVillageProfile( await new ExtendedVillageProfile(process.env.TWHELP_API_BASE_URL ?? '')
new TWHelpClient(process.env.TWHELP_API_BASE_URL ?? '')
)
.run() .run()
.catch((err) => { .catch((err) => {
console.log(err); console.log(err);

View File

@ -1,5 +1,5 @@
import addSeconds from 'date-fns/addSeconds'; import { addSeconds } from 'date-fns/addSeconds';
import isAfter from 'date-fns/isAfter'; import { isAfter } from 'date-fns/isAfter';
export interface Storage { export interface Storage {
getItem(key: string): string | null; getItem(key: string): string | null;

View File

@ -1,4 +1,4 @@
import differenceInMinutes from 'date-fns/differenceInMinutes'; import { differenceInMinutes } from 'date-fns/differenceInMinutes';
import { LOYALTY_AFTER_CONQUER, MAX_LOYALTY } from './constants'; import { LOYALTY_AFTER_CONQUER, MAX_LOYALTY } from './constants';
export const calcLoyalty = ( export const calcLoyalty = (

View File

@ -1,424 +0,0 @@
import axios, {
AxiosInstance,
AxiosResponseHeaders,
RawAxiosResponseHeaders,
} from 'axios';
export type ServerMeta = {
key: string;
open: boolean;
};
export type Tribe = {
id: number;
name: string;
tag: string;
numMembers: number;
numVillages: number;
points: number;
allPoints: number;
rank: number;
dominance: number;
rankAtt: number;
scoreAtt: number;
rankDef: number;
scoreDef: number;
rankTotal: number;
scoreTotal: number;
profileUrl: string;
bestRank: number;
bestRankAt: string;
mostPoints: number;
mostPointsAt: string;
mostVillages: number;
mostVillagesAt: string;
createdAt: string;
deletedAt: string | null;
};
export type TribeMeta = {
id: number;
name: string;
tag: string;
profileUrl: string;
};
export type Player = {
id: number;
points: number;
rank: number;
numVillages: number;
scoreAtt: number;
rankAtt: number;
scoreDef: number;
rankDef: number;
scoreSup: number;
rankSup: number;
scoreTotal: number;
rankTotal: number;
bestRank: number;
bestRankAt: string;
mostPoints: number;
mostPointsAt: string;
mostVillages: number;
mostVillagesAt: string;
lastActivityAt: string;
createdAt: string;
tribe: TribeMeta | null;
};
export type PlayerWithServer = Player & {
server: ServerMeta;
};
export type PlayerMeta = {
id: number;
name: string;
profileUrl: string;
tribe: TribeMeta | null;
};
export type VillageMeta = {
id: number;
fullName: string;
profileUrl: string;
x: number;
y: number;
continent: string;
player: PlayerMeta | null;
};
export type TribeChange = {
id: number;
newTribe: TribeMeta | null;
player: PlayerMeta;
createdAt: string;
};
export type Ennoblement = {
id: number;
points: number;
newOwner: PlayerMeta | null;
village: VillageMeta;
createdAt: string;
};
export type TribeSnapshot = {
id: number;
numMembers: number;
numVillages: number;
points: number;
allPoints: number;
rank: number;
dominance: number;
rankAtt: number;
scoreAtt: number;
rankDef: number;
scoreDef: number;
rankTotal: number;
scoreTotal: number;
date: string;
};
export type PlayerSnapshot = {
id: number;
tribe: TribeMeta | null;
points: number;
numVillages: number;
rank: number;
rankAtt: number;
rankDef: number;
rankSup: number;
rankTotal: number;
scoreAtt: number;
scoreDef: number;
scoreSup: number;
scoreTotal: number;
date: string;
};
export type ServerConfig = {
speed: number;
unitSpeed: number;
snob: {
maxDist: number;
};
};
export type Unit = {
speed: number;
};
export type UnitInfo = {
archer: Unit;
axe: Unit;
catapult: Unit;
heavy: Unit;
knight: Unit;
light: Unit;
marcher: Unit;
militia: Unit;
ram: Unit;
snob: Unit;
spear: Unit;
spy: Unit;
sword: Unit;
};
export type ListResult<T> = {
data: T[];
total: number;
};
export type ListTribeChangesQueryParams = {
offset?: number;
limit?: number;
sort?: string[];
};
export type ListEnnoblementsParams = {
offset?: number;
limit?: number;
sort?: string[];
};
export type ListTribeMembers = {
offset?: number;
limit?: number;
sort?: string[];
};
export type ListSnapshotsParams = {
offset?: number;
limit?: number;
sort?: string[];
};
export type ListPlayerOtherServersParams = {
offset?: number;
limit?: number;
};
export class TWHelpClient {
client: AxiosInstance;
constructor(url: string, timeout = 10000) {
this.client = axios.create({
baseURL: url,
timeout,
});
}
public async serverConfig(
version: string,
server: string
): Promise<ServerConfig> {
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/config`
);
return resp.data.data;
}
public async unitInfo(version: string, server: string): Promise<UnitInfo> {
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/unit-info`
);
return resp.data.data;
}
public async tribe(
version: string,
server: string,
id: number
): Promise<Tribe> {
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/tribes/${id}`
);
return resp.data.data;
}
public async tribeHistory(
version: string,
server: string,
id: number,
queryParams?: ListSnapshotsParams
): Promise<ListResult<TribeSnapshot>> {
const queryString = queryParams ? this.buildQueryString(queryParams) : '';
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/tribes/${id}/history?${queryString}`
);
return {
data: resp.data.data,
total: this.parseTotal(resp.headers),
};
}
public async tribeTribeChanges(
version: string,
server: string,
id: number,
queryParams?: ListTribeChangesQueryParams
): Promise<ListResult<TribeChange>> {
const queryString = queryParams ? this.buildQueryString(queryParams) : '';
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/tribes/${id}/tribe-changes?${queryString}`
);
return {
data: resp.data.data,
total: this.parseTotal(resp.headers),
};
}
public async tribeEnnoblements(
version: string,
server: string,
id: number,
queryParams?: ListEnnoblementsParams
): Promise<ListResult<Ennoblement>> {
const queryString = queryParams ? this.buildQueryString(queryParams) : '';
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/tribes/${id}/ennoblements?${queryString}`
);
return {
data: resp.data.data,
total: this.parseTotal(resp.headers),
};
}
public async tribeMembers(
version: string,
server: string,
id: number,
queryParams?: ListTribeMembers
): Promise<ListResult<Player>> {
const queryString = queryParams ? this.buildQueryString(queryParams) : '';
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/tribes/${id}/members?${queryString}`
);
return {
data: resp.data.data,
total: this.parseTotal(resp.headers),
};
}
public async player(
version: string,
server: string,
id: number
): Promise<Player> {
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/players/${id}`
);
return resp.data.data;
}
public async playerTribeChanges(
version: string,
server: string,
id: number,
queryParams?: ListTribeChangesQueryParams
): Promise<ListResult<TribeChange>> {
const queryString = queryParams ? this.buildQueryString(queryParams) : '';
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/players/${id}/tribe-changes?${queryString}`
);
return {
data: resp.data.data,
total: this.parseTotal(resp.headers),
};
}
public async playerEnnoblements(
version: string,
server: string,
id: number,
queryParams?: ListEnnoblementsParams
): Promise<ListResult<Ennoblement>> {
const queryString = queryParams ? this.buildQueryString(queryParams) : '';
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/players/${id}/ennoblements?${queryString}`
);
return {
data: resp.data.data,
total: this.parseTotal(resp.headers),
};
}
public async playerHistory(
version: string,
server: string,
id: number,
queryParams?: ListSnapshotsParams
): Promise<ListResult<PlayerSnapshot>> {
const queryString = queryParams ? this.buildQueryString(queryParams) : '';
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/players/${id}/history?${queryString}`
);
return {
data: resp.data.data,
total: this.parseTotal(resp.headers),
};
}
public async playerOtherServers(
version: string,
server: string,
id: number,
queryParams?: ListPlayerOtherServersParams
): Promise<ListResult<PlayerWithServer>> {
const queryString = queryParams ? this.buildQueryString(queryParams) : '';
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/players/${id}/other-servers?${queryString}`
);
return {
data: resp.data.data,
total: this.parseTotal(resp.headers),
};
}
public async villageEnnoblements(
version: string,
server: string,
id: number,
queryParams?: ListEnnoblementsParams
): Promise<ListResult<Ennoblement>> {
const queryString = queryParams ? this.buildQueryString(queryParams) : '';
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/villages/${id}/ennoblements?${queryString}`
);
return {
data: resp.data.data,
total: this.parseTotal(resp.headers),
};
}
private buildQueryString(
queryParams: Record<string, string | boolean | number | Date | string[]>
): string {
const params = new URLSearchParams();
for (const [name, val] of Object.entries(queryParams)) {
if (Array.isArray(val)) {
val.forEach((s) => {
params.append(name, s);
});
continue;
}
if (val instanceof Date) {
params.set(name, val.toISOString());
continue;
}
params.set(name, val.toString());
}
return params.toString();
}
private parseTotal(
headers: RawAxiosResponseHeaders | AxiosResponseHeaders
): number {
return parseInt(headers['x-total-count'] ?? '0');
}
}

1
src/lib/twhelp/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
generated

2
src/lib/twhelp/index.ts Normal file
View File

@ -0,0 +1,2 @@
export * from './generated';
export * from './timeout';

File diff suppressed because one or more lines are too long

20
src/lib/twhelp/timeout.ts Normal file
View File

@ -0,0 +1,20 @@
import axios from 'axios';
import { request as __request } from './generated/core/request';
import { CancelablePromise } from './generated/core/CancelablePromise';
import { BaseHttpRequest } from './generated/core/BaseHttpRequest';
import { ApiRequestOptions } from './generated/core/ApiRequestOptions';
import type { OpenAPIConfig } from './generated/core/OpenAPI';
export class AxiosHttpRequestWithTimeout extends BaseHttpRequest {
axiosInstance = axios.create({
timeout: 5000,
});
constructor(config: OpenAPIConfig) {
super(config);
}
public override request<T>(options: ApiRequestOptions): CancelablePromise<T> {
return __request(this.config, options, this.axiosInstance);
}
}

3033
yarn.lock

File diff suppressed because it is too large Load Diff