@tileflow/static 0.1.0-alpha.27 → 0.1.0-alpha.29
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 +15 -19
- package/dist/client.d.ts +1 -1
- package/dist/client.js +360 -14
- package/dist/manifest.d.ts +5 -5
- package/dist/manifest.js +322 -17
- package/dist/overlays.d.ts +2 -2
- package/dist/overlays.js +164 -8
- package/dist/{scene-contract-Cr6BNLz0.d.ts → scene-contract-NFnIcQtt.d.ts} +13 -13
- package/dist/scene.d.ts +14 -14
- package/package.json +3 -10
- package/dist/chunk-4GPRPR33.js +0 -380
- package/dist/chunk-4MXFTGQV.js +0 -340
- package/dist/chunk-HVVIAOBE.js +0 -175
- package/dist/index.d.ts +0 -7
- package/dist/index.js +0 -116
package/README.md
CHANGED
|
@@ -31,12 +31,9 @@ silently share another scene's identity.
|
|
|
31
31
|
<!-- docs:check -->
|
|
32
32
|
|
|
33
33
|
```ts
|
|
34
|
-
import {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
marker,
|
|
38
|
-
validateStaticScene,
|
|
39
|
-
} from '@tileflow/static';
|
|
34
|
+
import {createStaticMap, createStaticMapIdempotencyKey} from '@tileflow/static/client';
|
|
35
|
+
import {marker} from '@tileflow/static/overlays';
|
|
36
|
+
import {validateStaticScene} from '@tileflow/static/scene';
|
|
40
37
|
|
|
41
38
|
const apiKey = process.env.TILEFLOW_API_KEY;
|
|
42
39
|
if (!apiKey) throw new Error('Set TILEFLOW_API_KEY on the server.');
|
|
@@ -99,7 +96,7 @@ preserved within each placement; later overlays paint above earlier overlays in
|
|
|
99
96
|
Use `symbol` for a deployed sprite icon, renderer-owned text, or both:
|
|
100
97
|
|
|
101
98
|
```ts
|
|
102
|
-
import {symbol} from '@tileflow/static';
|
|
99
|
+
import {symbol} from '@tileflow/static/overlays';
|
|
103
100
|
|
|
104
101
|
symbol({
|
|
105
102
|
coordinate: [-3.7038, 40.4168],
|
|
@@ -155,7 +152,7 @@ Choose a corner when composition requires it:
|
|
|
155
152
|
<!-- docs:check -->
|
|
156
153
|
|
|
157
154
|
```ts
|
|
158
|
-
import type {StaticAttributionRequest} from '@tileflow/static';
|
|
155
|
+
import type {StaticAttributionRequest} from '@tileflow/static/scene';
|
|
159
156
|
|
|
160
157
|
const attribution = {
|
|
161
158
|
mode: 'embedded',
|
|
@@ -168,7 +165,7 @@ Or request structured external attribution:
|
|
|
168
165
|
<!-- docs:check -->
|
|
169
166
|
|
|
170
167
|
```ts
|
|
171
|
-
import {createStaticMap, createStaticMapIdempotencyKey} from '@tileflow/static';
|
|
168
|
+
import {createStaticMap, createStaticMapIdempotencyKey} from '@tileflow/static/client';
|
|
172
169
|
|
|
173
170
|
const apiKey = process.env.TILEFLOW_API_KEY;
|
|
174
171
|
if (!apiKey) throw new Error('Set TILEFLOW_API_KEY on the server.');
|
|
@@ -251,19 +248,18 @@ operation or API-unit charge. A different `403` is a credential or Map-coverage
|
|
|
251
248
|
|
|
252
249
|
## API entry points
|
|
253
250
|
|
|
254
|
-
The package has four deliberately separate
|
|
251
|
+
The package has four deliberately separate entry points:
|
|
255
252
|
|
|
256
|
-
- scene validation and normalization: `staticSceneSchema`,
|
|
257
|
-
`normalizeStaticScene`;
|
|
258
|
-
- overlay authoring and MapLibre compilation: `line`, `circle`,
|
|
259
|
-
`compileStaticOverlays`;
|
|
260
|
-
- renderer identity: `createRenderManifest`,
|
|
253
|
+
- `@tileflow/static/scene`, scene validation and normalization: `staticSceneSchema`,
|
|
254
|
+
`validateStaticScene`, and `normalizeStaticScene`;
|
|
255
|
+
- `@tileflow/static/overlays`, overlay authoring and MapLibre compilation: `line`, `circle`,
|
|
256
|
+
`marker`, `polygon`, `symbol`, and `compileStaticOverlays`;
|
|
257
|
+
- `@tileflow/static/manifest`, renderer identity: `createRenderManifest`,
|
|
261
258
|
`validateStaticRenderManifest`, `hashRenderManifest`, and `hashStaticSceneRequest`;
|
|
262
|
-
- bounded Hosted transport: `prepareStaticMapRequest`,
|
|
263
|
-
`requestStaticMapUntilReady`.
|
|
259
|
+
- `@tileflow/static/client`, bounded Hosted transport: `prepareStaticMapRequest`,
|
|
260
|
+
`createStaticMap`, `precacheStaticMap`, and `requestStaticMapUntilReady`.
|
|
264
261
|
|
|
265
|
-
|
|
266
|
-
or `/client`. The root remains a compatibility entry point.
|
|
262
|
+
The package has no root entry point.
|
|
267
263
|
|
|
268
264
|
`StaticRenderManifest` is the single strict immutable input contract between a resolved Hosted style
|
|
269
265
|
and a Static Maps renderer. It binds safe attribution, exact source identity, semantic placement
|
package/dist/client.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
export { S as StaticMapError, a as StaticMapErrorResponse, s as staticMapErrorResponseSchema } from './errors-CSz1xaDx.js';
|
|
3
|
-
import {
|
|
3
|
+
import { S as StaticAttributionPosition, a as StaticSceneInput } from './scene-contract-NFnIcQtt.js';
|
|
4
4
|
|
|
5
5
|
declare function stableStringify(value: unknown): string;
|
|
6
6
|
|
package/dist/client.js
CHANGED
|
@@ -1,23 +1,369 @@
|
|
|
1
|
-
import {
|
|
2
|
-
STATIC_MAP_RESULT_MEDIA_TYPE,
|
|
3
|
-
createStaticMap,
|
|
4
|
-
createStaticMapIdempotencyKey,
|
|
5
|
-
precacheStaticMap,
|
|
6
|
-
prepareStaticMapRequest,
|
|
7
|
-
requestStaticMapUntilReady,
|
|
8
|
-
staticMapAttributionEntrySchema,
|
|
9
|
-
staticMapAttributionResultSchema,
|
|
10
|
-
staticMapHostedResultSchema,
|
|
11
|
-
staticMapProcessingResultSchema,
|
|
12
|
-
validateStaticMapIdempotencyKey
|
|
13
|
-
} from "./chunk-4GPRPR33.js";
|
|
14
1
|
import {
|
|
15
2
|
StaticMapError,
|
|
16
|
-
|
|
3
|
+
StaticMapRequestError,
|
|
4
|
+
staticMapErrorResponseSchema,
|
|
5
|
+
staticMapRequestErrorResponseSchema,
|
|
6
|
+
validateStaticScene
|
|
17
7
|
} from "./chunk-ALFVZ3PC.js";
|
|
18
8
|
import {
|
|
9
|
+
isSafeHttpUrl,
|
|
10
|
+
jsonByteLength,
|
|
19
11
|
stableStringify
|
|
20
12
|
} from "./chunk-6DWVCK64.js";
|
|
13
|
+
|
|
14
|
+
// src/client.ts
|
|
15
|
+
import { z } from "zod";
|
|
16
|
+
var maxStaticMapResponseBytes = 64 * 1024;
|
|
17
|
+
var staticMapIdempotencyKeyPattern = /^[A-Za-z0-9][A-Za-z0-9._:-]{7,127}$/;
|
|
18
|
+
var STATIC_MAP_RESULT_MEDIA_TYPE = "application/vnd.tileflow.static-map-result+json;version=1";
|
|
19
|
+
var preparedStaticMapRequestBodies = /* @__PURE__ */ new WeakMap();
|
|
20
|
+
var staticMapReadyResultBaseSchema = z.object({
|
|
21
|
+
cached: z.boolean(),
|
|
22
|
+
hash: z.string().regex(/^[A-Za-z0-9_-]{43}$/),
|
|
23
|
+
imageUrl: z.string().trim().url().max(2048).refine(isSafeHttpUrl, { message: "Expected an http(s) URL without credentials" }),
|
|
24
|
+
operationId: z.string().min(20).max(68),
|
|
25
|
+
remainingUnits: z.number().int().nonnegative().nullable(),
|
|
26
|
+
status: z.literal("ready"),
|
|
27
|
+
unitCost: z.literal(15)
|
|
28
|
+
}).strict();
|
|
29
|
+
var safeAttributionTextSchema = z.string().min(1).max(16384).refine(hasNoControlCharacters, { message: "Attribution text contains control characters" });
|
|
30
|
+
var staticMapAttributionEntrySchema = z.object({
|
|
31
|
+
authority: z.enum(["platform-notice", "team-declared"]),
|
|
32
|
+
links: z.array(
|
|
33
|
+
z.object({
|
|
34
|
+
label: safeAttributionTextSchema,
|
|
35
|
+
url: z.string().trim().url().max(2048).refine(isSafeHttpUrl, {
|
|
36
|
+
message: "Expected an http(s) URL without credentials or a fragment"
|
|
37
|
+
})
|
|
38
|
+
}).strict()
|
|
39
|
+
).max(8),
|
|
40
|
+
text: safeAttributionTextSchema
|
|
41
|
+
}).strict();
|
|
42
|
+
var staticMapAttributionResultSchema = z.object({
|
|
43
|
+
entries: z.array(staticMapAttributionEntrySchema).max(18),
|
|
44
|
+
mode: z.enum(["embedded", "external"]),
|
|
45
|
+
position: z.enum(["top-left", "top-right", "bottom-left", "bottom-right"]).nullable()
|
|
46
|
+
}).strict().superRefine((result, context) => {
|
|
47
|
+
if (result.mode === "external" && result.position !== null || result.mode === "embedded" && result.position === null) {
|
|
48
|
+
context.addIssue({
|
|
49
|
+
code: "custom",
|
|
50
|
+
message: "Attribution position must match its mode",
|
|
51
|
+
path: ["position"]
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
if (jsonByteLength(result) > 32 * 1024) {
|
|
55
|
+
context.addIssue({ code: "custom", message: "Attribution result exceeds 32 KiB" });
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
var staticMapHostedResultSchema = staticMapReadyResultBaseSchema.extend({
|
|
59
|
+
attribution: staticMapAttributionResultSchema,
|
|
60
|
+
resultVersion: z.literal(1)
|
|
61
|
+
}).strict();
|
|
62
|
+
var staticMapProcessingResultSchema = z.object({
|
|
63
|
+
operationId: z.string().min(20).max(68),
|
|
64
|
+
retryAfterMs: z.number().int().min(0).max(5e3),
|
|
65
|
+
status: z.literal("processing")
|
|
66
|
+
}).strict();
|
|
67
|
+
function validateStaticMapIdempotencyKey(value) {
|
|
68
|
+
if (typeof value !== "string" || !staticMapIdempotencyKeyPattern.test(value)) {
|
|
69
|
+
return {
|
|
70
|
+
error: "Idempotency key must contain 8-128 ASCII letters, digits, dot, underscore, colon, or hyphen and start with a letter or digit",
|
|
71
|
+
ok: false
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
return { key: value, ok: true };
|
|
75
|
+
}
|
|
76
|
+
function createStaticMapIdempotencyKey() {
|
|
77
|
+
const key = `static_${crypto.randomUUID()}`;
|
|
78
|
+
if (!validateStaticMapIdempotencyKey(key).ok) {
|
|
79
|
+
throw new Error("Unable to create a valid Tileflow Static Maps idempotency key");
|
|
80
|
+
}
|
|
81
|
+
return key;
|
|
82
|
+
}
|
|
83
|
+
function prepareStaticMapRequest(scene) {
|
|
84
|
+
const validation = validateStaticScene(scene);
|
|
85
|
+
if (!validation.ok) {
|
|
86
|
+
if (isStaticMapRequestFailure(validation)) {
|
|
87
|
+
const { ok: _ok, ...response } = validation;
|
|
88
|
+
throw new StaticMapRequestError(response);
|
|
89
|
+
}
|
|
90
|
+
throw new Error(`Invalid Tileflow static scene: ${validation.error}`);
|
|
91
|
+
}
|
|
92
|
+
const prepared = Object.freeze({
|
|
93
|
+
sceneKey: stableStringify(validation.scene)
|
|
94
|
+
});
|
|
95
|
+
preparedStaticMapRequestBodies.set(prepared, JSON.stringify(validation.scene));
|
|
96
|
+
return prepared;
|
|
97
|
+
}
|
|
98
|
+
async function createStaticMap(scene, options) {
|
|
99
|
+
return requestStaticMap(scene, options, "/v1/static/maps");
|
|
100
|
+
}
|
|
101
|
+
async function precacheStaticMap(scene, options) {
|
|
102
|
+
return requestStaticMap(scene, options, "/v1/static/maps/precache");
|
|
103
|
+
}
|
|
104
|
+
async function requestStaticMap(scene, options, path) {
|
|
105
|
+
const preparedRequest = prepareStaticMapRequest(scene);
|
|
106
|
+
const { apiUrl = "https://api.tileflow.dev", ...requestOptions } = options;
|
|
107
|
+
return requestStaticMapUntilReady(preparedRequest, {
|
|
108
|
+
...requestOptions,
|
|
109
|
+
createUrl: `${normalizeUrl(apiUrl)}${path}`
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
async function requestStaticMapUntilReady(request, options) {
|
|
113
|
+
const body = preparedStaticMapRequestBodies.get(request);
|
|
114
|
+
if (body === void 0) {
|
|
115
|
+
throw new Error("Tileflow static map request must be created with prepareStaticMapRequest");
|
|
116
|
+
}
|
|
117
|
+
const idempotency = validateStaticMapIdempotencyKey(options.idempotencyKey);
|
|
118
|
+
if (!idempotency.ok) {
|
|
119
|
+
throw new Error(`Invalid Tileflow Static Maps idempotency key: ${idempotency.error}`);
|
|
120
|
+
}
|
|
121
|
+
const maxWaitMs = boundedClientDuration(options.maxWaitMs, 3e4, 100, 12e4, "maxWaitMs");
|
|
122
|
+
const pollIntervalMs = boundedClientDuration(
|
|
123
|
+
options.pollIntervalMs,
|
|
124
|
+
500,
|
|
125
|
+
0,
|
|
126
|
+
5e3,
|
|
127
|
+
"pollIntervalMs"
|
|
128
|
+
);
|
|
129
|
+
const fetcher = options.fetch ?? fetch;
|
|
130
|
+
const createUrl = normalizeStaticMapEndpointUrl(options.createUrl);
|
|
131
|
+
const headers = {
|
|
132
|
+
Accept: STATIC_MAP_RESULT_MEDIA_TYPE,
|
|
133
|
+
"Content-Type": "application/json",
|
|
134
|
+
"Idempotency-Key": idempotency.key
|
|
135
|
+
};
|
|
136
|
+
if (options.apiKey) {
|
|
137
|
+
headers.Authorization = `Bearer ${options.apiKey}`;
|
|
138
|
+
}
|
|
139
|
+
if (options.mapId !== void 0) {
|
|
140
|
+
if (!/^map_[A-Za-z0-9_-]{16}$/u.test(options.mapId)) {
|
|
141
|
+
throw new Error("Invalid Tileflow Map ID.");
|
|
142
|
+
}
|
|
143
|
+
headers["X-Tileflow-Map-Id"] = options.mapId;
|
|
144
|
+
}
|
|
145
|
+
return runWithinStaticMapBudget(maxWaitMs, options.signal, async (signal) => {
|
|
146
|
+
let operationId = null;
|
|
147
|
+
while (true) {
|
|
148
|
+
const response = await fetcher(createUrl, {
|
|
149
|
+
body,
|
|
150
|
+
headers,
|
|
151
|
+
method: "POST",
|
|
152
|
+
signal
|
|
153
|
+
});
|
|
154
|
+
throwIfAborted(signal);
|
|
155
|
+
if (!response.ok) {
|
|
156
|
+
const errorBody = await readStaticMapErrorBody(response, 8 * 1024);
|
|
157
|
+
throwIfAborted(signal);
|
|
158
|
+
if (response.status === 422) {
|
|
159
|
+
const requestError = staticMapRequestErrorResponseSchema.safeParse(errorBody);
|
|
160
|
+
if (requestError.success) {
|
|
161
|
+
throw new StaticMapRequestError(requestError.data, response.status);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
const structured = staticMapErrorResponseSchema.safeParse(errorBody);
|
|
165
|
+
if (structured.success) {
|
|
166
|
+
throw new StaticMapError(structured.data, response.status);
|
|
167
|
+
}
|
|
168
|
+
throw new Error(`Tileflow static map failed (${response.status}).`);
|
|
169
|
+
}
|
|
170
|
+
const json = await readJsonResponse(response);
|
|
171
|
+
throwIfAborted(signal);
|
|
172
|
+
if (response.status !== 202) {
|
|
173
|
+
const parsed = staticMapHostedResultSchema.safeParse(json);
|
|
174
|
+
if (!parsed.success) {
|
|
175
|
+
throw new Error(
|
|
176
|
+
`Tileflow static map returned an invalid response: ${parsed.error.message}`
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
assertStaticMapOperationIdentity(operationId, parsed.data.operationId);
|
|
180
|
+
return parsed.data;
|
|
181
|
+
}
|
|
182
|
+
const pending = staticMapProcessingResultSchema.safeParse(json);
|
|
183
|
+
if (!pending.success) {
|
|
184
|
+
throw new Error(
|
|
185
|
+
`Tileflow static map returned an invalid response: ${pending.error.message}`
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
assertStaticMapOperationIdentity(operationId, pending.data.operationId);
|
|
189
|
+
operationId ??= pending.data.operationId;
|
|
190
|
+
await delay(Math.max(pollIntervalMs, pending.data.retryAfterMs), signal);
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
function hasNoControlCharacters(value) {
|
|
195
|
+
return !Array.from(value).some((character) => {
|
|
196
|
+
const codePoint = character.codePointAt(0) ?? 0;
|
|
197
|
+
return codePoint <= 31 || codePoint === 127;
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
function boundedClientDuration(value, fallback, minimum, maximum, name) {
|
|
201
|
+
const resolved = value ?? fallback;
|
|
202
|
+
if (!Number.isSafeInteger(resolved) || resolved < minimum || resolved > maximum) {
|
|
203
|
+
throw new Error(
|
|
204
|
+
`Tileflow Static Maps ${name} must be an integer from ${minimum} to ${maximum}`
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
return resolved;
|
|
208
|
+
}
|
|
209
|
+
async function readJsonResponse(response) {
|
|
210
|
+
const source = await readBoundedResponseText(response, maxStaticMapResponseBytes, "64 KiB");
|
|
211
|
+
try {
|
|
212
|
+
return JSON.parse(source);
|
|
213
|
+
} catch {
|
|
214
|
+
throw new Error("Tileflow static map returned an invalid response: expected JSON");
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
async function readStaticMapErrorBody(response, maximumBytes) {
|
|
218
|
+
try {
|
|
219
|
+
const source = await readBoundedResponseText(response, maximumBytes, `${maximumBytes} bytes`);
|
|
220
|
+
return JSON.parse(source);
|
|
221
|
+
} catch {
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
function isStaticMapRequestFailure(value) {
|
|
226
|
+
if (!("code" in value)) return false;
|
|
227
|
+
const { ok: _ok, ...response } = value;
|
|
228
|
+
return staticMapRequestErrorResponseSchema.safeParse(response).success;
|
|
229
|
+
}
|
|
230
|
+
async function readBoundedResponseText(response, maximumBytes, displayLimit) {
|
|
231
|
+
if (!response.body) return "";
|
|
232
|
+
const reader = response.body.getReader();
|
|
233
|
+
const chunks = [];
|
|
234
|
+
let byteLength = 0;
|
|
235
|
+
while (true) {
|
|
236
|
+
const { done, value } = await reader.read();
|
|
237
|
+
if (done) break;
|
|
238
|
+
byteLength += value.byteLength;
|
|
239
|
+
if (byteLength > maximumBytes) {
|
|
240
|
+
await reader.cancel();
|
|
241
|
+
throw new Error(
|
|
242
|
+
`Tileflow static map returned an invalid response: response exceeded ${displayLimit}`
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
chunks.push(value);
|
|
246
|
+
}
|
|
247
|
+
const bytes = new Uint8Array(byteLength);
|
|
248
|
+
let offset = 0;
|
|
249
|
+
for (const chunk of chunks) {
|
|
250
|
+
bytes.set(chunk, offset);
|
|
251
|
+
offset += chunk.byteLength;
|
|
252
|
+
}
|
|
253
|
+
try {
|
|
254
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
255
|
+
} catch {
|
|
256
|
+
throw new Error("Tileflow static map returned an invalid response: expected UTF-8 JSON");
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
async function runWithinStaticMapBudget(maxWaitMs, externalSignal, operation) {
|
|
260
|
+
const controller = new AbortController();
|
|
261
|
+
const timeoutError = new Error(`Tileflow static map timed out after ${maxWaitMs}ms`);
|
|
262
|
+
const abortFromCaller = () => controller.abort(externalSignal?.reason);
|
|
263
|
+
if (externalSignal?.aborted) {
|
|
264
|
+
abortFromCaller();
|
|
265
|
+
} else {
|
|
266
|
+
externalSignal?.addEventListener("abort", abortFromCaller, { once: true });
|
|
267
|
+
}
|
|
268
|
+
const timeout = setTimeout(() => controller.abort(timeoutError), maxWaitMs);
|
|
269
|
+
try {
|
|
270
|
+
throwIfAborted(controller.signal);
|
|
271
|
+
const pending = operation(controller.signal);
|
|
272
|
+
return await raceWithAbort(pending, controller.signal);
|
|
273
|
+
} finally {
|
|
274
|
+
clearTimeout(timeout);
|
|
275
|
+
externalSignal?.removeEventListener("abort", abortFromCaller);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
function delay(milliseconds, signal) {
|
|
279
|
+
if (milliseconds === 0) {
|
|
280
|
+
throwIfAborted(signal);
|
|
281
|
+
return Promise.resolve();
|
|
282
|
+
}
|
|
283
|
+
return new Promise((resolve, reject) => {
|
|
284
|
+
const timeout = setTimeout(() => {
|
|
285
|
+
signal.removeEventListener("abort", onAbort);
|
|
286
|
+
resolve();
|
|
287
|
+
}, milliseconds);
|
|
288
|
+
const onAbort = () => {
|
|
289
|
+
clearTimeout(timeout);
|
|
290
|
+
reject(abortReason(signal));
|
|
291
|
+
};
|
|
292
|
+
if (signal.aborted) {
|
|
293
|
+
onAbort();
|
|
294
|
+
} else {
|
|
295
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
function raceWithAbort(operation, signal) {
|
|
300
|
+
if (signal.aborted) return Promise.reject(abortReason(signal));
|
|
301
|
+
return new Promise((resolve, reject) => {
|
|
302
|
+
const onAbort = () => {
|
|
303
|
+
cleanup();
|
|
304
|
+
reject(abortReason(signal));
|
|
305
|
+
};
|
|
306
|
+
const cleanup = () => signal.removeEventListener("abort", onAbort);
|
|
307
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
308
|
+
operation.then(
|
|
309
|
+
(value) => {
|
|
310
|
+
cleanup();
|
|
311
|
+
resolve(value);
|
|
312
|
+
},
|
|
313
|
+
(error) => {
|
|
314
|
+
cleanup();
|
|
315
|
+
reject(error);
|
|
316
|
+
}
|
|
317
|
+
);
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
function throwIfAborted(signal) {
|
|
321
|
+
if (signal.aborted) throw abortReason(signal);
|
|
322
|
+
}
|
|
323
|
+
function abortReason(signal) {
|
|
324
|
+
if (signal.reason instanceof Error) return signal.reason;
|
|
325
|
+
const error = new Error("Tileflow static map request was aborted");
|
|
326
|
+
error.name = "AbortError";
|
|
327
|
+
return error;
|
|
328
|
+
}
|
|
329
|
+
function assertStaticMapOperationIdentity(expected, actual) {
|
|
330
|
+
if (expected !== null && actual !== expected) {
|
|
331
|
+
throw new Error("Tileflow static map changed operation identity while polling");
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
function normalizeUrl(value) {
|
|
335
|
+
const url = new URL(value);
|
|
336
|
+
if (!isSafeHttpUrl(value) || url.search) {
|
|
337
|
+
throw new TypeError(
|
|
338
|
+
"Tileflow Static Maps apiUrl must be HTTP(S) without credentials, query, or fragment"
|
|
339
|
+
);
|
|
340
|
+
}
|
|
341
|
+
return url.toString().replace(/\/+$/, "");
|
|
342
|
+
}
|
|
343
|
+
function normalizeStaticMapEndpointUrl(value) {
|
|
344
|
+
if (value.startsWith("/")) {
|
|
345
|
+
if (value.startsWith("//") || value.length > 2048 || /[\\?#]/u.test(value) || hasControlCharacter(value)) {
|
|
346
|
+
throw new TypeError(
|
|
347
|
+
"Tileflow Static Maps createUrl must be HTTP(S) without credentials, query, or fragment or a safe root-relative path"
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
return value;
|
|
351
|
+
}
|
|
352
|
+
const url = new URL(value);
|
|
353
|
+
if (!isSafeHttpUrl(value) || url.search) {
|
|
354
|
+
throw new TypeError(
|
|
355
|
+
"Tileflow Static Maps createUrl must be HTTP(S) without credentials, query, or fragment or a safe root-relative path"
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
return url.toString();
|
|
359
|
+
}
|
|
360
|
+
function hasControlCharacter(value) {
|
|
361
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
362
|
+
const codePoint = value.charCodeAt(index);
|
|
363
|
+
if (codePoint <= 31 || codePoint === 127) return true;
|
|
364
|
+
}
|
|
365
|
+
return false;
|
|
366
|
+
}
|
|
21
367
|
export {
|
|
22
368
|
STATIC_MAP_RESULT_MEDIA_TYPE,
|
|
23
369
|
StaticMapError,
|
package/dist/manifest.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import {
|
|
2
|
+
import { a as StaticSceneInput } from './scene-contract-NFnIcQtt.js';
|
|
3
3
|
|
|
4
4
|
declare const staticRendererSchemaVersion = 1;
|
|
5
5
|
declare const staticAttributionPlanSchemaVersion = 1;
|
|
@@ -452,8 +452,8 @@ declare const staticRenderManifestSchema: z.ZodObject<{
|
|
|
452
452
|
haloColor: string;
|
|
453
453
|
haloWidth: number;
|
|
454
454
|
language: "ja" | "ko" | "zh-Hans" | "zh-Hant";
|
|
455
|
-
text: string;
|
|
456
455
|
position?: "above" | "above-left" | "above-right" | "below" | "below-left" | "below-right" | "center" | "left" | "right" | undefined;
|
|
456
|
+
text: string;
|
|
457
457
|
} | {
|
|
458
458
|
appearance: "badge";
|
|
459
459
|
backgroundColor: string;
|
|
@@ -468,8 +468,8 @@ declare const staticRenderManifestSchema: z.ZodObject<{
|
|
|
468
468
|
x: number;
|
|
469
469
|
y: number;
|
|
470
470
|
};
|
|
471
|
-
text: string;
|
|
472
471
|
position?: "above" | "above-left" | "above-right" | "below" | "below-left" | "below-right" | "center" | "left" | "right" | undefined;
|
|
472
|
+
text: string;
|
|
473
473
|
}, string | {
|
|
474
474
|
appearance: "plain";
|
|
475
475
|
color: string;
|
|
@@ -478,8 +478,8 @@ declare const staticRenderManifestSchema: z.ZodObject<{
|
|
|
478
478
|
haloColor: string;
|
|
479
479
|
haloWidth: number;
|
|
480
480
|
language: "ja" | "ko" | "zh-Hans" | "zh-Hant";
|
|
481
|
-
text: string;
|
|
482
481
|
position?: "above" | "above-left" | "above-right" | "below" | "below-left" | "below-right" | "center" | "left" | "right" | undefined;
|
|
482
|
+
text: string;
|
|
483
483
|
} | {
|
|
484
484
|
appearance: "badge";
|
|
485
485
|
backgroundColor: string;
|
|
@@ -494,8 +494,8 @@ declare const staticRenderManifestSchema: z.ZodObject<{
|
|
|
494
494
|
x: number;
|
|
495
495
|
y: number;
|
|
496
496
|
};
|
|
497
|
-
text: string;
|
|
498
497
|
position?: "above" | "above-left" | "above-right" | "below" | "below-left" | "below-right" | "center" | "left" | "right" | undefined;
|
|
498
|
+
text: string;
|
|
499
499
|
}>>>;
|
|
500
500
|
offset: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
|
|
501
501
|
opacity: z.ZodDefault<z.ZodNumber>;
|