@goable-io/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 +121 -0
- package/dist/client.d.ts +52 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +134 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +40 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +57 -0
- package/dist/errors.js.map +1 -0
- package/dist/generated/api.d.ts +1051 -0
- package/dist/generated/api.d.ts.map +1 -0
- package/dist/generated/api.js +7 -0
- package/dist/generated/api.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +63 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/package.json +57 -0
- package/src/client.ts +206 -0
- package/src/errors.ts +75 -0
- package/src/generated/api.ts +1051 -0
- package/src/index.ts +19 -0
- package/src/types.ts +77 -0
package/README.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# @goable-io/sdk
|
|
2
|
+
|
|
3
|
+
TypeScript client for the [Goable](https://goable.io) API — 0-100 suitability
|
|
4
|
+
scoring for outdoor activities (water, snow, air, land) from real-time weather
|
|
5
|
+
and multi-domain physics.
|
|
6
|
+
|
|
7
|
+
> **Status: v0.1, publish-ready (not yet on npm).** Thin, typed transport over
|
|
8
|
+
> the public tenant-facing REST surface. Zero runtime dependencies. Works in
|
|
9
|
+
> Node ≥18 and modern browser/edge runtimes (uses the global `fetch`).
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @goable-io/sdk # once published
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quickstart
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { GoableClient } from "@goable-io/sdk"
|
|
21
|
+
|
|
22
|
+
const goable = new GoableClient({ apiKey: process.env.GOABLE_API_KEY! })
|
|
23
|
+
|
|
24
|
+
const result = await goable.score({
|
|
25
|
+
activity: "kitesurfing",
|
|
26
|
+
location: { lat: 43.7, lng: 7.27 },
|
|
27
|
+
window: { from: "2026-06-01T06:00:00Z", to: "2026-06-01T18:00:00Z" },
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
result.score // 0-100
|
|
31
|
+
result.verdict // "unsafe" | "poor" | "marginal" | "fair" | "favorable" | "excellent"
|
|
32
|
+
result.confidence
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Configuration
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
new GoableClient({
|
|
39
|
+
apiKey: "…", // required — sent as Authorization: Bearer
|
|
40
|
+
baseUrl: "https://api.goable.io", // default
|
|
41
|
+
timeoutMs: 30_000, // default; 0 disables
|
|
42
|
+
fetch: customFetch, // default globalThis.fetch (inject for Node <18 / tests)
|
|
43
|
+
})
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Methods
|
|
47
|
+
|
|
48
|
+
| Method | Endpoint | Notes |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| `score(input)` | `POST /v1/score` | `ensemble: true` → probabilistic (Pro+) |
|
|
51
|
+
| `scoreSeries(input)` | `POST /v1/score/series` | per-step over a window |
|
|
52
|
+
| `scoreMulti(input)` | `POST /v1/score/multi` | many activities, one location |
|
|
53
|
+
| `scoreHistorical(input)` | `POST /v1/score/historical` | climatology percentiles (Pro+) |
|
|
54
|
+
| `scorePortfolio(input)` | `POST /v1/score/portfolio` | multi-spot joint variance |
|
|
55
|
+
| `explainCounterfactual(input)` | `POST /v1/score/explain-counterfactual` | binding constraint, sensitivities, best window/spot |
|
|
56
|
+
| `decision(input)` | `POST /v1/decision` | personalized go/no-go (Pro+) |
|
|
57
|
+
| `deleteUserData(pseudonym)` | `DELETE /v1/decision/user-data/:p` | GDPR erasure; returns receipt headers |
|
|
58
|
+
| `explain(input)` / `briefing(input)` | `POST /v1/intelligence/*` | LLM narratives (Pro+) |
|
|
59
|
+
| `projections(input)` | `POST /v1/projections` | climate-decadal (Scale) |
|
|
60
|
+
| `quote(input)` | `POST /v1/underwriting/quote` | parametric premium (Scale) |
|
|
61
|
+
| `health()` | `GET /v1/health` | liveness |
|
|
62
|
+
|
|
63
|
+
## Errors
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
import { GoableApiError, GoableNetworkError } from "@goable-io/sdk"
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
await goable.score({ activity: "kitesurfing", location: { lat: 43.7, lng: 7.27 }, ensemble: true })
|
|
70
|
+
} catch (err) {
|
|
71
|
+
if (err instanceof GoableApiError) {
|
|
72
|
+
err.status // 402
|
|
73
|
+
err.code // "PAYMENT_REQUIRED"
|
|
74
|
+
err.issues // Zod issues on 422 VALIDATION_ERROR
|
|
75
|
+
err.detail // free-form context (e.g. plan info)
|
|
76
|
+
} else if (err instanceof GoableNetworkError) {
|
|
77
|
+
err.kind // "timeout" | "network" | "parse"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Browser use
|
|
83
|
+
|
|
84
|
+
The client runs in the browser, but **API keys are secrets** — prefer
|
|
85
|
+
server-side use. For direct browser calls the API's CORS allowlist must
|
|
86
|
+
include your origin (contact Goable to allowlist it).
|
|
87
|
+
|
|
88
|
+
## Types are generated from the API contract
|
|
89
|
+
|
|
90
|
+
The request/response types are **generated** from the API's OpenAPI
|
|
91
|
+
document (`apps/api/src/openapi/spec.ts`) via
|
|
92
|
+
[`openapi-typescript`](https://github.com/openapi-ts/openapi-typescript) —
|
|
93
|
+
they are never hand-authored, so they can't drift from the server. When the
|
|
94
|
+
API contract changes, a maintainer runs:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
pnpm --filter @goable-io/sdk gen
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
which rewrites `src/generated/api.ts` + `openapi.json`. A test
|
|
101
|
+
(`generatedFresh.test.ts`) fails in CI if the committed output is stale, so
|
|
102
|
+
the types are always in lock-step with the contract. Adding a brand-new
|
|
103
|
+
endpoint is the only manual step (a new client method).
|
|
104
|
+
|
|
105
|
+
Request types are precise (the API rejects unknown fields). Some response
|
|
106
|
+
bodies are modelled as open objects where the endpoint returns a rich,
|
|
107
|
+
documented payload — the full wire payload is always returned, and these
|
|
108
|
+
tighten automatically as the OpenAPI response schemas are enriched.
|
|
109
|
+
|
|
110
|
+
## Release (maintainers)
|
|
111
|
+
|
|
112
|
+
Publishing is automated by `.github/workflows/sdk-release.yml` (on changes
|
|
113
|
+
to `packages/sdk/**` on `main`): it builds, runs the freshness guard +
|
|
114
|
+
tests, resolves the next version, prints `npm pack --dry-run` as a leak
|
|
115
|
+
check, and `pnpm publish --access public` using the org `NPM_TOKEN`. The
|
|
116
|
+
private engine never leaves the repo — only this package's `files` are
|
|
117
|
+
published. `publishConfig` repoints `main`/`types`/`exports` at `dist/` at
|
|
118
|
+
publish time, so in-repo development keeps using the TS sources.
|
|
119
|
+
|
|
120
|
+
> No npm provenance: it requires a public source repo, and the SDK source
|
|
121
|
+
> stays in this private monorepo by design.
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GoableClient — thin typed transport over the public Goable REST API.
|
|
3
|
+
* No caching, no business logic; one `request<T>` powers every method.
|
|
4
|
+
*/
|
|
5
|
+
import type { BriefingRequest, BriefingResponse, CounterfactualRequest, CounterfactualResponse, DecisionRequest, DecisionResponse, DeleteUserDataResult, ExplainRequest, ExplainResponse, HealthResponse, ProjectionsRequest, ProjectionsResponse, QuoteRequest, QuoteResponse, ScoreHistoricalRequest, ScoreHistoricalResponse, ScoreMultiRequest, ScoreMultiResponse, ScorePortfolioRequest, ScorePortfolioResponse, ScoreRequest, ScoreResponse, ScoreSeriesRequest, ScoreSeriesResponse } from "./types.js";
|
|
6
|
+
export type FetchLike = (input: string, init?: {
|
|
7
|
+
method?: string;
|
|
8
|
+
headers?: Record<string, string>;
|
|
9
|
+
body?: string;
|
|
10
|
+
signal?: AbortSignal;
|
|
11
|
+
}) => Promise<{
|
|
12
|
+
ok: boolean;
|
|
13
|
+
status: number;
|
|
14
|
+
headers: {
|
|
15
|
+
get(name: string): string | null;
|
|
16
|
+
};
|
|
17
|
+
text(): Promise<string>;
|
|
18
|
+
}>;
|
|
19
|
+
export interface GoableClientOptions {
|
|
20
|
+
/** Tenant API key — sent as `Authorization: Bearer <apiKey>`. */
|
|
21
|
+
apiKey: string;
|
|
22
|
+
/** Base URL. Default https://api.goable.io */
|
|
23
|
+
baseUrl?: string;
|
|
24
|
+
/** Injected fetch (tests, non-global-fetch runtimes). Default globalThis.fetch. */
|
|
25
|
+
fetch?: FetchLike;
|
|
26
|
+
/** Per-request timeout in ms. Default 30000. 0 disables. */
|
|
27
|
+
timeoutMs?: number;
|
|
28
|
+
}
|
|
29
|
+
export declare class GoableClient {
|
|
30
|
+
private readonly apiKey;
|
|
31
|
+
private readonly baseUrl;
|
|
32
|
+
private readonly fetchImpl;
|
|
33
|
+
private readonly timeoutMs;
|
|
34
|
+
constructor(options: GoableClientOptions);
|
|
35
|
+
health(): Promise<HealthResponse>;
|
|
36
|
+
score(input: ScoreRequest): Promise<ScoreResponse>;
|
|
37
|
+
scoreSeries(input: ScoreSeriesRequest): Promise<ScoreSeriesResponse>;
|
|
38
|
+
scoreMulti(input: ScoreMultiRequest): Promise<ScoreMultiResponse>;
|
|
39
|
+
scoreHistorical(input: ScoreHistoricalRequest): Promise<ScoreHistoricalResponse>;
|
|
40
|
+
scorePortfolio(input: ScorePortfolioRequest): Promise<ScorePortfolioResponse>;
|
|
41
|
+
explainCounterfactual(input: CounterfactualRequest): Promise<CounterfactualResponse>;
|
|
42
|
+
decision(input: DecisionRequest): Promise<DecisionResponse>;
|
|
43
|
+
explain(input: ExplainRequest): Promise<ExplainResponse>;
|
|
44
|
+
briefing(input: BriefingRequest): Promise<BriefingResponse>;
|
|
45
|
+
projections(input: ProjectionsRequest): Promise<ProjectionsResponse>;
|
|
46
|
+
quote(input: QuoteRequest): Promise<QuoteResponse>;
|
|
47
|
+
/** GDPR Art. 17 erasure. Surfaces the receipt headers from a 204. */
|
|
48
|
+
deleteUserData(pseudonym: string): Promise<DeleteUserDataResult>;
|
|
49
|
+
private request;
|
|
50
|
+
private rawRequest;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,EACtB,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,EACZ,aAAa,EACb,sBAAsB,EACtB,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,YAAY,CAAA;AAEnB,MAAM,MAAM,SAAS,GAAG,CACtB,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE;IACL,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB,KACE,OAAO,CAAC;IACX,EAAE,EAAE,OAAO,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE;QAAE,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;KAAE,CAAA;IAC7C,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;CACxB,CAAC,CAAA;AAEF,MAAM,WAAW,mBAAmB;IAClC,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAA;IACd,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,mFAAmF;IACnF,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAKD,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;gBAEtB,OAAO,EAAE,mBAAmB;IAaxC,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC;IAIjC,KAAK,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IAIlD,WAAW,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAIpE,UAAU,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAIjE,eAAe,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAIhF,cAAc,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAI7E,qBAAqB,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAIpF,QAAQ,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAI3D,OAAO,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;IAIxD,QAAQ,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAI3D,WAAW,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAIpE,KAAK,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IAIlD,qEAAqE;IAC/D,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;YAsBxD,OAAO;YAOP,UAAU;CA+BzB"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GoableClient — thin typed transport over the public Goable REST API.
|
|
3
|
+
* No caching, no business logic; one `request<T>` powers every method.
|
|
4
|
+
*/
|
|
5
|
+
import { GoableNetworkError, toApiError } from "./errors.js";
|
|
6
|
+
const DEFAULT_BASE_URL = "https://api.goable.io";
|
|
7
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
8
|
+
export class GoableClient {
|
|
9
|
+
apiKey;
|
|
10
|
+
baseUrl;
|
|
11
|
+
fetchImpl;
|
|
12
|
+
timeoutMs;
|
|
13
|
+
constructor(options) {
|
|
14
|
+
if (!options.apiKey)
|
|
15
|
+
throw new Error("GoableClient requires an apiKey");
|
|
16
|
+
this.apiKey = options.apiKey;
|
|
17
|
+
this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
18
|
+
const f = options.fetch ?? globalThis.fetch;
|
|
19
|
+
if (!f) {
|
|
20
|
+
throw new Error("No fetch available — pass options.fetch (Node < 18 or non-fetch runtime)");
|
|
21
|
+
}
|
|
22
|
+
this.fetchImpl = f;
|
|
23
|
+
this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
24
|
+
}
|
|
25
|
+
// ── public methods ──────────────────────────────────────────────────────
|
|
26
|
+
health() {
|
|
27
|
+
return this.request("GET", "/v1/health");
|
|
28
|
+
}
|
|
29
|
+
score(input) {
|
|
30
|
+
return this.request("POST", "/v1/score", input);
|
|
31
|
+
}
|
|
32
|
+
scoreSeries(input) {
|
|
33
|
+
return this.request("POST", "/v1/score/series", input);
|
|
34
|
+
}
|
|
35
|
+
scoreMulti(input) {
|
|
36
|
+
return this.request("POST", "/v1/score/multi", input);
|
|
37
|
+
}
|
|
38
|
+
scoreHistorical(input) {
|
|
39
|
+
return this.request("POST", "/v1/score/historical", input);
|
|
40
|
+
}
|
|
41
|
+
scorePortfolio(input) {
|
|
42
|
+
return this.request("POST", "/v1/score/portfolio", input);
|
|
43
|
+
}
|
|
44
|
+
explainCounterfactual(input) {
|
|
45
|
+
return this.request("POST", "/v1/score/explain-counterfactual", input);
|
|
46
|
+
}
|
|
47
|
+
decision(input) {
|
|
48
|
+
return this.request("POST", "/v1/decision", input);
|
|
49
|
+
}
|
|
50
|
+
explain(input) {
|
|
51
|
+
return this.request("POST", "/v1/intelligence/explain", input);
|
|
52
|
+
}
|
|
53
|
+
briefing(input) {
|
|
54
|
+
return this.request("POST", "/v1/intelligence/briefing", input);
|
|
55
|
+
}
|
|
56
|
+
projections(input) {
|
|
57
|
+
return this.request("POST", "/v1/projections", input);
|
|
58
|
+
}
|
|
59
|
+
quote(input) {
|
|
60
|
+
return this.request("POST", "/v1/underwriting/quote", input);
|
|
61
|
+
}
|
|
62
|
+
/** GDPR Art. 17 erasure. Surfaces the receipt headers from a 204. */
|
|
63
|
+
async deleteUserData(pseudonym) {
|
|
64
|
+
const res = await this.rawRequest("DELETE", `/v1/decision/user-data/${encodeURIComponent(pseudonym)}`);
|
|
65
|
+
if (!res.ok) {
|
|
66
|
+
throw toApiError(res.status, await safeJson(res));
|
|
67
|
+
}
|
|
68
|
+
const intHeader = (name) => {
|
|
69
|
+
const v = res.headers.get(name);
|
|
70
|
+
const n = v === null ? Number.NaN : Number(v);
|
|
71
|
+
return Number.isFinite(n) ? n : null;
|
|
72
|
+
};
|
|
73
|
+
return {
|
|
74
|
+
status: res.status,
|
|
75
|
+
anonymizedRows: intHeader("X-Anonymized-Rows"),
|
|
76
|
+
anonymizedDecisionRuns: intHeader("X-Anonymized-Decision-Runs"),
|
|
77
|
+
receipt: res.headers.get("X-Receipt"),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
// ── transport ─────────────────────────────────────────────────────────────
|
|
81
|
+
async request(method, path, body) {
|
|
82
|
+
const res = await this.rawRequest(method, path, body);
|
|
83
|
+
const parsed = await safeJson(res);
|
|
84
|
+
if (!res.ok)
|
|
85
|
+
throw toApiError(res.status, parsed);
|
|
86
|
+
return parsed;
|
|
87
|
+
}
|
|
88
|
+
async rawRequest(method, path, body) {
|
|
89
|
+
const headers = {
|
|
90
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
91
|
+
Accept: "application/json",
|
|
92
|
+
};
|
|
93
|
+
if (body !== undefined)
|
|
94
|
+
headers["Content-Type"] = "application/json";
|
|
95
|
+
const controller = this.timeoutMs > 0 ? new AbortController() : undefined;
|
|
96
|
+
const timer = controller && this.timeoutMs > 0
|
|
97
|
+
? setTimeout(() => controller.abort(), this.timeoutMs)
|
|
98
|
+
: undefined;
|
|
99
|
+
try {
|
|
100
|
+
return await this.fetchImpl(`${this.baseUrl}${path}`, {
|
|
101
|
+
method,
|
|
102
|
+
headers,
|
|
103
|
+
...(body !== undefined && { body: JSON.stringify(body) }),
|
|
104
|
+
...(controller && { signal: controller.signal }),
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
const aborted = err?.name === "AbortError";
|
|
109
|
+
throw new GoableNetworkError(aborted ? `Request timed out after ${this.timeoutMs}ms` : `Network request failed: ${path}`, aborted ? "timeout" : "network", err);
|
|
110
|
+
}
|
|
111
|
+
finally {
|
|
112
|
+
if (timer)
|
|
113
|
+
clearTimeout(timer);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
async function safeJson(res) {
|
|
118
|
+
let text;
|
|
119
|
+
try {
|
|
120
|
+
text = await res.text();
|
|
121
|
+
}
|
|
122
|
+
catch (err) {
|
|
123
|
+
throw new GoableNetworkError("Failed to read response body", "parse", err);
|
|
124
|
+
}
|
|
125
|
+
if (text === "")
|
|
126
|
+
return undefined;
|
|
127
|
+
try {
|
|
128
|
+
return JSON.parse(text);
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
return text;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK error model. Two distinct failure modes:
|
|
3
|
+
* - GoableApiError : the API returned a non-2xx response. Maps the
|
|
4
|
+
* canonical flat error envelope
|
|
5
|
+
* ({ error, message?, issues?, detail? }).
|
|
6
|
+
* - GoableNetworkError: the request never produced an HTTP response
|
|
7
|
+
* (DNS, connection, abort/timeout, JSON parse).
|
|
8
|
+
*/
|
|
9
|
+
export interface ZodIssueLike {
|
|
10
|
+
code?: string;
|
|
11
|
+
path?: Array<string | number>;
|
|
12
|
+
message?: string;
|
|
13
|
+
[k: string]: unknown;
|
|
14
|
+
}
|
|
15
|
+
export declare class GoableApiError extends Error {
|
|
16
|
+
readonly name = "GoableApiError";
|
|
17
|
+
/** HTTP status code. */
|
|
18
|
+
readonly status: number;
|
|
19
|
+
/** Machine-readable code from the `error` field (e.g. "PAYMENT_REQUIRED"). */
|
|
20
|
+
readonly code: string;
|
|
21
|
+
/** Zod validation issues, present on 422 VALIDATION_ERROR responses. */
|
|
22
|
+
readonly issues?: ZodIssueLike[];
|
|
23
|
+
/** Free-form extra context (e.g. plan info, quote id). */
|
|
24
|
+
readonly detail?: Record<string, unknown>;
|
|
25
|
+
constructor(status: number, code: string, message?: string, extra?: {
|
|
26
|
+
issues?: ZodIssueLike[];
|
|
27
|
+
detail?: Record<string, unknown>;
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
export declare class GoableNetworkError extends Error {
|
|
31
|
+
readonly name = "GoableNetworkError";
|
|
32
|
+
/** "timeout" when the request was aborted by the configured timeout. */
|
|
33
|
+
readonly kind: "timeout" | "network" | "parse";
|
|
34
|
+
readonly cause?: unknown;
|
|
35
|
+
constructor(message: string, kind: "timeout" | "network" | "parse", cause?: unknown);
|
|
36
|
+
}
|
|
37
|
+
/** Map a parsed error body + status into a GoableApiError. Tolerant of a
|
|
38
|
+
* non-conforming body (falls back to the status code as the error code). */
|
|
39
|
+
export declare function toApiError(status: number, body: unknown): GoableApiError;
|
|
40
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAA;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACrB;AAED,qBAAa,cAAe,SAAQ,KAAK;IACvC,SAAkB,IAAI,oBAAmB;IACzC,wBAAwB;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,8EAA8E;IAC9E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,wEAAwE;IACxE,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,CAAA;IAChC,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;gBAGvC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE;CAUxE;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,SAAkB,IAAI,wBAAuB;IAC7C,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,CAAA;IAC9C,SAAkB,KAAK,CAAC,EAAE,OAAO,CAAA;gBAErB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,EAAE,KAAK,CAAC,EAAE,OAAO;CAMpF;AASD;6EAC6E;AAC7E,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,cAAc,CAQxE"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK error model. Two distinct failure modes:
|
|
3
|
+
* - GoableApiError : the API returned a non-2xx response. Maps the
|
|
4
|
+
* canonical flat error envelope
|
|
5
|
+
* ({ error, message?, issues?, detail? }).
|
|
6
|
+
* - GoableNetworkError: the request never produced an HTTP response
|
|
7
|
+
* (DNS, connection, abort/timeout, JSON parse).
|
|
8
|
+
*/
|
|
9
|
+
export class GoableApiError extends Error {
|
|
10
|
+
name = "GoableApiError";
|
|
11
|
+
/** HTTP status code. */
|
|
12
|
+
status;
|
|
13
|
+
/** Machine-readable code from the `error` field (e.g. "PAYMENT_REQUIRED"). */
|
|
14
|
+
code;
|
|
15
|
+
/** Zod validation issues, present on 422 VALIDATION_ERROR responses. */
|
|
16
|
+
issues;
|
|
17
|
+
/** Free-form extra context (e.g. plan info, quote id). */
|
|
18
|
+
detail;
|
|
19
|
+
constructor(status, code, message, extra) {
|
|
20
|
+
super(message ?? code);
|
|
21
|
+
this.status = status;
|
|
22
|
+
this.code = code;
|
|
23
|
+
if (extra?.issues)
|
|
24
|
+
this.issues = extra.issues;
|
|
25
|
+
if (extra?.detail)
|
|
26
|
+
this.detail = extra.detail;
|
|
27
|
+
// Restore prototype chain for `instanceof` across transpilation targets.
|
|
28
|
+
Object.setPrototypeOf(this, GoableApiError.prototype);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export class GoableNetworkError extends Error {
|
|
32
|
+
name = "GoableNetworkError";
|
|
33
|
+
/** "timeout" when the request was aborted by the configured timeout. */
|
|
34
|
+
kind;
|
|
35
|
+
cause;
|
|
36
|
+
constructor(message, kind, cause) {
|
|
37
|
+
super(message);
|
|
38
|
+
this.kind = kind;
|
|
39
|
+
if (cause !== undefined)
|
|
40
|
+
this.cause = cause;
|
|
41
|
+
Object.setPrototypeOf(this, GoableNetworkError.prototype);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/** Map a parsed error body + status into a GoableApiError. Tolerant of a
|
|
45
|
+
* non-conforming body (falls back to the status code as the error code). */
|
|
46
|
+
export function toApiError(status, body) {
|
|
47
|
+
const b = (body ?? {});
|
|
48
|
+
const code = typeof b.error === "string" ? b.error : `HTTP_${status}`;
|
|
49
|
+
const message = typeof b.message === "string" ? b.message : undefined;
|
|
50
|
+
const extra = {};
|
|
51
|
+
if (Array.isArray(b.issues))
|
|
52
|
+
extra.issues = b.issues;
|
|
53
|
+
if (b.detail && typeof b.detail === "object")
|
|
54
|
+
extra.detail = b.detail;
|
|
55
|
+
return new GoableApiError(status, code, message, extra);
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,MAAM,OAAO,cAAe,SAAQ,KAAK;IACrB,IAAI,GAAG,gBAAgB,CAAA;IACzC,wBAAwB;IACf,MAAM,CAAQ;IACvB,8EAA8E;IACrE,IAAI,CAAQ;IACrB,wEAAwE;IAC/D,MAAM,CAAiB;IAChC,0DAA0D;IACjD,MAAM,CAA0B;IAEzC,YACE,MAAc,EACd,IAAY,EACZ,OAAgB,EAChB,KAAqE;QAErE,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,CAAA;QACtB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,KAAK,EAAE,MAAM;YAAE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAA;QAC7C,IAAI,KAAK,EAAE,MAAM;YAAE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAA;QAC7C,yEAAyE;QACzE,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,cAAc,CAAC,SAAS,CAAC,CAAA;IACvD,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IACzB,IAAI,GAAG,oBAAoB,CAAA;IAC7C,wEAAwE;IAC/D,IAAI,CAAiC;IAC5B,KAAK,CAAU;IAEjC,YAAY,OAAe,EAAE,IAAqC,EAAE,KAAe;QACjF,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,KAAK,KAAK,SAAS;YAAE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAC3C,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAA;IAC3D,CAAC;CACF;AASD;6EAC6E;AAC7E,MAAM,UAAU,UAAU,CAAC,MAAc,EAAE,IAAa;IACtD,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAiB,CAAA;IACtC,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,MAAM,EAAE,CAAA;IACrE,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAA;IACrE,MAAM,KAAK,GAAkE,EAAE,CAAA;IAC/E,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;QAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,MAAwB,CAAA;IACtE,IAAI,CAAC,CAAC,MAAM,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ;QAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,MAAiC,CAAA;IAChG,OAAO,IAAI,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAA;AACzD,CAAC"}
|