json5 0.0.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.
Files changed (132) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.ruby-version +1 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +60 -0
  7. data/Rakefile +1 -0
  8. data/json5.gemspec +25 -0
  9. data/lib/json5.rb +13 -0
  10. data/lib/json5/parser.rb +461 -0
  11. data/lib/json5/stringifier.rb +242 -0
  12. data/lib/json5/version.rb +3 -0
  13. data/spec/json5/parse_spec.rb +71 -0
  14. data/spec/parse-cases/arrays/empty-array.json +1 -0
  15. data/spec/parse-cases/arrays/leading-comma-array.js +3 -0
  16. data/spec/parse-cases/arrays/lone-trailing-comma-array.js +3 -0
  17. data/spec/parse-cases/arrays/no-comma-array.txt +4 -0
  18. data/spec/parse-cases/arrays/regular-array.json +5 -0
  19. data/spec/parse-cases/arrays/trailing-comma-array.json5 +3 -0
  20. data/spec/parse-cases/comments/block-comment-following-array-element.json5 +6 -0
  21. data/spec/parse-cases/comments/block-comment-following-top-level-value.json5 +5 -0
  22. data/spec/parse-cases/comments/block-comment-in-string.json +1 -0
  23. data/spec/parse-cases/comments/block-comment-preceding-top-level-value.json5 +5 -0
  24. data/spec/parse-cases/comments/block-comment-with-asterisks.json5 +7 -0
  25. data/spec/parse-cases/comments/inline-comment-following-array-element.json5 +3 -0
  26. data/spec/parse-cases/comments/inline-comment-following-top-level-value.json5 +1 -0
  27. data/spec/parse-cases/comments/inline-comment-in-string.json +1 -0
  28. data/spec/parse-cases/comments/inline-comment-preceding-top-level-value.json5 +2 -0
  29. data/spec/parse-cases/comments/top-level-block-comment.txt +4 -0
  30. data/spec/parse-cases/comments/top-level-inline-comment.txt +1 -0
  31. data/spec/parse-cases/comments/unterminated-block-comment.txt +5 -0
  32. data/spec/parse-cases/misc/empty.txt +0 -0
  33. data/spec/parse-cases/misc/npm-package.json +106 -0
  34. data/spec/parse-cases/misc/npm-package.json5 +106 -0
  35. data/spec/parse-cases/misc/readme-example.json5 +25 -0
  36. data/spec/parse-cases/numbers/binary-coffeescript.txt +1 -0
  37. data/spec/parse-cases/numbers/float-leading-decimal-point.json5 +1 -0
  38. data/spec/parse-cases/numbers/float-leading-zero.json +1 -0
  39. data/spec/parse-cases/numbers/float-trailing-decimal-point-with-integer-exponent.json5.todo +1 -0
  40. data/spec/parse-cases/numbers/float-trailing-decimal-point.json5 +1 -0
  41. data/spec/parse-cases/numbers/float-with-integer-exponent.json +1 -0
  42. data/spec/parse-cases/numbers/float.json +1 -0
  43. data/spec/parse-cases/numbers/hexadecimal-empty.txt +1 -0
  44. data/spec/parse-cases/numbers/hexadecimal-lowercase-letter.json5 +1 -0
  45. data/spec/parse-cases/numbers/hexadecimal-uppercase-x.json5 +1 -0
  46. data/spec/parse-cases/numbers/hexadecimal-with-integer-exponent.json5 +1 -0
  47. data/spec/parse-cases/numbers/hexadecimal.json5 +1 -0
  48. data/spec/parse-cases/numbers/infinity.json5 +1 -0
  49. data/spec/parse-cases/numbers/integer-with-float-exponent.txt +1 -0
  50. data/spec/parse-cases/numbers/integer-with-hexadecimal-exponent.txt +1 -0
  51. data/spec/parse-cases/numbers/integer-with-integer-exponent.json +1 -0
  52. data/spec/parse-cases/numbers/integer-with-negative-float-exponent.txt +1 -0
  53. data/spec/parse-cases/numbers/integer-with-negative-hexadecimal-exponent.txt +1 -0
  54. data/spec/parse-cases/numbers/integer-with-negative-integer-exponent.json +1 -0
  55. data/spec/parse-cases/numbers/integer-with-negative-zero-integer-exponent.json +1 -0
  56. data/spec/parse-cases/numbers/integer-with-positive-float-exponent.txt +1 -0
  57. data/spec/parse-cases/numbers/integer-with-positive-hexadecimal-exponent.txt +1 -0
  58. data/spec/parse-cases/numbers/integer-with-positive-integer-exponent.json +1 -0
  59. data/spec/parse-cases/numbers/integer-with-positive-zero-integer-exponent.json +1 -0
  60. data/spec/parse-cases/numbers/integer-with-zero-integer-exponent.json +1 -0
  61. data/spec/parse-cases/numbers/integer.json +1 -0
  62. data/spec/parse-cases/numbers/lone-decimal-point.txt +1 -0
  63. data/spec/parse-cases/numbers/nan.json5 +1 -0
  64. data/spec/parse-cases/numbers/negative-binary-coffeescript.txt +1 -0
  65. data/spec/parse-cases/numbers/negative-float-leading-decimal-point.json5 +1 -0
  66. data/spec/parse-cases/numbers/negative-float-leading-zero.json +1 -0
  67. data/spec/parse-cases/numbers/negative-float-trailing-decimal-point.json5 +1 -0
  68. data/spec/parse-cases/numbers/negative-float.json +1 -0
  69. data/spec/parse-cases/numbers/negative-hexadecimal.js +1 -0
  70. data/spec/parse-cases/numbers/negative-infinity.json5 +1 -0
  71. data/spec/parse-cases/numbers/negative-integer.json +1 -0
  72. data/spec/parse-cases/numbers/negative-noctal.js +1 -0
  73. data/spec/parse-cases/numbers/negative-octal-coffeescript.txt +1 -0
  74. data/spec/parse-cases/numbers/negative-octal.txt +1 -0
  75. data/spec/parse-cases/numbers/negative-zero-binary-coffeescript.txt +1 -0
  76. data/spec/parse-cases/numbers/negative-zero-float-leading-decimal-point.json5 +1 -0
  77. data/spec/parse-cases/numbers/negative-zero-float-trailing-decimal-point.json5 +1 -0
  78. data/spec/parse-cases/numbers/negative-zero-float.json +1 -0
  79. data/spec/parse-cases/numbers/negative-zero-hexadecimal.js +1 -0
  80. data/spec/parse-cases/numbers/negative-zero-integer.json +1 -0
  81. data/spec/parse-cases/numbers/negative-zero-octal-coffeescript.txt +1 -0
  82. data/spec/parse-cases/numbers/negative-zero-octal.txt +1 -0
  83. data/spec/parse-cases/numbers/noctal-with-leading-octal-digit.js +1 -0
  84. data/spec/parse-cases/numbers/noctal.js +1 -0
  85. data/spec/parse-cases/numbers/octal-coffeescript.txt +1 -0
  86. data/spec/parse-cases/numbers/octal.txt +1 -0
  87. data/spec/parse-cases/numbers/positive-binary-coffeescript.txt +1 -0
  88. data/spec/parse-cases/numbers/positive-float-leading-decimal-point.json5 +1 -0
  89. data/spec/parse-cases/numbers/positive-float-leading-zero.json5 +1 -0
  90. data/spec/parse-cases/numbers/positive-float-trailing-decimal-point.json5 +1 -0
  91. data/spec/parse-cases/numbers/positive-float.json5 +1 -0
  92. data/spec/parse-cases/numbers/positive-hexadecimal.js +1 -0
  93. data/spec/parse-cases/numbers/positive-infinity.json5 +1 -0
  94. data/spec/parse-cases/numbers/positive-integer.json5 +1 -0
  95. data/spec/parse-cases/numbers/positive-noctal.js +1 -0
  96. data/spec/parse-cases/numbers/positive-octal-coffeescript.txt +1 -0
  97. data/spec/parse-cases/numbers/positive-octal.txt +1 -0
  98. data/spec/parse-cases/numbers/positive-zero-binary-coffeescript.txt +1 -0
  99. data/spec/parse-cases/numbers/positive-zero-float-leading-decimal-point.json5 +1 -0
  100. data/spec/parse-cases/numbers/positive-zero-float-trailing-decimal-point.json5 +1 -0
  101. data/spec/parse-cases/numbers/positive-zero-float.json5 +1 -0
  102. data/spec/parse-cases/numbers/positive-zero-hexadecimal.js +1 -0
  103. data/spec/parse-cases/numbers/positive-zero-integer.json5 +1 -0
  104. data/spec/parse-cases/numbers/positive-zero-octal-coffeescript.txt +1 -0
  105. data/spec/parse-cases/numbers/positive-zero-octal.txt +1 -0
  106. data/spec/parse-cases/numbers/zero-binary-coffeescript.txt +1 -0
  107. data/spec/parse-cases/numbers/zero-float-leading-decimal-point.json5 +1 -0
  108. data/spec/parse-cases/numbers/zero-float-trailing-decimal-point.json5 +1 -0
  109. data/spec/parse-cases/numbers/zero-float.json +1 -0
  110. data/spec/parse-cases/numbers/zero-hexadecimal.json5 +1 -0
  111. data/spec/parse-cases/numbers/zero-integer-with-integer-exponent.json +1 -0
  112. data/spec/parse-cases/numbers/zero-integer.json +1 -0
  113. data/spec/parse-cases/numbers/zero-octal-coffeescript.txt +1 -0
  114. data/spec/parse-cases/numbers/zero-octal.txt +1 -0
  115. data/spec/parse-cases/objects/empty-object.json +1 -0
  116. data/spec/parse-cases/objects/illegal-unquoted-key-number.txt +3 -0
  117. data/spec/parse-cases/objects/illegal-unquoted-key-symbol.txt +3 -0
  118. data/spec/parse-cases/objects/leading-comma-object.txt +3 -0
  119. data/spec/parse-cases/objects/lone-trailing-comma-object.txt +3 -0
  120. data/spec/parse-cases/objects/no-comma-object.txt +4 -0
  121. data/spec/parse-cases/objects/reserved-unquoted-key.json5 +3 -0
  122. data/spec/parse-cases/objects/single-quoted-key.json5 +3 -0
  123. data/spec/parse-cases/objects/trailing-comma-object.json5 +3 -0
  124. data/spec/parse-cases/objects/unquoted-keys.json5 +8 -0
  125. data/spec/parse-cases/strings/escaped-single-quoted-string.json5 +1 -0
  126. data/spec/parse-cases/strings/multi-line-string.json5 +2 -0
  127. data/spec/parse-cases/strings/single-quoted-string.json5 +1 -0
  128. data/spec/parse-cases/strings/unescaped-multi-line-string.txt +2 -0
  129. data/spec/parse-cases/todo/unicode-escaped-unquoted-key.json5.todo +3 -0
  130. data/spec/parse-cases/todo/unicode-unquoted-key.json5.todo +3 -0
  131. data/spec/spec_helper.rb +15 -0
  132. metadata +363 -0
