@nekosuneprojects/gaming-infos 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/sync-api-cache.yml +72 -0
- package/CACHE_SYNC.md +172 -0
- package/CHANGELOG.md +23 -2
- package/README.md +455 -126
- package/data/arknightsendfield/meta.json +14 -0
- package/data/fortnite/meta.json +14 -0
- package/data/game-codes/.gitkeep +0 -0
- package/data/toweroffantasy/meta.json +14 -0
- package/data/vrchat/avatars/.gitkeep +0 -0
- package/data/warframe/meta.json +14 -0
- package/data/wutheringwaves/meta.json +14 -0
- package/data/zenlesszonezero/meta.json +14 -0
- package/gamecodes.js +178 -0
- package/index.js +34 -17
- package/package.json +20 -2
- package/scripts/cache-sync-smoke.js +92 -0
- package/scripts/game-code-cache-smoke.js +85 -0
- package/scripts/sync-all-cache.js +18 -0
- package/scripts/sync-api-cache.js +319 -0
- package/scripts/sync-game-code-cache.js +244 -0
- package/scripts/sync-gaming-info-cache.js +46 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
name: Sync APINODE fallback caches
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
schedule:
|
|
6
|
+
# Daily at 03:23 UTC. GitHub Actions cron uses UTC.
|
|
7
|
+
- cron: "23 3 * * *"
|
|
8
|
+
push:
|
|
9
|
+
branches:
|
|
10
|
+
- main
|
|
11
|
+
paths:
|
|
12
|
+
- "scripts/sync-api-cache.js"
|
|
13
|
+
- "scripts/sync-gaming-info-cache.js"
|
|
14
|
+
- "scripts/sync-game-code-cache.js"
|
|
15
|
+
- "scripts/sync-all-cache.js"
|
|
16
|
+
- "scripts/cache-sync-smoke.js"
|
|
17
|
+
- "scripts/game-code-cache-smoke.js"
|
|
18
|
+
- "gamecodes.js"
|
|
19
|
+
- "index.js"
|
|
20
|
+
- "package.json"
|
|
21
|
+
- "CACHE_SYNC.md"
|
|
22
|
+
- ".github/workflows/sync-api-cache.yml"
|
|
23
|
+
|
|
24
|
+
permissions:
|
|
25
|
+
contents: write
|
|
26
|
+
|
|
27
|
+
concurrency:
|
|
28
|
+
group: gaming-infos-api-cache
|
|
29
|
+
cancel-in-progress: false
|
|
30
|
+
|
|
31
|
+
jobs:
|
|
32
|
+
sync:
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
steps:
|
|
35
|
+
- name: Checkout
|
|
36
|
+
uses: actions/checkout@v4
|
|
37
|
+
with:
|
|
38
|
+
fetch-depth: 0
|
|
39
|
+
|
|
40
|
+
- name: Use Node.js 22
|
|
41
|
+
uses: actions/setup-node@v4
|
|
42
|
+
with:
|
|
43
|
+
node-version: 22
|
|
44
|
+
|
|
45
|
+
- name: Test atomic cache behavior
|
|
46
|
+
run: npm run test:all-cache
|
|
47
|
+
|
|
48
|
+
- name: Mirror APINODE gaming-infos and game codes
|
|
49
|
+
run: npm run sync:cache
|
|
50
|
+
env:
|
|
51
|
+
GAMING_INFOS_API_BASE: https://api.nekosunevr.co.uk
|
|
52
|
+
GAMING_INFOS_API_PATH: /v5/games/api/gaming-infos
|
|
53
|
+
GAME_CODES_API_PATH: /v5/games/api/codes
|
|
54
|
+
GAMING_INFOS_CACHE_TIMEOUT_MS: 20000
|
|
55
|
+
GAMING_INFOS_CACHE_RETRIES: 2
|
|
56
|
+
GAME_CODES_CACHE_TIMEOUT_MS: 20000
|
|
57
|
+
GAME_CODES_CACHE_RETRIES: 2
|
|
58
|
+
GAME_CODES_CACHE_GAME_DELAY_MS: 150
|
|
59
|
+
|
|
60
|
+
- name: Commit fallback changes
|
|
61
|
+
shell: bash
|
|
62
|
+
run: |
|
|
63
|
+
git add -A data
|
|
64
|
+
if git diff --cached --quiet; then
|
|
65
|
+
echo "Fallback caches already match APINODE."
|
|
66
|
+
exit 0
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
git config user.name "github-actions[bot]"
|
|
70
|
+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
71
|
+
git commit -m "chore(cache): mirror APINODE fallback data [skip ci]"
|
|
72
|
+
git push
|
package/CACHE_SYNC.md
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# APINODE fallback-cache mirror
|
|
2
|
+
|
|
3
|
+
`@nekosuneprojects/gaming-infos` is API-first. Normal reads try the NekoSuneVR V5 API before using bundled JSON under `data/`.
|
|
4
|
+
|
|
5
|
+
The repository keeps **two independent last-good fallback snapshots** synchronized automatically:
|
|
6
|
+
|
|
7
|
+
- Gaming Infos: `GET /v5/games/api/gaming-infos`
|
|
8
|
+
- Game Codes: `GET /v5/games/api/codes`
|
|
9
|
+
|
|
10
|
+
## Schedule
|
|
11
|
+
|
|
12
|
+
The GitHub Action runs **once every day at 03:23 UTC** and can also be started manually with `workflow_dispatch`.
|
|
13
|
+
|
|
14
|
+
It also runs when the cache implementation itself changes so a newly deployed cache format can be populated immediately.
|
|
15
|
+
|
|
16
|
+
## Mirrored gaming-infos datasets
|
|
17
|
+
|
|
18
|
+
| Game | API type(s) |
|
|
19
|
+
|---|---|
|
|
20
|
+
| VRChat | `players`, `groups`, `worlds`, `avatars` |
|
|
21
|
+
| Genshin Impact | `characters` |
|
|
22
|
+
| Honkai: Star Rail | `characters` |
|
|
23
|
+
| Neverness to Everness | `characters` |
|
|
24
|
+
| Wuthering Waves | `characters` (Resonators) |
|
|
25
|
+
| Warframe | `characters` (Warframes) |
|
|
26
|
+
| Fortnite | `characters` (current/released Battle Royale characters) |
|
|
27
|
+
| Zenless Zone Zero | `characters` (Agents) |
|
|
28
|
+
| Tower of Fantasy | `characters` (Simulacra) |
|
|
29
|
+
| Arknights: Endfield | `characters` (Operators) |
|
|
30
|
+
|
|
31
|
+
## Mirrored Game Codes endpoints
|
|
32
|
+
|
|
33
|
+
The daily mirror also caches:
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
GET /v5/games/api/codes
|
|
37
|
+
GET /v5/games/api/codes/status
|
|
38
|
+
GET /v5/games/api/codes/:game?includeUnknown=true
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`/codes/status` only reads APINODE's cached source state. It does **not** trigger source website refreshes.
|
|
42
|
+
|
|
43
|
+
The per-game request uses `includeUnknown=true`, so the fallback contains all three buckets when available:
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"Active": [],
|
|
48
|
+
"Expired": [],
|
|
49
|
+
"Unknown": []
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The mirror does not call every `/:game/:code` endpoint. `GameCode(game, code)` can search the full cached per-game snapshot during an outage, which keeps the daily request count low.
|
|
54
|
+
|
|
55
|
+
Game-code fallback layout:
|
|
56
|
+
|
|
57
|
+
```text
|
|
58
|
+
data/game-codes/
|
|
59
|
+
├── directory.json
|
|
60
|
+
├── status.json
|
|
61
|
+
├── .cache-manifest.json
|
|
62
|
+
└── games/
|
|
63
|
+
├── fortnite.json
|
|
64
|
+
├── warframe.json
|
|
65
|
+
├── genshin-impact.json
|
|
66
|
+
└── ...
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Atomic synchronization / deletion behavior
|
|
70
|
+
|
|
71
|
+
Each cache is authoritative only **after its complete API download succeeds**.
|
|
72
|
+
|
|
73
|
+
For Gaming Infos:
|
|
74
|
+
|
|
75
|
+
1. Temporarily preserve `data/game-codes/` outside the gaming-info snapshot.
|
|
76
|
+
2. Fetch the root gaming-infos endpoint.
|
|
77
|
+
3. Fetch every configured game's meta endpoint.
|
|
78
|
+
4. Fetch every configured type-list endpoint.
|
|
79
|
+
5. Validate every response and entry slug.
|
|
80
|
+
6. Build a completely separate temporary snapshot.
|
|
81
|
+
7. Atomically replace the gaming-info `data/` snapshot.
|
|
82
|
+
8. Restore the previous game-code fallback before the code phase begins.
|
|
83
|
+
|
|
84
|
+
For Game Codes:
|
|
85
|
+
|
|
86
|
+
1. Fetch `/codes` and validate its game directory.
|
|
87
|
+
2. Fetch cache-only `/codes/status`.
|
|
88
|
+
3. Fetch every listed game's full `Active` / `Expired` / `Unknown` snapshot.
|
|
89
|
+
4. Build a separate temporary `data/game-codes/` tree.
|
|
90
|
+
5. Only after every game succeeds, atomically replace the old game-code snapshot.
|
|
91
|
+
|
|
92
|
+
Because successful API snapshots are authoritative, **adds, changes and removals are mirrored**. If APINODE removes an entry/code/game, the corresponding fallback disappears on the next successful daily sync.
|
|
93
|
+
|
|
94
|
+
If APINODE is down, times out, returns 429/5xx, or one required endpoint fails halfway through, that cache is **not replaced**. The previous last-good fallback remains available.
|
|
95
|
+
|
|
96
|
+
## Package API
|
|
97
|
+
|
|
98
|
+
Gaming Infos functions remain available:
|
|
99
|
+
|
|
100
|
+
```js
|
|
101
|
+
const info = require('@nekosuneprojects/gaming-infos');
|
|
102
|
+
|
|
103
|
+
await info.Games();
|
|
104
|
+
await info.List('vrchat', 'avatars');
|
|
105
|
+
await info.Characters('wutheringwaves', 'cartethyia');
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Game Codes helpers use live APINODE first and the daily fallback second:
|
|
109
|
+
|
|
110
|
+
```js
|
|
111
|
+
await info.Codes(); // GET /v5/games/api/codes
|
|
112
|
+
await info.CodesStatus(); // GET /v5/games/api/codes/status
|
|
113
|
+
await info.GameCodes('fortnite'); // Active + Expired
|
|
114
|
+
await info.GameCodes('fortnite', { includeUnknown: true });
|
|
115
|
+
await info.GameCode('fortnite', 'NEKOSUNEVR');
|
|
116
|
+
await info.CodeCacheInfo();
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Per-game fallback filtering is supported for `category` and `claimType` as well.
|
|
120
|
+
|
|
121
|
+
## Commands
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# Test both atomic cache systems
|
|
125
|
+
npm run test:all-cache
|
|
126
|
+
|
|
127
|
+
# Mirror both Gaming Infos and Game Codes
|
|
128
|
+
npm run sync:cache
|
|
129
|
+
|
|
130
|
+
# Debug individually
|
|
131
|
+
npm run sync:gaming-infos-cache
|
|
132
|
+
npm run sync:game-codes-cache
|
|
133
|
+
npm run test:cache-sync
|
|
134
|
+
npm run test:game-code-cache
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Override APINODE while testing:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
GAMING_INFOS_API_BASE=http://localhost:3000 npm run sync:cache
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Useful variables:
|
|
144
|
+
|
|
145
|
+
| Variable | Default | Purpose |
|
|
146
|
+
|---|---|---|
|
|
147
|
+
| `GAMING_INFOS_API_BASE` | `https://api.nekosunevr.co.uk` | APINODE host used by both caches |
|
|
148
|
+
| `GAMING_INFOS_API_PATH` | `/v5/games/api/gaming-infos` | Gaming Infos path |
|
|
149
|
+
| `GAME_CODES_API_PATH` | `/v5/games/api/codes` | Game Codes path |
|
|
150
|
+
| `GAMING_INFOS_CACHE_TIMEOUT_MS` | `15000` | Gaming Infos per-request timeout |
|
|
151
|
+
| `GAMING_INFOS_CACHE_RETRIES` | `2` | Gaming Infos retry count |
|
|
152
|
+
| `GAME_CODES_CACHE_TIMEOUT_MS` | `15000` | Game Codes per-request timeout |
|
|
153
|
+
| `GAME_CODES_CACHE_RETRIES` | `2` | Game Codes retry count |
|
|
154
|
+
| `GAME_CODES_CACHE_GAME_DELAY_MS` | `150` | Small delay between game-list requests |
|
|
155
|
+
|
|
156
|
+
## Runtime fallback behavior
|
|
157
|
+
|
|
158
|
+
The package does **not** use the cache instead of live data. It remains API-first:
|
|
159
|
+
|
|
160
|
+
```text
|
|
161
|
+
application
|
|
162
|
+
↓
|
|
163
|
+
live APINODE
|
|
164
|
+
├─ success → current API response
|
|
165
|
+
└─ unavailable/error → last-good bundled fallback
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
A successful changed Gaming Infos snapshot records `data/.cache-manifest.json`. Game Codes records its own `data/game-codes/.cache-manifest.json`. Both include source URL, content hash, counts, synchronization time and add/change/remove statistics.
|
|
169
|
+
|
|
170
|
+
The hash comparison ignores manifest timestamps, so an unchanged API dataset does not create a pointless daily commit.
|
|
171
|
+
|
|
172
|
+
Note: npm releases are immutable. Repository fallback files update daily, but an already-installed npm version keeps the bundled snapshot from that package release until upgraded. Live API reads still remain current whenever APINODE is available.
|
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## Unreleased
|
|
9
9
|
|
|
10
|
+
## 2.2.0 - 2026-08-24
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Added API-first Game Codes helpers: `Codes()`, `CodesStatus()`, `GameCodes(game, options)`, `GameCode(game, code, options)`, and `CodeCacheInfo()`.
|
|
14
|
+
- Added an atomic `data/game-codes/` fallback mirror for `/v5/games/api/codes`, cache-only `/status`, and every per-game Active/Expired/Unknown dataset.
|
|
15
|
+
- Added game-code fallback alias resolution using the cached `/codes` directory aliases.
|
|
16
|
+
- Added game-code cache smoke tests covering additions, changes, removals, and partial API outages.
|
|
17
|
+
- Added `Avatars(game, name)` for VRChat avatar records.
|
|
18
|
+
- Added public Gaming Infos support for Wuthering Waves Resonators, Warframe Warframes, Fortnite current/released Battle Royale characters, Zenless Zone Zero Agents, Tower of Fantasy Simulacra, and Arknights: Endfield Operators.
|
|
19
|
+
- Expanded the mirrored VRChat datasets to include players, groups, worlds, and avatars.
|
|
20
|
+
- Added `CacheInfo()` for inspecting the last mirrored Gaming Infos snapshot.
|
|
21
|
+
- Added automatic fallback-cache manifests with source URL, content hash, counts, and add/change/remove statistics.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- `npm run sync:cache` now mirrors both Gaming Infos and Game Codes.
|
|
25
|
+
- The automatic cache workflow now runs once daily at 03:23 UTC instead of every six hours.
|
|
26
|
+
- Gaming Infos and Game Codes are mirrored as independent atomic snapshots so a failure in one cache cannot destroy the other cache's last-good data.
|
|
27
|
+
- Successful mirror runs now synchronize additions, updates, and removals from APINODE while failed or partial runs preserve the previous fallback snapshot.
|
|
28
|
+
- Local fallback entities expose stable slugs so offline lookups match live API behavior more closely.
|
|
29
|
+
- Expanded the package description and keywords for the new games, VRChat avatars, and redeem/creator-code support.
|
|
30
|
+
- Reworked `README.md` to document the full supported-game matrix, API-first fallback behavior, Game Codes API helpers, daily sync workflow, cache commands, configuration, and examples.
|
|
31
|
+
|
|
10
32
|
## 2.1.0 - 2026-08-02
|
|
11
33
|
|
|
12
34
|
### Added
|
|
@@ -27,10 +49,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
27
49
|
- Renamed package from `vrchat-infos` to `gaming-infos` to reflect multi-game support (VRChat today, Genshin Impact and more coming soon).
|
|
28
50
|
- `data/` is now scoped per game: `data/<game>/worlds`, `data/<game>/groups`, `data/<game>/players`, `data/<game>/meta.json`. VRChat data moved under `data/vrchat/`.
|
|
29
51
|
- Every lookup function now takes a `game` as its first argument, e.g. `Worlds('vrchat', 'theblackcat')` instead of `Worlds('theblackcat')`.
|
|
30
|
-
- Added `Game(game)` for game-level
|
|
52
|
+
- Added `Game(game)` for game-level info, `Characters(game, name)` for character-based games, and a generic `Get(game, type, name)` escape hatch.
|
|
31
53
|
|
|
32
54
|
### Added
|
|
33
55
|
- Lookups now try the NekoSuneVR V5 API first (`GAMING_INFOS_API_BASE`, default `https://api.nekosunevr.co.uk`) and fall back to the bundled local JSON if the API is unreachable, so data can be updated in real time without republishing this package. Set `GAMING_INFOS_DISABLE_API=1` to force local-only lookups.
|
|
34
56
|
- Added `genshinimpact`, `nte` (Neverness to Everness), and `honkaistarrail` games, each with `meta.json`.
|
|
35
57
|
- Added all 104 currently-released Genshin Impact characters, all 20 currently-playable NTE characters, and all 69 currently-released Honkai: Star Rail characters under their respective `data/<game>/characters/` folders.
|
|
36
|
-
|