@tileflow/core 0.1.0-alpha.26 → 0.1.0-alpha.27
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 +43 -3
- package/THIRD_PARTY_NOTICES.md +84 -0
- package/dist/build.d.ts +417 -6
- package/dist/build.js +12095 -2197
- package/dist/{capture-scene-BK_0J2oR.d.ts → capture-scene-D6soWztE.d.ts} +1 -1
- package/dist/capture.d.ts +2 -2
- package/dist/capture.js +107 -37
- package/dist/{icon-composition-BssSKOKF.d.ts → icon-composition-C2bVldOJ.d.ts} +89 -7
- package/dist/index.d.ts +156 -27
- package/dist/index.js +5217 -4678
- package/dist/{manifest-B5GKVMFE.d.ts → manifest-types-BdGjIYy-.d.ts} +2 -11
- package/dist/manifest.d.ts +9 -2
- package/dist/manifest.js +316 -193
- package/dist/native-profile.d.ts +187 -0
- package/dist/native-profile.js +9316 -0
- package/dist/native.d.ts +196 -5
- package/dist/native.js +4813 -95
- package/dist/runtime.d.ts +1 -2
- package/dist/runtime.js +338 -221
- package/docs/authoring-model.md +5 -4
- package/docs/data-is-separate-from-design.md +8 -8
- package/docs/hosted-session-authorization.md +11 -2
- package/docs/native-artifact-profile.md +145 -0
- package/docs/native-resource-urls.md +257 -7
- package/docs/public-api-and-browser-subpath.md +14 -8
- package/package.json +10 -4
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
|
|
3
1
|
declare const expressionBrand: unique symbol;
|
|
4
2
|
declare const themeValueBrand: unique symbol;
|
|
5
3
|
declare const zoomBrand: unique symbol;
|
|
@@ -610,14 +608,10 @@ type TileflowStyleFontFace = {
|
|
|
610
608
|
style?: 'italic' | 'normal' | 'oblique';
|
|
611
609
|
weight?: '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900';
|
|
612
610
|
};
|
|
613
|
-
/**
|
|
611
|
+
/** One published Tileflow map. Renderer-specific styles are not framework Map inputs. */
|
|
614
612
|
type TileflowRuntimeSource = {
|
|
615
|
-
kind: 'tileflow';
|
|
616
613
|
manifestUrl?: string;
|
|
617
614
|
map: string;
|
|
618
|
-
} | {
|
|
619
|
-
kind: 'maplibre';
|
|
620
|
-
style: MapLibreStyle | string;
|
|
621
615
|
};
|
|
622
616
|
type TileflowRuntimeStyleOptions = {
|
|
623
617
|
colorScheme?: TileflowRuntimeColorScheme;
|
|
@@ -750,8 +744,5 @@ type TileflowRuntimeManifest = {
|
|
|
750
744
|
maps: Record<string, TileflowRuntimeManifestMapEntry>;
|
|
751
745
|
version: typeof tileflowRuntimeManifestVersion;
|
|
752
746
|
};
|
|
753
|
-
declare const tileflowRuntimeManifestSchema: z.ZodType<TileflowRuntimeManifest>;
|
|
754
|
-
declare function parseTileflowRuntimeManifest(input: unknown): TileflowRuntimeManifest;
|
|
755
|
-
declare function safeParseTileflowRuntimeManifest(input: unknown): z.ZodSafeParseResult<TileflowRuntimeManifest>;
|
|
756
747
|
|
|
757
|
-
export { type
|
|
748
|
+
export { type TileflowManifestFetchOptions as $, type TileflowAreaStyle as A, type TileflowBackgroundPaint as B, type TileflowCirclePaint as C, type TileflowColor as D, type TileflowColorStyleValue as E, type TileflowExtrusionPaint as F, type TileflowFillPaint as G, type TileflowIconAnchor as H, type TileflowIconLayout as I, type TileflowIconPaint as J, type TileflowIconStyle as K, type TileflowIconTextFit as L, type MapLibreStyle as M, type TileflowImageStyleValue as N, type TileflowLabelDetail as O, type TileflowLabelLanguage as P, type TileflowLabelStyles as Q, type TileflowLayerRange as R, type TileflowLight as S, type TileflowRuntimeManifest as T, type TileflowLineCap as U, type ValidationMessage as V, type TileflowLineHatchStyle as W, type TileflowLineJoin as X, type TileflowLineLayout as Y, type TileflowLinePaint as Z, type TileflowLineStackStyle as _, type TileflowRuntimeColorScheme as a, type TileflowTextJustify as a$, type TileflowManifestLoadOptions as a0, type TileflowMapMode as a1, type TileflowMapModeOptions as a2, type TileflowMarkerSymbolStyle as a3, type TileflowMountainBikeScale as a4, type TileflowNumberInsetsStyleValue as a5, type TileflowNumberStyleValue as a6, type TileflowPlaceLabelClass as a7, type TileflowPoiCategory as a8, type TileflowPoiCategoryStyle as a9, type TileflowRoadWeight as aA, type TileflowRuntimeCenterLike as aB, type TileflowRuntimeManifestMap as aC, type TileflowRuntimeSource as aD, type TileflowRuntimeSourceValidation as aE, type TileflowRuntimeStyle as aF, type TileflowRuntimeStyleOptions as aG, type TileflowRuntimeViewOptions as aH, type TileflowSessionController as aI, type TileflowSessionGrantResponse as aJ, type TileflowStringStyleValue as aK, type TileflowStructuralStyleValue as aL, type TileflowStyleFontFace as aM, type TileflowStyleValue as aN, type TileflowSymbolPlacement as aO, type TileflowSymbolPlacementStyle as aP, type TileflowSymbolZOrder as aQ, type TileflowTerrain as aR, type TileflowTerrainConfig as aS, type TileflowTerrainContourLabelStyle as aT, type TileflowTerrainContourLineStyle as aU, type TileflowTerrainContoursConfig as aV, type TileflowTerrainEncoding as aW, type TileflowTerrainHillshadeStyle as aX, type TileflowTerrainLayerRange as aY, type TileflowTerrainMode as aZ, type TileflowTextAnchor as a_, type TileflowPoiColorMode as aa, type TileflowPoiDensity as ab, type TileflowPriorityOrder as ac, type TileflowProjection as ad, type TileflowResolvedRuntimeTheme as ae, type TileflowRoadAreaStyle as af, type TileflowRoadClass as ag, type TileflowRoadClassStyle as ah, type TileflowRoadCrossingStyle as ai, type TileflowRoadDetail as aj, type TileflowRoadExtras as ak, type TileflowRoadHierarchy as al, type TileflowRoadLabelDetail as am, type TileflowRoadLayerStyle as an, type TileflowRoadModifier as ao, type TileflowRoadOutline as ap, type TileflowRoadRestriction as aq, type TileflowRoadRoundaboutStyle as ar, type TileflowRoadServiceType as as, type TileflowRoadShieldDetail as at, type TileflowRoadShieldStyles as au, type TileflowRoadSidewalkStyle as av, type TileflowRoadStructure as aw, type TileflowRoadTreatmentLayerStyle as ax, type TileflowRoadTreatmentLineStyle as ay, type TileflowRoadTreatmentStyle as az, type TileflowRuntimeManifestMapEntry as b, type TileflowTextLayout as b0, type TileflowTextPaint as b1, type TileflowTextStyle as b2, type TileflowThemeColorAlpha as b3, type TileflowThemeColorMix as b4, type TileflowThemeColorValue as b5, type TileflowThemeFontValue as b6, type TileflowThemeImageValue as b7, type TileflowThemeNumberValue as b8, type TileflowThemeSelection as b9, resolveTileflowRuntimeStyle as bA, resolveTileflowRuntimeTheme as bB, resolveTileflowRuntimeView as bC, resolveTileflowStaticImageUrl as bD, shouldLoadTileflowManifest as bE, startTileflowSession as bF, tileflowPoiCategories as bG, tileflowStyleFontFaceLimits as bH, tileflowStyleFontFacesMetadataKey as bI, tileflowThemeTokenCategories as bJ, token as bK, validateTileflowRuntimeSource as bL, validateTileflowThemeSelection as bM, zoom as bN, type TileflowTypographyStyle as bO, type ResolvedTileflowTypography as bP, normalizeTileflowSurfaceId as bQ, type TileflowThemeTokenCategory as ba, type TileflowThemeValue as bb, type TileflowViewConfig as bc, type TileflowWaterLabelClass as bd, type TileflowZoomInterpolation as be, type TileflowZoomValue as bf, type ValidationResult as bg, assertValidTileflowRuntimeSource as bh, clearTileflowManifestCache as bi, color as bj, createTileflowSessionController as bk, createTileflowSessionId as bl, defaultTileflowManifestUrl as bm, defaultTileflowRuntimeView as bn, fixed as bo, getTileflowAnalyticsApiUrl as bp, getTileflowStyleFontFaces as bq, inferTileflowAnalyticsFromStyleUrl as br, loadTileflowManifest as bs, mergeTileflowAnalytics as bt, normalizeTileflowRuntimeCenter as bu, normalizeTileflowStaticImageSize as bv, normalizeTileflowUrl as bw, resolveTileflowAnalyticsRequestUrl as bx, resolveTileflowManifestMap as by, resolveTileflowMapMode as bz, type TileflowRuntimeManifestTheme as c, type TileflowRuntimeSystemThemes as d, tileflowRuntimeManifestVersion as e, type TileflowExpression as f, type TileflowFixedValue as g, type TileflowThemeTokenReference as h, type TileflowThemeColorOperation as i, type TileflowBackgroundStyle as j, type TileflowCircleStyle as k, type TileflowExtrusionStyle as l, type TileflowFillStyle as m, type TileflowLineStyle as n, type TileflowSymbolStyle as o, type TileflowRoadsModuleOptions as p, type TileflowRoadsModuleConfig as q, type TileflowLabelsModuleOptions as r, type TileflowLabelsModuleConfig as s, tileflowRuntimeManifestLimits as t, type TileflowPoiModuleOptions as u, type TileflowPoiModuleConfig as v, type MapLibreSprite as w, type TileflowAerodromeCodeDetail as x, type TileflowAlignment as y, type TileflowAnalytics as z };
|
package/dist/manifest.d.ts
CHANGED
|
@@ -1,2 +1,9 @@
|
|
|
1
|
-
import 'zod';
|
|
2
|
-
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { T as TileflowRuntimeManifest } from './manifest-types-BdGjIYy-.js';
|
|
3
|
+
export { a as TileflowRuntimeColorScheme, b as TileflowRuntimeManifestMapEntry, c as TileflowRuntimeManifestTheme, d as TileflowRuntimeSystemThemes, t as tileflowRuntimeManifestLimits, e as tileflowRuntimeManifestVersion } from './manifest-types-BdGjIYy-.js';
|
|
4
|
+
|
|
5
|
+
declare const tileflowRuntimeManifestSchema: z.ZodType<TileflowRuntimeManifest>;
|
|
6
|
+
declare function parseTileflowRuntimeManifest(input: unknown): TileflowRuntimeManifest;
|
|
7
|
+
declare function safeParseTileflowRuntimeManifest(input: unknown): z.ZodSafeParseResult<TileflowRuntimeManifest>;
|
|
8
|
+
|
|
9
|
+
export { TileflowRuntimeManifest, parseTileflowRuntimeManifest, safeParseTileflowRuntimeManifest, tileflowRuntimeManifestSchema };
|
package/dist/manifest.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
// src/manifest.ts
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
// src/portable-identity.ts
|
|
5
|
-
import { z } from "zod";
|
|
1
|
+
// src/manifest-types.ts
|
|
2
|
+
var tileflowRuntimeManifestVersion = 1;
|
|
3
|
+
var tileflowRuntimeManifestLimits = Object.freeze({ maximumBytes: 1024 * 1024 });
|
|
6
4
|
|
|
7
5
|
// src/portable-identity-rules.ts
|
|
8
6
|
var tileflowPortableIdMaximumLength = 64;
|
|
@@ -14,17 +12,41 @@ function isTileflowThemeName(value) {
|
|
|
14
12
|
return isTileflowPortableId(value) && value !== "system";
|
|
15
13
|
}
|
|
16
14
|
|
|
17
|
-
// src/portable-identity.ts
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
);
|
|
15
|
+
// src/portable-identity-schema.ts
|
|
16
|
+
function createPortableIdentitySchemas(operations) {
|
|
17
|
+
const bounded = operations.maxLength(
|
|
18
|
+
operations.minLength(operations.string(), 1),
|
|
19
|
+
tileflowPortableIdMaximumLength
|
|
20
|
+
);
|
|
21
|
+
const pattern = operations.regex(
|
|
22
|
+
bounded,
|
|
23
|
+
tileflowPortableIdPattern,
|
|
24
|
+
"Expected lowercase kebab-case beginning with a letter"
|
|
25
|
+
);
|
|
26
|
+
const tileflowPortableIdSchema2 = operations.refine(
|
|
27
|
+
pattern,
|
|
28
|
+
(name) => !["constructor", "prototype"].includes(name) && !/^(?:AUX|CON|NUL|PRN|COM[1-9]|LPT[1-9])$/i.test(name),
|
|
29
|
+
"Expected a portable identifier that is not a reserved filename or prototype key"
|
|
30
|
+
);
|
|
31
|
+
const tileflowThemeNameSchema2 = operations.refine(
|
|
32
|
+
tileflowPortableIdSchema2,
|
|
33
|
+
isTileflowThemeName,
|
|
34
|
+
"Expected a concrete theme name; system is browser-only"
|
|
35
|
+
);
|
|
36
|
+
return { tileflowPortableIdSchema: tileflowPortableIdSchema2, tileflowThemeNameSchema: tileflowThemeNameSchema2 };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// src/runtime-view-schema.ts
|
|
40
|
+
function createTileflowRuntimeViewSchema(operations) {
|
|
41
|
+
return operations.object({
|
|
42
|
+
bearing: operations.optional(operations.number(-180, 180)),
|
|
43
|
+
center: operations.optional(
|
|
44
|
+
operations.tuplePair(operations.number(-180, 180), operations.number(-90, 90))
|
|
45
|
+
),
|
|
46
|
+
pitch: operations.optional(operations.number(0, 85)),
|
|
47
|
+
zoom: operations.optional(operations.number(0, 24))
|
|
48
|
+
});
|
|
49
|
+
}
|
|
28
50
|
|
|
29
51
|
// src/themes/model.ts
|
|
30
52
|
var tileflowThemeLimits = Object.freeze({ maxThemes: 64 });
|
|
@@ -37,204 +59,305 @@ var themeTypographyKeys = [
|
|
|
37
59
|
"water"
|
|
38
60
|
];
|
|
39
61
|
|
|
40
|
-
// src/manifest.ts
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
62
|
+
// src/manifest-schema.ts
|
|
63
|
+
function createTileflowRuntimeManifestSchema(primitives, operations, identities = createPortableIdentitySchemas(operations)) {
|
|
64
|
+
const { tileflowPortableIdSchema: tileflowPortableIdSchema2, tileflowThemeNameSchema: tileflowThemeNameSchema2 } = identities;
|
|
65
|
+
const safeTextSchema = operations.refine(
|
|
66
|
+
operations.refine(
|
|
67
|
+
operations.maxLength(operations.minLength(operations.string(), 1), 2048),
|
|
68
|
+
(value) => value === value.trim(),
|
|
69
|
+
"Expected text without surrounding whitespace"
|
|
70
|
+
),
|
|
71
|
+
(value) => !/[\p{Cc}\\]/u.test(value),
|
|
72
|
+
"Expected safe text"
|
|
73
|
+
);
|
|
74
|
+
const publicResourceUrlSchema = operations.refine(
|
|
75
|
+
safeTextSchema,
|
|
76
|
+
isPublicResourceUrl,
|
|
77
|
+
"Expected an HTTP(S), root-relative, or path-relative public URL"
|
|
78
|
+
);
|
|
79
|
+
const apiOriginSchema = operations.refine(
|
|
80
|
+
safeTextSchema,
|
|
81
|
+
isApiOrigin,
|
|
82
|
+
"Expected an absolute HTTP(S) origin without path, credentials, query, or fragment"
|
|
83
|
+
);
|
|
84
|
+
const viewSchema = createTileflowRuntimeViewSchema(operations);
|
|
85
|
+
const fontFaceSchema = operations.object({
|
|
86
|
+
family: operations.maxLength(safeTextSchema, 100),
|
|
87
|
+
source: publicResourceUrlSchema,
|
|
88
|
+
style: operations.optional(operations.enum(["italic", "normal", "oblique"])),
|
|
89
|
+
weight: operations.optional(
|
|
90
|
+
operations.enum(["100", "200", "300", "400", "500", "600", "700", "800", "900"])
|
|
91
|
+
)
|
|
92
|
+
});
|
|
93
|
+
const fontFacesSchema = operations.superRefine(
|
|
94
|
+
operations.maxLength(operations.array(fontFaceSchema), 16),
|
|
95
|
+
validateUniqueFontFaces
|
|
96
|
+
);
|
|
97
|
+
const manifestThemeSchema = operations.object({
|
|
98
|
+
colorScheme: operations.enum(["dark", "light"]),
|
|
99
|
+
fontFaces: operations.optional(fontFacesSchema),
|
|
100
|
+
revision: operations.optional(operations.maxLength(safeTextSchema, 128)),
|
|
101
|
+
styleId: operations.optional(operations.maxLength(safeTextSchema, 128)),
|
|
102
|
+
styleUrl: publicResourceUrlSchema
|
|
103
|
+
});
|
|
104
|
+
const manifestMapSchema = operations.superRefine(
|
|
105
|
+
operations.object({
|
|
106
|
+
apiUrl: operations.optional(apiOriginSchema),
|
|
107
|
+
defaultTheme: tileflowThemeNameSchema2,
|
|
108
|
+
environment: operations.optional(operations.maxLength(safeTextSchema, 128)),
|
|
109
|
+
mapId: operations.optional(operations.maxLength(safeTextSchema, 128)),
|
|
110
|
+
systemThemes: operations.optional(
|
|
111
|
+
operations.object({
|
|
112
|
+
dark: tileflowThemeNameSchema2,
|
|
113
|
+
light: tileflowThemeNameSchema2
|
|
114
|
+
})
|
|
115
|
+
),
|
|
116
|
+
themes: operations.record(tileflowThemeNameSchema2, manifestThemeSchema),
|
|
117
|
+
usageMode: operations.optional(operations.literal("session")),
|
|
118
|
+
view: operations.optional(viewSchema),
|
|
119
|
+
worldGeneration: operations.optional(operations.literal("v1"))
|
|
120
|
+
}),
|
|
121
|
+
(entry, context) => {
|
|
122
|
+
const names = Object.keys(entry.themes);
|
|
123
|
+
if (names.length === 0) {
|
|
124
|
+
context.addIssue({
|
|
125
|
+
code: "custom",
|
|
126
|
+
message: "Expected at least one theme",
|
|
127
|
+
path: ["themes"]
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
if (names.length > tileflowThemeLimits.maxThemes) {
|
|
131
|
+
context.addIssue({
|
|
132
|
+
code: "too_big",
|
|
133
|
+
maximum: tileflowThemeLimits.maxThemes,
|
|
134
|
+
origin: "object",
|
|
135
|
+
path: ["themes"]
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
if (!Object.hasOwn(entry.themes, entry.defaultTheme)) {
|
|
105
139
|
context.addIssue({
|
|
106
140
|
code: "custom",
|
|
107
|
-
message:
|
|
108
|
-
path: ["
|
|
141
|
+
message: "defaultTheme must name a declared theme",
|
|
142
|
+
path: ["defaultTheme"]
|
|
109
143
|
});
|
|
110
|
-
}
|
|
144
|
+
}
|
|
145
|
+
if (entry.systemThemes) {
|
|
146
|
+
for (const colorScheme of ["light", "dark"]) {
|
|
147
|
+
const name = entry.systemThemes[colorScheme];
|
|
148
|
+
const theme = entry.themes[name];
|
|
149
|
+
if (!theme) {
|
|
150
|
+
context.addIssue({
|
|
151
|
+
code: "custom",
|
|
152
|
+
message: `systemThemes.${colorScheme} must name a declared theme`,
|
|
153
|
+
path: ["systemThemes", colorScheme]
|
|
154
|
+
});
|
|
155
|
+
} else if (theme.colorScheme !== colorScheme) {
|
|
156
|
+
context.addIssue({
|
|
157
|
+
code: "custom",
|
|
158
|
+
message: `systemThemes.${colorScheme} must reference a ${colorScheme} theme`,
|
|
159
|
+
path: ["systemThemes", colorScheme]
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (entry.usageMode === void 0 !== (entry.worldGeneration === void 0)) {
|
|
111
165
|
context.addIssue({
|
|
112
166
|
code: "custom",
|
|
113
|
-
message:
|
|
114
|
-
path: ["systemThemes", colorScheme]
|
|
167
|
+
message: "usageMode and worldGeneration must be declared together"
|
|
115
168
|
});
|
|
116
169
|
}
|
|
117
170
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
});
|
|
147
|
-
var safeManifestInputSchema = z2.unknown().superRefine((input, context) => {
|
|
148
|
-
const unsafe = findUnsafeManifestStructure(input);
|
|
149
|
-
if (unsafe) {
|
|
150
|
-
context.addIssue({
|
|
151
|
-
code: "custom",
|
|
152
|
-
message: unsafe.reason === "prototype" ? "Expected plain manifest objects" : "Expected no prototype-mutating keys",
|
|
153
|
-
path: unsafe.path
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
});
|
|
157
|
-
var tileflowRuntimeManifestSchema = safeManifestInputSchema.pipe(canonicalManifestSchema);
|
|
158
|
-
function parseTileflowRuntimeManifest(input) {
|
|
159
|
-
return tileflowRuntimeManifestSchema.parse(input);
|
|
160
|
-
}
|
|
161
|
-
function safeParseTileflowRuntimeManifest(input) {
|
|
162
|
-
return tileflowRuntimeManifestSchema.safeParse(input);
|
|
163
|
-
}
|
|
164
|
-
function validateUniqueFontFaces(fontFaces, context) {
|
|
165
|
-
const seen = /* @__PURE__ */ new Map();
|
|
166
|
-
for (const [index, fontFace] of fontFaces.entries()) {
|
|
167
|
-
const identity = `${fontFace.family}\0${fontFace.style ?? "normal"}\0${fontFace.weight ?? "400"}`;
|
|
168
|
-
const first = seen.get(identity);
|
|
169
|
-
if (first !== void 0) {
|
|
171
|
+
);
|
|
172
|
+
const canonicalManifestSchema = operations.superRefine(
|
|
173
|
+
operations.object({
|
|
174
|
+
apiUrl: operations.optional(apiOriginSchema),
|
|
175
|
+
maps: operations.record(tileflowPortableIdSchema2, manifestMapSchema),
|
|
176
|
+
version: operations.literal(tileflowRuntimeManifestVersion)
|
|
177
|
+
}),
|
|
178
|
+
(manifest, context) => {
|
|
179
|
+
const mapCount = Object.keys(manifest.maps).length;
|
|
180
|
+
if (mapCount === 0) {
|
|
181
|
+
context.addIssue({ code: "custom", message: "Expected at least one map", path: ["maps"] });
|
|
182
|
+
}
|
|
183
|
+
if (mapCount > 1e3) {
|
|
184
|
+
context.addIssue({ code: "too_big", maximum: 1e3, origin: "object", path: ["maps"] });
|
|
185
|
+
}
|
|
186
|
+
if (primitives.utf8ByteLength(JSON.stringify(manifest)) > tileflowRuntimeManifestLimits.maximumBytes) {
|
|
187
|
+
context.addIssue({
|
|
188
|
+
code: "too_big",
|
|
189
|
+
maximum: tileflowRuntimeManifestLimits.maximumBytes,
|
|
190
|
+
origin: "string",
|
|
191
|
+
message: "Manifest JSON exceeds the 1 MiB limit"
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
);
|
|
196
|
+
const safeManifestInputSchema = operations.superRefine(operations.unknown(), (input, context) => {
|
|
197
|
+
const unsafe = findUnsafeManifestStructure(input);
|
|
198
|
+
if (unsafe) {
|
|
170
199
|
context.addIssue({
|
|
171
200
|
code: "custom",
|
|
172
|
-
message:
|
|
173
|
-
path:
|
|
201
|
+
message: unsafe.reason === "prototype" ? "Expected plain manifest objects" : "Expected no prototype-mutating keys",
|
|
202
|
+
path: unsafe.path
|
|
174
203
|
});
|
|
175
|
-
continue;
|
|
176
204
|
}
|
|
177
|
-
|
|
205
|
+
});
|
|
206
|
+
function validateUniqueFontFaces(fontFaces, context) {
|
|
207
|
+
const seen = /* @__PURE__ */ new Map();
|
|
208
|
+
for (const [index, fontFace] of fontFaces.entries()) {
|
|
209
|
+
const identity = `${fontFace.family}\0${fontFace.style ?? "normal"}\0${fontFace.weight ?? "400"}`;
|
|
210
|
+
const first = seen.get(identity);
|
|
211
|
+
if (first !== void 0) {
|
|
212
|
+
context.addIssue({
|
|
213
|
+
code: "custom",
|
|
214
|
+
message: `Duplicate font face identity; first declared at index ${first}`,
|
|
215
|
+
path: [index]
|
|
216
|
+
});
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
seen.set(identity, index);
|
|
220
|
+
}
|
|
178
221
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
222
|
+
function isPublicResourceUrl(value) {
|
|
223
|
+
if (value.startsWith("//")) return false;
|
|
224
|
+
if (!value.startsWith("/") && !value.startsWith("./") && !value.startsWith("../") && !isAbsolutePublicUrl(value)) {
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
return isSafeResolvedPublicUrl(value);
|
|
184
228
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
return false;
|
|
229
|
+
function isAbsolutePublicUrl(value) {
|
|
230
|
+
try {
|
|
231
|
+
const url = primitives.parseUrl(value);
|
|
232
|
+
return (url.protocol === "http:" || url.protocol === "https:") && !url.username && !url.password && !url.hash && !hasEncodedPathSeparator(value);
|
|
233
|
+
} catch {
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
193
236
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
237
|
+
function isSafeResolvedPublicUrl(value) {
|
|
238
|
+
try {
|
|
239
|
+
const url = primitives.parseUrl(value, "https://manifest.invalid/owner/manifest.json");
|
|
240
|
+
return (url.protocol === "http:" || url.protocol === "https:") && !url.username && !url.password && !url.hash && !hasEncodedPathSeparator(value);
|
|
241
|
+
} catch {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
201
244
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
return /%(?:2f|5c)/iu.test(value);
|
|
205
|
-
}
|
|
206
|
-
function isApiOrigin(value) {
|
|
207
|
-
try {
|
|
208
|
-
const url = new URL(value);
|
|
209
|
-
return isAbsolutePublicUrl(value) && url.pathname === "/" && !url.search && value.replace(/\/$/u, "") === url.origin;
|
|
210
|
-
} catch {
|
|
211
|
-
return false;
|
|
245
|
+
function hasEncodedPathSeparator(value) {
|
|
246
|
+
return /%(?:2f|5c)/iu.test(value);
|
|
212
247
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
const current = pending.pop();
|
|
220
|
-
if (visited.has(current.value)) continue;
|
|
221
|
-
visited.add(current.value);
|
|
222
|
-
if (!Array.isArray(current.value)) {
|
|
223
|
-
const prototype = Object.getPrototypeOf(current.value);
|
|
224
|
-
if (prototype !== Object.prototype && prototype !== null) {
|
|
225
|
-
return { path: current.path, reason: "prototype" };
|
|
226
|
-
}
|
|
248
|
+
function isApiOrigin(value) {
|
|
249
|
+
try {
|
|
250
|
+
const url = primitives.parseUrl(value);
|
|
251
|
+
return isAbsolutePublicUrl(value) && url.pathname === "/" && !url.search && value.replace(/\/$/u, "") === url.origin;
|
|
252
|
+
} catch {
|
|
253
|
+
return false;
|
|
227
254
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
255
|
+
}
|
|
256
|
+
function findUnsafeManifestStructure(input) {
|
|
257
|
+
if (!input || typeof input !== "object") return void 0;
|
|
258
|
+
const pending = [
|
|
259
|
+
{ path: [], value: input }
|
|
260
|
+
];
|
|
261
|
+
const visited = /* @__PURE__ */ new WeakSet();
|
|
262
|
+
while (pending.length > 0) {
|
|
263
|
+
const current = pending.pop();
|
|
264
|
+
if (visited.has(current.value)) continue;
|
|
265
|
+
visited.add(current.value);
|
|
266
|
+
if (!Array.isArray(current.value)) {
|
|
267
|
+
const prototype = Object.getPrototypeOf(current.value);
|
|
268
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
269
|
+
return { path: current.path, reason: "prototype" };
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
for (const key of Object.keys(current.value)) {
|
|
273
|
+
const path = [...current.path, Array.isArray(current.value) ? Number(key) : key];
|
|
274
|
+
if (key === "__proto__") return { path, reason: "key" };
|
|
275
|
+
const descriptor = Object.getOwnPropertyDescriptor(current.value, key);
|
|
276
|
+
if (descriptor && "value" in descriptor && descriptor.value && typeof descriptor.value === "object") {
|
|
277
|
+
pending.push({ path, value: descriptor.value });
|
|
278
|
+
}
|
|
234
279
|
}
|
|
235
280
|
}
|
|
281
|
+
return void 0;
|
|
236
282
|
}
|
|
237
|
-
return
|
|
283
|
+
return operations.pipe(safeManifestInputSchema, canonicalManifestSchema);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// src/manifest-schema-classic.ts
|
|
287
|
+
import { z as z2 } from "zod";
|
|
288
|
+
|
|
289
|
+
// src/native-zod-object.ts
|
|
290
|
+
import { z } from "zod";
|
|
291
|
+
function strictNativeObject(shape) {
|
|
292
|
+
const object = new z.core.$ZodObject({
|
|
293
|
+
type: "object",
|
|
294
|
+
shape,
|
|
295
|
+
catchall: z.never()
|
|
296
|
+
});
|
|
297
|
+
return z.lazy(() => object);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// src/manifest-schema-classic.ts
|
|
301
|
+
function classic(schema) {
|
|
302
|
+
return schema;
|
|
303
|
+
}
|
|
304
|
+
var classicManifestStringOperations = {
|
|
305
|
+
string: () => z2.string(),
|
|
306
|
+
minLength(schema, minimum) {
|
|
307
|
+
return schema.min(
|
|
308
|
+
minimum
|
|
309
|
+
);
|
|
310
|
+
},
|
|
311
|
+
maxLength(schema, maximum) {
|
|
312
|
+
return schema.max(
|
|
313
|
+
maximum
|
|
314
|
+
);
|
|
315
|
+
},
|
|
316
|
+
regex: (schema, pattern, message) => schema.regex(pattern, { message }),
|
|
317
|
+
refine: (schema, check, message) => classic(schema).refine(check, message)
|
|
318
|
+
};
|
|
319
|
+
var classicManifestSchemaOperations = {
|
|
320
|
+
...classicManifestStringOperations,
|
|
321
|
+
number: (minimum, maximum) => z2.number().finite().min(minimum).max(maximum),
|
|
322
|
+
unknown: () => z2.unknown(),
|
|
323
|
+
optional: (schema) => classic(schema).optional(),
|
|
324
|
+
array: (schema) => z2.array(classic(schema)),
|
|
325
|
+
enum(values) {
|
|
326
|
+
return z2.enum(values);
|
|
327
|
+
},
|
|
328
|
+
literal: (value) => z2.literal(value),
|
|
329
|
+
tuplePair(left, right) {
|
|
330
|
+
return z2.tuple([classic(left), classic(right)]);
|
|
331
|
+
},
|
|
332
|
+
object(shape) {
|
|
333
|
+
return strictNativeObject(shape);
|
|
334
|
+
},
|
|
335
|
+
record(key, value) {
|
|
336
|
+
return z2.record(classic(key), classic(value));
|
|
337
|
+
},
|
|
338
|
+
superRefine: (schema, check) => classic(schema).superRefine(check),
|
|
339
|
+
pipe: (input, output) => classic(input).pipe(classic(output))
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
// src/portable-identity.ts
|
|
343
|
+
var schemas = createPortableIdentitySchemas(classicManifestStringOperations);
|
|
344
|
+
var tileflowPortableIdSchema = schemas.tileflowPortableIdSchema;
|
|
345
|
+
var tileflowThemeNameSchema = schemas.tileflowThemeNameSchema;
|
|
346
|
+
|
|
347
|
+
// src/manifest.ts
|
|
348
|
+
var tileflowRuntimeManifestSchema = createTileflowRuntimeManifestSchema(
|
|
349
|
+
{
|
|
350
|
+
parseUrl: (value, base) => base === void 0 ? new URL(value) : new URL(value, base),
|
|
351
|
+
utf8ByteLength: (value) => new TextEncoder().encode(value).byteLength
|
|
352
|
+
},
|
|
353
|
+
classicManifestSchemaOperations,
|
|
354
|
+
{ tileflowPortableIdSchema, tileflowThemeNameSchema }
|
|
355
|
+
);
|
|
356
|
+
function parseTileflowRuntimeManifest(input) {
|
|
357
|
+
return tileflowRuntimeManifestSchema.parse(input);
|
|
358
|
+
}
|
|
359
|
+
function safeParseTileflowRuntimeManifest(input) {
|
|
360
|
+
return tileflowRuntimeManifestSchema.safeParse(input);
|
|
238
361
|
}
|
|
239
362
|
export {
|
|
240
363
|
parseTileflowRuntimeManifest,
|