maplibre-gl 2.2.1 → 2.3.0
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/build/generate-typings.ts +11 -1
- package/dist/maplibre-gl-csp-worker.js +1 -1
- package/dist/maplibre-gl-csp.js +1 -1
- package/dist/maplibre-gl-dev.js +268 -60
- package/dist/maplibre-gl.d.ts +10 -0
- package/dist/maplibre-gl.js +4 -4
- package/dist/style-spec/index.d.ts +1781 -0
- package/package.json +2 -2
- package/src/data/bucket/symbol_bucket.test.ts +30 -19
- package/src/index.test.ts +9 -0
- package/src/index.ts +11 -1
- package/src/source/worker_tile.ts +9 -1
- package/src/style-spec/CHANGELOG.md +10 -0
- package/src/style-spec/composite.test.ts +7 -8
- package/src/style-spec/expression/index.ts +13 -13
- package/src/style-spec/expression/parsing_context.ts +4 -4
- package/src/style-spec/expression/parsing_error.ts +2 -2
- package/src/style-spec/migrate/v8.test.ts +12 -14
- package/src/style-spec/migrate/v9.test.ts +2 -4
- package/src/style-spec/migrate.test.ts +6 -8
- package/src/style-spec/package.json +2 -1
- package/src/symbol/symbol_layout.ts +56 -56
- package/src/ui/map.test.ts +11 -0
- package/src/ui/map.ts +11 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "maplibre-gl",
|
|
3
3
|
"description": "BSD licensed community fork of mapbox-gl, a WebGL interactive maps library",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.3.0",
|
|
5
5
|
"main": "dist/maplibre-gl.js",
|
|
6
6
|
"style": "dist/maplibre-gl.css",
|
|
7
7
|
"license": "BSD-3-Clause",
|
|
@@ -167,7 +167,7 @@
|
|
|
167
167
|
"test-render": "node --loader ts-node/esm --experimental-specifier-resolution=node --max-old-space-size=2048 test/integration/render/render.test.ts",
|
|
168
168
|
"test-query": "jest -c ./jest.config.e2e.ts --roots ./test/integration/query",
|
|
169
169
|
"test-expression": "jest --roots ./test/integration/expression",
|
|
170
|
-
"test-unit": "jest -c ./jest.config.ts
|
|
170
|
+
"test-unit": "jest --roots ./src -c ./jest.config.ts ",
|
|
171
171
|
"codegen": "npm run generate-style-code && npm run generate-struct-arrays && npm run generate-style-spec && npm run generate-shaders && npm run generate-debug-index-file",
|
|
172
172
|
"benchmark": "node --loader ts-node/esm --experimental-specifier-resolution=node test/bench/run-benchmarks.ts",
|
|
173
173
|
"gl-stats": "node --loader ts-node/esm --experimental-specifier-resolution=node test/bench/gl-stats.ts",
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
|
-
|
|
3
1
|
import fs from 'fs';
|
|
4
2
|
import path from 'path';
|
|
5
3
|
import Protobuf from 'pbf';
|
|
@@ -9,7 +7,7 @@ import {CollisionBoxArray} from '../../data/array_types.g';
|
|
|
9
7
|
import {performSymbolLayout} from '../../symbol/symbol_layout';
|
|
10
8
|
import {Placement} from '../../symbol/placement';
|
|
11
9
|
import Transform from '../../geo/transform';
|
|
12
|
-
import {OverscaledTileID} from '../../source/tile_id';
|
|
10
|
+
import {CanonicalTileID, OverscaledTileID} from '../../source/tile_id';
|
|
13
11
|
import Tile from '../../source/tile';
|
|
14
12
|
import CrossTileSymbolIndex from '../../symbol/cross_tile_symbol_index';
|
|
15
13
|
import FeatureIndex from '../../data/feature_index';
|
|
@@ -66,26 +64,33 @@ describe('SymbolBucket', () => {
|
|
|
66
64
|
const bucketA = bucketSetup() as any as SymbolBucket;
|
|
67
65
|
const bucketB = bucketSetup() as any as SymbolBucket;
|
|
68
66
|
const options = {iconDependencies: {}, glyphDependencies: {}} as PopulateParameters;
|
|
69
|
-
const placement = new Placement(transform, 0, true);
|
|
67
|
+
const placement = new Placement(transform, undefined as any, 0, true);
|
|
70
68
|
const tileID = new OverscaledTileID(0, 0, 0, 0, 0);
|
|
71
69
|
const crossTileSymbolIndex = new CrossTileSymbolIndex();
|
|
72
70
|
|
|
73
71
|
// add feature from bucket A
|
|
74
|
-
bucketA.populate([{feature} as IndexedFeature], options, undefined);
|
|
75
|
-
performSymbolLayout(
|
|
72
|
+
bucketA.populate([{feature} as IndexedFeature], options, undefined as any);
|
|
73
|
+
performSymbolLayout(
|
|
74
|
+
{
|
|
75
|
+
bucket: bucketA,
|
|
76
|
+
glyphMap: stacks,
|
|
77
|
+
glyphPositions: {}
|
|
78
|
+
} as any);
|
|
76
79
|
const tileA = new Tile(tileID, 512);
|
|
77
80
|
tileA.latestFeatureIndex = new FeatureIndex(tileID);
|
|
78
81
|
tileA.buckets = {test: bucketA};
|
|
79
82
|
tileA.collisionBoxArray = collisionBoxArray;
|
|
80
83
|
|
|
81
84
|
// add same feature from bucket B
|
|
82
|
-
bucketB.populate([{feature} as IndexedFeature], options, undefined);
|
|
83
|
-
performSymbolLayout(
|
|
85
|
+
bucketB.populate([{feature} as IndexedFeature], options, undefined as any);
|
|
86
|
+
performSymbolLayout({
|
|
87
|
+
bucket: bucketB, glyphMap: stacks, glyphPositions: {}
|
|
88
|
+
} as any);
|
|
84
89
|
const tileB = new Tile(tileID, 512);
|
|
85
90
|
tileB.buckets = {test: bucketB};
|
|
86
91
|
tileB.collisionBoxArray = collisionBoxArray;
|
|
87
92
|
|
|
88
|
-
crossTileSymbolIndex.addLayer(bucketA.layers[0], [tileA, tileB], undefined);
|
|
93
|
+
crossTileSymbolIndex.addLayer(bucketA.layers[0], [tileA, tileB], undefined as any);
|
|
89
94
|
|
|
90
95
|
const place = (layer, tile) => {
|
|
91
96
|
const parts = [];
|
|
@@ -112,9 +117,13 @@ describe('SymbolBucket', () => {
|
|
|
112
117
|
const bucket = bucketSetup() as any as SymbolBucket;
|
|
113
118
|
const options = {iconDependencies: {}, glyphDependencies: {}} as PopulateParameters;
|
|
114
119
|
|
|
115
|
-
bucket.populate([{feature} as IndexedFeature], options, undefined);
|
|
120
|
+
bucket.populate([{feature} as IndexedFeature], options, undefined as any);
|
|
116
121
|
const fakeGlyph = {rect: {w: 10, h: 10}, metrics: {left: 10, top: 10, advance: 10}};
|
|
117
|
-
performSymbolLayout(
|
|
122
|
+
performSymbolLayout({
|
|
123
|
+
bucket,
|
|
124
|
+
glyphMap: stacks,
|
|
125
|
+
glyphPositions: {'Test': {97: fakeGlyph, 98: fakeGlyph, 99: fakeGlyph, 100: fakeGlyph, 101: fakeGlyph, 102: fakeGlyph} as any}
|
|
126
|
+
} as any);
|
|
118
127
|
|
|
119
128
|
expect(spy).toHaveBeenCalledTimes(1);
|
|
120
129
|
expect(spy.mock.calls[0][0].includes('Too many glyphs being rendered in a tile.')).toBeTruthy();
|
|
@@ -146,14 +155,16 @@ describe('SymbolBucket', () => {
|
|
|
146
155
|
createIndexedFeature(1, 1, 'b'),
|
|
147
156
|
createIndexedFeature(2, 2, 'a')
|
|
148
157
|
] as any as IndexedFeature[],
|
|
149
|
-
options, undefined
|
|
158
|
+
options, undefined as any
|
|
150
159
|
);
|
|
151
160
|
|
|
152
161
|
const icons = options.iconDependencies as any;
|
|
153
162
|
expect(icons.a).toBe(true);
|
|
154
163
|
expect(icons.b).toBe(true);
|
|
155
164
|
|
|
156
|
-
performSymbolLayout(
|
|
165
|
+
performSymbolLayout({
|
|
166
|
+
bucket, imageMap, imagePositions: imagePos
|
|
167
|
+
} as any);
|
|
157
168
|
|
|
158
169
|
// undefined SDF should be treated the same as false SDF - no warning raised
|
|
159
170
|
expect(spy).not.toHaveBeenCalledTimes(1);
|
|
@@ -186,14 +197,14 @@ describe('SymbolBucket', () => {
|
|
|
186
197
|
createIndexedFeature(1, 1, 'b'),
|
|
187
198
|
createIndexedFeature(2, 2, 'a')
|
|
188
199
|
] as any as IndexedFeature[],
|
|
189
|
-
options, undefined
|
|
200
|
+
options, undefined as unknown as CanonicalTileID
|
|
190
201
|
);
|
|
191
202
|
|
|
192
203
|
const icons = options.iconDependencies as any;
|
|
193
204
|
expect(icons.a).toBe(true);
|
|
194
205
|
expect(icons.b).toBe(true);
|
|
195
206
|
|
|
196
|
-
performSymbolLayout(bucket,
|
|
207
|
+
performSymbolLayout({bucket, imageMap, imagePositions: imagePos} as any);
|
|
197
208
|
|
|
198
209
|
// true SDF and false SDF in same bucket should trigger warning
|
|
199
210
|
expect(spy).toHaveBeenCalledTimes(1);
|
|
@@ -203,8 +214,8 @@ describe('SymbolBucket', () => {
|
|
|
203
214
|
const rtlBucket = bucketSetup('مرحبا');
|
|
204
215
|
const ltrBucket = bucketSetup('hello');
|
|
205
216
|
const options = {iconDependencies: {}, glyphDependencies: {}} as PopulateParameters;
|
|
206
|
-
rtlBucket.populate([{feature} as IndexedFeature], options, undefined);
|
|
207
|
-
ltrBucket.populate([{feature} as IndexedFeature], options, undefined);
|
|
217
|
+
rtlBucket.populate([{feature} as IndexedFeature], options, undefined as any);
|
|
218
|
+
ltrBucket.populate([{feature} as IndexedFeature], options, undefined as any);
|
|
208
219
|
|
|
209
220
|
expect(rtlBucket.hasRTLText).toBeTruthy();
|
|
210
221
|
expect(ltrBucket.hasRTLText).toBeFalsy();
|
|
@@ -215,7 +226,7 @@ describe('SymbolBucket', () => {
|
|
|
215
226
|
const rtlBucket = bucketSetup('مرحبا');
|
|
216
227
|
const options = {iconDependencies: {}, glyphDependencies: {}} as PopulateParameters;
|
|
217
228
|
rtlBucket.createArrays();
|
|
218
|
-
rtlBucket.populate([{feature} as IndexedFeature], options, undefined);
|
|
229
|
+
rtlBucket.populate([{feature} as IndexedFeature], options, undefined as any);
|
|
219
230
|
|
|
220
231
|
expect(rtlBucket.isEmpty()).toBeFalsy();
|
|
221
232
|
expect(rtlBucket.symbolInstances).toHaveLength(0);
|
|
@@ -224,7 +235,7 @@ describe('SymbolBucket', () => {
|
|
|
224
235
|
test('SymbolBucket detects rtl text mixed with ltr text', () => {
|
|
225
236
|
const mixedBucket = bucketSetup('مرحبا translates to hello');
|
|
226
237
|
const options = {iconDependencies: {}, glyphDependencies: {}} as PopulateParameters;
|
|
227
|
-
mixedBucket.populate([{feature} as IndexedFeature], options, undefined);
|
|
238
|
+
mixedBucket.populate([{feature} as IndexedFeature], options, undefined as any);
|
|
228
239
|
|
|
229
240
|
expect(mixedBucket.hasRTLText).toBeTruthy();
|
|
230
241
|
});
|
package/src/index.test.ts
CHANGED
|
@@ -4,4 +4,13 @@ describe('maplibre', () => {
|
|
|
4
4
|
test('workerCount', () => {
|
|
5
5
|
expect(typeof maplibre.workerCount === 'number').toBeTruthy();
|
|
6
6
|
});
|
|
7
|
+
|
|
8
|
+
test('version', () => {
|
|
9
|
+
expect(typeof maplibre.version === 'string').toBeTruthy();
|
|
10
|
+
|
|
11
|
+
// Semver regex: https://gist.github.com/jhorsman/62eeea161a13b80e39f5249281e17c39
|
|
12
|
+
// Backslashes are doubled to escape them
|
|
13
|
+
const regexp = new RegExp('^([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?(?:\\+[0-9A-Za-z-]+)?$');
|
|
14
|
+
expect(regexp.test(maplibre.version)).toBeTruthy();
|
|
15
|
+
});
|
|
7
16
|
});
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import assert from 'assert';
|
|
2
2
|
import {supported} from '@mapbox/mapbox-gl-supported';
|
|
3
|
-
|
|
3
|
+
import packageJSON from '../package.json' assert {type: 'json'};
|
|
4
4
|
import Map from './ui/map';
|
|
5
5
|
import NavigationControl from './ui/control/navigation_control';
|
|
6
6
|
import GeolocateControl from './ui/control/geolocate_control';
|
|
@@ -36,6 +36,8 @@ import RasterTileSource from './source/raster_tile_source';
|
|
|
36
36
|
import VectorTileSource from './source/vector_tile_source';
|
|
37
37
|
import VideoSource from './source/video_source';
|
|
38
38
|
|
|
39
|
+
const version = packageJSON.version;
|
|
40
|
+
|
|
39
41
|
const exported = {
|
|
40
42
|
supported,
|
|
41
43
|
setRTLTextPlugin,
|
|
@@ -99,6 +101,14 @@ const exported = {
|
|
|
99
101
|
*/
|
|
100
102
|
clearPrewarmedResources,
|
|
101
103
|
|
|
104
|
+
/**
|
|
105
|
+
* Returns the package version of the library
|
|
106
|
+
* @returns {string} Package version of the library
|
|
107
|
+
*/
|
|
108
|
+
get version(): string {
|
|
109
|
+
return version;
|
|
110
|
+
},
|
|
111
|
+
|
|
102
112
|
/**
|
|
103
113
|
* Gets and sets the number of web workers instantiated on a page with GL JS maps.
|
|
104
114
|
* By default, it is set to half the number of CPU cores (capped at 6).
|
|
@@ -189,7 +189,15 @@ class WorkerTile {
|
|
|
189
189
|
const bucket = buckets[key];
|
|
190
190
|
if (bucket instanceof SymbolBucket) {
|
|
191
191
|
recalculateLayers(bucket.layers, this.zoom, availableImages);
|
|
192
|
-
performSymbolLayout(
|
|
192
|
+
performSymbolLayout({
|
|
193
|
+
bucket,
|
|
194
|
+
glyphMap,
|
|
195
|
+
glyphPositions: glyphAtlas.positions,
|
|
196
|
+
imageMap: iconMap,
|
|
197
|
+
imagePositions: imageAtlas.iconPositions,
|
|
198
|
+
showCollisionBoxes: this.showCollisionBoxes,
|
|
199
|
+
canonical: this.tileID.canonical
|
|
200
|
+
});
|
|
193
201
|
} else if (bucket.hasPattern &&
|
|
194
202
|
(bucket instanceof LineBucket ||
|
|
195
203
|
bucket instanceof FillBucket ||
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
## 17.0.1
|
|
2
|
+
|
|
3
|
+
* Generated typings file as not created in the build process and was added in this version [#1470](https://github.com/maplibre/maplibre-gl-js/pull/1470)
|
|
4
|
+
|
|
5
|
+
## 17.0.0
|
|
6
|
+
|
|
7
|
+
### Breaking changes
|
|
8
|
+
|
|
9
|
+
* Renamed `ParsingError` to `ExpressionParsingError` as there were two with the same name and added typescript typings [1468](https://github.com/maplibre/maplibre-gl-js/pull/1468)
|
|
10
|
+
|
|
1
11
|
## 16.1.0
|
|
2
12
|
|
|
3
13
|
### ✨ Features and improvements
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
|
-
|
|
3
1
|
import composite from './composite';
|
|
2
|
+
import {LineLayerSpecification} from './types.g';
|
|
4
3
|
|
|
5
4
|
describe('composite', () => {
|
|
6
5
|
test('composites Mapbox vector sources', () => {
|
|
7
6
|
const result = composite({
|
|
8
|
-
'version': 7,
|
|
7
|
+
'version': 7 as any,
|
|
9
8
|
'sources': {
|
|
10
9
|
'mapbox-a': {
|
|
11
10
|
'type': 'vector',
|
|
@@ -34,13 +33,13 @@ describe('composite', () => {
|
|
|
34
33
|
}
|
|
35
34
|
});
|
|
36
35
|
|
|
37
|
-
expect(result.layers[0].source).toBe('a,b');
|
|
38
|
-
expect(result.layers[1].source).toBe('a,b');
|
|
36
|
+
expect((result.layers[0] as LineLayerSpecification).source).toBe('a,b');
|
|
37
|
+
expect((result.layers[1] as LineLayerSpecification).source).toBe('a,b');
|
|
39
38
|
});
|
|
40
39
|
|
|
41
40
|
test('does not composite vector + raster', () => {
|
|
42
41
|
const result = composite({
|
|
43
|
-
'version': 7,
|
|
42
|
+
'version': 7 as any,
|
|
44
43
|
'sources': {
|
|
45
44
|
'a': {
|
|
46
45
|
'type': 'vector',
|
|
@@ -59,7 +58,7 @@ describe('composite', () => {
|
|
|
59
58
|
|
|
60
59
|
test('incorrect url match', () => {
|
|
61
60
|
const result = composite({
|
|
62
|
-
'version': 7,
|
|
61
|
+
'version': 7 as any,
|
|
63
62
|
'sources': {
|
|
64
63
|
'a': {
|
|
65
64
|
'type': 'vector',
|
|
@@ -79,7 +78,7 @@ describe('composite', () => {
|
|
|
79
78
|
test('composites Mapbox vector sources with conflicting source layer names', () => {
|
|
80
79
|
expect(() => {
|
|
81
80
|
composite({
|
|
82
|
-
'version': 7,
|
|
81
|
+
'version': 7 as any,
|
|
83
82
|
'sources': {
|
|
84
83
|
'mapbox-a': {
|
|
85
84
|
'type': 'vector',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import assert from 'assert';
|
|
2
2
|
|
|
3
3
|
import extend from '../util/extend';
|
|
4
|
-
import
|
|
4
|
+
import ExpressionParsingError from './parsing_error';
|
|
5
5
|
import ParsingContext from './parsing_context';
|
|
6
6
|
import EvaluationContext from './evaluation_context';
|
|
7
7
|
import CompoundExpression from './compound_expression';
|
|
@@ -135,7 +135,7 @@ export function isExpression(expression: unknown) {
|
|
|
135
135
|
*
|
|
136
136
|
* @private
|
|
137
137
|
*/
|
|
138
|
-
export function createExpression(expression: unknown, propertySpec?: StylePropertySpecification | null): Result<StyleExpression, Array<
|
|
138
|
+
export function createExpression(expression: unknown, propertySpec?: StylePropertySpecification | null): Result<StyleExpression, Array<ExpressionParsingError>> {
|
|
139
139
|
const parser = new ParsingContext(definitions, [], propertySpec ? getExpectedType(propertySpec) : undefined);
|
|
140
140
|
|
|
141
141
|
// For string-valued properties, coerce to string at the top level rather than asserting.
|
|
@@ -287,7 +287,7 @@ export type CompositeExpression = {
|
|
|
287
287
|
|
|
288
288
|
export type StylePropertyExpression = ConstantExpression | SourceExpression | CameraExpression | CompositeExpression;
|
|
289
289
|
|
|
290
|
-
export function createPropertyExpression(expressionInput: unknown, propertySpec: StylePropertySpecification): Result<StylePropertyExpression, Array<
|
|
290
|
+
export function createPropertyExpression(expressionInput: unknown, propertySpec: StylePropertySpecification): Result<StylePropertyExpression, Array<ExpressionParsingError>> {
|
|
291
291
|
const expression = createExpression(expressionInput, propertySpec);
|
|
292
292
|
if (expression.result === 'error') {
|
|
293
293
|
return expression;
|
|
@@ -297,21 +297,21 @@ export function createPropertyExpression(expressionInput: unknown, propertySpec:
|
|
|
297
297
|
|
|
298
298
|
const isFeatureConstant = isConstant.isFeatureConstant(parsed);
|
|
299
299
|
if (!isFeatureConstant && !supportsPropertyExpression(propertySpec)) {
|
|
300
|
-
return error([new
|
|
300
|
+
return error([new ExpressionParsingError('', 'data expressions not supported')]);
|
|
301
301
|
}
|
|
302
302
|
|
|
303
303
|
const isZoomConstant = isConstant.isGlobalPropertyConstant(parsed, ['zoom']);
|
|
304
304
|
if (!isZoomConstant && !supportsZoomExpression(propertySpec)) {
|
|
305
|
-
return error([new
|
|
305
|
+
return error([new ExpressionParsingError('', 'zoom expressions not supported')]);
|
|
306
306
|
}
|
|
307
307
|
|
|
308
308
|
const zoomCurve = findZoomCurve(parsed);
|
|
309
309
|
if (!zoomCurve && !isZoomConstant) {
|
|
310
|
-
return error([new
|
|
311
|
-
} else if (zoomCurve instanceof
|
|
310
|
+
return error([new ExpressionParsingError('', '"zoom" expression may only be used as input to a top-level "step" or "interpolate" expression.')]);
|
|
311
|
+
} else if (zoomCurve instanceof ExpressionParsingError) {
|
|
312
312
|
return error([zoomCurve]);
|
|
313
313
|
} else if (zoomCurve instanceof Interpolate && !supportsInterpolation(propertySpec)) {
|
|
314
|
-
return error([new
|
|
314
|
+
return error([new ExpressionParsingError('', '"interpolate" expressions cannot be used with this property')]);
|
|
315
315
|
}
|
|
316
316
|
|
|
317
317
|
if (!zoomCurve) {
|
|
@@ -394,7 +394,7 @@ export function normalizePropertyExpression<T>(
|
|
|
394
394
|
// Zoom-dependent expressions may only use ["zoom"] as the input to a top-level "step" or "interpolate"
|
|
395
395
|
// expression (collectively referred to as a "curve"). The curve may be wrapped in one or more "let" or
|
|
396
396
|
// "coalesce" expressions.
|
|
397
|
-
function findZoomCurve(expression: Expression): Step | Interpolate |
|
|
397
|
+
function findZoomCurve(expression: Expression): Step | Interpolate | ExpressionParsingError | null {
|
|
398
398
|
let result = null;
|
|
399
399
|
if (expression instanceof Let) {
|
|
400
400
|
result = findZoomCurve(expression.result);
|
|
@@ -414,18 +414,18 @@ function findZoomCurve(expression: Expression): Step | Interpolate | ParsingErro
|
|
|
414
414
|
result = expression;
|
|
415
415
|
}
|
|
416
416
|
|
|
417
|
-
if (result instanceof
|
|
417
|
+
if (result instanceof ExpressionParsingError) {
|
|
418
418
|
return result;
|
|
419
419
|
}
|
|
420
420
|
|
|
421
421
|
expression.eachChild((child) => {
|
|
422
422
|
const childResult = findZoomCurve(child);
|
|
423
|
-
if (childResult instanceof
|
|
423
|
+
if (childResult instanceof ExpressionParsingError) {
|
|
424
424
|
result = childResult;
|
|
425
425
|
} else if (!result && childResult) {
|
|
426
|
-
result = new
|
|
426
|
+
result = new ExpressionParsingError('', '"zoom" expression may only be used as input to a top-level "step" or "interpolate" expression.');
|
|
427
427
|
} else if (result && childResult && result !== childResult) {
|
|
428
|
-
result = new
|
|
428
|
+
result = new ExpressionParsingError('', 'Only one zoom-based "step" or "interpolate" subexpression may be used in an expression.');
|
|
429
429
|
}
|
|
430
430
|
});
|
|
431
431
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Scope from './scope';
|
|
2
2
|
import {checkSubtype} from './types';
|
|
3
|
-
import
|
|
3
|
+
import ExpressionParsingError from './parsing_error';
|
|
4
4
|
import Literal from './definitions/literal';
|
|
5
5
|
import Assertion from './definitions/assertion';
|
|
6
6
|
import Coercion from './definitions/coercion';
|
|
@@ -23,7 +23,7 @@ class ParsingContext {
|
|
|
23
23
|
path: Array<number>;
|
|
24
24
|
key: string;
|
|
25
25
|
scope: Scope;
|
|
26
|
-
errors: Array<
|
|
26
|
+
errors: Array<ExpressionParsingError>;
|
|
27
27
|
|
|
28
28
|
// The expected type of this expression. Provided only to allow Expression
|
|
29
29
|
// implementations to infer argument types: Expression#parse() need not
|
|
@@ -36,7 +36,7 @@ class ParsingContext {
|
|
|
36
36
|
path: Array<number> = [],
|
|
37
37
|
expectedType?: Type | null,
|
|
38
38
|
scope: Scope = new Scope(),
|
|
39
|
-
errors: Array<
|
|
39
|
+
errors: Array<ExpressionParsingError> = []
|
|
40
40
|
) {
|
|
41
41
|
this.registry = registry;
|
|
42
42
|
this.path = path;
|
|
@@ -183,7 +183,7 @@ class ParsingContext {
|
|
|
183
183
|
*/
|
|
184
184
|
error(error: string, ...keys: Array<number>) {
|
|
185
185
|
const key = `${this.key}${keys.map(k => `[${k}]`).join('')}`;
|
|
186
|
-
this.errors.push(new
|
|
186
|
+
this.errors.push(new ExpressionParsingError(key, error));
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class ExpressionParsingError extends Error {
|
|
2
2
|
key: string;
|
|
3
3
|
message: string;
|
|
4
4
|
constructor(key: string, message: string) {
|
|
@@ -8,4 +8,4 @@ class ParsingError extends Error {
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
export default
|
|
11
|
+
export default ExpressionParsingError;
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
|
-
|
|
3
1
|
import migrate from './v8';
|
|
4
2
|
|
|
5
3
|
describe('migrate v8', () => {
|
|
@@ -23,7 +21,7 @@ describe('migrate v8', () => {
|
|
|
23
21
|
}
|
|
24
22
|
}
|
|
25
23
|
]
|
|
26
|
-
};
|
|
24
|
+
} as any;
|
|
27
25
|
|
|
28
26
|
const output = {
|
|
29
27
|
'version': 8,
|
|
@@ -68,7 +66,7 @@ describe('migrate v8', () => {
|
|
|
68
66
|
}
|
|
69
67
|
}
|
|
70
68
|
]
|
|
71
|
-
};
|
|
69
|
+
} as any;
|
|
72
70
|
|
|
73
71
|
const output = {
|
|
74
72
|
'version': 8,
|
|
@@ -103,7 +101,7 @@ describe('migrate v8', () => {
|
|
|
103
101
|
}
|
|
104
102
|
},
|
|
105
103
|
'layers': []
|
|
106
|
-
};
|
|
104
|
+
} as any;
|
|
107
105
|
|
|
108
106
|
const output = {
|
|
109
107
|
'version': 8,
|
|
@@ -140,7 +138,7 @@ describe('migrate v8', () => {
|
|
|
140
138
|
}
|
|
141
139
|
}
|
|
142
140
|
}]
|
|
143
|
-
};
|
|
141
|
+
} as any;
|
|
144
142
|
|
|
145
143
|
const output = {
|
|
146
144
|
'version': 8,
|
|
@@ -187,7 +185,7 @@ describe('migrate v8', () => {
|
|
|
187
185
|
}
|
|
188
186
|
}
|
|
189
187
|
}]
|
|
190
|
-
};
|
|
188
|
+
} as any;
|
|
191
189
|
|
|
192
190
|
const output = {
|
|
193
191
|
'version': 8,
|
|
@@ -233,7 +231,7 @@ describe('migrate v8', () => {
|
|
|
233
231
|
}
|
|
234
232
|
}
|
|
235
233
|
]
|
|
236
|
-
};
|
|
234
|
+
} as any;
|
|
237
235
|
|
|
238
236
|
const output = {
|
|
239
237
|
'version': 8,
|
|
@@ -276,7 +274,7 @@ describe('migrate v8', () => {
|
|
|
276
274
|
}
|
|
277
275
|
}
|
|
278
276
|
]
|
|
279
|
-
};
|
|
277
|
+
} as any;
|
|
280
278
|
|
|
281
279
|
const output = {
|
|
282
280
|
'version': 8,
|
|
@@ -328,7 +326,7 @@ describe('migrate v8', () => {
|
|
|
328
326
|
}
|
|
329
327
|
}
|
|
330
328
|
]
|
|
331
|
-
};
|
|
329
|
+
} as any;
|
|
332
330
|
|
|
333
331
|
const output = {
|
|
334
332
|
'version': 8,
|
|
@@ -389,7 +387,7 @@ describe('migrate v8', () => {
|
|
|
389
387
|
}
|
|
390
388
|
}
|
|
391
389
|
]
|
|
392
|
-
};
|
|
390
|
+
} as any;
|
|
393
391
|
|
|
394
392
|
const output = {
|
|
395
393
|
'version': 8,
|
|
@@ -445,7 +443,7 @@ describe('migrate v8', () => {
|
|
|
445
443
|
}
|
|
446
444
|
}
|
|
447
445
|
]
|
|
448
|
-
};
|
|
446
|
+
} as any;
|
|
449
447
|
|
|
450
448
|
const output = {
|
|
451
449
|
'version': 8,
|
|
@@ -479,7 +477,7 @@ describe('migrate v8', () => {
|
|
|
479
477
|
'version': 7,
|
|
480
478
|
'glyphs': 'mapbox://fontstack/{fontstack}/{range}.pbf',
|
|
481
479
|
'layers': []
|
|
482
|
-
};
|
|
480
|
+
} as any;
|
|
483
481
|
|
|
484
482
|
const output = {
|
|
485
483
|
'version': 8,
|
|
@@ -495,7 +493,7 @@ describe('migrate v8', () => {
|
|
|
495
493
|
'version': 7,
|
|
496
494
|
'glyphs': 'mapbox://fonts/v1/boxmap/{fontstack}/{range}.pbf',
|
|
497
495
|
'layers': []
|
|
498
|
-
};
|
|
496
|
+
} as any;
|
|
499
497
|
|
|
500
498
|
const output = {
|
|
501
499
|
'version': 8,
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
|
-
|
|
3
1
|
import migrate from './v9';
|
|
4
2
|
|
|
5
3
|
describe('migrate v9', () => {
|
|
@@ -18,7 +16,7 @@ describe('migrate v9', () => {
|
|
|
18
16
|
id: 'child',
|
|
19
17
|
ref: 'parent'
|
|
20
18
|
}]
|
|
21
|
-
};
|
|
19
|
+
} as any;
|
|
22
20
|
|
|
23
21
|
expect(migrate(input)).toEqual({
|
|
24
22
|
version: 9,
|
|
@@ -58,7 +56,7 @@ describe('migrate v9', () => {
|
|
|
58
56
|
'fill-color': 'blue'
|
|
59
57
|
}
|
|
60
58
|
}]
|
|
61
|
-
};
|
|
59
|
+
} as any;
|
|
62
60
|
|
|
63
61
|
expect(migrate(input)).toEqual({
|
|
64
62
|
version: 9,
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
|
-
|
|
3
1
|
import migrate from './migrate';
|
|
4
2
|
import * as spec from './style-spec';
|
|
5
3
|
import v8 from './reference/v8.json';
|
|
@@ -8,18 +6,18 @@ import validate from './validate_style';
|
|
|
8
6
|
describe('migrate', () => {
|
|
9
7
|
test('does not migrate from version 5', () => {
|
|
10
8
|
expect(() => {
|
|
11
|
-
migrate({version: 5, layers: []});
|
|
9
|
+
migrate({version: 5, layers: []} as any);
|
|
12
10
|
}).toThrow(new Error('Cannot migrate from 5'));
|
|
13
11
|
});
|
|
14
12
|
|
|
15
13
|
test('does not migrate from version 6', () => {
|
|
16
14
|
expect(() => {
|
|
17
|
-
migrate({version: 6, layers: []});
|
|
15
|
+
migrate({version: 6, layers: []} as any);
|
|
18
16
|
}).toThrow(new Error('Cannot migrate from 6'));
|
|
19
17
|
});
|
|
20
18
|
|
|
21
19
|
test('migrates to latest version from version 7', () => {
|
|
22
|
-
expect(migrate({version: 7, layers: []}).version).toEqual(spec.latest.$version);
|
|
20
|
+
expect(migrate({version: 7, layers: []} as any).version).toEqual(spec.latest.$version);
|
|
23
21
|
});
|
|
24
22
|
|
|
25
23
|
test('converts token strings to expressions', () => {
|
|
@@ -30,7 +28,7 @@ describe('migrate', () => {
|
|
|
30
28
|
type: 'symbol',
|
|
31
29
|
layout: {'text-field': 'a{x}', 'icon-image': '{y}'}
|
|
32
30
|
}]
|
|
33
|
-
});
|
|
31
|
+
} as any);
|
|
34
32
|
expect(migrated.layers[0].layout['text-field']).toEqual(['concat', 'a', ['get', 'x']]);
|
|
35
33
|
expect(migrated.layers[0].layout['icon-image']).toEqual(['to-string', ['get', 'y']]);
|
|
36
34
|
});
|
|
@@ -57,7 +55,7 @@ describe('migrate', () => {
|
|
|
57
55
|
}
|
|
58
56
|
}
|
|
59
57
|
}]
|
|
60
|
-
});
|
|
58
|
+
} as any);
|
|
61
59
|
expect(migrated.layers[0].paint['background-opacity']).toEqual([
|
|
62
60
|
'interpolate',
|
|
63
61
|
['linear'],
|
|
@@ -101,7 +99,7 @@ describe('migrate', () => {
|
|
|
101
99
|
}
|
|
102
100
|
}
|
|
103
101
|
}]
|
|
104
|
-
});
|
|
102
|
+
} as any);
|
|
105
103
|
expect(migrated.layers[0].layout['icon-image']).toEqual([
|
|
106
104
|
'match',
|
|
107
105
|
['get', 'type'],
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maplibre/maplibre-gl-style-spec",
|
|
3
3
|
"description": "a specification for maplibre gl styles",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "17.0.1",
|
|
5
5
|
"author": "MapLibre",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mapbox",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"license": "ISC",
|
|
15
15
|
"main": "./dist/index.cjs",
|
|
16
16
|
"module": "./dist/index.mjs",
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
17
18
|
"type": "module",
|
|
18
19
|
"scripts": {
|
|
19
20
|
},
|