vulcan 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (260) hide show
  1. data/lib/vulcan/cli.rb +20 -10
  2. data/lib/vulcan/version.rb +1 -1
  3. data/server/Procfile +1 -1
  4. data/server/bin/web +10 -0
  5. data/server/lib/cloudant.coffee +20 -0
  6. data/server/lib/logger.coffee +17 -0
  7. data/server/lib/on.coffee +10 -0
  8. data/server/lib/spawner.coffee +65 -0
  9. data/server/node_modules/coffee-script/CNAME +1 -0
  10. data/server/node_modules/coffee-script/LICENSE +22 -0
  11. data/server/node_modules/coffee-script/README +51 -0
  12. data/server/node_modules/coffee-script/Rakefile +78 -0
  13. data/server/node_modules/coffee-script/bin/cake +7 -0
  14. data/server/node_modules/coffee-script/bin/coffee +7 -0
  15. data/server/node_modules/coffee-script/extras/jsl.conf +44 -0
  16. data/server/node_modules/coffee-script/lib/coffee-script/browser.js +92 -0
  17. data/server/node_modules/coffee-script/lib/coffee-script/cake.js +111 -0
  18. data/server/node_modules/coffee-script/lib/coffee-script/coffee-script.js +167 -0
  19. data/server/node_modules/coffee-script/lib/coffee-script/command.js +500 -0
  20. data/server/node_modules/coffee-script/lib/coffee-script/grammar.js +606 -0
  21. data/server/node_modules/coffee-script/lib/coffee-script/helpers.js +77 -0
  22. data/server/node_modules/coffee-script/lib/coffee-script/index.js +11 -0
  23. data/server/node_modules/coffee-script/lib/coffee-script/lexer.js +788 -0
  24. data/server/node_modules/coffee-script/lib/coffee-script/nodes.js +2986 -0
  25. data/server/node_modules/coffee-script/lib/coffee-script/optparse.js +138 -0
  26. data/server/node_modules/coffee-script/lib/coffee-script/parser.js +683 -0
  27. data/server/node_modules/coffee-script/lib/coffee-script/repl.js +261 -0
  28. data/server/node_modules/coffee-script/lib/coffee-script/rewriter.js +349 -0
  29. data/server/node_modules/coffee-script/lib/coffee-script/scope.js +146 -0
  30. data/server/node_modules/coffee-script/package.json +55 -0
  31. data/server/node_modules/connect-form/History.md +0 -6
  32. data/server/node_modules/connect-form/lib/connect-form.js +2 -4
  33. data/server/node_modules/connect-form/node_modules/formidable/Readme.md +64 -36
  34. data/server/node_modules/connect-form/node_modules/formidable/lib/incoming_form.js +5 -1
  35. data/server/node_modules/connect-form/node_modules/formidable/package.json +20 -6
  36. data/server/node_modules/connect-form/node_modules/formidable/test/common.js +5 -6
  37. data/server/node_modules/connect-form/node_modules/formidable/test/fixture/file/funkyfilename.txt +1 -0
  38. data/server/node_modules/connect-form/node_modules/formidable/test/fixture/js/special-chars-in-filename.js +1 -1
  39. data/server/node_modules/connect-form/node_modules/formidable/test/{slow → integration}/test-fixtures.js +38 -33
  40. data/server/node_modules/connect-form/node_modules/formidable/test/legacy/simple/test-incoming-form.js +11 -0
  41. data/server/node_modules/connect-form/node_modules/formidable/test/run.js +1 -6
  42. data/server/node_modules/connect-form/node_modules/formidable/test/unit/test-incoming-form.js +63 -0
  43. data/server/node_modules/connect-form/package.json +27 -5
  44. data/server/node_modules/cradle/README.md +10 -10
  45. data/server/node_modules/cradle/lib/cradle.js +117 -523
  46. data/server/node_modules/cradle/lib/cradle/database/attachments.js +120 -0
  47. data/server/node_modules/cradle/lib/cradle/database/changes.js +56 -0
  48. data/server/node_modules/cradle/lib/cradle/database/documents.js +215 -0
  49. data/server/node_modules/cradle/lib/cradle/database/index.js +65 -0
  50. data/server/node_modules/cradle/lib/cradle/database/views.js +125 -0
  51. data/server/node_modules/cradle/node_modules/follow/LICENSE +202 -0
  52. data/server/node_modules/cradle/node_modules/follow/README.md +164 -0
  53. data/server/node_modules/cradle/node_modules/follow/Rakefile +54 -0
  54. data/server/node_modules/cradle/node_modules/follow/api.js +35 -0
  55. data/server/node_modules/cradle/node_modules/follow/browser/eventemitter2.js +453 -0
  56. data/server/node_modules/cradle/node_modules/follow/browser/export.js +78 -0
  57. data/server/node_modules/cradle/node_modules/follow/browser/index.html +14 -0
  58. data/server/node_modules/cradle/node_modules/follow/browser/jquery-1.6.1.min.js +18 -0
  59. data/server/node_modules/cradle/node_modules/follow/browser/log4js.js +46 -0
  60. data/server/node_modules/cradle/node_modules/follow/browser/main.js +92 -0
  61. data/server/node_modules/cradle/node_modules/follow/browser/querystring.js +28 -0
  62. data/server/node_modules/cradle/node_modules/follow/browser/request.jquery.js +237 -0
  63. data/server/node_modules/cradle/node_modules/follow/browser/require.js +33 -0
  64. data/server/node_modules/cradle/node_modules/follow/browser/util.js +28 -0
  65. data/server/node_modules/cradle/node_modules/follow/cli.js +101 -0
  66. data/server/node_modules/cradle/node_modules/follow/lib/feed.js +556 -0
  67. data/server/node_modules/cradle/node_modules/follow/lib/index.js +66 -0
  68. data/server/node_modules/cradle/node_modules/follow/lib/stream.js +305 -0
  69. data/server/node_modules/cradle/node_modules/follow/node_modules/request/LICENSE +55 -0
  70. data/server/node_modules/cradle/node_modules/follow/node_modules/request/README.md +285 -0
  71. data/server/node_modules/cradle/node_modules/follow/node_modules/request/main.js +618 -0
  72. data/server/node_modules/cradle/node_modules/follow/node_modules/request/mimetypes.js +146 -0
  73. data/server/node_modules/cradle/node_modules/follow/node_modules/request/oauth.js +34 -0
  74. data/server/node_modules/cradle/node_modules/follow/node_modules/request/package.json +42 -0
  75. data/server/node_modules/cradle/node_modules/follow/node_modules/request/tests/googledoodle.png +0 -0
  76. data/server/node_modules/cradle/node_modules/follow/node_modules/request/tests/run.sh +6 -0
  77. data/server/node_modules/cradle/node_modules/follow/node_modules/request/tests/server.js +57 -0
  78. data/server/node_modules/cradle/node_modules/follow/node_modules/request/tests/test-body.js +90 -0
  79. data/server/node_modules/cradle/node_modules/follow/node_modules/request/tests/test-cookie.js +29 -0
  80. data/server/node_modules/cradle/node_modules/follow/node_modules/request/tests/test-cookiejar.js +90 -0
  81. data/server/node_modules/cradle/node_modules/follow/node_modules/request/tests/test-errors.js +30 -0
  82. data/server/node_modules/cradle/node_modules/follow/node_modules/request/tests/test-oauth.js +109 -0
  83. data/server/node_modules/cradle/node_modules/follow/node_modules/request/tests/test-pipes.js +167 -0
  84. data/server/node_modules/cradle/node_modules/follow/node_modules/request/tests/test-proxy.js +39 -0
  85. data/server/node_modules/cradle/node_modules/follow/node_modules/request/tests/test-timeout.js +87 -0
  86. data/server/node_modules/cradle/node_modules/follow/node_modules/request/uuid.js +19 -0
  87. data/server/node_modules/cradle/node_modules/follow/node_modules/request/vendor/cookie/index.js +55 -0
  88. data/server/node_modules/cradle/node_modules/follow/node_modules/request/vendor/cookie/jar.js +72 -0
  89. data/server/node_modules/cradle/node_modules/follow/package.json +45 -0
  90. data/server/node_modules/cradle/node_modules/follow/test/couch.js +153 -0
  91. data/server/node_modules/cradle/node_modules/follow/test/follow.js +136 -0
  92. data/server/node_modules/cradle/node_modules/follow/test/issues.js +178 -0
  93. data/server/node_modules/cradle/node_modules/follow/test/issues/10.js +24 -0
  94. data/server/node_modules/cradle/node_modules/follow/test/stream.js +493 -0
  95. data/server/node_modules/cradle/node_modules/request/LICENSE +55 -0
  96. data/server/node_modules/cradle/node_modules/request/README.md +287 -0
  97. data/server/node_modules/cradle/node_modules/request/forever.js +103 -0
  98. data/server/node_modules/cradle/node_modules/request/main.js +913 -0
  99. data/server/node_modules/cradle/node_modules/request/mimetypes.js +152 -0
  100. data/server/node_modules/cradle/node_modules/request/oauth.js +34 -0
  101. data/server/node_modules/cradle/node_modules/request/package.json +42 -0
  102. data/server/node_modules/cradle/node_modules/request/tests/googledoodle.png +0 -0
  103. data/server/node_modules/cradle/node_modules/request/tests/run.js +38 -0
  104. data/server/node_modules/cradle/node_modules/request/tests/server.js +82 -0
  105. data/server/node_modules/cradle/node_modules/request/tests/squid.conf +77 -0
  106. data/server/node_modules/cradle/node_modules/request/tests/ssl/ca/ca.cnf +20 -0
  107. data/server/node_modules/cradle/node_modules/request/tests/ssl/ca/ca.crl +0 -0
  108. data/server/node_modules/cradle/node_modules/request/tests/ssl/ca/ca.crt +17 -0
  109. data/server/node_modules/cradle/node_modules/request/tests/ssl/ca/ca.csr +13 -0
  110. data/server/node_modules/cradle/node_modules/request/tests/ssl/ca/ca.key +18 -0
  111. data/server/node_modules/cradle/node_modules/request/tests/ssl/ca/ca.srl +1 -0
  112. data/server/node_modules/cradle/node_modules/request/tests/ssl/ca/server.cnf +19 -0
  113. data/server/node_modules/cradle/node_modules/request/tests/ssl/ca/server.crt +16 -0
  114. data/server/node_modules/cradle/node_modules/request/tests/ssl/ca/server.csr +11 -0
  115. data/server/node_modules/cradle/node_modules/request/tests/ssl/ca/server.js +28 -0
  116. data/server/node_modules/cradle/node_modules/request/tests/ssl/ca/server.key +9 -0
  117. data/server/node_modules/cradle/node_modules/request/tests/ssl/npm-ca.crt +16 -0
  118. data/server/node_modules/cradle/node_modules/request/tests/ssl/test.crt +15 -0
  119. data/server/node_modules/cradle/node_modules/request/tests/ssl/test.key +15 -0
  120. data/server/node_modules/cradle/node_modules/request/tests/test-body.js +95 -0
  121. data/server/node_modules/cradle/node_modules/request/tests/test-cookie.js +29 -0
  122. data/server/node_modules/cradle/node_modules/request/tests/test-cookiejar.js +90 -0
  123. data/server/node_modules/cradle/node_modules/request/tests/test-defaults.js +68 -0
  124. data/server/node_modules/cradle/node_modules/request/tests/test-errors.js +37 -0
  125. data/server/node_modules/cradle/node_modules/request/tests/test-headers.js +52 -0
  126. data/server/node_modules/cradle/node_modules/request/tests/test-httpModule.js +94 -0
  127. data/server/node_modules/cradle/node_modules/request/tests/test-https-strict.js +97 -0
  128. data/server/node_modules/cradle/node_modules/request/tests/test-https.js +86 -0
  129. data/server/node_modules/cradle/node_modules/request/tests/test-oauth.js +117 -0
  130. data/server/node_modules/cradle/node_modules/request/tests/test-params.js +92 -0
  131. data/server/node_modules/cradle/node_modules/request/tests/test-pipes.js +202 -0
  132. data/server/node_modules/cradle/node_modules/request/tests/test-proxy.js +39 -0
  133. data/server/node_modules/cradle/node_modules/request/tests/test-qs.js +28 -0
  134. data/server/node_modules/cradle/node_modules/request/tests/test-redirect.js +154 -0
  135. data/server/node_modules/cradle/node_modules/request/tests/test-timeout.js +87 -0
  136. data/server/node_modules/cradle/node_modules/request/tests/test-toJSON.js +14 -0
  137. data/server/node_modules/cradle/node_modules/request/tests/test-tunnel.js +61 -0
  138. data/server/node_modules/cradle/node_modules/request/tunnel.js +229 -0
  139. data/server/node_modules/cradle/node_modules/request/uuid.js +19 -0
  140. data/server/node_modules/cradle/node_modules/request/vendor/cookie/index.js +65 -0
  141. data/server/node_modules/cradle/node_modules/request/vendor/cookie/jar.js +72 -0
  142. data/server/node_modules/cradle/node_modules/vargs/package.json +33 -10
  143. data/server/node_modules/cradle/package.json +50 -12
  144. data/server/node_modules/cradle/test/cache-test.js +1 -4
  145. data/server/node_modules/cradle/test/connection-test.js +179 -0
  146. data/server/node_modules/cradle/test/database-attachment-test.js +344 -0
  147. data/server/node_modules/cradle/test/database-cache-test.js +132 -0
  148. data/server/node_modules/cradle/test/database-test.js +219 -0
  149. data/server/node_modules/cradle/test/database-view-test.js +141 -0
  150. data/server/node_modules/cradle/test/fixtures/databases.json +28 -1
  151. data/server/node_modules/cradle/test/helpers/seed.js +14 -5
  152. data/server/node_modules/cradle/test/response-test.js +1 -1
  153. data/server/node_modules/express/History.md +16 -0
  154. data/server/node_modules/express/bin/express +7 -6
  155. data/server/node_modules/express/lib-cov/application.js +510 -0
  156. data/server/node_modules/express/lib-cov/express.js +65 -0
  157. data/server/node_modules/express/lib-cov/middleware.js +54 -0
  158. data/server/node_modules/express/lib-cov/request.js +225 -0
  159. data/server/node_modules/express/lib-cov/response.js +611 -0
  160. data/server/node_modules/express/lib-cov/router/collection.js +40 -0
  161. data/server/node_modules/express/lib-cov/router/index.js +515 -0
  162. data/server/node_modules/express/lib-cov/router/methods.js +9 -0
  163. data/server/node_modules/express/lib-cov/router/route.js +68 -0
  164. data/server/node_modules/express/lib-cov/utils.js +151 -0
  165. data/server/node_modules/express/lib-cov/view.js +81 -0
  166. data/server/node_modules/express/lib/express.js +1 -1
  167. data/server/node_modules/express/lib/http.js +1 -2
  168. data/server/node_modules/express/lib/request.js +2 -2
  169. data/server/node_modules/express/lib/router/methods.js +10 -1
  170. data/server/node_modules/express/node_modules/connect/lib/connect.js +1 -1
  171. data/server/node_modules/express/node_modules/connect/lib/http.js +3 -2
  172. data/server/node_modules/express/node_modules/connect/lib/middleware/limit.js +0 -2
  173. data/server/node_modules/express/node_modules/connect/lib/middleware/session.js +1 -2
  174. data/server/node_modules/express/node_modules/connect/node_modules/formidable/Readme.md +42 -25
  175. data/server/node_modules/express/node_modules/connect/node_modules/formidable/lib/incoming_form.js +1 -0
  176. data/server/node_modules/express/node_modules/connect/node_modules/formidable/package.json +14 -3
  177. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-incoming-form.js +11 -0
  178. data/server/node_modules/express/node_modules/connect/package.json +35 -7
  179. data/server/node_modules/express/node_modules/mime/package.json +30 -8
  180. data/server/node_modules/express/node_modules/mkdirp/README.markdown +35 -2
  181. data/server/node_modules/express/node_modules/mkdirp/examples/pow.js +1 -1
  182. data/server/node_modules/express/node_modules/mkdirp/index.js +72 -13
  183. data/server/node_modules/express/node_modules/mkdirp/package.json +39 -21
  184. data/server/node_modules/express/node_modules/mkdirp/test/chmod.js +38 -0
  185. data/server/node_modules/express/node_modules/mkdirp/test/clobber.js +37 -0
  186. data/server/node_modules/express/node_modules/mkdirp/test/perm.js +32 -0
  187. data/server/node_modules/express/node_modules/mkdirp/test/perm_sync.js +39 -0
  188. data/server/node_modules/express/node_modules/mkdirp/test/sync.js +27 -0
  189. data/server/node_modules/express/node_modules/mkdirp/test/umask.js +28 -0
  190. data/server/node_modules/express/node_modules/mkdirp/test/umask_sync.js +27 -0
  191. data/server/node_modules/express/node_modules/qs/History.md +10 -0
  192. data/server/node_modules/express/node_modules/qs/Readme.md +9 -2
  193. data/server/node_modules/express/node_modules/qs/examples.js +3 -0
  194. data/server/node_modules/express/node_modules/qs/lib/querystring.js +8 -6
  195. data/server/node_modules/express/node_modules/qs/package.json +26 -8
  196. data/server/node_modules/express/node_modules/qs/test/parse.js +13 -1
  197. data/server/node_modules/express/node_modules/qs/test/stringify.js +45 -37
  198. data/server/node_modules/express/package.json +55 -16
  199. data/server/node_modules/express/test.js +41 -0
  200. data/server/node_modules/knox/package.json +26 -4
  201. data/server/node_modules/node-uuid/package.json +40 -11
  202. data/server/node_modules/node-uuid/test/test.js +1 -1
  203. data/server/node_modules/nodemon/README.md +120 -0
  204. data/server/node_modules/nodemon/nodemon.js +518 -0
  205. data/server/node_modules/nodemon/nodemonignore.example +11 -0
  206. data/server/node_modules/nodemon/package.json +49 -0
  207. data/server/node_modules/restler/README.md +144 -94
  208. data/server/node_modules/restler/lib/multipartform.js +2 -0
  209. data/server/node_modules/restler/lib/restler.js +218 -61
  210. data/server/node_modules/restler/package.json +35 -8
  211. data/server/node_modules/restler/test/all.js +6 -1
  212. data/server/node_modules/restler/test/restler.js +624 -118
  213. data/server/package.json +14 -10
  214. data/server/web.coffee +64 -0
  215. data/server/web.js +15 -3
  216. metadata +170 -57
  217. data/server/index.js +0 -14
  218. data/server/node_modules/connect-form/LICENSE +0 -22
  219. data/server/node_modules/connect-form/index.js +0 -100
  220. data/server/node_modules/connect-form/node_modules/formidable/test/fast/test-incoming-form.js +0 -45
  221. data/server/node_modules/connect-form/node_modules/formidable/test/fixture/http/no-filename/generic.http +0 -13
  222. data/server/node_modules/connect-form/node_modules/formidable/test/fixture/http/special-chars-in-filename/osx-chrome-13.http +0 -26
  223. data/server/node_modules/connect-form/node_modules/formidable/test/fixture/http/special-chars-in-filename/osx-firefox-3.6.http +0 -24
  224. data/server/node_modules/connect-form/node_modules/formidable/test/fixture/http/special-chars-in-filename/osx-safari-5.http +0 -23
  225. data/server/node_modules/connect-form/node_modules/formidable/test/fixture/http/special-chars-in-filename/xp-chrome-12.http +0 -24
  226. data/server/node_modules/connect-form/node_modules/formidable/test/fixture/http/special-chars-in-filename/xp-ie-7.http +0 -22
  227. data/server/node_modules/connect-form/node_modules/formidable/test/fixture/http/special-chars-in-filename/xp-ie-8.http +0 -22
  228. data/server/node_modules/connect-form/node_modules/formidable/test/fixture/http/special-chars-in-filename/xp-safari-5.http +0 -22
  229. data/server/node_modules/connect-form/node_modules/formidable/test/fixture/multi_video.upload +0 -0
  230. data/server/node_modules/cradle/Makefile +0 -10
  231. data/server/node_modules/cradle/test/cradle-test.js +0 -650
  232. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/no-filename/generic.http +0 -13
  233. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/osx-chrome-13.http +0 -26
  234. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/osx-firefox-3.6.http +0 -24
  235. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/osx-safari-5.http +0 -23
  236. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/xp-chrome-12.http +0 -24
  237. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/xp-ie-7.http +0 -22
  238. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/xp-ie-8.http +0 -22
  239. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/xp-safari-5.http +0 -22
  240. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/multi_video.upload +0 -0
  241. data/server/node_modules/express/node_modules/connect/test.js +0 -52
  242. data/server/node_modules/express/testing/foo/app.js +0 -35
  243. data/server/node_modules/express/testing/foo/package.json +0 -9
  244. data/server/node_modules/express/testing/foo/public/stylesheets/style.css +0 -8
  245. data/server/node_modules/express/testing/foo/routes/index.js +0 -10
  246. data/server/node_modules/express/testing/foo/views/index.jade +0 -2
  247. data/server/node_modules/express/testing/foo/views/layout.jade +0 -6
  248. data/server/node_modules/express/testing/index.js +0 -43
  249. data/server/node_modules/express/testing/public/test.txt +0 -2971
  250. data/server/node_modules/express/testing/views/page.html +0 -1
  251. data/server/node_modules/express/testing/views/page.jade +0 -3
  252. data/server/node_modules/express/testing/views/test.md +0 -1
  253. data/server/node_modules/express/testing/views/user/index.jade +0 -1
  254. data/server/node_modules/express/testing/views/user/list.jade +0 -1
  255. data/server/node_modules/knox/lib/knox/mime/index.js +0 -308
  256. data/server/node_modules/knox/lib/knox/mime/test.js +0 -59
  257. data/server/node_modules/node-uuid/test/benchmark-native +0 -0
  258. data/server/node_modules/on/index.js +0 -13
  259. data/server/node_modules/restler/test/test_helper.js +0 -163
  260. data/server/node_modules/spawner/index.js +0 -106
