pogo-masterfile 0.1.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/CHANGELOG.md +5 -0
- package/LICENSE +21 -0
- package/README.md +187 -0
- package/dist/errors.d.ts +17 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +30 -0
- package/dist/errors.js.map +1 -0
- package/dist/fetch.d.ts +9 -0
- package/dist/fetch.d.ts.map +1 -0
- package/dist/fetch.js +31 -0
- package/dist/fetch.js.map +1 -0
- package/dist/group-names.d.ts +3 -0
- package/dist/group-names.d.ts.map +1 -0
- package/dist/group-names.js +64 -0
- package/dist/group-names.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/masterfile.d.ts +47 -0
- package/dist/masterfile.d.ts.map +1 -0
- package/dist/masterfile.js +163 -0
- package/dist/masterfile.js.map +1 -0
- package/dist/types.d.ts +18 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +66 -0
package/CHANGELOG.md
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Hazel's Lab Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# pogo-masterfile
|
|
2
|
+
|
|
3
|
+
Runtime API for the Pokémon GO masterfile. Loads, indexes, and queries entries with per-group literal-typed accessors. Built on [`pogo-masterfile-types`](../ts/README.md).
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install pogo-masterfile
|
|
9
|
+
# or
|
|
10
|
+
bun add pogo-masterfile
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quickstart
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { Masterfile } from "pogo-masterfile";
|
|
17
|
+
|
|
18
|
+
const mf = await Masterfile.fromRemote();
|
|
19
|
+
|
|
20
|
+
// Top-level lookup — wide return type (MasterfileEntry).
|
|
21
|
+
const move = mf.getEntry("V0022_MOVE_MEGAHORN");
|
|
22
|
+
|
|
23
|
+
// Per-group accessor — literal-narrow return type, full intellisense.
|
|
24
|
+
// `tackle` is typed as the exact literal entry, e.g. its `power` is `105`.
|
|
25
|
+
const tackle = mf.moveSettings.get("V0033_MOVE_TACKLE_FAST");
|
|
26
|
+
|
|
27
|
+
// Iterate one group.
|
|
28
|
+
for (const m of mf.moveSettings) {
|
|
29
|
+
// m is fully typed as a MoveSettingsMasterfileEntry
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Search.
|
|
33
|
+
const items = mf.findByPattern(/^ITEM_/);
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Top-level vs per-group lookups
|
|
37
|
+
|
|
38
|
+
The `Masterfile` class deliberately splits its lookup APIs to keep TypeScript's
|
|
39
|
+
compile times fast:
|
|
40
|
+
|
|
41
|
+
- **Top-level** (`mf.getEntry`, `mf.tryGetEntry`, `mf.has`) returns the wide
|
|
42
|
+
`MasterfileEntry` union with no literal narrowing. Use it when you have an
|
|
43
|
+
arbitrary string templateId and just want the entry.
|
|
44
|
+
- **Per-group accessor** (`mf.moveSettings.get`, etc.) narrows to the exact
|
|
45
|
+
literal entry type for that group's templateIds. Use it when you know the
|
|
46
|
+
group up front — you get full autocomplete on IDs and a precisely-typed
|
|
47
|
+
return value.
|
|
48
|
+
|
|
49
|
+
If you want cross-group literal narrowing on top-level lookups, import the
|
|
50
|
+
explicit `EntryByTemplateID` interface from `pogo-masterfile-types/lookup-table`
|
|
51
|
+
and cast to it. That interface materializes ~18k keys and is correspondingly
|
|
52
|
+
expensive to type-check, so reach for it only when you actually need it.
|
|
53
|
+
|
|
54
|
+
## Loading
|
|
55
|
+
|
|
56
|
+
`Masterfile` instances are constructed via two factories:
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
// Fetch from the default community mirror (alexelgt/game_masters).
|
|
60
|
+
const mf = await Masterfile.fromRemote();
|
|
61
|
+
|
|
62
|
+
// Wrap an already-loaded array (e.g., bundled with your app or fetched manually).
|
|
63
|
+
const mf = Masterfile.fromJson(myEntries);
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Custom URL
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
const mf = await Masterfile.fromRemote({
|
|
70
|
+
url: "https://my-cdn.example/masterfile.json",
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Custom fetcher
|
|
75
|
+
|
|
76
|
+
If your upstream returns a different shape, supply a custom fetcher that normalizes to `MasterfileEntry[]`:
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
const mf = await Masterfile.fromRemote({
|
|
80
|
+
fetcher: async (url, signal) => {
|
|
81
|
+
const r = await fetch(url, {
|
|
82
|
+
signal,
|
|
83
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
84
|
+
});
|
|
85
|
+
const wrapped = (await r.json()) as { data: MasterfileEntry[] };
|
|
86
|
+
return wrapped.data;
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
You can also compose around the default fetcher:
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
import { defaultFetcher } from "pogo-masterfile/fetch";
|
|
95
|
+
|
|
96
|
+
const mf = await Masterfile.fromRemote({
|
|
97
|
+
fetcher: async (url, signal) => {
|
|
98
|
+
const entries = await defaultFetcher(url, signal);
|
|
99
|
+
return entries.filter((e) => /* user filter */);
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Cancellation
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
const ac = new AbortController();
|
|
108
|
+
setTimeout(() => ac.abort(), 5000);
|
|
109
|
+
const mf = await Masterfile.fromRemote({ signal: ac.signal });
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Top-level API
|
|
113
|
+
|
|
114
|
+
| Method | Description |
|
|
115
|
+
|---|---|
|
|
116
|
+
| `getEntry(id)` | Return the entry (wide `MasterfileEntry`). Throws `EntryNotFoundError` if missing. |
|
|
117
|
+
| `tryGetEntry(id)` | Return the entry or `undefined`. |
|
|
118
|
+
| `has(id)` | Boolean check. |
|
|
119
|
+
| `getAll()` | All entries. |
|
|
120
|
+
| `getGroup(name)` | All entries for one group, narrowed to that group's union. |
|
|
121
|
+
| `groups()` | All group names. |
|
|
122
|
+
| `templateIds()` / `templateIds(group)` | All template IDs (or just one group's). |
|
|
123
|
+
| `[Symbol.iterator]()` | `for (const e of mf)` over all entries. |
|
|
124
|
+
| `size` | Total entry count. |
|
|
125
|
+
| `raw` | Underlying `MasterfileEntry[]` (read-only view). |
|
|
126
|
+
| `find(pred)` / `filter(pred)` | Predicate search over all entries. |
|
|
127
|
+
| `findByPattern(regex)` | All entries whose `templateId` matches the regex. |
|
|
128
|
+
| `refresh(opts?)` | Re-fetch from remote and swap data atomically. |
|
|
129
|
+
| `update(json)` | Replace data with a provided array (sync). |
|
|
130
|
+
|
|
131
|
+
## Per-group accessors
|
|
132
|
+
|
|
133
|
+
For every group `G`, `mf.<G>` is a `GroupAccessor<G>` with a focused, narrowly-typed mini-API:
|
|
134
|
+
|
|
135
|
+
```ts
|
|
136
|
+
mf.moveSettings.get(id) // throws if missing
|
|
137
|
+
mf.moveSettings.tryGet(id) // T | undefined
|
|
138
|
+
mf.moveSettings.has(id) // type predicate
|
|
139
|
+
mf.moveSettings.all() // alias for getGroup("moveSettings")
|
|
140
|
+
mf.moveSettings.templateIds() // narrow ID array
|
|
141
|
+
mf.moveSettings.find(predicate) // predicate typed against MoveSettings union
|
|
142
|
+
mf.moveSettings.filter(predicate)
|
|
143
|
+
mf.moveSettings.size
|
|
144
|
+
for (const m of mf.moveSettings) { … }
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The accessor's `find` / `filter` predicates receive the narrow group union, so `entry.data.moveSettings` autocompletes without runtime type guards.
|
|
148
|
+
|
|
149
|
+
## Errors
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
import { MasterfileFetchError, MasterfileParseError, EntryNotFoundError } from "pogo-masterfile/errors";
|
|
153
|
+
|
|
154
|
+
try {
|
|
155
|
+
const mf = await Masterfile.fromRemote();
|
|
156
|
+
} catch (err) {
|
|
157
|
+
if (err instanceof MasterfileFetchError) console.error("fetch failed:", err.url, err.cause);
|
|
158
|
+
if (err instanceof MasterfileParseError) console.error("parse failed:", err.cause);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
try {
|
|
162
|
+
mf.getEntry("DOES_NOT_EXIST");
|
|
163
|
+
} catch (err) {
|
|
164
|
+
if (err instanceof EntryNotFoundError) console.error("missing:", err.templateId);
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Module resolution
|
|
169
|
+
|
|
170
|
+
This package ships compiled `.js` + `.d.ts` from a `src/` → `dist/` build. It targets `module: "ES2022"` and uses universal `fetch` (Node ≥18, modern browsers, Bun, Deno). No polyfills needed.
|
|
171
|
+
|
|
172
|
+
```jsonc
|
|
173
|
+
// tsconfig.json
|
|
174
|
+
{
|
|
175
|
+
"compilerOptions": {
|
|
176
|
+
"moduleResolution": "bundler" // or "node16" / "nodenext"
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Source
|
|
182
|
+
|
|
183
|
+
All code under `dist/` is built from generated source in `src/`, which is itself produced by the codegen pipeline at the [repo root](https://github.com/Hazels-Lab/pogo-masterfile). Don't edit emitted files by hand — re-run `bun run generate`.
|
|
184
|
+
|
|
185
|
+
## License
|
|
186
|
+
|
|
187
|
+
MIT — see [LICENSE](./LICENSE).
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Network or HTTP failure when fetching the masterfile. */
|
|
2
|
+
export declare class MasterfileFetchError extends Error {
|
|
3
|
+
readonly url: string;
|
|
4
|
+
readonly cause?: unknown;
|
|
5
|
+
constructor(message: string, url: string, cause?: unknown);
|
|
6
|
+
}
|
|
7
|
+
/** Response could not be parsed as a `MasterfileEntry[]`. */
|
|
8
|
+
export declare class MasterfileParseError extends Error {
|
|
9
|
+
readonly cause?: unknown;
|
|
10
|
+
constructor(message: string, cause?: unknown);
|
|
11
|
+
}
|
|
12
|
+
/** A `getEntry` lookup did not find an entry with the given templateId. */
|
|
13
|
+
export declare class EntryNotFoundError extends Error {
|
|
14
|
+
readonly templateId: string;
|
|
15
|
+
constructor(templateId: string);
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,qBAAa,oBAAqB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,SAAkB,KAAK,CAAC,EAAE,OAAO,CAAC;gBAEtB,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAMzD;AAED,6DAA6D;AAC7D,qBAAa,oBAAqB,SAAQ,KAAK;IAC9C,SAAkB,KAAK,CAAC,EAAE,OAAO,CAAC;gBAEtB,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAK5C;AAED,2EAA2E;AAC3E,qBAAa,kBAAmB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;gBAEhB,UAAU,EAAE,MAAM;CAK9B"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** Network or HTTP failure when fetching the masterfile. */
|
|
2
|
+
export class MasterfileFetchError extends Error {
|
|
3
|
+
url;
|
|
4
|
+
cause;
|
|
5
|
+
constructor(message, url, cause) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = "MasterfileFetchError";
|
|
8
|
+
this.url = url;
|
|
9
|
+
this.cause = cause;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/** Response could not be parsed as a `MasterfileEntry[]`. */
|
|
13
|
+
export class MasterfileParseError extends Error {
|
|
14
|
+
cause;
|
|
15
|
+
constructor(message, cause) {
|
|
16
|
+
super(message);
|
|
17
|
+
this.name = "MasterfileParseError";
|
|
18
|
+
this.cause = cause;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/** A `getEntry` lookup did not find an entry with the given templateId. */
|
|
22
|
+
export class EntryNotFoundError extends Error {
|
|
23
|
+
templateId;
|
|
24
|
+
constructor(templateId) {
|
|
25
|
+
super(`No entry with templateId "${templateId}"`);
|
|
26
|
+
this.name = "EntryNotFoundError";
|
|
27
|
+
this.templateId = templateId;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IACrC,GAAG,CAAS;IACH,KAAK,CAAW;IAElC,YAAY,OAAe,EAAE,GAAW,EAAE,KAAe;QACxD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACpB,CAAC;CACD;AAED,6DAA6D;AAC7D,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC5B,KAAK,CAAW;IAElC,YAAY,OAAe,EAAE,KAAe;QAC3C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACpB,CAAC;CACD;AAED,2EAA2E;AAC3E,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IACnC,UAAU,CAAS;IAE5B,YAAY,UAAkB;QAC7B,KAAK,CAAC,6BAA6B,UAAU,GAAG,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;QACjC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC9B,CAAC;CACD"}
|
package/dist/fetch.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Fetcher } from "./types";
|
|
2
|
+
export declare const DEFAULT_MASTERFILE_URL = "https://raw.githubusercontent.com/alexelgt/game_masters/refs/heads/master/GAME_MASTER.json";
|
|
3
|
+
/**
|
|
4
|
+
* Default fetcher: standard `fetch` + JSON parse, with shape validation.
|
|
5
|
+
* Throws `MasterfileFetchError` for network/HTTP failures and
|
|
6
|
+
* `MasterfileParseError` for invalid JSON or non-array bodies.
|
|
7
|
+
*/
|
|
8
|
+
export declare const defaultFetcher: Fetcher;
|
|
9
|
+
//# sourceMappingURL=fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../src/fetch.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,eAAO,MAAM,sBAAsB,+FAA+F,CAAC;AAEnI;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,OAoB5B,CAAC"}
|
package/dist/fetch.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { MasterfileFetchError, MasterfileParseError } from "./errors";
|
|
2
|
+
export const DEFAULT_MASTERFILE_URL = "https://raw.githubusercontent.com/alexelgt/game_masters/refs/heads/master/GAME_MASTER.json";
|
|
3
|
+
/**
|
|
4
|
+
* Default fetcher: standard `fetch` + JSON parse, with shape validation.
|
|
5
|
+
* Throws `MasterfileFetchError` for network/HTTP failures and
|
|
6
|
+
* `MasterfileParseError` for invalid JSON or non-array bodies.
|
|
7
|
+
*/
|
|
8
|
+
export const defaultFetcher = async (url, signal) => {
|
|
9
|
+
let response;
|
|
10
|
+
try {
|
|
11
|
+
response = await fetch(url, { signal });
|
|
12
|
+
}
|
|
13
|
+
catch (cause) {
|
|
14
|
+
throw new MasterfileFetchError(`network error fetching ${url}`, url, cause);
|
|
15
|
+
}
|
|
16
|
+
if (!response.ok) {
|
|
17
|
+
throw new MasterfileFetchError(`${response.status} ${response.statusText} from ${url}`, url);
|
|
18
|
+
}
|
|
19
|
+
let json;
|
|
20
|
+
try {
|
|
21
|
+
json = await response.json();
|
|
22
|
+
}
|
|
23
|
+
catch (cause) {
|
|
24
|
+
throw new MasterfileParseError("response body is not valid JSON", cause);
|
|
25
|
+
}
|
|
26
|
+
if (!Array.isArray(json)) {
|
|
27
|
+
throw new MasterfileParseError("expected top-level JSON array of entries");
|
|
28
|
+
}
|
|
29
|
+
return json;
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=fetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../src/fetch.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAGtE,MAAM,CAAC,MAAM,sBAAsB,GAAG,4FAA4F,CAAC;AAEnI;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAY,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE;IAC5D,IAAI,QAAkB,CAAC;IACvB,IAAI,CAAC;QACJ,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,IAAI,oBAAoB,CAAC,0BAA0B,GAAG,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IAC7E,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QAClB,MAAM,IAAI,oBAAoB,CAAC,GAAG,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,SAAS,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC;IAC9F,CAAC;IACD,IAAI,IAAa,CAAC;IAClB,IAAI,CAAC;QACJ,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC9B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,IAAI,oBAAoB,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;IAC1E,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,oBAAoB,CAAC,0CAA0C,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,IAAyB,CAAC;AAClC,CAAC,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const GROUP_NAMES: readonly ["avatarCustomization", "avatarGroupOrderSettings", "avatarItemDisplay", "badgeSettings", "breadMoveLevelSettings", "buddyActivityCategorySettings", "buddyEmotionLevelSettings", "buddyLevelSettings", "clientQuestTemplate", "codeGateProto", "combatLeague", "combatMove", "combatNpcPersonality", "combatNpcTrainer", "combatRankingProtoSettings", "combatType", "eventPassSettings", "eventPassTierSettings", "evolutionChainDisplaySettings", "evolutionQuestTemplate", "featureGate", "formSettings", "fortPowerUpLevelSettings", "friendshipMilestoneSettings", "genderSettings", "iapCategoryDisplay", "iapItemDisplay", "invasionNpcDisplaySettings", "itemExpirationSettings", "itemSettings", "languageSettings", "levelUpRewards", "limitedPurchaseSkuSettings", "locationCardSettings", "megaEvoLevelSettings", "moveSequenceSettings", "moveSettings", "nonCombatMoveSettings", "partyPlayGeneralSettings", "photoSetsSettingsProto", "pokemonExtendedSettings", "pokemonFamily", "pokemonHomeEnergyCosts", "pokemonHomeFormReversions", "pokemonScaleSettings", "pokemonSettings", "pokemonUpgrades", "pokestopInvasionAvailabilitySettings", "questSettings", "recommendedSearchSettings", "rollBack", "settingsOverrideRule", "singletons", "stickerMetadata", "tappableSettings", "temporaryEvolutionSettings", "typeEffective", "vsSeekerLoot", "vsSeekerPokemonRewards", "weatherAffinities"];
|
|
2
|
+
export type GroupName = (typeof GROUP_NAMES)[number];
|
|
3
|
+
//# sourceMappingURL=group-names.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"group-names.d.ts","sourceRoot":"","sources":["../src/group-names.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW,81CA6Dd,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// Generated from Pokémon GO masterfile — list of group discriminators.
|
|
2
|
+
export const GROUP_NAMES = [
|
|
3
|
+
"avatarCustomization",
|
|
4
|
+
"avatarGroupOrderSettings",
|
|
5
|
+
"avatarItemDisplay",
|
|
6
|
+
"badgeSettings",
|
|
7
|
+
"breadMoveLevelSettings",
|
|
8
|
+
"buddyActivityCategorySettings",
|
|
9
|
+
"buddyEmotionLevelSettings",
|
|
10
|
+
"buddyLevelSettings",
|
|
11
|
+
"clientQuestTemplate",
|
|
12
|
+
"codeGateProto",
|
|
13
|
+
"combatLeague",
|
|
14
|
+
"combatMove",
|
|
15
|
+
"combatNpcPersonality",
|
|
16
|
+
"combatNpcTrainer",
|
|
17
|
+
"combatRankingProtoSettings",
|
|
18
|
+
"combatType",
|
|
19
|
+
"eventPassSettings",
|
|
20
|
+
"eventPassTierSettings",
|
|
21
|
+
"evolutionChainDisplaySettings",
|
|
22
|
+
"evolutionQuestTemplate",
|
|
23
|
+
"featureGate",
|
|
24
|
+
"formSettings",
|
|
25
|
+
"fortPowerUpLevelSettings",
|
|
26
|
+
"friendshipMilestoneSettings",
|
|
27
|
+
"genderSettings",
|
|
28
|
+
"iapCategoryDisplay",
|
|
29
|
+
"iapItemDisplay",
|
|
30
|
+
"invasionNpcDisplaySettings",
|
|
31
|
+
"itemExpirationSettings",
|
|
32
|
+
"itemSettings",
|
|
33
|
+
"languageSettings",
|
|
34
|
+
"levelUpRewards",
|
|
35
|
+
"limitedPurchaseSkuSettings",
|
|
36
|
+
"locationCardSettings",
|
|
37
|
+
"megaEvoLevelSettings",
|
|
38
|
+
"moveSequenceSettings",
|
|
39
|
+
"moveSettings",
|
|
40
|
+
"nonCombatMoveSettings",
|
|
41
|
+
"partyPlayGeneralSettings",
|
|
42
|
+
"photoSetsSettingsProto",
|
|
43
|
+
"pokemonExtendedSettings",
|
|
44
|
+
"pokemonFamily",
|
|
45
|
+
"pokemonHomeEnergyCosts",
|
|
46
|
+
"pokemonHomeFormReversions",
|
|
47
|
+
"pokemonScaleSettings",
|
|
48
|
+
"pokemonSettings",
|
|
49
|
+
"pokemonUpgrades",
|
|
50
|
+
"pokestopInvasionAvailabilitySettings",
|
|
51
|
+
"questSettings",
|
|
52
|
+
"recommendedSearchSettings",
|
|
53
|
+
"rollBack",
|
|
54
|
+
"settingsOverrideRule",
|
|
55
|
+
"singletons",
|
|
56
|
+
"stickerMetadata",
|
|
57
|
+
"tappableSettings",
|
|
58
|
+
"temporaryEvolutionSettings",
|
|
59
|
+
"typeEffective",
|
|
60
|
+
"vsSeekerLoot",
|
|
61
|
+
"vsSeekerPokemonRewards",
|
|
62
|
+
"weatherAffinities",
|
|
63
|
+
];
|
|
64
|
+
//# sourceMappingURL=group-names.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"group-names.js","sourceRoot":"","sources":["../src/group-names.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAEvE,MAAM,CAAC,MAAM,WAAW,GAAG;IAC1B,qBAAqB;IACrB,0BAA0B;IAC1B,mBAAmB;IACnB,eAAe;IACf,wBAAwB;IACxB,+BAA+B;IAC/B,2BAA2B;IAC3B,oBAAoB;IACpB,qBAAqB;IACrB,eAAe;IACf,cAAc;IACd,YAAY;IACZ,sBAAsB;IACtB,kBAAkB;IAClB,4BAA4B;IAC5B,YAAY;IACZ,mBAAmB;IACnB,uBAAuB;IACvB,+BAA+B;IAC/B,wBAAwB;IACxB,aAAa;IACb,cAAc;IACd,0BAA0B;IAC1B,6BAA6B;IAC7B,gBAAgB;IAChB,oBAAoB;IACpB,gBAAgB;IAChB,4BAA4B;IAC5B,wBAAwB;IACxB,cAAc;IACd,kBAAkB;IAClB,gBAAgB;IAChB,4BAA4B;IAC5B,sBAAsB;IACtB,sBAAsB;IACtB,sBAAsB;IACtB,cAAc;IACd,uBAAuB;IACvB,0BAA0B;IAC1B,wBAAwB;IACxB,yBAAyB;IACzB,eAAe;IACf,wBAAwB;IACxB,2BAA2B;IAC3B,sBAAsB;IACtB,iBAAiB;IACjB,iBAAiB;IACjB,sCAAsC;IACtC,eAAe;IACf,2BAA2B;IAC3B,UAAU;IACV,sBAAsB;IACtB,YAAY;IACZ,iBAAiB;IACjB,kBAAkB;IAClB,4BAA4B;IAC5B,eAAe;IACf,cAAc;IACd,wBAAwB;IACxB,mBAAmB;CACV,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { EntryNotFoundError, MasterfileFetchError, MasterfileParseError } from "./errors";
|
|
2
|
+
export { DEFAULT_MASTERFILE_URL, defaultFetcher } from "./fetch";
|
|
3
|
+
export type { GroupAccessor } from "./masterfile";
|
|
4
|
+
export { Masterfile } from "./masterfile";
|
|
5
|
+
export type { Fetcher, FromRemoteOptions } from "./types";
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAC1F,OAAO,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACjE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// Generated from Pokémon GO masterfile — top-level barrel.
|
|
2
|
+
export { EntryNotFoundError, MasterfileFetchError, MasterfileParseError } from "./errors";
|
|
3
|
+
export { DEFAULT_MASTERFILE_URL, defaultFetcher } from "./fetch";
|
|
4
|
+
export { Masterfile } from "./masterfile";
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAE3D,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAC1F,OAAO,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEjE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** biome-ignore-all lint/suspicious/noUnsafeDeclarationMerging: the Masterfile class+interface merge below intentionally adds per-group accessor properties installed dynamically in the constructor. */
|
|
2
|
+
import type { MasterfileEntry } from "pogo-masterfile-types/entries";
|
|
3
|
+
import type { EntriesByGroup, LookupByGroup, TemplateIDsByGroup } from "pogo-masterfile-types/lookup-table";
|
|
4
|
+
import { type GroupName } from "./group-names";
|
|
5
|
+
import type { FromRemoteOptions } from "./types";
|
|
6
|
+
export interface GroupAccessor<G extends GroupName> {
|
|
7
|
+
get<T extends keyof LookupByGroup[G] & string>(templateId: T): LookupByGroup[G][T];
|
|
8
|
+
get(templateId: string): EntriesByGroup[G];
|
|
9
|
+
tryGet<T extends keyof LookupByGroup[G] & string>(templateId: T): LookupByGroup[G][T] | undefined;
|
|
10
|
+
tryGet(templateId: string): EntriesByGroup[G] | undefined;
|
|
11
|
+
has(templateId: string): templateId is keyof LookupByGroup[G] & string;
|
|
12
|
+
all(): readonly EntriesByGroup[G][];
|
|
13
|
+
templateIds(): readonly (TemplateIDsByGroup[G] & string)[];
|
|
14
|
+
find(predicate: (entry: EntriesByGroup[G]) => boolean): EntriesByGroup[G] | undefined;
|
|
15
|
+
filter(predicate: (entry: EntriesByGroup[G]) => boolean): readonly EntriesByGroup[G][];
|
|
16
|
+
readonly size: number;
|
|
17
|
+
[Symbol.iterator](): IterableIterator<EntriesByGroup[G]>;
|
|
18
|
+
}
|
|
19
|
+
type GroupAccessorMap = {
|
|
20
|
+
[G in GroupName]: GroupAccessor<G>;
|
|
21
|
+
};
|
|
22
|
+
export declare class Masterfile {
|
|
23
|
+
#private;
|
|
24
|
+
private constructor();
|
|
25
|
+
static fromRemote(opts?: FromRemoteOptions): Promise<Masterfile>;
|
|
26
|
+
static fromJson(json: readonly MasterfileEntry[]): Masterfile;
|
|
27
|
+
getEntry(templateId: string): MasterfileEntry;
|
|
28
|
+
tryGetEntry(templateId: string): MasterfileEntry | undefined;
|
|
29
|
+
has(templateId: string): boolean;
|
|
30
|
+
getAll(): readonly MasterfileEntry[];
|
|
31
|
+
getGroup<G extends GroupName>(group: G): readonly EntriesByGroup[G][];
|
|
32
|
+
groups(): readonly GroupName[];
|
|
33
|
+
templateIds(): readonly string[];
|
|
34
|
+
templateIds<G extends GroupName>(group: G): readonly (TemplateIDsByGroup[G] & string)[];
|
|
35
|
+
[Symbol.iterator](): IterableIterator<MasterfileEntry>;
|
|
36
|
+
get size(): number;
|
|
37
|
+
get raw(): readonly MasterfileEntry[];
|
|
38
|
+
refresh(opts?: FromRemoteOptions): Promise<void>;
|
|
39
|
+
update(json: readonly MasterfileEntry[]): void;
|
|
40
|
+
find(predicate: (entry: MasterfileEntry) => boolean): MasterfileEntry | undefined;
|
|
41
|
+
filter(predicate: (entry: MasterfileEntry) => boolean): readonly MasterfileEntry[];
|
|
42
|
+
findByPattern(pattern: RegExp): readonly MasterfileEntry[];
|
|
43
|
+
}
|
|
44
|
+
export interface Masterfile extends GroupAccessorMap {
|
|
45
|
+
}
|
|
46
|
+
export {};
|
|
47
|
+
//# sourceMappingURL=masterfile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"masterfile.d.ts","sourceRoot":"","sources":["../src/masterfile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/** biome-ignore-all lint/suspicious/noUnsafeDeclarationMerging: the Masterfile class+interface merge below intentionally adds per-group accessor properties installed dynamically in the constructor. */
|
|
2
|
+
import { EntryNotFoundError } from "./errors";
|
|
3
|
+
import { DEFAULT_MASTERFILE_URL, defaultFetcher } from "./fetch";
|
|
4
|
+
import { GROUP_NAMES } from "./group-names";
|
|
5
|
+
// ── Class ──────────────────────────────────────────────────────────────────
|
|
6
|
+
export class Masterfile {
|
|
7
|
+
#entries = [];
|
|
8
|
+
#byTemplateId = new Map();
|
|
9
|
+
#byGroup = new Map();
|
|
10
|
+
constructor(entries) {
|
|
11
|
+
this.#install(entries);
|
|
12
|
+
for (const groupName of GROUP_NAMES) {
|
|
13
|
+
this.#installAccessor(groupName);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
// ── Loaders ──
|
|
17
|
+
static async fromRemote(opts = {}) {
|
|
18
|
+
const url = opts.url ?? DEFAULT_MASTERFILE_URL;
|
|
19
|
+
const fetcher = opts.fetcher ?? defaultFetcher;
|
|
20
|
+
const entries = await fetcher(url, opts.signal);
|
|
21
|
+
return new Masterfile(entries);
|
|
22
|
+
}
|
|
23
|
+
static fromJson(json) {
|
|
24
|
+
return new Masterfile(json);
|
|
25
|
+
}
|
|
26
|
+
// ── Core lookups ──
|
|
27
|
+
//
|
|
28
|
+
// Top-level lookups return the wide `MasterfileEntry` union — no literal
|
|
29
|
+
// narrowing. For literal narrowing, reach for the per-group accessor:
|
|
30
|
+
// `mf.moveSettings.get("V0022_MOVE_MEGAHORN")` returns the exact literal
|
|
31
|
+
// entry type. (Cross-group literal narrowing requires materializing the
|
|
32
|
+
// global `EntryByTemplateID` interface from
|
|
33
|
+
// `pogo-masterfile-types/lookup-table`, which is genuinely expensive.)
|
|
34
|
+
getEntry(templateId) {
|
|
35
|
+
const entry = this.#byTemplateId.get(templateId);
|
|
36
|
+
if (!entry)
|
|
37
|
+
throw new EntryNotFoundError(templateId);
|
|
38
|
+
return entry;
|
|
39
|
+
}
|
|
40
|
+
tryGetEntry(templateId) {
|
|
41
|
+
return this.#byTemplateId.get(templateId);
|
|
42
|
+
}
|
|
43
|
+
has(templateId) {
|
|
44
|
+
return this.#byTemplateId.has(templateId);
|
|
45
|
+
}
|
|
46
|
+
getAll() {
|
|
47
|
+
return this.#entries;
|
|
48
|
+
}
|
|
49
|
+
getGroup(group) {
|
|
50
|
+
return (this.#byGroup.get(group) ?? []);
|
|
51
|
+
}
|
|
52
|
+
// ── Introspection ──
|
|
53
|
+
groups() {
|
|
54
|
+
return GROUP_NAMES;
|
|
55
|
+
}
|
|
56
|
+
templateIds(group) {
|
|
57
|
+
if (group === undefined) {
|
|
58
|
+
return [...this.#byTemplateId.keys()];
|
|
59
|
+
}
|
|
60
|
+
return (this.#byGroup.get(group) ?? []).map((e) => e.templateId);
|
|
61
|
+
}
|
|
62
|
+
[Symbol.iterator]() {
|
|
63
|
+
return this.#entries[Symbol.iterator]();
|
|
64
|
+
}
|
|
65
|
+
get size() {
|
|
66
|
+
return this.#entries.length;
|
|
67
|
+
}
|
|
68
|
+
get raw() {
|
|
69
|
+
return this.#entries;
|
|
70
|
+
}
|
|
71
|
+
// ── Mutation ──
|
|
72
|
+
async refresh(opts = {}) {
|
|
73
|
+
const url = opts.url ?? DEFAULT_MASTERFILE_URL;
|
|
74
|
+
const fetcher = opts.fetcher ?? defaultFetcher;
|
|
75
|
+
const entries = await fetcher(url, opts.signal);
|
|
76
|
+
this.#install(entries);
|
|
77
|
+
}
|
|
78
|
+
update(json) {
|
|
79
|
+
this.#install(json);
|
|
80
|
+
}
|
|
81
|
+
// ── Top-level search ──
|
|
82
|
+
find(predicate) {
|
|
83
|
+
return this.#entries.find(predicate);
|
|
84
|
+
}
|
|
85
|
+
filter(predicate) {
|
|
86
|
+
return this.#entries.filter(predicate);
|
|
87
|
+
}
|
|
88
|
+
findByPattern(pattern) {
|
|
89
|
+
return this.#entries.filter((e) => pattern.test(e.templateId));
|
|
90
|
+
}
|
|
91
|
+
// ── Internals ──
|
|
92
|
+
#install(entries) {
|
|
93
|
+
const byTemplateId = new Map();
|
|
94
|
+
const byGroup = new Map();
|
|
95
|
+
for (const groupName of GROUP_NAMES) {
|
|
96
|
+
byGroup.set(groupName, []);
|
|
97
|
+
}
|
|
98
|
+
for (const entry of entries) {
|
|
99
|
+
byTemplateId.set(entry.templateId, entry);
|
|
100
|
+
const group = detectGroup(entry);
|
|
101
|
+
if (group !== undefined) {
|
|
102
|
+
byGroup.get(group).push(entry);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
const singletonsKey = "singletons";
|
|
106
|
+
const list = byGroup.get(singletonsKey);
|
|
107
|
+
if (list)
|
|
108
|
+
list.push(entry);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
this.#entries = entries;
|
|
112
|
+
this.#byTemplateId = byTemplateId;
|
|
113
|
+
this.#byGroup = byGroup;
|
|
114
|
+
}
|
|
115
|
+
#installAccessor(groupName) {
|
|
116
|
+
const self = this;
|
|
117
|
+
const accessor = {
|
|
118
|
+
get(templateId) {
|
|
119
|
+
const entry = self.#byTemplateId.get(templateId);
|
|
120
|
+
if (!entry)
|
|
121
|
+
throw new EntryNotFoundError(templateId);
|
|
122
|
+
return entry;
|
|
123
|
+
},
|
|
124
|
+
tryGet(templateId) {
|
|
125
|
+
return self.#byTemplateId.get(templateId);
|
|
126
|
+
},
|
|
127
|
+
has(templateId) {
|
|
128
|
+
const list = self.#byGroup.get(groupName) ?? [];
|
|
129
|
+
return list.some((e) => e.templateId === templateId);
|
|
130
|
+
},
|
|
131
|
+
all() {
|
|
132
|
+
return (self.#byGroup.get(groupName) ?? []);
|
|
133
|
+
},
|
|
134
|
+
templateIds() {
|
|
135
|
+
return (self.#byGroup.get(groupName) ?? []).map((e) => e.templateId);
|
|
136
|
+
},
|
|
137
|
+
find(predicate) {
|
|
138
|
+
return (self.#byGroup.get(groupName) ?? []).find(predicate);
|
|
139
|
+
},
|
|
140
|
+
filter(predicate) {
|
|
141
|
+
return (self.#byGroup.get(groupName) ?? []).filter(predicate);
|
|
142
|
+
},
|
|
143
|
+
get size() {
|
|
144
|
+
return (self.#byGroup.get(groupName) ?? []).length;
|
|
145
|
+
},
|
|
146
|
+
[Symbol.iterator]() {
|
|
147
|
+
return (self.#byGroup.get(groupName) ?? [])[Symbol.iterator]();
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
this[groupName] = accessor;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
function detectGroup(entry) {
|
|
154
|
+
const dataKeys = Object.keys(entry.data).filter((k) => k !== "templateId");
|
|
155
|
+
const first = dataKeys[0];
|
|
156
|
+
if (first === undefined)
|
|
157
|
+
return undefined;
|
|
158
|
+
if (GROUP_NAMES.includes(first)) {
|
|
159
|
+
return first;
|
|
160
|
+
}
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=masterfile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"masterfile.js","sourceRoot":"","sources":["../src/masterfile.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { MasterfileEntry } from "pogo-masterfile-types/entries";
|
|
2
|
+
export interface FromRemoteOptions {
|
|
3
|
+
/** URL to fetch from. Defaults to `DEFAULT_MASTERFILE_URL`. */
|
|
4
|
+
url?: string;
|
|
5
|
+
/** Custom fetcher. Default uses global `fetch` + `response.json()`. */
|
|
6
|
+
fetcher?: Fetcher;
|
|
7
|
+
/** Cancellation. */
|
|
8
|
+
signal?: AbortSignal;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Fetch the masterfile JSON and normalize it to `MasterfileEntry[]`.
|
|
12
|
+
*
|
|
13
|
+
* Custom fetchers MUST handle whatever upstream shape they receive and return
|
|
14
|
+
* an array conforming to `MasterfileEntry[]`. They should propagate `signal`
|
|
15
|
+
* to the underlying fetch so cancellation works.
|
|
16
|
+
*/
|
|
17
|
+
export type Fetcher = (url: string, signal?: AbortSignal) => Promise<MasterfileEntry[]>;
|
|
18
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAErE,MAAM,WAAW,iBAAiB;IACjC,+DAA+D;IAC/D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oBAAoB;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pogo-masterfile",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Runtime API for the Pokémon GO masterfile. Loads, indexes, and queries entries with literal-typed lookups and per-group accessors. Built on `pogo-masterfile-types`.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Hazel's Lab (https://github.com/Hazels-Lab)",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/Hazels-Lab/pogo-masterfile.git",
|
|
10
|
+
"directory": "packages/ts-api"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/Hazels-Lab/pogo-masterfile#readme",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/Hazels-Lab/pogo-masterfile/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"pokemon-go",
|
|
18
|
+
"pokemon",
|
|
19
|
+
"masterfile",
|
|
20
|
+
"api",
|
|
21
|
+
"typescript"
|
|
22
|
+
],
|
|
23
|
+
"type": "module",
|
|
24
|
+
"sideEffects": false,
|
|
25
|
+
"main": "./dist/index.js",
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"import": "./dist/index.js",
|
|
30
|
+
"types": "./dist/index.d.ts"
|
|
31
|
+
},
|
|
32
|
+
"./fetch": {
|
|
33
|
+
"import": "./dist/fetch.js",
|
|
34
|
+
"types": "./dist/fetch.d.ts"
|
|
35
|
+
},
|
|
36
|
+
"./errors": {
|
|
37
|
+
"import": "./dist/errors.js",
|
|
38
|
+
"types": "./dist/errors.d.ts"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"files": [
|
|
42
|
+
"dist",
|
|
43
|
+
"README.md",
|
|
44
|
+
"LICENSE",
|
|
45
|
+
"CHANGELOG.md"
|
|
46
|
+
],
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public"
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "tsc -p tsconfig.build.json",
|
|
52
|
+
"check": "tsc --noEmit -p tsconfig.json",
|
|
53
|
+
"prepublishOnly": "bun run build"
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"pogo-masterfile-types": "workspace:^"
|
|
57
|
+
},
|
|
58
|
+
"peerDependencies": {
|
|
59
|
+
"typescript": ">=5.0"
|
|
60
|
+
},
|
|
61
|
+
"peerDependenciesMeta": {
|
|
62
|
+
"typescript": {
|
|
63
|
+
"optional": true
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|