@mapbox/mapbox-gl-style-spec 14.21.0 → 14.22.0-rc.1

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.
@@ -146,9 +146,8 @@ class Config implements Expression {
146
146
  }
147
147
  }
148
148
 
149
- // @ts-expect-error - TS2367 - This comparison appears to be unintentional because the types 'string' and 'Type' have no overlap.
150
149
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
151
- if ((type && type !== this.type) || (result !== undefined && !typeEquals(typeOf(result), this.type))) {
150
+ if ((type && type !== (this.type as unknown as string)) || (result !== undefined && !typeEquals(typeOf(result), this.type))) {
152
151
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
153
152
  result = coerceValue(this.type.kind, result);
154
153
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mapbox/mapbox-gl-style-spec",
3
- "version": "14.21.0",
3
+ "version": "14.22.0-rc.1",
4
4
  "description": "a specification for mapbox gl styles",
5
5
  "author": "Mapbox",
6
6
  "license": "SEE LICENSE IN LICENSE.txt",
@@ -44,7 +44,6 @@
44
44
  "gl-style-composite": "./bin/gl-style-composite.js"
45
45
  },
46
46
  "dependencies": {
47
- "@mapbox/jsonlint-lines-primitives": "~2.0.2",
48
47
  "@mapbox/point-geometry": "^1.1.0",
49
48
  "@mapbox/unitbezier": "^0.0.1",
50
49
  "cheap-ruler": "^4.0.0",
package/read_style.ts CHANGED
@@ -1,12 +1,13 @@
1
1
  import ParsingError from './error/parsing_error';
2
- import jsonlint from '@mapbox/jsonlint-lines-primitives';
3
2
 
4
3
  import type {StyleSpecification} from './types';
5
4
 
6
5
  export default function readStyle(style: string | Buffer | StyleSpecification): StyleSpecification {
7
6
  if (style instanceof String || typeof style === 'string' || ArrayBuffer.isView(style)) {
8
7
  try {
9
- return (jsonlint as {parse: (input: string) => StyleSpecification}).parse(style.toString());
8
+ const str = style.toString();
9
+ JSON.parse(str); // first try full parsing to catch malformed JSON
10
+ return parse(str) as StyleSpecification; // then our custom parser
10
11
  } catch (e) {
11
12
  throw new ParsingError(e as Error);
12
13
  }
@@ -14,3 +15,124 @@ export default function readStyle(style: string | Buffer | StyleSpecification):
14
15
 
15
16
  return style;
16
17
  }
18
+
19
+ // custom JSON parser that assumes valid JSON and wraps values to include line metadata
20
+
21
+ export const LBRACE = 0; // {
22
+ export const RBRACE = 1; // }
23
+ export const LBRACKET = 2; // [
24
+ export const RBRACKET = 3; // ]
25
+ export const STRING = 4; // "..."
26
+ export const NUMBER = 5; // -1.5e+3
27
+ export const TRUE = 6; // true
28
+ export const FALSE = 7; // false
29
+ export const NULL = 8; // null
30
+
31
+ export function tokenize(s: string) {
32
+ const tokens: number[] = [];
33
+ let pos = 0;
34
+ const len = s.length;
35
+
36
+ while (pos < len) {
37
+ const c = s.charCodeAt(pos);
38
+
39
+ if (c === 32 || c === 9 || c === 10 || c === 13 || c === 58 || c === 44) { // whitespace
40
+ pos++;
41
+ continue;
42
+ }
43
+
44
+ const start = pos;
45
+
46
+ if (c === 123) tokens.push(LBRACE, start, ++pos); // {
47
+ else if (c === 125) tokens.push(RBRACE, start, ++pos); // }
48
+ else if (c === 91) tokens.push(LBRACKET, start, ++pos); // [
49
+ else if (c === 93) tokens.push(RBRACKET, start, ++pos); // ]
50
+ else if (c === 34) { // "
51
+ pos++;
52
+ while (pos < len) {
53
+ const ch = s.charCodeAt(pos);
54
+ if (ch === 92) pos += s.charCodeAt(pos + 1) === 117 ? 6 : 2; // escape; \uXXXX = 6 chars, others = 2
55
+ else if (ch === 34) break; // closing quote
56
+ else pos++;
57
+ }
58
+ tokens.push(STRING, start, ++pos);
59
+ } else if (c === 116) tokens.push(TRUE, start, pos += 4); // true
60
+ else if (c === 102) tokens.push(FALSE, start, pos += 5); // false
61
+ else if (c === 110) tokens.push(NULL, start, pos += 4); // null
62
+ else { // number
63
+ while (pos < len) {
64
+ const ch = s.charCodeAt(pos);
65
+ if ((ch >= 48 && ch <= 57) || ch === 45 || ch === 43 || ch === 46 || ch === 101 || ch === 69) pos++;
66
+ else break;
67
+ }
68
+ tokens.push(NUMBER, start, pos);
69
+ }
70
+ }
71
+
72
+ return tokens;
73
+ }
74
+
75
+ /* eslint-disable @typescript-eslint/no-wrapper-object-types */
76
+ type JSONValue = String | Number | Boolean | null | {[key: string]: JSONValue} | JSONValue[];
77
+
78
+ function parseTokens(s: string, tokens: number[]) {
79
+ let i = 0;
80
+
81
+ const lineOffsets = [0];
82
+ for (let j = 0; j < s.length; j++) {
83
+ if (s.charCodeAt(j) === 10) lineOffsets.push(j + 1);
84
+ }
85
+
86
+ function lineNum(pos: number) {
87
+ let lo = 0, hi = lineOffsets.length - 1;
88
+ while (lo < hi) {
89
+ const mid = (lo + hi + 1) >> 1;
90
+ if (lineOffsets[mid] <= pos) lo = mid;
91
+ else hi = mid - 1;
92
+ }
93
+ return lo + 1;
94
+ }
95
+
96
+ function setLine<T>(obj: T, line: number): T {
97
+ Object.defineProperty(obj, '__line__', {value: line});
98
+ return obj;
99
+ }
100
+
101
+ function parseValue(): JSONValue {
102
+ const type = tokens[i];
103
+ const start = tokens[i + 1];
104
+ const end = tokens[i + 2];
105
+ i += 3;
106
+
107
+ const line = lineNum(start);
108
+
109
+ if (type === LBRACE) {
110
+ const obj = setLine({}, line);
111
+ while (tokens[i] !== RBRACE) {
112
+ const key: string = JSON.parse(s.slice(tokens[i + 1], tokens[i + 2])) as string;
113
+ i += 3;
114
+ obj[key] = parseValue();
115
+ }
116
+ i += 3;
117
+ return obj;
118
+ }
119
+ if (type === LBRACKET) {
120
+ const arr: JSONValue = setLine([], line);
121
+ while (tokens[i] !== RBRACKET) arr.push(parseValue());
122
+ i += 3;
123
+ return arr;
124
+ }
125
+ /* eslint-disable no-new-wrappers */
126
+ if (type === STRING) return setLine(new String(JSON.parse(s.slice(start, end))), line);
127
+ if (type === NUMBER) return setLine(new Number(+s.slice(start, end)), line);
128
+ if (type === TRUE) return setLine(new Boolean(true), line);
129
+ if (type === FALSE) return setLine(new Boolean(false), line);
130
+ return null; // null cannot carry properties
131
+ }
132
+
133
+ return parseValue();
134
+ }
135
+
136
+ function parse(s: string): JSONValue {
137
+ return parseTokens(s, tokenize(s));
138
+ }
package/rollup.config.js CHANGED
@@ -1,4 +1,3 @@
1
- import replace from '@rollup/plugin-replace';
2
1
  import resolve from '@rollup/plugin-node-resolve';
3
2
  import commonjs from '@rollup/plugin-commonjs';
4
3
  import unassert from 'rollup-plugin-unassert';
@@ -20,15 +19,6 @@ const config = [{
20
19
  sourcemap: true
21
20
  },
22
21
  plugins: [
23
- // https://github.com/zaach/jison/issues/351
24
- replace({
25
- preventAssignment: true,
26
- include: /\/jsonlint-lines-primitives\/lib\/jsonlint.js/,
27
- delimiters: ['', ''],
28
- values: {
29
- '_token_stack:': ''
30
- }
31
- }),
32
22
  esbuild({tsconfig: `${__dirname}/../../tsconfig.json`}),
33
23
  json(),
34
24
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call