npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@maixio/nintendo-eshop-tool

v0.1.3

Published

Nintendo eShop search and lookup tool with separated regional adapters

Readme

nintendo-eshop-tool

Nintendo eShop 查询工具,使用 Bun + TypeScript 编写。它把不同国家/地区的实现拆成独立 adapter,便于后续新增区域或修复单一区域的网站变化。

支持区域

  • hk: 香港
  • us: 美国
  • jp: 日本
  • gb: 英国
  • au: 澳大利亚

使用

cd nintendo-eshop-tool
bun install

bun run src/cli.ts search jp "ゼルダ" --limit 3
bun run src/cli.ts lookup hk 70010000119464
bun run src/cli.ts appid jp 70010000124937
bun run src/cli.ts resolve hk 0100616025B6C000
bun run src/cli.ts map jp 70010000027618

作为 npm 包安装:

bun add @maixio/nintendo-eshop-tool

作为 SDK 使用

这个项目的 SDK 入口是 src/index.ts。在 Bun / TypeScript 项目里,可以直接从包名或本地源码导入:

import * as NintendoEshop from "@maixio/nintendo-eshop-tool";

const lookupResult = await NintendoEshop.lookupItem("gb", "70010000122206", {
  timeoutMs: 15_000,
});

const mapResult = await NintendoEshop.mapItemRegions("gb", "70070000036431", {
  regions: ["hk", "us", "jp", "au"],
  timeoutMs: 15_000,
  debug: true,
});

const resolverResult = await NintendoEshop.resolveAppTitleIdToRegion(
  "hk",
  "0100616025B6C000",
);

const searchResult = await NintendoEshop.searchItems("jp", "KINGDOM HEARTS", {
  limit: 10,
});

如果不是通过 package name 引用,而是在仓库内直接调用:

import * as NintendoEshop from "./src/index.ts";

推荐使用标准 ESM namespace import,把整个模块作为 NintendoEshop 使用:

  • searchItems(region, query, options?):搜索商品,返回 SearchResponse
  • lookupItem(region, nsuid, options?):按 NSUID 查单个商品,返回 LookupResponse
  • resolveAppTitleIdToRegion(region, appTitleId, options?):用 Nintendo resolver 解析 App Title ID。
  • mapItemRegions(region, nsuid, options?):跨区映射 title / aoc / bundle。
  • getAdapter(region) / adapters:需要直接调用单一区域 adapter 时使用。

为了兼容旧代码,入口仍保留 searchlookupmapNintendoNsuidAcrossRegionsresolveNintendoAppTitleIdToRegionProduct 这些具名导出。也保留 nintendoEshop 对象供偏好对象式 API 的场景使用;新代码建议优先使用 import * as NintendoEshop from "@maixio/nintendo-eshop-tool"。常用类型也从入口导出,例如 NintendoItemNintendoRegionCrossRegionMapResponseCrossRegionTargetLookupOptionsSearchOptions

region 支持 hkusjpgbauoptions.timeoutMs 是单个 HTTP 请求包含重试在内的总预算;NintendoEshop.mapItemRegions 额外支持 regions 限定目标区域。Node.js 项目若不使用 Bun 或 TypeScript runtime,需要先增加编译产物再从 JavaScript 导入。

无参数运行会进入交互模式:

bun run src/cli.ts

Agent Skill 安装

项目内置一个面向 agent 使用的 skill,源文件位于:

skills/nintendo-eshop-tool/

源码仓库开发时,推荐用符号链接安装到目标 agent 的固定 skills 目录,而不是复制文件。这样 skill 会随本项目更新,agent 侧无需重复同步:

mkdir -p "${CODEX_HOME:-$HOME/.codex}/skills"

ln -s "$(pwd)/skills/nintendo-eshop-tool" \
  "${CODEX_HOME:-$HOME/.codex}/skills/nintendo-eshop-tool"

从 npm 包使用时,skill 会和 CLI 一起发布。把包内 skill 链接到目标项目的 agent skills 目录,并通过项目本地 bin 调用 CLI:

bun add -d @maixio/nintendo-eshop-tool
mkdir -p .agents/skills
ln -s "$(pwd)/node_modules/@maixio/nintendo-eshop-tool/skills/nintendo-eshop-tool" \
  .agents/skills/nintendo-eshop-tool

./node_modules/.bin/nintendo-eshop --help

安装后,支持 skills 的 agent 可以通过 $nintendo-eshop-tool 读取该工具的 CLI 使用方式,包括 searchlookupappidresolvemap、跨区 bundle 映射结果解读,以及常见网络不确定性的处理建议。

目录结构

src/
  cli.ts              # CLI 和交互入口
  index.ts            # SDK 风格导出
  cross-region.ts     # title/aoc/bundle 跨区映射
  types.ts            # 公共类型
  regions/            # 各国家/地区独立实现
    hk.ts
    us.ts
    jp.ts
    gb.ts
    au.ts
  shared/             # HTTP、文本清洗、App API、页面解析等共用逻辑
    nsuid.ts          # NSUID 分类、路径和美区 productId 规则

设计原则

  • 区域代码分离:不同地区网站结构不同,避免把所有分支塞进一个大文件。
  • 公共逻辑只放稳定能力:HTTP 超时/重试、文本清洗、ZNEJ App API 解析。
  • CLI 保持薄层:命令行只负责参数、交互和输出 JSON。
  • 默认快速失败:网络请求有超时和有限重试,避免批量任务长时间挂住。

