@prantlf/jsonlint 10.2.0 → 11.1.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.
package/lib/jsonlint.js CHANGED
@@ -9,7 +9,7 @@
9
9
  // This is autogenerated with esprima tools, see:
10
10
  // https://github.com/ariya/esprima/blob/master/esprima.js
11
11
 
12
- var Uni = { // eslint-disable-line no-unused-vars
12
+ const Uni = { // eslint-disable-line no-unused-vars
13
13
  isWhiteSpace: function isWhiteSpace (x) {
14
14
  // section 7.2, table 2
15
15
  return x === '\u0020' ||
@@ -84,7 +84,7 @@ function isDecDigit (x) {
84
84
  return x >= '0' && x <= '9'
85
85
  }
86
86
 
87
- var unescapeMap = {
87
+ const unescapeMap = {
88
88
  '\'': '\'',
89
89
  '"': '"',
90
90
  '\\': '\\',
@@ -102,34 +102,34 @@ function parseInternal (input, options) {
102
102
  input = String(input)
103
103
  }
104
104
 
105
- var json5 = options.mode === 'json5'
106
- var ignoreComments = options.ignoreComments || options.mode === 'cjson' || json5
107
- var ignoreTrailingCommas = options.ignoreTrailingCommas || json5
108
- var allowSingleQuotedStrings = options.allowSingleQuotedStrings || json5
109
- var allowDuplicateObjectKeys = options.allowDuplicateObjectKeys
110
- var reviver = options.reviver
111
- var tokenize = options.tokenize
112
- var rawTokens = options.rawTokens
113
- var tokenLocations = options.tokenLocations
114
- var tokenPaths = options.tokenPaths
105
+ const json5 = options.mode === 'json5'
106
+ const ignoreComments = options.ignoreComments || options.mode === 'cjson' || json5
107
+ const ignoreTrailingCommas = options.ignoreTrailingCommas || json5
108
+ const allowSingleQuotedStrings = options.allowSingleQuotedStrings || json5
109
+ const allowDuplicateObjectKeys = options.allowDuplicateObjectKeys
110
+ const reviver = options.reviver
111
+ const tokenize = options.tokenize
112
+ const rawTokens = options.rawTokens
113
+ const tokenLocations = options.tokenLocations
114
+ const tokenPaths = options.tokenPaths
115
115
 
116
- var isLineTerminator = json5 ? Uni.isLineTerminator : Uni.isLineTerminatorJSON
117
- var isWhiteSpace = json5 ? Uni.isWhiteSpace : Uni.isWhiteSpaceJSON
116
+ const isLineTerminator = json5 ? Uni.isLineTerminator : Uni.isLineTerminatorJSON
117
+ const isWhiteSpace = json5 ? Uni.isWhiteSpace : Uni.isWhiteSpaceJSON
118
118
 
119
- var inputLength = input.length
120
- var lineNumber = 0
121
- var lineStart = 0
122
- var position = 0
119
+ const inputLength = input.length
120
+ let lineNumber = 0
121
+ let lineStart = 0
122
+ let position = 0
123
123
 
124
- var startToken
125
- var endToken
126
- var tokenPath
124
+ const tokens = []
125
+ let startToken
126
+ let endToken
127
+ let tokenPath
127
128
 
128
129
  if (tokenize) {
129
- var tokens = []
130
- var tokenOffset = null
131
- var tokenLine
132
- var tokenColumn
130
+ let tokenOffset = null
131
+ let tokenLine
132
+ let tokenColumn
133
133
  startToken = function () {
134
134
  if (tokenOffset !== null) throw Error('internal error, token overlap')
135
135
  tokenLine = lineNumber + 1
@@ -138,7 +138,7 @@ function parseInternal (input, options) {
138
138
  }
139
139
  endToken = function (type, value) {
140
140
  if (tokenOffset !== position) {
141
- var token = { type: type }
141
+ const token = { type }
142
142
  if (rawTokens) {
143
143
  token.raw = input.substr(tokenOffset, position - tokenOffset)
144
144
  }
@@ -166,9 +166,9 @@ function parseInternal (input, options) {
166
166
  }
167
167
 
168
168
  function generateMessage () {
169
- var message
169
+ let message
170
170
  if (position < inputLength) {
171
- var token = JSON.stringify(input[position])
171
+ const token = JSON.stringify(input[position])
172
172
  message = 'Unexpected token ' + token
173
173
  } else {
174
174
  message = 'Unexpected end of input'
@@ -177,16 +177,16 @@ function parseInternal (input, options) {
177
177
  }
178
178
 
179
179
  function createError (message) {
180
- var column = position - lineStart + 1
180
+ const column = position - lineStart + 1
181
181
  ++lineNumber
182
- var texts = getTexts(message, input, position, lineNumber, column)
183
- var error = SyntaxError(texts.message)
182
+ const texts = getTexts(message, input, position, lineNumber, column)
183
+ const error = SyntaxError(texts.message)
184
184
  error.reason = message
185
185
  error.excerpt = texts.excerpt
186
186
  error.pointer = texts.pointer
187
187
  error.location = {
188
188
  start: {
189
- column: column,
189
+ column,
190
190
  line: lineNumber,
191
191
  offset: position
192
192
  }
@@ -198,7 +198,7 @@ function parseInternal (input, options) {
198
198
  if (!message) {
199
199
  message = generateMessage()
200
200
  }
201
- var error = createError(message)
201
+ const error = createError(message)
202
202
  throw error
203
203
  }
204
204
 
@@ -212,11 +212,11 @@ function parseInternal (input, options) {
212
212
  }
213
213
 
214
214
  function parseGeneric () {
215
- while (position < inputLength) {
215
+ if (position < inputLength) {
216
216
  startToken && startToken()
217
- var char = input[position++]
217
+ const char = input[position++]
218
218
  if (char === '"' || (char === '\'' && allowSingleQuotedStrings)) {
219
- var string = parseString(char)
219
+ const string = parseString(char)
220
220
  endToken && endToken('literal', string)
221
221
  return string
222
222
  } else if (char === '{') {
@@ -227,7 +227,7 @@ function parseInternal (input, options) {
227
227
  return parseArray()
228
228
  } else if (char === '-' || char === '.' || isDecDigit(char) ||
229
229
  (json5 && (char === '+' || char === 'I' || char === 'N'))) {
230
- var number = parseNumber()
230
+ const number = parseNumber()
231
231
  endToken && endToken('literal', number)
232
232
  return number
233
233
  } else if (char === 'n') {
@@ -251,12 +251,12 @@ function parseInternal (input, options) {
251
251
  }
252
252
 
253
253
  function parseKey () {
254
- var result
255
- while (position < inputLength) {
254
+ let result
255
+ if (position < inputLength) {
256
256
  startToken && startToken()
257
- var char = input[position++]
257
+ const char = input[position++]
258
258
  if (char === '"' || (char === '\'' && allowSingleQuotedStrings)) {
259
- var string = parseString(char)
259
+ const string = parseString(char)
260
260
  endToken && endToken('literal', string)
261
261
  return string
262
262
  } else if (char === '{') {
@@ -266,12 +266,12 @@ function parseInternal (input, options) {
266
266
  endToken && endToken('symbol', '[')
267
267
  return parseArray()
268
268
  } else if (char === '.' || isDecDigit(char)) {
269
- var number = parseNumber(true)
269
+ const number = parseNumber(true)
270
270
  endToken && endToken('literal', number)
271
271
  return number
272
272
  } else if ((json5 && Uni.isIdentifierStart(char)) ||
273
273
  (char === '\\' && input[position] === 'u')) {
274
- var rollback = position - 1
274
+ const rollback = position - 1
275
275
  result = parseIdentifier()
276
276
  if (result === undefined) {
277
277
  position = rollback
@@ -290,7 +290,7 @@ function parseInternal (input, options) {
290
290
  }
291
291
 
292
292
  function skipWhiteSpace () {
293
- var insideWhiteSpace
293
+ let insideWhiteSpace
294
294
  function startWhiteSpace () {
295
295
  if (!insideWhiteSpace) {
296
296
  insideWhiteSpace = true
@@ -306,7 +306,7 @@ function parseInternal (input, options) {
306
306
  }
307
307
  }
308
308
  while (position < inputLength) {
309
- var char = input[position++]
309
+ const char = input[position++]
310
310
  if (isLineTerminator(char)) {
311
311
  startToken && startWhiteSpace()
312
312
  newLine(char)
@@ -332,7 +332,7 @@ function parseInternal (input, options) {
332
332
 
333
333
  function skipComment (multiLine) {
334
334
  while (position < inputLength) {
335
- var char = input[position++]
335
+ const char = input[position++]
336
336
  if (isLineTerminator(char)) {
337
337
  if (!multiLine) {
338
338
  // let parent function deal with newline
@@ -356,8 +356,8 @@ function parseInternal (input, options) {
356
356
 
357
357
  function parseKeyword (keyword) {
358
358
  // keyword[0] is not checked because it was checked earlier
359
- var startPosition = position
360
- for (var i = 1, keywordLength = keyword.length; i < keywordLength; ++i) {
359
+ const startPosition = position
360
+ for (let i = 1, keywordLength = keyword.length; i < keywordLength; ++i) {
361
361
  if (position >= inputLength || keyword[i] !== input[position]) {
362
362
  position = startPosition - 1
363
363
  fail()
@@ -367,19 +367,19 @@ function parseInternal (input, options) {
367
367
  }
368
368
 
369
369
  function parseObject () {
370
- var result = {}
371
- var emptyObject = {}
372
- var isNotEmpty = false
370
+ const result = {}
371
+ const emptyObject = {}
372
+ let isNotEmpty = false
373
373
 
374
374
  while (position < inputLength) {
375
375
  skipWhiteSpace()
376
- var key = parseKey()
376
+ const key = parseKey()
377
377
  if (allowDuplicateObjectKeys === false && result[key]) {
378
378
  fail('Duplicate key: "' + key + '"')
379
379
  }
380
380
  skipWhiteSpace()
381
381
  startToken && startToken()
382
- var char = input[position++]
382
+ let char = input[position++]
383
383
  endToken && endToken('symbol', char)
384
384
  if (char === '}' && key === undefined) {
385
385
  if (!ignoreTrailingCommas && isNotEmpty) {
@@ -390,7 +390,7 @@ function parseInternal (input, options) {
390
390
  } else if (char === ':' && key !== undefined) {
391
391
  skipWhiteSpace()
392
392
  tokenPath && tokenPath.push(key)
393
- var value = parseGeneric()
393
+ let value = parseGeneric()
394
394
  tokenPath && tokenPath.pop()
395
395
 
396
396
  if (value === undefined) fail('No value found for key "' + key + '"')
@@ -433,15 +433,15 @@ function parseInternal (input, options) {
433
433
  }
434
434
 
435
435
  function parseArray () {
436
- var result = []
436
+ const result = []
437
437
  while (position < inputLength) {
438
438
  skipWhiteSpace()
439
439
  tokenPath && tokenPath.push(result.length)
440
- var item = parseGeneric()
440
+ let item = parseGeneric()
441
441
  tokenPath && tokenPath.pop()
442
442
  skipWhiteSpace()
443
443
  startToken && startToken()
444
- var char = input[position++]
444
+ const char = input[position++]
445
445
  endToken && endToken('symbol', char)
446
446
  if (item !== undefined) {
447
447
  if (reviver) {
@@ -476,11 +476,11 @@ function parseInternal (input, options) {
476
476
  // rewind because we don't know first char
477
477
  --position
478
478
 
479
- var start = position
480
- var char = input[position++]
481
- var toNumber = function (isOctal) {
482
- var string = input.substr(start, position - start)
483
- var result
479
+ let start = position
480
+ let char = input[position++]
481
+ const toNumber = function (isOctal) {
482
+ const string = input.substr(start, position - start)
483
+ let result
484
484
 
485
485
  if (isOctal) {
486
486
  result = parseInt(string.replace(/^0o?/, ''), 8)
@@ -531,8 +531,8 @@ function parseInternal (input, options) {
531
531
  char = input[position++]
532
532
 
533
533
  // new syntax, "0o777" old syntax, "0777"
534
- var isOctal = char === 'o' || char === 'O' || isOctDigit(char)
535
- var isHex = char === 'x' || char === 'X'
534
+ const isOctal = char === 'o' || char === 'O' || isOctDigit(char)
535
+ const isHex = char === 'x' || char === 'X'
536
536
 
537
537
  if (json5 && (isOctal || isHex)) {
538
538
  while (position < inputLength &&
@@ -540,7 +540,7 @@ function parseInternal (input, options) {
540
540
  ++position
541
541
  }
542
542
 
543
- var sign = 1
543
+ let sign = 1
544
544
  if (input[start] === '-') {
545
545
  sign = -1
546
546
  ++start
@@ -583,9 +583,9 @@ function parseInternal (input, options) {
583
583
  // rewind because we don't know first char
584
584
  --position
585
585
 
586
- var result = ''
586
+ let result = ''
587
587
  while (position < inputLength) {
588
- var char = input[position++]
588
+ let char = input[position++]
589
589
  if (char === '\\' &&
590
590
  input[position] === 'u' &&
591
591
  isHexDigit(input[position + 1]) &&
@@ -619,9 +619,9 @@ function parseInternal (input, options) {
619
619
 
620
620
  function parseString (endChar) {
621
621
  // 7.8.4 of ES262 spec
622
- var result = ''
622
+ let result = ''
623
623
  while (position < inputLength) {
624
- var char = input[position++]
624
+ let char = input[position++]
625
625
  if (char === endChar) {
626
626
  return result
627
627
  } else if (char === '\\') {
@@ -636,9 +636,9 @@ function parseInternal (input, options) {
636
636
  newLine(char)
637
637
  } else if (char === 'u' || (char === 'x' && json5)) {
638
638
  // unicode/character escape sequence
639
- var count = char === 'u' ? 4 : 2
639
+ const count = char === 'u' ? 4 : 2
640
640
  // validation for \uXXXX
641
- for (var i = 0; i < count; ++i) {
641
+ for (let i = 0; i < count; ++i) {
642
642
  if (position >= inputLength) {
643
643
  fail()
644
644
  }
@@ -649,7 +649,7 @@ function parseInternal (input, options) {
649
649
  }
650
650
  result += String.fromCharCode(parseInt(input.substr(position - count, count), 16))
651
651
  } else if (json5 && isOctDigit(char)) {
652
- var digits
652
+ let digits
653
653
  if (char < '4' && isOctDigit(input[position]) && isOctDigit(input[position + 1])) {
654
654
  // three-digit octal
655
655
  digits = 3
@@ -684,7 +684,7 @@ function parseInternal (input, options) {
684
684
  }
685
685
 
686
686
  skipWhiteSpace()
687
- var returnValue = parseGeneric()
687
+ let returnValue = parseGeneric()
688
688
  if (returnValue !== undefined || position < inputLength) {
689
689
  skipWhiteSpace()
690
690
  if (position >= inputLength) {
@@ -721,9 +721,9 @@ function tokenize (input, options) { // eslint-disable-line no-unused-vars
721
721
  }
722
722
  // As long as this is the single modification, this is easier than cloning.
723
723
  // (Once Node.js 6 is dropped, this can be replaced by object destructuring.)
724
- var oldTokenize = options.tokenize
724
+ const oldTokenize = options.tokenize
725
725
  options.tokenize = true
726
- var tokens = parseInternal(input, options)
726
+ const tokens = parseInternal(input, options)
727
727
  options.tokenize = oldTokenize
728
728
  return tokens
729
729
  }
@@ -764,46 +764,59 @@ function pointerToPath (pointer) { // eslint-disable-line no-unused-vars
764
764
  }
765
765
 
766
766
  function getLineAndColumn (input, offset) {
767
- var lines = input
767
+ const lines = input
768
768
  .substr(0, offset)
769
769
  .split(/\r?\n/)
770
- var line = lines.length
771
- var column = lines[line - 1].length + 1
770
+ const line = lines.length
771
+ const column = lines[line - 1].length + 1
772
772
  return {
773
- line: line,
774
- column: column
773
+ line,
774
+ column
775
+ }
776
+ }
777
+
778
+ function getOffset (input, line, column) {
779
+ if (line > 1) {
780
+ const breaks = /\r?\n/g
781
+ let match
782
+ while (match = breaks.exec(input)) { // eslint-disable-line no-cond-assign
783
+ if (--line === 1) {
784
+ return match.index + column
785
+ }
786
+ }
775
787
  }
788
+ return column - 1
776
789
  }
777
790
 
778
791
  function pastInput (input, offset) {
779
- var start = Math.max(0, offset - 20)
780
- var previous = input.substr(start, offset - start)
792
+ const start = Math.max(0, offset - 20)
793
+ const previous = input.substr(start, offset - start)
781
794
  return (offset > 20 ? '...' : '') + previous.replace(/\r?\n/g, '')
782
795
  }
783
796
 
784
797
  function upcomingInput (input, offset) {
785
- var start = Math.max(0, offset - 20)
798
+ let start = Math.max(0, offset - 20)
786
799
  start += offset - start
787
- var rest = input.length - start
788
- var next = input.substr(start, Math.min(20, rest))
800
+ const rest = input.length - start
801
+ const next = input.substr(start, Math.min(20, rest))
789
802
  return next.replace(/\r?\n/g, '') + (rest > 20 ? '...' : '')
790
803
  }
791
804
 
792
805
  function getPositionContext (input, offset) {
793
- var past = pastInput(input, offset)
794
- var upcoming = upcomingInput(input, offset)
795
- var pointer = new Array(past.length + 1).join('-') + '^'
806
+ const past = pastInput(input, offset)
807
+ const upcoming = upcomingInput(input, offset)
808
+ const pointer = new Array(past.length + 1).join('-') + '^'
796
809
  return {
797
810
  excerpt: past + upcoming,
798
- pointer: pointer
811
+ pointer
799
812
  }
800
813
  }
801
814
 
802
815
  function getReason (error) {
803
- var message = error.message
816
+ let message = error.message
804
817
  .replace('JSON.parse: ', '') // SpiderMonkey
805
818
  .replace('JSON Parse error: ', '') // SquirrelFish
806
- var firstCharacter = message.charAt(0)
819
+ const firstCharacter = message.charAt(0)
807
820
  if (firstCharacter >= 'a') {
808
821
  message = firstCharacter.toUpperCase() + message.substr(1)
809
822
  }
@@ -811,12 +824,12 @@ function getReason (error) {
811
824
  }
812
825
 
813
826
  function getLocationOnV8 (input, reason) {
814
- var match = / in JSON at position (\d+)$/.exec(reason)
827
+ const match = / in JSON at position (\d+)$/.exec(reason)
815
828
  if (match) {
816
- var offset = +match[1]
817
- var location = getLineAndColumn(input, offset)
829
+ const offset = +match[1]
830
+ const location = getLineAndColumn(input, offset)
818
831
  return {
819
- offset: offset,
832
+ offset,
820
833
  line: location.line,
821
834
  column: location.column,
822
835
  reason: reason.substr(0, match.index)
@@ -825,12 +838,12 @@ function getLocationOnV8 (input, reason) {
825
838
  }
826
839
 
827
840
  function checkUnexpectedEndOnV8 (input, reason) {
828
- var match = / end of JSON input$/.exec(reason)
841
+ const match = / end of JSON input$/.exec(reason)
829
842
  if (match) {
830
- var offset = input.length
831
- var location = getLineAndColumn(input, offset)
843
+ const offset = input.length
844
+ const location = getLineAndColumn(input, offset)
832
845
  return {
833
- offset: offset,
846
+ offset,
834
847
  line: location.line,
835
848
  column: location.column,
836
849
  reason: reason.substr(0, match.index + 4)
@@ -839,24 +852,24 @@ function checkUnexpectedEndOnV8 (input, reason) {
839
852
  }
840
853
 
841
854
  function getLocationOnSpiderMonkey (input, reason) {
842
- var match = / at line (\d+) column (\d+) of the JSON data$/.exec(reason)
855
+ const match = / at line (\d+) column (\d+) of the JSON data$/.exec(reason)
843
856
  if (match) {
844
- var line = +match[1]
845
- var column = +match[2]
846
- var offset = getOffset(input, line, column) // eslint-disable-line no-undef
857
+ const line = +match[1]
858
+ const column = +match[2]
859
+ const offset = getOffset(input, line, column) // eslint-disable-line no-undef
847
860
  return {
848
- offset: offset,
849
- line: line,
850
- column: column,
861
+ offset,
862
+ line,
863
+ column,
851
864
  reason: reason.substr(0, match.index)
852
865
  }
853
866
  }
854
867
  }
855
868
 
856
869
  function getTexts (reason, input, offset, line, column) {
857
- var position = getPositionContext(input, offset)
858
- var excerpt = position.excerpt
859
- var message, pointer
870
+ const position = getPositionContext(input, offset)
871
+ const excerpt = position.excerpt
872
+ let message, pointer
860
873
  if (typeof line === 'number') {
861
874
  pointer = position.pointer
862
875
  message = 'Parse error on line ' + line + ', column ' +
@@ -865,18 +878,18 @@ function getTexts (reason, input, offset, line, column) {
865
878
  message = 'Parse error in JSON input:\n' + excerpt + '\n' + reason
866
879
  }
867
880
  return {
868
- message: message,
869
- excerpt: excerpt,
870
- pointer: pointer
881
+ message,
882
+ excerpt,
883
+ pointer
871
884
  }
872
885
  }
873
886
 
874
887
  function improveNativeError (input, error) {
875
- var reason = getReason(error)
876
- var location = getLocationOnV8(input, reason) ||
888
+ let reason = getReason(error)
889
+ const location = getLocationOnV8(input, reason) ||
877
890
  checkUnexpectedEndOnV8(input, reason) ||
878
891
  getLocationOnSpiderMonkey(input, reason)
879
- var offset, line, column
892
+ let offset, line, column
880
893
  if (location) {
881
894
  offset = location.offset
882
895
  line = location.line
@@ -886,16 +899,16 @@ function improveNativeError (input, error) {
886
899
  offset = 0
887
900
  }
888
901
  error.reason = reason
889
- var texts = getTexts(reason, input, offset, line, column)
902
+ const texts = getTexts(reason, input, offset, line, column)
890
903
  error.message = texts.message
891
904
  error.excerpt = texts.excerpt
892
905
  if (texts.pointer) {
893
906
  error.pointer = texts.pointer
894
907
  error.location = {
895
908
  start: {
896
- column: column,
897
- line: line,
898
- offset: offset
909
+ column,
910
+ line,
911
+ offset
899
912
  }
900
913
  }
901
914
  }
@@ -912,8 +925,8 @@ function parseNative (input, reviver) { // eslint-disable-line no-unused-vars
912
925
 
913
926
  /* globals navigator, process, parseCustom, parseNative */
914
927
 
915
- var isSafari = typeof navigator !== 'undefined' && /Safari/.test(navigator.userAgent) && /Apple Computer/.test(navigator.vendor)
916
- var oldNode = typeof process !== 'undefined' && process.version.startsWith('v4.')
928
+ const isSafari = typeof navigator !== 'undefined' && /Safari/.test(navigator.userAgent) && /Apple Computer/.test(navigator.vendor)
929
+ const oldNode = typeof process !== 'undefined' && process.version.startsWith('v4.')
917
930
 
918
931
  function needsCustomParser (options) {
919
932
  return options.ignoreComments || options.ignoreTrailingCommas ||