@maixio/pstore 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 +13 -0
- package/LICENSE +21 -0
- package/README.md +515 -0
- package/README.zh-CN.md +610 -0
- package/dist/api/batarang.d.ts +25 -0
- package/dist/api/browse.d.ts +64 -0
- package/dist/api/catalog-discovery.d.ts +40 -0
- package/dist/api/catalog-registry.d.ts +21 -0
- package/dist/api/catalog-validation.d.ts +21 -0
- package/dist/api/category-names.d.ts +2 -0
- package/dist/api/graphql.d.ts +216 -0
- package/dist/api/search.d.ts +23 -0
- package/dist/api/status.d.ts +81 -0
- package/dist/build-record.d.ts +20 -0
- package/dist/cache.d.ts +25 -0
- package/dist/cli.js +5500 -0
- package/dist/client.d.ts +47 -0
- package/dist/config.d.ts +30 -0
- package/dist/fetch.d.ts +19 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +2107 -0
- package/dist/locale.d.ts +12 -0
- package/dist/log.d.ts +31 -0
- package/dist/perf.d.ts +16 -0
- package/dist/provider.d.ts +16 -0
- package/dist/types.d.ts +253 -0
- package/dist/utils.d.ts +54 -0
- package/package.json +76 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0 - 2026-05-09
|
|
4
|
+
|
|
5
|
+
Initial public release of `@maixio/pstore`.
|
|
6
|
+
|
|
7
|
+
- Added PlayStation Store lookup by Concept ID and Product ID.
|
|
8
|
+
- Added lightweight search, category browse, and browse window commands.
|
|
9
|
+
- Added built-in catalog UUID registry with validation and live discovery helpers.
|
|
10
|
+
- Added multi-locale support for HK, TW, JP, US, GB, and CN storefronts.
|
|
11
|
+
- Added optional Batarang page extraction for publisher, descriptions, content rating, and localized title metadata.
|
|
12
|
+
- Added PlayStation Network status check command and SDK API.
|
|
13
|
+
- Added TypeScript SDK entrypoint and `pstore` CLI.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Maixiang
|
|
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,515 @@
|
|
|
1
|
+
# pstore
|
|
2
|
+
|
|
3
|
+
Unofficial PlayStation Store Web API client for querying publicly available storefront metadata. It ships as both a CLI and a TypeScript SDK.
|
|
4
|
+
|
|
5
|
+
> Disclaimer: pstore is a personal, unofficial project. It is not affiliated with, endorsed by, sponsored by, or authorized by Sony Interactive Entertainment, PlayStation, or any related company. PlayStation, PSN, and related marks are trademarks of their respective owners. The upstream PlayStation Store web APIs are not a public stable contract and may change without notice.
|
|
6
|
+
|
|
7
|
+
Chinese documentation is available in [README.zh-CN.md](./README.zh-CN.md).
|
|
8
|
+
|
|
9
|
+
## Quick Start
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Lookup a game
|
|
13
|
+
pstore lookup 10014149
|
|
14
|
+
|
|
15
|
+
# Search the store
|
|
16
|
+
pstore search diablo
|
|
17
|
+
|
|
18
|
+
# Browse a category
|
|
19
|
+
pstore category pre-orders
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
Run directly:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
bunx @maixio/pstore --help
|
|
28
|
+
npx @maixio/pstore --help
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Install globally:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
bun add -g @maixio/pstore
|
|
35
|
+
npm i -g @maixio/pstore
|
|
36
|
+
pstore --help
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Use as a library:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
bun add @maixio/pstore
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
import { createPstoreClient } from "@maixio/pstore";
|
|
47
|
+
|
|
48
|
+
const pstore = createPstoreClient({ locale: "en-US" });
|
|
49
|
+
|
|
50
|
+
const game = await pstore.lookup("10014149", {
|
|
51
|
+
includeProducts: true,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const search = await pstore.search({
|
|
55
|
+
term: "elden ring",
|
|
56
|
+
locale: "en-US",
|
|
57
|
+
size: 10,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const upcoming = await pstore.browse({
|
|
61
|
+
window: "next-thirty-days",
|
|
62
|
+
sortBy: "conceptReleaseDate",
|
|
63
|
+
order: "asc",
|
|
64
|
+
size: 10,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const deals = await pstore.categoryGrid({
|
|
68
|
+
id: "all-deals",
|
|
69
|
+
size: 10,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const status = await pstore.status();
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Public API
|
|
76
|
+
|
|
77
|
+
| API | Description |
|
|
78
|
+
| --- | --- |
|
|
79
|
+
| `createPstoreClient(options)` | Creates a small SDK facade with a default locale. |
|
|
80
|
+
| `lookupGame(id, options)` | Looks up a Concept ID or Product ID. |
|
|
81
|
+
| `searchGames(options)` | Searches the store and returns lightweight fields available from PSN Search. |
|
|
82
|
+
| `fetchBrowseGrid(query)` | Browses the store by time window, sorting, pagination, and filters. |
|
|
83
|
+
| `fetchCategoryGridResult(params)` | Browses a catalog/category UUID or built-in alias and returns pagination, sort, and facet metadata. |
|
|
84
|
+
| `fetchPsnStatus(options)` | Reads PlayStation Network service status. |
|
|
85
|
+
| `discoverCatalogs(options)` | Discovers catalog UUIDs from the current storefront pages. |
|
|
86
|
+
| `validateCatalogs(options)` | Validates whether built-in catalog UUIDs are still reachable. |
|
|
87
|
+
| `clearPstoreCaches()` | Clears process-local lookup/search/category caches. |
|
|
88
|
+
|
|
89
|
+
## API Notes
|
|
90
|
+
|
|
91
|
+
- `lookupGame` detects Concept IDs and Product IDs from the ID shape.
|
|
92
|
+
- `searchGames` intentionally avoids hidden N+1 enrichment by default. It does not fetch publisher, release date, genres, or localized titles unless you use `lookup`.
|
|
93
|
+
- `fetchCategoryGridResult` accepts raw UUIDs. The SDK facade methods `category` and `categoryGrid` also accept built-in aliases.
|
|
94
|
+
- `createPstoreClient({ locale })` stores only a default locale. Caches are process-local and shared.
|
|
95
|
+
- The upstream PSN Web API has no public stability guarantee. Fields and persisted query hashes may drift when the web store changes.
|
|
96
|
+
|
|
97
|
+
## CLI Overview
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
pstore lookup --help
|
|
101
|
+
pstore search --help
|
|
102
|
+
pstore category --help
|
|
103
|
+
pstore browse --help
|
|
104
|
+
pstore catalogs
|
|
105
|
+
pstore status
|
|
106
|
+
pstore config
|
|
107
|
+
pstore init
|
|
108
|
+
pstore clear-cache
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Output Fields
|
|
112
|
+
|
|
113
|
+
Text and JSON output are projected from the same English field keys. `--json` only changes rendering. `--fields` limits output fields. `--select` limits output fields and, where possible, chooses a smaller lookup request plan.
|
|
114
|
+
|
|
115
|
+
Common fields:
|
|
116
|
+
|
|
117
|
+
- Lookup detail: `id`, `idType`, `conceptId`, `productId`, `name`, `locale`, `publisher`, `edition`, `releaseDate`, `price`, `rating`, `classification`, `topCategory`, `platforms`, `npTitleId`, `warnings`
|
|
118
|
+
- Full lookup detail: `productName`, `genres`, `skus`, `descriptions`, `media`, `products`, `contentRating`, `localizedTitles`, `concept`, `sources`, `timing`
|
|
119
|
+
- Search/category/browse default list fields: `id`, `name`, `type`, `price`, `platforms`, `classification`
|
|
120
|
+
- Optional list field: `url`
|
|
121
|
+
|
|
122
|
+
`search`, `category`, and `browse` do not output `url` by default because `id` is enough for `lookup` and scripts. Add it explicitly when needed:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
pstore search astro --json --fields id,name,price,url
|
|
126
|
+
pstore category all-deals --json --fields id,name,url
|
|
127
|
+
pstore browse --window next-thirty-days --json --fields id,name,url
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
`lookup --select` can reduce upstream requests. For example, `--select id,name,price` skips rating, related products, and Batarang page requests. Selecting `publisher`, `descriptions`, or `contentRating` enables Batarang. For `search`, `category`, and `browse`, `--select` currently behaves like `--fields`.
|
|
131
|
+
|
|
132
|
+
## lookup
|
|
133
|
+
|
|
134
|
+
Looks up game details by Concept ID or Product ID. Comma-separated batch lookup is supported.
|
|
135
|
+
|
|
136
|
+
Options:
|
|
137
|
+
|
|
138
|
+
- `-l, --locale <locale>`: locale, defaulting to config
|
|
139
|
+
- `-f, --fields <fields>`: comma-separated output fields
|
|
140
|
+
- `--select <fields>`: field-driven request plan and output projection
|
|
141
|
+
- `--full`: full detail profile with related products, concept data, and Batarang details
|
|
142
|
+
- `-p, --products`: include related editions/products
|
|
143
|
+
- `--with-concept`: include concept/default product data for Product ID lookups
|
|
144
|
+
- `-b, --batarang`: force Batarang HTML extraction for descriptions, publisher, and page metadata
|
|
145
|
+
- `--title-locales <locales>`: fetch localized titles; supports `cjk-en` or comma-separated locales
|
|
146
|
+
- `-j, --json`: JSON output
|
|
147
|
+
- `--verbose`: include timing information in text output
|
|
148
|
+
- `--concurrency <count>`: batch lookup concurrency, default `3`
|
|
149
|
+
|
|
150
|
+
Examples:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
pstore lookup 10014149
|
|
154
|
+
pstore lookup UP1001-PPSA28420_00-NBA2K26000000000
|
|
155
|
+
pstore lookup 10014149,231761
|
|
156
|
+
pstore lookup 10014149 --locale en-US
|
|
157
|
+
pstore lookup 10014149 --json
|
|
158
|
+
pstore lookup 10014149 --products
|
|
159
|
+
pstore lookup 10014149 --title-locales cjk-en --json
|
|
160
|
+
pstore lookup 10014149,10005069,10017939 --products --concurrency 2 --json
|
|
161
|
+
pstore lookup 10014149 --fields id,name,price,rating
|
|
162
|
+
pstore lookup 10014149 --select id,name,price --json
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Lookup keeps PSN object semantics:
|
|
166
|
+
|
|
167
|
+
- Product ID lookup uses `productRetrieve`; the top-level `price` belongs to that product/edition.
|
|
168
|
+
- Concept ID lookup uses `conceptRetrieve`; the top-level `price` belongs to the concept/default product.
|
|
169
|
+
- Product ID results expose the owning `conceptId`; use `--with-concept` when you need concept/default product details.
|
|
170
|
+
- `--products` returns related editions under the same concept, and each `products[].price` remains that edition's own price.
|
|
171
|
+
|
|
172
|
+
## category
|
|
173
|
+
|
|
174
|
+
Browses a category by UUID or built-in alias.
|
|
175
|
+
|
|
176
|
+
Options:
|
|
177
|
+
|
|
178
|
+
- `-l, --locale <locale>`: locale
|
|
179
|
+
- `-p, --page <page>`: page number, default `1`
|
|
180
|
+
- `-s, --size <size>`: page size, default `24`
|
|
181
|
+
- `--sort <sort>`: sort alias or raw field direction
|
|
182
|
+
- `--filter <facet:key>`: generic facet filter, repeatable
|
|
183
|
+
- `--platform <platform>`: platform filter, repeatable
|
|
184
|
+
- `--genre <genre>`: genre filter, repeatable
|
|
185
|
+
- `--classification <classification>`: product classification filter
|
|
186
|
+
- `--price <range>`: price range, for example `0-0`
|
|
187
|
+
- `--release <window>`: release window, for example `last_thirty_days`
|
|
188
|
+
- `--vr <compatibility>`: VR compatibility filter
|
|
189
|
+
- `--facets`: include supported facet metadata
|
|
190
|
+
- `--sorts`: include supported sort metadata
|
|
191
|
+
- `-f, --fields <fields>`: comma-separated output fields
|
|
192
|
+
- `--select <fields>`: currently equivalent to `--fields`
|
|
193
|
+
- `-j, --json`: JSON output
|
|
194
|
+
|
|
195
|
+
Supported sort aliases:
|
|
196
|
+
|
|
197
|
+
- `best-selling`
|
|
198
|
+
- `downloads`
|
|
199
|
+
- `name`
|
|
200
|
+
- `name-desc`
|
|
201
|
+
- `price-asc`
|
|
202
|
+
- `price-desc`
|
|
203
|
+
- `release-new`
|
|
204
|
+
- `release-old`
|
|
205
|
+
- `field:asc` / `field:desc`
|
|
206
|
+
|
|
207
|
+
Examples:
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
pstore category pre-orders
|
|
211
|
+
pstore category action
|
|
212
|
+
pstore category rpg
|
|
213
|
+
pstore category sports
|
|
214
|
+
pstore category simulation
|
|
215
|
+
pstore category all-deals
|
|
216
|
+
pstore category 3bf499d7-7acf-4931-97dd-2667494ee2c9
|
|
217
|
+
pstore category pre-orders --sort price-asc
|
|
218
|
+
pstore category all-deals --size 3 --facets --sorts
|
|
219
|
+
pstore category all-deals --platform PS5 --genre ACTION --price 0-0 --sort downloads
|
|
220
|
+
pstore category pre-orders --page 2 --size 12
|
|
221
|
+
pstore category pre-orders --json
|
|
222
|
+
pstore category all-deals --fields id,name,url --json
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## browse
|
|
226
|
+
|
|
227
|
+
Browses PlayStation Store list semantics by time window, sorting, pagination, sampling, and generic filters.
|
|
228
|
+
|
|
229
|
+
Options:
|
|
230
|
+
|
|
231
|
+
- `-w, --window <window>`: `next-thirty-days`, `next_thirty_days`, `last-thirty-days`, `last_thirty_days`, or `all`
|
|
232
|
+
- `--sort <sort>`: `conceptReleaseDate`, `sales30`, `downloads30`, `conceptName`, `webBasePrice`, or `contentCollections.contentCollectionStartDate`
|
|
233
|
+
- `--order <order>`: `asc` or `desc`
|
|
234
|
+
- `-p, --page <page>`: page number, default `1`
|
|
235
|
+
- `-s, --size <size>`: page size, default `24`
|
|
236
|
+
- `--sample <count>`: random sample count
|
|
237
|
+
- `--filter <facet:value>`: generic raw PSN facet filter, repeatable
|
|
238
|
+
- `--platform <value>`: platform filter, for example `PS5`
|
|
239
|
+
- `--genre <value>`: genre filter, for example `ACTION`
|
|
240
|
+
- `--price <range>`: price range, for example `0-0` or `10000-19999`
|
|
241
|
+
- `--classification <value>`: classification filter, for example `FULL_GAME`
|
|
242
|
+
- `--age-rating <value>`: age rating filter
|
|
243
|
+
- `--vr <value>`: VR compatibility filter
|
|
244
|
+
- `--notice <value>`: compatibility notice filter
|
|
245
|
+
- `-f, --fields <fields>`: comma-separated output fields
|
|
246
|
+
- `--select <fields>`: currently equivalent to `--fields`
|
|
247
|
+
- `-l, --locale <locale>`: locale
|
|
248
|
+
- `-j, --json`: JSON output
|
|
249
|
+
|
|
250
|
+
Examples:
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
pstore browse --window next-thirty-days --sort conceptReleaseDate --order asc --sample 3
|
|
254
|
+
pstore browse --window next-thirty-days --sort sales30 --order desc --sample 3
|
|
255
|
+
pstore browse --window last-thirty-days --sort conceptReleaseDate --order desc --sample 3
|
|
256
|
+
pstore browse --window last-thirty-days --sort sales30 --order desc --sample 3
|
|
257
|
+
pstore browse --platform PS5 --genre ACTION --price 0-0
|
|
258
|
+
pstore browse --filter conceptGenres:SPORTS --filter webBasePrice:10000-19999
|
|
259
|
+
pstore browse --fields id,name,url --json
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## search
|
|
263
|
+
|
|
264
|
+
Searches games in the PlayStation Store.
|
|
265
|
+
|
|
266
|
+
`search` returns only stable lightweight fields that are present in the PSN Search response. It does not enrich each result with detail calls. For publisher, release date, genres, localized titles, descriptions, or ratings, take an `id` from search results and call `lookup <id>`.
|
|
267
|
+
|
|
268
|
+
Options:
|
|
269
|
+
|
|
270
|
+
- `-l, --locale <locale>`: locale
|
|
271
|
+
- `-p, --page <page>`: page number, default `1`
|
|
272
|
+
- `-s, --size <size>`: page size, default `24`
|
|
273
|
+
- `-f, --fields <fields>`: comma-separated output fields
|
|
274
|
+
- `--select <fields>`: currently equivalent to `--fields`
|
|
275
|
+
- `-j, --json`: JSON output
|
|
276
|
+
|
|
277
|
+
Examples:
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
pstore search diablo
|
|
281
|
+
pstore search "elden ring" --locale en-US
|
|
282
|
+
pstore search "elden ring" --json
|
|
283
|
+
pstore search "elden ring" --json --fields id,name,price,url
|
|
284
|
+
pstore search "elden ring" --fields id,name,url
|
|
285
|
+
pstore search game --page 2
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## catalogs
|
|
289
|
+
|
|
290
|
+
Lists built-in category aliases and UUIDs by default. The built-in table contains 58 relatively stable catalog UUIDs: 57 currently discoverable from storefront pages plus the hidden `all-deals` catalog. They are still upstream storefront data, so validate critical workflows before relying on them.
|
|
291
|
+
|
|
292
|
+
Live discovery is also available:
|
|
293
|
+
|
|
294
|
+
```bash
|
|
295
|
+
pstore catalogs
|
|
296
|
+
pstore catalogs --live --depth 1 --limit 50
|
|
297
|
+
pstore catalogs --validate all-deals
|
|
298
|
+
pstore catalogs --validate --json
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
In live output, `[from latest]` means the UUID was discovered from the `latest` navigation source page. It is a source marker, not the catalog title.
|
|
302
|
+
|
|
303
|
+
## status
|
|
304
|
+
|
|
305
|
+
Reads public JSON data from [status.playstation.com](https://status.playstation.com) to report PlayStation Network service status.
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
pstore status
|
|
309
|
+
pstore status --locale en-US
|
|
310
|
+
pstore status --country JP --json
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
## config / init
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
pstore config
|
|
317
|
+
pstore init
|
|
318
|
+
pstore clear-cache
|
|
319
|
+
bun run live-smoke
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
Global color option:
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
pstore lookup 10014149 --no-color
|
|
326
|
+
export NO_COLOR=1
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
## Supported Locales
|
|
330
|
+
|
|
331
|
+
| Locale | Language | Region | Currency |
|
|
332
|
+
| --- | --- | --- | --- |
|
|
333
|
+
| `zh-hans-HK` | Simplified Chinese | Hong Kong | HK$ |
|
|
334
|
+
| `zh-hant-HK` | Traditional Chinese | Hong Kong | HK$ |
|
|
335
|
+
| `en-HK` | English | Hong Kong | HK$ |
|
|
336
|
+
| `zh-hant-TW` | Traditional Chinese | Taiwan | NT$ |
|
|
337
|
+
| `en-TW` | English | Taiwan | NT$ |
|
|
338
|
+
| `ja-JP` | Japanese | Japan | ¥ |
|
|
339
|
+
| `en-US` | English | United States | $ |
|
|
340
|
+
| `en-GB` | English | United Kingdom | £ |
|
|
341
|
+
| `zh-hans-CN` | Simplified Chinese | Mainland China | ¥ |
|
|
342
|
+
|
|
343
|
+
## Field Reference
|
|
344
|
+
|
|
345
|
+
CLI field names are English keys for scripts and SDK consumers.
|
|
346
|
+
|
|
347
|
+
### Default Lookup Fields
|
|
348
|
+
|
|
349
|
+
| Field | Type | Source | Description |
|
|
350
|
+
| --- | --- | --- | --- |
|
|
351
|
+
| `id` | string | derived | Primary result ID. |
|
|
352
|
+
| `idType` | `"concept"` / `"product"` | derived | Result object type. |
|
|
353
|
+
| `conceptId` | string | telemetry/price/rating/upsell | Owning concept ID. Product ID lookups try to fill this as well. |
|
|
354
|
+
| `productId` | string | telemetry/price/rating/upsell | Current product ID or default product ID for a concept. |
|
|
355
|
+
| `name` | string | telemetry/batarang | Game title. |
|
|
356
|
+
| `locale` | string | input | Current locale. |
|
|
357
|
+
| `publisher` | string | batarang | Publisher. The default detail profile attempts to fetch it. |
|
|
358
|
+
| `edition` | string | telemetry | Edition name. |
|
|
359
|
+
| `releaseDate` | string | telemetry/rating/batarang | ISO 8601 release date. |
|
|
360
|
+
| `price` | object | price/telemetry | Top-level price. Product ID means product price; Concept ID means default product price. |
|
|
361
|
+
| `rating` | object | rating/batarang | Rating summary without `ratingsDistribution`. |
|
|
362
|
+
| `platforms` | string[] | telemetry/upsell/batarang | Platform list. |
|
|
363
|
+
| `genres` | string[] | telemetry/batarang | Localized genres. |
|
|
364
|
+
| `localizedTitles` | object | lookup by locale | Multi-locale titles. Defaults to the `cjk-en` preset. |
|
|
365
|
+
| `warnings` | object[] | runtime | Non-fatal data source failures. |
|
|
366
|
+
|
|
367
|
+
### Full Lookup Fields
|
|
368
|
+
|
|
369
|
+
| Field | Type | Source | Description |
|
|
370
|
+
| --- | --- | --- | --- |
|
|
371
|
+
| `productName` | string | telemetry | Product-level title. |
|
|
372
|
+
| `skus` | object[] | telemetry | SKU data. |
|
|
373
|
+
| `descriptions` | object[] | batarang | Short description, long description, compatibility notices, and legal text. |
|
|
374
|
+
| `media` | object[] | upsell/batarang | Screenshots, videos, and storefront images. |
|
|
375
|
+
| `products` | object[] | upsell | Related editions under the same concept; each product keeps its own `price`. |
|
|
376
|
+
| `contentRating` | object | telemetry/batarang | Content rating. |
|
|
377
|
+
| `concept` | object | lookup | Extra concept/default product data for Product ID lookups with `--with-concept`. |
|
|
378
|
+
| `sources` | object | runtime | Source tracking for important fields. |
|
|
379
|
+
| `timing` | object | runtime | Per-source timings. |
|
|
380
|
+
| `npTitleId` | string | telemetry/batarang | PSN title id. It is not in the default detail profile; select it with `--fields npTitleId`. |
|
|
381
|
+
|
|
382
|
+
### Search / Category / Browse List Fields
|
|
383
|
+
|
|
384
|
+
| Field | Type | Default | Source | Description |
|
|
385
|
+
| --- | --- | --- | --- | --- |
|
|
386
|
+
| `id` | string | Yes | search/category grid | Concept ID or Product ID; use with `type`. |
|
|
387
|
+
| `name` | string | Yes | search/category grid | Localized title. |
|
|
388
|
+
| `type` | `"concept"` / `"product"` | Yes | `__typename` | List item type. |
|
|
389
|
+
| `price` | string/null | Yes | search/category grid | Current display price. |
|
|
390
|
+
| `platforms` | string[]/null | Yes | search/category grid | Platform list. |
|
|
391
|
+
| `classification` | string/null | Yes | search/category grid | Localized product classification, such as full game or deluxe edition. |
|
|
392
|
+
| `url` | string | No | derived | Store URL; explicitly request it with `--fields id,name,url`. |
|
|
393
|
+
|
|
394
|
+
Use `lookup --batarang`, `lookup --full`, or a detail-oriented `lookup --select` when you need descriptions, publisher, ratings, or content rating. `search` avoids default enrichment to prevent slow N+1 request patterns.
|
|
395
|
+
|
|
396
|
+
## Category Aliases
|
|
397
|
+
|
|
398
|
+
| Alias | UUID | Description |
|
|
399
|
+
| --- | --- | --- |
|
|
400
|
+
| `all-deals` | `3f772501-...` | All deals, hidden catalog |
|
|
401
|
+
| `all-games` | `28c9c2b2-...` | All games |
|
|
402
|
+
| `all-ps5-games` | `d0446d4b-...` | All PS5 games |
|
|
403
|
+
| `all-ps4-games` | `30e3fe35-...` | All PS4 games |
|
|
404
|
+
| `pre-orders` | `3bf499d7-...` | Pre-orders |
|
|
405
|
+
| `add-ons` | `51c9aa7a-...` | Add-ons |
|
|
406
|
+
| `free-to-play` | `4dfd67ab-...` | Free-to-play |
|
|
407
|
+
| `best-sellers` | `132bb05e-...` | Best sellers |
|
|
408
|
+
| `new-games` | `e1699f77-...` | New games |
|
|
409
|
+
| `action` | `298b428c-...` | Action games |
|
|
410
|
+
| `rpg` | `e0b1cde3-...` | Role-playing games |
|
|
411
|
+
| `shooter` | `64ee024b-...` | Shooter games |
|
|
412
|
+
| `sports` | `b86f0f65-...` | Sports games |
|
|
413
|
+
| `racing` | `b78c6346-...` | Racing games |
|
|
414
|
+
| `fighting` | `0f6fc626-...` | Fighting games |
|
|
415
|
+
| `simulation` | `bb42a4e0-...` | Simulation games |
|
|
416
|
+
|
|
417
|
+
The complete list is available through `pstore catalogs` and the exported `BUILTIN_CATALOGS`.
|
|
418
|
+
|
|
419
|
+
## Configuration
|
|
420
|
+
|
|
421
|
+
pstore reads `pstore.config.json` as the default config file.
|
|
422
|
+
|
|
423
|
+
Lookup order:
|
|
424
|
+
|
|
425
|
+
1. `./pstore.config.json`
|
|
426
|
+
2. `./psn-config.json` for legacy compatibility
|
|
427
|
+
3. `~/.config/pstore/config.json`
|
|
428
|
+
4. `~/.config/psn-cli/config.json` for legacy compatibility
|
|
429
|
+
|
|
430
|
+
Default config:
|
|
431
|
+
|
|
432
|
+
```json
|
|
433
|
+
{
|
|
434
|
+
"locale": "zh-hans-HK",
|
|
435
|
+
"format": "text",
|
|
436
|
+
"pageSize": 24,
|
|
437
|
+
"verbose": false,
|
|
438
|
+
"color": true,
|
|
439
|
+
"cacheTtl": {
|
|
440
|
+
"lookup": 300000,
|
|
441
|
+
"search": 120000,
|
|
442
|
+
"category": 120000
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
Fields:
|
|
448
|
+
|
|
449
|
+
- `locale`: default locale.
|
|
450
|
+
- `format`: default output format, `text` or `json`.
|
|
451
|
+
- `pageSize`: default page size for `search`, `category`, and `browse`, from `1` to `100`.
|
|
452
|
+
- `verbose`: whether lookup text output includes timing by default.
|
|
453
|
+
- `color`: whether colored output is enabled by default.
|
|
454
|
+
- `cacheTtl.lookup/search/category`: in-memory cache TTL in milliseconds.
|
|
455
|
+
|
|
456
|
+
Generate a config file:
|
|
457
|
+
|
|
458
|
+
```bash
|
|
459
|
+
pstore init
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
## Technical Notes
|
|
463
|
+
|
|
464
|
+
- Uses PSN GraphQL persisted query APIs without login.
|
|
465
|
+
- Detail lookup combines telemetry, price, rating, upsell, and optional Batarang HTML sources.
|
|
466
|
+
- Product IDs map to PSN `productRetrieve`; the top-level price is the current product/edition CTA price.
|
|
467
|
+
- Concept IDs map to PSN `conceptRetrieve`; the top-level price is the default product CTA price.
|
|
468
|
+
- `conceptRetrieveForUpsellWithCtas` returns multiple editions/products, and pstore preserves each `products[].price`.
|
|
469
|
+
- HTTP timeout is 10 seconds, with 2 default retries. `429` and `5xx` responses back off and respect `Retry-After`.
|
|
470
|
+
- Batch lookup defaults to 3 concurrent requests and can be tuned with `--concurrency`.
|
|
471
|
+
- Process-local TTL caching covers lookup, search, and category calls.
|
|
472
|
+
- Batarang HTML data is extracted from SSR pages without a browser.
|
|
473
|
+
- Product ID results keep the product as the primary object and expose `conceptId`; use `--with-concept` for concept/default product details.
|
|
474
|
+
|
|
475
|
+
## Scripting Tips
|
|
476
|
+
|
|
477
|
+
Prefer JSON output for automation:
|
|
478
|
+
|
|
479
|
+
```bash
|
|
480
|
+
pstore lookup 10005069 --products --title-locales cjk-en --json
|
|
481
|
+
pstore search "Saros" --locale en-US --json --fields id,name,price,url
|
|
482
|
+
pstore browse --window next-thirty-days --sort conceptReleaseDate --order asc --sample 3 --json --fields id,name,price,url
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
Recommendations:
|
|
486
|
+
|
|
487
|
+
- Always use `--json` and inspect `warnings` for partial data source failures.
|
|
488
|
+
- For product details, treat top-level `price` as that product's price. For concept details, treat top-level `price` as the default product price and `products[].price` as each edition's price.
|
|
489
|
+
- Use `--concurrency 2` or `--concurrency 3` for batch lookup to reduce the chance of `429` responses.
|
|
490
|
+
- Use `--title-locales cjk-en` when you need multi-locale titles.
|
|
491
|
+
- Use `--batarang` when you need descriptions, publisher, or content rating.
|
|
492
|
+
- Do not depend on text output order; depend on JSON keys.
|
|
493
|
+
|
|
494
|
+
## Logs
|
|
495
|
+
|
|
496
|
+
API request logs are written to `logs/pstore-YYYY-MM-DD.log`, including request timings and outcomes.
|
|
497
|
+
|
|
498
|
+
## Testing
|
|
499
|
+
|
|
500
|
+
```bash
|
|
501
|
+
bun test
|
|
502
|
+
bunx tsc --noEmit
|
|
503
|
+
bun run live-smoke
|
|
504
|
+
bun run test:live
|
|
505
|
+
bun run test:live:locales
|
|
506
|
+
bun run test:live:full
|
|
507
|
+
PSTORE_SMOKE_LOCALES=zh-hans-HK,en-US,ja-JP,zh-hant-TW,en-TW bun run live-smoke
|
|
508
|
+
PSTORE_SMOKE_FULL=1 bun run live-smoke
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
The test suite covers unit tests, API response fixtures, CLI/package contracts, performance checks, and edge cases. `live-smoke` checks the default locale by default. Use `PSTORE_SMOKE_LOCALES` and `PSTORE_SMOKE_FULL=1` to broaden live coverage when checking for persisted query hash or field shape drift.
|
|
512
|
+
|
|
513
|
+
## License
|
|
514
|
+
|
|
515
|
+
MIT
|