@seta-labs/geo 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/CHANGELOG.md +9 -0
- package/README.md +7 -0
- package/dist/index.d.ts +65 -11
- package/dist/index.js +19 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @seta-labs/geo
|
|
2
2
|
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
- `geocode`, `geocodeBatch`, `reverseGeocode` and `cadastreParcel` take
|
|
6
|
+
`cache: { refresh, noStore, maxAge, onlyIfCached }`, sent as
|
|
7
|
+
`Cache-Control` (`no-cache`, `no-store`, `max-age`, `only-if-cached`).
|
|
8
|
+
Without it nothing changes. New types `LookupCache` and `LookupOptions`.
|
|
9
|
+
- A lookup refused by `onlyIfCached` rejects with `ApiError` 504
|
|
10
|
+
(`code: 'NOT_CACHED'`); a batch item has `status: 'NOT_CACHED'`.
|
|
11
|
+
|
|
3
12
|
## 0.2.0
|
|
4
13
|
|
|
5
14
|
- New `cadastreParcel({ lat, lng })` on `POST /cadastre/parcel`: what the AdE
|
package/README.md
CHANGED
|
@@ -64,6 +64,13 @@ OpenAPI remains authoritative: TypeScript provides static types, not runtime
|
|
|
64
64
|
validation of received data. `include` may be omitted and defaults to `best`
|
|
65
65
|
on the service.
|
|
66
66
|
|
|
67
|
+
The four lookups (`geocode`, `geocodeBatch`, `reverseGeocode`,
|
|
68
|
+
`cadastreParcel`) take `cache` in their options, sent as `Cache-Control`:
|
|
69
|
+
`{ refresh: true }` asks the provider again and stores the new answer,
|
|
70
|
+
`{ refresh: true, noStore: true }` bypasses the store entirely, `{ maxAge }`
|
|
71
|
+
asks again past that many seconds, `{ onlyIfCached: true }` never asks the
|
|
72
|
+
provider (504 `NOT_CACHED`, or `status: 'NOT_CACHED'` for a batch item).
|
|
73
|
+
|
|
67
74
|
HTTP errors are `ApiError`; their body is JSON when parseable, otherwise text,
|
|
68
75
|
or `undefined` for an empty response. A `503` from `cadastreParcel` with
|
|
69
76
|
`code: 'CADASTRE_BLOCKED'` means the cadastral map is refusing calls: its
|
package/dist/index.d.ts
CHANGED
|
@@ -355,8 +355,11 @@ interface components {
|
|
|
355
355
|
include?: 'best' | 'full';
|
|
356
356
|
};
|
|
357
357
|
GeocodeResultDto: {
|
|
358
|
-
/**
|
|
359
|
-
|
|
358
|
+
/**
|
|
359
|
+
* @description NOT_CACHED: a batch item refused by Cache-Control only-if-cached.
|
|
360
|
+
* @enum {string}
|
|
361
|
+
*/
|
|
362
|
+
status: 'OK' | 'NO_RESULT' | 'INVALID_QUERY' | 'NOT_CACHED';
|
|
360
363
|
/** @description The normalized query actually used as cache key and provider input. */
|
|
361
364
|
query: string | null;
|
|
362
365
|
lat: number | null;
|
|
@@ -652,7 +655,10 @@ interface operations {
|
|
|
652
655
|
GeocodeController_geocode: {
|
|
653
656
|
parameters: {
|
|
654
657
|
query?: never;
|
|
655
|
-
header?:
|
|
658
|
+
header?: {
|
|
659
|
+
/** @description no-cache: ask the provider and store its answer; no-store: never write the store; max-age=N: a stored answer older than N seconds is asked again; only-if-cached: never ask the provider. The response says what happened in Cache-Status (hit, fwd=miss|request|stale, stored) and, on a hit, Age. */
|
|
660
|
+
'Cache-Control'?: string;
|
|
661
|
+
};
|
|
656
662
|
path?: never;
|
|
657
663
|
cookie?: never;
|
|
658
664
|
};
|
|
@@ -684,12 +690,22 @@ interface operations {
|
|
|
684
690
|
};
|
|
685
691
|
content?: never;
|
|
686
692
|
};
|
|
693
|
+
/** @description NOT_CACHED: only-if-cached and no usable stored answer. */
|
|
694
|
+
504: {
|
|
695
|
+
headers: {
|
|
696
|
+
[name: string]: unknown;
|
|
697
|
+
};
|
|
698
|
+
content?: never;
|
|
699
|
+
};
|
|
687
700
|
};
|
|
688
701
|
};
|
|
689
702
|
GeocodeController_geocodeBatch: {
|
|
690
703
|
parameters: {
|
|
691
704
|
query?: never;
|
|
692
|
-
header?:
|
|
705
|
+
header?: {
|
|
706
|
+
/** @description Applies to every item: no-cache, no-store, max-age=N, only-if-cached. An item only-if-cached refuses has status NOT_CACHED; the batch still answers 200. */
|
|
707
|
+
'Cache-Control'?: string;
|
|
708
|
+
};
|
|
693
709
|
path?: never;
|
|
694
710
|
cookie?: never;
|
|
695
711
|
};
|
|
@@ -726,7 +742,10 @@ interface operations {
|
|
|
726
742
|
GeocodeController_reverseGeocode: {
|
|
727
743
|
parameters: {
|
|
728
744
|
query?: never;
|
|
729
|
-
header?:
|
|
745
|
+
header?: {
|
|
746
|
+
/** @description no-cache: ask the provider and store its answer; no-store: never write the store; max-age=N: a stored answer older than N seconds is asked again; only-if-cached: never ask the provider. The response says what happened in Cache-Status (hit, fwd=miss|request|stale, stored) and, on a hit, Age. */
|
|
747
|
+
'Cache-Control'?: string;
|
|
748
|
+
};
|
|
730
749
|
path?: never;
|
|
731
750
|
cookie?: never;
|
|
732
751
|
};
|
|
@@ -758,12 +777,22 @@ interface operations {
|
|
|
758
777
|
};
|
|
759
778
|
content?: never;
|
|
760
779
|
};
|
|
780
|
+
/** @description NOT_CACHED: only-if-cached and no usable stored answer. */
|
|
781
|
+
504: {
|
|
782
|
+
headers: {
|
|
783
|
+
[name: string]: unknown;
|
|
784
|
+
};
|
|
785
|
+
content?: never;
|
|
786
|
+
};
|
|
761
787
|
};
|
|
762
788
|
};
|
|
763
789
|
CadastreController_parcel: {
|
|
764
790
|
parameters: {
|
|
765
791
|
query?: never;
|
|
766
|
-
header?:
|
|
792
|
+
header?: {
|
|
793
|
+
/** @description no-cache: ask the provider and store its answer; no-store: never write the store; max-age=N: a stored answer older than N seconds is asked again; only-if-cached: never ask the provider. The response says what happened in Cache-Status (hit, fwd=miss|request|stale, stored) and, on a hit, Age. */
|
|
794
|
+
'Cache-Control'?: string;
|
|
795
|
+
};
|
|
767
796
|
path?: never;
|
|
768
797
|
cookie?: never;
|
|
769
798
|
};
|
|
@@ -803,6 +832,13 @@ interface operations {
|
|
|
803
832
|
};
|
|
804
833
|
content?: never;
|
|
805
834
|
};
|
|
835
|
+
/** @description NOT_CACHED: only-if-cached and no usable stored answer. */
|
|
836
|
+
504: {
|
|
837
|
+
headers: {
|
|
838
|
+
[name: string]: unknown;
|
|
839
|
+
};
|
|
840
|
+
content?: never;
|
|
841
|
+
};
|
|
806
842
|
};
|
|
807
843
|
};
|
|
808
844
|
TerritoryController_status: {
|
|
@@ -1065,6 +1101,23 @@ type TerritoryCompravenditeQuery = NonNullable<ApiPaths['/territory/compravendit
|
|
|
1065
1101
|
interface RequestOptions {
|
|
1066
1102
|
signal?: AbortSignal;
|
|
1067
1103
|
}
|
|
1104
|
+
/**
|
|
1105
|
+
* How a lookup may use seta-geo's store, sent as `Cache-Control` (RFC 9111).
|
|
1106
|
+
* Without it the store answers when it can and the provider otherwise.
|
|
1107
|
+
*/
|
|
1108
|
+
interface LookupCache {
|
|
1109
|
+
/** `no-cache`: ask the provider even with a stored answer, and store the new one. */
|
|
1110
|
+
refresh?: boolean;
|
|
1111
|
+
/** `no-store`: never write the provider's answer (with `refresh`: a pure bypass). */
|
|
1112
|
+
noStore?: boolean;
|
|
1113
|
+
/** `max-age`: a stored answer older than this many seconds is asked again. */
|
|
1114
|
+
maxAge?: number;
|
|
1115
|
+
/** `only-if-cached`: never ask the provider; 504 `NOT_CACHED` without a stored answer. */
|
|
1116
|
+
onlyIfCached?: boolean;
|
|
1117
|
+
}
|
|
1118
|
+
interface LookupOptions extends RequestOptions {
|
|
1119
|
+
cache?: LookupCache;
|
|
1120
|
+
}
|
|
1068
1121
|
interface GeoClientOptions {
|
|
1069
1122
|
/** Complete API root, including /api. Relative roots are supported in browsers. */
|
|
1070
1123
|
baseUrl: string;
|
|
@@ -1083,15 +1136,16 @@ interface TerritoryClient {
|
|
|
1083
1136
|
resolve(input: TerritoryResolveRequest, options?: RequestOptions): Promise<TerritoryResolveResponse>;
|
|
1084
1137
|
}
|
|
1085
1138
|
interface GeoClient {
|
|
1086
|
-
geocode(input: GeocodeRequest, options?:
|
|
1087
|
-
|
|
1088
|
-
|
|
1139
|
+
geocode(input: GeocodeRequest, options?: LookupOptions): Promise<GeocodeResult>;
|
|
1140
|
+
/** `cache` applies to every item; an item only-if-cached refuses has status NOT_CACHED. */
|
|
1141
|
+
geocodeBatch(input: GeocodeBatchRequest, options?: LookupOptions): Promise<GeocodeBatchResponse>;
|
|
1142
|
+
reverseGeocode(input: ReverseGeocodeRequest, options?: LookupOptions): Promise<ReverseGeocodeResult>;
|
|
1089
1143
|
/** What the AdE cadastral map finds under a point; 503 `CADASTRE_BLOCKED` carries Retry-After. */
|
|
1090
|
-
cadastreParcel(input: CadastreParcelRequest, options?:
|
|
1144
|
+
cadastreParcel(input: CadastreParcelRequest, options?: LookupOptions): Promise<CadastreParcelResult>;
|
|
1091
1145
|
territory: TerritoryClient;
|
|
1092
1146
|
}
|
|
1093
1147
|
|
|
1094
1148
|
declare function createGeoClient(options: GeoClientOptions): GeoClient;
|
|
1095
1149
|
|
|
1096
1150
|
export { ApiError, createGeoClient };
|
|
1097
|
-
export type { CadastreParcelRequest, CadastreParcelResult, 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 };
|
|
1151
|
+
export type { CadastreParcelRequest, CadastreParcelResult, GeoClient, GeoClientOptions, GeocodeBatchRequest, GeocodeBatchResponse, GeocodeRequest, GeocodeResult, LookupCache, LookupOptions, 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
CHANGED
|
@@ -39,6 +39,21 @@ async function data(request) {
|
|
|
39
39
|
if (result.data === void 0) throw new SyntaxError("Geo API returned an empty JSON response");
|
|
40
40
|
return result.data;
|
|
41
41
|
}
|
|
42
|
+
function cacheControl(cache) {
|
|
43
|
+
if (!cache) return void 0;
|
|
44
|
+
const directives = [
|
|
45
|
+
cache.refresh ? "no-cache" : void 0,
|
|
46
|
+
cache.noStore ? "no-store" : void 0,
|
|
47
|
+
cache.maxAge === void 0 ? void 0 : `max-age=${Math.max(0, Math.floor(cache.maxAge))}`,
|
|
48
|
+
cache.onlyIfCached ? "only-if-cached" : void 0
|
|
49
|
+
].filter((directive) => directive !== void 0);
|
|
50
|
+
return directives.length > 0 ? directives.join(", ") : void 0;
|
|
51
|
+
}
|
|
52
|
+
function lookupInit(options) {
|
|
53
|
+
const { cache, ...request } = options ?? {};
|
|
54
|
+
const header = cacheControl(cache);
|
|
55
|
+
return header ? { ...request, headers: { "cache-control": header } } : request;
|
|
56
|
+
}
|
|
42
57
|
function territory(client) {
|
|
43
58
|
return {
|
|
44
59
|
status: (options) => data(client.GET("/territory/status", { ...options })),
|
|
@@ -67,10 +82,10 @@ function createGeoClient(options) {
|
|
|
67
82
|
}
|
|
68
83
|
});
|
|
69
84
|
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
|
-
cadastreParcel: (input, request) => data(client.POST("/cadastre/parcel", { ...request, body: input })),
|
|
85
|
+
geocode: (input, request) => data(client.POST("/geocode", { ...lookupInit(request), body: input })),
|
|
86
|
+
geocodeBatch: (input, request) => data(client.POST("/geocode/batch", { ...lookupInit(request), body: input })),
|
|
87
|
+
reverseGeocode: (input, request) => data(client.POST("/geocode/reverse", { ...lookupInit(request), body: input })),
|
|
88
|
+
cadastreParcel: (input, request) => data(client.POST("/cadastre/parcel", { ...lookupInit(request), body: input })),
|
|
74
89
|
territory: territory(client)
|
|
75
90
|
};
|
|
76
91
|
}
|