Compare commits

...

105 Commits

Author SHA1 Message Date
Renovate 73189203f3 chore(deps): update dependency eslint-config-prettier to v9.1.0 (#89)
ci/woodpecker/push/test Pipeline was successful Details
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
Renovate ce584fd292 chore(deps): update dependency typescript to v5.4.5 (#99)
ci/woodpecker/push/test Pipeline failed Details
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
Renovate a6f4d4616e chore(deps): update node.js to v20.13.1 (#106)
ci/woodpecker/push/test Pipeline failed Details
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
Renovate 50a42f91f0 chore(deps): update commitlint monorepo to v19.3.0 (#102)
ci/woodpecker/push/test Pipeline failed Details
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
Renovate 9797bbb9d9 chore(deps): update dependency @types/jquery to v3.5.30 (#104)
ci/woodpecker/push/test Pipeline was successful Details
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
Renovate c5005680b4 chore(deps): update dependency @types/lodash to v4.17.3 (#66)
ci/woodpecker/push/test Pipeline failed Details
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
Dawid Wysokiński 99ef0c40de
chore: update README.md
ci/woodpecker/push/test Pipeline was successful Details
ci/woodpecker/tag/docker Pipeline was successful Details
ci/woodpecker/tag/deployment Pipeline was successful Details
2024-04-05 07:41:58 +02:00
Dawid Wysokiński cab4709463
chore(deps): update dependency date-fns to v3
ci/woodpecker/push/test Pipeline was successful Details
2024-04-05 06:38:20 +02:00
Renovate 82b864946b chore(deps): update dependency husky to v9 (#98)
ci/woodpecker/push/test Pipeline was successful Details
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
Dawid Wysokiński b43139bcbb
chore: caddy - enable file listings
ci/woodpecker/push/test Pipeline was successful Details
2024-04-03 07:59:17 +02:00
Dawid Wysokiński 81274707d3
chore: update README.md
ci/woodpecker/push/test Pipeline was successful Details
2024-04-03 07:55:30 +02:00
Dawid Wysokiński f2ed75e4c8
chore: delete manifest.tmpl
ci/woodpecker/push/test Pipeline was successful Details
ci/woodpecker/tag/docker Pipeline was successful Details
ci/woodpecker/tag/deployment Pipeline was successful Details
2024-04-03 07:44:06 +02:00
Dawid Wysokiński dc5f4a03de
chore: add linux/arm64 to docker buildx config
ci/woodpecker/push/test Pipeline was successful Details
2024-04-03 07:41:07 +02:00
Dawid Wysokiński 8496747ac8
chore: update README.md
ci/woodpecker/push/test Pipeline was successful Details
2024-04-03 07:38:16 +02:00
Dawid Wysokiński a637e66258
chore: rename docs folder -> assets
ci/woodpecker/push/test Pipeline was successful Details
2024-04-03 07:32:24 +02:00
Dawid Wysokiński 0fbea77850
feat: specify timeout for api requests
ci/woodpecker/push/test Pipeline was successful Details
2024-04-03 07:29:27 +02:00
Dawid Wysokiński 0d034710b5
refactor: extended tribe profile - use /api/v2
ci/woodpecker/push/test Pipeline was successful Details
2024-04-03 07:18:14 +02:00
Dawid Wysokiński 998deef3aa
refactor: extended player profile - use /api/v2
ci/woodpecker/push/test Pipeline was successful Details
2024-04-03 06:46:29 +02:00
Renovate a740a589be chore(deps): update dependency @types/jquery to v3.5.29 (#82)
ci/woodpecker/push/test Pipeline was successful Details
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
Renovate 8bffd2647b chore(deps): update commitlint monorepo to v19 (major) (#96)
ci/woodpecker/push/test Pipeline was successful Details
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
Dawid Wysokiński af3fffae43
refactor: extended village profile - use /api/v2
ci/woodpecker/push/test Pipeline was successful Details
2024-04-02 08:24:02 +02:00
Dawid Wysokiński a2fb6425a0
refactor: extended map popup - use /api/v2
ci/woodpecker/push/test Pipeline was successful Details
2024-04-02 07:29:59 +02:00
Renovate 93fa246f14 chore(deps): update dependency axios to v1.6.8 (#94)
ci/woodpecker/push/test Pipeline was successful Details
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
Dawid Wysokiński fc9d1be2fe
chore: update README.md [skip ci] 2024-04-01 09:52:38 +02:00
Dawid Wysokiński aaabe449d5
chore: new domain - twhelp.app
ci/woodpecker/push/test Pipeline was successful Details
2024-04-01 09:48:09 +02:00
Dawid Wysokiński ac571326c3
feat: /api/v2 - generate client
ci/woodpecker/push/test Pipeline was successful Details
2024-04-01 09:45:33 +02:00
Renovate cceeb270c4 chore(deps): update commitlint monorepo to v18.6.1 (#92)
ci/woodpecker/push/test Pipeline was successful Details
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
Dawid Wysokiński f94fd27432
chore: update ci/cd pipelines
ci/woodpecker/push/test Pipeline was successful Details
2024-04-01 09:21:56 +02:00
Renovate 1ddcbb66ed chore(deps): update dependency prettier to v3.2.5 (#93)
ci/woodpecker/push/test Pipeline was successful Details
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
Renovate d099601b69 chore(deps): update dependency typescript to v5.4.3 (#88)
ci/woodpecker/push/test Pipeline failed Details
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
Renovate ff364a93ea chore(deps): update node.js to v20 (#79)
ci/woodpecker/push/test Pipeline was successful Details
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
Renovate f38e3d6954 chore(deps): update dependency @types/node to v18.19.14 (#81)
ci/woodpecker/push/test Pipeline was successful Details
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
Renovate 2bfc8b1c84 chore(deps): update dependency axios to v1.6.7 (#91)
ci/woodpecker/push/test Pipeline failed Details
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
Renovate c2fd244639 chore(deps): update caddy docker tag to v2.7.6 (#90)
ci/woodpecker/push/test Pipeline was successful Details
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
Renovate e69cf46abe chore(deps): update commitlint monorepo to v18.4.4 (#86)
ci/woodpecker/push/test Pipeline was successful Details
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
Renovate 56944664ac chore(deps): update commitlint monorepo to v18.4.1 (#85)
ci/woodpecker/push/test Pipeline was successful Details
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
Renovate 0427e0dd60 chore(deps): update dependency axios to v1.6.2 (#84)
ci/woodpecker/push/test Pipeline failed Details
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
Renovate a6a68cd530 chore(deps): update parcel monorepo to v2.10.3 (#83)
ci/woodpecker/push/test Pipeline failed Details
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
Renovate 4bd12132f9 chore(deps): update commitlint monorepo to v18 (major) (#76)
ci/woodpecker/push/test Pipeline was successful Details
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
Renovate d66e2de08d chore(deps): update dependency prettier to v3.1.0 (#77)
ci/woodpecker/push/test Pipeline failed Details
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
Renovate 00397f0aaf chore(deps): update dependency axios to v1.6.1 (#78)
ci/woodpecker/push/test Pipeline failed Details
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
Dawid Wysokiński 483ffa3ef7
chore: bump script versions
ci/woodpecker/push/test Pipeline was successful Details
ci/woodpecker/tag/docker Pipeline was successful Details
ci/woodpecker/tag/deploy Pipeline was successful Details
2023-10-30 09:35:57 +01:00
Dawid Wysokiński 54e5faeb44
chore: update alpine/k8s docker tag to v1.26.9
ci/woodpecker/push/test Pipeline was successful Details
2023-10-30 09:34:38 +01:00
Renovate b7f08832d9 chore(deps): update dependency eslint-config-prettier to v9 (#58)
ci/woodpecker/push/test Pipeline was successful Details
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
Renovate cfc26dd822 chore(deps): update dependency @types/jquery to v3.5.25 (#71)
ci/woodpecker/push/test Pipeline failed Details
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
Renovate 0cae454104 chore(deps): update dependency @types/node to v18.18.7 (#72)
ci/woodpecker/push/test Pipeline failed Details
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
Renovate 58dbb8433d chore(deps): update parcel monorepo to v2.10.1 (#75)
ci/woodpecker/push/test Pipeline failed Details
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
Renovate 4adc41cb7e chore(deps): update dependency prettier to v3 (#52)
ci/woodpecker/push/test Pipeline failed Details
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
Renovate 0bd3692516 chore(deps): update commitlint monorepo to v17.8.1 (#70)
ci/woodpecker/push/test Pipeline was successful Details
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
Renovate fabfcf55e4 chore(deps): update dependency axios to v1.5.1 (#74)
ci/woodpecker/push/test Pipeline failed Details
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
Renovate 754ead62a3 chore(deps): update caddy docker tag to v2.7.5 (#73)
ci/woodpecker/push/test Pipeline was successful Details
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
Renovate 2f1e6e2bff chore(deps): update dependency @types/jquery to v3.5.21 (#65)
ci/woodpecker/push/test Pipeline was successful Details
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
Renovate 156c13e5e1 chore(deps): update dependency @types/node to v18.18.3 (#50)
ci/woodpecker/push/test Pipeline failed Details
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
Renovate fe800229a5 chore(deps): update node.js to v18.18 (#68)
ci/woodpecker/push/test Pipeline failed Details
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
Dawid Wysokiński 24b5c4d24d
chore: remove unnecessary group [skip ci] 2023-09-09 07:23:05 +02:00
Dawid Wysokiński 41614f5054
chore: bump user scripts versions
ci/woodpecker/push/test Pipeline was successful Details
ci/woodpecker/tag/docker Pipeline was successful Details
ci/woodpecker/tag/deploy Pipeline was successful Details
2023-09-09 07:04:42 +02:00
Dawid Wysokiński 4e54a84ff5 feat: migrate from drone to woodpecker (#67)
ci/woodpecker/push/test Pipeline was successful Details
Reviewed-on: #67
2023-09-09 05:03:30 +00:00
Renovate 900c173702 chore(deps): update dependency axios to v1.5.0 (#64)
continuous-integration/drone/push Build is passing Details
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
Renovate 03e151d4e1 chore(deps): update dependency typescript to v5.2.2 (#63)
continuous-integration/drone/push Build is passing Details
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
Dawid Wysokiński 26965f9f73
fix: metadata are added more than once to the output
continuous-integration/drone/push Build is passing Details
2023-08-19 07:55:46 +02:00
Renovate 3140f56ae9 chore(deps): update commitlint monorepo to v17.7.1 (#59)
continuous-integration/drone/push Build is passing Details
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
Renovate b53acc0499 chore(deps): update caddy docker tag to v2.7.4 (#61)
continuous-integration/drone/push Build is passing Details
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
Renovate 5952c4e0fb chore(deps): update caddy docker tag to v2.7.3 (#60)
continuous-integration/drone/push Build is passing Details
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
Renovate 7ab3ce1955 chore(deps): update dependency eslint-config-prettier to v8.10.0 (#56)
continuous-integration/drone/push Build is passing Details
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
Renovate f868086570 chore(deps): update caddy docker tag to v2.7.2 (#57)
continuous-integration/drone/push Build is passing Details
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
Renovate 1987c99761 chore(deps): update typescript-eslint monorepo to v5.62.0 (#51)
continuous-integration/drone/push Build is passing Details
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
Renovate 9e21d30c77 chore(deps): update commitlint monorepo to v17.6.7 (#54)
continuous-integration/drone/push Build is passing Details
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
Dawid Wysokiński b05d0413b1
feat: ci/cd - email notifications
continuous-integration/drone/push Build is passing Details
2023-07-01 14:14:58 +02:00
Dawid Wysokiński 3f3e836177
chore: bump script versions
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2023-07-01 09:52:57 +02:00
renovate b3e6edb08e chore(deps): update dependency typescript to v5.1.6 (#49)
continuous-integration/drone/push Build is passing Details
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
renovate 59e5933167 chore(deps): update dependency typescript to v5.1.5 (#48)
continuous-integration/drone/push Build is passing Details
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
renovate d609f87550 chore(deps): update parcel monorepo to v2.9.3 (#46)
continuous-integration/drone/push Build is passing Details
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
renovate 83f142ad97 chore(deps): update commitlint monorepo to v17.6.6 (#45)
continuous-integration/drone/push Build is passing Details
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
renovate 7bb73e9dce chore(deps): update typescript-eslint monorepo to v5.60.0 (#44)
continuous-integration/drone/push Build is passing Details
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
renovate 4e8422c435 chore(deps): update parcel monorepo to v2.9.2 (#42)
continuous-integration/drone/push Build is passing Details
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
Dawid Wysokiński 56fbe86774
chore: update alpine/k8s to v1.26.5
continuous-integration/drone/push Build is passing Details
2023-06-09 06:59:27 +02:00
renovate c26c7ebbc9 chore(deps): update dependency @types/lodash to v4.14.195 (#37)
continuous-integration/drone/push Build is passing Details
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
renovate 8dc4faa06f chore(deps): update typescript-eslint monorepo to v5.59.9 (#41)
continuous-integration/drone/push Build is passing Details
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
Dawid Wysokiński a968d42e8a
chore: bump typescript to v5.1.3 and remove npm-run-all from devDependencies
continuous-integration/drone/push Build is passing Details
2023-06-02 08:12:06 +02:00
Dawid Wysokiński 0ff002ce1a
chore(deps): update parcel monorepo to v2.9.1
continuous-integration/drone/push Build is passing Details
2023-06-02 08:05:32 +02:00
renovate 24a9b7113f chore(deps): update commitlint monorepo to v17.6.5 (#39)
continuous-integration/drone/push Build is passing Details
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
renovate 4a30e57fbf chore(deps): update typescript-eslint monorepo to v5.59.8 (#36)
continuous-integration/drone/push Build is passing Details
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
renovate 31f276a981 chore(deps): update typescript-eslint monorepo to v5.59.6 (#35)
continuous-integration/drone/push Build is passing Details
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
renovate 773d95e923 chore(deps): update typescript-eslint monorepo to v5.59.5 (#34)
continuous-integration/drone/push Build is passing Details
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
renovate 9f33b32632 chore(deps): update dependency typescript to v5.0.4 (#30)
continuous-integration/drone/push Build is passing Details
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
renovate da32822563 chore(deps): update typescript-eslint monorepo to v5.59.2 (#32)
continuous-integration/drone/push Build is passing Details
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
renovate 11cd008009 chore(deps): update commitlint monorepo to v17.6.3 (#33)
continuous-integration/drone/push Build is passing Details
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
renovate c6b51673d6 chore(deps): update dependency date-fns to v2.30.0 (#31)
continuous-integration/drone/push Build is passing Details
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
Dawid Wysokiński b03bae4cd9
refactor: replace deprecated endpoints
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2023-05-07 08:03:51 +02:00
Dawid Wysokiński c29f987caa
chore: update alpine/k8s docker tag to v1.26.4 [skip ci] 2023-05-01 06:54:04 +02:00
renovate f2dd3d10a8 chore(deps): update dependency typescript to v5 (#14)
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
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
renovate 40c4fb7e7c chore(deps): update typescript-eslint monorepo to v5.59.1 (#22)
continuous-integration/drone/push Build is passing Details
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
renovate 75b1d6987d chore(deps): update dependency @types/lodash to v4.14.194 (#23)
continuous-integration/drone/push Build is passing Details
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
renovate 85ad186242 chore(deps): update dependency prettier to v2.8.8 (#29)
continuous-integration/drone/push Build is passing Details
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
renovate 7763f8246d chore(deps): update dependency axios to v1.4.0 (#27)
continuous-integration/drone/push Build is passing Details
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
renovate 8ecfce7ac9 chore(deps): update dependency axios to v1.3.5 (#25)
continuous-integration/drone/push Build is passing Details
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
renovate 5c76bd3f14 chore(deps): update commitlint monorepo to v17.6.1 (#26)
continuous-integration/drone/push Build is passing Details
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
renovate dad998978c chore(deps): update dependency @commitlint/cli to v17.5.1 (#18)
continuous-integration/drone/push Build is passing Details
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
renovate 0e1b744f5a chore(deps): update dependency eslint-config-prettier to v8.8.0 (#21)
continuous-integration/drone/push Build is passing Details
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
renovate 5545e6617a chore(deps): update dependency axios to v1.3.4 (#20)
continuous-integration/drone/push Build is passing Details
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
renovate 1d8480d90e chore(deps): update node.js to v16.20 (#24)
continuous-integration/drone/push Build is passing Details
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
renovate 95ed638c2a chore(deps): update dependency @types/jquery to v3.5.16 (#15)
continuous-integration/drone/push Build is passing Details
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
renovate 3257e748e9 chore(deps): update dependency typescript to v4.9.5 (#17)
continuous-integration/drone/push Build is passing Details
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
renovate 6b037c00fd chore(deps): update dependency prettier to v2.8.7 (#16)
continuous-integration/drone/push Build is passing Details
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
Dawid Wysokiński 418e6f2c99 feat: add commitlint (#13)
continuous-integration/drone/push Build is passing Details
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
k8s
.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 {
root * /var/www
file_server
file_server browse
header -Server
header Cache-Control max-age=3600
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.13-alpine as build-deps
WORKDIR /app
COPY package.json yarn.lock ./
@ -8,7 +8,7 @@ COPY . ./
ENV NODE_ENV=production
RUN yarn build
FROM caddy:2.6.4-alpine
FROM caddy:2.7.6-alpine
COPY --from=build-deps /app/dist /var/www
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
@ -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.
![img.png](docs/extended-player-profile.png)
![img.png](assets/extended-player-profile.png)
#### 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:
```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
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
[User script](https://scripts.tribalwarshelp.com/extended-tribe-profile.user.js)
[User script](https://scripts.twhelp.app/extended-tribe-profile.user.js)
Quick bar:
```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
This script extends the map popup with additional info.
![img.png](docs/extended-map-popup.png)
![img.png](assets/extended-map-popup.png)
#### 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:
```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
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
[User script](https://scripts.tribalwarshelp.com/extended-village-profile.user.js)
[User script](https://scripts.twhelp.app/extended-village-profile.user.js)
Quick bar:
```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
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
port:
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",
"license": "MIT",
"scripts": {
"build-single": "PUBLIC_URL=https://scripts.tribalwarshelp.com parcel build",
"build:extended-player-profile-user": "PREAMBLE=extended-player-profile yarn build-single ./src/extended-player-profile.user.ts",
"build:extended-player-profile-quickbar": "yarn build-single ./src/extended-player-profile.quickbar.ts",
"build:extended-map-popup-user": "PREAMBLE=extended-map-popup yarn build-single ./src/extended-map-popup.user.ts",
"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:*",
"prepare": "husky",
"generate-client": "openapi --input src/lib/twhelp/openapi3.json --output src/lib/twhelp/generated --name TWHelpClient --useOptions --client axios",
"build": "rm -rf dist && yarn generate-client && parcel build ./src/*.user.ts ./src/*.quickbar.ts",
"postbuild": "PUBLIC_URL=https://scripts.twhelp.app node postbuild.js",
"lint": "eslint src/**/*.ts"
},
"targets": {
@ -27,27 +21,30 @@
"url": "https://dwysokinski.me/"
},
"browserslist": [
"since 2017-06"
"since 2020-01"
],
"devDependencies": {
"@parcel/validator-eslint": "^2.8.3",
"@parcel/validator-typescript": "^2.8.3",
"@commitlint/cli": "^19.0.0",
"@commitlint/config-conventional": "^19.0.0",
"@parcel/validator-eslint": "^2.12.0",
"@parcel/validator-typescript": "^2.12.0",
"@types/jquery": "^3.5.14",
"@types/lodash": "^4.14.191",
"@types/node": "^18.11.17",
"@types/node": "^20.0.0",
"@typescript-eslint/eslint-plugin": "^5.50.0",
"@typescript-eslint/parser": "^5.50.0",
"buffer": "^5.5.0",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.6.0",
"npm-run-all": "^4.1.5",
"parcel": "^2.8.3",
"prettier": "^2.8.3",
"typescript": "^4.9.4"
"eslint-config-prettier": "^9.0.0",
"husky": "^9.0.0",
"openapi-typescript-codegen": "^0.28.0",
"parcel": "^2.12.0",
"prettier": "^3.0.0",
"typescript": "^5.0.0"
},
"dependencies": {
"axios": "^1.2.2",
"date-fns": "^2.29.3",
"date-fns": "^3.0.0",
"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==
// @name Extended player profile
// @version 1.1.2
// @version 1.2.0
// @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*
// @downloadURL ${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==`,
'extended-map-popup': `// ==UserScript==
// @name Extended map popup
// @version 1.0.2
// @version 1.1.0
// @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*
// @downloadURL ${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==`,
'extended-village-profile': `// ==UserScript==
// @name Extended village profile
// @version 1.0.1
// @version 1.1.0
// @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*
// @downloadURL ${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==`,
'extended-tribe-profile': `// ==UserScript==
// @name Extended tribe profile
// @version 1.0.0
// @version 1.1.0
// @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*
// @downloadURL ${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==`,
};
const preamble = preambles[process.env.PREAMBLE];
module.exports = preamble
? {
output: {
preamble: preamble,
},
}
: {};
Object.entries(metadata).forEach(([name, m]) => {
const p = path.join('.', DIST_DIR, `${name}${FILE_SUFFIX}`);
const data = fs.readFileSync(p);
const fd = fs.openSync(p, 'w+');
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;
};
export type Cursor = {
next?: string;
self?: string;
};
export type LoadDataResult<T> = {
cursor?: Cursor;
data: T[];
total: number;
};
export class DialogTable<T> {
prevPageId: string;
selectId: string;
nextPageId: string;
private readonly prevPageId: string;
private readonly nextPageId: string;
private readonly prevCursors: Cursor[] = [];
constructor(
private readonly id: string,
private readonly columns: DialogTableColumn<T>[],
private readonly limit: number,
private readonly loadData: (
page: number,
cursor: string | undefined,
limit: number
) => Promise<LoadDataResult<T>>
) {
this.prevPageId = `${this.id}_page_prev`;
this.selectId = `${this.id}_page_select`;
this.nextPageId = `${this.id}_page_next`;
}
public async render() {
await this.renderPage(1);
await this.renderPage();
}
private async renderPage(page: number) {
window.Dialog.show(`${this.id}_loading`, `<p>${t('Loading')}...</p>`);
private async renderPage(pageCursor?: string) {
window.Dialog.show(this.id, `<p>${t('Loading')}...</p>`);
try {
const { data, total } = await this.loadData(page, this.limit);
const { data, cursor } = await this.loadData(pageCursor, this.limit);
window.Dialog.show(
this.id,
`
${this.buildPagination(page, total)}
${this.buildPagination(cursor)}
${this.buildTable(data)}
`
);
this.addEventListeners(page);
this.addEventListeners(cursor);
} catch (err) {
console.error(err);
window.Dialog.close();
@ -64,31 +70,17 @@ export class DialogTable<T> {
}
}
private buildPagination(page: number, total: number): 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>`
);
}
private buildPagination(cursor?: Cursor): string {
return `
<div style="display: flex; flex-direction: row; align-items: center; justify-content: center; margin-bottom: 10px">
<button title="${t(
'Previous page'
)}" style="margin-right: 5px" class="btn" id="${this.prevPageId}"${
page <= 1 ? ' disabled' : ''
}>&lt;</button>
<select style="margin-right: 5px" id="${this.selectId}">
${pageOpts.join('')}
</select>
this.prevCursors.length === 0 ? ' disabled' : ''
}>&lt;</button>
<button title="${t('Next page')}" class="btn" id="${
this.nextPageId
}"${page >= maxPage ? ' disabled' : ''}>&gt;</button>
this.nextPageId
}"${!cursor?.next ? ' disabled' : ''}>&gt;</button>
</div>
`;
}
@ -116,27 +108,25 @@ export class DialogTable<T> {
`;
}
private addEventListeners(page: number) {
private addEventListeners(cursor?: Cursor) {
document
.querySelector('#' + this.prevPageId)
?.addEventListener('click', () => {
this.renderPage(page - 1);
});
document
.querySelector('#' + this.selectId)
?.addEventListener('change', (e: Event) => {
if (!(e.currentTarget instanceof HTMLSelectElement)) {
const prev = this.prevCursors.pop();
if (!prev) {
return;
}
this.renderPage(parseInt(e.currentTarget.value));
this.renderPage(prev.self);
});
document
.querySelector('#' + this.nextPageId)
?.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 {
Ennoblement,
ServerConfig,
TWHelpClient,
UnitInfo,
} from './lib/twhelp';
import { addSeconds } from 'date-fns/addSeconds';
import { Cache, InMemoryStorage } from './lib/cache';
import { calcDistance, calcLoyalty } from './lib/tw';
import { createTranslationFunc } from './utils';
import {
TWHelpClient,
Ennoblement,
UnitInfo,
ServerConfig,
AxiosHttpRequestWithTimeout,
} from './lib/twhelp';
declare global {
interface Window {
@ -43,25 +44,41 @@ const t = createTranslationFunc({
class TWHelpConnector {
private static readonly SERVER_CONFIG_CACHE_KEY =
'extended_map_popup_server_config';
private static readonly UNIT_INFO_CACHE_KEY = 'extended_map_popup_unit_info';
'extended_map_popup_server_config_v2';
private static readonly UNIT_INFO_CACHE_KEY =
'extended_map_popup_unit_info_v2';
private static readonly VILLAGE_CACHE_KEY_PREFIX =
'extended_map_popup_village_';
'extended_map_popup_village_v2_';
private readonly localStorageCache = new Cache(localStorage);
private readonly inMemoryCache = new Cache(new InMemoryStorage());
private readonly client: TWHelpClient;
constructor(
private readonly client: TWHelpClient,
readonly baseUrl: string,
private readonly version: string,
private readonly server: string
) {}
) {
this.client = new TWHelpClient(
{
BASE: baseUrl,
},
AxiosHttpRequestWithTimeout
);
}
serverConfig() {
return this.localStorageCache.load(
TWHelpConnector.SERVER_CONFIG_CACHE_KEY,
3600,
() => {
return this.client.serverConfig(this.version, this.server);
async () => {
return (
await this.client.servers.getServerConfig({
serverKey: this.server,
versionCode: this.version,
})
).data;
}
);
}
@ -70,8 +87,13 @@ class TWHelpConnector {
return this.localStorageCache.load(
TWHelpConnector.UNIT_INFO_CACHE_KEY,
3600,
() => {
return this.client.unitInfo(this.version, this.server);
async () => {
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 () => {
const ennoblements = await this.client.villageEnnoblements(
this.version,
this.server,
id,
{
limit: 1,
const ennoblements =
await this.client.ennoblements.listVillageEnnoblements({
versionCode: this.version,
serverKey: this.server,
sort: ['createdAt:DESC'],
}
);
villageId: id,
limit: 1,
});
return ennoblements.data.length > 0 ? ennoblements.data[0] : null;
});
}
@ -245,9 +266,9 @@ class Popup {
class ExtendedMapPopup {
connector: TWHelpConnector;
constructor(client: TWHelpClient) {
constructor(baseApiUrl: string) {
this.connector = new TWHelpConnector(
client,
baseApiUrl,
window.game_data.market,
window.game_data.world
);
@ -273,9 +294,7 @@ class ExtendedMapPopup {
return;
}
await new ExtendedMapPopup(
new TWHelpClient(process.env.TWHELP_API_BASE_URL ?? '')
)
await new ExtendedMapPopup(process.env.TWHELP_API_BASE_URL ?? '')
.run()
.catch((err) => {
console.log(err);

View File

@ -1,10 +1,16 @@
// Extended player profile
import { Player, PlayerSnapshot, TWHelpClient } from './lib/twhelp';
import { DialogTable } from './common/dialog-table';
import { InADayClient } from './lib/tw';
import { createTranslationFunc } from './utils';
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({
pl_PL: {
@ -59,62 +65,98 @@ const t = createTranslationFunc({
});
class TWHelpConnector {
private readonly client: TWHelpClient;
constructor(
private readonly client: TWHelpClient,
readonly baseUrl: string,
private readonly version: string,
private readonly server: string,
private readonly id: number
) {}
) {
this.client = new TWHelpClient(
{
BASE: baseUrl,
},
AxiosHttpRequestWithTimeout
);
}
player() {
return this.client.player(this.version, this.server, this.id);
async player() {
return (
await this.client.players.getPlayer({
versionCode: this.version,
serverKey: this.server,
playerId: this.id,
})
).data;
}
async latestSnapshot() {
const history = await this.playerHistory(1, 1);
return history.data.length > 0 ? history.data[0] : null;
const snapshot = await this.playerSnapshots(undefined, 1);
return snapshot.data.length > 0 ? snapshot.data[0] : null;
}
playerTribeChanges(page: number, limit: number) {
return this.client.playerTribeChanges(this.version, this.server, this.id, {
offset: (page - 1) * limit,
playerTribeChanges(cursor: string | undefined, limit: number) {
return this.client.tribeChanges.listPlayerTribeChanges({
versionCode: this.version,
serverKey: this.server,
playerId: this.id,
limit,
sort: ['createdAt:desc', 'id:asc'],
cursor,
sort: ['createdAt:DESC'],
});
}
playerEnnoblements(page: number, limit: number) {
return this.client.playerEnnoblements(this.version, this.server, this.id, {
offset: (page - 1) * limit,
playerEnnoblements(cursor: string | undefined, limit: number) {
return this.client.ennoblements.listPlayerEnnoblements({
versionCode: this.version,
serverKey: this.server,
playerId: this.id,
limit,
sort: ['createdAt:desc'],
cursor,
sort: ['createdAt:DESC'],
});
}
playerHistory(page: number, limit: number) {
return this.client.playerHistory(this.version, this.server, this.id, {
offset: (page - 1) * limit,
playerSnapshots(cursor: string | undefined, limit: number) {
return this.client.snapshots.listPlayerPlayerSnapshots({
versionCode: this.version,
serverKey: this.server,
playerId: this.id,
limit,
sort: ['date:desc'],
cursor,
sort: ['date:DESC'],
});
}
playerOtherServers(page: number, limit: number) {
return this.client.playerOtherServers(this.version, this.server, this.id, {
offset: (page - 1) * limit,
playerOtherServers(cursor: string | undefined, limit: number) {
return this.client.players.listVersionPlayers({
versionCode: this.version,
limit,
cursor,
id: [this.id],
});
}
}
class InADayConnector {
constructor(
private readonly client: InADayClient,
private readonly name: string
) {}
private static readonly CACHE_KEY_PREFIX =
'extended_player_profile_in_a_day_';
private readonly cache = new Cache(localStorage);
private readonly client = new InADayClient();
constructor(private readonly name: string) {}
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>
<td>${t('Best rank')}:</td>
<td>${this.player.bestRank} (${new Date(
this.player.bestRankAt
).toLocaleString()})</td>
this.player.bestRankAt
).toLocaleString()})</td>
</tr>
<tr>
<td>${t('Most points')}:</td>
<td>${this.player.mostPoints.toLocaleString()} (${new Date(
this.player.mostPointsAt
).toLocaleString()})</td>
this.player.mostPointsAt
).toLocaleString()})</td>
</tr>
<tr>
<td>${t('Most villages')}:</td>
<td>${this.player.mostVillages.toLocaleString()} (${new Date(
this.player.mostVillagesAt
).toLocaleString()})</td>
this.player.mostVillagesAt
).toLocaleString()})</td>
</tr>
`
);
@ -204,38 +246,54 @@ class UI {
},
{
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'),
value: this.player.rankAtt - (this.latestSnapshot?.rankAtt ?? 0),
value:
this.player.opponentsDefeated.rankAtt -
(this.latestSnapshot?.opponentsDefeated.rankAtt ?? 0),
rank: true,
},
{
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'),
value: this.player.rankDef - (this.latestSnapshot?.rankDef ?? 0),
value:
this.player.opponentsDefeated.rankDef -
(this.latestSnapshot?.opponentsDefeated.rankDef ?? 0),
rank: true,
},
{
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'),
value: this.player.rankSup - (this.latestSnapshot?.rankSup ?? 0),
value:
this.player.opponentsDefeated.rankSup -
(this.latestSnapshot?.opponentsDefeated.rankSup ?? 0),
rank: true,
},
{
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'),
value: this.player.rankTotal - (this.latestSnapshot?.rankTotal ?? 0),
value:
this.player.opponentsDefeated.rankTotal -
(this.latestSnapshot?.opponentsDefeated.rankTotal ?? 0),
rank: true,
},
];
@ -364,8 +422,8 @@ class UI {
},
],
30,
(page: number, limit: number) => {
return this.twhelpConnector.playerOtherServers(page, limit);
(cursor: string | undefined, limit: number) => {
return this.twhelpConnector.playerOtherServers(cursor, limit);
}
).render();
}
@ -454,8 +512,8 @@ class UI {
},
],
30,
(page: number, limit: number) => {
return this.twhelpConnector.playerTribeChanges(page, limit);
(cursor: string | undefined, limit: number) => {
return this.twhelpConnector.playerTribeChanges(cursor, limit);
}
).render();
}
@ -473,8 +531,8 @@ class UI {
{
header: t('Tribe'),
accessor: (s) =>
s.tribe
? `<a href="${s.tribe.profileUrl}">${s.tribe.tag}</a>`
s.player.tribe
? `<a href="${s.player.tribe.profileUrl}">${s.player.tribe.tag}</a>`
: '-',
},
{
@ -489,29 +547,29 @@ class UI {
{
header: t('OD'),
accessor: (s) =>
`${s.scoreTotal.toLocaleString()} (<strong>${
s.rankTotal
`${s.opponentsDefeated.scoreTotal.toLocaleString()} (<strong>${
s.opponentsDefeated.rankTotal
}</strong>)`,
},
{
header: t('ODA'),
accessor: (s) =>
`${s.scoreAtt.toLocaleString()} (<strong>${s.rankAtt}</strong>)`,
`${s.opponentsDefeated.scoreAtt.toLocaleString()} (<strong>${s.opponentsDefeated.rankAtt}</strong>)`,
},
{
header: t('ODD'),
accessor: (s) =>
`${s.scoreDef.toLocaleString()} (<strong>${s.rankDef}</strong>)`,
`${s.opponentsDefeated.scoreDef.toLocaleString()} (<strong>${s.opponentsDefeated.rankDef}</strong>)`,
},
{
header: t('ODS'),
accessor: (s) =>
`${s.scoreSup.toLocaleString()} (<strong>${s.rankSup}</strong>)`,
`${s.opponentsDefeated.scoreSup.toLocaleString()} (<strong>${s.opponentsDefeated.rankSup}</strong>)`,
},
],
30,
(page: number, limit: number) => {
return this.twhelpConnector.playerHistory(page, limit);
(cursor: string | undefined, limit: number) => {
return this.twhelpConnector.playerSnapshots(cursor, limit);
}
).render();
}
@ -563,8 +621,8 @@ class UI {
},
],
30,
(page: number, limit: number) => {
return this.twhelpConnector.playerEnnoblements(page, limit);
(cursor: string | undefined, limit: number) => {
return this.twhelpConnector.playerEnnoblements(cursor, limit);
}
).render();
}
@ -574,18 +632,15 @@ class ExtendedPlayerProfile {
private readonly twhelpConnector: TWHelpConnector;
private readonly inADayConnector: InADayConnector;
constructor(twhelpClient: TWHelpClient, inADayClient: InADayClient) {
constructor(apiBaseUrl: string) {
this.twhelpConnector = new TWHelpConnector(
twhelpClient,
apiBaseUrl,
window.game_data.market,
window.game_data.world,
this.getPlayerId()
);
this.inADayConnector = new InADayConnector(
inADayClient,
this.getPlayerName()
);
this.inADayConnector = new InADayConnector(this.getPlayerName());
}
async run() {
@ -627,10 +682,7 @@ class ExtendedPlayerProfile {
return;
}
await new ExtendedPlayerProfile(
new TWHelpClient(process.env.TWHELP_API_BASE_URL ?? ''),
new InADayClient()
)
await new ExtendedPlayerProfile(process.env.TWHELP_API_BASE_URL ?? '')
.run()
.catch((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 { DialogTable } from './common/dialog-table';
import { buildURL } from './lib/twstats';
import { DialogTable } from './common/dialog-table';
const t = createTranslationFunc({
pl_PL: {
@ -44,47 +50,75 @@ const t = createTranslationFunc({
});
class TWHelpConnector {
private readonly client: TWHelpClient;
constructor(
private readonly client: TWHelpClient,
baseUrl: string,
private readonly version: string,
private readonly server: string,
private readonly id: number
) {}
) {
this.client = new TWHelpClient(
{
BASE: baseUrl,
},
AxiosHttpRequestWithTimeout
);
}
tribe() {
return this.client.tribe(this.version, this.server, this.id);
async tribe() {
return (
await this.client.tribes.getTribe({
versionCode: this.version,
serverKey: this.server,
tribeId: this.id,
})
).data;
}
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() {
const history = await this.tribeHistory(1, 1);
return history.data.length > 0 ? history.data[0] : null;
const snapshot = await this.tribeSnapshots(undefined, 1);
return snapshot.data.length > 0 ? snapshot.data[0] : null;
}
tribeHistory(page: number, limit: number) {
return this.client.tribeHistory(this.version, this.server, this.id, {
offset: (page - 1) * limit,
tribeSnapshots(cursor: string | undefined, limit: number) {
return this.client.snapshots.listTribeTribeSnapshots({
versionCode: this.version,
serverKey: this.server,
tribeId: this.id,
cursor,
limit,
sort: ['date:desc'],
sort: ['date:DESC'],
});
}
tribeTribeChanges(page: number, limit: number) {
return this.client.tribeTribeChanges(this.version, this.server, this.id, {
offset: (page - 1) * limit,
memberChanges(cursor: string | undefined, limit: number) {
return this.client.tribeChanges.listTribeMemberChanges({
versionCode: this.version,
serverKey: this.server,
tribeId: this.id,
cursor,
limit,
sort: ['createdAt:desc'],
sort: ['createdAt:DESC'],
});
}
tribeEnnoblements(page: number, limit: number) {
return this.client.tribeEnnoblements(this.version, this.server, this.id, {
offset: (page - 1) * limit,
tribeEnnoblements(cursor: string | undefined, limit: number) {
return this.client.ennoblements.listTribeEnnoblements({
versionCode: this.version,
serverKey: this.server,
tribeId: this.id,
cursor,
limit,
sort: ['createdAt:desc'],
sort: ['createdAt:DESC'],
});
}
}
@ -133,20 +167,20 @@ class UI {
<tr>
<td>${t('Best rank')}:</td>
<td>${this.tribe.bestRank} (${new Date(
this.tribe.bestRankAt
).toLocaleString()})</td>
this.tribe.bestRankAt
).toLocaleString()})</td>
</tr>
<tr>
<td>${t('Most points')}:</td>
<td>${this.tribe.mostPoints.toLocaleString()} (${new Date(
this.tribe.mostPointsAt
).toLocaleString()})</td>
this.tribe.mostPointsAt
).toLocaleString()})</td>
</tr>
<tr>
<td>${t('Most villages')}:</td>
<td>${this.tribe.mostVillages.toLocaleString()} (${new Date(
this.tribe.mostVillagesAt
).toLocaleString()})</td>
this.tribe.mostVillagesAt
).toLocaleString()})</td>
</tr>
`
);
@ -185,29 +219,41 @@ class UI {
},
{
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'),
value: this.tribe.rankAtt - (this.latestSnapshot?.rankAtt ?? 0),
value:
this.tribe.opponentsDefeated.rankAtt -
(this.latestSnapshot?.opponentsDefeated.rankAtt ?? 0),
rank: true,
},
{
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'),
value: this.tribe.rankDef - (this.latestSnapshot?.rankDef ?? 0),
value:
this.tribe.opponentsDefeated.rankDef -
(this.latestSnapshot?.opponentsDefeated.rankDef ?? 0),
rank: true,
},
{
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'),
value: this.tribe.rankTotal - (this.latestSnapshot?.rankTotal ?? 0),
value:
this.tribe.opponentsDefeated.rankTotal -
(this.latestSnapshot?.opponentsDefeated.rankTotal ?? 0),
rank: true,
},
];
@ -231,10 +277,10 @@ class UI {
r.value,
r.rank
)}">${
r.customFormat
? r.customFormat(r.value)
: Math.abs(r.value).toLocaleString()
}</td>
r.customFormat
? r.customFormat(r.value)
: Math.abs(r.value).toLocaleString()
}</td>
</tr>
`
)
@ -323,8 +369,8 @@ class UI {
},
],
30,
(page: number, limit: number) => {
return this.twhelpConnector.tribeTribeChanges(page, limit);
(cursor: string | undefined, limit: number) => {
return this.twhelpConnector.memberChanges(cursor, limit);
}
).render();
}
@ -359,24 +405,24 @@ class UI {
{
header: t('OD'),
accessor: (s) =>
`${s.scoreTotal.toLocaleString()} (<strong>${
s.rankTotal
`${s.opponentsDefeated.scoreTotal.toLocaleString()} (<strong>${
s.opponentsDefeated.rankTotal
}</strong>)`,
},
{
header: t('ODA'),
accessor: (s) =>
`${s.scoreAtt.toLocaleString()} (<strong>${s.rankAtt}</strong>)`,
`${s.opponentsDefeated.scoreAtt.toLocaleString()} (<strong>${s.opponentsDefeated.rankAtt}</strong>)`,
},
{
header: t('ODD'),
accessor: (s) =>
`${s.scoreDef.toLocaleString()} (<strong>${s.rankDef}</strong>)`,
`${s.opponentsDefeated.scoreDef.toLocaleString()} (<strong>${s.opponentsDefeated.rankDef}</strong>)`,
},
],
30,
(page: number, limit: number) => {
return this.twhelpConnector.tribeHistory(page, limit);
(cursor: string | undefined, limit: number) => {
return this.twhelpConnector.tribeSnapshots(cursor, limit);
}
).render();
}
@ -428,8 +474,8 @@ class UI {
},
],
30,
(page: number, limit: number) => {
return this.twhelpConnector.tribeEnnoblements(page, limit);
(cursor: string | undefined, limit: number) => {
return this.twhelpConnector.tribeEnnoblements(cursor, limit);
}
).render();
}
@ -477,10 +523,10 @@ class UI {
const member = this.members.find((m) => m.id === id);
[
(member?.rankAtt ?? 0).toString(),
(member?.rankDef ?? 0).toString(),
(member?.rankSup ?? 0).toString(),
(member?.rankTotal ?? 0).toString(),
(member?.opponentsDefeated.rankAtt ?? 0).toString(),
(member?.opponentsDefeated.rankDef ?? 0).toString(),
(member?.opponentsDefeated.rankSup ?? 0).toString(),
(member?.opponentsDefeated.rankTotal ?? 0).toString(),
member?.lastActivityAt
? new Date(member.lastActivityAt).toLocaleString()
: '-',
@ -501,9 +547,9 @@ class UI {
class ExtendedTribeProfile {
private readonly twhelpConnector: TWHelpConnector;
constructor(twhelpClient: TWHelpClient) {
constructor(apiBaseUrl: string) {
this.twhelpConnector = new TWHelpConnector(
twhelpClient,
apiBaseUrl,
window.game_data.market,
window.game_data.world,
this.getTribeId()
@ -543,9 +589,7 @@ class ExtendedTribeProfile {
return;
}
await new ExtendedTribeProfile(
new TWHelpClient(process.env.TWHELP_API_BASE_URL ?? '')
)
await new ExtendedTribeProfile(process.env.TWHELP_API_BASE_URL ?? '')
.run()
.catch((err) => {
console.log(err);

View File

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

View File

@ -1,5 +1,5 @@
import addSeconds from 'date-fns/addSeconds';
import isAfter from 'date-fns/isAfter';
import { addSeconds } from 'date-fns/addSeconds';
import { isAfter } from 'date-fns/isAfter';
export interface Storage {
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';
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