@@ -0,0 +1,242 @@
1
+ module JSON5
2
+ class Stringifier
3
+ # # JSON5 stringify will not quote keys where appropriate
4
+ # JSON5.stringify = function (obj, replacer, space)
5
+ def initialize obj, replacer, space
6
+ if (replacer && (typeof(replacer) != "function" && !isArray(replacer)))
7
+ throw new Error('Replacer must be a function or an array')
8
+ end
9
+ end
10
+
11
+ def getReplacedValueOrUndefined holder, key, isTopLevel
12
+ value = holder[key]
13
+
14
+ # Replace the value with its toJSON value first, if possible
15
+ # if (value && value.toJSON && typeof value.toJSON === "function")
16
+ if (value && value.responds_to?(:to_json))
17
+ # value = value.toJSON
18
+ value = value.to_json
19
+ end
20
+
21
+ # If the user-supplied replacer if a function, call it. If it's an array, check objects' string keys for
22
+ # presence in the array (removing the key/value pair from the resulting JSON if the key is missing).
23
+ if (typeof(replacer) === "function")
24
+ return replacer.call(holder, key, value)
25
+ elsif(replacer)
26
+ if (isTopLevel || isArray(holder) || replacer.indexOf(key) >= 0)
27
+ return value
28
+ else
29
+ return undefined
30
+ end
31
+ else
32
+ return value
33
+ end
34
+ end
35
+
36
+ def isWordChar(char)
37
+ return (char >= 'a' && char <= 'z') ||
38
+ (char >= 'A' && char <= 'Z') ||
39
+ (char >= '0' && char <= '9') ||
40
+ char === '_' || char === '$'
41
+ end
42
+
43
+ def isWordStart(char)
44
+ return (char >= 'a' && char <= 'z') ||
45
+ (char >= 'A' && char <= 'Z') ||
46
+ char === '_' || char === '$'
47
+ end
48
+
49
+ def isWord(key)
50
+ if (typeof key != 'string')
51
+ return false
52
+ end
53
+ if (!isWordStart(key[0]))
54
+ return false
55
+ end
56
+ i = 1, length = key.length
57
+ while (i < length) do
58
+ if (!isWordChar(key[i]))
59
+ return false
60
+ end
61
+ i += 1
62
+ end
63
+ return true
64
+ end
65
+
66
+ # # export for use in tests
67
+ # JSON5.isWord = isWord
68
+
69
+ # # polyfills
70
+ def isArray(obj)
71
+ if (Array.isArray)
72
+ return Array.isArray(obj)
73
+ else
74
+ return Object.prototype.toString.call(obj) === '[object Array]'
75
+ end
76
+ end
77
+
78
+ def isDate(obj)
79
+ return Object.prototype.toString.call(obj) === '[object Date]'
80
+ end
81
+
82
+ # isNaN = isNaN || ->(val)
83
+ # return typeof val === 'number' && val != val
84
+ # end
85
+
86
+ # objStack = []
87
+ # def checkForCircular(obj)
88
+ # for (i = 0; i < objStack.length; i++)
89
+ # if (objStack[i] === obj)
90
+ # throw new TypeError("Converting circular structure to JSON")
91
+ # end
92
+ # end
93
+ # end
94
+
95
+ # def makeIndent(str, num, noNewLine)
96
+ # if (!str)
97
+ # return ""
98
+ # end
99
+ # # indentation no more than 10 chars
100
+ # if (str.length > 10)
101
+ # str = str.substring(0, 10)
102
+ # end
103
+
104
+ # indent = noNewLine ? "" : "\n"
105
+ # for (i = 0; i < num; i++)
106
+ # indent += str
107
+ # end
108
+
109
+ # return indent
110
+ # end
111
+
112
+ # indentStr
113
+ # if (space)
114
+ # if (typeof space === "string")
115
+ # indentStr = space
116
+ # elsif (typeof space === "number" && space >= 0)
117
+ # indentStr = makeIndent(" ", space, true)
118
+ # else
119
+ # # ignore space parameter
120
+ # end
121
+ # end
122
+
123
+ # # Copied from Crokford's implementation of JSON
124
+ # # See https://github.com/douglascrockford/JSON-js/blob/e39db4b7e6249f04a195e7dd0840e610cc9e941e/json2.js#L195
125
+ # # Begin
126
+ # cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
127
+ # escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
128
+ # meta = { # table of character substitutions
129
+ # '\b': '\\b',
130
+ # '\t': '\\t',
131
+ # '\n': '\\n',
132
+ # '\f': '\\f',
133
+ # '\r': '\\r',
134
+ # '"' : '\\"',
135
+ # '\\': '\\\\'
136
+ # end
137
+ # def escapeString(string)
138
+
139
+ # # If the string contains no control characters, no quote characters, and no
140
+ # # backslash characters, then we can safely slap some quotes around it.
141
+ # # Otherwise we must also replace the offending characters with safe escape
142
+ # # sequences.
143
+ # escapable.lastIndex = 0
144
+ # return escapable.test(string) ? '"' + string.replace(escapable, function (a)
145
+ # c = meta[a]
146
+ # return typeof c === 'string' ?
147
+ # c :
148
+ # '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4)
149
+ # end) + '"' : '"' + string + '"'
150
+ # end
151
+ # # End
152
+
153
+ # def internalStringify(holder, key, isTopLevel)
154
+ # buffer, res
155
+
156
+ # # Replace the value, if necessary
157
+ # obj_part = getReplacedValueOrUndefined(holder, key, isTopLevel)
158
+
159
+ # if (obj_part && !isDate(obj_part))
160
+ # # unbox objects
161
+ # # don't unbox dates, since will turn it into number
162
+ # obj_part = obj_part.valueOf
163
+ # end
164
+ # switch(typeof obj_part)
165
+ # when "boolean"
166
+ # return obj_part.toString
167
+
168
+ # when "number"
169
+ # if (isNaN(obj_part) || !isFinite(obj_part))
170
+ # return "null"
171
+ # end
172
+ # return obj_part.toString
173
+
174
+ # when "string"
175
+ # return escapeString(obj_part.toString)
176
+
177
+ # when "object"
178
+ # if (obj_part === null)
179
+ # return "null"
180
+ # elsif (isArray(obj_part))
181
+ # checkForCircular(obj_part)
182
+ # buffer = "["
183
+ # objStack.push(obj_part)
184
+
185
+ # for (i = 0; i < obj_part.length; i++)
186
+ # res = internalStringify(obj_part, i, false)
187
+ # buffer += makeIndent(indentStr, objStack.length)
188
+ # if (res === null || typeof res === "undefined")
189
+ # buffer += "null"
190
+ # else
191
+ # buffer += res
192
+ # end
193
+ # if (i < obj_part.length-1)
194
+ # buffer += ","
195
+ # elsif (indentStr)
196
+ # buffer += "\n"
197
+ # end
198
+ # end
199
+ # objStack.pop
200
+ # buffer += makeIndent(indentStr, objStack.length, true) + "]"
201
+ # else
202
+ # checkForCircular(obj_part)
203
+ # buffer = "{"
204
+ # nonEmpty = false
205
+ # objStack.push(obj_part)
206
+ # for (prop in obj_part)
207
+ # if (obj_part.hasOwnProperty(prop))
208
+ # value = internalStringify(obj_part, prop, false)
209
+ # isTopLevel = false
210
+ # if (typeof value != "undefined" && value != null)
211
+ # buffer += makeIndent(indentStr, objStack.length)
212
+ # nonEmpty = true
213
+ # key = isWord(prop) ? prop : escapeString(prop)
214
+ # buffer += key + ":" + (indentStr ? ' ' : '') + value + ","
215
+ # end
216
+ # end
217
+ # end
218
+ # objStack.pop
219
+ # if (nonEmpty)
220
+ # buffer = buffer.substring(0, buffer.length-1) + makeIndent(indentStr, objStack.length) + "}"
221
+ # else
222
+ # buffer = '{}'
223
+ # end
224
+ # end
225
+ # return buffer
226
+ # else
227
+ # # functions and undefined should be ignored
228
+ # return undefined
229
+ # end
230
+ # end
231
+
232
+ # # special case...when undefined is used inside of
233
+ # # a compound object/array, return null.
234
+ # # but when top-level, return undefined
235
+ # topLevelHolder = {"":obj}
236
+ # if (obj === undefined)
237
+ # return getReplacedValueOrUndefined(topLevelHolder, '', true)
238
+ # end
239
+ # return internalStringify(topLevelHolder, '', true)
240
+ # end
241
+ end
242
+ end
@@ -0,0 +1,3 @@
1
+ module JSON5
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+
3
+ describe JSON5 do
4
+ def parseJSON5
5
+ JSON5.parse(@str)
6
+ end
7
+
8
+ def parseJSON
9
+ Oj.load(@str)
10
+ end
11
+
12
+ def parseES5
13
+ js = V8::Context.new.eval("\"use strict\"; (\n" + @str + "\n)")
14
+ unify(js)
15
+ end
16
+
17
+ def unify obj
18
+ case obj
19
+ when V8::Array
20
+ unify(obj.to_a)
21
+ when V8::Object
22
+ unify(obj.to_h)
23
+ when Hash
24
+ obj.map{ |k, v| [k, unify(v)] }.to_h
25
+ when Array
26
+ obj.map{ |v| unify(v) }
27
+ else
28
+ obj
29
+ end
30
+ end
31
+
32
+ Dir[File.expand_path('../../parse-cases/**/*.*', __FILE__)].each do |path|
33
+ filename = File.basename(path)
34
+ context "#{filename}" do
35
+ before do
36
+ @str = File.read(path, encoding: 'UTF-8')
37
+ end
38
+
39
+ case File.extname(path)
40
+ when '.json'
41
+ it "Expected parsed JSON5 to equal parsed JSON" do
42
+ expect(parseJSON5).to eq(parseJSON)
43
+ end
44
+ when '.json5'
45
+ it 'Expected parsed JSON5 to equal parsed ES5.' do
46
+ if filename == 'nan.json5'
47
+ expect(parseJSON5.nan?).to eq(parseES5.nan?)
48
+ else
49
+ expect(parseJSON5).to eq(parseES5)
50
+ end
51
+ end
52
+ when '.js'
53
+ it 'Test case bug expected ES5 parsing not to fail.' do
54
+ expect{ parseES5 }.not_to raise_exception
55
+ end
56
+
57
+ it 'Expected JSON5 parsing to fail.' do
58
+ expect{ parseJSON5 }.to raise_exception
59
+ end
60
+ when '.txt'
61
+ it 'Test case bug: expected ES5 parsing to fail.' do
62
+ expect{ parseES5 }.to raise_exception
63
+ end
64
+
65
+ it 'Expected JSON5 parsing to fail.' do
66
+ expect{ parseJSON5 }.to raise_exception
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,4 @@
1
+ [
2
+ true
3
+ false
4
+ ]
@@ -0,0 +1,5 @@
1
+ [
2
+ true,
3
+ false,
4
+ null
5
+ ]
@@ -0,0 +1,5 @@
1
+ null
2
+ /*
3
+ Some non-comment top-level value is needed;
4
+ we use null above.
5
+ */
@@ -0,0 +1 @@
1
+ "This /* block comment */ isn't really a block comment."
@@ -0,0 +1,5 @@
1
+ /*
2
+ Some non-comment top-level value is needed;
3
+ we use null below.
4
+ */
5
+ null
@@ -0,0 +1,7 @@
1
+ /**
2
+ * This is a JavaDoc-like block comment.
3
+ * It contains asterisks inside of it.
4
+ * It might also be closed with multiple asterisks.
5
+ * Like this:
6
+ **/
7
+ true
@@ -0,0 +1 @@
1
+ null // Some non-comment top-level value is needed; we use null here.
@@ -0,0 +1 @@
1
+ "This inline comment // isn't really an inline comment."
@@ -0,0 +1,2 @@
1
+ // Some non-comment top-level value is needed; we use null below.
2
+ null
@@ -0,0 +1,4 @@
1
+ /*
2
+ This should fail;
3
+ comments cannot be the top-level value.
4
+ */
@@ -0,0 +1 @@
1
+ // This should fail; comments cannot be the top-level value.
@@ -0,0 +1,5 @@
1
+ true
2
+ /*
3
+ This block comment doesn't terminate.
4
+ There was a legitimate value before this,
5
+ but this is still invalid JS/JSON5.
File without changes
@@ -0,0 +1,106 @@
1
+ {
2
+ "name": "npm",
3
+ "publishConfig": {
4
+ "proprietary-attribs": false
5
+ },
6
+ "description": "A package manager for node",
7
+ "keywords": [
8
+ "package manager",
9
+ "modules",
10
+ "install",
11
+ "package.json"
12
+ ],
13
+ "version": "1.1.22",
14
+ "preferGlobal": true,
15
+ "config": {
16
+ "publishtest": false
17
+ },
18
+ "homepage": "http://npmjs.org/",
19
+ "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/isaacs/npm"
23
+ },
24
+ "bugs": {
25
+ "email": "npm-@googlegroups.com",
26
+ "url": "http://github.com/isaacs/npm/issues"
27
+ },
28
+ "directories": {
29
+ "doc": "./doc",
30
+ "man": "./man",
31
+ "lib": "./lib",
32
+ "bin": "./bin"
33
+ },
34
+ "main": "./lib/npm.js",
35
+ "bin": "./bin/npm-cli.js",
36
+ "dependencies": {
37
+ "semver": "~1.0.14",
38
+ "ini": "1",
39
+ "slide": "1",
40
+ "abbrev": "1",
41
+ "graceful-fs": "~1.1.1",
42
+ "minimatch": "~0.2",
43
+ "nopt": "1",
44
+ "node-uuid": "~1.3",
45
+ "proto-list": "1",
46
+ "rimraf": "2",
47
+ "request": "~2.9",
48
+ "which": "1",
49
+ "tar": "~0.1.12",
50
+ "fstream": "~0.1.17",
51
+ "block-stream": "*",
52
+ "inherits": "1",
53
+ "mkdirp": "0.3",
54
+ "read": "0",
55
+ "lru-cache": "1",
56
+ "node-gyp": "~0.4.1",
57
+ "fstream-npm": "0 >=0.0.5",
58
+ "uid-number": "0",
59
+ "archy": "0",
60
+ "chownr": "0"
61
+ },
62
+ "bundleDependencies": [
63
+ "slide",
64
+ "ini",
65
+ "semver",
66
+ "abbrev",
67
+ "graceful-fs",
68
+ "minimatch",
69
+ "nopt",
70
+ "node-uuid",
71
+ "rimraf",
72
+ "request",
73
+ "proto-list",
74
+ "which",
75
+ "tar",
76
+ "fstream",
77
+ "block-stream",
78
+ "inherits",
79
+ "mkdirp",
80
+ "read",
81
+ "lru-cache",
82
+ "node-gyp",
83
+ "fstream-npm",
84
+ "uid-number",
85
+ "archy",
86
+ "chownr"
87
+ ],
88
+ "devDependencies": {
89
+ "ronn": "https://github.com/isaacs/ronnjs/tarball/master"
90
+ },
91
+ "engines": {
92
+ "node": "0.6 || 0.7 || 0.8",
93
+ "npm": "1"
94
+ },
95
+ "scripts": {
96
+ "test": "node ./test/run.js",
97
+ "prepublish": "npm prune; rm -rf node_modules/*/{test,example,bench}*; make -j4 doc",
98
+ "dumpconf": "env | grep npm | sort | uniq"
99
+ },
100
+ "licenses": [
101
+ {
102
+ "type": "MIT +no-false-attribs",
103
+ "url": "http://github.com/isaacs/npm/raw/master/LICENSE"
104
+ }
105
+ ]
106
+ }