@goable-io/sdk 0.2.0 → 0.3.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/LICENSE +21 -0
- package/README.md +61 -39
- package/dist/generated/api.d.ts +2 -2
- package/dist/generated/api.js +2 -2
- package/package.json +21 -18
- package/src/generated/api.ts +2 -2
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Fabio Carucci
|
|
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
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
# @goable-io/sdk
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@goable-io/sdk)
|
|
4
|
+
[](https://github.com/goable-io/sdk/actions/workflows/ci.yml)
|
|
5
|
+
[](./LICENSE)
|
|
6
|
+
|
|
3
7
|
TypeScript client for the [Goable](https://goable.io) API — 0-100 suitability
|
|
4
8
|
scoring for outdoor activities (water, snow, air, land) from real-time weather
|
|
5
9
|
and multi-domain physics.
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
11
|
+
Thin, typed transport over the public tenant-facing REST surface. **Zero runtime
|
|
12
|
+
dependencies.** Works in Node ≥18 and modern browser/edge runtimes (uses the
|
|
13
|
+
global `fetch`). Published to npm with [provenance](https://docs.npmjs.com/generating-provenance-statements).
|
|
10
14
|
|
|
11
15
|
## Install
|
|
12
16
|
|
|
13
17
|
```bash
|
|
14
|
-
npm install @goable-io/sdk
|
|
18
|
+
npm install @goable-io/sdk
|
|
19
|
+
# or: pnpm add @goable-io/sdk
|
|
15
20
|
```
|
|
16
21
|
|
|
17
22
|
## Quickstart
|
|
@@ -21,6 +26,7 @@ import { GoableClient } from "@goable-io/sdk"
|
|
|
21
26
|
|
|
22
27
|
const goable = new GoableClient({ apiKey: process.env.GOABLE_API_KEY! })
|
|
23
28
|
|
|
29
|
+
// Score a single activity at a location + time window
|
|
24
30
|
const result = await goable.score({
|
|
25
31
|
activity: "kitesurfing",
|
|
26
32
|
location: { lat: 43.7, lng: 7.27 },
|
|
@@ -32,14 +38,44 @@ result.verdict // "unsafe" | "poor" | "marginal" | "fair" | "favorable" | "exce
|
|
|
32
38
|
result.confidence
|
|
33
39
|
```
|
|
34
40
|
|
|
41
|
+
Inverse query — "where should I go?" — ranks sub-spots for an activity within
|
|
42
|
+
a region:
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
const spots = await goable.recommendSpot({
|
|
46
|
+
activity: "kitesurfing",
|
|
47
|
+
region: { center: { lat: 43.7, lng: 7.27 }, radiusKm: 50 },
|
|
48
|
+
window: { from: "2026-06-01T06:00:00Z", to: "2026-06-01T18:00:00Z" },
|
|
49
|
+
topK: 5,
|
|
50
|
+
})
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Authentication
|
|
54
|
+
|
|
55
|
+
Every request carries your tenant API key. The canonical production header is
|
|
56
|
+
**`X-Goable-Key`**, which the client sends automatically:
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
new GoableClient({ apiKey: "gk_…" }) // → sends "X-Goable-Key: gk_…"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
> The API also accepts `Authorization: Bearer <key>` as a legacy fallback for
|
|
63
|
+
> direct testing, but new integrations should use the default `X-Goable-Key`
|
|
64
|
+
> path. (Production traffic sits behind CloudFront, which reserves the
|
|
65
|
+
> `Authorization` header for its own signature — the custom header sidesteps
|
|
66
|
+
> that.)
|
|
67
|
+
|
|
68
|
+
Mint a key from the tenant portal at
|
|
69
|
+
[console.goable.io/portal/keys](https://console.goable.io/portal/keys).
|
|
70
|
+
|
|
35
71
|
## Configuration
|
|
36
72
|
|
|
37
73
|
```ts
|
|
38
74
|
new GoableClient({
|
|
39
|
-
apiKey: "…",
|
|
75
|
+
apiKey: "…", // required — sent as X-Goable-Key
|
|
40
76
|
baseUrl: "https://api.goable.io", // default
|
|
41
|
-
timeoutMs: 30_000,
|
|
42
|
-
fetch: customFetch,
|
|
77
|
+
timeoutMs: 30_000, // default; 0 disables
|
|
78
|
+
fetch: customFetch, // default globalThis.fetch (inject for Node <18 / tests)
|
|
43
79
|
})
|
|
44
80
|
```
|
|
45
81
|
|
|
@@ -53,6 +89,7 @@ new GoableClient({
|
|
|
53
89
|
| `scoreHistorical(input)` | `POST /v1/score/historical` | climatology percentiles (Pro+) |
|
|
54
90
|
| `scorePortfolio(input)` | `POST /v1/score/portfolio` | multi-spot joint variance |
|
|
55
91
|
| `explainCounterfactual(input)` | `POST /v1/score/explain-counterfactual` | binding constraint, sensitivities, best window/spot |
|
|
92
|
+
| `recommendSpot(input)` | `POST /v1/recommend-spot` | inverse query: top-K ranked sub-spots |
|
|
56
93
|
| `decision(input)` | `POST /v1/decision` | personalized go/no-go (Pro+) |
|
|
57
94
|
| `deleteUserData(pseudonym)` | `DELETE /v1/decision/user-data/:p` | GDPR erasure; returns receipt headers |
|
|
58
95
|
| `explain(input)` / `briefing(input)` | `POST /v1/intelligence/*` | LLM narratives (Pro+) |
|
|
@@ -60,6 +97,8 @@ new GoableClient({
|
|
|
60
97
|
| `quote(input)` | `POST /v1/underwriting/quote` | parametric premium (Scale) |
|
|
61
98
|
| `health()` | `GET /v1/health` | liveness |
|
|
62
99
|
|
|
100
|
+
Full endpoint reference: [goable.io/docs](https://goable.io/docs).
|
|
101
|
+
|
|
63
102
|
## Errors
|
|
64
103
|
|
|
65
104
|
```ts
|
|
@@ -69,8 +108,8 @@ try {
|
|
|
69
108
|
await goable.score({ activity: "kitesurfing", location: { lat: 43.7, lng: 7.27 }, ensemble: true })
|
|
70
109
|
} catch (err) {
|
|
71
110
|
if (err instanceof GoableApiError) {
|
|
72
|
-
err.status // 402
|
|
73
|
-
err.code // "PAYMENT_REQUIRED"
|
|
111
|
+
err.status // e.g. 402
|
|
112
|
+
err.code // e.g. "PAYMENT_REQUIRED"
|
|
74
113
|
err.issues // Zod issues on 422 VALIDATION_ERROR
|
|
75
114
|
err.detail // free-form context (e.g. plan info)
|
|
76
115
|
} else if (err instanceof GoableNetworkError) {
|
|
@@ -82,40 +121,23 @@ try {
|
|
|
82
121
|
## Browser use
|
|
83
122
|
|
|
84
123
|
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
|
-
|
|
124
|
+
server-side use. For direct browser calls the API's CORS allowlist must include
|
|
125
|
+
your origin (contact Goable to allowlist it).
|
|
87
126
|
|
|
88
127
|
## Types are generated from the API contract
|
|
89
128
|
|
|
90
|
-
The request/response types are **generated** from the API's OpenAPI
|
|
91
|
-
document (`
|
|
92
|
-
[`openapi-typescript`](https://github.com/openapi-ts/openapi-typescript) —
|
|
93
|
-
|
|
94
|
-
|
|
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).
|
|
129
|
+
The request/response types are **generated** from the Goable API's OpenAPI
|
|
130
|
+
document (`openapi.json`) via
|
|
131
|
+
[`openapi-typescript`](https://github.com/openapi-ts/openapi-typescript) — they
|
|
132
|
+
are never hand-authored, so they can't drift from the contract. The committed
|
|
133
|
+
`openapi.json` tracks the live public API; see
|
|
134
|
+
[CONTRIBUTING.md](./CONTRIBUTING.md) for how it stays in sync.
|
|
104
135
|
|
|
105
|
-
|
|
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.
|
|
136
|
+
## Contributing & releases
|
|
109
137
|
|
|
110
|
-
|
|
138
|
+
See [CONTRIBUTING.md](./CONTRIBUTING.md). Releases are automated: merging to
|
|
139
|
+
`main` publishes to npm with provenance.
|
|
111
140
|
|
|
112
|
-
|
|
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.
|
|
141
|
+
## License
|
|
119
142
|
|
|
120
|
-
|
|
121
|
-
> stays in this private monorepo by design.
|
|
143
|
+
MIT © Fabio Carucci
|
package/dist/generated/api.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* GENERATED FILE — do not edit by hand.
|
|
3
|
-
* Source:
|
|
4
|
-
* Regenerate: pnpm
|
|
3
|
+
* Source: openapi.json (the committed Goable API contract).
|
|
4
|
+
* Regenerate: pnpm gen
|
|
5
5
|
*/
|
|
6
6
|
export interface paths {
|
|
7
7
|
"/v1/health": {
|
package/dist/generated/api.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* GENERATED FILE — do not edit by hand.
|
|
3
|
-
* Source:
|
|
4
|
-
* Regenerate: pnpm
|
|
3
|
+
* Source: openapi.json (the committed Goable API contract).
|
|
4
|
+
* Regenerate: pnpm gen
|
|
5
5
|
*/
|
|
6
6
|
export {};
|
|
7
7
|
//# sourceMappingURL=api.js.map
|
package/package.json
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goable-io/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "TypeScript client for the Goable API — suitability scoring for outdoor activities.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|
|
8
|
-
"
|
|
8
|
+
"author": "Fabio Carucci <contact@fabio-carucci.com>",
|
|
9
|
+
"homepage": "https://github.com/goable-io/sdk#readme",
|
|
9
10
|
"repository": {
|
|
10
11
|
"type": "git",
|
|
11
|
-
"url": "https://github.com/goable-io/
|
|
12
|
-
|
|
12
|
+
"url": "git+https://github.com/goable-io/sdk.git"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/goable-io/sdk/issues"
|
|
13
16
|
},
|
|
14
17
|
"keywords": [
|
|
15
18
|
"goable",
|
|
@@ -30,28 +33,28 @@
|
|
|
30
33
|
"default": "./dist/index.js"
|
|
31
34
|
}
|
|
32
35
|
},
|
|
33
|
-
"files": [
|
|
34
|
-
"dist",
|
|
35
|
-
"src",
|
|
36
|
-
"README.md"
|
|
37
|
-
],
|
|
36
|
+
"files": ["dist", "src", "README.md", "LICENSE"],
|
|
38
37
|
"engines": {
|
|
39
38
|
"node": ">=18"
|
|
40
39
|
},
|
|
40
|
+
"packageManager": "pnpm@11.3.0",
|
|
41
41
|
"publishConfig": {
|
|
42
|
-
"access": "public"
|
|
42
|
+
"access": "public",
|
|
43
|
+
"provenance": true
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "tsc",
|
|
47
|
+
"typecheck": "tsc --noEmit",
|
|
48
|
+
"test": "vitest run --passWithNoTests",
|
|
49
|
+
"gen": "tsx scripts/gen.ts",
|
|
50
|
+
"prepublishOnly": "tsc",
|
|
51
|
+
"clean": "rm -rf dist *.tsbuildinfo"
|
|
43
52
|
},
|
|
44
53
|
"devDependencies": {
|
|
54
|
+
"@types/node": "^22.10.0",
|
|
45
55
|
"openapi-typescript": "^7.13.0",
|
|
46
56
|
"tsx": "^4.19.2",
|
|
47
57
|
"typescript": "^5.7.2",
|
|
48
58
|
"vitest": "^2.1.8"
|
|
49
|
-
},
|
|
50
|
-
"scripts": {
|
|
51
|
-
"build": "tsc -b",
|
|
52
|
-
"typecheck": "tsc --noEmit",
|
|
53
|
-
"test": "vitest run --passWithNoTests",
|
|
54
|
-
"gen": "tsx scripts/gen.ts",
|
|
55
|
-
"clean": "rm -rf dist .turbo *.tsbuildinfo"
|
|
56
59
|
}
|
|
57
|
-
}
|
|
60
|
+
}
|
package/src/generated/api.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* GENERATED FILE — do not edit by hand.
|
|
3
|
-
* Source:
|
|
4
|
-
* Regenerate: pnpm
|
|
3
|
+
* Source: openapi.json (the committed Goable API contract).
|
|
4
|
+
* Regenerate: pnpm gen
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
export interface paths {
|