maplibre-gl 6.0.0-21 → 6.0.0-22

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.
Files changed (60) hide show
  1. package/build/generate-struct-arrays.ts +3 -3
  2. package/build/generate-style-code.ts +232 -134
  3. package/dist/maplibre-gl-dev.mjs +59 -89
  4. package/dist/maplibre-gl-dev.mjs.map +1 -1
  5. package/dist/maplibre-gl-shared-dev.mjs +549 -351
  6. package/dist/maplibre-gl-shared-dev.mjs.map +1 -1
  7. package/dist/maplibre-gl-shared.mjs +2 -2
  8. package/dist/maplibre-gl-shared.mjs.map +1 -1
  9. package/dist/maplibre-gl-worker-dev.mjs +12 -12
  10. package/dist/maplibre-gl-worker-dev.mjs.map +1 -1
  11. package/dist/maplibre-gl-worker.mjs +2 -2
  12. package/dist/maplibre-gl-worker.mjs.map +1 -1
  13. package/dist/maplibre-gl.d.ts +1035 -1030
  14. package/dist/maplibre-gl.mjs +13 -13
  15. package/dist/maplibre-gl.mjs.map +1 -1
  16. package/package.json +20 -20
  17. package/src/data/feature_index.ts +2 -2
  18. package/src/geo/projection/globe_projection.test.ts +23 -0
  19. package/src/geo/projection/globe_projection.ts +5 -16
  20. package/src/source/geojson_source.ts +1 -1
  21. package/src/source/geojson_worker_source.test.ts +1 -0
  22. package/src/source/geojson_worker_source.ts +11 -9
  23. package/src/style/format_section_override.test.ts +1 -0
  24. package/src/style/light.test.ts +24 -3
  25. package/src/style/light.ts +17 -80
  26. package/src/style/light_properties.g.ts +41 -0
  27. package/src/style/projection_properties.g.ts +32 -0
  28. package/src/style/properties.test.ts +63 -7
  29. package/src/style/properties.ts +42 -16
  30. package/src/style/sky.test.ts +20 -1
  31. package/src/style/sky.ts +9 -48
  32. package/src/style/sky_properties.g.ts +50 -0
  33. package/src/style/style.test.ts +39 -0
  34. package/src/style/style.ts +11 -25
  35. package/src/style/style_layer/background_style_layer_properties.g.ts +5 -5
  36. package/src/style/style_layer/circle_style_layer_properties.g.ts +16 -15
  37. package/src/style/style_layer/color_relief_style_layer_properties.g.ts +5 -5
  38. package/src/style/style_layer/custom_style_layer.ts +8 -13
  39. package/src/style/style_layer/fill_extrusion_style_layer_properties.g.ts +10 -10
  40. package/src/style/style_layer/fill_style_layer_properties.g.ts +13 -12
  41. package/src/style/style_layer/heatmap_style_layer_properties.g.ts +7 -7
  42. package/src/style/style_layer/hillshade_style_layer_properties.g.ts +11 -11
  43. package/src/style/style_layer/line_style_layer.ts +1 -1
  44. package/src/style/style_layer/line_style_layer_properties.g.ts +21 -20
  45. package/src/style/style_layer/raster_style_layer_properties.g.ts +11 -11
  46. package/src/style/style_layer/symbol_style_layer.ts +1 -1
  47. package/src/style/style_layer/symbol_style_layer_properties.g.ts +62 -61
  48. package/src/style/style_layer.ts +13 -24
  49. package/src/style/style_layer_index.ts +1 -1
  50. package/src/style/validate_style.test.ts +109 -0
  51. package/src/style/validate_style.ts +93 -26
  52. package/src/tile/terrain_tile_manager.test.ts +1 -1
  53. package/src/tile/tile.ts +1 -1
  54. package/src/ui/map.ts +6 -1
  55. package/src/ui/map_tests/map_terrain.test.ts +25 -0
  56. package/src/util/color_ramp.test.ts +3 -3
  57. package/src/util/util.ts +7 -12
  58. package/src/util/web_worker_transfer.test.ts +1 -1
  59. package/src/webgl/draw/draw_sky.ts +2 -2
  60. package/src/webgl/program/fill_extrusion_program.ts +1 -2
@@ -9,7 +9,7 @@
9
9
  'use strict';
10
10
 
11
11
  import * as fs from 'fs';
12
- import * as util from '../src/util/util.ts';
12
+ import {extend} from '../src/util/util.ts';
13
13
  import {createLayout, viewTypes} from '../src/util/struct_array.ts';
