@tileflow/dev 0.1.0-alpha.37 → 0.1.0-alpha.39
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 +11 -21
- package/dist/artifacts.js +4 -4
- package/dist/{chunk-UKWAQKLH.js → chunk-AVJMTXW5.js} +57 -22
- package/dist/{chunk-5RT4CHSK.js → chunk-C4VPHZ3F.js} +1109 -305
- package/dist/{chunk-UTRO4IBQ.js → chunk-FOMTSCOP.js} +1 -1
- package/dist/{chunk-7C4F6GAX.js → chunk-RTU7TD4M.js} +4 -2
- package/dist/fonts.js +2 -2
- package/dist/icons.js +2 -2
- package/dist/preview.js +4 -2
- package/dist/server.js +4 -4
- package/package.json +4 -5
- package/docs/artifact-lifecycle.md +0 -152
- package/docs/beacon-map-audits.md +0 -145
- package/docs/bounded-pmtiles-resource-inspection.md +0 -21
- package/docs/bounded-vector-feature-inspection.md +0 -99
- package/docs/building-models.md +0 -179
- package/docs/layers-inspection.md +0 -92
- package/docs/local-comparison-workbench-and-compiler-inspection.md +0 -130
- package/docs/map-design-diagnostics.md +0 -76
- package/docs/native-artifacts.md +0 -287
- package/docs/native-icons.md +0 -129
- package/docs/structured-config-inspection-and-diagnostics.md +0 -39
package/README.md
CHANGED
|
@@ -37,8 +37,6 @@ The CLI's local Inspector provides a dockable layer inspector, loaded tiles, ass
|
|
|
37
37
|
controls and frame timing. Its element picker selects a layer and evaluates its rules using the
|
|
38
38
|
feature clicked on the map.
|
|
39
39
|
Debug's Overdraw overlay uses a heatmap with a visible pass-count legend and explanation.
|
|
40
|
-
See [Inspector and compiler inspection](https://github.com/tileflow/tileflow-sdk/blob/main/packages/dev/docs/local-comparison-workbench-and-compiler-inspection.md)
|
|
41
|
-
for interaction details and observation limits.
|
|
42
40
|
|
|
43
41
|
## Prepare a generation
|
|
44
42
|
|
|
@@ -66,6 +64,8 @@ compile icons separately can use `prepareTileflowMapTreeModels` from `@tileflow/
|
|
|
66
64
|
the map's model directories, base directory, working directory, target and diagnostic path. Pass
|
|
67
65
|
its `models` result as `preparedAssets.models` when compiling the style; retain its source
|
|
68
66
|
identities and watch paths when managing revisions. The artifact pipeline does this automatically.
|
|
67
|
+
A GLB whose materials name only `bark`, `leaves`, `fronds` or `stem` is a tree model; any other
|
|
68
|
+
is a building model, whose materials name its parts.
|
|
69
69
|
|
|
70
70
|
To write production output rather than manage it in memory:
|
|
71
71
|
|
|
@@ -82,6 +82,8 @@ await writeTileflowBuildArtifacts({
|
|
|
82
82
|
|
|
83
83
|
Serve the complete output. The writer installs immutable generation assets before changing the
|
|
84
84
|
manifest pointer, tracks its own files, and refuses to replace a hosted manifest by default.
|
|
85
|
+
Native builds retain embedded PNG image sources as hashed files beside the styles, so their
|
|
86
|
+
resource URLs remain portable without permitting data URLs in the native profile.
|
|
85
87
|
`overwriteHostedManifest: true` is an explicit migration option, not a normal build setting.
|
|
86
88
|
Production rejects unresolved local PMTiles; publish data explicitly or provide an application-owned
|
|
87
89
|
production source. Local development snapshots do not publish or redistribute the original dataset.
|
|
@@ -122,7 +124,12 @@ export async function createMapHandler() {
|
|
|
122
124
|
The caller mounts `fetch` in its server and calls `close()` on shutdown. This factory does not open
|
|
123
125
|
a listener. Sessions follow config imports and local asset inputs, retain the last good generation
|
|
124
126
|
after invalid edits, and publish structured state changes through `subscribe()`.
|
|
127
|
+
Session creation waits for the first valid generation or a settled invalid result, including
|
|
128
|
+
when a watched edit replaces the initial build before it finishes.
|
|
125
129
|
Watching follows aliased working directories, including newly created or removed icon metadata.
|
|
130
|
+
Package assets resolve from the config directory. Linked package assets inside the selected working
|
|
131
|
+
tree are watched too; installed assets in `node_modules` remain immutable.
|
|
132
|
+
|
|
126
133
|
A single startup consistency check complements ordinary watcher notifications; no recurring scan
|
|
127
134
|
is added.
|
|
128
135
|
|
|
@@ -138,7 +145,7 @@ for local PMTiles inspection, and `/validation` for diagnostics. `/preview` is t
|
|
|
138
145
|
contract, including experimental preview-only rendering; it does not promise hosted support.
|
|
139
146
|
The package has no root entry point. `/server` also exposes the reusable Inspector shell. The CLI
|
|
140
147
|
connects appearance controls and shared browser context through its optional local
|
|
141
|
-
workflow adapter
|
|
148
|
+
workflow adapter.
|
|
142
149
|
The navigation contains **Map**, **Layers**, **Tiles**, **Assets**, **Debug** and **Diagnostics**.
|
|
143
150
|
Zoom, Pitch and Bearing appear as **Z**, **P** and **B** directly below it, with live Zoom and Pitch
|
|
144
151
|
sliders and **Copy for AI**. Pitch and Bearing each have an inline reset to 0° within the map's
|
|
@@ -163,7 +170,6 @@ feature's layer in **Rules**. Rules expose live colors, numeric sliders, enums,
|
|
|
163
170
|
defaults, and checkboxes for temporarily disabling paint, layout and filters. Diagnosis, Data and
|
|
164
171
|
Origin explain renderer state, sample features and available compiler provenance. **Visible**
|
|
165
172
|
filters to the current viewport. Context can be reviewed as Markdown or JSON before copying.
|
|
166
|
-
See [Layers inspection](https://github.com/tileflow/tileflow-sdk/blob/main/packages/dev/docs/layers-inspection.md).
|
|
167
173
|
|
|
168
174
|
**Tiles** shows resident map tiles as a coordinate grid and source-grouped list. Source layers,
|
|
169
175
|
Features and Info expose raw payload sizes, consumer layers, paginated features, GeoJSON and bounds.
|
|
@@ -184,8 +190,6 @@ drawing work. Findings open the affected layer and rule, show available evidence
|
|
|
184
190
|
for an agent. Unavailable observations and stale results remain explicit. **Diagnosis** in
|
|
185
191
|
Layers describes the selected layer's zoom, visibility and feature-rule context without turning
|
|
186
192
|
empty viewport queries into errors. Legacy `tab=beacon` links open Diagnostics.
|
|
187
|
-
See [Map design diagnostics](https://github.com/tileflow/tileflow-sdk/blob/main/packages/dev/docs/map-design-diagnostics.md)
|
|
188
|
-
for detectors, sampling and interpretation limits.
|
|
189
193
|
|
|
190
194
|
The preview's globe rim follows the rendered canvas silhouette, including camera and viewport
|
|
191
195
|
changes, and fades between zooms 3 and 6. Its colors follow the map's atmosphere when declared.
|
|
@@ -254,22 +258,8 @@ publish anything. Every normal entry point composes declared shared descriptors
|
|
|
254
258
|
catalog publication and lock maintenance stay in the `tileflow` CLI, which is the only writer of
|
|
255
259
|
`tileflow.icons.lock.json` and the only caller that resolves `latest`.
|
|
256
260
|
|
|
257
|
-
## Detailed guides
|
|
258
|
-
|
|
259
|
-
These references are also included under `docs/` in the installed package:
|
|
260
|
-
|
|
261
|
-
- [Building model preparation](https://github.com/tileflow/tileflow-sdk/blob/main/packages/dev/docs/building-models.md): colour slots, architectural roles, ambient visibility and compatibility.
|
|
262
|
-
- [Native artifact preparation](https://github.com/tileflow/tileflow-sdk/blob/main/packages/dev/docs/native-artifacts.md): static compatibility, renderer-qualified output, and limitations.
|
|
263
|
-
- [Artifact lifecycle](https://github.com/tileflow/tileflow-sdk/blob/main/packages/dev/docs/artifact-lifecycle.md): generations, immutable snapshots, provenance, and cleanup.
|
|
264
|
-
- [Local comparison and inspection](https://github.com/tileflow/tileflow-sdk/blob/main/packages/dev/docs/local-comparison-workbench-and-compiler-inspection.md): Inspector controls and preview-only models.
|
|
265
|
-
- [Config diagnostics](https://github.com/tileflow/tileflow-sdk/blob/main/packages/dev/docs/structured-config-inspection-and-diagnostics.md): bounded, machine-readable inspection.
|
|
266
|
-
- [PMTiles inspection](https://github.com/tileflow/tileflow-sdk/blob/main/packages/dev/docs/bounded-pmtiles-resource-inspection.md): metadata, sampling limits, and requested properties.
|
|
267
|
-
- [Feature and icon inspection](https://github.com/tileflow/tileflow-sdk/blob/main/packages/dev/docs/bounded-vector-feature-inspection.md): supported sources, icon compilation, and delivered-pixel hashes.
|
|
268
|
-
|
|
269
|
-
For an installed release, prefer its declarations and packaged guides over newer source on `main`.
|
|
270
|
-
|
|
271
261
|
## Recolorable icons
|
|
272
262
|
|
|
273
263
|
Declare SDF defaults and optional stretch/content layout in `tileflow.icons.json` beside ordinary artwork. Preparation
|
|
274
264
|
verifies both densities and rejects mixed representations within one symbol layer, including
|
|
275
|
-
fallbacks and local overrides.
|
|
265
|
+
fallbacks and local overrides.
|
package/dist/artifacts.js
CHANGED
|
@@ -32,20 +32,20 @@ import {
|
|
|
32
32
|
usesTileflowLineBackgroundGlyphs,
|
|
33
33
|
writeTileflowArtifactPlan,
|
|
34
34
|
writeTileflowBuildArtifacts
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-AVJMTXW5.js";
|
|
36
36
|
import {
|
|
37
37
|
getTileflowAssetBasePath,
|
|
38
38
|
getTileflowAssetFileName,
|
|
39
39
|
joinTileflowPublicUrl,
|
|
40
40
|
normalizeTileflowBasePath,
|
|
41
41
|
resolveTileflowArtifactPublicUrls
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-FOMTSCOP.js";
|
|
43
43
|
import {
|
|
44
44
|
encodeTileflowLandmarkRegion,
|
|
45
45
|
packageTileflowLandmarkTile,
|
|
46
46
|
prepareTileflowBuildingModel
|
|
47
|
-
} from "./chunk-
|
|
48
|
-
import "./chunk-
|
|
47
|
+
} from "./chunk-C4VPHZ3F.js";
|
|
48
|
+
import "./chunk-RTU7TD4M.js";
|
|
49
49
|
import "./chunk-KDFTE4Q5.js";
|
|
50
50
|
import {
|
|
51
51
|
defaultTileflowConfigPath
|
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
joinTileflowPublicUrl,
|
|
5
5
|
prepareTileflowStyleFonts,
|
|
6
6
|
replaceTileflowStyleFontSources
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-FOMTSCOP.js";
|
|
8
8
|
import {
|
|
9
9
|
getTileflowIconWatchPaths,
|
|
10
10
|
prepareTileflowCatalogIcons
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-C4VPHZ3F.js";
|
|
12
12
|
import {
|
|
13
13
|
TileflowStyleValidationError,
|
|
14
14
|
normalizeTileflowStyleValidationIssues,
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
} from "./chunk-ONYQNLNA.js";
|
|
29
29
|
|
|
30
30
|
// src/artifacts.ts
|
|
31
|
-
import { createHash as
|
|
31
|
+
import { createHash as createHash5 } from "crypto";
|
|
32
32
|
import { realpathSync as realpathSync2 } from "fs";
|
|
33
33
|
import {
|
|
34
34
|
copyFile as copyFile2,
|
|
@@ -68,8 +68,32 @@ import {
|
|
|
68
68
|
TileflowNativeCompatibilityError as TileflowNativeCompatibilityError4
|
|
69
69
|
} from "@tileflow/core/native-profile";
|
|
70
70
|
|
|
71
|
+
// src/image-source-assets.ts
|
|
72
|
+
import { createHash } from "crypto";
|
|
73
|
+
function prepareEmbeddedImageSources(input) {
|
|
74
|
+
const styles = structuredClone(input);
|
|
75
|
+
const assets = /* @__PURE__ */ new Map();
|
|
76
|
+
for (const [map, themes] of Object.entries(styles)) {
|
|
77
|
+
for (const style of Object.values(themes)) {
|
|
78
|
+
for (const source of Object.values(style.sources)) {
|
|
79
|
+
if (source.type !== "image" || typeof source.url !== "string") continue;
|
|
80
|
+
const match = /^data:image\/png;base64,([A-Za-z0-9+/]+={0,2})$/u.exec(source.url);
|
|
81
|
+
if (!match || match[1].length > 14 * 1024 * 1024) continue;
|
|
82
|
+
const bytes = Buffer.from(match[1], "base64");
|
|
83
|
+
if (bytes.length < 24 || !bytes.subarray(0, 8).equals(Buffer.from("89504e470d0a1a0a", "hex")))
|
|
84
|
+
continue;
|
|
85
|
+
const hash = createHash("sha256").update(bytes).digest("hex");
|
|
86
|
+
const fileName = `images/${map}/${hash}.png`;
|
|
87
|
+
assets.set(fileName, { contentType: "image/png", fileName, source: bytes });
|
|
88
|
+
source.url = `../../${fileName}`;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return { styles, assets: [...assets.values()] };
|
|
93
|
+
}
|
|
94
|
+
|
|
71
95
|
// src/line-background-glyphs.ts
|
|
72
|
-
import { createHash, randomUUID } from "crypto";
|
|
96
|
+
import { createHash as createHash2, randomUUID } from "crypto";
|
|
73
97
|
import { lstat, mkdir, readFile, rename, rm, writeFile } from "fs/promises";
|
|
74
98
|
import { resolve } from "path";
|
|
75
99
|
import {
|
|
@@ -245,7 +269,7 @@ function absoluteHttpUrl(value) {
|
|
|
245
269
|
}
|
|
246
270
|
}
|
|
247
271
|
function digest(value) {
|
|
248
|
-
return
|
|
272
|
+
return createHash2("sha256").update(value).digest("hex").slice(0, 32);
|
|
249
273
|
}
|
|
250
274
|
function hasCode(error, code) {
|
|
251
275
|
return Boolean(error && typeof error === "object" && "code" in error && error.code === code);
|
|
@@ -567,25 +591,28 @@ function hasErrorCode(error, code) {
|
|
|
567
591
|
}
|
|
568
592
|
|
|
569
593
|
// src/native-artifacts.ts
|
|
570
|
-
import { createHash as createHash2 } from "crypto";
|
|
571
594
|
import {
|
|
572
595
|
convertFilter,
|
|
573
596
|
validateStyleMin
|
|
574
597
|
} from "@maplibre/maplibre-gl-style-spec";
|
|
598
|
+
import { createHash as createHash3 } from "crypto";
|
|
575
599
|
import {
|
|
576
600
|
getTileflowStyleFontFaces,
|
|
577
601
|
serializeCanonicalJson,
|
|
578
602
|
steadyTileflowNauticalLights,
|
|
579
|
-
tileflowStyleFontFacesMetadataKey,
|
|
580
603
|
tileflowIconIdPattern,
|
|
581
|
-
tileflowIconPackageLimits
|
|
604
|
+
tileflowIconPackageLimits,
|
|
605
|
+
tileflowStyleFontFacesMetadataKey
|
|
582
606
|
} from "@tileflow/core";
|
|
607
|
+
import {
|
|
608
|
+
prepareTileflowNativePathGround
|
|
609
|
+
} from "@tileflow/core/build";
|
|
583
610
|
import {
|
|
584
611
|
createTileflowNativeDiagnostic,
|
|
585
612
|
TileflowNativeCompatibilityError,
|
|
586
613
|
tileflowNativeProfileLimits,
|
|
587
|
-
|
|
588
|
-
|
|
614
|
+
validateTileflowNativePreparedStyle,
|
|
615
|
+
validateTileflowNativeStyle
|
|
589
616
|
} from "@tileflow/core/native-profile";
|
|
590
617
|
|
|
591
618
|
// src/native-layer-references.ts
|
|
@@ -1266,7 +1293,9 @@ function lowerTileflowNativeCompiledStyles(input, policy = {}) {
|
|
|
1266
1293
|
styles[map] = {};
|
|
1267
1294
|
for (const theme of Object.keys(input[map]).sort()) {
|
|
1268
1295
|
const web = input[map][theme];
|
|
1269
|
-
const
|
|
1296
|
+
const steady = steadyTileflowNauticalLights(web);
|
|
1297
|
+
const original = prepareTileflowNativePathGround(steady);
|
|
1298
|
+
const pathGroundFallback = original !== steady;
|
|
1270
1299
|
try {
|
|
1271
1300
|
const options = { ...urlOptions(map, theme, policy), deferFontClosure: true };
|
|
1272
1301
|
const pending = validateTileflowNativeStyle(original, options);
|
|
@@ -1324,12 +1353,13 @@ function lowerTileflowNativeCompiledStyles(input, policy = {}) {
|
|
|
1324
1353
|
transformations.push({
|
|
1325
1354
|
map,
|
|
1326
1355
|
theme,
|
|
1327
|
-
inputStyleSha256:
|
|
1328
|
-
loweredStyleSha256:
|
|
1356
|
+
inputStyleSha256: createHash3("sha256").update(serializeCanonicalJson(web)).digest("hex"),
|
|
1357
|
+
loweredStyleSha256: createHash3("sha256").update(serializeCanonicalJson(style)).digest("hex"),
|
|
1329
1358
|
inputLayers: lowered.inputLayers,
|
|
1330
1359
|
outputLayers: lowered.outputLayers,
|
|
1331
1360
|
projection: lowered.projection,
|
|
1332
1361
|
...lowered.sky ? { sky: lowered.sky } : {},
|
|
1362
|
+
...pathGroundFallback ? { pathGround: "ground-fallback" } : {},
|
|
1333
1363
|
layers: lowered.layers,
|
|
1334
1364
|
symbolOverlap: lowered.symbolOverlap
|
|
1335
1365
|
});
|
|
@@ -1441,7 +1471,7 @@ function isNativeFontAsset(asset) {
|
|
|
1441
1471
|
if (!/\.(?:ttf|otf)$/u.test(asset.fileName) || !["00010000", "4f54544f"].includes(signature))
|
|
1442
1472
|
return false;
|
|
1443
1473
|
const expectedHash = /-([a-f0-9]{64})\.(?:ttf|otf)$/u.exec(asset.fileName)?.[1];
|
|
1444
|
-
return expectedHash ===
|
|
1474
|
+
return expectedHash === createHash3("sha256").update(bytes).digest("hex");
|
|
1445
1475
|
}
|
|
1446
1476
|
function assertTileflowNativeGeneratedStyle(style, map, theme, policy = {}) {
|
|
1447
1477
|
const issues = validateTileflowNativePreparedStyle(style, urlOptions(map, theme, policy));
|
|
@@ -1647,6 +1677,9 @@ var TileflowArtifactSessionImpl = class {
|
|
|
1647
1677
|
await watcherReady;
|
|
1648
1678
|
}
|
|
1649
1679
|
await this.refresh("initial");
|
|
1680
|
+
while (!this.#current && this.#state.status === "building" && !this.#closed) {
|
|
1681
|
+
await Promise.all([...this.#refreshes]);
|
|
1682
|
+
}
|
|
1650
1683
|
if (this.#watcher && !this.#closed) {
|
|
1651
1684
|
this.#startupCheckTimer = setTimeout(() => {
|
|
1652
1685
|
this.#startupCheckTimer = void 0;
|
|
@@ -2050,7 +2083,7 @@ function boundDiagnosticText(value, limit) {
|
|
|
2050
2083
|
}
|
|
2051
2084
|
|
|
2052
2085
|
// src/hosted-native-artifacts.ts
|
|
2053
|
-
import { createHash as
|
|
2086
|
+
import { createHash as createHash4 } from "crypto";
|
|
2054
2087
|
import { serializeCanonicalJson as serializeCanonicalJson2 } from "@tileflow/core";
|
|
2055
2088
|
import {
|
|
2056
2089
|
inferTileflowDataRequirements,
|
|
@@ -2062,7 +2095,7 @@ import {
|
|
|
2062
2095
|
TileflowNativeCompatibilityError as TileflowNativeCompatibilityError3,
|
|
2063
2096
|
createTileflowNativeDiagnostic as createTileflowNativeDiagnostic2
|
|
2064
2097
|
} from "@tileflow/core/native-profile";
|
|
2065
|
-
var digest2 = (value) =>
|
|
2098
|
+
var digest2 = (value) => createHash4("sha256").update(serializeCanonicalJson2(value)).digest("hex");
|
|
2066
2099
|
var invalidSource = () => new TileflowNativeCompatibilityError3([
|
|
2067
2100
|
createTileflowNativeDiagnostic2("NATIVE_UNSUPPORTED_SOURCE", "/sources")
|
|
2068
2101
|
]);
|
|
@@ -2239,7 +2272,8 @@ async function createTileflowArtifactPlan(prepared, options = {}) {
|
|
|
2239
2272
|
apiBaseUrl: options.apiBaseUrl,
|
|
2240
2273
|
mapAssets: prepared.mapAssets
|
|
2241
2274
|
});
|
|
2242
|
-
const
|
|
2275
|
+
const embeddedImages = renderer === "native" ? prepareEmbeddedImageSources(compiledStyles) : { styles: compiledStyles, assets: [] };
|
|
2276
|
+
const nativeLowering = renderer === "native" ? lowerTileflowNativeCompiledStyles(embeddedImages.styles, nativeUrls) : void 0;
|
|
2243
2277
|
const rendererStyles = nativeLowering?.styles ?? compiledStyles;
|
|
2244
2278
|
if (renderer === "native")
|
|
2245
2279
|
assertTileflowNativeCompiledStyles(prepared.project, rendererStyles, nativeUrls);
|
|
@@ -2262,7 +2296,7 @@ async function createTileflowArtifactPlan(prepared, options = {}) {
|
|
|
2262
2296
|
}
|
|
2263
2297
|
throw error;
|
|
2264
2298
|
});
|
|
2265
|
-
const assets = [...prepared.assets, ...preparedFonts.assets];
|
|
2299
|
+
const assets = [...prepared.assets, ...preparedFonts.assets, ...embeddedImages.assets];
|
|
2266
2300
|
const lineBackgroundGlyphs = renderer === "native" || options.target === "production" ? { providers: {}, styles: preparedFonts.styles } : prepareTileflowLineBackgroundGlyphs(preparedFonts.styles, {
|
|
2267
2301
|
assetBaseUrl: resolveRendererAssetBaseUrl(options)
|
|
2268
2302
|
});
|
|
@@ -2526,7 +2560,7 @@ function retargetLocalFontAssetUrl(source, assets, generation) {
|
|
|
2526
2560
|
function getMapBuildAssets(mapName, assets, fontAssets) {
|
|
2527
2561
|
const selected = /* @__PURE__ */ new Map();
|
|
2528
2562
|
for (const asset of assets) {
|
|
2529
|
-
if (asset.fileName.startsWith(`icons/${mapName}/`) || asset.fileName.startsWith(`models/${mapName}/`))
|
|
2563
|
+
if (asset.fileName.startsWith(`icons/${mapName}/`) || asset.fileName.startsWith(`models/${mapName}/`) || asset.fileName.startsWith(`images/${mapName}/`))
|
|
2530
2564
|
selected.set(asset.fileName, asset);
|
|
2531
2565
|
}
|
|
2532
2566
|
for (const asset of fontAssets) {
|
|
@@ -2537,7 +2571,7 @@ function getMapBuildAssets(mapName, assets, fontAssets) {
|
|
|
2537
2571
|
);
|
|
2538
2572
|
}
|
|
2539
2573
|
function hashBytes(source) {
|
|
2540
|
-
return
|
|
2574
|
+
return createHash5("sha256").update(typeof source === "string" ? Buffer.from(source, "utf8") : Buffer.from(source)).digest("hex");
|
|
2541
2575
|
}
|
|
2542
2576
|
async function createTileflowBuildProvenance(cwd) {
|
|
2543
2577
|
const projectDirectory = resolve4(cwd);
|
|
@@ -2981,10 +3015,11 @@ function assertTileflowArtifactFileName(fileName) {
|
|
|
2981
3015
|
const logicalName = fileName.replace(/^generations\/[a-f0-9]{64}\//, "");
|
|
2982
3016
|
const styleMatch = /^styles\/([^/]+)\/([^/]+)\.json$/u.exec(logicalName);
|
|
2983
3017
|
const iconMatch = /^icons\/([^/]+)\/sprite(?:@2x)?\.(?:json|png)$/u.exec(logicalName);
|
|
3018
|
+
const imageMatch = /^images\/([^/]+)\/[a-f0-9]{64}\.png$/u.exec(logicalName);
|
|
2984
3019
|
const modelMatch = /^models\/([^/]+)\/[a-z0-9]+(?:-[a-z0-9]+)*-[a-f0-9]{16}\.glb$/u.exec(
|
|
2985
3020
|
logicalName
|
|
2986
3021
|
);
|
|
2987
|
-
if (fileName === "manifest.json" || fileName === tileflowMapBuildManifestFileName || fileName === tileflowNativeBuildRecordFileName || styleMatch && tileflowMapIdSchema.safeParse(styleMatch[1]).success && tileflowThemeNameSchema.safeParse(styleMatch[2]).success || iconMatch && tileflowMapIdSchema.safeParse(iconMatch[1]).success || modelMatch && tileflowMapIdSchema.safeParse(modelMatch[1]).success || /^tilesets\/[A-Za-z0-9][A-Za-z0-9._-]{0,127}\.pmtiles$/u.test(logicalName) || /^fonts\/[a-z0-9]+(?:-[a-z0-9]+)*-[a-f0-9]{64}\.(?:otf|ttf|woff2)$/.test(logicalName) || /^fonts\/licenses\/license-[a-f0-9]{64}\.txt$/.test(logicalName)) {
|
|
3022
|
+
if (fileName === "manifest.json" || fileName === tileflowMapBuildManifestFileName || fileName === tileflowNativeBuildRecordFileName || styleMatch && tileflowMapIdSchema.safeParse(styleMatch[1]).success && tileflowThemeNameSchema.safeParse(styleMatch[2]).success || iconMatch && tileflowMapIdSchema.safeParse(iconMatch[1]).success || imageMatch && tileflowMapIdSchema.safeParse(imageMatch[1]).success || modelMatch && tileflowMapIdSchema.safeParse(modelMatch[1]).success || /^tilesets\/[A-Za-z0-9][A-Za-z0-9._-]{0,127}\.pmtiles$/u.test(logicalName) || /^fonts\/[a-z0-9]+(?:-[a-z0-9]+)*-[a-f0-9]{64}\.(?:otf|ttf|woff2)$/.test(logicalName) || /^fonts\/licenses\/license-[a-f0-9]{64}\.txt$/.test(logicalName)) {
|
|
2988
3023
|
return;
|
|
2989
3024
|
}
|
|
2990
3025
|
throw new Error(`Unexpected Tileflow managed artifact file name: ${fileName}`);
|
|
@@ -3024,7 +3059,7 @@ async function removeManagedFile(path) {
|
|
|
3024
3059
|
}
|
|
3025
3060
|
}
|
|
3026
3061
|
function hashArtifactGeneration(files) {
|
|
3027
|
-
const hash =
|
|
3062
|
+
const hash = createHash5("sha256");
|
|
3028
3063
|
for (const file of files) {
|
|
3029
3064
|
const source = typeof file.source === "string" ? Buffer.from(file.source, "utf8") : Buffer.from(file.source);
|
|
3030
3065
|
hash.update(`${file.fileName}\0${file.contentType}\0${source.byteLength}\0`, "utf8");
|