@tileflow/static 0.1.0-alpha.26 → 0.1.0-alpha.28

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 CHANGED
@@ -31,12 +31,9 @@ silently share another scene's identity.
31
31
  <!-- docs:check -->
32
32
 
33
33
  ```ts
34
- import {
35
- createStaticMapIdempotencyKey,
36
- marker,
37
- createStaticMap,
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.');
@@ -241,25 +238,28 @@ attribution grammar or glyphs, excessive attribution, and a block that cannot fi
241
238
  non-retryable `422` boundary.
242
239
 
243
240
  Other bounded Hosted JSON failures throw `StaticMapError`. It preserves HTTP `status` and any safe
244
- `code`, `retryable`, `requestId`, or `remainingUnits` fields the server supplied; absent fields are
245
- `null`. `StaticMapRequestError` extends the same class. Malformed, oversized, or unsafe remote
246
- documents remain generic errors and are never reflected to the caller.
241
+ `code`, `requiredPlan`, `retryable`, `requestId`, or `remainingUnits` fields the server supplied;
242
+ absent fields are `null`. `StaticMapRequestError` extends the same class. Malformed, oversized, or
243
+ unsafe remote documents remain generic errors and are never reflected to the caller.
244
+
245
+ `STATIC_MAPS_PLAN_UNAVAILABLE` is a non-retryable Starter requirement. Its `requiredPlan` is
246
+ `starter-v1`; select a Starter Team or use a non-static fallback. It occurs before a Static Maps
247
+ operation or API-unit charge. A different `403` is a credential or Map-coverage failure.
247
248
 
248
249
  ## API entry points
249
250
 
250
- The package has four deliberately separate surfaces, all available from the root for compatibility:
251
+ The package has four deliberately separate entry points:
251
252
 
252
- - scene validation and normalization: `staticSceneSchema`, `validateStaticScene`, and
253
- `normalizeStaticScene`;
254
- - overlay authoring and MapLibre compilation: `line`, `circle`, `marker`, `polygon`, `symbol`, and
255
- `compileStaticOverlays`;
256
- - 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`,
257
258
  `validateStaticRenderManifest`, `hashRenderManifest`, and `hashStaticSceneRequest`;
258
- - bounded Hosted transport: `prepareStaticMapRequest`, `createStaticMap`, `precacheStaticMap`, and
259
- `requestStaticMapUntilReady`.
259
+ - `@tileflow/static/client`, bounded Hosted transport: `prepareStaticMapRequest`,
260
+ `createStaticMap`, `precacheStaticMap`, and `requestStaticMapUntilReady`.
260
261
 
261
- Applications that need only one surface can use `@tileflow/static/scene`, `/overlays`, `/manifest`,
262
- or `/client`. The root remains a compatibility entry point.
262
+ The package has no root entry point.
263
263
 
264
264
  `StaticRenderManifest` is the single strict immutable input contract between a resolved Hosted style
265
265
  and a Static Maps renderer. It binds safe attribution, exact source identity, semantic placement
@@ -23,12 +23,14 @@ var staticMapErrorResponseSchema = z.object({
23
23
  error: safeErrorTextSchema,
24
24
  remainingUnits: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).optional(),
25
25
  requestId: safeErrorIdentifierSchema.optional(),
26
+ requiredPlan: safeErrorIdentifierSchema.optional(),
26
27
  retryable: z.boolean().optional()
27
28
  }).strip();
