@seta-labs/geo 0.0.0-stage → 0.1.0-next.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 +78 -2
- package/dist/index.d.ts +1002 -0
- package/dist/index.js +79 -0
- package/package.json +49 -5
package/README.md
CHANGED
|
@@ -1,3 +1,79 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @seta-labs/geo
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Typed ESM client for Seta Geo's HTTP API. Requires Node.js 22+ or a browser with
|
|
4
|
+
standard Fetch, Request, Response and AbortController support. The server's
|
|
5
|
+
Node.js 26 development requirement does not apply to SDK consumers.
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { ApiError, createGeoClient } from '@seta-labs/geo';
|
|
9
|
+
|
|
10
|
+
const geo = createGeoClient({
|
|
11
|
+
baseUrl: 'https://geo.example.com/api',
|
|
12
|
+
apiKey: serverConfig.geoApiKey,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
const result = await geo.geocode(
|
|
17
|
+
{ query: 'Via Roma 1, Torino', include: 'full' },
|
|
18
|
+
{ signal: AbortSignal.timeout(20_000) },
|
|
19
|
+
);
|
|
20
|
+
// result is GeocodeResult, inferred from the generated HTTP contract.
|
|
21
|
+
} catch (error) {
|
|
22
|
+
if (error instanceof ApiError) {
|
|
23
|
+
// error.status, error.body (unknown), error.headers and error.requestId.
|
|
24
|
+
// Retry-After and any retryAfterMs in the body remain available.
|
|
25
|
+
}
|
|
26
|
+
throw error;
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
`baseUrl` is the complete API root, including `/api` when the deployment uses
|
|
31
|
+
that prefix. The SDK never appends `/api`. Browser-relative roots such as `/api`
|
|
32
|
+
resolve against the current page. SSR requires an absolute API root and a new
|
|
33
|
+
client for each request when credentials are request-scoped.
|
|
34
|
+
|
|
35
|
+
Use API keys only on a trusted backend. A browser may omit `apiKey` when calling
|
|
36
|
+
its own backend, which supplies the key to Geo. The bundled Geo panel follows
|
|
37
|
+
this arrangement through its existing Nitro pass-through. It adapts Nitro's
|
|
38
|
+
request-scoped Fetch to real `Response` objects and preserves cookies locally.
|
|
39
|
+
Do not use `$fetch` as `fetch`: it returns the parsed body instead of a Response.
|
|
40
|
+
|
|
41
|
+
All calls return `Promise<T>` and accept optional `{ signal }` as the last
|
|
42
|
+
argument. An optional `fetch: (request: Request) => Promise<Response>` allows
|
|
43
|
+
consumer-owned instrumentation or transport adapters. There is no scheduler,
|
|
44
|
+
queue, rate limiter or automatic retry, including for failed writes. Consumers
|
|
45
|
+
retain their own concurrency and retry policy.
|
|
46
|
+
|
|
47
|
+
| Method | Input |
|
|
48
|
+
| ---------------------------------------- | -------------------------------------- |
|
|
49
|
+
| `geocode` | `GeocodeRequest` |
|
|
50
|
+
| `geocodeBatch` | `GeocodeBatchRequest` |
|
|
51
|
+
| `reverseGeocode` | `ReverseGeocodeRequest` |
|
|
52
|
+
| `territory.status`, `territory.datasets` | options only |
|
|
53
|
+
| `territory.comuni` | optional `TerritoryComuniQuery` |
|
|
54
|
+
| `territory.quotazioni` | optional `TerritoryQuotazioniQuery` |
|
|
55
|
+
| `territory.compravendite` | optional `TerritoryCompravenditeQuery` |
|
|
56
|
+
| `territory.comune` | municipality code |
|
|
57
|
+
| `territory.resolve` | `TerritoryResolveRequest` |
|
|
58
|
+
|
|
59
|
+
The package exports `createGeoClient`, `ApiError`, client/options interfaces,
|
|
60
|
+
query types and the generated geocode/territory request and response aliases.
|
|
61
|
+
The three service health routes are intentionally outside this SDK surface.
|
|
62
|
+
OpenAPI remains authoritative: TypeScript provides static types, not runtime
|
|
63
|
+
validation of received data. `include` may be omitted and defaults to `best`
|
|
64
|
+
on the service.
|
|
65
|
+
|
|
66
|
+
HTTP errors are `ApiError`; their body is JSON when parseable, otherwise text,
|
|
67
|
+
or `undefined` for an empty response. Network failures, aborts and JSON parsing
|
|
68
|
+
errors retain their native types. Every Geo success operation requires a JSON
|
|
69
|
+
result: an unexpected empty/204 success raises `SyntaxError`. The SDK logs no
|
|
70
|
+
body, URL or credential automatically.
|
|
71
|
+
|
|
72
|
+
Versioning is independent from the service. The initial `0.1.0-next.0` candidate
|
|
73
|
+
uses the HTTP contract of Geo service `0.4.10`. Declarations are bundled from the
|
|
74
|
+
repository's generated types; installing the SDK needs no private workspace
|
|
75
|
+
package. Distribution is public npm; the retained license is `UNLICENSED`.
|
|
76
|
+
|
|
77
|
+
The SDK remains on `0.x` until an explicit decision to graduate to `1.0`.
|
|
78
|
+
Prerelease candidates use the `next` channel; completing prerelease testing
|
|
79
|
+
does not itself authorize a `1.0` version.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1002 @@
|
|
|
1
|
+
/** HTTP failures only. Network, abort and JSON parsing errors keep their native types. */
|
|
2
|
+
declare class ApiError extends Error {
|
|
3
|
+
readonly body: unknown;
|
|
4
|
+
readonly status: number;
|
|
5
|
+
readonly headers: Headers;
|
|
6
|
+
readonly requestId: string | undefined;
|
|
7
|
+
constructor(response: Response, body: unknown);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* This file was auto-generated by openapi-typescript.
|
|
12
|
+
* Do not make direct changes to the file.
|
|
13
|
+
*/
|
|
14
|
+
interface paths {
|
|
15
|
+
'/health': {
|
|
16
|
+
parameters: {
|
|
17
|
+
query?: never;
|
|
18
|
+
header?: never;
|
|
19
|
+
path?: never;
|
|
20
|
+
cookie?: never;
|
|
21
|
+
};
|
|
22
|
+
/** Liveness: the process answers; no dependency is checked */
|
|
23
|
+
get: operations['HealthController_live'];
|
|
24
|
+
put?: never;
|
|
25
|
+
post?: never;
|
|
26
|
+
delete?: never;
|
|
27
|
+
options?: never;
|
|
28
|
+
head?: never;
|
|
29
|
+
patch?: never;
|
|
30
|
+
trace?: never;
|
|
31
|
+
};
|
|
32
|
+
'/health/ready': {
|
|
33
|
+
parameters: {
|
|
34
|
+
query?: never;
|
|
35
|
+
header?: never;
|
|
36
|
+
path?: never;
|
|
37
|
+
cookie?: never;
|
|
38
|
+
};
|
|
39
|
+
/** Readiness: memory pressure and critical dependencies */
|
|
40
|
+
get: operations['HealthController_ready'];
|
|
41
|
+
put?: never;
|
|
42
|
+
post?: never;
|
|
43
|
+
delete?: never;
|
|
44
|
+
options?: never;
|
|
45
|
+
head?: never;
|
|
46
|
+
patch?: never;
|
|
47
|
+
trace?: never;
|
|
48
|
+
};
|
|
49
|
+
'/health/status': {
|
|
50
|
+
parameters: {
|
|
51
|
+
query?: never;
|
|
52
|
+
header?: never;
|
|
53
|
+
path?: never;
|
|
54
|
+
cookie?: never;
|
|
55
|
+
};
|
|
56
|
+
/** Diagnostics: memory, event loop delay, every check with its error */
|
|
57
|
+
get: operations['HealthController_status'];
|
|
58
|
+
put?: never;
|
|
59
|
+
post?: never;
|
|
60
|
+
delete?: never;
|
|
61
|
+
options?: never;
|
|
62
|
+
head?: never;
|
|
63
|
+
patch?: never;
|
|
64
|
+
trace?: never;
|
|
65
|
+
};
|
|
66
|
+
'/geocode': {
|
|
67
|
+
parameters: {
|
|
68
|
+
query?: never;
|
|
69
|
+
header?: never;
|
|
70
|
+
path?: never;
|
|
71
|
+
cookie?: never;
|
|
72
|
+
};
|
|
73
|
+
get?: never;
|
|
74
|
+
put?: never;
|
|
75
|
+
post: operations['GeocodeController_geocode'];
|
|
76
|
+
delete?: never;
|
|
77
|
+
options?: never;
|
|
78
|
+
head?: never;
|
|
79
|
+
patch?: never;
|
|
80
|
+
trace?: never;
|
|
81
|
+
};
|
|
82
|
+
'/geocode/batch': {
|
|
83
|
+
parameters: {
|
|
84
|
+
query?: never;
|
|
85
|
+
header?: never;
|
|
86
|
+
path?: never;
|
|
87
|
+
cookie?: never;
|
|
88
|
+
};
|
|
89
|
+
get?: never;
|
|
90
|
+
put?: never;
|
|
91
|
+
post: operations['GeocodeController_geocodeBatch'];
|
|
92
|
+
delete?: never;
|
|
93
|
+
options?: never;
|
|
94
|
+
head?: never;
|
|
95
|
+
patch?: never;
|
|
96
|
+
trace?: never;
|
|
97
|
+
};
|
|
98
|
+
'/geocode/reverse': {
|
|
99
|
+
parameters: {
|
|
100
|
+
query?: never;
|
|
101
|
+
header?: never;
|
|
102
|
+
path?: never;
|
|
103
|
+
cookie?: never;
|
|
104
|
+
};
|
|
105
|
+
get?: never;
|
|
106
|
+
put?: never;
|
|
107
|
+
post: operations['GeocodeController_reverseGeocode'];
|
|
108
|
+
delete?: never;
|
|
109
|
+
options?: never;
|
|
110
|
+
head?: never;
|
|
111
|
+
patch?: never;
|
|
112
|
+
trace?: never;
|
|
113
|
+
};
|
|
114
|
+
'/territory/status': {
|
|
115
|
+
parameters: {
|
|
116
|
+
query?: never;
|
|
117
|
+
header?: never;
|
|
118
|
+
path?: never;
|
|
119
|
+
cookie?: never;
|
|
120
|
+
};
|
|
121
|
+
get: operations['TerritoryController_status'];
|
|
122
|
+
put?: never;
|
|
123
|
+
post?: never;
|
|
124
|
+
delete?: never;
|
|
125
|
+
options?: never;
|
|
126
|
+
head?: never;
|
|
127
|
+
patch?: never;
|
|
128
|
+
trace?: never;
|
|
129
|
+
};
|
|
130
|
+
'/territory/datasets': {
|
|
131
|
+
parameters: {
|
|
132
|
+
query?: never;
|
|
133
|
+
header?: never;
|
|
134
|
+
path?: never;
|
|
135
|
+
cookie?: never;
|
|
136
|
+
};
|
|
137
|
+
get: operations['TerritoryController_datasets'];
|
|
138
|
+
put?: never;
|
|
139
|
+
post?: never;
|
|
140
|
+
delete?: never;
|
|
141
|
+
options?: never;
|
|
142
|
+
head?: never;
|
|
143
|
+
patch?: never;
|
|
144
|
+
trace?: never;
|
|
145
|
+
};
|
|
146
|
+
'/territory/comuni': {
|
|
147
|
+
parameters: {
|
|
148
|
+
query?: never;
|
|
149
|
+
header?: never;
|
|
150
|
+
path?: never;
|
|
151
|
+
cookie?: never;
|
|
152
|
+
};
|
|
153
|
+
get: operations['TerritoryController_listComuni'];
|
|
154
|
+
put?: never;
|
|
155
|
+
post?: never;
|
|
156
|
+
delete?: never;
|
|
157
|
+
options?: never;
|
|
158
|
+
head?: never;
|
|
159
|
+
patch?: never;
|
|
160
|
+
trace?: never;
|
|
161
|
+
};
|
|
162
|
+
'/territory/quotazioni': {
|
|
163
|
+
parameters: {
|
|
164
|
+
query?: never;
|
|
165
|
+
header?: never;
|
|
166
|
+
path?: never;
|
|
167
|
+
cookie?: never;
|
|
168
|
+
};
|
|
169
|
+
get: operations['TerritoryController_listQuotazioni'];
|
|
170
|
+
put?: never;
|
|
171
|
+
post?: never;
|
|
172
|
+
delete?: never;
|
|
173
|
+
options?: never;
|
|
174
|
+
head?: never;
|
|
175
|
+
patch?: never;
|
|
176
|
+
trace?: never;
|
|
177
|
+
};
|
|
178
|
+
'/territory/compravendite': {
|
|
179
|
+
parameters: {
|
|
180
|
+
query?: never;
|
|
181
|
+
header?: never;
|
|
182
|
+
path?: never;
|
|
183
|
+
cookie?: never;
|
|
184
|
+
};
|
|
185
|
+
get: operations['TerritoryController_listCompravendite'];
|
|
186
|
+
put?: never;
|
|
187
|
+
post?: never;
|
|
188
|
+
delete?: never;
|
|
189
|
+
options?: never;
|
|
190
|
+
head?: never;
|
|
191
|
+
patch?: never;
|
|
192
|
+
trace?: never;
|
|
193
|
+
};
|
|
194
|
+
'/territory/comuni/{codComune}': {
|
|
195
|
+
parameters: {
|
|
196
|
+
query?: never;
|
|
197
|
+
header?: never;
|
|
198
|
+
path?: never;
|
|
199
|
+
cookie?: never;
|
|
200
|
+
};
|
|
201
|
+
get: operations['TerritoryController_comune'];
|
|
202
|
+
put?: never;
|
|
203
|
+
post?: never;
|
|
204
|
+
delete?: never;
|
|
205
|
+
options?: never;
|
|
206
|
+
head?: never;
|
|
207
|
+
patch?: never;
|
|
208
|
+
trace?: never;
|
|
209
|
+
};
|
|
210
|
+
'/territory/resolve': {
|
|
211
|
+
parameters: {
|
|
212
|
+
query?: never;
|
|
213
|
+
header?: never;
|
|
214
|
+
path?: never;
|
|
215
|
+
cookie?: never;
|
|
216
|
+
};
|
|
217
|
+
get?: never;
|
|
218
|
+
put?: never;
|
|
219
|
+
post: operations['TerritoryController_resolve'];
|
|
220
|
+
delete?: never;
|
|
221
|
+
options?: never;
|
|
222
|
+
head?: never;
|
|
223
|
+
patch?: never;
|
|
224
|
+
trace?: never;
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
interface components {
|
|
228
|
+
schemas: {
|
|
229
|
+
/** @enum {string} */
|
|
230
|
+
HealthStatus: 'ok' | 'degraded' | 'down';
|
|
231
|
+
HealthCheckResultDto: {
|
|
232
|
+
/** @example database */
|
|
233
|
+
name: string;
|
|
234
|
+
/**
|
|
235
|
+
* @description A check is `ok` or `down`.
|
|
236
|
+
* @example ok
|
|
237
|
+
*/
|
|
238
|
+
status: components['schemas']['HealthStatus'];
|
|
239
|
+
/** @description A failing critical check fails readiness. */
|
|
240
|
+
critical: boolean;
|
|
241
|
+
/** @example 3.2 */
|
|
242
|
+
durationMs: number;
|
|
243
|
+
/**
|
|
244
|
+
* @description Failure reason, only in `/health/status`: probes are public.
|
|
245
|
+
* @example timed out after 750 ms
|
|
246
|
+
*/
|
|
247
|
+
error?: string;
|
|
248
|
+
};
|
|
249
|
+
HealthCheckResponseDto: {
|
|
250
|
+
/** @example ok */
|
|
251
|
+
status: components['schemas']['HealthStatus'];
|
|
252
|
+
/** @example api */
|
|
253
|
+
service: string;
|
|
254
|
+
/**
|
|
255
|
+
* Format: date-time
|
|
256
|
+
* @example 2026-07-03T10:00:00.000Z
|
|
257
|
+
*/
|
|
258
|
+
timestamp: string;
|
|
259
|
+
/** @description Readiness checks; absent on liveness. */
|
|
260
|
+
checks?: components['schemas']['HealthCheckResultDto'][];
|
|
261
|
+
};
|
|
262
|
+
MemoryUsageDto: {
|
|
263
|
+
/** @example 182.4 */
|
|
264
|
+
rssMiB: number;
|
|
265
|
+
/** @example 96.1 */
|
|
266
|
+
heapUsedMiB: number;
|
|
267
|
+
/** @example 120.5 */
|
|
268
|
+
heapTotalMiB: number;
|
|
269
|
+
/** @example 4.2 */
|
|
270
|
+
externalMiB: number;
|
|
271
|
+
/** @example 1.3 */
|
|
272
|
+
arrayBuffersMiB: number;
|
|
273
|
+
/**
|
|
274
|
+
* @description V8 `heap_size_limit`.
|
|
275
|
+
* @example 259
|
|
276
|
+
*/
|
|
277
|
+
heapLimitMiB: number;
|
|
278
|
+
/**
|
|
279
|
+
* @description cgroup memory limit, `null` when unconstrained.
|
|
280
|
+
* @example 512
|
|
281
|
+
*/
|
|
282
|
+
containerLimitMiB: number | null;
|
|
283
|
+
/**
|
|
284
|
+
* @description `heapUsed / heapLimit`.
|
|
285
|
+
* @example 0.371
|
|
286
|
+
*/
|
|
287
|
+
heapRatio: number;
|
|
288
|
+
/**
|
|
289
|
+
* @description `rss / containerLimit`, `null` when unconstrained.
|
|
290
|
+
* @example 0.356
|
|
291
|
+
*/
|
|
292
|
+
rssRatio: number | null;
|
|
293
|
+
};
|
|
294
|
+
EventLoopDelayDto: {
|
|
295
|
+
/** @example 10.1 */
|
|
296
|
+
p50Ms: number;
|
|
297
|
+
/** @example 21.4 */
|
|
298
|
+
p99Ms: number;
|
|
299
|
+
/** @example 48.7 */
|
|
300
|
+
maxMs: number;
|
|
301
|
+
/**
|
|
302
|
+
* @description Seconds covered: since the previous status report, or since startup.
|
|
303
|
+
* @example 60
|
|
304
|
+
*/
|
|
305
|
+
windowSec: number;
|
|
306
|
+
};
|
|
307
|
+
HealthReportResponseDto: {
|
|
308
|
+
/** @example ok */
|
|
309
|
+
status: components['schemas']['HealthStatus'];
|
|
310
|
+
/** @example api */
|
|
311
|
+
service: string;
|
|
312
|
+
/** @example v0.4.2 */
|
|
313
|
+
version?: string;
|
|
314
|
+
/** @example v22.23.2 */
|
|
315
|
+
node: string;
|
|
316
|
+
/** @example 3600 */
|
|
317
|
+
uptimeSec: number;
|
|
318
|
+
/**
|
|
319
|
+
* Format: date-time
|
|
320
|
+
* @example 2026-07-03T10:00:00.000Z
|
|
321
|
+
*/
|
|
322
|
+
timestamp: string;
|
|
323
|
+
memory: components['schemas']['MemoryUsageDto'];
|
|
324
|
+
eventLoop: components['schemas']['EventLoopDelayDto'];
|
|
325
|
+
checks: components['schemas']['HealthCheckResultDto'][];
|
|
326
|
+
};
|
|
327
|
+
GeocodeRequestDto: {
|
|
328
|
+
/** @description Free-text query, used verbatim when present. */
|
|
329
|
+
query?: string;
|
|
330
|
+
indirizzo?: string;
|
|
331
|
+
cap?: string;
|
|
332
|
+
citta?: string;
|
|
333
|
+
provincia?: string;
|
|
334
|
+
/**
|
|
335
|
+
* @description 'full' adds `results`: the provider's untouched result list, for callers that pick themselves.
|
|
336
|
+
* @default best
|
|
337
|
+
* @enum {string}
|
|
338
|
+
*/
|
|
339
|
+
include?: 'best' | 'full';
|
|
340
|
+
};
|
|
341
|
+
GeocodeResultDto: {
|
|
342
|
+
/** @enum {string} */
|
|
343
|
+
status: 'OK' | 'NO_RESULT' | 'INVALID_QUERY';
|
|
344
|
+
/** @description The normalized query actually used as cache key and provider input. */
|
|
345
|
+
query: string | null;
|
|
346
|
+
lat: number | null;
|
|
347
|
+
lng: number | null;
|
|
348
|
+
/** @description True when the answer came from the cache, no provider call. */
|
|
349
|
+
cached: boolean;
|
|
350
|
+
/** @description True when the coordinates fall inside the loose Italy bounding box. */
|
|
351
|
+
withinItaly: boolean;
|
|
352
|
+
/** @description Only with include=full: the provider's result list exactly as returned (all tiers, all fields). Empty array = the provider answered with no results. Null = the raw response is not available for this cached row. */
|
|
353
|
+
results?: {
|
|
354
|
+
[key: string]: unknown;
|
|
355
|
+
}[] | null;
|
|
356
|
+
};
|
|
357
|
+
GeocodeBatchRequestDto: {
|
|
358
|
+
items: components['schemas']['GeocodeRequestDto'][];
|
|
359
|
+
/**
|
|
360
|
+
* @description Applied to every item; a per-item include overrides it.
|
|
361
|
+
* @default best
|
|
362
|
+
* @enum {string}
|
|
363
|
+
*/
|
|
364
|
+
include?: 'best' | 'full';
|
|
365
|
+
};
|
|
366
|
+
GeocodeBatchResponseDto: {
|
|
367
|
+
/** @description Same order as the request items. */
|
|
368
|
+
items: components['schemas']['GeocodeResultDto'][];
|
|
369
|
+
};
|
|
370
|
+
ReverseGeocodeRequestDto: {
|
|
371
|
+
lat: number;
|
|
372
|
+
lng: number;
|
|
373
|
+
/**
|
|
374
|
+
* @default best
|
|
375
|
+
* @enum {string}
|
|
376
|
+
*/
|
|
377
|
+
include?: 'best' | 'full';
|
|
378
|
+
};
|
|
379
|
+
ReverseGeocodeResultDto: {
|
|
380
|
+
/** @enum {string} */
|
|
381
|
+
status: 'OK' | 'NO_RESULT';
|
|
382
|
+
/** @description Canonical cache key: "lat,lng" rounded to 5 decimals (~1 m). */
|
|
383
|
+
query: string;
|
|
384
|
+
/** @description Formatted address of the best-tier result. */
|
|
385
|
+
address: string | null;
|
|
386
|
+
/** @description True when the answer came from the cache, no provider call. */
|
|
387
|
+
cached: boolean;
|
|
388
|
+
/** @description Only with include=full: the provider's result list exactly as returned (all tiers, all fields). Empty array = the provider answered with no results. Null = the raw response is not available for this cached row. */
|
|
389
|
+
results?: {
|
|
390
|
+
[key: string]: unknown;
|
|
391
|
+
}[] | null;
|
|
392
|
+
};
|
|
393
|
+
TerritoryStatusDto: {
|
|
394
|
+
/** @description Latest OMI publication loaded (`YYYY-S`), null while no supply is loaded. */
|
|
395
|
+
semestre: string | null;
|
|
396
|
+
};
|
|
397
|
+
TerritoryDatasetsDto: {
|
|
398
|
+
comuni: number;
|
|
399
|
+
zone: number;
|
|
400
|
+
quotazioni: number;
|
|
401
|
+
compravendite: number;
|
|
402
|
+
/** @description Newest first. */
|
|
403
|
+
semestri: string[];
|
|
404
|
+
tipologie: string[];
|
|
405
|
+
stati: string[];
|
|
406
|
+
/** @description Newest first. */
|
|
407
|
+
anni: number[];
|
|
408
|
+
province: string[];
|
|
409
|
+
regioni: string[];
|
|
410
|
+
};
|
|
411
|
+
TerritoryComuneRigaDto: {
|
|
412
|
+
codComune: string;
|
|
413
|
+
codIstat: string;
|
|
414
|
+
denominazione: string;
|
|
415
|
+
provincia: string;
|
|
416
|
+
regione: string;
|
|
417
|
+
popolazione: number | null;
|
|
418
|
+
redditoMedio: number | null;
|
|
419
|
+
};
|
|
420
|
+
TerritoryComuniPageDto: {
|
|
421
|
+
page: number;
|
|
422
|
+
pageSize: number;
|
|
423
|
+
total: number;
|
|
424
|
+
items: components['schemas']['TerritoryComuneRigaDto'][];
|
|
425
|
+
};
|
|
426
|
+
TerritoryQuotazioneDto: {
|
|
427
|
+
semestre: string;
|
|
428
|
+
codComune: string;
|
|
429
|
+
comune: string | null;
|
|
430
|
+
provincia: string | null;
|
|
431
|
+
codZona: string;
|
|
432
|
+
zona: string | null;
|
|
433
|
+
tipologia: string;
|
|
434
|
+
stato: string;
|
|
435
|
+
comprMin: number | null;
|
|
436
|
+
comprMax: number | null;
|
|
437
|
+
locMin: number | null;
|
|
438
|
+
locMax: number | null;
|
|
439
|
+
};
|
|
440
|
+
TerritoryQuotazioniPageDto: {
|
|
441
|
+
page: number;
|
|
442
|
+
pageSize: number;
|
|
443
|
+
total: number;
|
|
444
|
+
/** @description Publication listed, null while none is loaded. */
|
|
445
|
+
semestre: string | null;
|
|
446
|
+
items: components['schemas']['TerritoryQuotazioneDto'][];
|
|
447
|
+
};
|
|
448
|
+
TerritoryCompravenditaDto: {
|
|
449
|
+
codComune: string;
|
|
450
|
+
comune: string | null;
|
|
451
|
+
provincia: string | null;
|
|
452
|
+
anno: number;
|
|
453
|
+
segmento: string;
|
|
454
|
+
ntn: number;
|
|
455
|
+
};
|
|
456
|
+
TerritoryCompravenditePageDto: {
|
|
457
|
+
page: number;
|
|
458
|
+
pageSize: number;
|
|
459
|
+
total: number;
|
|
460
|
+
items: components['schemas']['TerritoryCompravenditaDto'][];
|
|
461
|
+
};
|
|
462
|
+
TerritoryComuneDto: {
|
|
463
|
+
codComune: string;
|
|
464
|
+
codIstat: string;
|
|
465
|
+
denominazione: string;
|
|
466
|
+
provincia: string;
|
|
467
|
+
regione: string;
|
|
468
|
+
};
|
|
469
|
+
TerritoryIstatDto: {
|
|
470
|
+
denominazione: string;
|
|
471
|
+
provincia: string;
|
|
472
|
+
popolazione: number | null;
|
|
473
|
+
popolazioneAnno: number | null;
|
|
474
|
+
redditoMedio: number | null;
|
|
475
|
+
redditoAnno: number | null;
|
|
476
|
+
};
|
|
477
|
+
TerritoryOmiDto: {
|
|
478
|
+
semestre: string;
|
|
479
|
+
tipologia: string;
|
|
480
|
+
stato: string;
|
|
481
|
+
comprMin: number | null;
|
|
482
|
+
comprMax: number | null;
|
|
483
|
+
locMin: number | null;
|
|
484
|
+
locMax: number | null;
|
|
485
|
+
};
|
|
486
|
+
TerritoryZonaQuotazioneDto: {
|
|
487
|
+
codZona: string;
|
|
488
|
+
nome: string | null;
|
|
489
|
+
omi: components['schemas']['TerritoryOmiDto'] | null;
|
|
490
|
+
};
|
|
491
|
+
TerritoryCompravenditaAnnoDto: {
|
|
492
|
+
anno: number;
|
|
493
|
+
segmento: string;
|
|
494
|
+
ntn: number;
|
|
495
|
+
};
|
|
496
|
+
TerritoryComuneDetailDto: {
|
|
497
|
+
comune: components['schemas']['TerritoryComuneDto'];
|
|
498
|
+
istat: components['schemas']['TerritoryIstatDto'];
|
|
499
|
+
/** @description Publication the zone quotations come from, null while none is loaded. */
|
|
500
|
+
semestre: string | null;
|
|
501
|
+
zone: components['schemas']['TerritoryZonaQuotazioneDto'][];
|
|
502
|
+
compravendite: components['schemas']['TerritoryCompravenditaAnnoDto'][];
|
|
503
|
+
};
|
|
504
|
+
TerritoryPointDto: {
|
|
505
|
+
id: string;
|
|
506
|
+
lat: number;
|
|
507
|
+
lng: number;
|
|
508
|
+
};
|
|
509
|
+
TerritoryResolveRequestDto: {
|
|
510
|
+
/** @description OMI publication to quote from (`YYYY-S`). Callers pin it once per run — from `GET /territory/status` — so a publication switch mid-run cannot shear the batch. */
|
|
511
|
+
semestre: string;
|
|
512
|
+
points: components['schemas']['TerritoryPointDto'][];
|
|
513
|
+
};
|
|
514
|
+
TerritoryZonaDto: {
|
|
515
|
+
codComune: string;
|
|
516
|
+
codZona: string;
|
|
517
|
+
nome: string | null;
|
|
518
|
+
};
|
|
519
|
+
TerritoryCompravenditeDto: {
|
|
520
|
+
anno: number;
|
|
521
|
+
ntn: number;
|
|
522
|
+
};
|
|
523
|
+
TerritoryPointResultDto: {
|
|
524
|
+
id: string;
|
|
525
|
+
zona: components['schemas']['TerritoryZonaDto'] | null;
|
|
526
|
+
omi: components['schemas']['TerritoryOmiDto'] | null;
|
|
527
|
+
istat: components['schemas']['TerritoryIstatDto'] | null;
|
|
528
|
+
compravendite: components['schemas']['TerritoryCompravenditeDto'] | null;
|
|
529
|
+
};
|
|
530
|
+
TerritoryResolveResponseDto: {
|
|
531
|
+
items: components['schemas']['TerritoryPointResultDto'][];
|
|
532
|
+
};
|
|
533
|
+
};
|
|
534
|
+
responses: never;
|
|
535
|
+
parameters: never;
|
|
536
|
+
requestBodies: never;
|
|
537
|
+
headers: never;
|
|
538
|
+
pathItems: never;
|
|
539
|
+
}
|
|
540
|
+
interface operations {
|
|
541
|
+
HealthController_live: {
|
|
542
|
+
parameters: {
|
|
543
|
+
query?: never;
|
|
544
|
+
header?: never;
|
|
545
|
+
path?: never;
|
|
546
|
+
cookie?: never;
|
|
547
|
+
};
|
|
548
|
+
requestBody?: never;
|
|
549
|
+
responses: {
|
|
550
|
+
200: {
|
|
551
|
+
headers: {
|
|
552
|
+
[name: string]: unknown;
|
|
553
|
+
};
|
|
554
|
+
content: {
|
|
555
|
+
'application/json': components['schemas']['HealthCheckResponseDto'];
|
|
556
|
+
};
|
|
557
|
+
};
|
|
558
|
+
};
|
|
559
|
+
};
|
|
560
|
+
HealthController_ready: {
|
|
561
|
+
parameters: {
|
|
562
|
+
query?: never;
|
|
563
|
+
header?: never;
|
|
564
|
+
path?: never;
|
|
565
|
+
cookie?: never;
|
|
566
|
+
};
|
|
567
|
+
requestBody?: never;
|
|
568
|
+
responses: {
|
|
569
|
+
200: {
|
|
570
|
+
headers: {
|
|
571
|
+
[name: string]: unknown;
|
|
572
|
+
};
|
|
573
|
+
content: {
|
|
574
|
+
'application/json': components['schemas']['HealthCheckResponseDto'];
|
|
575
|
+
};
|
|
576
|
+
};
|
|
577
|
+
503: {
|
|
578
|
+
headers: {
|
|
579
|
+
[name: string]: unknown;
|
|
580
|
+
};
|
|
581
|
+
content: {
|
|
582
|
+
'application/json': components['schemas']['HealthCheckResponseDto'];
|
|
583
|
+
};
|
|
584
|
+
};
|
|
585
|
+
};
|
|
586
|
+
};
|
|
587
|
+
HealthController_status: {
|
|
588
|
+
parameters: {
|
|
589
|
+
query?: never;
|
|
590
|
+
header?: never;
|
|
591
|
+
path?: never;
|
|
592
|
+
cookie?: never;
|
|
593
|
+
};
|
|
594
|
+
requestBody?: never;
|
|
595
|
+
responses: {
|
|
596
|
+
200: {
|
|
597
|
+
headers: {
|
|
598
|
+
[name: string]: unknown;
|
|
599
|
+
};
|
|
600
|
+
content: {
|
|
601
|
+
'application/json': components['schemas']['HealthReportResponseDto'];
|
|
602
|
+
};
|
|
603
|
+
};
|
|
604
|
+
};
|
|
605
|
+
};
|
|
606
|
+
GeocodeController_geocode: {
|
|
607
|
+
parameters: {
|
|
608
|
+
query?: never;
|
|
609
|
+
header?: never;
|
|
610
|
+
path?: never;
|
|
611
|
+
cookie?: never;
|
|
612
|
+
};
|
|
613
|
+
requestBody: {
|
|
614
|
+
content: {
|
|
615
|
+
'application/json': components['schemas']['GeocodeRequestDto'];
|
|
616
|
+
};
|
|
617
|
+
};
|
|
618
|
+
responses: {
|
|
619
|
+
200: {
|
|
620
|
+
headers: {
|
|
621
|
+
[name: string]: unknown;
|
|
622
|
+
};
|
|
623
|
+
content: {
|
|
624
|
+
'application/json': components['schemas']['GeocodeResultDto'];
|
|
625
|
+
};
|
|
626
|
+
};
|
|
627
|
+
/** @description Missing or invalid API key. */
|
|
628
|
+
401: {
|
|
629
|
+
headers: {
|
|
630
|
+
[name: string]: unknown;
|
|
631
|
+
};
|
|
632
|
+
content?: never;
|
|
633
|
+
};
|
|
634
|
+
/** @description Provider not configured, cache miss unservable. */
|
|
635
|
+
503: {
|
|
636
|
+
headers: {
|
|
637
|
+
[name: string]: unknown;
|
|
638
|
+
};
|
|
639
|
+
content?: never;
|
|
640
|
+
};
|
|
641
|
+
};
|
|
642
|
+
};
|
|
643
|
+
GeocodeController_geocodeBatch: {
|
|
644
|
+
parameters: {
|
|
645
|
+
query?: never;
|
|
646
|
+
header?: never;
|
|
647
|
+
path?: never;
|
|
648
|
+
cookie?: never;
|
|
649
|
+
};
|
|
650
|
+
requestBody: {
|
|
651
|
+
content: {
|
|
652
|
+
'application/json': components['schemas']['GeocodeBatchRequestDto'];
|
|
653
|
+
};
|
|
654
|
+
};
|
|
655
|
+
responses: {
|
|
656
|
+
200: {
|
|
657
|
+
headers: {
|
|
658
|
+
[name: string]: unknown;
|
|
659
|
+
};
|
|
660
|
+
content: {
|
|
661
|
+
'application/json': components['schemas']['GeocodeBatchResponseDto'];
|
|
662
|
+
};
|
|
663
|
+
};
|
|
664
|
+
/** @description Missing or invalid API key. */
|
|
665
|
+
401: {
|
|
666
|
+
headers: {
|
|
667
|
+
[name: string]: unknown;
|
|
668
|
+
};
|
|
669
|
+
content?: never;
|
|
670
|
+
};
|
|
671
|
+
/** @description Provider not configured, cache miss unservable. */
|
|
672
|
+
503: {
|
|
673
|
+
headers: {
|
|
674
|
+
[name: string]: unknown;
|
|
675
|
+
};
|
|
676
|
+
content?: never;
|
|
677
|
+
};
|
|
678
|
+
};
|
|
679
|
+
};
|
|
680
|
+
GeocodeController_reverseGeocode: {
|
|
681
|
+
parameters: {
|
|
682
|
+
query?: never;
|
|
683
|
+
header?: never;
|
|
684
|
+
path?: never;
|
|
685
|
+
cookie?: never;
|
|
686
|
+
};
|
|
687
|
+
requestBody: {
|
|
688
|
+
content: {
|
|
689
|
+
'application/json': components['schemas']['ReverseGeocodeRequestDto'];
|
|
690
|
+
};
|
|
691
|
+
};
|
|
692
|
+
responses: {
|
|
693
|
+
200: {
|
|
694
|
+
headers: {
|
|
695
|
+
[name: string]: unknown;
|
|
696
|
+
};
|
|
697
|
+
content: {
|
|
698
|
+
'application/json': components['schemas']['ReverseGeocodeResultDto'];
|
|
699
|
+
};
|
|
700
|
+
};
|
|
701
|
+
/** @description Missing or invalid API key. */
|
|
702
|
+
401: {
|
|
703
|
+
headers: {
|
|
704
|
+
[name: string]: unknown;
|
|
705
|
+
};
|
|
706
|
+
content?: never;
|
|
707
|
+
};
|
|
708
|
+
/** @description Provider not configured, cache miss unservable. */
|
|
709
|
+
503: {
|
|
710
|
+
headers: {
|
|
711
|
+
[name: string]: unknown;
|
|
712
|
+
};
|
|
713
|
+
content?: never;
|
|
714
|
+
};
|
|
715
|
+
};
|
|
716
|
+
};
|
|
717
|
+
TerritoryController_status: {
|
|
718
|
+
parameters: {
|
|
719
|
+
query?: never;
|
|
720
|
+
header?: never;
|
|
721
|
+
path?: never;
|
|
722
|
+
cookie?: never;
|
|
723
|
+
};
|
|
724
|
+
requestBody?: never;
|
|
725
|
+
responses: {
|
|
726
|
+
200: {
|
|
727
|
+
headers: {
|
|
728
|
+
[name: string]: unknown;
|
|
729
|
+
};
|
|
730
|
+
content: {
|
|
731
|
+
'application/json': components['schemas']['TerritoryStatusDto'];
|
|
732
|
+
};
|
|
733
|
+
};
|
|
734
|
+
/** @description Missing or invalid API key. */
|
|
735
|
+
401: {
|
|
736
|
+
headers: {
|
|
737
|
+
[name: string]: unknown;
|
|
738
|
+
};
|
|
739
|
+
content?: never;
|
|
740
|
+
};
|
|
741
|
+
};
|
|
742
|
+
};
|
|
743
|
+
TerritoryController_datasets: {
|
|
744
|
+
parameters: {
|
|
745
|
+
query?: never;
|
|
746
|
+
header?: never;
|
|
747
|
+
path?: never;
|
|
748
|
+
cookie?: never;
|
|
749
|
+
};
|
|
750
|
+
requestBody?: never;
|
|
751
|
+
responses: {
|
|
752
|
+
200: {
|
|
753
|
+
headers: {
|
|
754
|
+
[name: string]: unknown;
|
|
755
|
+
};
|
|
756
|
+
content: {
|
|
757
|
+
'application/json': components['schemas']['TerritoryDatasetsDto'];
|
|
758
|
+
};
|
|
759
|
+
};
|
|
760
|
+
/** @description Missing or invalid API key. */
|
|
761
|
+
401: {
|
|
762
|
+
headers: {
|
|
763
|
+
[name: string]: unknown;
|
|
764
|
+
};
|
|
765
|
+
content?: never;
|
|
766
|
+
};
|
|
767
|
+
};
|
|
768
|
+
};
|
|
769
|
+
TerritoryController_listComuni: {
|
|
770
|
+
parameters: {
|
|
771
|
+
query?: {
|
|
772
|
+
page?: number;
|
|
773
|
+
pageSize?: number;
|
|
774
|
+
/** @description Part of the municipality name, case-insensitive. */
|
|
775
|
+
q?: string;
|
|
776
|
+
/** @description Province code, e.g. `GE`. */
|
|
777
|
+
provincia?: string;
|
|
778
|
+
regione?: string;
|
|
779
|
+
ordina?: 'denominazione' | 'popolazione';
|
|
780
|
+
};
|
|
781
|
+
header?: never;
|
|
782
|
+
path?: never;
|
|
783
|
+
cookie?: never;
|
|
784
|
+
};
|
|
785
|
+
requestBody?: never;
|
|
786
|
+
responses: {
|
|
787
|
+
200: {
|
|
788
|
+
headers: {
|
|
789
|
+
[name: string]: unknown;
|
|
790
|
+
};
|
|
791
|
+
content: {
|
|
792
|
+
'application/json': components['schemas']['TerritoryComuniPageDto'];
|
|
793
|
+
};
|
|
794
|
+
};
|
|
795
|
+
/** @description Missing or invalid API key. */
|
|
796
|
+
401: {
|
|
797
|
+
headers: {
|
|
798
|
+
[name: string]: unknown;
|
|
799
|
+
};
|
|
800
|
+
content?: never;
|
|
801
|
+
};
|
|
802
|
+
};
|
|
803
|
+
};
|
|
804
|
+
TerritoryController_listQuotazioni: {
|
|
805
|
+
parameters: {
|
|
806
|
+
query?: {
|
|
807
|
+
page?: number;
|
|
808
|
+
pageSize?: number;
|
|
809
|
+
/** @description Publication `YYYY-S`; defaults to the latest loaded. */
|
|
810
|
+
semestre?: string;
|
|
811
|
+
/** @description Belfiore code of the municipality. */
|
|
812
|
+
codComune?: string;
|
|
813
|
+
/** @description Province code, e.g. `GE`. */
|
|
814
|
+
provincia?: string;
|
|
815
|
+
/** @description Property type as published, e.g. `Abitazioni civili`. */
|
|
816
|
+
tipologia?: string;
|
|
817
|
+
/** @description Condition as published, e.g. `NORMALE`. */
|
|
818
|
+
stato?: string;
|
|
819
|
+
};
|
|
820
|
+
header?: never;
|
|
821
|
+
path?: never;
|
|
822
|
+
cookie?: never;
|
|
823
|
+
};
|
|
824
|
+
requestBody?: never;
|
|
825
|
+
responses: {
|
|
826
|
+
200: {
|
|
827
|
+
headers: {
|
|
828
|
+
[name: string]: unknown;
|
|
829
|
+
};
|
|
830
|
+
content: {
|
|
831
|
+
'application/json': components['schemas']['TerritoryQuotazioniPageDto'];
|
|
832
|
+
};
|
|
833
|
+
};
|
|
834
|
+
/** @description Missing or invalid API key. */
|
|
835
|
+
401: {
|
|
836
|
+
headers: {
|
|
837
|
+
[name: string]: unknown;
|
|
838
|
+
};
|
|
839
|
+
content?: never;
|
|
840
|
+
};
|
|
841
|
+
};
|
|
842
|
+
};
|
|
843
|
+
TerritoryController_listCompravendite: {
|
|
844
|
+
parameters: {
|
|
845
|
+
query?: {
|
|
846
|
+
page?: number;
|
|
847
|
+
pageSize?: number;
|
|
848
|
+
anno?: number;
|
|
849
|
+
/** @description Belfiore code of the municipality. */
|
|
850
|
+
codComune?: string;
|
|
851
|
+
/** @description Province code, e.g. `GE`. */
|
|
852
|
+
provincia?: string;
|
|
853
|
+
segmento?: 'RESIDENZIALE' | 'RESIDENZIALE_FINO_50MQ' | 'RESIDENZIALE_50_85MQ' | 'RESIDENZIALE_85_115MQ' | 'RESIDENZIALE_115_145MQ' | 'RESIDENZIALE_OLTRE_145MQ';
|
|
854
|
+
};
|
|
855
|
+
header?: never;
|
|
856
|
+
path?: never;
|
|
857
|
+
cookie?: never;
|
|
858
|
+
};
|
|
859
|
+
requestBody?: never;
|
|
860
|
+
responses: {
|
|
861
|
+
200: {
|
|
862
|
+
headers: {
|
|
863
|
+
[name: string]: unknown;
|
|
864
|
+
};
|
|
865
|
+
content: {
|
|
866
|
+
'application/json': components['schemas']['TerritoryCompravenditePageDto'];
|
|
867
|
+
};
|
|
868
|
+
};
|
|
869
|
+
/** @description Missing or invalid API key. */
|
|
870
|
+
401: {
|
|
871
|
+
headers: {
|
|
872
|
+
[name: string]: unknown;
|
|
873
|
+
};
|
|
874
|
+
content?: never;
|
|
875
|
+
};
|
|
876
|
+
};
|
|
877
|
+
};
|
|
878
|
+
TerritoryController_comune: {
|
|
879
|
+
parameters: {
|
|
880
|
+
query?: never;
|
|
881
|
+
header?: never;
|
|
882
|
+
path: {
|
|
883
|
+
/** @description Belfiore code of the municipality (e.g. `D969`). */
|
|
884
|
+
codComune: string;
|
|
885
|
+
};
|
|
886
|
+
cookie?: never;
|
|
887
|
+
};
|
|
888
|
+
requestBody?: never;
|
|
889
|
+
responses: {
|
|
890
|
+
200: {
|
|
891
|
+
headers: {
|
|
892
|
+
[name: string]: unknown;
|
|
893
|
+
};
|
|
894
|
+
content: {
|
|
895
|
+
'application/json': components['schemas']['TerritoryComuneDetailDto'];
|
|
896
|
+
};
|
|
897
|
+
};
|
|
898
|
+
/** @description Missing or invalid API key. */
|
|
899
|
+
401: {
|
|
900
|
+
headers: {
|
|
901
|
+
[name: string]: unknown;
|
|
902
|
+
};
|
|
903
|
+
content?: never;
|
|
904
|
+
};
|
|
905
|
+
/** @description The municipality is not in the registry. */
|
|
906
|
+
404: {
|
|
907
|
+
headers: {
|
|
908
|
+
[name: string]: unknown;
|
|
909
|
+
};
|
|
910
|
+
content?: never;
|
|
911
|
+
};
|
|
912
|
+
};
|
|
913
|
+
};
|
|
914
|
+
TerritoryController_resolve: {
|
|
915
|
+
parameters: {
|
|
916
|
+
query?: never;
|
|
917
|
+
header?: never;
|
|
918
|
+
path?: never;
|
|
919
|
+
cookie?: never;
|
|
920
|
+
};
|
|
921
|
+
requestBody: {
|
|
922
|
+
content: {
|
|
923
|
+
'application/json': components['schemas']['TerritoryResolveRequestDto'];
|
|
924
|
+
};
|
|
925
|
+
};
|
|
926
|
+
responses: {
|
|
927
|
+
200: {
|
|
928
|
+
headers: {
|
|
929
|
+
[name: string]: unknown;
|
|
930
|
+
};
|
|
931
|
+
content: {
|
|
932
|
+
'application/json': components['schemas']['TerritoryResolveResponseDto'];
|
|
933
|
+
};
|
|
934
|
+
};
|
|
935
|
+
/** @description Missing or invalid API key. */
|
|
936
|
+
401: {
|
|
937
|
+
headers: {
|
|
938
|
+
[name: string]: unknown;
|
|
939
|
+
};
|
|
940
|
+
content?: never;
|
|
941
|
+
};
|
|
942
|
+
};
|
|
943
|
+
};
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
type ApiPaths = paths;
|
|
947
|
+
type ApiSchemas = components['schemas'];
|
|
948
|
+
type GeocodeRequest = ApiSchemas['GeocodeRequestDto'];
|
|
949
|
+
type GeocodeBatchRequest = ApiSchemas['GeocodeBatchRequestDto'];
|
|
950
|
+
type GeocodeResult = ApiSchemas['GeocodeResultDto'];
|
|
951
|
+
type GeocodeBatchResponse = ApiSchemas['GeocodeBatchResponseDto'];
|
|
952
|
+
type ReverseGeocodeRequest = ApiSchemas['ReverseGeocodeRequestDto'];
|
|
953
|
+
type ReverseGeocodeResult = ApiSchemas['ReverseGeocodeResultDto'];
|
|
954
|
+
type TerritoryStatus = ApiSchemas['TerritoryStatusDto'];
|
|
955
|
+
type TerritoryResolveRequest = ApiSchemas['TerritoryResolveRequestDto'];
|
|
956
|
+
type TerritoryResolveResponse = ApiSchemas['TerritoryResolveResponseDto'];
|
|
957
|
+
type TerritoryPointResult = ApiSchemas['TerritoryPointResultDto'];
|
|
958
|
+
type TerritoryOmi = ApiSchemas['TerritoryOmiDto'];
|
|
959
|
+
type TerritoryComune = ApiSchemas['TerritoryComuneDto'];
|
|
960
|
+
type TerritoryComuneDetail = ApiSchemas['TerritoryComuneDetailDto'];
|
|
961
|
+
type TerritoryDatasets = ApiSchemas['TerritoryDatasetsDto'];
|
|
962
|
+
type TerritoryComuniPage = ApiSchemas['TerritoryComuniPageDto'];
|
|
963
|
+
type TerritoryComuneRiga = ApiSchemas['TerritoryComuneRigaDto'];
|
|
964
|
+
type TerritoryQuotazioniPage = ApiSchemas['TerritoryQuotazioniPageDto'];
|
|
965
|
+
type TerritoryQuotazione = ApiSchemas['TerritoryQuotazioneDto'];
|
|
966
|
+
type TerritoryCompravenditePage = ApiSchemas['TerritoryCompravenditePageDto'];
|
|
967
|
+
type TerritoryCompravendita = ApiSchemas['TerritoryCompravenditaDto'];
|
|
968
|
+
|
|
969
|
+
type TerritoryComuniQuery = NonNullable<ApiPaths['/territory/comuni']['get']['parameters']['query']>;
|
|
970
|
+
type TerritoryQuotazioniQuery = NonNullable<ApiPaths['/territory/quotazioni']['get']['parameters']['query']>;
|
|
971
|
+
type TerritoryCompravenditeQuery = NonNullable<ApiPaths['/territory/compravendite']['get']['parameters']['query']>;
|
|
972
|
+
interface RequestOptions {
|
|
973
|
+
signal?: AbortSignal;
|
|
974
|
+
}
|
|
975
|
+
interface GeoClientOptions {
|
|
976
|
+
/** Complete API root, including /api. Relative roots are supported in browsers. */
|
|
977
|
+
baseUrl: string;
|
|
978
|
+
/** Omit only when a trusted same-origin backend supplies the API key. */
|
|
979
|
+
apiKey?: string;
|
|
980
|
+
/** A real Fetch implementation returning a Response, not a parsed-body $fetch. */
|
|
981
|
+
fetch?: (request: Request) => Promise<Response>;
|
|
982
|
+
}
|
|
983
|
+
interface TerritoryClient {
|
|
984
|
+
status(options?: RequestOptions): Promise<TerritoryStatus>;
|
|
985
|
+
datasets(options?: RequestOptions): Promise<TerritoryDatasets>;
|
|
986
|
+
comuni(query?: TerritoryComuniQuery, options?: RequestOptions): Promise<TerritoryComuniPage>;
|
|
987
|
+
quotazioni(query?: TerritoryQuotazioniQuery, options?: RequestOptions): Promise<TerritoryQuotazioniPage>;
|
|
988
|
+
compravendite(query?: TerritoryCompravenditeQuery, options?: RequestOptions): Promise<TerritoryCompravenditePage>;
|
|
989
|
+
comune(codComune: string, options?: RequestOptions): Promise<TerritoryComuneDetail>;
|
|
990
|
+
resolve(input: TerritoryResolveRequest, options?: RequestOptions): Promise<TerritoryResolveResponse>;
|
|
991
|
+
}
|
|
992
|
+
interface GeoClient {
|
|
993
|
+
geocode(input: GeocodeRequest, options?: RequestOptions): Promise<GeocodeResult>;
|
|
994
|
+
geocodeBatch(input: GeocodeBatchRequest, options?: RequestOptions): Promise<GeocodeBatchResponse>;
|
|
995
|
+
reverseGeocode(input: ReverseGeocodeRequest, options?: RequestOptions): Promise<ReverseGeocodeResult>;
|
|
996
|
+
territory: TerritoryClient;
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
declare function createGeoClient(options: GeoClientOptions): GeoClient;
|
|
1000
|
+
|
|
1001
|
+
export { ApiError, createGeoClient };
|
|
1002
|
+
export type { GeoClient, GeoClientOptions, GeocodeBatchRequest, GeocodeBatchResponse, GeocodeRequest, GeocodeResult, RequestOptions, ReverseGeocodeRequest, ReverseGeocodeResult, TerritoryClient, TerritoryCompravendita, TerritoryCompravenditePage, TerritoryCompravenditeQuery, TerritoryComune, TerritoryComuneDetail, TerritoryComuneRiga, TerritoryComuniPage, TerritoryComuniQuery, TerritoryDatasets, TerritoryOmi, TerritoryPointResult, TerritoryQuotazione, TerritoryQuotazioniPage, TerritoryQuotazioniQuery, TerritoryResolveRequest, TerritoryResolveResponse, TerritoryStatus };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// src/api-error.ts
|
|
2
|
+
var ApiError = class extends Error {
|
|
3
|
+
constructor(response, body) {
|
|
4
|
+
super(`Geo API request failed with status ${response.status}`);
|
|
5
|
+
this.body = body;
|
|
6
|
+
this.name = "ApiError";
|
|
7
|
+
this.status = response.status;
|
|
8
|
+
this.headers = new Headers(response.headers);
|
|
9
|
+
this.requestId = response.headers.get("x-request-id") ?? void 0;
|
|
10
|
+
}
|
|
11
|
+
body;
|
|
12
|
+
status;
|
|
13
|
+
headers;
|
|
14
|
+
requestId;
|
|
15
|
+
};
|
|
16
|
+
async function readErrorBody(response) {
|
|
17
|
+
const text = await response.text();
|
|
18
|
+
if (!text) return void 0;
|
|
19
|
+
try {
|
|
20
|
+
return JSON.parse(text);
|
|
21
|
+
} catch {
|
|
22
|
+
return text;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// src/client.ts
|
|
27
|
+
import createClient from "openapi-fetch";
|
|
28
|
+
function apiBaseUrl(baseUrl) {
|
|
29
|
+
const url = new URL(baseUrl, globalThis.location?.href);
|
|
30
|
+
if (!["http:", "https:"].includes(url.protocol) || url.username || url.password || url.search || url.hash) {
|
|
31
|
+
throw new TypeError(
|
|
32
|
+
"baseUrl must be an HTTP(S) API root without credentials, query or fragment"
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
return url.href.replace(/\/+$/, "");
|
|
36
|
+
}
|
|
37
|
+
async function data(request) {
|
|
38
|
+
const result = await request;
|
|
39
|
+
if (result.data === void 0) throw new SyntaxError("Geo API returned an empty JSON response");
|
|
40
|
+
return result.data;
|
|
41
|
+
}
|
|
42
|
+
function territory(client) {
|
|
43
|
+
return {
|
|
44
|
+
status: (options) => data(client.GET("/territory/status", { ...options })),
|
|
45
|
+
datasets: (options) => data(client.GET("/territory/datasets", { ...options })),
|
|
46
|
+
comuni: (query, options) => data(client.GET("/territory/comuni", { ...options, params: { query } })),
|
|
47
|
+
quotazioni: (query, options) => data(client.GET("/territory/quotazioni", { ...options, params: { query } })),
|
|
48
|
+
compravendite: (query, options) => data(client.GET("/territory/compravendite", { ...options, params: { query } })),
|
|
49
|
+
comune: (codComune, options) => data(
|
|
50
|
+
client.GET("/territory/comuni/{codComune}", {
|
|
51
|
+
...options,
|
|
52
|
+
params: { path: { codComune } }
|
|
53
|
+
})
|
|
54
|
+
),
|
|
55
|
+
resolve: (input, options) => data(client.POST("/territory/resolve", { ...options, body: input }))
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function createGeoClient(options) {
|
|
59
|
+
const client = createClient({
|
|
60
|
+
baseUrl: apiBaseUrl(options.baseUrl),
|
|
61
|
+
fetch: options.fetch,
|
|
62
|
+
headers: options.apiKey ? { "x-api-key": options.apiKey } : void 0
|
|
63
|
+
});
|
|
64
|
+
client.use({
|
|
65
|
+
async onResponse({ response }) {
|
|
66
|
+
if (!response.ok) throw new ApiError(response, await readErrorBody(response));
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
return {
|
|
70
|
+
geocode: (input, request) => data(client.POST("/geocode", { ...request, body: input })),
|
|
71
|
+
geocodeBatch: (input, request) => data(client.POST("/geocode/batch", { ...request, body: input })),
|
|
72
|
+
reverseGeocode: (input, request) => data(client.POST("/geocode/reverse", { ...request, body: input })),
|
|
73
|
+
territory: territory(client)
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
export {
|
|
77
|
+
ApiError,
|
|
78
|
+
createGeoClient
|
|
79
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,50 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
"name": "@seta-labs/geo",
|
|
3
|
+
"version": "0.1.0-next.0",
|
|
4
|
+
"description": "Typed Fetch client for the Seta Geo HTTP API",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"main": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md"
|
|
19
|
+
],
|
|
20
|
+
"engines": {
|
|
21
|
+
"node": ">=22"
|
|
22
|
+
},
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/Seta-Labs/seta-geo.git",
|
|
26
|
+
"directory": "packages/sdk"
|
|
27
|
+
},
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public",
|
|
30
|
+
"tag": "next",
|
|
31
|
+
"provenance": false
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "tsup",
|
|
35
|
+
"lint": "eslint src tsup.config.ts",
|
|
36
|
+
"lint:fix": "eslint --fix src tsup.config.ts",
|
|
37
|
+
"typecheck": "tsc --noEmit",
|
|
38
|
+
"test:unit": "vitest run src"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"openapi-fetch": "^0.17.0"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@seta-geo/types": "workspace:*",
|
|
45
|
+
"@seta-labs/config": "^0.16.1",
|
|
46
|
+
"tsup": "^9.0.0",
|
|
47
|
+
"typescript": "^6.0.3",
|
|
48
|
+
"vitest": "^5.0.3"
|
|
49
|
+
}
|
|
50
|
+
}
|