@@ -247,6 +247,7 @@ IncomingForm.prototype._parseContentLength = function() {
247
247
  if (this.headers['content-length']) {
248
248
  this.bytesReceived = 0;
249
249
  this.bytesExpected = parseInt(this.headers['content-length'], 10);
250
+ this.emit('progress', this.bytesReceived, this.bytesExpected);
250
251
  }
251
252
  };
252
253
 
@@ -359,7 +360,10 @@ IncomingForm.prototype._uploadPath = function(filename) {
359
360
  }
360
361
 
361
362
  if (this.keepExtensions) {
362
- name += path.extname(filename);
363
+ var ext = path.extname(filename);
364
+ ext = ext.replace(/(\.[a-z0-9]+).*/, '$1')
365
+
366
+ name += ext;
363
367
  }
364
368
 
365
369
  return path.join(this.uploadDir, name);
@@ -1,19 +1,33 @@
1
1
  {
2
2
  "name": "formidable",
3
- "version": "1.0.6",
3
+ "version": "1.0.9",
4
4
  "dependencies": {},
5
5
  "devDependencies": {
6
6
  "gently": "0.8.0",
7
- "far": "0.0.7",
8
- "fast-or-slow": "0.0.5",
9
7
  "findit": "0.1.1",
10
- "hashish": "0.0.4"
8
+ "hashish": "0.0.4",
9
+ "urun": "0.0.4",
10
+ "utest": "0.0.3"
11
11
  },
12
12
  "directories": {
13
13
  "lib": "./lib"
14
14
  },
15
15
  "main": "./lib/index",
16
+ "scripts": {
17
+ "test": "make test"
18
+ },
16
19
  "engines": {
17
20
  "node": "*"
18
- }
19
- }
21
+ },
22
+ "_npmUser": {
23
+ "name": "ddollar",
24
+ "email": "ddollar@gmail.com"
25
+ },
26
+ "_id": "formidable@1.0.9",
27
+ "optionalDependencies": {},
28
+ "_engineSupported": true,
29
+ "_npmVersion": "1.1.21",
30
+ "_nodeVersion": "v0.6.17",
31
+ "_defaultsLoaded": true,
32
+ "_from": "formidable@>= 0.9.3"
33
+ }
@@ -3,17 +3,16 @@ var path = require('path');
3
3
 