--timeout 是单个 HTTP 请求包含全部重试在内的总预算,而不是每次重试各自拥有一份完整预算。遇到 429/5xx 时会有限重试,并优先遵守服务端的 Retry-After

区域数据源

| 区域 | 主要数据源 | 用途 | | --- | --- | --- | | HK | 香港搜索 API、EC 商品页 | 搜索、详情、bundle 内容 | | US | ZNEJ App API、Algolia、EC/Next.js 页面 | title ID、详情、publisher | | JP | ZNEJ App API、日本公开搜索、store-jp Shopper API | title ID、详情、publisher | | GB | ZNEJ App API、Nintendo Europe Solr、UK Store Catalog(不稳定补充) | title ID、详情、真实商品 URL;实体商店目录仅用于补充部分商品的 appId/硬件信息 | | AU | GB locale 的 ZNEJ App API、AU EC 商品页 | 共享 NSUID 数据、AU 页面详情 |

页面解析的离线样例位于 tests/fixtures/。任天堂页面结构变化时,先更新 fixture 并运行 bun test,再运行联网回归确认真实端点行为。

UK Store Catalog 属于英国实体/零售商店目录,不是完整 eShop 数据源。大量数字版、第三方商品和 bundle 可能返回空结果,因此实现只把它作为 GB lookup 的可选补充源,任何失败或缺失都不会阻断主要查询路径。

Application Title ID 解析

resolve 命令使用 Nintendo eShop 的官方跳转入口解析 Application Title ID 到指定区域的商品页:

bun run src/cli.ts resolve <hk|us|jp|gb|au> <application-title-id>
bun run src/cli.ts resolve 0100616025B6C000 HK

它请求的 resolver URL 形如:

https://ec.nintendo.com/apps/0100616025B6C000/HK

返回内容包含 resolver URL、最终 URL、能从 URL 提取到的 NSUID、商品类型线索或美区 slug。这个入口不是公开文档化 JSON API,主要适合基础游戏 Application Title ID;DLC、bundle、未上架区域、独立区域 ID、Queue-it 拦截等情况都可能无法解析出商品。

跨区映射

map 命令输入一个区域的 NSUID,并尽量映射到其他区域的同款商品:

bun run src/cli.ts map <hk|us|jp|gb|au> <nsuid>

title 和能拿到共享 title/right ID 的 aoc 会走 Application Title ID resolver。bundle 通常没有可直接解析的 Application Title ID,所以会解析包内 bundleItems。映射时优先只使用本体 title 的共享 app/title/right ID 找到目标区本体,并从目标区本体页的 includedBundleItems 或页面线索验证关联 bundle;只有直接路径未命中时,才继续解析 AOC 和执行搜索回退。最后按组件 appId 集合、目标组件 NSUID 和 bundle 结构确认同款。

候选数量较多时,映射内部会先使用 ZNEJ App API 批量获取匹配所需的 bundle identity,再对缺失或不完整的候选执行受限并发的完整 lookup,避免搜索回退瞬间产生大量页面请求。

输出中:

  • appId:只表示 title / aoc 自身的 Application Title ID。
  • bundleComponentAppIds:bundle 内可跨区映射的组件 appId/titleId/rightId。
  • matchedByapp-title-resolverrelated-versionapp-id-searchbridge-title-searchtitle-identity-searchregional-title-searchbundle-contentsrelated-version 表示 resolver 先落到同页旧版/升级包入口,再通过页面版本关系修正到目标商品;bridge-title-search 表示目标区 resolver 未给出可靠 NSUID 时,先借助另一个已解析区域的标题做搜索,再用 appId 校验;title-identity-search 表示区域 appId 分裂且目标商品缺少 appId 时,用商品类型、硬件与拉丁标题 token 做唯一确认;regional-title-search 仅用于区域间 App ID 整组不同的 bundle 组件,并要求唯一标题、商品类型与硬件一致,最终仍需完整 bundle 内容验证。
  • resolved:TypeScript 中可作为判别字段;未解析目标保证包含 reason,bundle 命中保证包含 nsuidcandidateCountcomponentAppIds

注意:部分 bundle 会包含 7009... 这类奖励/消耗型内容,它们通常没有共享 appId;当前实现会保留这些包内项目作为线索,但不把它们作为跨区硬匹配键。

验证

bun run typecheck
bun test
bun run test:network
bun run bench:network
bun run smoke:jp

bun test 默认跳过真实 Nintendo 网络测试,避免普通本地测试受网络或商品上下架影响。bun run test:network 会运行固定 NSUID 的跨区映射和 lookup 回归用例。

bun run bench:network 会顺序运行核心性能样本,验证源商品和预期跨区 NSUID 后,再输出 lookup、普通 title map、bundle map 的平均值、P50、P95 和最大耗时。空结果或错误映射会标记为 ERROR,不会作为快速成功样本污染基准。使用 bun run bench:network --full 可运行所有网络回归样本。默认性能阈值为:

  • lookup:5 秒
  • title/aoc map:10 秒
  • bundle map:20 秒

使用 bun run bench:network --fail-on-threshold 可在超过阈值时返回非零退出码。benchmark 参数同时支持 --kind=map--kind map 两种风格。

排查单次慢查询时使用 --debugmap 会额外输出源 lookup、各目标区组件解析、直接候选发现、批量/完整 hydration、搜索回退等阶段耗时:

bun run src/cli.ts map us 70070000037477 --debug --compact