vulcan 0.6.1 → 0.7.0

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 (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
+ };