4
4
  var root = path.join(__dirname, '../');
5
5
  exports.dir = {
6
- root: root,
7
- lib: root + '/lib',
8
- fixture: root + '/test/fixture',
9
- tmp: root + '/test/tmp',
6
+ root : root,
7
+ lib : root + '/lib',
8
+ fixture : root + '/test/fixture',
9
+ tmp : root + '/test/tmp',
10
10
  };
11
11
 
12
12
  exports.port = 13532;
13
13
 
14
14
  exports.formidable = require('..');
15
- exports.fastOrSlow = require('fast-or-slow');
16
- exports.assert = require('assert');
15
+ exports.assert = require('assert');
17
16
 
18
17
  exports.require = function(lib) {
19
18
  return require(exports.dir.lib + '/' + lib);
@@ -1,4 +1,4 @@
1
- var properFilename = '/ \\ ? % * | " < > . ☃ ; \' @ # $ ^ & ( ) - _ = + { } [ ] ` ~.txt';
1
+ var properFilename = 'funkyfilename.txt';
2
2
 
3
3
  function expect(filename) {
4
4
  return [
@@ -7,47 +7,52 @@ var net = require('net');
7
7
  var assert = require('assert');
8
8
 
9
9
  var common = require('../common');
10
- var test = common.fastOrSlow.slow();
11
10
  var formidable = common.formidable;
12
11
 
13
- var server;
14
- test.before(function(done) {
15
- if (server) return done();
12
+ var server = http.createServer();
13
+ server.listen(common.port, findFixtures);
16
14
 
17
- server = http.createServer();
18
- server.listen(common.port, done);
19
- });
15
+ function findFixtures() {
16
+ var fixtures = [];
17
+ findit
18
+ .sync(common.dir.fixture + '/js')
19
+ .forEach(function(jsPath) {
20
+ if (!/\.js$/.test(jsPath)) return;
20
21
 
21
- findit
22
- .sync(common.dir.fixture + '/js')
23
- .forEach(function(jsPath) {
24
- if (!/\.js$/.test(jsPath)) return;
25
-
26
- var group = path.basename(jsPath, '.js');
27
- hashish.forEach(require(jsPath), function(fixture, name) {
28
- addTest(group + '/' + name, fixture);
22
+ var group = path.basename(jsPath, '.js');
23
+ hashish.forEach(require(jsPath), function(fixture, name) {
24
+ fixtures.push({
25
+ name : group + '/' + name,
26
+ fixture : fixture,
27
+ });
28
+ });
29
29
  });
30
- });
31
30
 
32
- function addTest(name, fixture) {
33
- test('fixture: ' + name, function(done) {
34
- console.error(this.name);
35
- uploadFixture(name, function(err, parts) {
36
- if (err) return done(err);
37
-
38
- fixture.forEach(function(expectedPart, i) {
39
- var parsedPart = parts[i];
40
- assert.equal(parsedPart.type, expectedPart.type);
41
- assert.equal(parsedPart.name, expectedPart.name);
42
-
43
- if (parsedPart.type === 'file') {
44
- var filename = parsedPart.value.name;
45
- assert.equal(filename, expectedPart.filename);
46
- }
47
- });
31
+ testNext(fixtures);
32
+ }
48
33
 
49
- done();
34
+ function testNext(fixtures) {
35
+ var fixture = fixtures.shift();
36
+ if (!fixture) return server.close();
37
+
38
+ var name = fixture.name;
39
+ var fixture = fixture.fixture;
40
+
41
+ uploadFixture(name, function(err, parts) {
42
+ if (err) throw err;
43
+
44
+ fixture.forEach(function(expectedPart, i) {
45
+ var parsedPart = parts[i];
46
+ assert.equal(parsedPart.type, expectedPart.type);
47
+ assert.equal(parsedPart.name, expectedPart.name);
48
+
49
+ if (parsedPart.type === 'file') {
50
+ var filename = parsedPart.value.name;
51
+ assert.equal(filename, expectedPart.filename);
52
+ }
50
53
  });
54
+
55
+ testNext(fixtures);
51
56
  });
52
57
  };
53
58
 
@@ -372,15 +372,26 @@ test(function parseContentLength() {
372
372
 
373
373
  form.headers = {};
374
374
  form._parseContentLength();
375
+ assert.strictEqual(form.bytesReceived, null);
375
376
  assert.strictEqual(form.bytesExpected, null);
376
377
 
377
378
  form.headers['content-length'] = '8';
379
+ gently.expect(form, 'emit', function(event, bytesReceived, bytesExpected) {
380
+ assert.equal(event, 'progress');
381
+ assert.equal(bytesReceived, 0);
382
+ assert.equal(bytesExpected, 8);
383
+ });
378
384
  form._parseContentLength();
379
385
  assert.strictEqual(form.bytesReceived, 0);
380
386
  assert.strictEqual(form.bytesExpected, 8);
381
387
 
382
388
  // JS can be evil, lets make sure we are not
383
389
  form.headers['content-length'] = '08';
390
+ gently.expect(form, 'emit', function(event, bytesReceived, bytesExpected) {
391
+ assert.equal(event, 'progress');
392
+ assert.equal(bytesReceived, 0);
393
+ assert.equal(bytesExpected, 8);
394
+ });
384
395
  form._parseContentLength();
385
396
  assert.strictEqual(form.bytesExpected, 8);
386
397
  });
@@ -1,7 +1,2 @@
1
1
  #!/usr/bin/env node
2
- var far = require('far').create();
3
-
4
- far.add(__dirname);
5
- far.include(/test-.*\.js$/);
6
-
7
- far.execute();
2
+ require('urun')(__dirname)
@@ -0,0 +1,63 @@
1
+ var common = require('../common');
2
+ var test = require('utest');
3
+ var assert = common.assert;
4
+ var IncomingForm = common.require('incoming_form').IncomingForm;
5
+ var path = require('path');
6
+
7
+ var from;
8
+ test('IncomingForm', {
9
+ before: function() {
10
+ form = new IncomingForm();
11
+ },
12
+
13
+ '#_fileName with regular characters': function() {
14
+ var filename = 'foo.txt';
15
+ assert.equal(form._fileName(makeHeader(filename)), 'foo.txt');
16
+ },
17
+
18
+ '#_fileName with unescaped quote': function() {
19
+ var filename = 'my".txt';
20
+ assert.equal(form._fileName(makeHeader(filename)), 'my".txt');
21
+ },
22
+
23
+ '#_fileName with escaped quote': function() {
24
+ var filename = 'my%22.txt';
25
+ assert.equal(form._fileName(makeHeader(filename)), 'my".txt');
26
+ },
27
+
28
+ '#_fileName with bad quote and additional sub-header': function() {
29
+ var filename = 'my".txt';
30
+ var header = makeHeader(filename) + '; foo="bar"';
31
+ assert.equal(form._fileName(header), filename);
32
+ },
33
+
34
+ '#_fileName with semicolon': function() {
35
+ var filename = 'my;.txt';
36
+ assert.equal(form._fileName(makeHeader(filename)), 'my;.txt');
37
+ },
38
+
39
+ '#_fileName with utf8 character': function() {
40
+ var filename = 'my&#9731;.txt';
41
+ assert.equal(form._fileName(makeHeader(filename)), 'my☃.txt');
42
+ },
43
+
44
+ '#_uploadPath strips harmful characters from extension when keepExtensions': function() {
45
+ form.keepExtensions = true;
46
+
47
+ var ext = path.extname(form._uploadPath('fine.jpg?foo=bar'));
48
+ assert.equal(ext, '.jpg');
49
+
50
+ var ext = path.extname(form._uploadPath('fine?foo=bar'));
51
+ assert.equal(ext, '');
52
+
53
+ var ext = path.extname(form._uploadPath('super.cr2+dsad'));
54
+ assert.equal(ext, '.cr2');
55
+
56
+ var ext = path.extname(form._uploadPath('super.bar'));
57
+ assert.equal(ext, '.bar');
58
+ },
59
+ });
60
+
61
+ function makeHeader(filename) {
62
+ return 'Content-Disposition: form-data; name="upload"; filename="' + filename + '"';
63
+ }
@@ -1,9 +1,31 @@
1
1
  {
2
2
  "name": "connect-form",
3
3
  "description": "urlencoded / multipart form parsing middleware for Connect",
4
- "version": "0.2.1",
5
- "author": "TJ Holowaychuk <tj@vision-media.ca>",
6
- "dependencies": { "formidable": ">= 0.9.3" },
4
+ "version": "0.2.0",
5
+ "author": {
6
+ "name": "TJ Holowaychuk",
7
+ "email": "tj@vision-media.ca"
8
+ },
9
+ "dependencies": {
10
+ "formidable": ">= 0.9.3"
11
+ },
7
12
  "main": "./index.js",
8
- "engines": { "node": ">= 0.1.98" }
9
- }
13
+ "engines": {
14
+ "node": ">= 0.1.98"
15
+ },
16
+ "_npmUser": {
17
+ "name": "ddollar",
18
+ "email": "ddollar@gmail.com"
19
+ },
20
+ "_id": "connect-form@0.2.0",
21
+ "devDependencies": {},
22
+ "optionalDependencies": {},
23
+ "_engineSupported": true,
24
+ "_npmVersion": "1.1.21",
25
+ "_nodeVersion": "v0.6.17",
26
+ "_defaultsLoaded": true,
27
+ "dist": {
28
+ "shasum": "bb11f2830116945b27bf4aaa840f7d3d11521b76"
29
+ },
30
+ "_from": "connect-form@0.2.0"
31
+ }
@@ -112,7 +112,7 @@ You can check if a database exists with the `exists()` method.
112
112
 
113
113
  ``` js
114
114
  db.get('vader', function (err, doc) {
115
- sys.puts(doc);
115
+ console.log(doc);
116
116
  });
117
117
  ```
118
118
 
@@ -129,8 +129,7 @@ Cradle is also able to fetch multiple documents if you have a list of ids, just
129
129
  ``` js
130
130
  db.view('characters/all', function (err, res) {
131
131
  res.forEach(function (row) {
132
- sys.puts(row.name + " is on the " +
133
- row.force + " side of the force.");
132
+ console.log("%s is on the %s side of the force.", row.name, row.force);
134
133
  });
135
134
  });
136
135
  ```
@@ -331,18 +330,17 @@ the affected documents, simply pass `include_docs: true` in the options.
331
330
 
332
331
  ### Streaming #
333
332
 
334
- You can also *stream* changes, by calling `db.changes` without the callback:
333
+ You can also *stream* changes, by calling `db.changes` without the callback. This API uses the **excellent** [follow][0] library from [IrisCouch][1]:
335
334
 
336
335
  ``` js
337
- db.changes({ since: 42 }).on('response', function (res) {
338
- res.on('data', function (change) {
339
- console.log(change);
340
- });
341
- res.on('end', function () { ... });
336
+ var feed = db.changes({ since: 42 });
337
+
338
+ feed.on('change', function (change) {
339
+ console.log(change);
342
340
  });
343
341
  ```
344
342
 
345
- In this case, it returns an `EventEmitter`, which behaves very similarly to node's `Stream` API.
343
+ In this case, it returns an instance of `follow.Feed`, which behaves very similarly to node's `EventEmitter` API. For full documentation on the options available to you when monitoring CouchDB with `.changes()` see the [follow documentation][0].
346
344
 
347
345
 
348
346
  Other API methods
@@ -375,3 +373,5 @@ Other API methods
375
373
  - `viewCleanup()`: Cleanup old view data
376
374
  - `replicate(target, options)`: Replicate this database to `target`.
377
375
 
376
+ [0]: https://github.com/iriscouch/follow
377
+ [1]: http://iriscouch.com
@@ -1,19 +1,18 @@
1
- var path = require('path'),
2
- http = require("http"),
3
- https = require("https"),
4
- events = require('events'),
5
- fs = require("fs"),
6
- url = require('url'),
7
- buffer = require('buffer');
8
-
9
- var querystring = require('querystring');
10
- var Args = require('vargs').Constructor;
1
+ var events = require('events'),
2
+ fs = require('fs'),
3
+ path = require('path'),
4
+ url = require('url'),
5
+ http = require('http'),
6
+ https = require('https'),
7
+ querystring = require('querystring'),
8
+ request = require('request');
11
9
 
12
10
  var cradle = exports;
13
11
 
14
12
  cradle.extend = require('./cradle/response').extend;
15
13
  cradle.Response = require('./cradle/response').Response;
16
14
  cradle.Cache = require('./cradle/cache').Cache;
15
+ cradle.Database = require('./cradle/database').Database;
17
16
 
18
17
  cradle.host = '127.0.0.1';
19
18
  cradle.port = 5984;
@@ -29,7 +28,7 @@ cradle.options = {
29
28
  cradle.setup = function (settings) {
30
29
  this.host = settings.host;
31
30
  this.auth = settings.auth;
32
- this.port = parseInt(settings.port);
31
+ this.port = parseInt(settings.port, 10);
33
32
  cradle.merge(this.options, settings);
34
33
 
35
34
  return this;
@@ -39,7 +38,12 @@ var protocolPattern = /^(https?):\/\//;
39
38
 
40
39
  cradle.Connection = function Connection(/* variable args */) {
41
40
  var args = Array.prototype.slice.call(arguments),
42
- host, port, remote, auth, options = {};
41
+ options = {},
42
+ remote,
43
+ match,
44
+ host,
45
+ port,
46
+ auth;
43
47
 
44
48
  args.forEach(function (a) {
45
49
  if (typeof(a) === 'number' || (typeof(a) === 'string' && /^\d{2,5}$/.test(a))) {
@@ -51,6 +55,11 @@ cradle.Connection = function Connection(/* variable args */) {
51
55
  auth = options.auth;
52
56
  } else {
53
57
  host = a;
58
+
59
+ if (match = host.match(/^(.+)\:(\d{2,5})$/)) {
60
+ host = match[1];
61
+ port = parseInt(match[2]);
62
+ }
54
63
  }
55
64
  });
56
65
 
@@ -76,8 +85,8 @@ cradle.Connection = function Connection(/* variable args */) {
76
85
  console.log('Warning: "ssl" option is deprecated. Use "secure" instead.');
77
86
  }
78
87
 
79
- this.socket = (this.options.secure) ? https : http;
80
- this.agent = new (this.socket.Agent)({
88
+ this.transport = (this.options.secure) ? https : http;
89
+ this.agent = new (this.transport.Agent)({
81
90
  host: this.host,
82
91
  port: this.port
83
92
  });
@@ -93,85 +102,41 @@ cradle.Connection = function Connection(/* variable args */) {
93
102
  // JSON serialization and does not presuppose it is sending or receiving JSON
94
103
  // content
95
104
  //
96
- cradle.Connection.prototype.rawRequest = function (method, path, options, data, headers) {
97
- var promise = new(events.EventEmitter), request, that = this;
105
+ // OLDAPI: function (method, path, options, data, headers)
106
+ //
107
+ cradle.Connection.prototype.rawRequest = function (options, callback) {
108
+ var promise = new(events.EventEmitter),
109
+ self = this;
98
110
 
99
111
  // HTTP Headers
100
- headers = headers || {};
112
+ options.headers = options.headers || {};
101
113
 
102
114
  // Set HTTP Basic Auth
103
115
  if (this.auth) {
104
- headers['Authorization'] = "Basic " + new Buffer(this.auth.username + ':' + this.auth.password).toString('base64');
116
+ options.headers['Authorization'] = "Basic " + new Buffer(this.auth.username + ':' + this.auth.password).toString('base64');
105
117
  }
106
118
 
107
119
  // Set client-wide headers
108
- for (var h in this.options.headers) {
109
- headers[h] = this.options.headers[h];
110
- }
111
-
112
- path = (path || '/').replace(/https?:\/\//, '').replace(/\/{2,}/g, '/');
113
- if (path.charAt(0) !== '/') { path = '/' + path }
114
-
115
- if (options && Object.keys(options).length) {
116
- for (var k in options) {
117
- if (typeof(options[k]) === 'boolean') {
118
- options[k] = String(options[k]);
120
+ Object.keys(this.options.headers).forEach(function (header) {
121
+ options.headers[header] = self.options.headers[header];
122
+ });
123
+
124
+ if (options.query && Object.keys(options.query).length) {
125
+ for (var k in options.query) {
126
+ if (typeof(options.query[k]) === 'boolean') {
127
+ options.query[k] = String(options.query[k]);
119
128
  }
120
129
  }
121
- path += '?' + querystring.stringify(options);
130
+ options.path += '?' + querystring.stringify(options.query);
122
131
  }
123
132
 
124
- //
125
- // ** Remark (indexzero): ** Keep-alive is causing unexpected hangups in tests
126
- // removing it temporarily as we move forward towards a `request` based implementation.
127
- //
128
- // if (headers['Connection'] === undefined) {
129
- // // Keep the connection alive but set timeout to close the socket after 5 seconds of inactivity
130
- // headers['Connection'] = 'keep-alive';
131
- // if (this.connectionTimeout !== undefined) {
132
- // clearTimeout(this.connectionTimeout);
133
- // }
134
- // this.connectionTimeout = setTimeout(function () {
135
- // that.close();
136
- // }, 5000);
137
- // }
138
-
139
- request = this.socket.request({
140
- agent: this.agent,
141
- host: this.host,
142
- port: this.port,
143
- method: method.toUpperCase(),
144
- path: path,
145
- headers: headers
146
- });
147
-
148
- if (data && data.on) { headers['Transfer-Encoding'] = 'chunked' }
149
-
150
- request.on('response', function (res) {
151
- promise.emit('response', res);
152
- res.on('data', function (chunk) { promise.emit('data', chunk) });
153
- res.on('end', function () { promise.emit('end') });
154
- });
155
- request.on('error', function (err) {
156
- promise.emit('error', err);
157
- promise.emit('end');
158
- });
159
-
133
+ options.headers['Connection'] = options.headers['Connection'] || 'keep-alive';
134
+ options.agent = this.agent;
135
+ options.uri = this._url(options.path);
136
+ delete options.path;
160
137
 
161
- if (data) {
162
- if (data.on) {
163
- data.on('data', function (chunk) { request.write(chunk) });
164
- data.on('end', function () { request.end() });
165
- } else {
166
- request.write(data, 'utf8');
167
- request.end();
168
- }
169
- } else {
170
- request.end();
171
- }
172
-
173
- return promise;
174
- }
138
+ return request(options, callback || function () { });
139
+ };
175
140
 
176
141
  //
177
142
  // Connection.close()
@@ -190,74 +155,50 @@ cradle.Connection.prototype.close = function () {
190
155
  // This is the entry point for all requests to CouchDB, at this point,
191
156
  // the database name has been embed in the url, by one of the wrappers.
192
157
  //
193
- cradle.Connection.prototype.request = function (method, path, /* [options], [data], [headers] */ callback) {
194
- var request, that = this, args = Array.prototype.slice.call(arguments, 2);
195
-
196
- if (typeof(callback = args.pop()) !== 'function') {
197
- args.push(callback);
198
- callback = function () {};
199
- }
200
-
201
- var options = args.shift() || {},
202
- data = args.shift() || null,
203
- headers = cradle.merge({ host: this.host }, args.shift() || {});
158
+ cradle.Connection.prototype.request = function (options, callback) {
159
+ var headers = cradle.merge({ host: this.host }, options.headers || {}),
160
+ self = this;
204
161
 
162
+ // HTTP Headers
163
+ options.headers = options.headers || {};
164
+
205
165
  //
206
166
  // Handle POST/PUT data. We also convert functions to strings,
207
167
  // so they can be used in _design documents.
208
168
  //
209
- if (data) {
210
- data = JSON.stringify(data, function (k, val) {
169
+ if (options.body) {
170
+ options.body = JSON.stringify(options.body, function (k, val) {
211
171
  if (typeof(val) === 'function') {
212
172
  return val.toString();
213
173
  } else { return val }
214
174
  });
215
- headers["Content-Length"] = Buffer.byteLength(data);
216
- headers["Content-Type"] = "application/json";
217
- }
218
-
219
- if (typeof headers["Content-Length"] === 'undefined') {
220
- headers["Content-Length"] = 0;
175
+ options.headers["Content-Length"] = Buffer.byteLength(options.body);
176
+ options.headers["Content-Type"] = "application/json";
221
177
  }
222
178
 
223
- request = this.rawRequest(method, path, options, data, headers);
224
-
225
- //
226
- // Initialize the request, send the body, and finally,
227
- // dispatch the request.
228
- //
229
- request.on('response', function (res) {
230
- var body = [];
231
-
232
- res.setEncoding('utf8');
233
- res.on('data', function (chunk) {
234
- chunk && body.push(chunk);
235
- }).on('end', function () {
236
- var json, response;
237
-
238
- if (method === 'HEAD') {
239
- callback(null, res.headers, res.statusCode);
240
- } else {
241
- try { json = JSON.parse(body.join('')) }
242
- catch (e) { return callback(e) }
243
-
244
-
245
- if (json.error) {
246
- cradle.extend(json, { headers: res.headers });
247
- json.headers.status = res.statusCode;
248
- callback(json);
249
- } else {
250
- // If the `raw` option was set, we return the parsed
251
- // body as-is. If not, we wrap it in a `Response` object.
252
- callback(null, that.options.raw ? json : new(cradle.Response)(json, res));
253
- }
254
- }
255
- }).on('error', function (err) {
256
- return callback(err);
257
- });
258
- });
259
- request.on('error', function (err) {
260
- return callback(err);
179
+ return this.rawRequest(options, function (err, res, body) {
180
+ if (err) {
181
+ return callback(err);
182
+ }
183
+ else if (options.method === 'HEAD') {
184
+ return callback(null, res.headers, res.statusCode);
185
+ }
186
+ else if (body && body.error) {
187
+ cradle.extend(body, { headers: res.headers });
188
+ body.headers.status = res.statusCode;
189
+ return callback(body);
190
+ }
191
+
192
+ try { body = JSON.parse(body) }
193
+ catch (err) { }
194
+
195
+ if (body && body.error) {
196
+ cradle.extend(body, { headers: res.headers });
197
+ body.headers.status = res.statusCode;
198
+ return callback(body);
199
+ }
200
+
201
+ callback(null, self.options.raw ? body : new cradle.Response(body, res));
261
202
  });
262
203
  };
263
204
 
@@ -268,406 +209,59 @@ cradle.Connection.prototype.request = function (method, path, /* [options], [dat
268
209
  // closing around the `name` argument.
269
210
  //
270
211
  cradle.Connection.prototype.database = function (name) {
271
- var that = this, connection = this;
272
-
273
- return {
274
- name: encodeURIComponent(name),
275
- //
276
- // The database document cache.
277
- //
278
- cache: new(cradle.Cache)(that.options),
279
-
280
- // A wrapper around `Connection.request`,
281
- // which prepends the database name.
282
- query: function (method, path /* [options], [data], [headers], [callback] */) {
283
- var args = Array.prototype.slice.call(arguments, 2);
284
- that.request.apply(that, [method, [name, path].join('/')].concat(args));
285
- },
286
- exists: function (callback) {
287
- this.query('HEAD', '', function (err, res, status) {
288
- if (err) {
289
- callback(err);
290
- } else {
291
- if (status === 404) {
292
- callback(null, false);
293
- } else {
294
- callback(null, true);
295
- }
296
- }
297
- });
298
- },
299
-
300
- // Fetch either a single document from the database, or cache,
301
- // or multiple documents from the database.
302
- // If it's a single doc from the db, attempt to save it to the cache.
303
- get: function (id, rev) {
304
- var that = this, options = null,
305
- args = new(Args)(arguments);
306
-
307
- if (Array.isArray(id)) { // Bulk GET
308
- this.query('POST', '/_all_docs', { include_docs: true }, { keys: id },
309
- function (err, res) { args.callback(err, res) });
310
- } else {
311
- if (rev && args.length === 2) {
312
- if (typeof(rev) === 'string') { options = { rev: rev } }
313
- else if (typeof(rev) === 'object') { options = rev }
314
- } else if (this.cache.has(id)) {
315
- return args.callback(null, this.cache.get(id));
316
- }
317
- this.query('GET', cradle.escape(id), options, function (err, res) {
318
- if (! err) that.cache.save(res.id, res.json);
319
- args.callback(err, res);
320
- });
321
- }
322
- },
323
-
324
- save: function (/* [id], [rev], doc | [doc, ...] */) {
325
- var args = new(Args)(arguments),
326
- array = args.all.slice(0), doc, id, rev;
327
-
328
- if (Array.isArray(args.first)) {
329
- doc = args.first;
330
- } else {
331
- doc = array.pop(),
332
- id = array.shift(),
333
- rev = array.shift();
334
- }
335
- this._save(id, rev, doc, args.callback);
336
- },
337
- _save: function (id, rev, doc, callback) {
338
- var options = connection.options;
339
- var document = {}, that = this;
340
-
341
- // Bulk Insert
342
- if (Array.isArray(doc)) {
343
- document.docs = doc;
344
- if (options.allOrNothing) { document.all_or_nothing = true }
345
- this.query('POST', '/_bulk_docs', {}, document, callback);
346
- } else {
347
- // PUT a single document, with an id (Create or Update)
348
- if (id) {
349
- // Design document
350
- if (/^_design\/(\w|%|\-)+$/.test(id) && !('views' in doc)) {
351
- document.language = "javascript";
352
- document.views = doc;
353
- } else {
354
- document = doc;
355
- }
356
- // Try to set the '_rev' attribute of the document.
357
- // If it wasn't passed, attempt to retrieve it from the cache.
358
- rev && (document._rev = rev);
359
-
360
- if (document._rev) {
361
- this.put(id, document, callback);
362
- } else if (this.cache.has(id)) {
363
- document._rev = this.cache.get(id)._rev;
364
- this.put(id, document, callback);
365
- } else {
366
- // Attempt to create a new document. If it fails,
367
- // because an existing document with that _id exists (409),
368
- // perform a HEAD, to get the _rev, and try to re-save.
369
- this.put(id, document, function (e, res) {
370
- if (e && e.headers && e.headers.status === 409) { // Conflict
371
- that.head(id, function (e, headers, res) {
372
- if (res === 404 || !headers['etag']) {
373
- return callback({ reason: 'not_found' });
374
- }
375
-
376
- document._rev = headers['etag'].slice(1, -1);
377
- that.put(id, document, callback);
378
- });
379
- } else { callback(e, res) }
380
- });
381
- }
382
- // POST a single document, without an id (Create)
383
- } else {
384
- this.post(doc, callback);
385
- }
386
- }
387
- },
388
-
389
- merge: function (/* [id], doc */) {
390
- var args = Array.prototype.slice.call(arguments),
391
- callback = args.pop(),
392
- doc = args.pop(),
393
- id = args.pop() || doc._id;
394
-
395
- this._merge(id, doc, callback);
396
- },
397
- _merge: function (id, doc, callback) {
398
- var that = this;
399
- this.get(id, function (e, res) {
400
- if (e) { return callback(e) }
401
- doc = cradle.merge({}, res.json || res, doc);
402
- that.save(id, res._rev, doc, callback);
403
- });
404
- },
405
-
406
- //
407
- // PUT a document, and write through cache
408
- //
409
- put: function (id, doc, callback) {
410
- var cache = this.cache;
411
- if (typeof(id) !== 'string') { throw new(TypeError)("id must be a string") }
412
- this.query('PUT', cradle.escape(id), null, doc, function (e, res) {
413
- if (! e) { cache.save(id, cradle.merge({}, doc, { _id: id, _rev: res.rev })) }
414
- callback && callback(e, res);
415
- });
416
- },
417
-
418
- //
419
- // POST a document, and write through cache
420
- //
421
- post: function (doc, callback) {
422
- var cache = this.cache;
423
- this.query('POST', '/', null, doc, function (e, res) {
424
- if (! e) { cache.save(res.id, cradle.merge({}, doc, { _id: res.id, _rev: res.rev })) }
425
- callback && callback(e, res);
426
- });
427
- },
428
-
429
- //
430
- // Perform a HEAD request
431
- //
432
- head: function (id, callback) {
433
- this.query('HEAD', cradle.escape(id), null, callback);
434
- },
435
-
436
- insert: function () {
437
- throw new(Error)("`insert` is deprecated, use `save` instead");
438
- },
439
-
440
- replicate: function (target, options, callback) {
441
- if (typeof(options) === 'function') { callback = options, options = {} }
442
- that.replicate(cradle.merge({ source: name, target: target }, options), callback);
443
- },
444
-
445
- // Destroys a database with 'DELETE'
446
- // we raise an exception if arguments were supplied,
447
- // as we don't want users to confuse this function with `remove`.
448
- destroy: function (callback) {
449
- if (arguments.length > 1) {
450
- throw new(Error)("destroy() doesn't take any additional arguments");
451
- } else {
452
- this.query('DELETE', '/', callback);
453
- }
454
- },
455
-
456
- // Delete a document
457
- // if the _rev wasn't supplied, we attempt to retrieve it from the
458
- // cache. If the deletion was successful, we purge the cache.
459
- remove: function (id, rev) {
460
- var that = this, doc, args = new(Args)(arguments);
461
-
462
- if (typeof(rev) !== 'string') {
463
- if (doc = this.cache.get(id)) { rev = doc._rev }
464
- else { throw new(Error)("rev needs to be supplied") }
465
- }
466
- this.query('DELETE', cradle.escape(id), {rev: rev}, function (err, res) {
467
- if (! err) { that.cache.purge(id) }
468
- args.callback(err, res);
469
- });
470
- },
471
- create: function (callback) {
472
- this.query('PUT', '/', callback);
473
- },
474
- info: function (callback) {
475
- this.query('GET', '/', callback);
476
- },
477
- all: function (options, callback) {
478
- if (arguments.length === 1) { callback = options, options = {} }
479
- this.query('GET', '/_all_docs', options, callback);
480
- },
481
- compact: function (design) {
482
- var headers = {};
483
- headers['Content-Type'] = "application/json";
484
- this.query('POST', '/_compact' + (typeof(design) === 'string' ? '/' + querystring.escape(design) : ''),
485
- {}, {}, headers, Args.last(arguments));
486
- },
487
- viewCleanup: function (callback) {
488
- var headers = {};
489
- headers['Content-Type'] = "application/json";
490
- this.query('POST', '/_view_cleanup', {}, {}, headers, callback);
491
- },
492
- allBySeq: function (options) {
493
- options = typeof(options) === 'object' ? options : {};
494
- this.query('GET', '/_all_docs_by_seq', options, Args.last(arguments));
495
- },
496
-
497
- // Query a view, passing any options to the query string.
498
- // Some query string parameters' values have to be JSON-encoded.
499
- view: function (path, options) {
500
- var args = new(Args)(arguments);
501
-
502
- path = path.split('/');
503
- path = ['_design', path[0], '_view', path[1]].map(querystring.escape).join('/');
504
-
505
- if (typeof(options) === 'object') {
506
- ['key', 'startkey', 'endkey'].forEach(function (k) {
507
- if (k in options) { options[k] = JSON.stringify(options[k]) }
508
- });
509
- }
510
-
511
- if (options && options.keys) {
512
- this.query('POST', path, {}, options, args.callback);
513
- } else {
514
- this.query('GET', path, options, args.callback);
515
- }
516
- },
517
-
518
- // Query a list, passing any options to the query string.
519
- // Some query string parameters' values have to be JSON-encoded.
520
- list: function (path, options) {
521
- var args = new(Args)(arguments);
522
- path = path.split('/');
523
-
524
- if (typeof(options) === 'object') {
525
- ['key', 'startkey', 'endkey'].forEach(function (k) {
526
- if (k in options) { options[k] = JSON.stringify(options[k]) }
527
- });
528
- }
529
- this.query('GET', ['_design', path[0], '_list', path[1], path[2]].map(querystring.escape).join('/'), options, args.callback);
530
- },
531
-
532
- update: function (path, id, options) {
533
- var args = new(Args)(arguments);
534
- path = path.split('/');
535
-
536
- if (id) {
537
- this.query('PUT', ['_design', path[0], '_update', path[1], id].map(querystring.escape).join('/'), options, args.callback);
538
- } else {
539
- this.query('POST', ['_design', path[0], '_update', path[1]].map(querystring.escape).join('/'), options, args.callback);
540
- }
541
- },
542
-
543
- push: function (doc) {},
544
-
545
- changes: function (options, callback) {
546
- var promise = new(events.EventEmitter);
547
-
548
- if (typeof(options) === 'function') { callback = options, options = {}; }
549
-
550
- if (callback) {
551
- this.query('GET', '_changes', options, callback);
552
- } else {
553
- options = options || {};
554
- options.feed = options.feed || 'continuous';
555
- options.heartbeat = options.heartbeat || 1000;
556
-
557
- that.rawRequest('GET', [name, '_changes'].join('/'), options).on('response', function (res) {
558
- var response = new(events.EventEmitter), buffer = [];
559
- res.setEncoding('utf8');
560
-
561
- response.statusCode = res.statusCode;
562
- response.headers = res.headers;
563
-
564
- promise.emit('response', response);
565
-
566
- res.on('data', function (chunk) {
567
- var end;
568
- if (~(end = chunk.indexOf('\n'))) {
569
- buffer.push(chunk.substr(0, ++end));
570
- buffer.length && response.emit('data', JSON.parse(buffer.join('')));
571
- buffer = [chunk.substr(end)];
572
- } else {
573
- buffer.push(chunk);
574
- }
575
- }).on('end', function () {
576
- response.emit('end');
577
- }).on('error', function (err) {
578
- reponse.emit('error', err);
579
- })
580
- }).on('error', function (err) {
581
- promise.emit('error', err);
582
- });
583
-
584
- return promise;
585
- }
586
- },
587
-
588
- saveAttachment: function (/* id, [rev], attachmentName, contentType, dataOrStream */) {
589
- var doc, pathname, headers = {}, response, body = [], resHeaders, error, db = this;
590
-
591
- var args = new(Args)(arguments), params = args.all;
592
-
593
- if (typeof(args.first) === 'object') { throw new(TypeError)("first argument must be a document id") }
594
-
595
- var id = params.shift(),
596
- dataOrStream = params.pop(),
597
- contentType = params.pop(),
598
- attachmentName = params.pop(),
599
- rev = params.pop();
600
-
601
- if (!rev && db.cache.has(id)) {
602
- doc = { rev: db.cache.get(id)._rev };
603
- } else if (rev) {
604
- doc = { rev: rev };
605
- } else {
606
- doc = {};
607
- }
608
-
609
- pathname = '/' + [name, id, attachmentName].map(querystring.escape).join('/');
610
- headers['Content-Type'] = contentType;
611
-
612
- that.rawRequest('PUT', pathname, doc, dataOrStream, headers)
613
- .on('response', function (res) { resHeaders = { status: res.statusCode } })
614
- .on('data', function (chunk) { body.push(chunk) })
615
- .on('end', function () {
616
- response = JSON.parse(body.join(''));
617
- response.headers = resHeaders;
618
-
619
- if (response.headers.status == 201) {
620
- if (db.cache.has(id)) {
621
- cached = db.cache.store[id].document;
622
- cached._rev = response.rev;
623
- cached._attachments = cached._attachments || {};
624
- cached._attachments[attachmentName] = { stub: true };
625
- }
626
- args.callback(null, response);
627
- } else {
628
- args.callback(response);
629
- }
630
- });
631
- },
632
-
633
- getAttachment: function (docId, attachmentName) {
634
- var pathname, req;
635
- pathname = '/' + [name, docId, attachmentName].map(querystring.escape).join('/');
636
- return that.rawRequest('GET', pathname);
637
- },
638
-
639
- temporaryView: function (doc, callback) {
640
- this.query('POST', '_temp_view', null, doc, callback);
641
- }
642
- }
212
+ return new cradle.Database(name, this)
643
213
  };
644
214
 
645
215
  //
646
216
  // Wrapper functions for the server API
647
217
  //
648
- cradle.Connection.prototype.databases = function (c) {
649
- this.request('GET', '/_all_dbs', c);
218
+ cradle.Connection.prototype.databases = function (callback) {
219
+ this.request({ path: '/_all_dbs' }, callback);
650
220
  };
651
- cradle.Connection.prototype.config = function (c) {
652
- this.request('GET', '/_config', c);
221
+ cradle.Connection.prototype.config = function (callback) {
222
+ this.request({ path: '/_config' }, callback);
653
223
  };
654
- cradle.Connection.prototype.info = function (c) {
655
- this.request('GET', '/', c);
224
+ cradle.Connection.prototype.info = function (callback) {
225
+ this.request({ path: '/' }, callback);
656
226
  };
657
- cradle.Connection.prototype.stats = function (c) {
658
- this.request('GET', '/_stats', c);
227
+ cradle.Connection.prototype.stats = function (callback) {
228
+ this.request({ path: '/_stats' }, callback);
659
229
  };
660
- cradle.Connection.prototype.activeTasks = function (c) {
661
- this.request('GET', '/_active_tasks', c);
230
+ cradle.Connection.prototype.activeTasks = function (callback) {
231
+ this.request({ path: '/_active_tasks' }, callback);
662
232
  };
663
233
  cradle.Connection.prototype.uuids = function (count, callback) {
664
- if (typeof(count) === 'function') { callback = count, count = null }
665
- this.request('GET', '/_uuids', count ? {count: count} : {}, callback);
234
+ if (typeof(count) === 'function') {
235
+ callback = count;
236
+ count = null;
237
+ }
238
+
239
+ this.request({
240
+ method: 'GET',
241
+ path: '/_uuids',
242
+ query: count ? { count: count } : {}
243
+ }, callback);
666
244
  };
667
245
  cradle.Connection.prototype.replicate = function (options, callback) {
668
- this.request('POST', '/_replicate', null, options, callback);
246
+ this.request({
247
+ method: 'POST',
248
+ path: '/_replicate',
249
+ query: options
250
+ }, callback);
669
251
  };
670
252
 
253
+ cradle.Connection.prototype._url = function (path) {
254
+ var url = (this.protocol || 'http') + '://' + this.host;
255
+
256
+ if (this.port !== 443 && this.port !== 80) {
257
+ url += ':' + this.port;
258
+ }
259
+
260
+ url += path[0] === '/' ? path : ('/' + path);
261
+
262
+ return url;
263
+ }
264
+
671
265
  cradle.escape = function (id) {
672
266
  return ['_design', '_changes', '_temp_view'].indexOf(id.split('/')[0]) === -1
673
267
  ? querystring.escape(id)
@@ -684,4 +278,4 @@ cradle.merge = function (target) {
684
278
  });
685
279
  });
686
280
  return target;
687
- }
281
+ };