Skip to content
This repository was archived by the owner on Feb 27, 2026. It is now read-only.

Commit ecf8c6c

Browse files
authored
feat: add lodestone endpoints (#1)
* feat: add new columns to registry and enhance character retrieval tests * fix: change npm to pnpm * fix: vitest install node via pnpm * fix: pnpm version mismatch * deps: add @vitest/coverage-v8 for ci-vitest * feat: add remaining selectors * feat: ensure ESM-only and web-worker compatibility * feat: add regex query parameters * docs: add jsdocs for public facing endpoints * chore: run linter * chore: refactor examples * chore: refactor * chore: run linter * chore: major refactor * feat: add remaining endpoint tests
1 parent e89f331 commit ecf8c6c

File tree

14 files changed

+1353
-588
lines changed

14 files changed

+1353
-588
lines changed

.github/workflows/ci-vitest.yml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,18 @@ jobs:
1212
node-version: [20.x, 22.x, 24.x]
1313
steps:
1414
- uses: actions/checkout@v5
15-
- name: Install node ${{ matrix.node-version }}
16-
uses: actions/setup-node@v4
15+
- uses: pnpm/action-setup@v4
16+
with:
17+
run_install: false
18+
- uses: actions/setup-node@v4
1719
with:
1820
node-version: ${{ matrix.node-version }}
21+
cache: pnpm
1922
- name: Install dependencies
20-
run: npm ci
23+
run: pnpm install --frozen-lockfile
2124
- name: Run tests
22-
run: npx vitest --coverage.enabled true
23-
- name: "Report Coverage"
25+
run: pnpm vitest --coverage.enabled true
26+
- name: Report Coverage
2427
if: always()
2528
uses: davelosert/vitest-coverage-report-action@v2
2629
with:

.github/workflows/npm-publish.yml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,17 @@ jobs:
1010
id-token: write
1111
steps:
1212
- uses: actions/checkout@v5
13-
# Setup .npmrc file to publish to npm
13+
- uses: pnpm/action-setup@v4
14+
with:
15+
version: 9
16+
run_install: false
1417
- uses: actions/setup-node@v4
1518
with:
1619
node-version: "20.x"
1720
registry-url: "https://registry.npmjs.org"
18-
- run: npm ci
19-
- run: npm run build
20-
- run: npm publish --provenance --access public
21+
cache: "pnpm"
22+
- run: pnpm install --frozen-lockfile
23+
- run: pnpm build
24+
- run: pnpm publish --provenance --access public
2125
env:
2226
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

.prettierrc

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
{
22
"$schema": "https://json.schemastore.org/prettierrc",
3-
"plugins": ["@trivago/prettier-plugin-sort-imports"],
43
"printWidth": 100,
54
"tabWidth": 2,
65
"useTabs": false,
@@ -11,9 +10,5 @@
1110
"trailingComma": "es5",
1211
"bracketSpacing": true,
1312
"arrowParens": "always",
14-
"endOfLine": "lf",
15-
"importOrder": ["<BUILTIN_MODULES>", "<THIRD_PARTY_MODULES>", "^[./]"],
16-
"importOrderSeparation": false,
17-
"importOrderCaseInsensitive": true,
18-
"importOrderSortSpecifiers": true
13+
"endOfLine": "lf"
1914
}

README.md

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# @miichom/lodestone
22

3+
[![npm](https://img.shields.io/npm/v/@miichom/lodestone.svg)](https://www.npmjs.com/package/@miichom/lodestone)
4+
![node](https://img.shields.io/node/v/@miichom/lodestone)
5+
36
A **minimal, fully typed [Lodestone](https://na.finalfantasyxiv.com/lodestone/) client** for _[Final Fantasy XIV](https://www.finalfantasyxiv.com/)_, providing access to **all endpoints exposed by the Lodestone** through a consistent, schema-driven API.
47

58
Designed for **server-side and worker runtimes**: [Node.js 20+](https://nodejs.org/), [Bun](https://bun.sh/), [Cloudflare Workers](https://developers.cloudflare.com/workers/), and [Web Workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API).
@@ -26,17 +29,13 @@ Most Lodestone scrapers rely on DOM emulation (e.g. [JSDOM](https://github.com/j
2629
npm install @miichom/lodestone
2730
```
2831

29-
## Usage
32+
## Example usage
3033

3134
```ts
3235
import Lodestone from "@miichom/lodestone";
3336

34-
const ls = new Lodestone({ locale: "na" });
35-
```
36-
37-
### Example: characters
37+
const ls = new Lodestone();
3838

39-
```ts
4039
// fetch a character
4140
const character = await ls.character.get(12345678);
4241

@@ -54,6 +53,71 @@ const results = await ls.character.find({
5453

5554
> Additional Lodestone endpoints follow the same API pattern and are exposed through their respective namespaces.
5655
56+
## Options
57+
58+
The `Lodestone` constructor accepts a small set of configuration options.
59+
These apply globally to all endpoints (`character`, `cwls`, `freecompany`, `linkshell`, `pvpteam`).
60+
61+
```ts
62+
const ls = new Lodestone({
63+
locale: "eu",
64+
headers: {
65+
"user-agent": "my-xiv-tool/1.0",
66+
},
67+
});
68+
```
69+
70+
### `locale?: "de" | "eu" | "fr" | "jp" | "na"`
71+
72+
Selects which Lodestone region to target. Defaults to **`"na"`**.
73+
74+
Each locale maps to its own Lodestone instance:
75+
76+
- `na`https://na.finalfantasyxiv.com/lodestone
77+
- `eu`https://eu.finalfantasyxiv.com/lodestone
78+
- `jp`https://jp.finalfantasyxiv.com/lodestone
79+
- `fr`https://fr.finalfantasyxiv.com/lodestone
80+
- `de`https://de.finalfantasyxiv.com/lodestone
81+
82+
All requests made through the client automatically use the selected locale.
83+
84+
### `headers?: Record<string, string>`
85+
86+
Optional request headers applied to every Lodestone request.
87+
88+
- Header keys are normalized to lowercase.
89+
- A default User‑Agent is always prepended:
90+
91+
```
92+
curl/0.1.0 (+https://github.com/miichom/lodestone)
93+
```
94+
95+
If you provide your own `user-agent`, it is appended:
96+
97+
```ts
98+
headers: {
99+
"user-agent": "my-app/1.0",
100+
}
101+
// → curl/0.1.0 (+https://github.com/miichom/lodestone) my-app/1.0
102+
```
103+
104+
For more information on the `User-Agent` header, please see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/User-Agent.
105+
106+
> While optional, providing a custom User‑Agent is recommended for any automated or high‑volume usage.
107+
108+
### Column options (for `get` only)
109+
110+
Some endpoints (notably **characters**) expose additional “column” pages on Lodestone.
111+
You can request them via the `columns` option:
112+
113+
```ts
114+
const profile = await ls.character.get(12345678, {
115+
columns: ["mount", "minion"],
116+
});
117+
```
118+
119+
Columns are fetched lazily and merged into the returned object.
120+
57121
## Attribution
58122

59123
_Final Fantasy XIV_ and all related assets, including data accessed through the [Lodestone](https://na.finalfantasyxiv.com/lodestone/), are the intellectual property of &copy; [SQUARE ENIX CO., LTD.](https://www.square-enix.com/) All rights reserved.

eslint.config.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,26 @@
11
import js from "@eslint/js";
2-
import prettier from "eslint-config-prettier";
32
import { defineConfig } from "eslint/config";
3+
import prettier from "eslint-config-prettier";
4+
import sort from "eslint-plugin-sort";
5+
import unicorn from "eslint-plugin-unicorn";
46
import globals from "globals";
57
import ts from "typescript-eslint";
68

79
export default defineConfig([
810
js.configs.recommended,
911
...ts.configs.recommended,
1012
prettier,
13+
unicorn.configs.recommended,
14+
sort.configs["flat/recommended"],
1115
{ languageOptions: { globals: { ...globals.browser, ...globals.node } } },
1216
{
1317
rules: {
14-
"no-console": "warn",
18+
"@typescript-eslint/consistent-type-imports": "error",
1519
"@typescript-eslint/no-unused-vars": [
1620
"warn",
1721
{ argsIgnorePattern: "^_", varsIgnorePattern: "^_" },
1822
],
19-
"@typescript-eslint/consistent-type-imports": "error",
23+
"no-console": "warn",
2024
},
2125
},
2226
]);

package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,27 @@
2323
"license": "MIT",
2424
"author": "miichom <hello@cammy.xyz> (https://cammy.xyz/)",
2525
"type": "module",
26-
"main": "dist/index.mjs",
26+
"main": "./dist/index.js",
2727
"types": "./dist/index.d.ts",
2828
"scripts": {
2929
"test": "vitest",
3030
"build": "tsup",
3131
"format": "prettier --write .",
32-
"lint": "eslint src --ext .ts",
32+
"lint": "eslint --ext .ts",
3333
"prepublishOnly": "pnpm run build"
3434
},
3535
"dependencies": {
3636
"linkedom": "^0.18.12"
3737
},
3838
"devDependencies": {
3939
"@eslint/js": "^9.39.2",
40-
"@trivago/prettier-plugin-sort-imports": "^6.0.2",
4140
"@tsconfig/node20": "^20.1.8",
4241
"@types/node": "^25.0.9",
42+
"@vitest/coverage-v8": "^4.0.18",
4343
"eslint": "^9.39.2",
4444
"eslint-config-prettier": "^10.1.8",
45+
"eslint-plugin-sort": "^4.0.0",
46+
"eslint-plugin-unicorn": "^62.0.0",
4547
"globals": "^17.0.0",
4648
"jiti": "^2.6.1",
4749
"prettier": "^3.8.0",

0 commit comments

Comments
 (0)