@sc-db/sdk 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/README.md +33 -0
- package/dist/index.d.ts +130 -0
- package/dist/index.js +273 -0
- package/dist/schema.d.ts +2589 -0
- package/dist/schema.js +5 -0
- package/package.json +41 -0
package/README.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# @sc-db/sdk — TypeScript SDK
|
|
2
|
+
|
|
3
|
+
Typed client for the SCDB API. Types are generated from the API's OpenAPI spec,
|
|
4
|
+
so the SDK always matches the server.
|
|
5
|
+
|
|
6
|
+
```ts
|
|
7
|
+
import { createScdb } from "@sc-db/sdk";
|
|
8
|
+
|
|
9
|
+
const scdb = createScdb({ baseUrl: "http://127.0.0.1:8000" });
|
|
10
|
+
|
|
11
|
+
await scdb.stats();
|
|
12
|
+
await scdb.types();
|
|
13
|
+
await scdb.records({ type: "EntityClassDefinition", name: "gladius", is_main: true });
|
|
14
|
+
await scdb.record(guid); // full record + raw body
|
|
15
|
+
await scdb.refs(guid); // outgoing references
|
|
16
|
+
await scdb.refsIn(guid); // incoming references
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Dev
|
|
20
|
+
```bash
|
|
21
|
+
npm install
|
|
22
|
+
npm run gen # regenerate src/schema.ts from openapi.json
|
|
23
|
+
npm run build # tsc -> dist/
|
|
24
|
+
node example.mjs # smoke test (API must be running)
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Refresh `openapi.json` after API changes:
|
|
28
|
+
```bash
|
|
29
|
+
# from repo root
|
|
30
|
+
uv run python -c "import json; from api.main import app; json.dump(app.openapi(), open('sdk/js/openapi.json','w'), indent=2)"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Other language SDKs will live alongside this one: `sdk/python/`, etc.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import type { paths, components } from "./schema.js";
|
|
2
|
+
export type Stats = components["schemas"]["Stats"];
|
|
3
|
+
export type Meta = components["schemas"]["Meta"];
|
|
4
|
+
export type TypeCount = components["schemas"]["TypeCount"];
|
|
5
|
+
export type RecordSummary = components["schemas"]["RecordSummary"];
|
|
6
|
+
export type ScdbRecord = components["schemas"]["Record"];
|
|
7
|
+
export type RecordPage = components["schemas"]["RecordPage"];
|
|
8
|
+
export type Edge = components["schemas"]["Edge"];
|
|
9
|
+
export type ShipSummary = components["schemas"]["ShipSummary"];
|
|
10
|
+
export type ShipDetail = components["schemas"]["ShipDetail"];
|
|
11
|
+
export type ShipPage = components["schemas"]["ShipPage"];
|
|
12
|
+
export type ItemSummary = components["schemas"]["ItemSummary"];
|
|
13
|
+
export type ItemDetail = components["schemas"]["ItemDetail"];
|
|
14
|
+
export type ItemPage = components["schemas"]["ItemPage"];
|
|
15
|
+
export type ItemCompareRow = components["schemas"]["ItemCompareRow"];
|
|
16
|
+
export type ItemFacets = components["schemas"]["ItemFacets"];
|
|
17
|
+
export type MissionSummary = components["schemas"]["MissionSummary"];
|
|
18
|
+
export type MissionDetail = components["schemas"]["MissionDetail"];
|
|
19
|
+
export type MissionPage = components["schemas"]["MissionPage"];
|
|
20
|
+
export type ContractSummary = components["schemas"]["ContractSummary"];
|
|
21
|
+
export type ContractDetail = components["schemas"]["ContractDetail"];
|
|
22
|
+
export type ContractPage = components["schemas"]["ContractPage"];
|
|
23
|
+
export type BlueprintSummary = components["schemas"]["BlueprintSummary"];
|
|
24
|
+
export type BlueprintDetail = components["schemas"]["BlueprintDetail"];
|
|
25
|
+
export type BlueprintPage = components["schemas"]["BlueprintPage"];
|
|
26
|
+
export type StarmapSummary = components["schemas"]["StarmapSummary"];
|
|
27
|
+
export type StarmapDetail = components["schemas"]["StarmapDetail"];
|
|
28
|
+
export type StarmapPage = components["schemas"]["StarmapPage"];
|
|
29
|
+
export type Location = components["schemas"]["Location"];
|
|
30
|
+
export type LocationPage = components["schemas"]["LocationPage"];
|
|
31
|
+
export type LocalizationEntry = components["schemas"]["LocalizationEntry"];
|
|
32
|
+
export type LocalizationPage = components["schemas"]["LocalizationPage"];
|
|
33
|
+
export type MiningOre = components["schemas"]["MiningOre"];
|
|
34
|
+
export type MiningDeposit = components["schemas"]["MiningDeposit"];
|
|
35
|
+
export type MiningBody = components["schemas"]["MiningBody"];
|
|
36
|
+
export type MiningBodySummary = components["schemas"]["MiningBodySummary"];
|
|
37
|
+
export type MiningProspect = components["schemas"]["MiningProspect"];
|
|
38
|
+
export type CompareQuery = NonNullable<paths["/items/compare"]["get"]["parameters"]["query"]>;
|
|
39
|
+
export type MissionsQuery = NonNullable<paths["/missions"]["get"]["parameters"]["query"]>;
|
|
40
|
+
export type ContractsQuery = NonNullable<paths["/contracts"]["get"]["parameters"]["query"]>;
|
|
41
|
+
export type BlueprintsQuery = NonNullable<paths["/blueprints"]["get"]["parameters"]["query"]>;
|
|
42
|
+
export type StarmapQuery = NonNullable<paths["/starmap"]["get"]["parameters"]["query"]>;
|
|
43
|
+
export type LocationsQuery = NonNullable<paths["/locations"]["get"]["parameters"]["query"]>;
|
|
44
|
+
export type RecordsQuery = NonNullable<paths["/records"]["get"]["parameters"]["query"]>;
|
|
45
|
+
export type LocalizationQuery = NonNullable<paths["/localization"]["get"]["parameters"]["query"]>;
|
|
46
|
+
export type ShipsQuery = NonNullable<paths["/ships"]["get"]["parameters"]["query"]>;
|
|
47
|
+
export type ItemsQuery = NonNullable<paths["/items"]["get"]["parameters"]["query"]>;
|
|
48
|
+
export type ItemFacetsQuery = NonNullable<paths["/items/facets"]["get"]["parameters"]["query"]>;
|
|
49
|
+
export interface ScdbOptions {
|
|
50
|
+
/** API base URL. Default: http://127.0.0.1:8000 */
|
|
51
|
+
baseUrl?: string;
|
|
52
|
+
/** Custom fetch (e.g. for SSR / auth). Default: global fetch. */
|
|
53
|
+
fetch?: typeof fetch;
|
|
54
|
+
/**
|
|
55
|
+
* In-memory cache of GET responses (default: true). The whole DB is immutable
|
|
56
|
+
* within a game patch, so cached responses never go stale by time — instead the
|
|
57
|
+
* cache is flushed automatically the moment the API reports a new build
|
|
58
|
+
* (the `X-SCDB-Version` header changes), or manually via `clearCache()`.
|
|
59
|
+
*/
|
|
60
|
+
cache?: boolean;
|
|
61
|
+
}
|
|
62
|
+
export declare class ScdbError extends Error {
|
|
63
|
+
}
|
|
64
|
+
export declare function createScdb(opts?: ScdbOptions): {
|
|
65
|
+
/** Underlying openapi-fetch client (escape hatch). */
|
|
66
|
+
raw: import("openapi-fetch").Client<paths, `${string}/${string}`>;
|
|
67
|
+
/** Drop every cached GET response (e.g. to force a refetch). */
|
|
68
|
+
clearCache: () => void;
|
|
69
|
+
/** Poll the API for a new game build; if it changed, flush the cache and
|
|
70
|
+
* start busting the edge cache with the new version. Returns true on change.
|
|
71
|
+
* Call it on app mount / window focus to keep clients fresh without any purge. */
|
|
72
|
+
checkVersion: () => Promise<boolean>;
|
|
73
|
+
stats(): Promise<Stats>;
|
|
74
|
+
/** Build provenance — the Star Citizen patch this database was extracted from. */
|
|
75
|
+
meta(): Promise<Meta>;
|
|
76
|
+
types(): Promise<TypeCount[]>;
|
|
77
|
+
records(query?: RecordsQuery): Promise<RecordPage>;
|
|
78
|
+
record(guid: string): Promise<ScdbRecord>;
|
|
79
|
+
/** Records this one points to (outgoing references). */
|
|
80
|
+
refs(guid: string): Promise<Edge[]>;
|
|
81
|
+
/** Records that point to this one (incoming references). */
|
|
82
|
+
refsIn(guid: string): Promise<Edge[]>;
|
|
83
|
+
/** Search the full global.ini table (key/value/q substring, or key prefix). */
|
|
84
|
+
localization(query?: LocalizationQuery): Promise<LocalizationPage>;
|
|
85
|
+
/** Resolve a single localization key (case-insensitive, '@' optional). */
|
|
86
|
+
localizationKey(key: string): Promise<LocalizationEntry>;
|
|
87
|
+
ships(query?: ShipsQuery): Promise<ShipPage>;
|
|
88
|
+
ship(guid: string): Promise<ShipDetail>;
|
|
89
|
+
/** Filter the item catalog. type + size = the compatible set for a slot. */
|
|
90
|
+
items(query?: ItemsQuery): Promise<ItemPage>;
|
|
91
|
+
/** Distinct sizes / subTypes / manufacturers for a category — sidebar facets. */
|
|
92
|
+
itemFacets(query?: ItemFacetsQuery): Promise<ItemFacets>;
|
|
93
|
+
item(className: string): Promise<ItemDetail>;
|
|
94
|
+
/** Items of a type (+size) with comparable stats — for the comparison table. */
|
|
95
|
+
compareItems(query: CompareQuery): Promise<ItemCompareRow[]>;
|
|
96
|
+
missions(query?: MissionsQuery): Promise<MissionPage>;
|
|
97
|
+
mission(guid: string): Promise<MissionDetail>;
|
|
98
|
+
contracts(query?: ContractsQuery): Promise<ContractPage>;
|
|
99
|
+
contractTypes(): Promise<TypeCount[]>;
|
|
100
|
+
contractFactions(): Promise<TypeCount[]>;
|
|
101
|
+
contract(guid: string): Promise<ContractDetail>;
|
|
102
|
+
blueprints(query?: BlueprintsQuery): Promise<BlueprintPage>;
|
|
103
|
+
blueprintCategories(): Promise<TypeCount[]>;
|
|
104
|
+
blueprint(guid: string): Promise<BlueprintDetail>;
|
|
105
|
+
starmap(query?: StarmapQuery): Promise<StarmapPage>;
|
|
106
|
+
starmapSystems(): Promise<TypeCount[]>;
|
|
107
|
+
starmapObject(className: string): Promise<StarmapDetail>;
|
|
108
|
+
locations(query?: LocationsQuery): Promise<LocationPage>;
|
|
109
|
+
locationTypes(query?: {
|
|
110
|
+
body?: string;
|
|
111
|
+
system?: string;
|
|
112
|
+
}): Promise<TypeCount[]>;
|
|
113
|
+
/** Bodies/fields with mineable resources — the mining picker. */
|
|
114
|
+
miningBodies(query?: {
|
|
115
|
+
system?: string;
|
|
116
|
+
}): Promise<MiningBodySummary[]>;
|
|
117
|
+
/** Full mining table for one body, grouped by method (ship/roc/fps). */
|
|
118
|
+
miningBody(body: string): Promise<MiningBody>;
|
|
119
|
+
/** Ore catalog with mining-minigame physics. */
|
|
120
|
+
miningElements(): Promise<MiningOre[]>;
|
|
121
|
+
/** Rock/asteroid compositions — ores per deposit, with probability. */
|
|
122
|
+
miningDeposits(): Promise<MiningDeposit[]>;
|
|
123
|
+
/** Prospecting planner: rank bodies for a wanted ore set (best single spot). */
|
|
124
|
+
miningProspect(ores: string[], opts?: {
|
|
125
|
+
method?: string;
|
|
126
|
+
system?: string;
|
|
127
|
+
limit?: number;
|
|
128
|
+
}): Promise<MiningProspect[]>;
|
|
129
|
+
};
|
|
130
|
+
export type ScdbClient = ReturnType<typeof createScdb>;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SCDB SDK — typed TypeScript client for the SCDB API.
|
|
3
|
+
*
|
|
4
|
+
* import { createScdb } from "@sc-db/sdk";
|
|
5
|
+
* const scdb = createScdb({ baseUrl: "http://127.0.0.1:8000" });
|
|
6
|
+
* const page = await scdb.records({ type: "EntityClassDefinition", name: "gladius" });
|
|
7
|
+
*/
|
|
8
|
+
import createClient from "openapi-fetch";
|
|
9
|
+
export class ScdbError extends Error {
|
|
10
|
+
}
|
|
11
|
+
function unwrap(data, error) {
|
|
12
|
+
if (error !== undefined || data === undefined) {
|
|
13
|
+
throw new ScdbError(`SCDB API error: ${JSON.stringify(error)}`);
|
|
14
|
+
}
|
|
15
|
+
return data;
|
|
16
|
+
}
|
|
17
|
+
export function createScdb(opts = {}) {
|
|
18
|
+
const baseUrl = opts.baseUrl ?? "http://127.0.0.1:8000";
|
|
19
|
+
const baseFetch = opts.fetch ?? globalThis.fetch;
|
|
20
|
+
const useCache = opts.cache !== false;
|
|
21
|
+
// url -> Response (kept un-consumed; every read returns a fresh clone)
|
|
22
|
+
const store = new Map();
|
|
23
|
+
let currentVersion = null;
|
|
24
|
+
let versionProbe = null;
|
|
25
|
+
function clearCache() {
|
|
26
|
+
store.clear();
|
|
27
|
+
}
|
|
28
|
+
// /version is served uncached — it's the cheap "has the game patched?" check.
|
|
29
|
+
async function fetchVersion() {
|
|
30
|
+
try {
|
|
31
|
+
const r = await baseFetch(`${baseUrl}/version`, { headers: { "cache-control": "no-cache" } });
|
|
32
|
+
if (r.ok)
|
|
33
|
+
return (await r.json()).version ?? null;
|
|
34
|
+
}
|
|
35
|
+
catch { /* network — fall through */ }
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
async function ensureVersion() {
|
|
39
|
+
if (currentVersion)
|
|
40
|
+
return currentVersion;
|
|
41
|
+
if (!versionProbe)
|
|
42
|
+
versionProbe = fetchVersion().then((v) => (currentVersion = v));
|
|
43
|
+
return versionProbe;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Re-check the API's build version. If the game has patched, the local cache is
|
|
47
|
+
* dropped and subsequent requests bust the edge (Cloudflare) cache via `?v=` —
|
|
48
|
+
* so data refreshes with no manual purge. Returns true if the version changed.
|
|
49
|
+
*/
|
|
50
|
+
async function checkVersion() {
|
|
51
|
+
const v = await fetchVersion();
|
|
52
|
+
if (v && v !== currentVersion) {
|
|
53
|
+
currentVersion = v;
|
|
54
|
+
versionProbe = Promise.resolve(v);
|
|
55
|
+
store.clear();
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
const cachingFetch = async (input, init) => {
|
|
61
|
+
const isReq = typeof input === "object" && input instanceof Request;
|
|
62
|
+
const method = (init?.method ?? (isReq ? input.method : "GET")).toUpperCase();
|
|
63
|
+
let url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
64
|
+
if (method !== "GET")
|
|
65
|
+
return baseFetch(input, init);
|
|
66
|
+
// tag the request with the current build → a new patch = a new cache key,
|
|
67
|
+
// both in this Map and at the CDN edge (Cloudflare), so nothing goes stale.
|
|
68
|
+
const v = await ensureVersion();
|
|
69
|
+
if (v)
|
|
70
|
+
url += (url.includes("?") ? "&" : "?") + "v=" + encodeURIComponent(v);
|
|
71
|
+
const hit = store.get(url);
|
|
72
|
+
if (hit)
|
|
73
|
+
return hit.clone();
|
|
74
|
+
const res = await baseFetch(isReq ? new Request(url, input) : url, isReq ? undefined : init);
|
|
75
|
+
if (res.ok)
|
|
76
|
+
store.set(url, res.clone());
|
|
77
|
+
return res;
|
|
78
|
+
};
|
|
79
|
+
const client = createClient({
|
|
80
|
+
baseUrl,
|
|
81
|
+
fetch: useCache ? cachingFetch : baseFetch,
|
|
82
|
+
});
|
|
83
|
+
return {
|
|
84
|
+
/** Underlying openapi-fetch client (escape hatch). */
|
|
85
|
+
raw: client,
|
|
86
|
+
/** Drop every cached GET response (e.g. to force a refetch). */
|
|
87
|
+
clearCache,
|
|
88
|
+
/** Poll the API for a new game build; if it changed, flush the cache and
|
|
89
|
+
* start busting the edge cache with the new version. Returns true on change.
|
|
90
|
+
* Call it on app mount / window focus to keep clients fresh without any purge. */
|
|
91
|
+
checkVersion,
|
|
92
|
+
async stats() {
|
|
93
|
+
const { data, error } = await client.GET("/stats");
|
|
94
|
+
return unwrap(data, error);
|
|
95
|
+
},
|
|
96
|
+
/** Build provenance — the Star Citizen patch this database was extracted from. */
|
|
97
|
+
async meta() {
|
|
98
|
+
const { data, error } = await client.GET("/meta");
|
|
99
|
+
return unwrap(data, error);
|
|
100
|
+
},
|
|
101
|
+
async types() {
|
|
102
|
+
const { data, error } = await client.GET("/types");
|
|
103
|
+
return unwrap(data, error);
|
|
104
|
+
},
|
|
105
|
+
async records(query = {}) {
|
|
106
|
+
const { data, error } = await client.GET("/records", { params: { query } });
|
|
107
|
+
return unwrap(data, error);
|
|
108
|
+
},
|
|
109
|
+
async record(guid) {
|
|
110
|
+
const { data, error } = await client.GET("/records/{guid}", {
|
|
111
|
+
params: { path: { guid } },
|
|
112
|
+
});
|
|
113
|
+
return unwrap(data, error);
|
|
114
|
+
},
|
|
115
|
+
/** Records this one points to (outgoing references). */
|
|
116
|
+
async refs(guid) {
|
|
117
|
+
const { data, error } = await client.GET("/records/{guid}/refs", {
|
|
118
|
+
params: { path: { guid } },
|
|
119
|
+
});
|
|
120
|
+
return unwrap(data, error);
|
|
121
|
+
},
|
|
122
|
+
/** Records that point to this one (incoming references). */
|
|
123
|
+
async refsIn(guid) {
|
|
124
|
+
const { data, error } = await client.GET("/records/{guid}/refs-in", {
|
|
125
|
+
params: { path: { guid } },
|
|
126
|
+
});
|
|
127
|
+
return unwrap(data, error);
|
|
128
|
+
},
|
|
129
|
+
// ── localization (raw global.ini key→value table) ───────────────────────
|
|
130
|
+
/** Search the full global.ini table (key/value/q substring, or key prefix). */
|
|
131
|
+
async localization(query = {}) {
|
|
132
|
+
const { data, error } = await client.GET("/localization", { params: { query } });
|
|
133
|
+
return unwrap(data, error);
|
|
134
|
+
},
|
|
135
|
+
/** Resolve a single localization key (case-insensitive, '@' optional). */
|
|
136
|
+
async localizationKey(key) {
|
|
137
|
+
const { data, error } = await client.GET("/localization/{key}", {
|
|
138
|
+
params: { path: { key } },
|
|
139
|
+
});
|
|
140
|
+
return unwrap(data, error);
|
|
141
|
+
},
|
|
142
|
+
// ── layer 2: ships ──────────────────────────────────────────────────────
|
|
143
|
+
async ships(query = {}) {
|
|
144
|
+
const { data, error } = await client.GET("/ships", { params: { query } });
|
|
145
|
+
return unwrap(data, error);
|
|
146
|
+
},
|
|
147
|
+
async ship(guid) {
|
|
148
|
+
const { data, error } = await client.GET("/ships/{guid}", {
|
|
149
|
+
params: { path: { guid } },
|
|
150
|
+
});
|
|
151
|
+
return unwrap(data, error);
|
|
152
|
+
},
|
|
153
|
+
// ── layer 2: items (catalog + compatibility) ────────────────────────────
|
|
154
|
+
/** Filter the item catalog. type + size = the compatible set for a slot. */
|
|
155
|
+
async items(query = {}) {
|
|
156
|
+
const { data, error } = await client.GET("/items", { params: { query } });
|
|
157
|
+
return unwrap(data, error);
|
|
158
|
+
},
|
|
159
|
+
/** Distinct sizes / subTypes / manufacturers for a category — sidebar facets. */
|
|
160
|
+
async itemFacets(query = {}) {
|
|
161
|
+
const { data, error } = await client.GET("/items/facets", { params: { query } });
|
|
162
|
+
return unwrap(data, error);
|
|
163
|
+
},
|
|
164
|
+
async item(className) {
|
|
165
|
+
const { data, error } = await client.GET("/items/{className}", {
|
|
166
|
+
params: { path: { className } },
|
|
167
|
+
});
|
|
168
|
+
return unwrap(data, error);
|
|
169
|
+
},
|
|
170
|
+
/** Items of a type (+size) with comparable stats — for the comparison table. */
|
|
171
|
+
async compareItems(query) {
|
|
172
|
+
const { data, error } = await client.GET("/items/compare", { params: { query } });
|
|
173
|
+
return unwrap(data, error);
|
|
174
|
+
},
|
|
175
|
+
// ── layer 2: missions ───────────────────────────────────────────────────
|
|
176
|
+
async missions(query = {}) {
|
|
177
|
+
const { data, error } = await client.GET("/missions", { params: { query } });
|
|
178
|
+
return unwrap(data, error);
|
|
179
|
+
},
|
|
180
|
+
async mission(guid) {
|
|
181
|
+
const { data, error } = await client.GET("/missions/{guid}", {
|
|
182
|
+
params: { path: { guid } },
|
|
183
|
+
});
|
|
184
|
+
return unwrap(data, error);
|
|
185
|
+
},
|
|
186
|
+
// ── layer 2: contracts (real procedural missions) ───────────────────────
|
|
187
|
+
async contracts(query = {}) {
|
|
188
|
+
const { data, error } = await client.GET("/contracts", { params: { query } });
|
|
189
|
+
return unwrap(data, error);
|
|
190
|
+
},
|
|
191
|
+
async contractTypes() {
|
|
192
|
+
const { data, error } = await client.GET("/contracts/types");
|
|
193
|
+
return unwrap(data, error);
|
|
194
|
+
},
|
|
195
|
+
async contractFactions() {
|
|
196
|
+
const { data, error } = await client.GET("/contracts/factions");
|
|
197
|
+
return unwrap(data, error);
|
|
198
|
+
},
|
|
199
|
+
async contract(guid) {
|
|
200
|
+
const { data, error } = await client.GET("/contracts/{guid}", {
|
|
201
|
+
params: { path: { guid } },
|
|
202
|
+
});
|
|
203
|
+
return unwrap(data, error);
|
|
204
|
+
},
|
|
205
|
+
// ── layer 2: blueprints (crafting) ──────────────────────────────────────
|
|
206
|
+
async blueprints(query = {}) {
|
|
207
|
+
const { data, error } = await client.GET("/blueprints", { params: { query } });
|
|
208
|
+
return unwrap(data, error);
|
|
209
|
+
},
|
|
210
|
+
async blueprintCategories() {
|
|
211
|
+
const { data, error } = await client.GET("/blueprints/categories");
|
|
212
|
+
return unwrap(data, error);
|
|
213
|
+
},
|
|
214
|
+
async blueprint(guid) {
|
|
215
|
+
const { data, error } = await client.GET("/blueprints/{guid}", {
|
|
216
|
+
params: { path: { guid } },
|
|
217
|
+
});
|
|
218
|
+
return unwrap(data, error);
|
|
219
|
+
},
|
|
220
|
+
// ── layer 2: starmap ────────────────────────────────────────────────────
|
|
221
|
+
async starmap(query = {}) {
|
|
222
|
+
const { data, error } = await client.GET("/starmap", { params: { query } });
|
|
223
|
+
return unwrap(data, error);
|
|
224
|
+
},
|
|
225
|
+
async starmapSystems() {
|
|
226
|
+
const { data, error } = await client.GET("/starmap/systems");
|
|
227
|
+
return unwrap(data, error);
|
|
228
|
+
},
|
|
229
|
+
async starmapObject(className) {
|
|
230
|
+
const { data, error } = await client.GET("/starmap/{className}", {
|
|
231
|
+
params: { path: { className } },
|
|
232
|
+
});
|
|
233
|
+
return unwrap(data, error);
|
|
234
|
+
},
|
|
235
|
+
// ── layer 2: in-world locations (resource/derelict/outpost… from socpaks) ──
|
|
236
|
+
async locations(query = {}) {
|
|
237
|
+
const { data, error } = await client.GET("/locations", { params: { query } });
|
|
238
|
+
return unwrap(data, error);
|
|
239
|
+
},
|
|
240
|
+
async locationTypes(query = {}) {
|
|
241
|
+
const { data, error } = await client.GET("/locations/types", { params: { query } });
|
|
242
|
+
return unwrap(data, error);
|
|
243
|
+
},
|
|
244
|
+
// ── layer 2: mining (what's mineable where, with probabilities) ──────────
|
|
245
|
+
/** Bodies/fields with mineable resources — the mining picker. */
|
|
246
|
+
async miningBodies(query = {}) {
|
|
247
|
+
const { data, error } = await client.GET("/mining/bodies", { params: { query } });
|
|
248
|
+
return unwrap(data, error);
|
|
249
|
+
},
|
|
250
|
+
/** Full mining table for one body, grouped by method (ship/roc/fps). */
|
|
251
|
+
async miningBody(body) {
|
|
252
|
+
const { data, error } = await client.GET("/mining/{body}", { params: { path: { body } } });
|
|
253
|
+
return unwrap(data, error);
|
|
254
|
+
},
|
|
255
|
+
/** Ore catalog with mining-minigame physics. */
|
|
256
|
+
async miningElements() {
|
|
257
|
+
const { data, error } = await client.GET("/mining/elements");
|
|
258
|
+
return unwrap(data, error);
|
|
259
|
+
},
|
|
260
|
+
/** Rock/asteroid compositions — ores per deposit, with probability. */
|
|
261
|
+
async miningDeposits() {
|
|
262
|
+
const { data, error } = await client.GET("/mining/deposits");
|
|
263
|
+
return unwrap(data, error);
|
|
264
|
+
},
|
|
265
|
+
/** Prospecting planner: rank bodies for a wanted ore set (best single spot). */
|
|
266
|
+
async miningProspect(ores, opts = {}) {
|
|
267
|
+
const { data, error } = await client.GET("/mining/prospect", {
|
|
268
|
+
params: { query: { ores: ores.join(","), ...opts } },
|
|
269
|
+
});
|
|
270
|
+
return unwrap(data, error);
|
|
271
|
+
},
|
|
272
|
+
};
|
|
273
|
+
}
|