uesp-eso-build-wrapper 0.3.0 → 0.5.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/README.md +63 -257
- package/README.pt-BR.md +122 -0
- package/dist/lib/eso-engine/calculator.d.ts +26 -16
- package/dist/lib/eso-engine/calculator.d.ts.map +1 -1
- package/dist/lib/eso-engine/calculator.js +235 -202
- package/dist/lib/eso-engine/calculator.js.map +1 -1
- package/dist/lib/eso-engine/cp-gate.d.ts +70 -0
- package/dist/lib/eso-engine/cp-gate.d.ts.map +1 -0
- package/dist/lib/eso-engine/cp-gate.js +124 -0
- package/dist/lib/eso-engine/cp-gate.js.map +1 -0
- package/dist/lib/eso-engine/cp-tree.d.ts +24 -0
- package/dist/lib/eso-engine/cp-tree.d.ts.map +1 -0
- package/dist/lib/eso-engine/cp-tree.js +165 -0
- package/dist/lib/eso-engine/cp-tree.js.map +1 -0
- package/dist/lib/eso-engine/debug.d.ts +18 -15
- package/dist/lib/eso-engine/debug.d.ts.map +1 -1
- package/dist/lib/eso-engine/debug.js +17 -19
- package/dist/lib/eso-engine/debug.js.map +1 -1
- package/dist/lib/eso-engine/engine-globals.d.ts +176 -0
- package/dist/lib/eso-engine/engine-globals.d.ts.map +1 -0
- package/dist/lib/eso-engine/engine-globals.js +24 -0
- package/dist/lib/eso-engine/engine-globals.js.map +1 -0
- package/dist/lib/eso-engine/env-setup.d.ts +15 -15
- package/dist/lib/eso-engine/env-setup.d.ts.map +1 -1
- package/dist/lib/eso-engine/env-setup.js +42 -58
- package/dist/lib/eso-engine/env-setup.js.map +1 -1
- package/dist/lib/eso-engine/index.d.ts +33 -9
- package/dist/lib/eso-engine/index.d.ts.map +1 -1
- package/dist/lib/eso-engine/index.js +38 -64
- package/dist/lib/eso-engine/index.js.map +1 -1
- package/dist/lib/eso-engine/input-stats.js +2 -5
- package/dist/lib/eso-engine/input-stats.js.map +1 -1
- package/dist/lib/eso-engine/loader.d.ts +15 -15
- package/dist/lib/eso-engine/loader.d.ts.map +1 -1
- package/dist/lib/eso-engine/loader.js +116 -132
- package/dist/lib/eso-engine/loader.js.map +1 -1
- package/dist/lib/eso-engine/types.d.ts +189 -92
- package/dist/lib/eso-engine/types.d.ts.map +1 -1
- package/dist/lib/eso-engine/types.js +2 -3
- package/dist/lib/eso-engine/types.js.map +1 -1
- package/dist/lib/uesp-data/extract.d.ts +29 -0
- package/dist/lib/uesp-data/extract.d.ts.map +1 -0
- package/dist/lib/uesp-data/extract.js +348 -0
- package/dist/lib/uesp-data/extract.js.map +1 -0
- package/dist/lib/uesp-data/index.d.ts +14 -0
- package/dist/lib/uesp-data/index.d.ts.map +1 -0
- package/dist/lib/uesp-data/index.js +11 -0
- package/dist/lib/uesp-data/index.js.map +1 -0
- package/dist/lib/uesp-data/mariadb-dump.d.ts +32 -0
- package/dist/lib/uesp-data/mariadb-dump.d.ts.map +1 -0
- package/dist/lib/uesp-data/mariadb-dump.js +222 -0
- package/dist/lib/uesp-data/mariadb-dump.js.map +1 -0
- package/dist/lib/uesp-data/seed.d.ts +43 -0
- package/dist/lib/uesp-data/seed.d.ts.map +1 -0
- package/dist/lib/uesp-data/seed.js +450 -0
- package/dist/lib/uesp-data/seed.js.map +1 -0
- package/package.json +37 -13
package/README.md
CHANGED
|
@@ -1,21 +1,53 @@
|
|
|
1
1
|
# uesp-eso-build-wrapper
|
|
2
2
|
|
|
3
3
|
[](https://github.com/srtomy/uesp-eso-build-wrapper/actions/workflows/ci.yml)
|
|
4
|
+
[](https://codecov.io/gh/srtomy/uesp-eso-build-wrapper)
|
|
4
5
|
[](https://www.npmjs.com/package/uesp-eso-build-wrapper)
|
|
6
|
+
[](https://srtomy.github.io/uesp-eso-build-wrapper/)
|
|
7
|
+
[](https://bundlephobia.com/package/uesp-eso-build-wrapper)
|
|
5
8
|
[](LICENSE)
|
|
6
|
-
[](https://nodejs.org/en/download/)
|
|
10
|
+
|
|
11
|
+
> **Leia em [Português (BR)](README.pt-BR.md).**
|
|
7
12
|
|
|
8
13
|
A Node.js/TypeScript wrapper around the [UESP ESO Build Editor](https://github.com/uesp/uesp-esochardata) math engine.
|
|
9
14
|
|
|
10
15
|
Calculate Elder Scrolls Online **Computed Character Statistics** — Health, Magicka, Stamina, mitigation, crit chance, regeneration, and 200+ more — using UESP's own formulas. No formula reimplementation.
|
|
11
16
|
|
|
12
|
-
##
|
|
17
|
+
## What is this?
|
|
18
|
+
|
|
19
|
+
This is **not an HTTP client for UESP**. It runs the vendored UESP build calculation engine **locally, inside your Node.js process**, and exposes the results through a typed API:
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
Application
|
|
23
|
+
↓
|
|
24
|
+
uesp-eso-build-wrapper (TypeScript API)
|
|
25
|
+
↓
|
|
26
|
+
Node.js compatibility layer (browser-like globals + minimal DOM)
|
|
27
|
+
↓
|
|
28
|
+
UESP esoEditBuild.js (executed in-process via vm.runInThisContext)
|
|
29
|
+
↓
|
|
30
|
+
UESP calculation functions → ComputedStats
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
You inject the inputs, UESP's own code computes every stat, you read back one typed object.
|
|
34
|
+
|
|
35
|
+
## Why this library?
|
|
13
36
|
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
37
|
+
- **Reference accuracy** — same `esoEditBuild.js` engine that powers [esobuilds.uesp.net](https://esobuilds.uesp.net), kept up to date by UESP every patch.
|
|
38
|
+
- **No formula reimplementation** — the wrapper contains zero ESO math. When a stat looks wrong after a patch, the fix is always in the game *data* fed to the engine, never in wrapper code. That is what keeps it correct across patches.
|
|
39
|
+
- **Local and synchronous** — `calculateBuild()` performs no network requests. The engine runs in-process; game data and items are supplied by your application (file, database, generated data).
|
|
40
|
+
- **Accepts UESP item data directly** — gear in the [`exportJson.php?table=minedItem`](https://esolog.uesp.net) format plugs straight into `BuildInput.items`.
|
|
41
|
+
- **TypeScript-native** — typed inputs/outputs, TSDoc-documented [API Reference](https://srtomy.github.io/uesp-eso-build-wrapper/api/), plus runtime catalog functions (`listAvailableBuffs`, `listRacialPassives`, …) to discover valid names.
|
|
42
|
+
|
|
43
|
+
## Key properties
|
|
44
|
+
|
|
45
|
+
- Runs the vendored UESP calculation engine locally (`vendor/uesp-esochardata`)
|
|
46
|
+
- **No network required for build calculations** — see [Does it require an internet connection?](https://srtomy.github.io/uesp-eso-build-wrapper/architecture#does-it-require-an-internet-connection)
|
|
47
|
+
- Does not reimplement ESO stat formulas
|
|
48
|
+
- Synchronous API; engine initializes once per process (singleton, subsequent calls are no-ops)
|
|
49
|
+
- Zero runtime dependencies — pure Node.js
|
|
50
|
+
- 221 computed stats per build
|
|
19
51
|
|
|
20
52
|
## Installation
|
|
21
53
|
|
|
@@ -25,21 +57,18 @@ npm install uesp-eso-build-wrapper
|
|
|
25
57
|
|
|
26
58
|
## Quick Start
|
|
27
59
|
|
|
28
|
-
Game data is not bundled in the npm package — you supply it via `initEsoEngineFromData
|
|
29
|
-
The bundled `vendor/uesp-data/uesp-game-data.json` (committed to this repo) is the canonical source.
|
|
60
|
+
Game data is not bundled in the npm package — you supply it via `initEsoEngineFromData` (see [Getting Started](https://srtomy.github.io/uesp-eso-build-wrapper/getting-started)).
|
|
30
61
|
|
|
31
62
|
```ts
|
|
32
63
|
import fs from 'fs';
|
|
33
64
|
import { initEsoEngineFromData, calculateBuild } from 'uesp-eso-build-wrapper';
|
|
34
65
|
import type { UespInitData } from 'uesp-eso-build-wrapper';
|
|
35
66
|
|
|
36
|
-
// Load game data generated by: npm run generate-data -- --db /path/to/local.db
|
|
37
67
|
const initData = JSON.parse(
|
|
38
|
-
fs.readFileSync('
|
|
68
|
+
fs.readFileSync('uesp-game-data.json', 'utf-8'),
|
|
39
69
|
) as UespInitData;
|
|
40
70
|
|
|
41
|
-
//
|
|
42
|
-
initEsoEngineFromData({ initData });
|
|
71
|
+
initEsoEngineFromData({ initData }); // once per process
|
|
43
72
|
|
|
44
73
|
const stats = calculateBuild({
|
|
45
74
|
character: {
|
|
@@ -52,260 +81,37 @@ const stats = calculateBuild({
|
|
|
52
81
|
|
|
53
82
|
console.log(stats.Health); // 16000
|
|
54
83
|
console.log(stats.Magicka); // 19104
|
|
55
|
-
console.log(stats.MagickaRegen); // 514
|
|
56
84
|
console.log(stats.SpellDamage); // 1000
|
|
57
85
|
```
|
|
58
86
|
|
|
59
|
-
##
|
|
60
|
-
|
|
61
|
-
Items are passed directly as returned by the [UESP public item API](https://esolog.uesp.net/exportJson.php?table=minedItem&id=70&level=50&quality=5).
|
|
62
|
-
|
|
63
|
-
```ts
|
|
64
|
-
const res = await fetch(
|
|
65
|
-
'https://esolog.uesp.net/exportJson.php?table=minedItem&id=70&level=50&quality=5',
|
|
66
|
-
);
|
|
67
|
-
const data = await res.json();
|
|
68
|
-
const item = data.minedItem[0];
|
|
69
|
-
|
|
70
|
-
const stats = calculateBuild({
|
|
71
|
-
character: {
|
|
72
|
-
race: 'Nord',
|
|
73
|
-
class: 'Dragonknight',
|
|
74
|
-
level: 50,
|
|
75
|
-
attributes: { health: 64, magicka: 0, stamina: 0 },
|
|
76
|
-
},
|
|
77
|
-
items: {
|
|
78
|
-
Chest: item,
|
|
79
|
-
},
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
console.log(stats.Health); // includes item enchant + set bonus
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
## With Passives, Buffs, and Skill Bars
|
|
86
|
-
|
|
87
|
-
```ts
|
|
88
|
-
const stats = calculateBuild({
|
|
89
|
-
character: {
|
|
90
|
-
race: 'High Elf',
|
|
91
|
-
class: 'Sorcerer',
|
|
92
|
-
level: 50,
|
|
93
|
-
attributes: { health: 0, magicka: 64, stamina: 0 },
|
|
94
|
-
mundusStone: 'The Apprentice',
|
|
95
|
-
championPoints: 160,
|
|
96
|
-
},
|
|
97
|
-
// Auto-inject all racial passives at highest rank (mirrors UESP "Auto Purchase Racial Passives")
|
|
98
|
-
autoPassives: true,
|
|
99
|
-
// Named buffs from the UESP buff catalog
|
|
100
|
-
activeBuffs: ['Major Prophecy', 'Minor Slayer', 'Major Sorcery'],
|
|
101
|
-
// Active skills slotted on bars (affects conditional set bonuses and skill-line passives)
|
|
102
|
-
skillBars: {
|
|
103
|
-
bar1: [
|
|
104
|
-
{ skillId: 28807, morphIndex: 2 }, // Crystal Fragments
|
|
105
|
-
{ skillId: 24322 }, // Mages' Fury
|
|
106
|
-
],
|
|
107
|
-
},
|
|
108
|
-
});
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
## API
|
|
112
|
-
|
|
113
|
-
### `initEsoEngineFromData(options)`
|
|
114
|
-
|
|
115
|
-
Initializes the UESP math engine from a `UespInitData` object. **Must be called once** before `calculateBuild()`.
|
|
87
|
+
## How it works
|
|
116
88
|
|
|
117
|
-
|
|
89
|
+
1. `initEsoEngineFromData({ initData })` prepares browser-like globals, seeds the engine with your game data, and executes the vendored UESP scripts via `vm.runInThisContext` — once per process.
|
|
90
|
+
2. `calculateBuild(input)` writes your build into the engine state, runs the engine's own `UpdateEsoComputedStatsList_Real()`, and reads results from `g_EsoComputedStats` into a typed `ComputedStats` object.
|
|
118
91
|
|
|
119
|
-
|
|
120
|
-
| ---------- | -------------- | ---------------------------------------------- |
|
|
121
|
-
| `initData` | `UespInitData` | Parsed game data (see `vendor/uesp-data/`) |
|
|
122
|
-
|
|
123
|
-
---
|
|
124
|
-
|
|
125
|
-
### `calculateBuild(input: BuildInput): ComputedStats`
|
|
126
|
-
|
|
127
|
-
Runs the UESP engine and returns the computed stats.
|
|
128
|
-
|
|
129
|
-
#### `BuildInput`
|
|
130
|
-
|
|
131
|
-
```ts
|
|
132
|
-
interface BuildInput {
|
|
133
|
-
character: {
|
|
134
|
-
race: string; // "High Elf" | "Nord" | "Breton" | "Khajiit" | ...
|
|
135
|
-
class: string; // "Sorcerer" | "Dragonknight" | "Nightblade" | ...
|
|
136
|
-
level: number; // 1–50
|
|
137
|
-
attributes: {
|
|
138
|
-
health: number; // attribute points (max 64 total)
|
|
139
|
-
magicka: number;
|
|
140
|
-
stamina: number;
|
|
141
|
-
};
|
|
142
|
-
mundusStone?: string; // "The Thief" | "The Apprentice" | ...
|
|
143
|
-
mundusStone2?: string; // second Mundus Stone (requires Twice-Born Star set)
|
|
144
|
-
cyrodiil?: boolean; // Battle Spirit (PvP)
|
|
145
|
-
vampireStage?: number; // 0–4
|
|
146
|
-
werewolfStage?: number; // 0 or 1
|
|
147
|
-
championPoints?: number; // 0–3600
|
|
148
|
-
rulesVersion?: string; // "Live" (default) | "PTS"
|
|
149
|
-
};
|
|
150
|
-
items?: Partial<Record<EquipSlot, UespItemApiData>>;
|
|
151
|
-
championPointNodes?: Record<string | number, ChampionPointNode>;
|
|
152
|
-
activeBuffs?: string[]; // named buffs — see listAvailableBuffs()
|
|
153
|
-
toggleSkills?: string[]; // toggled skills — see listAvailableToggleSkills()
|
|
154
|
-
skillBars?: {
|
|
155
|
-
bar1?: SkillSlot[];
|
|
156
|
-
bar2?: SkillSlot[];
|
|
157
|
-
};
|
|
158
|
-
activeWeaponBar?: 1 | 2; // which weapon bar is active (default: 1)
|
|
159
|
-
passiveSkills?: number[]; // ability IDs of unlocked passive skills
|
|
160
|
-
autoPassives?: boolean; // auto-inject racial passives (default: false)
|
|
161
|
-
enchantOverrides?: Partial<Record<string, { enchantDesc: string; enchantName?: string }>>;
|
|
162
|
-
toggledSetBonuses?: string[];
|
|
163
|
-
}
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
#### `EquipSlot`
|
|
167
|
-
|
|
168
|
-
```
|
|
169
|
-
Head | Shoulders | Chest | Hands | Legs | Waist | Feet |
|
|
170
|
-
Neck | Ring1 | Ring2 |
|
|
171
|
-
MainHand1 | OffHand1 | MainHand2 | OffHand2 |
|
|
172
|
-
Poison1 | Poison2 | Food | Potion
|
|
173
|
-
```
|
|
92
|
+
Details: [Architecture](https://srtomy.github.io/uesp-eso-build-wrapper/architecture) · [Getting Started](https://srtomy.github.io/uesp-eso-build-wrapper/getting-started) · [Reading the Output](https://srtomy.github.io/uesp-eso-build-wrapper/output).
|
|
174
93
|
|
|
175
|
-
|
|
94
|
+
## Documentation
|
|
176
95
|
|
|
177
|
-
|
|
96
|
+
Full documentation is available in **English** and **Português (BR)** at
|
|
97
|
+
[**srtomy.github.io/uesp-eso-build-wrapper**](https://srtomy.github.io/uesp-eso-build-wrapper/):
|
|
178
98
|
|
|
179
|
-
|
|
|
180
|
-
|
|
|
181
|
-
|
|
|
182
|
-
|
|
|
183
|
-
|
|
|
184
|
-
|
|
|
185
|
-
|
|
|
186
|
-
|
|
|
187
|
-
|
|
|
188
|
-
|
|
|
189
|
-
| `RunSpeed` / `SprintSpeed` | Movement speed |
|
|
190
|
-
| `raw` | All 221 stats as `Record<string, number>` |
|
|
191
|
-
|
|
192
|
-
> All stat IDs match `g_EsoComputedStats` from the UESP engine (version 49+).
|
|
193
|
-
|
|
194
|
-
---
|
|
195
|
-
|
|
196
|
-
### Catalog Functions
|
|
197
|
-
|
|
198
|
-
| Function | Returns | Description |
|
|
199
|
-
|---|---|---|
|
|
200
|
-
| `listAvailableBuffs(group?)` | `BuffInfo[]` | 164 named buffs; filter by group `"Major"` \| `"Minor"` \| `"Set"` \| `"Target"` \| … |
|
|
201
|
-
| `listRacialPassives(race)` | `PassiveSkillInfo[]` | All passive ranks for a given race |
|
|
202
|
-
| `listClassPassives(cls)` | `PassiveSkillInfo[]` | All passive ranks for a given class (3 skill lines) |
|
|
203
|
-
| `listPassivesBySkillLine(line)` | `PassiveSkillInfo[]` | Passives for any skill line (Heavy Armor, Undaunted, etc.) |
|
|
204
|
-
| `listAvailableSkillLines()` | `string[]` | All available skill line names |
|
|
205
|
-
| `listAvailableToggleSkills()` | `ToggleSkillInfo[]` | 105 toggle skills; `requiresCyrodiil` marks PvP-only |
|
|
206
|
-
|
|
207
|
-
```ts
|
|
208
|
-
// Example: see all Major buffs
|
|
209
|
-
const buffs = listAvailableBuffs('Major');
|
|
210
|
-
// Example: find racial passive IDs for a High Elf build
|
|
211
|
-
const passives = listRacialPassives('High Elf');
|
|
212
|
-
const ids = passives.map(p => p.abilityId);
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
---
|
|
216
|
-
|
|
217
|
-
## Game Data
|
|
218
|
-
|
|
219
|
-
Game data (`UespInitData`) is extracted from the UESP SQL dumps and stored in `vendor/uesp-data/uesp-game-data.json`.
|
|
220
|
-
This file is committed to the repo but **not bundled in the npm package** — consumers are expected to supply their own copy or generate it.
|
|
221
|
-
|
|
222
|
-
### Generating game data
|
|
223
|
-
|
|
224
|
-
Requires Node.js ≥ 22 (uses `node:sqlite`).
|
|
225
|
-
|
|
226
|
-
```bash
|
|
227
|
-
npm run generate-data -- --db /path/to/local.db [--version 50]
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
The script reads from `local.db` and writes to `vendor/uesp-data/uesp-game-data.json`.
|
|
231
|
-
To populate `local.db`, use the seed script from [eso-build-editor](https://github.com/srtomy/eso-build-editor).
|
|
232
|
-
|
|
233
|
-
### Scripts
|
|
234
|
-
|
|
235
|
-
| Command | Description |
|
|
236
|
-
|---|---|
|
|
237
|
-
| `npm run generate-data -- --db <path>` | Generate `vendor/uesp-data/uesp-game-data.json` from a SQLite DB |
|
|
238
|
-
| `npm run test:db-init [json] [db] [version]` | Validate committed JSON matches a live DB |
|
|
239
|
-
| `npm run test:build <export.json>` | Print all computed stats for a UESP build export |
|
|
240
|
-
| `npm run test:explore` | Interactive engine exploration script |
|
|
241
|
-
|
|
242
|
-
---
|
|
243
|
-
|
|
244
|
-
## Validating Against the UESP Browser
|
|
245
|
-
|
|
246
|
-
The `scripts/browser-export-build.js` script runs inside the UESP Build Editor DevTools console and exports the full build — inputs and expected stats — as a JSON file.
|
|
247
|
-
|
|
248
|
-
**How to use:**
|
|
249
|
-
|
|
250
|
-
1. Open [esobuilds.uesp.net](https://esobuilds.uesp.net), configure your build
|
|
251
|
-
2. Open DevTools (F12) → Console, paste and run `browser-export-build.js`
|
|
252
|
-
3. A `uesp-build-export.json` file is downloaded
|
|
253
|
-
|
|
254
|
-
**Explore stats interactively:**
|
|
255
|
-
|
|
256
|
-
```bash
|
|
257
|
-
npm run test:build path/to/uesp-build-export.json
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
**Add as a golden regression fixture:**
|
|
261
|
-
|
|
262
|
-
```bash
|
|
263
|
-
cp path/to/uesp-build-export.json tests/fixtures/my-build.json
|
|
264
|
-
npm test
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
`tests/build-fixtures.test.ts` auto-discovers all `.json` files in `tests/fixtures/` and asserts every stat in `expectedStats` against the wrapper output.
|
|
268
|
-
|
|
269
|
-
---
|
|
270
|
-
|
|
271
|
-
## Updating Formulas After a New ESO Patch
|
|
272
|
-
|
|
273
|
-
```bash
|
|
274
|
-
# 1. Update the UESP engine submodule
|
|
275
|
-
cd vendor/uesp-esochardata
|
|
276
|
-
git fetch upstream && git merge upstream/master
|
|
277
|
-
cd ../..
|
|
278
|
-
|
|
279
|
-
# 2. Regenerate game data from an up-to-date local.db
|
|
280
|
-
# (populate local.db first via eso-build-editor's npm run db:seed)
|
|
281
|
-
npm run generate-data -- --db /path/to/local.db --version <patch>
|
|
282
|
-
|
|
283
|
-
# 3. Commit the updated game data
|
|
284
|
-
git add vendor/uesp-data/uesp-game-data.json
|
|
285
|
-
|
|
286
|
-
# 4. Run tests — update any golden values that changed intentionally
|
|
287
|
-
npm test
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
## Framework Integration
|
|
291
|
-
|
|
292
|
-
### Next.js (Vercel / serverless)
|
|
293
|
-
|
|
294
|
-
The vendor JS files (`esobuilddata.js`, `esoEditBuild.js`) are loaded at runtime via `fs.readFileSync` with a dynamic path. Next.js's output file tracer (`@vercel/nft`) cannot detect them automatically, so they must be declared explicitly in `next.config.ts`:
|
|
295
|
-
|
|
296
|
-
```ts
|
|
297
|
-
// next.config.ts
|
|
298
|
-
const nextConfig: NextConfig = {
|
|
299
|
-
serverExternalPackages: ['uesp-eso-build-wrapper'],
|
|
300
|
-
outputFileTracingIncludes: {
|
|
301
|
-
'/**': ['./node_modules/uesp-eso-build-wrapper/vendor/**'],
|
|
302
|
-
},
|
|
303
|
-
};
|
|
304
|
-
```
|
|
99
|
+
| Section | Description |
|
|
100
|
+
| --- | --- |
|
|
101
|
+
| [Introduction](https://srtomy.github.io/uesp-eso-build-wrapper/) | What it is, why it exists, key properties |
|
|
102
|
+
| [Architecture](https://srtomy.github.io/uesp-eso-build-wrapper/architecture) | Local engine, network policy, data flow |
|
|
103
|
+
| [Getting Started](https://srtomy.github.io/uesp-eso-build-wrapper/getting-started) | Install, game data, first calculation |
|
|
104
|
+
| [Guides](https://srtomy.github.io/uesp-eso-build-wrapper/guides/character) | Character, items, Champion Points, buffs, skills |
|
|
105
|
+
| [Reading the Output](https://srtomy.github.io/uesp-eso-build-wrapper/output) | All 221 computed stats, `debugBuild()` |
|
|
106
|
+
| [API Reference](https://srtomy.github.io/uesp-eso-build-wrapper/api/) | Generated from source TSDoc |
|
|
107
|
+
| [Troubleshooting](https://srtomy.github.io/uesp-eso-build-wrapper/troubleshooting) | Common integration issues (Next.js/serverless, wrong stats...) |
|
|
108
|
+
| [Contributing](https://srtomy.github.io/uesp-eso-build-wrapper/contributing) | Dev setup, tests, updating after an ESO patch |
|
|
305
109
|
|
|
306
|
-
|
|
110
|
+
## Limitations
|
|
307
111
|
|
|
308
|
-
|
|
112
|
+
- Behavior follows the vendored UESP engine version — updating ESO patch support means updating the vendored scripts + game data and running the tests.
|
|
113
|
+
- The engine was written for browsers around global state; the wrapper adapts it to Node.js (singleton init, synchronous calls). No concurrency guarantees beyond what the engine itself provides — see [Troubleshooting](https://srtomy.github.io/uesp-eso-build-wrapper/troubleshooting).
|
|
114
|
+
- Requires Node.js >= 24. Bundlers/serverless need explicit `vendor/**` inclusion (documented in Troubleshooting).
|
|
309
115
|
|
|
310
116
|
## License
|
|
311
117
|
|
package/README.pt-BR.md
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# uesp-eso-build-wrapper
|
|
2
|
+
|
|
3
|
+
[](https://github.com/srtomy/uesp-eso-build-wrapper/actions/workflows/ci.yml)
|
|
4
|
+
[](https://codecov.io/gh/srtomy/uesp-eso-build-wrapper)
|
|
5
|
+
[](https://www.npmjs.com/package/uesp-eso-build-wrapper)
|
|
6
|
+
[](https://srtomy.github.io/uesp-eso-build-wrapper/pt/)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
[](https://nodejs.org/en/download/)
|
|
9
|
+
|
|
10
|
+
> **Read in [English](README.md).**
|
|
11
|
+
|
|
12
|
+
Um wrapper Node.js/TypeScript em torno do motor de cálculo do [UESP ESO Build Editor](https://github.com/uesp/uesp-esochardata).
|
|
13
|
+
|
|
14
|
+
Calcule as **Computed Character Statistics** de Elder Scrolls Online — Health, Magicka, Stamina, mitigação, chance de crítico, regeneração e mais de 200 — usando as fórmulas da própria UESP. Sem reimplementar nenhuma fórmula.
|
|
15
|
+
|
|
16
|
+
## O que é?
|
|
17
|
+
|
|
18
|
+
Isto **não é um cliente HTTP da UESP**. A biblioteca executa o motor de cálculo da UESP **localmente, dentro do seu processo Node.js**, e expõe os resultados numa API tipada:
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
Aplicação
|
|
22
|
+
↓
|
|
23
|
+
uesp-eso-build-wrapper (API TypeScript)
|
|
24
|
+
↓
|
|
25
|
+
Camada de compatibilidade Node.js (globals de browser + DOM mínimo)
|
|
26
|
+
↓
|
|
27
|
+
UESP esoEditBuild.js (executado in-process via vm.runInThisContext)
|
|
28
|
+
↓
|
|
29
|
+
Funções de cálculo UESP → ComputedStats
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Você injeta os inputs, o próprio código da UESP calcula cada stat, você lê de volta um objeto tipado.
|
|
33
|
+
|
|
34
|
+
## Por que esta biblioteca?
|
|
35
|
+
|
|
36
|
+
- **Precisão de referência** — o mesmo motor `esoEditBuild.js` do [esobuilds.uesp.net](https://esobuilds.uesp.net), mantido pela UESP e atualizado a cada patch.
|
|
37
|
+
- **Sem reimplementar fórmulas** — o wrapper contém zero matemática de ESO. Quando um stat parece errado depois de um patch, a correção está sempre nos *dados* do jogo alimentados ao motor, nunca no código do wrapper. É isso que mantém a precisão entre patches.
|
|
38
|
+
- **Local e síncrono** — `calculateBuild()` não faz nenhuma requisição de rede. O motor roda in-process; os dados do jogo e os itens são fornecidos pela sua aplicação (arquivo, banco de dados, dados gerados).
|
|
39
|
+
- **Aceita item data da UESP diretamente** — equipamentos no formato [`exportJson.php?table=minedItem`](https://esolog.uesp.net) plugam direto em `BuildInput.items`.
|
|
40
|
+
- **Nativo TypeScript** — inputs/outputs tipados, [API Reference](https://srtomy.github.io/uesp-eso-build-wrapper/api/) documentada com TSDoc, além de funções de catálogo em runtime (`listAvailableBuffs`, `listRacialPassives`, …) para descobrir nomes válidos.
|
|
41
|
+
|
|
42
|
+
## Propriedades principais
|
|
43
|
+
|
|
44
|
+
- Executa o motor de cálculo UESP vendored localmente (`vendor/uesp-esochardata`)
|
|
45
|
+
- **Sem rede para calcular builds** — ver [Precisa de internet?](https://srtomy.github.io/uesp-eso-build-wrapper/pt/architecture#precisa-de-conexao-com-a-internet)
|
|
46
|
+
- Não reimplementa as fórmulas de stats do ESO
|
|
47
|
+
- API síncrona; o motor inicializa uma vez por processo (singleton, chamadas seguintes são no-op)
|
|
48
|
+
- Zero dependências de runtime — Node.js puro
|
|
49
|
+
- 221 computed stats por build
|
|
50
|
+
|
|
51
|
+
## Instalação
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npm install uesp-eso-build-wrapper
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Quick Start
|
|
58
|
+
|
|
59
|
+
Os game data não vêm no pacote npm — você os fornece via `initEsoEngineFromData` (ver [Primeiros Passos](https://srtomy.github.io/uesp-eso-build-wrapper/pt/getting-started)).
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import fs from 'fs';
|
|
63
|
+
import { initEsoEngineFromData, calculateBuild } from 'uesp-eso-build-wrapper';
|
|
64
|
+
import type { UespInitData } from 'uesp-eso-build-wrapper';
|
|
65
|
+
|
|
66
|
+
const initData = JSON.parse(
|
|
67
|
+
fs.readFileSync('uesp-game-data.json', 'utf-8'),
|
|
68
|
+
) as UespInitData;
|
|
69
|
+
|
|
70
|
+
initEsoEngineFromData({ initData }); // uma vez por processo
|
|
71
|
+
|
|
72
|
+
const stats = calculateBuild({
|
|
73
|
+
character: {
|
|
74
|
+
race: 'High Elf',
|
|
75
|
+
class: 'Sorcerer',
|
|
76
|
+
level: 50,
|
|
77
|
+
attributes: { health: 0, magicka: 64, stamina: 0 },
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
console.log(stats.Health); // 16000
|
|
82
|
+
console.log(stats.Magicka); // 19104
|
|
83
|
+
console.log(stats.SpellDamage); // 1000
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Como funciona
|
|
87
|
+
|
|
88
|
+
1. `initEsoEngineFromData({ initData })` prepara globals de browser, semeia o motor com seus game data e executa os scripts vendored da UESP via `vm.runInThisContext` — uma vez por processo.
|
|
89
|
+
2. `calculateBuild(input)` escreve sua build no estado do motor, roda o próprio `UpdateEsoComputedStatsList_Real()` do motor e lê os resultados de `g_EsoComputedStats` num objeto tipado `ComputedStats`.
|
|
90
|
+
|
|
91
|
+
Detalhes: [Arquitetura](https://srtomy.github.io/uesp-eso-build-wrapper/pt/architecture) · [Primeiros Passos](https://srtomy.github.io/uesp-eso-build-wrapper/pt/getting-started) · [Lendo o Resultado](https://srtomy.github.io/uesp-eso-build-wrapper/pt/output).
|
|
92
|
+
|
|
93
|
+
## Documentação
|
|
94
|
+
|
|
95
|
+
Documentação completa em **Português (BR)** e **English** em
|
|
96
|
+
[**srtomy.github.io/uesp-eso-build-wrapper**](https://srtomy.github.io/uesp-eso-build-wrapper/pt/):
|
|
97
|
+
|
|
98
|
+
| Seção | Descrição |
|
|
99
|
+
| --- | --- |
|
|
100
|
+
| [Introdução](https://srtomy.github.io/uesp-eso-build-wrapper/pt/) | O que é, por que existe, propriedades principais |
|
|
101
|
+
| [Arquitetura](https://srtomy.github.io/uesp-eso-build-wrapper/pt/architecture) | Motor local, política de rede, fluxo de dados |
|
|
102
|
+
| [Primeiros Passos](https://srtomy.github.io/uesp-eso-build-wrapper/pt/getting-started) | Instalação, game data, primeiro cálculo |
|
|
103
|
+
| [Guias](https://srtomy.github.io/uesp-eso-build-wrapper/pt/guides/character) | Personagem, itens, Champion Points, buffs, skills |
|
|
104
|
+
| [Lendo o Resultado](https://srtomy.github.io/uesp-eso-build-wrapper/pt/output) | Os 221 computed stats, `debugBuild()` |
|
|
105
|
+
| [API Reference](https://srtomy.github.io/uesp-eso-build-wrapper/api/) | Gerada a partir do TSDoc (em inglês) |
|
|
106
|
+
| [Solução de Problemas](https://srtomy.github.io/uesp-eso-build-wrapper/pt/troubleshooting) | Problemas comuns (Next.js/serverless, stats errados...) |
|
|
107
|
+
| [Contribuindo](https://srtomy.github.io/uesp-eso-build-wrapper/pt/contributing) | Setup dev, testes, atualização após patch do ESO |
|
|
108
|
+
|
|
109
|
+
## Limitações
|
|
110
|
+
|
|
111
|
+
- O comportamento segue a versão vendored do motor UESP — suportar um patch novo do ESO significa atualizar os scripts vendored + game data e rodar os testes.
|
|
112
|
+
- O motor foi escrito para browsers em torno de estado global; o wrapper adapta isso para Node.js (init singleton, chamadas síncronas). Sem garantias de concorrência além das que o próprio motor oferece — ver [Solução de Problemas](https://srtomy.github.io/uesp-eso-build-wrapper/pt/troubleshooting).
|
|
113
|
+
- Requer Node.js >= 24. Bundlers/serverless precisam incluir `vendor/**` explicitamente (documentado em Solução de Problemas).
|
|
114
|
+
|
|
115
|
+
## Licença
|
|
116
|
+
|
|
117
|
+
MIT © srtomy
|
|
118
|
+
|
|
119
|
+
Este pacote inclui arquivos de [uesp/uesp-esochardata](https://github.com/uesp/uesp-esochardata) (MIT).
|
|
120
|
+
Ver [THIRD_PARTY_NOTICES](THIRD_PARTY_NOTICES) para detalhes.
|
|
121
|
+
|
|
122
|
+
Elder Scrolls Online é marca registrada de ZeniMax Media Inc. Este projeto não é afiliado nem endossado pela ZeniMax Media Inc.
|
|
@@ -1,39 +1,49 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* ESO build calculation engine.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Implements the core architecture idea:
|
|
5
5
|
*
|
|
6
|
-
* 1.
|
|
7
|
-
* (jQuery
|
|
6
|
+
* 1. Inject character data into the mock DOM elements
|
|
7
|
+
* (jQuery will read via $("#esotbRace").val(), etc.)
|
|
8
8
|
*
|
|
9
|
-
* 2.
|
|
10
|
-
* —
|
|
11
|
-
*
|
|
9
|
+
* 2. Inject item data DIRECTLY into g_EsoBuildItemData[slot]
|
|
10
|
+
* — no need to mock jQuery for each item field.
|
|
11
|
+
* Fields come exactly in the UESP public API format:
|
|
12
12
|
* GET https://esolog.uesp.net/exportJson.php?table=minedItem&id=<id>&level=<lv>&quality=<q>
|
|
13
13
|
*
|
|
14
|
-
* 3.
|
|
15
|
-
* —
|
|
16
|
-
*
|
|
14
|
+
* 3. Call UpdateEsoComputedStatsList_Real(null, true)
|
|
15
|
+
* — the `noUpdate=true` parameter makes the engine compute everything but skip
|
|
16
|
+
* the DOM updates (DisplayEsoAllComputedStats, UpdateReadOnlyStats, etc.)
|
|
17
17
|
*
|
|
18
|
-
* 4.
|
|
18
|
+
* 4. Read the results from g_EsoComputedStats[statId].value
|
|
19
19
|
*/
|
|
20
|
-
import type { BuffInfo, BuildInput, ComputedStats, PassiveSkillInfo, ToggleSkillInfo } from './types';
|
|
20
|
+
import type { BuffInfo, BuildInput, ComputedStats, PassiveSkillInfo, ToggleSkillInfo } from './types.js';
|
|
21
21
|
export declare function cacheStatObjects(): void;
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* Calculates the Computed Character Statistics for the given build.
|
|
24
|
+
*
|
|
25
|
+
* Each call starts from a clean engine state (previous items, buffs, CP nodes
|
|
26
|
+
* and skill bars are reset), so builds never bleed into each other.
|
|
27
|
+
*
|
|
28
|
+
* @param input - The build to calculate: character sheet, items, champion
|
|
29
|
+
* point nodes, buffs, toggle skills, skill bars and passives.
|
|
30
|
+
* @returns All computed stats — named keys (Health, Magicka, SpellDamage, ...)
|
|
31
|
+
* plus `raw` with the full 221-stat `g_EsoComputedStats` record.
|
|
32
|
+
* @throws If the engine has not been initialized with
|
|
33
|
+
* `initEsoEngineFromData()` first.
|
|
24
34
|
*
|
|
25
35
|
* @example
|
|
26
36
|
* ```ts
|
|
27
|
-
* import { calculateBuild } from '
|
|
37
|
+
* import { calculateBuild } from 'uesp-eso-build-wrapper';
|
|
28
38
|
*
|
|
29
39
|
* const stats = calculateBuild({
|
|
30
40
|
* character: { race: 'High Elf', class: 'Sorcerer', level: 50,
|
|
31
41
|
* attributes: { health: 0, magicka: 64, stamina: 0 } },
|
|
32
42
|
* items: {
|
|
33
|
-
* Chest: chestItemFromUespApi, //
|
|
43
|
+
* Chest: chestItemFromUespApi, // object returned by esolog.uesp.net/exportJson.php
|
|
34
44
|
* },
|
|
35
45
|
* });
|
|
36
|
-
* console.log(stats.
|
|
46
|
+
* console.log(stats.Magicka, stats.SpellDamage);
|
|
37
47
|
* ```
|
|
38
48
|
*/
|
|
39
49
|
export declare function calculateBuild(input: BuildInput): ComputedStats;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calculator.d.ts","sourceRoot":"","sources":["../../../src/lib/eso-engine/calculator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;
|
|
1
|
+
{"version":3,"file":"calculator.d.ts","sourceRoot":"","sources":["../../../src/lib/eso-engine/calculator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,OAAO,KAAK,EACV,QAAQ,EACR,UAAU,EAEV,aAAa,EAEb,gBAAgB,EAEhB,eAAe,EAEhB,MAAM,YAAY,CAAC;AAMpB,wBAAgB,gBAAgB,IAAI,IAAI,CAKvC;AAwDD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,aAAa,CAygB/D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,EAAE,CA6B7D;AA2BD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAKnE;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAKvE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAK7E;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,EAAE,CASlD;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,IAAI,eAAe,EAAE,CA6B7D"}
|