28
29
  var StaticMapError = class extends Error {
29
30
  code;
30
31
  remainingUnits;
31
32
  requestId;
33
+ requiredPlan;
32
34
  response;
33
35
  retryable;
34
36
  status;
@@ -39,6 +41,7 @@ var StaticMapError = class extends Error {
39
41
  this.code = parsed.code ?? null;
40
42
  this.remainingUnits = parsed.remainingUnits ?? null;
41
43
  this.requestId = parsed.requestId ?? null;
44
+ this.requiredPlan = parsed.requiredPlan ?? null;
42
45
  this.response = Object.freeze(parsed);
43
46
  this.retryable = parsed.retryable ?? null;
44
47
  this.status = status;
package/dist/client.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
- export { S as StaticMapError, a as StaticMapErrorResponse, s as staticMapErrorResponseSchema } from './errors-B9rwehK0.js';
3
- import { a as StaticAttributionPosition, j as StaticSceneInput } from './scene-contract-Cr6BNLz0.js';
2
+ export { S as StaticMapError, a as StaticMapErrorResponse, s as staticMapErrorResponseSchema } from './errors-CSz1xaDx.js';
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-RGXE4HDY.js";
14
1
  import {
15
2
  StaticMapError,
16
- staticMapErrorResponseSchema
17
- } from "./chunk-TBI5AED6.js";
3
+ StaticMapRequestError,
4
+ staticMapErrorResponseSchema,
5
+ staticMapRequestErrorResponseSchema,
6
+ validateStaticScene
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,
@@ -5,6 +5,7 @@ declare const staticMapErrorResponseSchema: z.ZodObject<{
5
5
  error: z.ZodString;
6
6
  remainingUnits: z.ZodOptional<z.ZodNumber>;
7
7
  requestId: z.ZodOptional<z.ZodString>;
8
+ requiredPlan: z.ZodOptional<z.ZodString>;
8
9
  retryable: z.ZodOptional<z.ZodBoolean>;
9
10
  }, z.core.$strip>;
10
11
  type StaticMapErrorResponse = z.infer<typeof staticMapErrorResponseSchema>;
@@ -12,6 +13,7 @@ declare class StaticMapError extends Error {
12
13
  readonly code: string | null;
13
14
  readonly remainingUnits: number | null;
14
15
  readonly requestId: string | null;
16
+ readonly requiredPlan: string | null;
15
17
  readonly response: StaticMapErrorResponse;
16
18
  readonly retryable: boolean | null;
17
19
  readonly status: number;
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { j as StaticSceneInput } from './scene-contract-Cr6BNLz0.js';
2
+ import { a as StaticSceneInput } from './scene-contract-NFnIcQtt.js';
3
3
 
4
4
  declare const staticRendererSchemaVersion = 1;
5
5
  declare const staticAttributionPlanSchemaVersion = 1;
@@ -144,6 +144,20 @@ declare const staticRenderCompositionSchema: z.ZodObject<{
144
144
  'above-labels': z.ZodNull;
145
145
  }, z.core.$strict>;
146
146
  icons: z.ZodArray<z.ZodObject<{
147
+ layout: z.ZodOptional<z.ZodObject<{
148
+ stretchX: z.ZodOptional<z.ZodArray<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>>;
149
+ stretchY: z.ZodOptional<z.ZodArray<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>>;
150
+ content: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
151
+ }, z.core.$strict>>;
152
+ appearance: z.ZodOptional<z.ZodObject<{
153
+ representation: z.ZodLiteral<"sdf">;
154
+ defaults: z.ZodObject<{
155
+ color: z.ZodString;
156
+ haloColor: z.ZodString;
157
+ haloWidth: z.ZodNumber;
158
+ haloBlur: z.ZodNumber;
159
+ }, z.core.$strict>;
160
+ }, z.core.$strict>>;
147
161
  height: z.ZodNumber;
148
162
  icon: z.ZodString;
149
163
  overlayIndex: z.ZodNumber;
@@ -227,6 +241,20 @@ declare const staticRenderManifestSchema: z.ZodObject<{
227
241
  'above-labels': z.ZodNull;
228
242
  }, z.core.$strict>;
229
243
  icons: z.ZodArray<z.ZodObject<{
244
+ layout: z.ZodOptional<z.ZodObject<{
245
+ stretchX: z.ZodOptional<z.ZodArray<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>>;
246
+ stretchY: z.ZodOptional<z.ZodArray<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>>;
247
+ content: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
248
+ }, z.core.$strict>>;
249
+ appearance: z.ZodOptional<z.ZodObject<{
250
+ representation: z.ZodLiteral<"sdf">;
251
+ defaults: z.ZodObject<{
252
+ color: z.ZodString;
253
+ haloColor: z.ZodString;
254
+ haloWidth: z.ZodNumber;
255
+ haloBlur: z.ZodNumber;
256
+ }, z.core.$strict>;
257
+ }, z.core.$strict>>;
230
258
  height: z.ZodNumber;
231
259
  icon: z.ZodString;
232
260
  overlayIndex: z.ZodNumber;
@@ -424,8 +452,8 @@ declare const staticRenderManifestSchema: z.ZodObject<{
424
452
  haloColor: string;
425
453
  haloWidth: number;
426
454
  language: "ja" | "ko" | "zh-Hans" | "zh-Hant";
427
- text: string;
428
455
  position?: "above" | "above-left" | "above-right" | "below" | "below-left" | "below-right" | "center" | "left" | "right" | undefined;
456
+ text: string;
429
457
  } | {
430
458
  appearance: "badge";
431
459
  backgroundColor: string;
@@ -440,8 +468,8 @@ declare const staticRenderManifestSchema: z.ZodObject<{
440
468
  x: number;
441
469
  y: number;
442
470
  };
443
- text: string;
444
471
  position?: "above" | "above-left" | "above-right" | "below" | "below-left" | "below-right" | "center" | "left" | "right" | undefined;
472
+ text: string;
445
473
  }, string | {
446
474
  appearance: "plain";
447
475
  color: string;
@@ -450,8 +478,8 @@ declare const staticRenderManifestSchema: z.ZodObject<{
450
478
  haloColor: string;
451
479
  haloWidth: number;
452
480
  language: "ja" | "ko" | "zh-Hans" | "zh-Hant";
453
- text: string;
454
481
  position?: "above" | "above-left" | "above-right" | "below" | "below-left" | "below-right" | "center" | "left" | "right" | undefined;
482
+ text: string;
455
483
  } | {
456
484
  appearance: "badge";
457
485
  backgroundColor: string;
@@ -466,8 +494,8 @@ declare const staticRenderManifestSchema: z.ZodObject<{
466
494
  x: number;
467
495
  y: number;
468
496
  };
469
- text: string;
470
497
  position?: "above" | "above-left" | "above-right" | "below" | "below-left" | "below-right" | "center" | "left" | "right" | undefined;
498
+ text: string;
471
499
  }>>>;
472
500
  offset: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
473
501
  opacity: z.ZodDefault<z.ZodNumber>;