14
14
  import type {ViewType, StructArrayLayout} from '../src/util/struct_array.ts';
15
15
 
@@ -60,7 +60,7 @@ function normalizeMembers(members, usedTypes) {
60
60
  usedTypes.add(member.type);
61
61
  }
62
62
 
63
- return util.extend(member, {
63
+ return extend(member, {
64
64
  size: sizeOf(member.type),
65
65
  view: member.type.toLowerCase()
66
66
  });
@@ -103,7 +103,7 @@ function createStructArrayLayoutType({members, size, alignment}) {
103
103
  if (!alignment || alignment === 1) members = members.reduce((memo, member) => {
104
104
  if (memo.length > 0 && memo[memo.length - 1].type === member.type) {
105
105
  const last = memo[memo.length - 1];
106
- return memo.slice(0, -1).concat(util.extend({}, last, {
106
+ return memo.slice(0, -1).concat(extend({}, last, {
107
107
  components: last.components + member.components,
108
108
  }));
109
109
  }
@@ -2,7 +2,87 @@
2
2
 
3
3
  import * as fs from 'fs';
4
4
 
5
- import {v8} from '@maplibre/maplibre-gl-style-spec';
5
+ import {latest, type StylePropertySpecification} from '@maplibre/maplibre-gl-style-spec';
6
+
7
+ /**
8
+ * Which kind of value a property holds, and so which `Property` class implements it.
9
+ * Taken from the spec so a new kind shows up here as a compile error rather than at runtime.
10
+ */
11
+ type SpecPropertyType = StylePropertySpecification['property-type'];
12
+
13
+ /** The allowed values of an `enum`, keyed by name. */
14
+ type SpecEnumValues = {[value: string]: unknown};
15
+
16
+ /** The types a value can have when it carries nothing beyond the type itself. */
17
+ type SpecScalarType =
18
+ 'boolean' | 'number' | 'string' | 'color' | 'padding' | 'formatted' | 'resolvedImage' |
19
+ 'numberArray' | 'colorArray' | 'projectionDefinition' | 'variableAnchorOffsetCollection';
20
+
21
+ /**
22
+ * The part of a spec entry that describes what a value looks like. `enum` and `array` carry extra
23
+ * fields; everything else is just its type. Arrays describe their elements the same way, so this is
24
+ * also the shape passed when recursing into one.
25
+ */
26
+ type SpecValue =
27
+ /** the `name` on each is the property this came from, used for error messages */
28
+ | {type: SpecScalarType; name?: string}
29
+ | {type: 'enum'; values: SpecEnumValues; name?: string}
30
+ | {
31
+ type: 'array';
32
+ /** the type of each element */
33
+ value: 'number' | 'string' | 'enum';
34
+ /** how many elements, when the spec pins it down */
35
+ length?: number;
36
+ /** for an array of `enum`, the allowed values live here, on the array itself */
37
+ values?: SpecEnumValues;
38
+ name?: string;
39
+ };
40
+
41
+ /**
42
+ * A property of the style spec, tagged with where it lives so the generated code can reach its spec
43
+ * at runtime: either a layer's `layout`/`paint`, or a root such as `sky`.
44
+ */
45
+ type SpecProperty = SpecValue & {
46
+ name: string;
47
+ 'property-type': SpecPropertyType;
48
+ /** whether a data-driven property can be overridden per formatted section, e.g. `text-color` */
49
+ overridable?: boolean;
50
+ /** the layer type owning this property, e.g. `fill` */
51
+ layerType?: string;
52
+ /** the style root owning this property, e.g. `sky` */
53
+ root?: string;
54
+ };
55
+
56
+ /** A layer's properties, as {@link emitLayerProperties} takes them. */
57
+ type LayerProperties = {
58
+ type: string;
59
+ layoutProperties: SpecProperty[];
60
+ paintProperties: SpecProperty[];
61
+ };
62
+
63
+ /** A root's properties, as {@link emitRootProperties} takes them. */
64
+ type RootProperties = {
65
+ root: string;
66
+ properties: SpecProperty[];
67
+ };
68
+
69
+ /**
70
+ * One group of properties: the `Props` type, the `PropsPossiblyEvaluated` type, and the lazily
71
+ * built `Properties` singleton holding them. A layer file has one of these for `layout` and one for
72
+ * `paint`; a root file has a single one.
73
+ */
74
+ type PropertyBlock = {
75
+ /** what the generated types are named after, e.g. `FillPaint` gives `FillPaintProps` */
76
+ typeName: string;
77
+ properties: SpecProperty[];
78
+ /** the group the properties live in: `layout`, `paint`, or a root such as `sky` */
79
+ specGroup: string;
80
+ /** the singleton, and the getter that builds it on first use */
81
+ variable: string;
82
+ getter: string;
83
+ /** whether the getter is part of the module's API, or only reached through its default export */
84
+ exportGetter: boolean;
85
+ };
6
86
 
7
87
  function camelCase(str: string): string {
8
88
  return str.replace(/-(.)/g, (_, x) => {
@@ -15,7 +95,15 @@ function pascalCase(str: string): string {
15
95
  return almostCamelized[0].toUpperCase() + almostCamelized.slice(1);
16
96
  }
17
97
 
18
- function nativeType(property) {
98
+ /** How each element of an `array` property is specified. */
99
+ function elementOf(property: Extract<SpecValue, {type: 'array'}>): SpecValue {
100
+ return property.value === 'enum' ?
101
+ {type: 'enum', values: property.values ?? {}, name: property.name} :
102
+ {type: property.value, name: property.name};
103
+ }
104
+
105
+ /** The TypeScript type a property evaluates to, e.g. `Color` or `"map" | "viewport"`. */
106
+ function nativeType(property: SpecValue): string {
19
107
  switch (property.type) {
20
108
  case 'boolean':
21
109
  return 'boolean';
@@ -35,24 +123,29 @@ function nativeType(property) {
35
123
  return 'ColorArray';
36
124
  case 'variableAnchorOffsetCollection':
37
125
  return 'VariableAnchorOffsetCollection';
38
- case 'sprite':
39
- return 'Sprite';
126
+ case 'projectionDefinition':
127
+ return 'ProjectionDefinitionSpecification';
40
128
  case 'formatted':
41
129
  return 'Formatted';
42
130
  case 'resolvedImage':
43
131
  return 'ResolvedImage';
44
- case 'array':
132
+ case 'array': {
133
+ const inner = nativeType(elementOf(property));
45
134
  if (property.length) {
46
- return `[${new Array(property.length).fill(nativeType({type: property.value})).join(', ')}]`;
47
- } else {
48
- const inner = nativeType({type: property.value, values: property.values});
49
- return inner.includes('|') ? `Array<${inner}>` : `${inner}[]`;
135
+ return `[${new Array(property.length).fill(inner).join(', ')}]`;
50
136
  }
51
- default: throw new Error(`unknown type "${property.type}" for "${property.name}"`);
137
+ return inner.includes('|') ? `Array<${inner}>` : `${inner}[]`;
138
+ }
139
+ // Unreachable per the union above, but the spec is JSON: this still fires if it grows a type.
140
+ default: {
141
+ const {type, name} = property as SpecValue;
142
+ throw new Error(`unknown type "${type}" for "${name}"`);
143
+ }
52
144
  }
53
145
  }
54
146
 
55
- function possiblyEvaluatedType(property) {
147
+ /** The type the property has once evaluated, which for data-driven ones wraps {@link nativeType}. */
148
+ function possiblyEvaluatedType(property: SpecProperty): string {
56
149
  const propType = nativeType(property);
57
150
 
58
151
  switch (property['property-type']) {
@@ -69,7 +162,8 @@ function possiblyEvaluatedType(property) {
69
162
  return propType;
70
163
  }
71
164
 
72
- function propertyType(property) {
165
+ /** The `Property` class implementing this property, e.g. `DataConstantProperty<Color>`. */
166
+ function propertyType(property: SpecProperty): string {
73
167
  switch (property['property-type']) {
74
168
  case 'data-driven':
75
169
  return `DataDrivenProperty<${nativeType(property)}>`;
@@ -87,7 +181,8 @@ function propertyType(property) {
87
181
  }
88
182
  }
89
183
 
90
- function runtimeType(property) {
184
+ /** The expression type used to evaluate an overridable property at runtime. */
185
+ function runtimeType(property: SpecValue): string {
91
186
  switch (property.type) {
92
187
  case 'boolean':
93
188
  return 'BooleanType';
@@ -102,80 +197,73 @@ function runtimeType(property) {
102
197
  return 'PaddingType';
103
198
  case 'variableAnchorOffsetCollection':
104
199
  return 'VariableAnchorOffsetCollectionType';
105
- case 'sprite':
106
- return 'SpriteType';
107
200
  case 'formatted':
108
201
  return 'FormattedType';
109
- case 'Image':
110
- return 'ImageType';
111
- case 'array':
112
- if (property.length) {
113
- return `array(${runtimeType({type: property.value})}, ${property.length})`;
114
- } else {
115
- return `array(${runtimeType({type: property.value})})`;
116
- }
202
+ case 'array': {
203
+ const inner = runtimeType(elementOf(property));
204
+ return property.length ? `array(${inner}, ${property.length})` : `array(${inner})`;
205
+ }
117
206
  default: throw new Error(`unknown type "${property.type}" for "${property.name}"`);
118
207
  }
119
208
  }
120
209
 
121
- function overrides(property) {
210
+ /** How a formatted section overrides an overridable property, e.g. `text-color`. */
211
+ function overrides(property: SpecProperty): string {
122
212
  return `{ runtimeType: ${runtimeType(property)}, getOverride: (o) => o.${camelCase(property.name)}, hasOverride: (o) => !!o.${camelCase(property.name)} }`;
123
213
  }
124
214
 
125
- function propertyValue(property, type) {
126
- const propertyAsSpec = `styleSpec["${type}_${property.layerType}"]["${property.name}"] as any as StylePropertySpecification`;
215
+ /**
216
+ * Where a property's spec lives, e.g. `styleSpec["paint_fill"]["fill-color"]` for a layer property
217
+ * and `styleSpec["sky"]["sky-color"]` for a root one.
218
+ */
219
+ function specPath(property: SpecProperty, type: string): string {
220
+ return property.root ?
221
+ `styleSpec["${property.root}"]["${property.name}"]` :
222
+ `styleSpec["${type}_${property.layerType}"]["${property.name}"]`;
223
+ }
224
+
225
+ /** How the generated code constructs the property, e.g. `new DataConstantProperty(...)`. */
226
+ function propertyValue(property: SpecProperty, type: string): string {
227
+ const propertyAsSpec = `${specPath(property, type)} as any as StylePropertySpecification`;
228
+ const name = JSON.stringify(property.name);
127
229
 
128
230
  switch (property['property-type']) {
129
231
  case 'data-driven':
130
232
  if (property.overridable) {
131
- return `new DataDrivenProperty(${propertyAsSpec}, ${overrides(property)})`;
233
+ return `new DataDrivenProperty(${propertyAsSpec}, ${name}, ${overrides(property)})`;
132
234
  } else {
133
- return `new DataDrivenProperty(${propertyAsSpec})`;
235
+ return `new DataDrivenProperty(${propertyAsSpec}, ${name})`;
134
236
  }
135
237
  case 'cross-faded':
136
- return `new CrossFadedProperty(${propertyAsSpec})`;
238
+ return `new CrossFadedProperty(${propertyAsSpec}, ${name})`;
137
239
  case 'cross-faded-data-driven':
138
- return `new CrossFadedDataDrivenProperty(${propertyAsSpec})`;
240
+ return `new CrossFadedDataDrivenProperty(${propertyAsSpec}, ${name})`;
139
241
  case 'color-ramp':
140
- return `new ColorRampProperty(${propertyAsSpec})`;
242
+ return `new ColorRampProperty(${propertyAsSpec}, ${name})`;
141
243
  case 'data-constant':
142
244
  case 'constant':
143
- return `new DataConstantProperty(${propertyAsSpec})`;
245
+ return `new DataConstantProperty(${propertyAsSpec}, ${name})`;
144
246
  default:
145
247
  throw new Error(`unknown property-type "${property['property-type']}" for ${property.name}`);
146
248
  }
147
249
  }
148
250
 
149
- const layers = Object.keys(v8.layer.type.values).map((type) => {
150
- const layoutProperties = Object.keys(v8[`layout_${type}`]).reduce((memo, name) => {
151
- if (name !== 'visibility') {
152
- v8[`layout_${type}`][name].name = name;
153
- v8[`layout_${type}`][name].layerType = type;
154
- memo.push(v8[`layout_${type}`][name]);
155
- }
156
- return memo;
157
- }, []);
158
-
159
- const paintProperties = Object.keys(v8[`paint_${type}`]).reduce((memo, name) => {
160
- v8[`paint_${type}`][name].name = name;
161
- v8[`paint_${type}`][name].layerType = type;
162
- memo.push(v8[`paint_${type}`][name]);
163
- return memo;
164
- }, []);
165
-
166
- return {type, layoutProperties, paintProperties};
167
- });
168
-
169
- function emitlayerProperties(locals) {
170
- const output = [];
171
- const layerType = pascalCase(locals.type);
172
- const {
173
- layoutProperties,
174
- paintProperties
175
- } = locals;
176
-
177
- output.push(
178
- `// This file is generated. Edit build/generate-style-code.ts, then run 'npm run codegen'.
251
+ /**
252
+ * Parts of the style that carry properties without being layers. Their spec entries have the same
253
+ * shape as a layer's, so the same code generates them.
254
+ */
255
+ /**
256
+ * Collects the properties the spec lists under `specKey`, tagging each one with its name and with
257
+ * where it came from, which is what {@link specPath} needs to point the generated code back at it.
258
+ */
259
+ function specProperties(specKey: string, tag: Pick<SpecProperty, 'layerType'> | Pick<SpecProperty, 'root'>): SpecProperty[] {
260
+ const spec = latest[specKey as keyof typeof latest] as unknown as Record<string, SpecProperty>;
261
+ return Object.keys(spec).map((name) => ({...spec[name], ...tag, name}));
262
+ }
263
+
264
+ /** The imports every generated file opens with. */
265
+ function emitHeader(propertiesPath: string): string {
266
+ return `// This file is generated. Edit build/generate-style-code.ts, then run 'npm run codegen'.
179
267
  /* eslint-disable */
180
268
 
181
269
  import {latest as styleSpec} from '@maplibre/maplibre-gl-style-spec';
@@ -189,100 +277,110 @@ import {
189
277
  ColorRampProperty,
190
278
  PossiblyEvaluatedPropertyValue,
191
279
  CrossFaded
192
- } from '../properties.ts';
280
+ } from '${propertiesPath}';
193
281
 
194
- import type {Color, Formatted, Padding, NumberArray, ColorArray, ResolvedImage, VariableAnchorOffsetCollection} from '@maplibre/maplibre-gl-style-spec';
282
+ import type {Color, Formatted, Padding, NumberArray, ColorArray, ResolvedImage, VariableAnchorOffsetCollection, ProjectionDefinitionSpecification} from '@maplibre/maplibre-gl-style-spec';
195
283
  import {StylePropertySpecification} from '@maplibre/maplibre-gl-style-spec';
196
- `);
197
-
198
- const overridables = paintProperties.filter(p => p.overridable);
199
- if (overridables.length) {
200
- const overridesArray = `import {
201
- ${overridables.reduce((imports, prop) => { imports.push(runtimeType(prop)); return imports; }, []).join(',\n ')}
202
- } from '@maplibre/maplibre-gl-style-spec';
203
- `;
204
- output.push(overridesArray);
205
- }
206
-
207
- if (layoutProperties.length) {
208
- output.push(
209
- `export type ${layerType}LayoutProps = {`);
210
-
211
- for (const property of layoutProperties) {
212
- output.push(
213
- ` "${property.name}": ${propertyType(property)},`);
214
- }
215
-
216
- output.push(
217
- `};
218
-
219
- export type ${layerType}LayoutPropsPossiblyEvaluated = {`);
220
-
221
- for (const property of layoutProperties) {
222
- output.push(
223
- ` "${property.name}": ${possiblyEvaluatedType(property)},`);
224
- }
284
+ `;
285
+ }
225
286
 
226
- output.push(
227
- `};
287
+ function emitPropertyBlock({typeName, properties, specGroup, variable, getter, exportGetter}: PropertyBlock): string {
288
+ const output: string[] = [];
228
289
 
229
- let layout: Properties<${layerType}LayoutProps>;
230
- const getLayout = () => layout = layout || new Properties({`);
290
+ output.push(`
291
+ export type ${typeName}Props = {`);
292
+ for (const property of properties) {
293
+ output.push(` "${property.name}": ${propertyType(property)},`);
294
+ }
231
295
 
232
- for (const property of layoutProperties) {
233
- output.push(
234
- ` "${property.name}": ${propertyValue(property, 'layout')},`);
235
- }
296
+ output.push(`};
236
297
 
237
- output.push(
238
- '});');
298
+ export type ${typeName}PropsPossiblyEvaluated = {`);
299
+ for (const property of properties) {
300
+ output.push(` "${property.name}": ${possiblyEvaluatedType(property)},`);
239
301
  }
240
302
 
241
- if (paintProperties.length) {
242
- output.push(
243
- `
244
- export type ${layerType}PaintProps = {`);
303
+ output.push(`};
245
304
 
246
- for (const property of paintProperties) {
247
- output.push(
248
- ` "${property.name}": ${propertyType(property)},`);
249
- }
305
+ let ${variable}: Properties<${typeName}Props>;
306
+ ${exportGetter ? 'export ' : ''}const ${getter} = (): Properties<${typeName}Props> => ${variable} = ${variable} || new Properties({`);
307
+ for (const property of properties) {
308
+ output.push(` "${property.name}": ${propertyValue(property, specGroup)},`);
309
+ }
250
310
 
251
- output.push(
252
- `};
311
+ output.push('});');
253
312
 
254
- export type ${layerType}PaintPropsPossiblyEvaluated = {`);
313
+ return output.join('\n');
314
+ }
255
315
 
256
- for (const property of paintProperties) {
257
- output.push(
258
- ` "${property.name}": ${possiblyEvaluatedType(property)},`);
259
- }
316
+ function emitLayerProperties({type, layoutProperties, paintProperties}: LayerProperties): string {
317
+ const layerType = pascalCase(type);
318
+ const output: string[] = [emitHeader('../properties.ts')];
260
319
 
261
- output.push(
262
- '};');
263
- } else {
264
- output.push(
265
- `export type ${layerType}PaintProps = {};`);
320
+ const overridables = paintProperties.filter(p => p.overridable);
321
+ if (overridables.length) {
322
+ output.push(`import {
323
+ ${overridables.map(runtimeType).join(',\n ')}
324
+ } from '@maplibre/maplibre-gl-style-spec';
325
+ `);
266
326
  }
267
327
 
268
- output.push(
269
- `
270
- let paint: Properties<${layerType}PaintProps>;
271
- const getPaint = () => paint = paint || new Properties({`);
272
-
273
- for (const property of paintProperties) {
274
- output.push(
275
- ` "${property.name}": ${propertyValue(property, 'paint')},`);
328
+ if (layoutProperties.length) {
329
+ output.push(emitPropertyBlock({
330
+ typeName: `${layerType}Layout`,
331
+ properties: layoutProperties,
332
+ specGroup: 'layout',
333
+ variable: 'layout',
334
+ getter: 'getLayout',
335
+ exportGetter: false
336
+ }));
276
337
  }
277
338
 
278
- output.push(
279
- `});
339
+ output.push(emitPropertyBlock({
340
+ typeName: `${layerType}Paint`,
341
+ properties: paintProperties,
342
+ specGroup: 'paint',
343
+ variable: 'paint',
344
+ getter: 'getPaint',
345
+ exportGetter: false
346
+ }));
280
347
 
348
+ output.push(`
281
349
  export default ({ get paint(): Properties<${layerType}PaintProps> { return getPaint() }${layoutProperties.length ? `, get layout(): Properties<${layerType}LayoutProps> { return getLayout() }` : ''} });`);
282
350
 
283
351
  return output.join('\n');
284
352
  }
285
353
 
354
+ function emitRootProperties({root, properties}: RootProperties): string {
355
+ return [
356
+ emitHeader('./properties.ts'),
357
+ emitPropertyBlock({
358
+ typeName: pascalCase(root),
359
+ properties,
360
+ specGroup: root,
361
+ variable: 'properties',
362
+ getter: 'getProperties',
363
+ exportGetter: true
364
+ })
365
+ ].join('\n');
366
+ }
367
+
368
+ const layers: LayerProperties[] = Object.keys(latest.layer.type.values).map((type: string) => ({
369
+ type,
370
+ // `visibility` is not a real layout property: it is handled by the layer itself.
371
+ layoutProperties: specProperties(`layout_${type}`, {layerType: type}).filter(({name}) => name !== 'visibility'),
372
+ paintProperties: specProperties(`paint_${type}`, {layerType: type})
373
+ }));
374
+
286
375
  for (const layer of layers) {
287
- fs.writeFileSync(`src/style/style_layer/${layer.type.replace('-', '_')}_style_layer_properties.g.ts`, emitlayerProperties(layer));
376
+ fs.writeFileSync(`src/style/style_layer/${layer.type.replace('-', '_')}_style_layer_properties.g.ts`, emitLayerProperties(layer));
377
+ }
378
+
379
+ const roots: RootProperties[] = ['light', 'sky', 'projection'].map((root) => ({
380
+ root,
381
+ properties: specProperties(root, {root})
382
+ }));
383
+
384
+ for (const root of roots) {
385
+ fs.writeFileSync(`src/style/${root.root}_properties.g.ts`, emitRootProperties(root));
288
386
  }