@versatiles/style 3.5.1 → 3.5.2
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 +21 -50
- package/dist/index.d.ts +1 -1
- package/dist/index.js +0 -0
- package/dist/index.test.js +0 -1
- package/dist/lib/decorator.d.ts +1 -2
- package/dist/lib/decorator.test.js +2 -2
- package/dist/lib/recolor.d.ts +1 -11
- package/dist/lib/shortbread/layers.d.ts +2 -5
- package/dist/lib/shortbread/layers.js +10 -8
- package/dist/lib/shortbread/layers.test.js +1 -1
- package/dist/lib/shortbread/template.d.ts +2 -2
- package/dist/lib/shortbread/template.test.js +0 -2
- package/dist/lib/style_builder.d.ts +1 -14
- package/dist/lib/style_builder.js +12 -12
- package/dist/lib/style_builder.test.js +0 -2
- package/dist/lib/types.d.ts +70 -0
- package/dist/lib/types.js +89 -0
- package/dist/style/colorful.d.ts +1 -1
- package/dist/style/neutrino.d.ts +1 -1
- package/package.json +13 -11
package/README.MD
CHANGED
|
@@ -20,28 +20,16 @@ We provide each style with and without labels, and also in multiple languages.
|
|
|
20
20
|
|
|
21
21
|
Be aware that styles already include `tiles.versatiles.org` as source for tiles, fonts (glyphs) and icons (sprites). So you might want to update the URLs in the JSON.
|
|
22
22
|
|
|
23
|
-
## as Node.js module
|
|
24
|
-
|
|
25
|
-
Install `versatiles-style` via NPM:
|
|
26
|
-
```bash
|
|
27
|
-
npm install versatiles-style
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
Use it in Node.js:
|
|
31
|
-
```javascript
|
|
32
|
-
import { colorful } from 'versatiles-style';
|
|
33
|
-
let style = colorful({language:'de'});
|
|
34
|
-
writeFileSync('style.json', JSON.stringify(style));
|
|
35
|
-
```
|
|
36
|
-
|
|
37
23
|
## in a web browser
|
|
38
24
|
|
|
39
25
|
Download latest release:
|
|
26
|
+
|
|
40
27
|
```bash
|
|
41
28
|
wget "https://github.com/versatiles-org/versatiles-style/releases/latest/download/versatiles-style.js"
|
|
42
29
|
```
|
|
43
30
|
|
|
44
31
|
Use it in:
|
|
32
|
+
|
|
45
33
|
```html
|
|
46
34
|
<div id="map"></div>
|
|
47
35
|
<script src="maplibre-gl.js"></script>
|
|
@@ -59,39 +47,22 @@ Use it in:
|
|
|
59
47
|
<script>
|
|
60
48
|
```
|
|
61
49
|
|
|
62
|
-
##
|
|
63
|
-
|
|
64
|
-
`
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
* [x] :en labels
|
|
82
|
-
* [x] links under other roads, sort by size
|
|
83
|
-
* [x] waterway width
|
|
84
|
-
* [x] rail colorscheme
|
|
85
|
-
* [x] bridge semitransparent
|
|
86
|
-
* [x] cycleways and bicycle-roads
|
|
87
|
-
* [x] trams
|
|
88
|
-
* [x] rail zooms 17+
|
|
89
|
-
* [x] minor rails
|
|
90
|
-
* [x] more sites and landcovers
|
|
91
|
-
* [x] airports
|
|
92
|
-
* [x] pois
|
|
93
|
-
* [x] sprites and patterns, revisit sprites
|
|
94
|
-
* [x] public transport signage
|
|
95
|
-
* [x] road signage
|
|
96
|
-
* [ ] labels for rivers, islands, places
|
|
97
|
-
* [ ] aggregate layers with same filters and style for smaller result
|
|
50
|
+
## as Node.js module
|
|
51
|
+
|
|
52
|
+
Install `versatiles-style` via NPM:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npm install versatiles-style
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Use it in Node.js:
|
|
59
|
+
|
|
60
|
+
```javascript
|
|
61
|
+
import { colorful } from 'versatiles-style';
|
|
62
|
+
let style = colorful({language:'de'});
|
|
63
|
+
writeFileSync('style.json', JSON.stringify(style));
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Node.js API
|
|
67
|
+
|
|
68
|
+
<!--- This chapter is generated automatically --->
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { MaplibreStyle } from './lib/
|
|
1
|
+
export type { MaplibreStyle } from './lib/types.js';
|
|
2
2
|
export { default as Colorful } from './style/colorful.js';
|
|
3
3
|
export { default as Graybeard } from './style/graybeard.js';
|
|
4
4
|
export { default as Neutrino } from './style/neutrino.js';
|
package/dist/index.js
CHANGED
|
File without changes
|
package/dist/index.test.js
CHANGED
|
@@ -24,7 +24,6 @@ describe('Style Builders', () => {
|
|
|
24
24
|
expect(style.glyphs).toBe('https://example.org/assets/fonts/{fontstack}/{range}.pbf');
|
|
25
25
|
expect(style.sprite).toBe('https://example.org/assets/sprites/sprites');
|
|
26
26
|
expect(Object.keys(style.sources).join(',')).toBe('versatiles-shortbread');
|
|
27
|
-
// @ts-expect-error: Still Overwhelmed
|
|
28
27
|
expect(style.sources['versatiles-shortbread'].tiles).toEqual(['https://example.org/tiles/osm/{z}/{x}/{y}']);
|
|
29
28
|
});
|
|
30
29
|
});
|
package/dist/lib/decorator.d.ts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import type { MaplibreLayer } from './
|
|
2
|
-
import type { StyleRules } from './style_builder.js';
|
|
1
|
+
import type { MaplibreLayer, StyleRules } from './types.js';
|
|
3
2
|
export declare function decorate(layers: MaplibreLayer[], rules: StyleRules): MaplibreLayer[];
|
|
@@ -2,8 +2,8 @@ import { decorate } from './decorator.js';
|
|
|
2
2
|
import Color from 'color';
|
|
3
3
|
describe('decorate function', () => {
|
|
4
4
|
const mockLayers = [
|
|
5
|
-
{ id: 'layer1', type: 'fill', layout: {}, paint: {} },
|
|
6
|
-
{ id: 'layer2', type: 'line', layout: {}, paint: {} },
|
|
5
|
+
{ id: 'layer1', type: 'fill', layout: {}, paint: {}, source: 'versatiles-shortbread' },
|
|
6
|
+
{ id: 'layer2', type: 'line', layout: {}, paint: {}, source: 'versatiles-shortbread' },
|
|
7
7
|
];
|
|
8
8
|
const mockRules = {
|
|
9
9
|
'layer1': {
|
package/dist/lib/recolor.d.ts
CHANGED
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
import type { StylemakerColorLookup } from './
|
|
2
|
-
export interface RecolorOptions {
|
|
3
|
-
invert?: boolean;
|
|
4
|
-
rotate?: number;
|
|
5
|
-
saturate?: number;
|
|
6
|
-
gamma?: number;
|
|
7
|
-
contrast?: number;
|
|
8
|
-
brightness?: number;
|
|
9
|
-
tint?: number;
|
|
10
|
-
tintColor?: string;
|
|
11
|
-
}
|
|
1
|
+
import type { RecolorOptions, StylemakerColorLookup } from './types.js';
|
|
12
2
|
export declare function getDefaultRecolorFlags(): RecolorOptions;
|
|
13
3
|
export declare function recolor(colors: StylemakerColorLookup, opt?: RecolorOptions): void;
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { LanguageSuffix } from '../style_builder.js';
|
|
3
|
-
export type MaplibreLayer = BackgroundLayer | FillLayer | LineLayer | SymbolLayer;
|
|
4
|
-
export type MaplibreFilter = unknown[];
|
|
1
|
+
import type { LanguageSuffix, MaplibreLayerDefinition } from '../types.js';
|
|
5
2
|
export default function getLayers(option: {
|
|
6
3
|
readonly languageSuffix: LanguageSuffix;
|
|
7
|
-
}):
|
|
4
|
+
}): MaplibreLayerDefinition[];
|
|
@@ -108,7 +108,8 @@ export default function getLayers(option) {
|
|
|
108
108
|
},
|
|
109
109
|
// tunnel-, street-, bridges-bridge
|
|
110
110
|
...['tunnel', 'street', 'bridge'].flatMap((c) => {
|
|
111
|
-
let filter
|
|
111
|
+
let filter;
|
|
112
|
+
let prefix;
|
|
112
113
|
const results = [];
|
|
113
114
|
switch (c) {
|
|
114
115
|
case 'tunnel':
|
|
@@ -139,8 +140,8 @@ export default function getLayers(option) {
|
|
|
139
140
|
type: 'fill',
|
|
140
141
|
'source-layer': 'street_polygons',
|
|
141
142
|
filter: ['all',
|
|
142
|
-
['==', 'kind', 'pedestrian'],
|
|
143
143
|
...filter,
|
|
144
|
+
['==', 'kind', 'pedestrian'],
|
|
144
145
|
],
|
|
145
146
|
});
|
|
146
147
|
// non-car streets
|
|
@@ -150,12 +151,13 @@ export default function getLayers(option) {
|
|
|
150
151
|
type: 'line',
|
|
151
152
|
'source-layer': 'streets',
|
|
152
153
|
filter: ['all',
|
|
153
|
-
['in', 'kind', t],
|
|
154
154
|
...filter,
|
|
155
|
+
['in', 'kind', t],
|
|
155
156
|
],
|
|
156
157
|
});
|
|
157
158
|
});
|
|
158
159
|
// no links
|
|
160
|
+
const noDrivewayExpression = ['!=', 'service', 'driveway'];
|
|
159
161
|
['track', 'pedestrian', 'service', 'living_street', 'residential', 'unclassified'].forEach(t => {
|
|
160
162
|
results.push({
|
|
161
163
|
id: prefix + 'street-' + t.replace(/_/g, '') + suffix,
|
|
@@ -164,7 +166,7 @@ export default function getLayers(option) {
|
|
|
164
166
|
filter: ['all',
|
|
165
167
|
['==', 'kind', t],
|
|
166
168
|
...filter,
|
|
167
|
-
...(t === 'service') ? [
|
|
169
|
+
...(t === 'service') ? [noDrivewayExpression] : [], // ignore driveways
|
|
168
170
|
],
|
|
169
171
|
});
|
|
170
172
|
});
|
|
@@ -179,7 +181,7 @@ export default function getLayers(option) {
|
|
|
179
181
|
['==', 'kind', t],
|
|
180
182
|
['==', 'bicycle', 'designated'],
|
|
181
183
|
...filter,
|
|
182
|
-
...(t === 'service') ? [
|
|
184
|
+
...(t === 'service') ? [noDrivewayExpression] : [], // ignore driveways
|
|
183
185
|
],
|
|
184
186
|
});
|
|
185
187
|
});
|
|
@@ -190,9 +192,9 @@ export default function getLayers(option) {
|
|
|
190
192
|
type: 'line',
|
|
191
193
|
'source-layer': 'streets',
|
|
192
194
|
filter: ['all',
|
|
195
|
+
...filter,
|
|
193
196
|
['in', 'kind', t],
|
|
194
197
|
['==', 'link', true],
|
|
195
|
-
...filter,
|
|
196
198
|
],
|
|
197
199
|
});
|
|
198
200
|
});
|
|
@@ -203,9 +205,9 @@ export default function getLayers(option) {
|
|
|
203
205
|
type: 'line',
|
|
204
206
|
'source-layer': 'streets',
|
|
205
207
|
filter: ['all',
|
|
208
|
+
...filter,
|
|
206
209
|
['in', 'kind', t],
|
|
207
210
|
['!=', 'link', true],
|
|
208
|
-
...filter,
|
|
209
211
|
],
|
|
210
212
|
});
|
|
211
213
|
});
|
|
@@ -233,8 +235,8 @@ export default function getLayers(option) {
|
|
|
233
235
|
type: 'line',
|
|
234
236
|
'source-layer': 'aerialways',
|
|
235
237
|
filter: ['all',
|
|
236
|
-
['in', 'kind', t],
|
|
237
238
|
...filter,
|
|
239
|
+
['in', 'kind', t],
|
|
238
240
|
],
|
|
239
241
|
});
|
|
240
242
|
});
|
|
@@ -22,6 +22,6 @@ describe('layers', () => {
|
|
|
22
22
|
const layers = getLayers({ languageSuffix });
|
|
23
23
|
const landLayer = layers.find((layer) => layer.id === 'land-agriculture');
|
|
24
24
|
expect(landLayer).toBeDefined();
|
|
25
|
-
expect(landLayer
|
|
25
|
+
expect(landLayer.filter).toEqual(['all', ['in', 'kind', 'brownfield', 'farmland', 'farmyard', 'greenfield', 'greenhouse_horticulture', 'orchard', 'plant_nursery', 'vineyard']]);
|
|
26
26
|
});
|
|
27
27
|
});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export default function getTemplate():
|
|
1
|
+
import type { MaplibreStyleVector } from '../types.js';
|
|
2
|
+
export default function getTemplate(): MaplibreStyleVector;
|
|
@@ -39,8 +39,6 @@ describe('getTemplate', () => {
|
|
|
39
39
|
expect(styleTemplate.sources).toBeDefined();
|
|
40
40
|
const { vector_layers } = styleTemplate.sources['versatiles-shortbread'];
|
|
41
41
|
expect(typeof vector_layers).toBe('object');
|
|
42
|
-
if (!vector_layers)
|
|
43
|
-
return;
|
|
44
42
|
it('contains vector_layers with id and fields', () => {
|
|
45
43
|
expect(Array.isArray(vector_layers)).toBeTruthy();
|
|
46
44
|
vector_layers.forEach(layer => {
|
|
@@ -1,18 +1,5 @@
|
|
|
1
1
|
import Color from 'color';
|
|
2
|
-
import type { RecolorOptions } from './
|
|
3
|
-
import type { Style } from 'mapbox-gl';
|
|
4
|
-
export type MaplibreStyle = Style;
|
|
5
|
-
export type StyleRuleValue = boolean | number | object | string;
|
|
6
|
-
export type StyleRule = Record<string, StyleRuleValue>;
|
|
7
|
-
export type StyleRules = Record<string, StyleRule>;
|
|
8
|
-
export type StylemakerColorLookup = Record<string, Color>;
|
|
9
|
-
export type StylemakerStringLookup = Record<string, string>;
|
|
10
|
-
export type LanguageSuffix = '_de' | '_en' | '';
|
|
11
|
-
export interface StyleRulesOptions {
|
|
12
|
-
colors: StylemakerColorLookup;
|
|
13
|
-
fonts: StylemakerStringLookup;
|
|
14
|
-
languageSuffix: string;
|
|
15
|
-
}
|
|
2
|
+
import type { LanguageSuffix, MaplibreStyle, RecolorOptions, StyleRules, StyleRulesOptions } from './types.js';
|
|
16
3
|
export default abstract class StyleBuilder {
|
|
17
4
|
#private;
|
|
18
5
|
baseUrl: string;
|
|
@@ -38,26 +38,26 @@ export default class StyleBuilder {
|
|
|
38
38
|
languageSuffix: this.languageSuffix,
|
|
39
39
|
});
|
|
40
40
|
// get shortbread layers
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
layers = decorate(layers, layerStyleRules);
|
|
44
|
-
// hide labels, if wanted
|
|
45
|
-
if (this.hideLabels)
|
|
46
|
-
layers = layers.filter(l => l.type !== 'symbol');
|
|
47
|
-
// set source, if needed
|
|
48
|
-
layers.forEach(layer => {
|
|
41
|
+
const layerDefinitions = getShortbreadLayers({ languageSuffix: this.languageSuffix });
|
|
42
|
+
let layers = layerDefinitions.map(layer => {
|
|
49
43
|
switch (layer.type) {
|
|
50
44
|
case 'background':
|
|
51
|
-
|
|
52
|
-
return;
|
|
45
|
+
return layer;
|
|
53
46
|
case 'fill':
|
|
54
47
|
case 'line':
|
|
55
48
|
case 'symbol':
|
|
56
|
-
|
|
57
|
-
|
|
49
|
+
return {
|
|
50
|
+
...layer,
|
|
51
|
+
source: this.#sourceName,
|
|
52
|
+
};
|
|
58
53
|
}
|
|
59
54
|
throw Error('unknown layer type');
|
|
60
55
|
});
|
|
56
|
+
// apply layer rules
|
|
57
|
+
layers = decorate(layers, layerStyleRules);
|
|
58
|
+
// hide labels, if wanted
|
|
59
|
+
if (this.hideLabels)
|
|
60
|
+
layers = layers.filter(l => l.type !== 'symbol');
|
|
61
61
|
style.layers = layers;
|
|
62
62
|
style.name = 'versatiles-' + this.name;
|
|
63
63
|
style.glyphs = resolveUrl(this.baseUrl, this.glyphsUrl);
|
|
@@ -68,8 +68,6 @@ describe('StyleBuilder', () => {
|
|
|
68
68
|
expect(style.sprite).toBe('https://my.base.url/assets/sprites/sprites');
|
|
69
69
|
const source = style.sources['versatiles-shortbread'];
|
|
70
70
|
expect(source).toHaveProperty('tiles');
|
|
71
|
-
if (!source.tiles)
|
|
72
|
-
return;
|
|
73
71
|
expect(source.tiles[0]).toBe('https://my.base.url/tiles/osm/{z}/{x}/{y}');
|
|
74
72
|
});
|
|
75
73
|
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { BackgroundLayerSpecification, FillLayerSpecification, FilterSpecification, LineLayerSpecification, StyleSpecification, SymbolLayerSpecification } from '@maplibre/maplibre-gl-style-spec';
|
|
2
|
+
import type Color from 'color';
|
|
3
|
+
export type TileFormat = 'avif' | 'bin' | 'geojson' | 'jpg' | 'json' | 'pbf' | 'png' | 'svg' | 'topojson' | 'webp';
|
|
4
|
+
export type MaplibreLayer = BackgroundLayerSpecification | FillLayerSpecification | LineLayerSpecification | SymbolLayerSpecification;
|
|
5
|
+
export type MaplibreLayerDefinition = BackgroundLayerSpecification | Omit<FillLayerSpecification, 'source'> | Omit<LineLayerSpecification, 'source'> | Omit<SymbolLayerSpecification, 'source'>;
|
|
6
|
+
export type MaplibreFilter = FilterSpecification;
|
|
7
|
+
export interface VectorLayer {
|
|
8
|
+
id: string;
|
|
9
|
+
fields: Record<string, 'Boolean' | 'Number' | 'String'>;
|
|
10
|
+
description?: string;
|
|
11
|
+
minzoom?: number;
|
|
12
|
+
maxzoom?: number;
|
|
13
|
+
}
|
|
14
|
+
export interface TileJSONSpecificationRaster {
|
|
15
|
+
tilejson?: '3.0.0';
|
|
16
|
+
type: 'raster';
|
|
17
|
+
attribution?: string;
|
|
18
|
+
tiles: string[];
|
|
19
|
+
scheme?: 'tms' | 'xyz';
|
|
20
|
+
bounds?: [number, number, number, number];
|
|
21
|
+
center?: [number, number];
|
|
22
|
+
description?: string;
|
|
23
|
+
fillzoom?: number;
|
|
24
|
+
grids?: string[];
|
|
25
|
+
legend?: string;
|
|
26
|
+
minzoom?: number;
|
|
27
|
+
maxzoom?: number;
|
|
28
|
+
name?: string;
|
|
29
|
+
template?: string;
|
|
30
|
+
format: 'avif' | 'jpg' | 'png' | 'webp';
|
|
31
|
+
}
|
|
32
|
+
export interface TileJSONSpecificationVector extends Omit<TileJSONSpecificationRaster, 'format' | 'type'> {
|
|
33
|
+
vector_layers: VectorLayer[];
|
|
34
|
+
format: 'pbf';
|
|
35
|
+
type: 'vector';
|
|
36
|
+
}
|
|
37
|
+
export type TileJSONSpecification = TileJSONSpecificationRaster | TileJSONSpecificationVector;
|
|
38
|
+
export type MaplibreStyleRaster = Omit<StyleSpecification, 'sources'> & {
|
|
39
|
+
'sources': {
|
|
40
|
+
[_: string]: TileJSONSpecificationRaster;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
export type MaplibreStyleVector = Omit<StyleSpecification, 'sources'> & {
|
|
44
|
+
'sources': {
|
|
45
|
+
[_: string]: TileJSONSpecificationVector;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
export type MaplibreStyle = MaplibreStyleRaster | MaplibreStyleVector;
|
|
49
|
+
export type StyleRuleValue = boolean | number | object | string;
|
|
50
|
+
export type StyleRule = Record<string, StyleRuleValue>;
|
|
51
|
+
export type StyleRules = Record<string, StyleRule>;
|
|
52
|
+
export type StylemakerColorLookup = Record<string, Color>;
|
|
53
|
+
export type StylemakerStringLookup = Record<string, string>;
|
|
54
|
+
export type LanguageSuffix = '_de' | '_en' | '';
|
|
55
|
+
export interface StyleRulesOptions {
|
|
56
|
+
colors: StylemakerColorLookup;
|
|
57
|
+
fonts: StylemakerStringLookup;
|
|
58
|
+
languageSuffix: string;
|
|
59
|
+
}
|
|
60
|
+
export interface RecolorOptions {
|
|
61
|
+
invert?: boolean;
|
|
62
|
+
rotate?: number;
|
|
63
|
+
saturate?: number;
|
|
64
|
+
gamma?: number;
|
|
65
|
+
contrast?: number;
|
|
66
|
+
brightness?: number;
|
|
67
|
+
tint?: number;
|
|
68
|
+
tintColor?: string;
|
|
69
|
+
}
|
|
70
|
+
export declare function isTileJSONSpecification(obj: unknown): obj is TileJSONSpecification;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
2
|
+
export function isTileJSONSpecification(obj) {
|
|
3
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
4
|
+
throw Error('spec must be an object');
|
|
5
|
+
}
|
|
6
|
+
const spec = obj;
|
|
7
|
+
// Common property validation
|
|
8
|
+
if (typeof spec.tilejson !== 'undefined' && spec.tilejson !== '3.0.0') {
|
|
9
|
+
throw Error('spec.tilejson must be "3.0.0" if present');
|
|
10
|
+
}
|
|
11
|
+
if (typeof spec.attribution !== 'undefined' && typeof spec.attribution !== 'string') {
|
|
12
|
+
throw Error('spec.attribution must be a string if present');
|
|
13
|
+
}
|
|
14
|
+
if (typeof spec.scheme !== 'undefined' && !['tms', 'xyz'].includes(spec.scheme)) {
|
|
15
|
+
throw Error('spec.scheme must be "tms" or "xyz" if present');
|
|
16
|
+
}
|
|
17
|
+
if (typeof spec.bounds !== 'undefined' && (!Array.isArray(spec.bounds) || spec.bounds.length !== 4 || spec.bounds.some(num => typeof num !== 'number'))) {
|
|
18
|
+
throw Error('spec.bounds must be an array of four numbers if present');
|
|
19
|
+
}
|
|
20
|
+
if (typeof spec.center !== 'undefined' && (!Array.isArray(spec.center) || spec.center.length !== 2 || spec.center.some(num => typeof num !== 'number'))) {
|
|
21
|
+
throw Error('spec.center must be an array of two numbers if present');
|
|
22
|
+
}
|
|
23
|
+
if (typeof spec.description !== 'undefined' && typeof spec.description !== 'string') {
|
|
24
|
+
throw Error('spec.description must be a string if present');
|
|
25
|
+
}
|
|
26
|
+
if (typeof spec.fillzoom !== 'undefined' && typeof spec.fillzoom !== 'number') {
|
|
27
|
+
throw Error('spec.fillzoom must be a number if present');
|
|
28
|
+
}
|
|
29
|
+
if (typeof spec.grids !== 'undefined' && (!Array.isArray(spec.grids) || spec.grids.some(url => typeof url !== 'string'))) {
|
|
30
|
+
throw Error('spec.grids must be an array of strings if present');
|
|
31
|
+
}
|
|
32
|
+
if (typeof spec.legend !== 'undefined' && typeof spec.legend !== 'string') {
|
|
33
|
+
throw Error('spec.legend must be a string if present');
|
|
34
|
+
}
|
|
35
|
+
if (typeof spec.minzoom !== 'undefined' && typeof spec.minzoom !== 'number') {
|
|
36
|
+
throw Error('spec.minzoom must be a number if present');
|
|
37
|
+
}
|
|
38
|
+
if (typeof spec.maxzoom !== 'undefined' && typeof spec.maxzoom !== 'number') {
|
|
39
|
+
throw Error('spec.maxzoom must be a number if present');
|
|
40
|
+
}
|
|
41
|
+
if (typeof spec.name !== 'undefined' && typeof spec.name !== 'string') {
|
|
42
|
+
throw Error('spec.name must be a string if present');
|
|
43
|
+
}
|
|
44
|
+
if (typeof spec.template !== 'undefined' && typeof spec.template !== 'string') {
|
|
45
|
+
throw Error('spec.template must be a string if present');
|
|
46
|
+
}
|
|
47
|
+
if (spec.type === 'raster') {
|
|
48
|
+
if (!['avif', 'jpg', 'png', 'webp'].includes(spec.format)) {
|
|
49
|
+
throw Error('spec.format must be "avif", "jpg", "png", or "webp"');
|
|
50
|
+
}
|
|
51
|
+
if (!Array.isArray(spec.tiles) || spec.tiles.some(url => typeof url !== 'string')) {
|
|
52
|
+
throw Error('spec.tiles must be an array of strings');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else if (spec.type === 'vector') {
|
|
56
|
+
if (spec.format !== 'pbf') {
|
|
57
|
+
throw Error('spec.format must be "pbf"');
|
|
58
|
+
}
|
|
59
|
+
if (!Array.isArray(spec.vector_layers) || spec.vector_layers.some(layer => !validateVectorLayer(layer))) {
|
|
60
|
+
throw Error('spec.vector_layers must be an array of VectorLayer');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
throw Error('spec.type must be "raster" or "vector"');
|
|
65
|
+
}
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
function validateVectorLayer(obj) {
|
|
69
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
70
|
+
throw Error('layer must be an object');
|
|
71
|
+
}
|
|
72
|
+
const layer = obj;
|
|
73
|
+
if (typeof layer.id !== 'string') {
|
|
74
|
+
throw Error('layer.id must be a string');
|
|
75
|
+
}
|
|
76
|
+
if (typeof layer.fields !== 'object' || layer.fields === null || Object.values(layer.fields).some(type => !['Boolean', 'Number', 'String'].includes(type))) {
|
|
77
|
+
throw Error('layer.fields must be an object with values "Boolean", "Number", or "String"');
|
|
78
|
+
}
|
|
79
|
+
if (typeof layer.description !== 'undefined' && typeof layer.description !== 'string') {
|
|
80
|
+
throw Error('layer.description must be a string if present');
|
|
81
|
+
}
|
|
82
|
+
if (typeof layer.minzoom !== 'undefined' && (typeof layer.minzoom !== 'number' || layer.minzoom < 0)) {
|
|
83
|
+
throw Error('layer.minzoom must be a non-negative number if present');
|
|
84
|
+
}
|
|
85
|
+
if (typeof layer.maxzoom !== 'undefined' && (typeof layer.maxzoom !== 'number' || layer.maxzoom < 0)) {
|
|
86
|
+
throw Error('layer.maxzoom must be a non-negative number if present');
|
|
87
|
+
}
|
|
88
|
+
return true;
|
|
89
|
+
}
|
package/dist/style/colorful.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import StyleBuilder from '../lib/style_builder.js';
|
|
2
|
-
import type { StyleRules, StyleRulesOptions } from '../lib/
|
|
2
|
+
import type { StyleRules, StyleRulesOptions } from '../lib/types.js';
|
|
3
3
|
export default class Colorful extends StyleBuilder {
|
|
4
4
|
readonly name: string;
|
|
5
5
|
fonts: {
|
package/dist/style/neutrino.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import StyleBuilder from '../lib/style_builder.js';
|
|
2
|
-
import type { StyleRules, StyleRulesOptions } from '../lib/
|
|
2
|
+
import type { StyleRules, StyleRulesOptions } from '../lib/types.js';
|
|
3
3
|
export default class Neutrino extends StyleBuilder {
|
|
4
4
|
readonly name: string;
|
|
5
5
|
fonts: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@versatiles/style",
|
|
3
|
-
"version": "3.5.
|
|
3
|
+
"version": "3.5.2",
|
|
4
4
|
"description": "Generate StyleJSON for MapLibre",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -8,9 +8,11 @@
|
|
|
8
8
|
"check": "npm run lint && npm run build && npm run test",
|
|
9
9
|
"build": "npm run build-browser && npm run build-node && npm run build-styles",
|
|
10
10
|
"build-browser": "rollup -c=rollup.config.js",
|
|
11
|
-
"build-node": "rm -rf dist && tsc -p tsconfig.node.json",
|
|
11
|
+
"build-node": "rm -rf dist && tsc -p tsconfig.node.json && chmod +x dist/index.js",
|
|
12
12
|
"build-styles": "tsx scripts/build-styles.ts",
|
|
13
|
-
"
|
|
13
|
+
"doc": "vrt ts2md src/index.ts tsconfig.node.json | vrt insertmd README.md '### Node.js API'",
|
|
14
|
+
"lint": "eslint --color .",
|
|
15
|
+
"prepublish": "npm run build && npm run doc",
|
|
14
16
|
"release": "tsx scripts/release.ts",
|
|
15
17
|
"test": "npm run test-node && npm run test-coverage && npm run test-browser",
|
|
16
18
|
"test-browser": "npm run build-browser && echo 'add browser test'",
|
|
@@ -27,7 +29,6 @@
|
|
|
27
29
|
"type": "module",
|
|
28
30
|
"dependencies": {
|
|
29
31
|
"@types/color": "^3.0.6",
|
|
30
|
-
"@types/mapbox-gl": "^2.7.18",
|
|
31
32
|
"brace-expansion": "^3.0.0",
|
|
32
33
|
"color": "^4.2.3"
|
|
33
34
|
},
|
|
@@ -44,19 +45,20 @@
|
|
|
44
45
|
"@types/brace-expansion": "^1.1.2",
|
|
45
46
|
"@types/inquirer": "^9.0.7",
|
|
46
47
|
"@types/jest": "^29.5.8",
|
|
47
|
-
"@types/node": "^20.9.
|
|
48
|
-
"@typescript-eslint/eslint-plugin": "^6.
|
|
49
|
-
"@typescript-eslint/parser": "^6.
|
|
50
|
-
"
|
|
48
|
+
"@types/node": "^20.9.2",
|
|
49
|
+
"@typescript-eslint/eslint-plugin": "^6.11.0",
|
|
50
|
+
"@typescript-eslint/parser": "^6.11.0",
|
|
51
|
+
"@versatiles/release-tool": "^1.0.1",
|
|
52
|
+
"eslint": "^8.54.0",
|
|
51
53
|
"inquirer": "^9.2.12",
|
|
52
54
|
"jest": "^29.7.0",
|
|
53
55
|
"jest-ts-webcompat-resolver": "^1.0.0",
|
|
54
|
-
"npm-check-updates": "^16.14.
|
|
55
|
-
"rollup": "^4.
|
|
56
|
+
"npm-check-updates": "^16.14.11",
|
|
57
|
+
"rollup": "^4.5.0",
|
|
56
58
|
"rollup-plugin-dts": "^6.1.0",
|
|
57
59
|
"ts-jest": "^29.1.1",
|
|
58
60
|
"ts-node": "^10.9.1",
|
|
59
|
-
"tsx": "^4.1.
|
|
61
|
+
"tsx": "^4.1.4",
|
|
60
62
|
"typescript": "^5.2.2"
|
|
61
63
|
}
|
|
62
64
|
}
|