├── .babelrc ├── .eslintignore ├── .eslintrc ├── .gitignore ├── .npmignore ├── .travis.yml ├── LICENSE ├── README.md ├── docs ├── ast │ └── source │ │ ├── index.js.json │ │ ├── utils │ │ └── url.js.json │ │ └── validate.js.json ├── badge.svg ├── class │ └── src │ │ └── index.js~Http.html ├── coverage.json ├── css │ ├── prettify-tomorrow.css │ └── style.css ├── dump.json ├── file │ └── src │ │ ├── index.js.html │ │ ├── utils │ │ └── url.js.html │ │ └── validate.js.html ├── identifiers.html ├── image │ ├── badge.svg │ ├── github.png │ └── search.png ├── index.html ├── package.json ├── script │ ├── inherited-summary.js │ ├── inner-link.js │ ├── manual.js │ ├── patch-for-local.js │ ├── prettify │ │ ├── Apache-License-2.0.txt │ │ └── prettify.js │ ├── pretty-print.js │ ├── search.js │ ├── search_index.js │ └── test-summary.js ├── source.html └── typedef │ └── index.html ├── esdoc.json ├── karma.conf.js ├── package.json ├── src ├── index.js ├── utils │ └── url.js └── validate.js ├── test ├── .eslintrc ├── api_test.js ├── execution_test.js ├── url_test.js └── validate_test.js └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015"] 3 | } 4 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | server.js 2 | ./dist/* 3 | ./__tests__/* 4 | karma.conf.js 5 | webpack.config.js 6 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "ecmaFeatures": { 4 | "blockBindings": true, 5 | "forOf": true, 6 | "destructuring": true, 7 | "defaultParams": true, 8 | "classes": true, 9 | "arrowFunctions": true, 10 | "templateStrings": true, 11 | "superInFunctions": true, 12 | "spread": true, 13 | "restParams": true, 14 | "objectLiteralComputedProperties": true, 15 | "objectLiteralDuplicateProperties": true, 16 | "objectLiteralShorthandMethods": true, 17 | "objectLiteralShorthandProperties": true, 18 | "modules": true 19 | }, 20 | "env": { 21 | "browser": true, 22 | "node": true, 23 | "es6": true 24 | }, 25 | "rules": { 26 | "strict": 0, 27 | "semi": [2, "never"], 28 | "comma-dangle": [2, "never"], 29 | "no-constant-condition": 2, 30 | "no-cond-assign": [2, "except-parens"], 31 | "no-dupe-args": 2, 32 | "no-dupe-keys": 2, 33 | "no-duplicate-case": 2, 34 | "no-empty": 2, 35 | "no-ex-assign": 2, 36 | "no-extra-boolean-cast": 2, 37 | "no-func-assign": 1, 38 | "no-negated-in-lhs": 2, 39 | "no-irregular-whitespace": 2, 40 | "use-isnan": 2, 41 | "valid-jsdoc": [2, { 42 | "requireReturn": false 43 | }], 44 | "valid-typeof": 2, 45 | "complexity": [1,3], 46 | "consistent-return": 2, 47 | "curly": 0, 48 | "default-case": 2, 49 | "dot-notation": 2, 50 | "dot-location": [2, "property"], 51 | "eqeqeq": 2, 52 | "guard-for-in": 2, 53 | "no-alert": 1, 54 | "no-console": 1, 55 | "no-debugger": 2, 56 | "no-caller": 2, 57 | "no-else-return": 2, 58 | "no-labels": 2, 59 | "no-eq-null": 2, 60 | "no-eval": 2, 61 | "no-extend-native": 2, 62 | "no-extra-bind": 2, 63 | "no-implied-eval": 2, 64 | "no-iterator": 2, 65 | "no-lone-blocks": 2, 66 | "no-loop-func": 2, 67 | "no-multi-spaces": 2, 68 | "no-multi-str": 2, 69 | "no-new-func": 2, 70 | "no-new-wrappers": 2, 71 | "no-new": 2, 72 | "no-param-reassign": 2, 73 | "no-process-env": 2, 74 | "no-proto": 2, 75 | "no-redeclare": 2, 76 | "no-return-assign": 2, 77 | "no-script-url": 2, 78 | "no-self-compare": 2, 79 | "no-sequences": 2, 80 | "no-throw-literal": 2, 81 | "no-unused-expressions": 2, 82 | "no-void": 2, 83 | "no-warning-comments": [1, { "terms": ["todo", "fixme"], "location": "anywhere" }], 84 | "no-catch-shadow": 2, 85 | "no-undef-init": 2, 86 | "no-undef": 2, 87 | "no-unused-vars": [2, {"vars": "all", "args": "after-used"}], 88 | "no-use-before-define": 2, 89 | "brace-style": [2, "1tbs", { "allowSingleLine": true }], 90 | "camelcase": [2, {"properties": "always"}], 91 | "comma-style": [2, "last"], 92 | "comma-spacing": [2, {"before": false, "after": true}], 93 | "eol-last": 2, 94 | "func-names": 2, 95 | "indent": [2, 2, { "SwitchCase": 1 }], 96 | "key-spacing": [2, { "beforeColon": false, "afterColon": true }], 97 | "linebreak-style": 2, 98 | "max-nested-callbacks": [2, 3], 99 | "new-parens": 2, 100 | "new-cap": 2, 101 | "no-array-constructor": 2, 102 | "no-lonely-if": 2, 103 | "no-mixed-spaces-and-tabs": 2, 104 | "no-multiple-empty-lines": [2, { "max": 1 }], 105 | "no-nested-ternary": 2, 106 | "no-spaced-func": 2, 107 | "no-trailing-spaces": 2, 108 | "no-underscore-dangle": 2, 109 | "no-unneeded-ternary": 2, 110 | "no-extra-parens": 2, 111 | "padded-blocks": [2, "never"], 112 | "operator-linebreak": [2, "before"], 113 | "quote-props": [2, "as-needed"], 114 | "quotes": [2, "single", "avoid-escape"], 115 | "semi-spacing": [2, {"before": false, "after": true}], 116 | "space-before-blocks": [2, "always"], 117 | "space-before-function-paren": [2, "always"], 118 | "space-in-parens": [2, "never"], 119 | "space-infix-ops": [2, {"int32Hint": true}], 120 | "keyword-spacing": 2, 121 | "space-unary-ops": [2, { "words": true, "nonwords": false }], 122 | "spaced-comment": [2, "always"], 123 | "wrap-regex": 2, 124 | "generator-star-spacing": [2, "after"], 125 | "no-var": 2, 126 | "object-shorthand": 2, 127 | "max-len": [2, 120, 2, { "ignoreComments": true }] 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | dist 4 | npm-debug.log 5 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .babelrc 2 | .eslintrc 3 | .eslintignore 4 | esdoc.json 5 | karma.conf.js 6 | npm-debug.log 7 | server.js 8 | webpack.* 9 | /test 10 | /src 11 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "4.1" 4 | - "4.0" 5 | - "0.12" 6 | - "0.11" 7 | install: npm i 8 | script: npm run test:ci 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Yuriy Ankudinov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Immutable-http 2 | 3 | [![npm version](https://badge.fury.io/js/immutable-http.svg)](http://badge.fury.io/js/immutable-http) 4 | [![Build Status](https://travis-ci.org/stremlenye/immutable-http.svg?branch=master)](https://travis-ci.org/stremlenye/immutable-http) 5 | 6 | __Http client with pretty simple chaining API__ 7 | 8 | [Docs](http://stremlenye.github.io/immutable-http/) 9 | 10 | #### Usage 11 | 12 | ```js 13 | import executor from 'third-party-executor' 14 | 15 | var result = new Http().url('http://any_api.com/:id') 16 | .executor(executor) 17 | .method('GET') 18 | .header('Content-Type','application/json') 19 | .body({some:data}) 20 | .responseType('json') 21 | .segment('id',123) 22 | .query('filter','some_filter') // Adds query section for the url like '?filter=some_filter' 23 | .exec(); // returns Promise 24 | ``` 25 | `executor` is just a function with signature 26 | ```scala 27 | f(url: String, method: String, headers:Array[Tuple[String, String]], responseType: String, body: Any): Promise 28 | ``` 29 | It allows you to have your own favorite HTTP library under the hood and be able to test your code with mocked `executor` without any hacks. 30 | [Executor implementation example](https://github.com/stremlenye/simple-immutablehttp-executor) 31 | 32 | #### Build 33 | 34 | ``` 35 | npm run dist 36 | ``` 37 | 38 | #### Tests 39 | Run 40 | 41 | ``` 42 | npm test 43 | ``` 44 | -------------------------------------------------------------------------------- /docs/ast/source/utils/url.js.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "Program", 3 | "start": 0, 4 | "end": 729, 5 | "loc": { 6 | "start": { 7 | "line": 1, 8 | "column": 0 9 | }, 10 | "end": { 11 | "line": 25, 12 | "column": 0 13 | } 14 | }, 15 | "sourceType": "module", 16 | "body": [ 17 | { 18 | "type": "ExportNamedDeclaration", 19 | "start": 215, 20 | "end": 381, 21 | "loc": { 22 | "start": { 23 | "line": 9, 24 | "column": 0 25 | }, 26 | "end": { 27 | "line": 12, 28 | "column": 1 29 | } 30 | }, 31 | "declaration": { 32 | "type": "FunctionDeclaration", 33 | "start": 222, 34 | "end": 381, 35 | "loc": { 36 | "start": { 37 | "line": 9, 38 | "column": 7 39 | }, 40 | "end": { 41 | "line": 12, 42 | "column": 1 43 | } 44 | }, 45 | "id": { 46 | "type": "Identifier", 47 | "start": 231, 48 | "end": 257, 49 | "loc": { 50 | "start": { 51 | "line": 9, 52 | "column": 16 53 | }, 54 | "end": { 55 | "line": 9, 56 | "column": 42 57 | } 58 | }, 59 | "name": "mixinDynamicSegmentsValues", 60 | "leadingComments": null 61 | }, 62 | "generator": false, 63 | "expression": false, 64 | "async": false, 65 | "params": [ 66 | { 67 | "type": "Identifier", 68 | "start": 259, 69 | "end": 262, 70 | "loc": { 71 | "start": { 72 | "line": 9, 73 | "column": 44 74 | }, 75 | "end": { 76 | "line": 9, 77 | "column": 47 78 | } 79 | }, 80 | "name": "url" 81 | }, 82 | { 83 | "type": "Identifier", 84 | "start": 264, 85 | "end": 279, 86 | "loc": { 87 | "start": { 88 | "line": 9, 89 | "column": 49 90 | }, 91 | "end": { 92 | "line": 9, 93 | "column": 64 94 | } 95 | }, 96 | "name": "dynamicSegments" 97 | } 98 | ], 99 | "body": { 100 | "type": "BlockStatement", 101 | "start": 281, 102 | "end": 381, 103 | "loc": { 104 | "start": { 105 | "line": 9, 106 | "column": 66 107 | }, 108 | "end": { 109 | "line": 12, 110 | "column": 1 111 | } 112 | }, 113 | "body": [ 114 | { 115 | "type": "ReturnStatement", 116 | "start": 285, 117 | "end": 379, 118 | "loc": { 119 | "start": { 120 | "line": 10, 121 | "column": 2 122 | }, 123 | "end": { 124 | "line": 11, 125 | "column": 40 126 | } 127 | }, 128 | "argument": { 129 | "type": "CallExpression", 130 | "start": 292, 131 | "end": 379, 132 | "loc": { 133 | "start": { 134 | "line": 10, 135 | "column": 9 136 | }, 137 | "end": { 138 | "line": 11, 139 | "column": 40 140 | } 141 | }, 142 | "callee": { 143 | "type": "MemberExpression", 144 | "start": 292, 145 | "end": 314, 146 | "loc": { 147 | "start": { 148 | "line": 10, 149 | "column": 9 150 | }, 151 | "end": { 152 | "line": 10, 153 | "column": 31 154 | } 155 | }, 156 | "object": { 157 | "type": "Identifier", 158 | "start": 292, 159 | "end": 307, 160 | "loc": { 161 | "start": { 162 | "line": 10, 163 | "column": 9 164 | }, 165 | "end": { 166 | "line": 10, 167 | "column": 24 168 | } 169 | }, 170 | "name": "dynamicSegments" 171 | }, 172 | "property": { 173 | "type": "Identifier", 174 | "start": 308, 175 | "end": 314, 176 | "loc": { 177 | "start": { 178 | "line": 10, 179 | "column": 25 180 | }, 181 | "end": { 182 | "line": 10, 183 | "column": 31 184 | } 185 | }, 186 | "name": "reduce" 187 | }, 188 | "computed": false 189 | }, 190 | "arguments": [ 191 | { 192 | "type": "ArrowFunctionExpression", 193 | "start": 315, 194 | "end": 373, 195 | "loc": { 196 | "start": { 197 | "line": 10, 198 | "column": 32 199 | }, 200 | "end": { 201 | "line": 11, 202 | "column": 34 203 | } 204 | }, 205 | "id": null, 206 | "generator": false, 207 | "expression": true, 208 | "async": false, 209 | "params": [ 210 | { 211 | "type": "Identifier", 212 | "start": 316, 213 | "end": 320, 214 | "loc": { 215 | "start": { 216 | "line": 10, 217 | "column": 33 218 | }, 219 | "end": { 220 | "line": 10, 221 | "column": 37 222 | } 223 | }, 224 | "name": "aggr" 225 | }, 226 | { 227 | "type": "ArrayPattern", 228 | "start": 322, 229 | "end": 334, 230 | "loc": { 231 | "start": { 232 | "line": 10, 233 | "column": 39 234 | }, 235 | "end": { 236 | "line": 10, 237 | "column": 51 238 | } 239 | }, 240 | "elements": [ 241 | { 242 | "type": "Identifier", 243 | "start": 323, 244 | "end": 326, 245 | "loc": { 246 | "start": { 247 | "line": 10, 248 | "column": 40 249 | }, 250 | "end": { 251 | "line": 10, 252 | "column": 43 253 | } 254 | }, 255 | "name": "key" 256 | }, 257 | { 258 | "type": "Identifier", 259 | "start": 328, 260 | "end": 333, 261 | "loc": { 262 | "start": { 263 | "line": 10, 264 | "column": 45 265 | }, 266 | "end": { 267 | "line": 10, 268 | "column": 50 269 | } 270 | }, 271 | "name": "value" 272 | } 273 | ] 274 | } 275 | ], 276 | "body": { 277 | "type": "CallExpression", 278 | "start": 343, 279 | "end": 373, 280 | "loc": { 281 | "start": { 282 | "line": 11, 283 | "column": 4 284 | }, 285 | "end": { 286 | "line": 11, 287 | "column": 34 288 | } 289 | }, 290 | "callee": { 291 | "type": "MemberExpression", 292 | "start": 343, 293 | "end": 355, 294 | "loc": { 295 | "start": { 296 | "line": 11, 297 | "column": 4 298 | }, 299 | "end": { 300 | "line": 11, 301 | "column": 16 302 | } 303 | }, 304 | "object": { 305 | "type": "Identifier", 306 | "start": 343, 307 | "end": 347, 308 | "loc": { 309 | "start": { 310 | "line": 11, 311 | "column": 4 312 | }, 313 | "end": { 314 | "line": 11, 315 | "column": 8 316 | } 317 | }, 318 | "name": "aggr" 319 | }, 320 | "property": { 321 | "type": "Identifier", 322 | "start": 348, 323 | "end": 355, 324 | "loc": { 325 | "start": { 326 | "line": 11, 327 | "column": 9 328 | }, 329 | "end": { 330 | "line": 11, 331 | "column": 16 332 | } 333 | }, 334 | "name": "replace" 335 | }, 336 | "computed": false 337 | }, 338 | "arguments": [ 339 | { 340 | "type": "TemplateLiteral", 341 | "start": 356, 342 | "end": 365, 343 | "loc": { 344 | "start": { 345 | "line": 11, 346 | "column": 17 347 | }, 348 | "end": { 349 | "line": 11, 350 | "column": 26 351 | } 352 | }, 353 | "expressions": [ 354 | { 355 | "type": "Identifier", 356 | "start": 360, 357 | "end": 363, 358 | "loc": { 359 | "start": { 360 | "line": 11, 361 | "column": 21 362 | }, 363 | "end": { 364 | "line": 11, 365 | "column": 24 366 | } 367 | }, 368 | "name": "key" 369 | } 370 | ], 371 | "quasis": [ 372 | { 373 | "type": "TemplateElement", 374 | "start": 357, 375 | "end": 358, 376 | "loc": { 377 | "start": { 378 | "line": 11, 379 | "column": 18 380 | }, 381 | "end": { 382 | "line": 11, 383 | "column": 19 384 | } 385 | }, 386 | "value": { 387 | "raw": ":", 388 | "cooked": ":" 389 | }, 390 | "tail": false 391 | }, 392 | { 393 | "type": "TemplateElement", 394 | "start": 364, 395 | "end": 364, 396 | "loc": { 397 | "start": { 398 | "line": 11, 399 | "column": 25 400 | }, 401 | "end": { 402 | "line": 11, 403 | "column": 25 404 | } 405 | }, 406 | "value": { 407 | "raw": "", 408 | "cooked": "" 409 | }, 410 | "tail": true 411 | } 412 | ] 413 | }, 414 | { 415 | "type": "Identifier", 416 | "start": 367, 417 | "end": 372, 418 | "loc": { 419 | "start": { 420 | "line": 11, 421 | "column": 28 422 | }, 423 | "end": { 424 | "line": 11, 425 | "column": 33 426 | } 427 | }, 428 | "name": "value" 429 | } 430 | ] 431 | } 432 | }, 433 | { 434 | "type": "Identifier", 435 | "start": 375, 436 | "end": 378, 437 | "loc": { 438 | "start": { 439 | "line": 11, 440 | "column": 36 441 | }, 442 | "end": { 443 | "line": 11, 444 | "column": 39 445 | } 446 | }, 447 | "name": "url" 448 | } 449 | ] 450 | } 451 | } 452 | ], 453 | "trailingComments": null 454 | }, 455 | "leadingComments": [ 456 | { 457 | "type": "Block", 458 | "value": "*\n * @ignore\n * Mixins dynamic segments replacing the `:segment_name` parts with provide\n * values\n * @param {String} url – URL\n * @param {Object} dynamicSegments – dynamic segments\n * @returns {String} – URL\n ", 459 | "start": 0, 460 | "end": 214, 461 | "loc": { 462 | "start": { 463 | "line": 1, 464 | "column": 0 465 | }, 466 | "end": { 467 | "line": 8, 468 | "column": 3 469 | } 470 | }, 471 | "range": [ 472 | 0, 473 | 214 474 | ] 475 | } 476 | ], 477 | "trailingComments": [ 478 | { 479 | "type": "Block", 480 | "value": "*\n * @ignore\n * Adds query params string to url\n * @param {string} url – URL\n * @param {Array} queryParams – query params\n * @returns {String} – URL\n ", 481 | "start": 383, 482 | "end": 537, 483 | "loc": { 484 | "start": { 485 | "line": 14, 486 | "column": 0 487 | }, 488 | "end": { 489 | "line": 20, 490 | "column": 3 491 | } 492 | }, 493 | "range": [ 494 | 383, 495 | 537 496 | ] 497 | } 498 | ] 499 | }, 500 | "specifiers": [], 501 | "source": null, 502 | "leadingComments": [ 503 | { 504 | "type": "Block", 505 | "value": "*\n * @ignore\n * Mixins dynamic segments replacing the `:segment_name` parts with provide\n * values\n * @param {String} url – URL\n * @param {Object} dynamicSegments – dynamic segments\n * @returns {String} – URL\n ", 506 | "start": 0, 507 | "end": 214, 508 | "loc": { 509 | "start": { 510 | "line": 1, 511 | "column": 0 512 | }, 513 | "end": { 514 | "line": 8, 515 | "column": 3 516 | } 517 | }, 518 | "range": [ 519 | 0, 520 | 214 521 | ] 522 | } 523 | ], 524 | "trailingComments": [ 525 | { 526 | "type": "Block", 527 | "value": "*\n * @ignore\n * Adds query params string to url\n * @param {string} url – URL\n * @param {Array} queryParams – query params\n * @returns {String} – URL\n ", 528 | "start": 383, 529 | "end": 537, 530 | "loc": { 531 | "start": { 532 | "line": 14, 533 | "column": 0 534 | }, 535 | "end": { 536 | "line": 20, 537 | "column": 3 538 | } 539 | }, 540 | "range": [ 541 | 383, 542 | 537 543 | ] 544 | } 545 | ] 546 | }, 547 | { 548 | "type": "ExportNamedDeclaration", 549 | "start": 538, 550 | "end": 728, 551 | "loc": { 552 | "start": { 553 | "line": 21, 554 | "column": 0 555 | }, 556 | "end": { 557 | "line": 24, 558 | "column": 1 559 | } 560 | }, 561 | "declaration": { 562 | "type": "FunctionDeclaration", 563 | "start": 545, 564 | "end": 728, 565 | "loc": { 566 | "start": { 567 | "line": 21, 568 | "column": 7 569 | }, 570 | "end": { 571 | "line": 24, 572 | "column": 1 573 | } 574 | }, 575 | "id": { 576 | "type": "Identifier", 577 | "start": 554, 578 | "end": 568, 579 | "loc": { 580 | "start": { 581 | "line": 21, 582 | "column": 16 583 | }, 584 | "end": { 585 | "line": 21, 586 | "column": 30 587 | } 588 | }, 589 | "name": "addQueryParams", 590 | "leadingComments": null 591 | }, 592 | "generator": false, 593 | "expression": false, 594 | "async": false, 595 | "params": [ 596 | { 597 | "type": "Identifier", 598 | "start": 570, 599 | "end": 573, 600 | "loc": { 601 | "start": { 602 | "line": 21, 603 | "column": 32 604 | }, 605 | "end": { 606 | "line": 21, 607 | "column": 35 608 | } 609 | }, 610 | "name": "url" 611 | }, 612 | { 613 | "type": "Identifier", 614 | "start": 575, 615 | "end": 586, 616 | "loc": { 617 | "start": { 618 | "line": 21, 619 | "column": 37 620 | }, 621 | "end": { 622 | "line": 21, 623 | "column": 48 624 | } 625 | }, 626 | "name": "queryParams" 627 | } 628 | ], 629 | "body": { 630 | "type": "BlockStatement", 631 | "start": 588, 632 | "end": 728, 633 | "loc": { 634 | "start": { 635 | "line": 21, 636 | "column": 50 637 | }, 638 | "end": { 639 | "line": 24, 640 | "column": 1 641 | } 642 | }, 643 | "body": [ 644 | { 645 | "type": "VariableDeclaration", 646 | "start": 592, 647 | "end": 659, 648 | "loc": { 649 | "start": { 650 | "line": 22, 651 | "column": 2 652 | }, 653 | "end": { 654 | "line": 22, 655 | "column": 69 656 | } 657 | }, 658 | "declarations": [ 659 | { 660 | "type": "VariableDeclarator", 661 | "start": 598, 662 | "end": 659, 663 | "loc": { 664 | "start": { 665 | "line": 22, 666 | "column": 8 667 | }, 668 | "end": { 669 | "line": 22, 670 | "column": 69 671 | } 672 | }, 673 | "id": { 674 | "type": "Identifier", 675 | "start": 598, 676 | "end": 604, 677 | "loc": { 678 | "start": { 679 | "line": 22, 680 | "column": 8 681 | }, 682 | "end": { 683 | "line": 22, 684 | "column": 14 685 | } 686 | }, 687 | "name": "chanks" 688 | }, 689 | "init": { 690 | "type": "CallExpression", 691 | "start": 607, 692 | "end": 659, 693 | "loc": { 694 | "start": { 695 | "line": 22, 696 | "column": 17 697 | }, 698 | "end": { 699 | "line": 22, 700 | "column": 69 701 | } 702 | }, 703 | "callee": { 704 | "type": "MemberExpression", 705 | "start": 607, 706 | "end": 622, 707 | "loc": { 708 | "start": { 709 | "line": 22, 710 | "column": 17 711 | }, 712 | "end": { 713 | "line": 22, 714 | "column": 32 715 | } 716 | }, 717 | "object": { 718 | "type": "Identifier", 719 | "start": 607, 720 | "end": 618, 721 | "loc": { 722 | "start": { 723 | "line": 22, 724 | "column": 17 725 | }, 726 | "end": { 727 | "line": 22, 728 | "column": 28 729 | } 730 | }, 731 | "name": "queryParams" 732 | }, 733 | "property": { 734 | "type": "Identifier", 735 | "start": 619, 736 | "end": 622, 737 | "loc": { 738 | "start": { 739 | "line": 22, 740 | "column": 29 741 | }, 742 | "end": { 743 | "line": 22, 744 | "column": 32 745 | } 746 | }, 747 | "name": "map" 748 | }, 749 | "computed": false 750 | }, 751 | "arguments": [ 752 | { 753 | "type": "ArrowFunctionExpression", 754 | "start": 623, 755 | "end": 658, 756 | "loc": { 757 | "start": { 758 | "line": 22, 759 | "column": 33 760 | }, 761 | "end": { 762 | "line": 22, 763 | "column": 68 764 | } 765 | }, 766 | "id": null, 767 | "generator": false, 768 | "expression": true, 769 | "async": false, 770 | "params": [ 771 | { 772 | "type": "ArrayPattern", 773 | "start": 624, 774 | "end": 636, 775 | "loc": { 776 | "start": { 777 | "line": 22, 778 | "column": 34 779 | }, 780 | "end": { 781 | "line": 22, 782 | "column": 46 783 | } 784 | }, 785 | "elements": [ 786 | { 787 | "type": "Identifier", 788 | "start": 625, 789 | "end": 628, 790 | "loc": { 791 | "start": { 792 | "line": 22, 793 | "column": 35 794 | }, 795 | "end": { 796 | "line": 22, 797 | "column": 38 798 | } 799 | }, 800 | "name": "key" 801 | }, 802 | { 803 | "type": "Identifier", 804 | "start": 630, 805 | "end": 635, 806 | "loc": { 807 | "start": { 808 | "line": 22, 809 | "column": 40 810 | }, 811 | "end": { 812 | "line": 22, 813 | "column": 45 814 | } 815 | }, 816 | "name": "value" 817 | } 818 | ] 819 | } 820 | ], 821 | "body": { 822 | "type": "TemplateLiteral", 823 | "start": 641, 824 | "end": 658, 825 | "loc": { 826 | "start": { 827 | "line": 22, 828 | "column": 51 829 | }, 830 | "end": { 831 | "line": 22, 832 | "column": 68 833 | } 834 | }, 835 | "expressions": [ 836 | { 837 | "type": "Identifier", 838 | "start": 644, 839 | "end": 647, 840 | "loc": { 841 | "start": { 842 | "line": 22, 843 | "column": 54 844 | }, 845 | "end": { 846 | "line": 22, 847 | "column": 57 848 | } 849 | }, 850 | "name": "key" 851 | }, 852 | { 853 | "type": "Identifier", 854 | "start": 651, 855 | "end": 656, 856 | "loc": { 857 | "start": { 858 | "line": 22, 859 | "column": 61 860 | }, 861 | "end": { 862 | "line": 22, 863 | "column": 66 864 | } 865 | }, 866 | "name": "value" 867 | } 868 | ], 869 | "quasis": [ 870 | { 871 | "type": "TemplateElement", 872 | "start": 642, 873 | "end": 642, 874 | "loc": { 875 | "start": { 876 | "line": 22, 877 | "column": 52 878 | }, 879 | "end": { 880 | "line": 22, 881 | "column": 52 882 | } 883 | }, 884 | "value": { 885 | "raw": "", 886 | "cooked": "" 887 | }, 888 | "tail": false 889 | }, 890 | { 891 | "type": "TemplateElement", 892 | "start": 648, 893 | "end": 649, 894 | "loc": { 895 | "start": { 896 | "line": 22, 897 | "column": 58 898 | }, 899 | "end": { 900 | "line": 22, 901 | "column": 59 902 | } 903 | }, 904 | "value": { 905 | "raw": "=", 906 | "cooked": "=" 907 | }, 908 | "tail": false 909 | }, 910 | { 911 | "type": "TemplateElement", 912 | "start": 657, 913 | "end": 657, 914 | "loc": { 915 | "start": { 916 | "line": 22, 917 | "column": 67 918 | }, 919 | "end": { 920 | "line": 22, 921 | "column": 67 922 | } 923 | }, 924 | "value": { 925 | "raw": "", 926 | "cooked": "" 927 | }, 928 | "tail": true 929 | } 930 | ] 931 | } 932 | } 933 | ] 934 | } 935 | } 936 | ], 937 | "kind": "const" 938 | }, 939 | { 940 | "type": "ReturnStatement", 941 | "start": 662, 942 | "end": 726, 943 | "loc": { 944 | "start": { 945 | "line": 23, 946 | "column": 2 947 | }, 948 | "end": { 949 | "line": 23, 950 | "column": 66 951 | } 952 | }, 953 | "argument": { 954 | "type": "BinaryExpression", 955 | "start": 669, 956 | "end": 726, 957 | "loc": { 958 | "start": { 959 | "line": 23, 960 | "column": 9 961 | }, 962 | "end": { 963 | "line": 23, 964 | "column": 66 965 | } 966 | }, 967 | "left": { 968 | "type": "Identifier", 969 | "start": 669, 970 | "end": 672, 971 | "loc": { 972 | "start": { 973 | "line": 23, 974 | "column": 9 975 | }, 976 | "end": { 977 | "line": 23, 978 | "column": 12 979 | } 980 | }, 981 | "name": "url" 982 | }, 983 | "operator": "+", 984 | "right": { 985 | "type": "ConditionalExpression", 986 | "start": 676, 987 | "end": 725, 988 | "loc": { 989 | "start": { 990 | "line": 23, 991 | "column": 16 992 | }, 993 | "end": { 994 | "line": 23, 995 | "column": 65 996 | } 997 | }, 998 | "test": { 999 | "type": "BinaryExpression", 1000 | "start": 676, 1001 | "end": 695, 1002 | "loc": { 1003 | "start": { 1004 | "line": 23, 1005 | "column": 16 1006 | }, 1007 | "end": { 1008 | "line": 23, 1009 | "column": 35 1010 | } 1011 | }, 1012 | "left": { 1013 | "type": "MemberExpression", 1014 | "start": 676, 1015 | "end": 689, 1016 | "loc": { 1017 | "start": { 1018 | "line": 23, 1019 | "column": 16 1020 | }, 1021 | "end": { 1022 | "line": 23, 1023 | "column": 29 1024 | } 1025 | }, 1026 | "object": { 1027 | "type": "Identifier", 1028 | "start": 676, 1029 | "end": 682, 1030 | "loc": { 1031 | "start": { 1032 | "line": 23, 1033 | "column": 16 1034 | }, 1035 | "end": { 1036 | "line": 23, 1037 | "column": 22 1038 | } 1039 | }, 1040 | "name": "chanks" 1041 | }, 1042 | "property": { 1043 | "type": "Identifier", 1044 | "start": 683, 1045 | "end": 689, 1046 | "loc": { 1047 | "start": { 1048 | "line": 23, 1049 | "column": 23 1050 | }, 1051 | "end": { 1052 | "line": 23, 1053 | "column": 29 1054 | } 1055 | }, 1056 | "name": "length" 1057 | }, 1058 | "computed": false 1059 | }, 1060 | "operator": "!==", 1061 | "right": { 1062 | "type": "Literal", 1063 | "start": 694, 1064 | "end": 695, 1065 | "loc": { 1066 | "start": { 1067 | "line": 23, 1068 | "column": 34 1069 | }, 1070 | "end": { 1071 | "line": 23, 1072 | "column": 35 1073 | } 1074 | }, 1075 | "value": 0, 1076 | "rawValue": 0, 1077 | "raw": "0" 1078 | } 1079 | }, 1080 | "consequent": { 1081 | "type": "BinaryExpression", 1082 | "start": 698, 1083 | "end": 720, 1084 | "loc": { 1085 | "start": { 1086 | "line": 23, 1087 | "column": 38 1088 | }, 1089 | "end": { 1090 | "line": 23, 1091 | "column": 60 1092 | } 1093 | }, 1094 | "left": { 1095 | "type": "Literal", 1096 | "start": 698, 1097 | "end": 701, 1098 | "loc": { 1099 | "start": { 1100 | "line": 23, 1101 | "column": 38 1102 | }, 1103 | "end": { 1104 | "line": 23, 1105 | "column": 41 1106 | } 1107 | }, 1108 | "value": "?", 1109 | "rawValue": "?", 1110 | "raw": "'?'" 1111 | }, 1112 | "operator": "+", 1113 | "right": { 1114 | "type": "CallExpression", 1115 | "start": 704, 1116 | "end": 720, 1117 | "loc": { 1118 | "start": { 1119 | "line": 23, 1120 | "column": 44 1121 | }, 1122 | "end": { 1123 | "line": 23, 1124 | "column": 60 1125 | } 1126 | }, 1127 | "callee": { 1128 | "type": "MemberExpression", 1129 | "start": 704, 1130 | "end": 715, 1131 | "loc": { 1132 | "start": { 1133 | "line": 23, 1134 | "column": 44 1135 | }, 1136 | "end": { 1137 | "line": 23, 1138 | "column": 55 1139 | } 1140 | }, 1141 | "object": { 1142 | "type": "Identifier", 1143 | "start": 704, 1144 | "end": 710, 1145 | "loc": { 1146 | "start": { 1147 | "line": 23, 1148 | "column": 44 1149 | }, 1150 | "end": { 1151 | "line": 23, 1152 | "column": 50 1153 | } 1154 | }, 1155 | "name": "chanks" 1156 | }, 1157 | "property": { 1158 | "type": "Identifier", 1159 | "start": 711, 1160 | "end": 715, 1161 | "loc": { 1162 | "start": { 1163 | "line": 23, 1164 | "column": 51 1165 | }, 1166 | "end": { 1167 | "line": 23, 1168 | "column": 55 1169 | } 1170 | }, 1171 | "name": "join" 1172 | }, 1173 | "computed": false 1174 | }, 1175 | "arguments": [ 1176 | { 1177 | "type": "Literal", 1178 | "start": 716, 1179 | "end": 719, 1180 | "loc": { 1181 | "start": { 1182 | "line": 23, 1183 | "column": 56 1184 | }, 1185 | "end": { 1186 | "line": 23, 1187 | "column": 59 1188 | } 1189 | }, 1190 | "value": "&", 1191 | "rawValue": "&", 1192 | "raw": "'&'" 1193 | } 1194 | ] 1195 | } 1196 | }, 1197 | "alternate": { 1198 | "type": "Literal", 1199 | "start": 723, 1200 | "end": 725, 1201 | "loc": { 1202 | "start": { 1203 | "line": 23, 1204 | "column": 63 1205 | }, 1206 | "end": { 1207 | "line": 23, 1208 | "column": 65 1209 | } 1210 | }, 1211 | "value": "", 1212 | "rawValue": "", 1213 | "raw": "''" 1214 | }, 1215 | "parenthesizedExpression": true 1216 | } 1217 | } 1218 | } 1219 | ] 1220 | }, 1221 | "leadingComments": [ 1222 | { 1223 | "type": "Block", 1224 | "value": "*\n * @ignore\n * Adds query params string to url\n * @param {string} url – URL\n * @param {Array} queryParams – query params\n * @returns {String} – URL\n ", 1225 | "start": 383, 1226 | "end": 537, 1227 | "loc": { 1228 | "start": { 1229 | "line": 14, 1230 | "column": 0 1231 | }, 1232 | "end": { 1233 | "line": 20, 1234 | "column": 3 1235 | } 1236 | }, 1237 | "range": [ 1238 | 383, 1239 | 537 1240 | ] 1241 | } 1242 | ], 1243 | "trailingComments": [] 1244 | }, 1245 | "specifiers": [], 1246 | "source": null, 1247 | "leadingComments": [ 1248 | { 1249 | "type": "Block", 1250 | "value": "*\n * @ignore\n * Adds query params string to url\n * @param {string} url – URL\n * @param {Array} queryParams – query params\n * @returns {String} – URL\n ", 1251 | "start": 383, 1252 | "end": 537, 1253 | "loc": { 1254 | "start": { 1255 | "line": 14, 1256 | "column": 0 1257 | }, 1258 | "end": { 1259 | "line": 20, 1260 | "column": 3 1261 | } 1262 | }, 1263 | "range": [ 1264 | 383, 1265 | 537 1266 | ] 1267 | } 1268 | ] 1269 | } 1270 | ] 1271 | } -------------------------------------------------------------------------------- /docs/badge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | document 13 | document 14 | 92% 15 | 92% 16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/coverage.json: -------------------------------------------------------------------------------- 1 | { 2 | "coverage": "92.85%", 3 | "expectCount": 14, 4 | "actualCount": 13, 5 | "files": { 6 | "src/index.js": { 7 | "expectCount": 14, 8 | "actualCount": 13, 9 | "undocumentLines": [ 10 | 63 11 | ] 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /docs/css/prettify-tomorrow.css: -------------------------------------------------------------------------------- 1 | /* Tomorrow Theme */ 2 | /* Original theme - https://github.com/chriskempson/tomorrow-theme */ 3 | /* Pretty printing styles. Used with prettify.js. */ 4 | /* SPAN elements with the classes below are added by prettyprint. */ 5 | /* plain text */ 6 | .pln { 7 | color: #4d4d4c; } 8 | 9 | @media screen { 10 | /* string content */ 11 | .str { 12 | color: #718c00; } 13 | 14 | /* a keyword */ 15 | .kwd { 16 | color: #8959a8; } 17 | 18 | /* a comment */ 19 | .com { 20 | color: #8e908c; } 21 | 22 | /* a type name */ 23 | .typ { 24 | color: #4271ae; } 25 | 26 | /* a literal value */ 27 | .lit { 28 | color: #f5871f; } 29 | 30 | /* punctuation */ 31 | .pun { 32 | color: #4d4d4c; } 33 | 34 | /* lisp open bracket */ 35 | .opn { 36 | color: #4d4d4c; } 37 | 38 | /* lisp close bracket */ 39 | .clo { 40 | color: #4d4d4c; } 41 | 42 | /* a markup tag name */ 43 | .tag { 44 | color: #c82829; } 45 | 46 | /* a markup attribute name */ 47 | .atn { 48 | color: #f5871f; } 49 | 50 | /* a markup attribute value */ 51 | .atv { 52 | color: #3e999f; } 53 | 54 | /* a declaration */ 55 | .dec { 56 | color: #f5871f; } 57 | 58 | /* a variable name */ 59 | .var { 60 | color: #c82829; } 61 | 62 | /* a function name */ 63 | .fun { 64 | color: #4271ae; } } 65 | /* Use higher contrast and text-weight for printable form. */ 66 | @media print, projection { 67 | .str { 68 | color: #060; } 69 | 70 | .kwd { 71 | color: #006; 72 | font-weight: bold; } 73 | 74 | .com { 75 | color: #600; 76 | font-style: italic; } 77 | 78 | .typ { 79 | color: #404; 80 | font-weight: bold; } 81 | 82 | .lit { 83 | color: #044; } 84 | 85 | .pun, .opn, .clo { 86 | color: #440; } 87 | 88 | .tag { 89 | color: #006; 90 | font-weight: bold; } 91 | 92 | .atn { 93 | color: #404; } 94 | 95 | .atv { 96 | color: #060; } } 97 | /* Style */ 98 | /* 99 | pre.prettyprint { 100 | background: white; 101 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 102 | font-size: 12px; 103 | line-height: 1.5; 104 | border: 1px solid #ccc; 105 | padding: 10px; } 106 | */ 107 | 108 | /* Specify class=linenums on a pre to get line numbering */ 109 | ol.linenums { 110 | margin-top: 0; 111 | margin-bottom: 0; } 112 | 113 | /* IE indents via margin-left */ 114 | li.L0, 115 | li.L1, 116 | li.L2, 117 | li.L3, 118 | li.L4, 119 | li.L5, 120 | li.L6, 121 | li.L7, 122 | li.L8, 123 | li.L9 { 124 | /* */ } 125 | 126 | /* Alternate shading for lines */ 127 | li.L1, 128 | li.L3, 129 | li.L5, 130 | li.L7, 131 | li.L9 { 132 | /* */ } 133 | -------------------------------------------------------------------------------- /docs/css/style.css: -------------------------------------------------------------------------------- 1 | @import url(https://fonts.googleapis.com/css?family=Roboto:400,300,700); 2 | 3 | * { 4 | margin: 0; 5 | padding: 0; 6 | text-decoration: none; 7 | } 8 | 9 | html 10 | { 11 | font-family: 'Roboto', sans-serif; 12 | overflow: auto; 13 | font-size: 14px; 14 | /*color: #4d4e53;*/ 15 | color: rgba(0, 0, 0, .68); 16 | background-color: #fff; 17 | } 18 | 19 | a { 20 | /*color: #0095dd;*/ 21 | /*color:rgb(37, 138, 175);*/ 22 | color: #039BE5; 23 | } 24 | 25 | code a:hover { 26 | text-decoration: underline; 27 | } 28 | 29 | ul, ol { 30 | padding-left: 20px; 31 | } 32 | 33 | ul li { 34 | list-style: disc; 35 | margin: 4px 0; 36 | } 37 | 38 | ol li { 39 | margin: 4px 0; 40 | } 41 | 42 | h1 { 43 | margin-bottom: 10px; 44 | font-size: 34px; 45 | font-weight: 300; 46 | border-bottom: solid 1px #ddd; 47 | } 48 | 49 | h2 { 50 | margin-top: 24px; 51 | margin-bottom: 10px; 52 | font-size: 20px; 53 | border-bottom: solid 1px #ddd; 54 | font-weight: 300; 55 | } 56 | 57 | h3 { 58 | position: relative; 59 | font-size: 16px; 60 | margin-bottom: 12px; 61 | background-color: #E2E2E2; 62 | padding: 4px; 63 | font-weight: 300; 64 | } 65 | 66 | del { 67 | text-decoration: line-through; 68 | } 69 | 70 | p { 71 | margin-bottom: 15px; 72 | line-height: 1.5; 73 | } 74 | 75 | p > code { 76 | background-color: #f5f5f5; 77 | border-radius: 3px; 78 | } 79 | 80 | pre > code { 81 | display: block; 82 | } 83 | 84 | pre.prettyprint, pre > code { 85 | padding: 4px; 86 | margin: 1em 0; 87 | background-color: #f5f5f5; 88 | border-radius: 3px; 89 | } 90 | 91 | pre.prettyprint > code { 92 | margin: 0; 93 | } 94 | 95 | p > code, 96 | li > code { 97 | padding: 0 4px; 98 | border-radius: 3px; 99 | } 100 | 101 | .import-path pre.prettyprint, 102 | .import-path pre.prettyprint code { 103 | margin: 0; 104 | padding: 0; 105 | border: none; 106 | background: white; 107 | } 108 | 109 | .layout-container { 110 | /*display: flex;*/ 111 | /*flex-direction: row;*/ 112 | /*justify-content: flex-start;*/ 113 | /*align-items: stretch;*/ 114 | } 115 | 116 | .layout-container > header { 117 | height: 40px; 118 | line-height: 40px; 119 | font-size: 16px; 120 | padding: 0 10px; 121 | margin: 0; 122 | position: fixed; 123 | width: 100%; 124 | z-index: 1; 125 | background-color: white; 126 | top: 0; 127 | border-bottom: solid 1px #E02130; 128 | } 129 | .layout-container > header > a{ 130 | margin: 0 5px; 131 | } 132 | 133 | .layout-container > header > a.repo-url-github { 134 | font-size: 0; 135 | display: inline-block; 136 | width: 20px; 137 | height: 38px; 138 | background: url("../image/github.png") no-repeat center; 139 | background-size: 20px; 140 | vertical-align: top; 141 | } 142 | 143 | .navigation { 144 | position: fixed; 145 | top: 0; 146 | left: 0; 147 | box-sizing: border-box; 148 | width: 250px; 149 | height: 100%; 150 | padding-top: 40px; 151 | padding-left: 15px; 152 | padding-bottom: 2em; 153 | margin-top:1em; 154 | overflow-x: scroll; 155 | box-shadow: rgba(255, 255, 255, 1) -1px 0 0 inset; 156 | border-right: 1px solid rgba(0, 0, 0, 0.1); 157 | } 158 | 159 | .navigation ul { 160 | padding: 0; 161 | } 162 | 163 | .navigation li { 164 | list-style: none; 165 | margin: 4px 0; 166 | white-space: nowrap; 167 | } 168 | 169 | .navigation .nav-dir-path { 170 | margin-top: 0.7em; 171 | margin-bottom: 0.25em; 172 | font-size: 0.8em; 173 | color: #aaa; 174 | } 175 | 176 | .kind-class, 177 | .kind-interface, 178 | .kind-function, 179 | .kind-typedef, 180 | .kind-variable, 181 | .kind-external { 182 | margin-left: 0.75em; 183 | width: 1.2em; 184 | height: 1.2em; 185 | display: inline-block; 186 | text-align: center; 187 | border-radius: 0.2em; 188 | margin-right: 0.2em; 189 | font-weight: bold; 190 | } 191 | 192 | .kind-class { 193 | color: #009800; 194 | background-color: #bfe5bf; 195 | } 196 | 197 | .kind-interface { 198 | color: #fbca04; 199 | background-color: #fef2c0; 200 | } 201 | 202 | .kind-function { 203 | color: #6b0090; 204 | background-color: #d6bdde; 205 | } 206 | 207 | .kind-variable { 208 | color: #eb6420; 209 | background-color: #fad8c7; 210 | } 211 | 212 | .kind-typedef { 213 | color: #db001e; 214 | background-color: #edbec3; 215 | } 216 | 217 | .kind-external { 218 | color: #0738c3; 219 | background-color: #bbcbea; 220 | } 221 | 222 | h1 .version, 223 | h1 .url a { 224 | font-size: 14px; 225 | color: #aaa; 226 | } 227 | 228 | .content { 229 | margin-top: 40px; 230 | margin-left: 250px; 231 | padding: 10px 50px 10px 20px; 232 | } 233 | 234 | .header-notice { 235 | font-size: 14px; 236 | color: #aaa; 237 | margin: 0; 238 | } 239 | 240 | .expression-extends .prettyprint { 241 | margin-left: 10px; 242 | background: white; 243 | } 244 | 245 | .extends-chain { 246 | border-bottom: 1px solid#ddd; 247 | padding-bottom: 10px; 248 | margin-bottom: 10px; 249 | } 250 | 251 | .extends-chain span:nth-of-type(1) { 252 | padding-left: 10px; 253 | } 254 | 255 | .extends-chain > div { 256 | margin: 5px 0; 257 | } 258 | 259 | .description table { 260 | font-size: 14px; 261 | border-spacing: 0; 262 | border: 0; 263 | border-collapse: collapse; 264 | } 265 | 266 | .description thead { 267 | background: #999; 268 | color: white; 269 | } 270 | 271 | .description table td, 272 | .description table th { 273 | border: solid 1px #ddd; 274 | padding: 4px; 275 | font-weight: normal; 276 | } 277 | 278 | .flat-list ul { 279 | padding-left: 0; 280 | } 281 | 282 | .flat-list li { 283 | display: inline; 284 | list-style: none; 285 | } 286 | 287 | table.summary { 288 | width: 100%; 289 | margin: 10px 0; 290 | border-spacing: 0; 291 | border: 0; 292 | border-collapse: collapse; 293 | } 294 | 295 | table.summary thead { 296 | background: #999; 297 | color: white; 298 | } 299 | 300 | table.summary td { 301 | border: solid 1px #ddd; 302 | padding: 4px 10px; 303 | } 304 | 305 | table.summary tbody td:nth-child(1) { 306 | text-align: right; 307 | white-space: nowrap; 308 | min-width: 64px; 309 | vertical-align: top; 310 | } 311 | 312 | table.summary tbody td:nth-child(2) { 313 | width: 100%; 314 | border-right: none; 315 | } 316 | 317 | table.summary tbody td:nth-child(3) { 318 | white-space: nowrap; 319 | border-left: none; 320 | vertical-align: top; 321 | } 322 | 323 | table.summary td > div:nth-of-type(2) { 324 | padding-top: 4px; 325 | padding-left: 15px; 326 | } 327 | 328 | table.summary td p { 329 | margin-bottom: 0; 330 | } 331 | 332 | .inherited-summary thead td { 333 | padding-left: 2px; 334 | } 335 | 336 | .inherited-summary thead a { 337 | color: white; 338 | } 339 | 340 | .inherited-summary .summary tbody { 341 | display: none; 342 | } 343 | 344 | .inherited-summary .summary .toggle { 345 | padding: 0 4px; 346 | font-size: 12px; 347 | cursor: pointer; 348 | } 349 | .inherited-summary .summary .toggle.closed:before { 350 | content: "▶"; 351 | } 352 | .inherited-summary .summary .toggle.opened:before { 353 | content: "▼"; 354 | } 355 | 356 | .member, .method { 357 | margin-bottom: 24px; 358 | } 359 | 360 | table.params { 361 | width: 100%; 362 | margin: 10px 0; 363 | border-spacing: 0; 364 | border: 0; 365 | border-collapse: collapse; 366 | } 367 | 368 | table.params thead { 369 | background: #eee; 370 | color: #aaa; 371 | } 372 | 373 | table.params td { 374 | padding: 4px; 375 | border: solid 1px #ddd; 376 | } 377 | 378 | table.params td p { 379 | margin: 0; 380 | } 381 | 382 | .content .detail > * { 383 | margin: 15px 0; 384 | } 385 | 386 | .content .detail > h3 { 387 | color: black; 388 | } 389 | 390 | .content .detail > div { 391 | margin-left: 10px; 392 | } 393 | 394 | .content .detail > .import-path { 395 | margin-top: -8px; 396 | } 397 | 398 | .content .detail + .detail { 399 | margin-top: 30px; 400 | } 401 | 402 | .content .detail .throw td:first-child { 403 | padding-right: 10px; 404 | } 405 | 406 | .content .detail h4 + :not(pre) { 407 | padding-left: 0; 408 | margin-left: 10px; 409 | } 410 | 411 | .content .detail h4 + ul li { 412 | list-style: none; 413 | } 414 | 415 | .return-param * { 416 | display: inline; 417 | } 418 | 419 | .argument-params { 420 | margin-bottom: 20px; 421 | } 422 | 423 | .return-type { 424 | padding-right: 10px; 425 | font-weight: normal; 426 | } 427 | 428 | .return-desc { 429 | margin-left: 10px; 430 | margin-top: 4px; 431 | } 432 | 433 | .return-desc p { 434 | margin: 0; 435 | } 436 | 437 | .deprecated, .experimental, .instance-docs { 438 | border-left: solid 5px orange; 439 | padding-left: 4px; 440 | margin: 4px 0; 441 | } 442 | 443 | tr.listen p, 444 | tr.throw p, 445 | tr.emit p{ 446 | margin-bottom: 10px; 447 | } 448 | 449 | .version, .since { 450 | color: #aaa; 451 | } 452 | 453 | h3 .right-info { 454 | position: absolute; 455 | right: 4px; 456 | font-size: 14px; 457 | } 458 | 459 | .version + .since:before { 460 | content: '| '; 461 | } 462 | 463 | .see { 464 | margin-top: 10px; 465 | } 466 | 467 | .see h4 { 468 | margin: 4px 0; 469 | } 470 | 471 | .content .detail h4 + .example-doc { 472 | margin: 6px 0; 473 | } 474 | 475 | .example-caption { 476 | position: relative; 477 | bottom: -1px; 478 | display: inline-block; 479 | padding: 4px; 480 | font-style: italic; 481 | background-color: #f5f5f5; 482 | font-weight: bold; 483 | border-radius: 3px; 484 | border-bottom-left-radius: 0; 485 | border-bottom-right-radius: 0; 486 | } 487 | 488 | .example-caption + pre.source-code { 489 | margin-top: 0; 490 | border-top-left-radius: 0; 491 | } 492 | 493 | footer, .file-footer { 494 | text-align: right; 495 | font-style: italic; 496 | font-weight: 100; 497 | font-size: 13px; 498 | margin-right: 50px; 499 | margin-left: 270px; 500 | border-top: 1px solid #ddd; 501 | padding-top: 30px; 502 | margin-top: 20px; 503 | padding-bottom: 10px; 504 | } 505 | 506 | pre.source-code { 507 | background: #f5f5f5; 508 | padding: 4px; 509 | } 510 | 511 | pre.raw-source-code > code { 512 | padding: 0; 513 | margin: 0; 514 | } 515 | 516 | pre.source-code.line-number { 517 | padding: 0; 518 | } 519 | 520 | pre.source-code ol { 521 | background: #eee; 522 | padding-left: 40px; 523 | } 524 | 525 | pre.source-code li { 526 | background: white; 527 | padding-left: 4px; 528 | list-style: decimal; 529 | margin: 0; 530 | } 531 | 532 | pre.source-code.line-number li.active { 533 | background: rgb(255, 255, 150); 534 | } 535 | 536 | pre.source-code.line-number li.error-line { 537 | background: #ffb8bf; 538 | } 539 | 540 | table.files-summary { 541 | width: 100%; 542 | margin: 10px 0; 543 | border-spacing: 0; 544 | border: 0; 545 | border-collapse: collapse; 546 | text-align: right; 547 | } 548 | 549 | table.files-summary tbody tr:hover { 550 | background: #eee; 551 | } 552 | 553 | table.files-summary td:first-child, 554 | table.files-summary td:nth-of-type(2) { 555 | text-align: left; 556 | } 557 | 558 | table.files-summary[data-use-coverage="false"] td.coverage { 559 | display: none; 560 | } 561 | 562 | table.files-summary thead { 563 | background: #999; 564 | color: white; 565 | } 566 | 567 | table.files-summary td { 568 | border: solid 1px #ddd; 569 | padding: 4px 10px; 570 | vertical-align: top; 571 | } 572 | 573 | table.files-summary td.identifiers > span { 574 | display: block; 575 | margin-top: 4px; 576 | } 577 | table.files-summary td.identifiers > span:first-child { 578 | margin-top: 0; 579 | } 580 | 581 | table.files-summary .coverage-count { 582 | font-size: 12px; 583 | color: #aaa; 584 | display: inline-block; 585 | min-width: 40px; 586 | } 587 | 588 | .total-coverage-count { 589 | position: relative; 590 | bottom: 2px; 591 | font-size: 12px; 592 | color: #666; 593 | font-weight: 500; 594 | padding-left: 5px; 595 | } 596 | 597 | table.test-summary thead { 598 | background: #999; 599 | color: white; 600 | } 601 | 602 | table.test-summary thead .test-description { 603 | width: 50%; 604 | } 605 | 606 | table.test-summary { 607 | width: 100%; 608 | margin: 10px 0; 609 | border-spacing: 0; 610 | border: 0; 611 | border-collapse: collapse; 612 | } 613 | 614 | table.test-summary thead .test-count { 615 | width: 3em; 616 | } 617 | 618 | table.test-summary tbody tr:hover { 619 | background-color: #eee; 620 | } 621 | 622 | table.test-summary td { 623 | border: solid 1px #ddd; 624 | padding: 4px 10px; 625 | vertical-align: top; 626 | } 627 | 628 | table.test-summary td p { 629 | margin: 0; 630 | } 631 | 632 | table.test-summary tr.test-describe .toggle { 633 | display: inline-block; 634 | float: left; 635 | margin-right: 4px; 636 | cursor: pointer; 637 | } 638 | 639 | table.test-summary tr.test-describe .toggle.opened:before { 640 | content: '▼'; 641 | } 642 | 643 | table.test-summary tr.test-describe .toggle.closed:before { 644 | content: '▶'; 645 | } 646 | 647 | table.test-summary .test-target > span { 648 | display: block; 649 | margin-top: 4px; 650 | } 651 | table.test-summary .test-target > span:first-child { 652 | margin-top: 0; 653 | } 654 | 655 | .inner-link-active { 656 | background: rgb(255, 255, 150); 657 | } 658 | 659 | /* search box */ 660 | .search-box { 661 | position: absolute; 662 | top: 10px; 663 | right: 50px; 664 | padding-right: 8px; 665 | padding-bottom: 10px; 666 | line-height: normal; 667 | font-size: 12px; 668 | } 669 | 670 | .search-box img { 671 | width: 20px; 672 | vertical-align: top; 673 | } 674 | 675 | .search-input { 676 | display: inline; 677 | visibility: hidden; 678 | width: 0; 679 | padding: 2px; 680 | height: 1.5em; 681 | outline: none; 682 | background: transparent; 683 | border: 1px #0af; 684 | border-style: none none solid none; 685 | vertical-align: bottom; 686 | } 687 | 688 | .search-input-edge { 689 | display: none; 690 | width: 1px; 691 | height: 5px; 692 | background-color: #0af; 693 | vertical-align: bottom; 694 | } 695 | 696 | .search-result { 697 | position: absolute; 698 | display: none; 699 | height: 600px; 700 | width: 100%; 701 | padding: 0; 702 | margin-top: 5px; 703 | margin-left: 24px; 704 | background: white; 705 | box-shadow: 1px 1px 4px rgb(0,0,0); 706 | white-space: nowrap; 707 | overflow-y: scroll; 708 | } 709 | 710 | .search-result-import-path { 711 | color: #aaa; 712 | font-size: 12px; 713 | } 714 | 715 | .search-result li { 716 | list-style: none; 717 | padding: 2px 4px; 718 | } 719 | 720 | .search-result li a { 721 | display: block; 722 | } 723 | 724 | .search-result li.selected { 725 | background: #ddd; 726 | } 727 | 728 | .search-result li.search-separator { 729 | background: rgb(37, 138, 175); 730 | color: white; 731 | } 732 | 733 | .search-box.active .search-input { 734 | visibility: visible; 735 | transition: width 0.2s ease-out; 736 | width: 300px; 737 | } 738 | 739 | .search-box.active .search-input-edge { 740 | display: inline-block; 741 | } 742 | 743 | /* coverage badge */ 744 | .esdoc-coverage { 745 | display: inline-block; 746 | height: 20px; 747 | vertical-align: top; 748 | } 749 | 750 | h1 .esdoc-coverage { 751 | position: relative; 752 | top: -4px; 753 | } 754 | 755 | .esdoc-coverage-wrap { 756 | color: white; 757 | font-size: 12px; 758 | font-weight: 500; 759 | } 760 | 761 | .esdoc-coverage-label { 762 | padding: 3px 4px 3px 6px; 763 | background: linear-gradient(to bottom, #5e5e5e 0%,#4c4c4c 100%); 764 | border-radius: 4px 0 0 4px; 765 | display: inline-block; 766 | height: 20px; 767 | box-sizing: border-box; 768 | line-height: 14px; 769 | } 770 | 771 | .esdoc-coverage-ratio { 772 | padding: 3px 6px 3px 4px; 773 | border-radius: 0 4px 4px 0; 774 | display: inline-block; 775 | height: 20px; 776 | box-sizing: border-box; 777 | line-height: 14px; 778 | } 779 | 780 | .esdoc-coverage-low { 781 | background: linear-gradient(to bottom, #db654f 0%,#c9533d 100%); 782 | } 783 | 784 | .esdoc-coverage-middle { 785 | background: linear-gradient(to bottom, #dab226 0%,#c9a179 100%); 786 | } 787 | 788 | .esdoc-coverage-high { 789 | background: linear-gradient(to bottom, #4fc921 0%,#3eb810 100%); 790 | } 791 | 792 | .github-markdown .manual-toc { 793 | padding-left: 0; 794 | } 795 | 796 | /** manual */ 797 | 798 | .manual-root .navigation { 799 | padding-left: 0; 800 | } 801 | 802 | .navigation .manual-toc-title { 803 | margin: 0; 804 | padding: 0.5em 0 0.5em 1em; 805 | border: none; 806 | font-size: 1em; 807 | font-weight: normal; 808 | } 809 | 810 | .navigation .manual-toc-title:first-child { 811 | margin-top: 0; 812 | } 813 | 814 | .navigation .manual-toc { 815 | display: none; 816 | margin-left: 0.5em; 817 | margin-top: -0.25em; 818 | } 819 | 820 | .github-markdown .manual-toc-title a { 821 | color: inherit; 822 | } 823 | 824 | .manual-breadcrumb-list { 825 | font-size: 0.8em; 826 | margin-bottom: 1em; 827 | } 828 | 829 | .manual-toc-title a:hover { 830 | color: #039BE5; 831 | } 832 | 833 | .manual-toc li { 834 | margin: 0.75em 0; 835 | list-style-type: none; 836 | } 837 | 838 | .manual-toc .indent-h1 { 839 | margin-left: 0; 840 | } 841 | .manual-toc .indent-h2 { 842 | margin-left: 1em; 843 | } 844 | .manual-toc .indent-h3 { 845 | margin-left: 3em; 846 | } 847 | .manual-toc .indent-h4 { 848 | margin-left: 4em; 849 | } 850 | .manual-toc .indent-h5 { 851 | margin-left: 5em; 852 | } 853 | 854 | .manual-nav li { 855 | margin: 0.75em 0; 856 | } 857 | 858 | .manual-dot { 859 | margin-left: 0.75em; 860 | width: 0.6em; 861 | height: 0.6em; 862 | display: inline-block; 863 | border-radius: 0.3em; 864 | margin-right: 0.3em; 865 | background-color: #bfe5bf; 866 | } 867 | 868 | /* github markdown */ 869 | .github-markdown { 870 | font-size: 16px; 871 | } 872 | 873 | .github-markdown h1, 874 | .github-markdown h2, 875 | .github-markdown h3, 876 | .github-markdown h4, 877 | .github-markdown h5 { 878 | margin-top: 1em; 879 | margin-bottom: 16px; 880 | font-weight: bold; 881 | padding: 0; 882 | } 883 | 884 | .github-markdown h1:nth-of-type(1) { 885 | margin-top: 0; 886 | } 887 | 888 | .github-markdown h1 { 889 | font-size: 2em; 890 | padding-bottom: 0.3em; 891 | } 892 | 893 | .github-markdown h2 { 894 | font-size: 1.75em; 895 | padding-bottom: 0.3em; 896 | } 897 | 898 | .github-markdown h3 { 899 | font-size: 1.5em; 900 | background-color: transparent; 901 | } 902 | 903 | .github-markdown h4 { 904 | font-size: 1.25em; 905 | } 906 | 907 | .github-markdown h5 { 908 | font-size: 1em; 909 | } 910 | 911 | .github-markdown ul, .github-markdown ol { 912 | padding-left: 2em; 913 | } 914 | 915 | .github-markdown pre > code { 916 | font-size: 0.85em; 917 | } 918 | 919 | .github-markdown table { 920 | margin-bottom: 1em; 921 | border-collapse: collapse; 922 | border-spacing: 0; 923 | } 924 | 925 | .github-markdown table tr { 926 | background-color: #fff; 927 | border-top: 1px solid #ccc; 928 | } 929 | 930 | .github-markdown table th, 931 | .github-markdown table td { 932 | padding: 6px 13px; 933 | border: 1px solid #ddd; 934 | } 935 | 936 | .github-markdown table tr:nth-child(2n) { 937 | background-color: #f8f8f8; 938 | } 939 | 940 | /** badge(.svg) does not have border */ 941 | .github-markdown img:not([src*=".svg"]) { 942 | max-width: 100%; 943 | box-shadow: 1px 1px 1px rgba(0,0,0,0.5); 944 | } 945 | -------------------------------------------------------------------------------- /docs/file/src/index.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | src/index.js | API Document 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | Home 18 | 19 | Reference 20 | Source 21 | 22 | Repository 23 | 30 |
31 | 32 | 41 | 42 |

src/index.js

43 |
import validate from './validate'
 44 | import { addQueryParams, mixinDynamicSegmentsValues } from './utils/url'
 45 | 
 46 | const identity = x => x
 47 | 
 48 | const defaultParams = {
 49 |   executor: null,
 50 |   url: null,
 51 |   method: null,
 52 |   headers: [],
 53 |   body: null,
 54 |   responseType: null,
 55 |   dynamicSegments: [],
 56 |   queryParams: [],
 57 |   bodyProcessor: identity,
 58 |   responseProcessor: identity
 59 | }
 60 | 
 61 | class Internals {
 62 |   constructor (params) {
 63 |     Object.entries(params)
 64 |       .map(([key, value]) =>
 65 |         Object.defineProperty(this, key, {
 66 |           get: () => value,
 67 |           enumerable: true,
 68 |           configurable: true
 69 |         }))
 70 |   }
 71 | }
 72 | 
 73 | /**
 74 |  * @typedef {[key: string, value: string]} Tuple
 75 |  */
 76 | 
 77 |  /**
 78 |   * @typedef {Object} HttpRequestParams
 79 |   * @property {string} url resource url
 80 |   * @property {string} method HTTP method,
 81 |   * @property {Tuple[]} headers array of HTTP headers key-value pairs
 82 |   * @property {Object} body request payload
 83 |   * @property {string} responseType response type
 84 |   * @property {Tuple[]} dynamicSegments key-value array of replacements for the provided url
 85 |   * @property {Tuple[]} queryParams key-value array of url params
 86 |   * @property {function(x: Object): Object} bodyProcessor map body function
 87 |   * @property {function(x: Object): Object} responseProcessor map response function
 88 |   * @property {function(url: string, method: string, headers: string[], responseType: string, body: Object): Promise} executor performs HTTP request and returns Promise,
 89 |   */
 90 | 
 91 | // executor: function(url: string, method: string, headers: string[], responseType: string, body: Object): Promise,
 92 | // bodyProcessor: function(x: Object): Object, responseProcessor: function(x: Object): Object
 93 | 
 94 | /**
 95 |  * Http request object.
 96 |  * Expose chainable API
 97 |  */
 98 | export default class Http {
 99 | 
100 |   /**
101 |    * @param {HttpRequestParams} params - HTTP request params
102 |    */
103 |   constructor (params = defaultParams) {
104 |     const internals = new Internals(params)
105 |     this.internals = () => internals
106 |   }
107 | 
108 |   /**
109 |    * Set the middleware that will perform the request
110 |    * @param {function(url: string, method: string, headers: string[], responseType: string, body: Object): Promise} executor -
111 |    * function which performs the request asynchroniously and returns Promise back
112 |    * @returns {Object} Http object
113 |    */
114 |   executor (executor) {
115 |     return new Http(Object.assign({}, this.internals(), { executor }))
116 |   }
117 | 
118 |   /**
119 |    * Adds URL information to HTTP request model
120 |    * @param {string} url - URL
121 |    * @returns {Object} Http object
122 |    */
123 |   url (url) {
124 |     return new Http(Object.assign({}, this.internals(), { url }))
125 |   }
126 | 
127 |   /**
128 |    * Adds HTTP method information to request model
129 |    * @param {string} method - HTTP method
130 |    * @returns {Object} Http object
131 |    */
132 |   method (method) {
133 |     return new Http(Object.assign({}, this.internals(), { method }))
134 |   }
135 | 
136 |   /**
137 |    * Adds header to request model
138 |    * @param {string} header - valid header key
139 |    * @param {string} value - valid header value
140 |    * @returns {Object} Http object
141 |    */
142 |   header (header, value) {
143 |     const headers = this.internals().headers.concat([[header, value]])
144 |     return new Http(Object.assign({}, this.internals(), { headers }))
145 |   }
146 | 
147 |   /**
148 |    * Adds body to request model
149 |    * @param {Object} body - request payload
150 |    * @returns {Object} Http object
151 |    */
152 |   body (body) {
153 |     return new Http(Object.assign({}, this.internals(), { body }))
154 |   }
155 | 
156 |   /**
157 |    * Sets response content type
158 |    * Proper values could be obtained form XmlHttpRequest specification
159 |    * https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#Properties
160 |    * @param {string} responseType - Proper values could be obtained form
161 |    * XmlHttpRequest specification
162 |    * https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#Properties
163 |    * @returns {Object} Http object
164 |    */
165 |   responseType (responseType) {
166 |     return new Http(Object.assign({}, this.internals(), { responseType }))
167 |   }
168 | 
169 |   /**
170 |    * Adds dynamic segment value
171 |    * @param {string} segment - segment key
172 |    * @param {string} value - segment value
173 |    * @returns {Object} Http object
174 |    */
175 |   segment (segment, value) {
176 |     const dynamicSegments
177 |       = this.internals().dynamicSegments.concat([[segment, value]])
178 |     return new Http(Object.assign({}, this.internals(), { dynamicSegments }))
179 |   }
180 | 
181 |   /**
182 |    * Adds query string param
183 |    * @param {string} name - param key
184 |    * @param {string} value - param value
185 |    * @returns {Object} Http object
186 |    */
187 |   query (name, value) {
188 |     const queryParams = this.internals().queryParams.concat([[name, value]])
189 |     return new Http(Object.assign({}, this.internals(), { queryParams }))
190 |   }
191 | 
192 |   /**
193 |    * Sets the function which gets the body object as a parameter
194 |    * which result would be used as a request body
195 |    * @param {func} bodyProcessor - f(x) => valid_http_body
196 |    * @returns {Object} Http object
197 |    */
198 |   bodyProcessor (bodyProcessor) {
199 |     return new Http(Object.assign({}, this.internals(), { bodyProcessor }))
200 |   }
201 | 
202 |   /**
203 |    * Sets the function which gets the response and produces another value
204 |    * Useful for default HTTP error handling
205 |    *
206 |    * @example
207 |    * response => {
208 |    *  switch(response.code) {
209 |    *    case "404":
210 |    *      return { message: 'Resource not found' }
211 |    *  }
212 |    *}
213 |    *
214 |    * @param {func} responseProcessor - f(x) => y
215 |    * @returns {Object} Http object
216 |    */
217 |   responseProcessor (responseProcessor) {
218 |     return new Http(Object.assign({}, this.internals(), { responseProcessor }))
219 |   }
220 | 
221 |   /**
222 |    * Executes HTTP request
223 |    * @returns {Object} - Promise
224 |    */
225 |   exec () {
226 |     const {
227 |       url, method, headers, responseType, dynamicSegments, queryParams, body,
228 |       bodyProcessor, responseProcessor, executor
229 |     } = this.internals()
230 |     if (!executor) {
231 |       throw new Error('executor was not set')
232 |     }
233 |     const errors = validate(url, method, headers, responseType)
234 |     if (errors.length !== 0)
235 |       throw new Error(errors.join('\n'))
236 |     const urlWithDynamicSegments
237 |       = mixinDynamicSegmentsValues(url, dynamicSegments)
238 |     const fullUrl = addQueryParams(urlWithDynamicSegments, queryParams)
239 |     return executor(
240 |       fullUrl, method, headers, responseType, bodyProcessor(body)
241 |     ).then(responseProcessor)
242 |   }
243 | }
244 | 
245 | 246 |
247 | 248 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | -------------------------------------------------------------------------------- /docs/file/src/utils/url.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | src/utils/url.js | API Document 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | Home 18 | 19 | Reference 20 | Source 21 | 22 | Repository 23 | 30 |
31 | 32 | 41 | 42 |

src/utils/url.js

43 |
/**
44 |  * @ignore
45 |  * Mixins dynamic segments replacing the `:segment_name` parts with provide
46 |  * values
47 |  * @param {String} url – URL
48 |  * @param {Object} dynamicSegments – dynamic segments
49 |  * @returns {String} – URL
50 |  */
51 | export function mixinDynamicSegmentsValues (url, dynamicSegments) {
52 |   return dynamicSegments.reduce((aggr, [key, value]) =>
53 |     aggr.replace(`:${key}`, value), url)
54 | }
55 | 
56 | /**
57 |  * @ignore
58 |  * Adds query params string to url
59 |  * @param {string} url – URL
60 |  * @param {Array} queryParams – query params
61 |  * @returns {String} – URL
62 |  */
63 | export function addQueryParams (url, queryParams) {
64 |   const chanks = queryParams.map(([key, value]) => `${key}=${value}`)
65 |   return url + (chanks.length !== 0 ? '?' + chanks.join('&') : '')
66 | }
67 | 
68 | 69 |
70 | 71 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /docs/file/src/validate.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | src/validate.js | API Document 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | Home 18 | 19 | Reference 20 | Source 21 | 22 | Repository 23 | 30 |
31 | 32 | 41 | 42 |

src/validate.js

43 |
import option from 'option'
 44 | 
 45 | const supportedMethods = ['GET', 'POST', 'PUT', 'DELETE']
 46 | const validTypes = [null, '', 'arraybuffer', 'blob', 'document', 'text', 'json']
 47 | 
 48 | /**
 49 |  * Validate HTTP method
 50 |  * @param {String} method – HTTP method
 51 |  * @return {String} error
 52 |  */
 53 | function validateMethod (method) {
 54 |   if (!method) {
 55 |     return option.some('HTTP method is not specified')
 56 |   }
 57 |   if (typeof method !== 'string') {
 58 |     return option.some('HTTP method should be type of string')
 59 |   }
 60 |   if (supportedMethods.indexOf(method.toUpperCase()) < 0) {
 61 |     return option.some(`Http method ${method} is not supported`)
 62 |   }
 63 |   return option.none
 64 | }
 65 | 
 66 | /**
 67 |  * Basicly validate url
 68 |  * @param {String} url – URL
 69 |  * @return {String} error
 70 |  */
 71 | function validateUrl (url) {
 72 |   if (!url) {
 73 |     return option.some('Url is not specified')
 74 |   }
 75 |   if (typeof url !== 'string') {
 76 |     return option.some('Url should be type of string')
 77 |   }
 78 |   return option.none
 79 | }
 80 | 
 81 | /**
 82 |  * Validate header to all parts be strings
 83 |  * @param {String} key – Header key
 84 |  * @param {String} value – Header value
 85 |  * @return {String} error
 86 |  */
 87 | function validateHeader (key, value) {
 88 |   if (typeof key !== 'string' || typeof value !== 'string')
 89 |     return option.some(`Parts of header ${key}:${value} must be strings`)
 90 |   return option.none
 91 | }
 92 | 
 93 | /**
 94 |  * Validate headers
 95 |  * @param {Object} headers – headers
 96 |  * @return {Array} error
 97 |  */
 98 | function validateHeaders (headers) {
 99 |   const aggr = []
100 |   for (let [key, value] of headers)
101 |     aggr.push(validateHeader(key, value))
102 |   return aggr
103 | }
104 | 
105 | /**
106 |  * Validates response type
107 |  * @param {string} type - response type
108 |  * @return {String} error
109 |  */
110 | function validateResponseType (type) {
111 |   if (validTypes.indexOf(type) < 0)
112 |     return option.some(`Response content type ${type} is not supported`)
113 |   return option.none
114 | }
115 | 
116 | /**
117 |  * @ignore
118 |  * Validate HTTP request model
119 |  * @param {String} url – url
120 |  * @param {String} method – HTTP method
121 |  * @param {Map} headers – HTTP headers
122 |  * @param {String} responseType – response type
123 |  * @return {Array} array of errors
124 |  */
125 | function validate (url, method, headers, responseType) {
126 |   return [validateUrl(url),
127 |     validateMethod(method),
128 |     validateResponseType(responseType)]
129 |     .concat(validateHeaders(headers)).filter(_ => _.isSome()).map(_ => _.value())
130 | }
131 | 
132 | export default validate
133 | 
134 | 135 |
136 | 137 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /docs/identifiers.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Index | API Document 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | Home 18 | 19 | Reference 20 | Source 21 | 22 | Repository 23 | 30 |
31 | 32 | 41 | 42 |

References

43 |

Class Summary

44 | 45 | 46 | 47 | 48 | 55 | 68 | 72 | 73 | 74 |
Static Public Class Summary
49 | public 50 | 51 | 52 | 53 | 54 | 56 |
57 |

58 | Http 59 |

60 |
61 |
62 | 63 | 64 |

Http request object.

65 |
66 |
67 |
69 | 70 | 71 |
75 |
76 | 77 | 78 | 79 |

Typedef Summary

80 | 81 | 82 | 83 | 84 | 91 | 103 | 107 | 108 | 109 | 116 | 128 | 132 | 133 | 134 |
Static Public Typedef Summary
85 | public 86 | 87 | 88 | 89 | 90 | 92 |
93 |

94 | HttpRequestParams: Object 95 |

96 |
97 |
98 | 99 | 100 | 101 |
102 |
104 | 105 | 106 |
110 | public 111 | 112 | 113 | 114 | 115 | 117 |
118 |

119 | Tuple: [key: string, value: string] 120 |

121 |
122 |
123 | 124 | 125 | 126 |
127 |
129 | 130 | 131 |
135 |
136 | 137 |
138 | 139 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /docs/image/badge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | document 13 | document 14 | @ratio@ 15 | @ratio@ 16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/image/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stremlenye/immutable-http/4d46a66cc11cd02d96be63a3283bbfe7df1272c3/docs/image/github.png -------------------------------------------------------------------------------- /docs/image/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stremlenye/immutable-http/4d46a66cc11cd02d96be63a3283bbfe7df1272c3/docs/image/search.png -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | API Document 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | Home 18 | 19 | Reference 20 | Source 21 | 22 | Repository 23 | 30 |
31 | 32 | 41 | 42 |

Immutable-http

43 |

npm version 44 | Build Status

45 |

Http client with pretty simple chaining API

46 |

Docs

47 |

Usage

48 |
import executor from 'third-party-executor'
49 | 
50 | var result = new Http().url('http://any_api.com/:id')
51 |                         .executor(executor)
52 |                         .method('GET')
53 |                         .header('Content-Type','application/json')
54 |                         .body({some:data})
55 |                         .responseType('json')
56 |                         .segment('id',123)
57 |                         .query('filter','some_filter') // Adds query section for the url like '?filter=some_filter'
58 |                         .exec(); // returns Promise
59 | 
60 |

executor is just a function with signature

61 |
f(url: String, method: String, headers:Array[Tuple[String, String]], responseType: String, body: Any): Promise
62 | 
63 |

It allows you to have your own favorite HTTP library under the hood and be able to test your code with mocked executor without any hacks. 64 | Executor implementation example

65 |

Build

66 |
npm run dist
67 | 

Tests

68 |

Run

69 |
npm test
70 | 
71 |
72 | 73 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "immutable-http", 3 | "version": "4.0.0", 4 | "description": "Http client with pretty simple chaining API", 5 | "keywords": [ 6 | "javascript", 7 | "xhr", 8 | "http", 9 | "rest" 10 | ], 11 | "scripts": { 12 | "doc": "rm -rf docs && esdoc -c ./esdoc.json", 13 | "doc:publish": "gh-pages -d docs", 14 | "lint": "eslint src test", 15 | "test": "karma start --single-run", 16 | "test:debug": "karma start", 17 | "test:ci": "karma start --single-run --browsers PhantomJS", 18 | "clean": "rm -rf ./dist", 19 | "dist": "npm run clean && mkdir dist && webpack --progress --colors --config webpack.config.js", 20 | "prepublish:supressed": "npm run dist && npm run doc && npm run doc:publish" 21 | }, 22 | "main": "dist/index.js", 23 | "homepage": "http://stremlenye.github.io/immutable-http/", 24 | "bugs": { 25 | "url": "https://github.com/stremlenye/immutable-http/issues" 26 | }, 27 | "license": "MIT", 28 | "people": { 29 | "author": { 30 | "name": "Yuriy Ankudinov", 31 | "email": "stremlenye@gmail.com", 32 | "url": "https://github.com/stremlenye" 33 | } 34 | }, 35 | "repository": { 36 | "type": "git", 37 | "url": "https://github.com/stremlenye/immutable-http.git" 38 | }, 39 | "devDependencies": { 40 | "babel": "^6.5.2", 41 | "babel-core": "^6.7.4", 42 | "babel-eslint": "^6.0.2", 43 | "babel-loader": "^6.2.4", 44 | "babel-polyfill": "^6.7.4", 45 | "babel-preset-es2015": "^6.6.0", 46 | "body-parser": "^1.15.0", 47 | "chai": "^3.2.0", 48 | "cors": "^2.7.1", 49 | "esdoc": "^0.4.6", 50 | "esdoc-es7-plugin": "0.0.3", 51 | "eslint": "^2.5.3", 52 | "express": "^4.13.3", 53 | "gh-pages": "^0.11.0", 54 | "karma": "^0.13.22", 55 | "karma-chrome-launcher": "^0.2.3", 56 | "karma-firefox-launcher": "^0.1.6", 57 | "karma-mocha": "^0.2.2", 58 | "karma-phantomjs-launcher": "^1.0.0", 59 | "karma-webpack": "^1.7.0", 60 | "mocha": "^2.3.2", 61 | "phantomjs-prebuilt": "^2.1.7", 62 | "webpack": "^1.12.14" 63 | }, 64 | "dependencies": { 65 | "babel-runtime": "^6.6.1", 66 | "option": "^0.2.3" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /docs/script/inherited-summary.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | function toggle(ev) { 3 | var button = ev.target; 4 | var parent = ev.target.parentElement; 5 | while(parent) { 6 | if (parent.tagName === 'TABLE' && parent.classList.contains('summary')) break; 7 | parent = parent.parentElement; 8 | } 9 | 10 | if (!parent) return; 11 | 12 | var tbody = parent.querySelector('tbody'); 13 | if (button.classList.contains('opened')) { 14 | button.classList.remove('opened'); 15 | button.classList.add('closed'); 16 | tbody.style.display = 'none'; 17 | } else { 18 | button.classList.remove('closed'); 19 | button.classList.add('opened'); 20 | tbody.style.display = 'block'; 21 | } 22 | } 23 | 24 | var buttons = document.querySelectorAll('.inherited-summary thead .toggle'); 25 | for (var i = 0; i < buttons.length; i++) { 26 | buttons[i].addEventListener('click', toggle); 27 | } 28 | })(); 29 | -------------------------------------------------------------------------------- /docs/script/inner-link.js: -------------------------------------------------------------------------------- 1 | // inner link(#foo) can not correctly scroll, because page has fixed header, 2 | // so, I manually scroll. 3 | (function(){ 4 | var matched = location.hash.match(/errorLines=([\d,]+)/); 5 | if (matched) return; 6 | 7 | function adjust() { 8 | window.scrollBy(0, -55); 9 | var el = document.querySelector('.inner-link-active'); 10 | if (el) el.classList.remove('inner-link-active'); 11 | 12 | // ``[ ] . ' " @`` are not valid in DOM id. so must escape these. 13 | var id = location.hash.replace(/([\[\].'"@$])/g, '\\$1'); 14 | var el = document.querySelector(id); 15 | if (el) el.classList.add('inner-link-active'); 16 | } 17 | 18 | window.addEventListener('hashchange', adjust); 19 | 20 | if (location.hash) { 21 | setTimeout(adjust, 0); 22 | } 23 | })(); 24 | 25 | (function(){ 26 | var els = document.querySelectorAll('[href^="#"]'); 27 | for (var i = 0; i < els.length; i++) { 28 | var el = els[i]; 29 | el.href = location.href + el.getAttribute('href'); // because el.href is absolute path 30 | } 31 | })(); 32 | -------------------------------------------------------------------------------- /docs/script/manual.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | var matched = location.pathname.match(/([^/]*)\.html$/); 3 | if (!matched) return; 4 | 5 | var currentName = matched[1]; 6 | var cssClass = '.navigation [data-toc-name="' + currentName + '"]'; 7 | var styleText = cssClass + ' .manual-toc { display: block; }\n'; 8 | styleText += cssClass + ' .manual-toc-title { background-color: #039BE5; }\n'; 9 | styleText += cssClass + ' .manual-toc-title a { color: white; }\n'; 10 | var style = document.createElement('style'); 11 | style.textContent = styleText; 12 | document.querySelector('head').appendChild(style); 13 | })(); 14 | -------------------------------------------------------------------------------- /docs/script/patch-for-local.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | if (location.protocol === 'file:') { 3 | var elms = document.querySelectorAll('a[href="./"]'); 4 | for (var i = 0; i < elms.length; i++) { 5 | elms[i].href = './index.html'; 6 | } 7 | } 8 | })(); 9 | -------------------------------------------------------------------------------- /docs/script/prettify/Apache-License-2.0.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /docs/script/prettify/prettify.js: -------------------------------------------------------------------------------- 1 | var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; 2 | (function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= 3 | [],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), 9 | l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, 10 | q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, 11 | q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, 12 | "");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), 13 | a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} 14 | for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], 18 | "catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], 19 | H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], 20 | J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ 21 | I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), 22 | ["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", 23 | /^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), 24 | ["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", 25 | hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p=0){var k=k.match(g),f,b;if(b= 26 | !k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p' + pair[2] + ''); 35 | } 36 | } 37 | 38 | var innerHTML = ''; 39 | for (kind in html) { 40 | var list = html[kind]; 41 | if (!list.length) continue; 42 | innerHTML += '
  • ' + kind + '
  • \n' + list.join('\n'); 43 | } 44 | result.innerHTML = innerHTML; 45 | if (innerHTML) result.style.display = 'block'; 46 | selectedIndex = -1; 47 | }); 48 | 49 | // down, up and enter key are pressed, select search result. 50 | input.addEventListener('keydown', function(ev){ 51 | if (ev.keyCode === 40) { 52 | // arrow down 53 | var current = result.children[selectedIndex]; 54 | var selected = result.children[selectedIndex + 1]; 55 | if (selected && selected.classList.contains('search-separator')) { 56 | var selected = result.children[selectedIndex + 2]; 57 | selectedIndex++; 58 | } 59 | 60 | if (selected) { 61 | if (current) current.classList.remove('selected'); 62 | selectedIndex++; 63 | selected.classList.add('selected'); 64 | } 65 | } else if (ev.keyCode === 38) { 66 | // arrow up 67 | var current = result.children[selectedIndex]; 68 | var selected = result.children[selectedIndex - 1]; 69 | if (selected && selected.classList.contains('search-separator')) { 70 | var selected = result.children[selectedIndex - 2]; 71 | selectedIndex--; 72 | } 73 | 74 | if (selected) { 75 | if (current) current.classList.remove('selected'); 76 | selectedIndex--; 77 | selected.classList.add('selected'); 78 | } 79 | } else if (ev.keyCode === 13) { 80 | // enter 81 | var current = result.children[selectedIndex]; 82 | if (current) { 83 | var link = current.querySelector('a'); 84 | if (link) location.href = link.href; 85 | } 86 | } else { 87 | return; 88 | } 89 | 90 | ev.preventDefault(); 91 | }); 92 | 93 | // select search result when search result is mouse over. 94 | result.addEventListener('mousemove', function(ev){ 95 | var current = result.children[selectedIndex]; 96 | if (current) current.classList.remove('selected'); 97 | 98 | var li = ev.target; 99 | while (li) { 100 | if (li.nodeName === 'LI') break; 101 | li = li.parentElement; 102 | } 103 | 104 | if (li) { 105 | selectedIndex = Array.prototype.indexOf.call(result.children, li); 106 | li.classList.add('selected'); 107 | } 108 | }); 109 | 110 | // clear search result when body is clicked. 111 | document.body.addEventListener('click', function(ev){ 112 | selectedIndex = -1; 113 | result.style.display = 'none'; 114 | result.innerHTML = ''; 115 | }); 116 | 117 | })(); 118 | -------------------------------------------------------------------------------- /docs/script/search_index.js: -------------------------------------------------------------------------------- 1 | window.esdocSearchIndex = [ 2 | [ 3 | "immutable-http/src/index.js~http", 4 | "class/src/index.js~Http.html", 5 | "Http immutable-http/src/index.js", 6 | "class" 7 | ], 8 | [ 9 | "builtinexternal/ecmascriptexternal.js~array", 10 | "external/index.html", 11 | "BuiltinExternal/ECMAScriptExternal.js~Array", 12 | "external" 13 | ], 14 | [ 15 | "builtinexternal/ecmascriptexternal.js~arraybuffer", 16 | "external/index.html", 17 | "BuiltinExternal/ECMAScriptExternal.js~ArrayBuffer", 18 | "external" 19 | ], 20 | [ 21 | "builtinexternal/ecmascriptexternal.js~boolean", 22 | "external/index.html", 23 | "BuiltinExternal/ECMAScriptExternal.js~Boolean", 24 | "external" 25 | ], 26 | [ 27 | "builtinexternal/ecmascriptexternal.js~dataview", 28 | "external/index.html", 29 | "BuiltinExternal/ECMAScriptExternal.js~DataView", 30 | "external" 31 | ], 32 | [ 33 | "builtinexternal/ecmascriptexternal.js~date", 34 | "external/index.html", 35 | "BuiltinExternal/ECMAScriptExternal.js~Date", 36 | "external" 37 | ], 38 | [ 39 | "builtinexternal/ecmascriptexternal.js~error", 40 | "external/index.html", 41 | "BuiltinExternal/ECMAScriptExternal.js~Error", 42 | "external" 43 | ], 44 | [ 45 | "builtinexternal/ecmascriptexternal.js~evalerror", 46 | "external/index.html", 47 | "BuiltinExternal/ECMAScriptExternal.js~EvalError", 48 | "external" 49 | ], 50 | [ 51 | "builtinexternal/ecmascriptexternal.js~float32array", 52 | "external/index.html", 53 | "BuiltinExternal/ECMAScriptExternal.js~Float32Array", 54 | "external" 55 | ], 56 | [ 57 | "builtinexternal/ecmascriptexternal.js~float64array", 58 | "external/index.html", 59 | "BuiltinExternal/ECMAScriptExternal.js~Float64Array", 60 | "external" 61 | ], 62 | [ 63 | "builtinexternal/ecmascriptexternal.js~function", 64 | "external/index.html", 65 | "BuiltinExternal/ECMAScriptExternal.js~Function", 66 | "external" 67 | ], 68 | [ 69 | "builtinexternal/ecmascriptexternal.js~generator", 70 | "external/index.html", 71 | "BuiltinExternal/ECMAScriptExternal.js~Generator", 72 | "external" 73 | ], 74 | [ 75 | "builtinexternal/ecmascriptexternal.js~generatorfunction", 76 | "external/index.html", 77 | "BuiltinExternal/ECMAScriptExternal.js~GeneratorFunction", 78 | "external" 79 | ], 80 | [ 81 | "builtinexternal/ecmascriptexternal.js~infinity", 82 | "external/index.html", 83 | "BuiltinExternal/ECMAScriptExternal.js~Infinity", 84 | "external" 85 | ], 86 | [ 87 | "builtinexternal/ecmascriptexternal.js~int16array", 88 | "external/index.html", 89 | "BuiltinExternal/ECMAScriptExternal.js~Int16Array", 90 | "external" 91 | ], 92 | [ 93 | "builtinexternal/ecmascriptexternal.js~int32array", 94 | "external/index.html", 95 | "BuiltinExternal/ECMAScriptExternal.js~Int32Array", 96 | "external" 97 | ], 98 | [ 99 | "builtinexternal/ecmascriptexternal.js~int8array", 100 | "external/index.html", 101 | "BuiltinExternal/ECMAScriptExternal.js~Int8Array", 102 | "external" 103 | ], 104 | [ 105 | "builtinexternal/ecmascriptexternal.js~internalerror", 106 | "external/index.html", 107 | "BuiltinExternal/ECMAScriptExternal.js~InternalError", 108 | "external" 109 | ], 110 | [ 111 | "builtinexternal/ecmascriptexternal.js~json", 112 | "external/index.html", 113 | "BuiltinExternal/ECMAScriptExternal.js~JSON", 114 | "external" 115 | ], 116 | [ 117 | "builtinexternal/ecmascriptexternal.js~map", 118 | "external/index.html", 119 | "BuiltinExternal/ECMAScriptExternal.js~Map", 120 | "external" 121 | ], 122 | [ 123 | "builtinexternal/ecmascriptexternal.js~nan", 124 | "external/index.html", 125 | "BuiltinExternal/ECMAScriptExternal.js~NaN", 126 | "external" 127 | ], 128 | [ 129 | "builtinexternal/ecmascriptexternal.js~number", 130 | "external/index.html", 131 | "BuiltinExternal/ECMAScriptExternal.js~Number", 132 | "external" 133 | ], 134 | [ 135 | "builtinexternal/ecmascriptexternal.js~object", 136 | "external/index.html", 137 | "BuiltinExternal/ECMAScriptExternal.js~Object", 138 | "external" 139 | ], 140 | [ 141 | "builtinexternal/ecmascriptexternal.js~promise", 142 | "external/index.html", 143 | "BuiltinExternal/ECMAScriptExternal.js~Promise", 144 | "external" 145 | ], 146 | [ 147 | "builtinexternal/ecmascriptexternal.js~proxy", 148 | "external/index.html", 149 | "BuiltinExternal/ECMAScriptExternal.js~Proxy", 150 | "external" 151 | ], 152 | [ 153 | "builtinexternal/ecmascriptexternal.js~rangeerror", 154 | "external/index.html", 155 | "BuiltinExternal/ECMAScriptExternal.js~RangeError", 156 | "external" 157 | ], 158 | [ 159 | "builtinexternal/ecmascriptexternal.js~referenceerror", 160 | "external/index.html", 161 | "BuiltinExternal/ECMAScriptExternal.js~ReferenceError", 162 | "external" 163 | ], 164 | [ 165 | "builtinexternal/ecmascriptexternal.js~reflect", 166 | "external/index.html", 167 | "BuiltinExternal/ECMAScriptExternal.js~Reflect", 168 | "external" 169 | ], 170 | [ 171 | "builtinexternal/ecmascriptexternal.js~regexp", 172 | "external/index.html", 173 | "BuiltinExternal/ECMAScriptExternal.js~RegExp", 174 | "external" 175 | ], 176 | [ 177 | "builtinexternal/ecmascriptexternal.js~set", 178 | "external/index.html", 179 | "BuiltinExternal/ECMAScriptExternal.js~Set", 180 | "external" 181 | ], 182 | [ 183 | "builtinexternal/ecmascriptexternal.js~string", 184 | "external/index.html", 185 | "BuiltinExternal/ECMAScriptExternal.js~String", 186 | "external" 187 | ], 188 | [ 189 | "builtinexternal/ecmascriptexternal.js~symbol", 190 | "external/index.html", 191 | "BuiltinExternal/ECMAScriptExternal.js~Symbol", 192 | "external" 193 | ], 194 | [ 195 | "builtinexternal/ecmascriptexternal.js~syntaxerror", 196 | "external/index.html", 197 | "BuiltinExternal/ECMAScriptExternal.js~SyntaxError", 198 | "external" 199 | ], 200 | [ 201 | "builtinexternal/ecmascriptexternal.js~typeerror", 202 | "external/index.html", 203 | "BuiltinExternal/ECMAScriptExternal.js~TypeError", 204 | "external" 205 | ], 206 | [ 207 | "builtinexternal/ecmascriptexternal.js~urierror", 208 | "external/index.html", 209 | "BuiltinExternal/ECMAScriptExternal.js~URIError", 210 | "external" 211 | ], 212 | [ 213 | "builtinexternal/ecmascriptexternal.js~uint16array", 214 | "external/index.html", 215 | "BuiltinExternal/ECMAScriptExternal.js~Uint16Array", 216 | "external" 217 | ], 218 | [ 219 | "builtinexternal/ecmascriptexternal.js~uint32array", 220 | "external/index.html", 221 | "BuiltinExternal/ECMAScriptExternal.js~Uint32Array", 222 | "external" 223 | ], 224 | [ 225 | "builtinexternal/ecmascriptexternal.js~uint8array", 226 | "external/index.html", 227 | "BuiltinExternal/ECMAScriptExternal.js~Uint8Array", 228 | "external" 229 | ], 230 | [ 231 | "builtinexternal/ecmascriptexternal.js~uint8clampedarray", 232 | "external/index.html", 233 | "BuiltinExternal/ECMAScriptExternal.js~Uint8ClampedArray", 234 | "external" 235 | ], 236 | [ 237 | "builtinexternal/ecmascriptexternal.js~weakmap", 238 | "external/index.html", 239 | "BuiltinExternal/ECMAScriptExternal.js~WeakMap", 240 | "external" 241 | ], 242 | [ 243 | "builtinexternal/ecmascriptexternal.js~weakset", 244 | "external/index.html", 245 | "BuiltinExternal/ECMAScriptExternal.js~WeakSet", 246 | "external" 247 | ], 248 | [ 249 | "builtinexternal/ecmascriptexternal.js~boolean", 250 | "external/index.html", 251 | "BuiltinExternal/ECMAScriptExternal.js~boolean", 252 | "external" 253 | ], 254 | [ 255 | "builtinexternal/ecmascriptexternal.js~function", 256 | "external/index.html", 257 | "BuiltinExternal/ECMAScriptExternal.js~function", 258 | "external" 259 | ], 260 | [ 261 | "builtinexternal/ecmascriptexternal.js~null", 262 | "external/index.html", 263 | "BuiltinExternal/ECMAScriptExternal.js~null", 264 | "external" 265 | ], 266 | [ 267 | "builtinexternal/ecmascriptexternal.js~number", 268 | "external/index.html", 269 | "BuiltinExternal/ECMAScriptExternal.js~number", 270 | "external" 271 | ], 272 | [ 273 | "builtinexternal/ecmascriptexternal.js~object", 274 | "external/index.html", 275 | "BuiltinExternal/ECMAScriptExternal.js~object", 276 | "external" 277 | ], 278 | [ 279 | "builtinexternal/ecmascriptexternal.js~string", 280 | "external/index.html", 281 | "BuiltinExternal/ECMAScriptExternal.js~string", 282 | "external" 283 | ], 284 | [ 285 | "builtinexternal/ecmascriptexternal.js~undefined", 286 | "external/index.html", 287 | "BuiltinExternal/ECMAScriptExternal.js~undefined", 288 | "external" 289 | ], 290 | [ 291 | "builtinexternal/webapiexternal.js~audiocontext", 292 | "external/index.html", 293 | "BuiltinExternal/WebAPIExternal.js~AudioContext", 294 | "external" 295 | ], 296 | [ 297 | "builtinexternal/webapiexternal.js~canvasrenderingcontext2d", 298 | "external/index.html", 299 | "BuiltinExternal/WebAPIExternal.js~CanvasRenderingContext2D", 300 | "external" 301 | ], 302 | [ 303 | "builtinexternal/webapiexternal.js~documentfragment", 304 | "external/index.html", 305 | "BuiltinExternal/WebAPIExternal.js~DocumentFragment", 306 | "external" 307 | ], 308 | [ 309 | "builtinexternal/webapiexternal.js~element", 310 | "external/index.html", 311 | "BuiltinExternal/WebAPIExternal.js~Element", 312 | "external" 313 | ], 314 | [ 315 | "builtinexternal/webapiexternal.js~event", 316 | "external/index.html", 317 | "BuiltinExternal/WebAPIExternal.js~Event", 318 | "external" 319 | ], 320 | [ 321 | "builtinexternal/webapiexternal.js~node", 322 | "external/index.html", 323 | "BuiltinExternal/WebAPIExternal.js~Node", 324 | "external" 325 | ], 326 | [ 327 | "builtinexternal/webapiexternal.js~nodelist", 328 | "external/index.html", 329 | "BuiltinExternal/WebAPIExternal.js~NodeList", 330 | "external" 331 | ], 332 | [ 333 | "builtinexternal/webapiexternal.js~xmlhttprequest", 334 | "external/index.html", 335 | "BuiltinExternal/WebAPIExternal.js~XMLHttpRequest", 336 | "external" 337 | ], 338 | [ 339 | "src/index.js", 340 | "file/src/index.js.html", 341 | "src/index.js", 342 | "file" 343 | ], 344 | [ 345 | "src/index.js~http#body", 346 | "class/src/index.js~Http.html#instance-method-body", 347 | "src/index.js~Http#body", 348 | "method" 349 | ], 350 | [ 351 | "src/index.js~http#bodyprocessor", 352 | "class/src/index.js~Http.html#instance-method-bodyProcessor", 353 | "src/index.js~Http#bodyProcessor", 354 | "method" 355 | ], 356 | [ 357 | "src/index.js~http#constructor", 358 | "class/src/index.js~Http.html#instance-constructor-constructor", 359 | "src/index.js~Http#constructor", 360 | "method" 361 | ], 362 | [ 363 | "src/index.js~http#exec", 364 | "class/src/index.js~Http.html#instance-method-exec", 365 | "src/index.js~Http#exec", 366 | "method" 367 | ], 368 | [ 369 | "src/index.js~http#executor", 370 | "class/src/index.js~Http.html#instance-method-executor", 371 | "src/index.js~Http#executor", 372 | "method" 373 | ], 374 | [ 375 | "src/index.js~http#header", 376 | "class/src/index.js~Http.html#instance-method-header", 377 | "src/index.js~Http#header", 378 | "method" 379 | ], 380 | [ 381 | "src/index.js~http#internals", 382 | "class/src/index.js~Http.html#instance-member-internals", 383 | "src/index.js~Http#internals", 384 | "member" 385 | ], 386 | [ 387 | "src/index.js~http#method", 388 | "class/src/index.js~Http.html#instance-method-method", 389 | "src/index.js~Http#method", 390 | "method" 391 | ], 392 | [ 393 | "src/index.js~http#query", 394 | "class/src/index.js~Http.html#instance-method-query", 395 | "src/index.js~Http#query", 396 | "method" 397 | ], 398 | [ 399 | "src/index.js~http#responseprocessor", 400 | "class/src/index.js~Http.html#instance-method-responseProcessor", 401 | "src/index.js~Http#responseProcessor", 402 | "method" 403 | ], 404 | [ 405 | "src/index.js~http#responsetype", 406 | "class/src/index.js~Http.html#instance-method-responseType", 407 | "src/index.js~Http#responseType", 408 | "method" 409 | ], 410 | [ 411 | "src/index.js~http#segment", 412 | "class/src/index.js~Http.html#instance-method-segment", 413 | "src/index.js~Http#segment", 414 | "method" 415 | ], 416 | [ 417 | "src/index.js~http#url", 418 | "class/src/index.js~Http.html#instance-method-url", 419 | "src/index.js~Http#url", 420 | "method" 421 | ], 422 | [ 423 | "src/index.js~httprequestparams", 424 | "typedef/index.html#static-typedef-HttpRequestParams", 425 | "src/index.js~HttpRequestParams", 426 | "typedef" 427 | ], 428 | [ 429 | "src/index.js~tuple", 430 | "typedef/index.html#static-typedef-Tuple", 431 | "src/index.js~Tuple", 432 | "typedef" 433 | ], 434 | [ 435 | "src/utils/url.js", 436 | "file/src/utils/url.js.html", 437 | "src/utils/url.js", 438 | "file" 439 | ], 440 | [ 441 | "src/validate.js", 442 | "file/src/validate.js.html", 443 | "src/validate.js", 444 | "file" 445 | ] 446 | ] -------------------------------------------------------------------------------- /docs/script/test-summary.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | function toggle(ev) { 3 | var button = ev.target; 4 | var parent = ev.target.parentElement; 5 | while(parent) { 6 | if (parent.tagName === 'TR' && parent.classList.contains('test-describe')) break; 7 | parent = parent.parentElement; 8 | } 9 | 10 | if (!parent) return; 11 | 12 | var direction; 13 | if (button.classList.contains('opened')) { 14 | button.classList.remove('opened'); 15 | button.classList.add('closed'); 16 | direction = 'closed'; 17 | } else { 18 | button.classList.remove('closed'); 19 | button.classList.add('opened'); 20 | direction = 'opened'; 21 | } 22 | 23 | var targetDepth = parseInt(parent.dataset.testDepth, 10) + 1; 24 | var nextElement = parent.nextElementSibling; 25 | while (nextElement) { 26 | var depth = parseInt(nextElement.dataset.testDepth, 10); 27 | if (depth >= targetDepth) { 28 | if (direction === 'opened') { 29 | if (depth === targetDepth) nextElement.style.display = ''; 30 | } else if (direction === 'closed') { 31 | nextElement.style.display = 'none'; 32 | var innerButton = nextElement.querySelector('.toggle'); 33 | if (innerButton && innerButton.classList.contains('opened')) { 34 | innerButton.classList.remove('opened'); 35 | innerButton.classList.add('closed'); 36 | } 37 | } 38 | } else { 39 | break; 40 | } 41 | nextElement = nextElement.nextElementSibling; 42 | } 43 | } 44 | 45 | var buttons = document.querySelectorAll('.test-summary tr.test-describe .toggle'); 46 | for (var i = 0; i < buttons.length; i++) { 47 | buttons[i].addEventListener('click', toggle); 48 | } 49 | 50 | var topDescribes = document.querySelectorAll('.test-summary tr[data-test-depth="0"]'); 51 | for (var i = 0; i < topDescribes.length; i++) { 52 | topDescribes[i].style.display = ''; 53 | } 54 | })(); 55 | -------------------------------------------------------------------------------- /docs/source.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Source | API Document 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
    17 | Home 18 | 19 | Reference 20 | Source 21 | 22 | Repository 23 | 30 |
    31 | 32 | 41 | 42 |

    Source 13/14

    43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 |
    FileIdentifierDocumentSizeLinesUpdated
    src/index.jsHttp92 %13/146169 byte2012016-04-06 14:13:49 (UTC)
    src/utils/url.js--741 byte242016-04-06 14:13:49 (UTC)
    src/validate.js--2315 byte902016-04-06 14:13:49 (UTC)
    83 |
    84 | 85 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /docs/typedef/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Typedef | API Document 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
    17 | Home 18 | 19 | Reference 20 | Source 21 | 22 | Repository 23 | 30 |
    31 | 32 | 41 | 42 |

    Typedef

    43 |
    44 | 45 | 46 | 47 | 48 | 55 | 67 | 71 | 72 | 73 | 80 | 92 | 96 | 97 | 98 |
    Static Public Summary
    49 | public 50 | 51 | 52 | 53 | 54 | 56 |
    57 |

    58 | HttpRequestParams: Object 59 |

    60 |
    61 |
    62 | 63 | 64 | 65 |
    66 |
    68 | 69 | 70 |
    74 | public 75 | 76 | 77 | 78 | 79 | 81 |
    82 |

    83 | Tuple: [key: string, value: string] 84 |

    85 |
    86 |
    87 | 88 | 89 | 90 |
    91 |
    93 | 94 | 95 |
    99 |
    100 |

    Static Public

    101 | 102 |
    103 |

    104 | public 105 | 106 | 107 | 108 | 109 | HttpRequestParams: Object 110 | 111 | 112 | 113 | source 114 | 115 |

    116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 |
    125 |

    Properties:

    126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 138 | 139 | 140 | 141 | 142 | 143 | 145 | 146 | 147 | 148 | 149 | 150 | 152 | 153 | 154 | 155 | 156 | 157 | 159 | 160 | 161 | 162 | 163 | 164 | 166 | 167 | 168 | 169 | 170 | 171 | 173 | 174 | 175 | 176 | 177 | 178 | 180 | 181 | 182 | 183 | 184 | 185 | 187 | 188 | 189 | 190 | 191 | 192 | 194 | 195 | 196 | 197 | 198 | 199 | 201 | 202 | 203 |
    NameTypeAttributeDescription
    urlstring

    resource url

    137 |
    methodstring

    HTTP method,

    144 |
    headersTuple[]

    array of HTTP headers key-value pairs

    151 |
    bodyObject

    request payload

    158 |
    responseTypestring

    response type

    165 |
    dynamicSegmentsTuple[]

    key-value array of replacements for the provided url

    172 |
    queryParamsTuple[]

    key-value array of url params

    179 |
    bodyProcessorfunction(x: Object): Object

    map body function

    186 |
    responseProcessorfunction(x: Object): Object

    map response function

    193 |
    executorfunction(url: string, method: string, headers: string[], responseType: string, body: Object): Promise

    performs HTTP request and returns Promise,

    200 |
    204 |
    205 |
    206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 |
    222 |
    223 |

    224 | public 225 | 226 | 227 | 228 | 229 | Tuple: [key: string, value: string] 230 | 231 | 232 | 233 | source 234 | 235 |

    236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 |
    245 |
    246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 |
    262 |
    263 |
    264 | 265 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | -------------------------------------------------------------------------------- /esdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "source": "./src", 3 | "destination": "./docs", 4 | "package": "./package.json", 5 | "plugins": [ 6 | {"name": "esdoc-es7-plugin"} 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var webpack = require('webpack'); 3 | 4 | module.exports = function(config) { 5 | config.set({ 6 | 7 | // base path that will be used to resolve all patterns (eg. files, exclude) 8 | basePath: '', 9 | 10 | // frameworks to use 11 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter 12 | frameworks: ['mocha'], 13 | 14 | plugins: [ 15 | require('karma-webpack'), 16 | require('karma-chrome-launcher'), 17 | require('karma-firefox-launcher'), 18 | require('karma-phantomjs-launcher'), 19 | require('karma-mocha') 20 | ], 21 | 22 | // list of files / patterns to load in the browser 23 | files: [ 24 | 'test/**/*.js' 25 | ], 26 | 27 | // preprocess matching files before serving them to the browser 28 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor 29 | preprocessors: { 30 | 'src/**/*.js': ['webpack'], 31 | 'test/**/*.js': ['webpack'] 32 | }, 33 | 34 | webpack: { 35 | devtool: 'source-map', 36 | module: { 37 | loaders: [ 38 | { 39 | test: /\.js$/, 40 | loader: 'babel', 41 | exclude: /node_modules/, 42 | query: { 43 | presets: ["es2015"] 44 | } 45 | } 46 | ] 47 | } 48 | }, 49 | 50 | // test results reporter to use 51 | // possible values: 'dots', 'progress' 52 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter 53 | reporters: ['progress'], 54 | 55 | // web server port 56 | port: 9876, 57 | 58 | // enable / disable colors in the output (reporters and logs) 59 | colors: true, 60 | 61 | // level of logging 62 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 63 | logLevel: config.LOG_INFO, 64 | 65 | // enable / disable watching file and executing tests whenever any file changes 66 | autoWatch: true, 67 | 68 | // start these browsers 69 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher 70 | browsers: [ 71 | 'Chrome', 72 | 'Firefox' 73 | ] 74 | }) 75 | } 76 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "immutable-http", 3 | "version": "4.0.0", 4 | "description": "Http client with pretty simple chaining API", 5 | "keywords": [ 6 | "javascript", 7 | "xhr", 8 | "http", 9 | "rest" 10 | ], 11 | "scripts": { 12 | "doc": "rm -rf docs && esdoc -c ./esdoc.json", 13 | "doc:publish": "gh-pages -d docs", 14 | "lint": "eslint src test", 15 | "test": "karma start --single-run", 16 | "test:debug": "karma start", 17 | "test:ci": "karma start --single-run --browsers PhantomJS", 18 | "clean": "rm -rf ./dist", 19 | "dist": "npm run clean && mkdir dist && webpack --progress --colors --config webpack.config.js", 20 | "prepublish:supressed": "npm run dist && npm run doc && npm run doc:publish" 21 | }, 22 | "main": "dist/index.js", 23 | "homepage": "http://stremlenye.github.io/immutable-http/", 24 | "bugs": { 25 | "url": "https://github.com/stremlenye/immutable-http/issues" 26 | }, 27 | "license": "MIT", 28 | "people": { 29 | "author": { 30 | "name": "Yuriy Ankudinov", 31 | "email": "stremlenye@gmail.com", 32 | "url": "https://github.com/stremlenye" 33 | } 34 | }, 35 | "repository": { 36 | "type": "git", 37 | "url": "https://github.com/stremlenye/immutable-http.git" 38 | }, 39 | "devDependencies": { 40 | "babel": "^6.5.2", 41 | "babel-core": "^6.7.4", 42 | "babel-eslint": "^6.0.2", 43 | "babel-loader": "^6.2.4", 44 | "babel-polyfill": "^6.7.4", 45 | "babel-preset-es2015": "^6.6.0", 46 | "body-parser": "^1.15.0", 47 | "chai": "^3.2.0", 48 | "cors": "^2.7.1", 49 | "esdoc": "^0.4.6", 50 | "esdoc-es7-plugin": "0.0.3", 51 | "eslint": "^2.5.3", 52 | "express": "^4.13.3", 53 | "gh-pages": "^0.11.0", 54 | "karma": "^0.13.22", 55 | "karma-chrome-launcher": "^0.2.3", 56 | "karma-firefox-launcher": "^0.1.6", 57 | "karma-mocha": "^0.2.2", 58 | "karma-phantomjs-launcher": "^1.0.0", 59 | "karma-webpack": "^1.7.0", 60 | "mocha": "^2.3.2", 61 | "phantomjs-prebuilt": "^2.1.7", 62 | "webpack": "^1.12.14" 63 | }, 64 | "dependencies": { 65 | "babel-runtime": "^6.6.1", 66 | "option": "^0.2.3" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import validate from './validate' 2 | import { addQueryParams, mixinDynamicSegmentsValues } from './utils/url' 3 | 4 | const identity = x => x 5 | 6 | const defaultParams = { 7 | executor: null, 8 | url: null, 9 | method: null, 10 | headers: [], 11 | body: null, 12 | responseType: null, 13 | dynamicSegments: [], 14 | queryParams: [], 15 | bodyProcessor: identity, 16 | responseProcessor: identity 17 | } 18 | 19 | class Internals { 20 | constructor (params) { 21 | Object.entries(params) 22 | .map(([key, value]) => 23 | Object.defineProperty(this, key, { 24 | get: () => value, 25 | enumerable: true, 26 | configurable: true 27 | })) 28 | } 29 | } 30 | 31 | /** 32 | * @typedef {[key: string, value: string]} Tuple 33 | */ 34 | 35 | /** 36 | * @typedef {Object} HttpRequestParams 37 | * @property {string} url resource url 38 | * @property {string} method HTTP method, 39 | * @property {Tuple[]} headers array of HTTP headers key-value pairs 40 | * @property {Object} body request payload 41 | * @property {string} responseType response type 42 | * @property {Tuple[]} dynamicSegments key-value array of replacements for the provided url 43 | * @property {Tuple[]} queryParams key-value array of url params 44 | * @property {function(x: Object): Object} bodyProcessor map body function 45 | * @property {function(x: Object): Object} responseProcessor map response function 46 | * @property {function(url: string, method: string, headers: string[], responseType: string, body: Object): Promise} executor performs HTTP request and returns Promise, 47 | */ 48 | 49 | // executor: function(url: string, method: string, headers: string[], responseType: string, body: Object): Promise, 50 | // bodyProcessor: function(x: Object): Object, responseProcessor: function(x: Object): Object 51 | 52 | /** 53 | * Http request object. 54 | * Expose chainable API 55 | */ 56 | export default class Http { 57 | 58 | /** 59 | * @param {HttpRequestParams} params - HTTP request params 60 | */ 61 | constructor (params = defaultParams) { 62 | const internals = new Internals(params) 63 | this.internals = () => internals 64 | } 65 | 66 | /** 67 | * Set the middleware that will perform the request 68 | * @param {function(url: string, method: string, headers: string[], responseType: string, body: Object): Promise} executor - 69 | * function which performs the request asynchroniously and returns Promise back 70 | * @returns {Object} Http object 71 | */ 72 | executor (executor) { 73 | return new Http(Object.assign({}, this.internals(), { executor })) 74 | } 75 | 76 | /** 77 | * Adds URL information to HTTP request model 78 | * @param {string} url - URL 79 | * @returns {Object} Http object 80 | */ 81 | url (url) { 82 | return new Http(Object.assign({}, this.internals(), { url })) 83 | } 84 | 85 | /** 86 | * Adds HTTP method information to request model 87 | * @param {string} method - HTTP method 88 | * @returns {Object} Http object 89 | */ 90 | method (method) { 91 | return new Http(Object.assign({}, this.internals(), { method })) 92 | } 93 | 94 | /** 95 | * Adds header to request model 96 | * @param {string} header - valid header key 97 | * @param {string} value - valid header value 98 | * @returns {Object} Http object 99 | */ 100 | header (header, value) { 101 | const headers = this.internals().headers.concat([[header, value]]) 102 | return new Http(Object.assign({}, this.internals(), { headers })) 103 | } 104 | 105 | /** 106 | * Adds body to request model 107 | * @param {Object} body - request payload 108 | * @returns {Object} Http object 109 | */ 110 | body (body) { 111 | return new Http(Object.assign({}, this.internals(), { body })) 112 | } 113 | 114 | /** 115 | * Sets response content type 116 | * Proper values could be obtained form XmlHttpRequest specification 117 | * https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#Properties 118 | * @param {string} responseType - Proper values could be obtained form 119 | * XmlHttpRequest specification 120 | * https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#Properties 121 | * @returns {Object} Http object 122 | */ 123 | responseType (responseType) { 124 | return new Http(Object.assign({}, this.internals(), { responseType })) 125 | } 126 | 127 | /** 128 | * Adds dynamic segment value 129 | * @param {string} segment - segment key 130 | * @param {string} value - segment value 131 | * @returns {Object} Http object 132 | */ 133 | segment (segment, value) { 134 | const dynamicSegments 135 | = this.internals().dynamicSegments.concat([[segment, value]]) 136 | return new Http(Object.assign({}, this.internals(), { dynamicSegments })) 137 | } 138 | 139 | /** 140 | * Adds query string param 141 | * @param {string} name - param key 142 | * @param {string} value - param value 143 | * @returns {Object} Http object 144 | */ 145 | query (name, value) { 146 | const queryParams = this.internals().queryParams.concat([[name, value]]) 147 | return new Http(Object.assign({}, this.internals(), { queryParams })) 148 | } 149 | 150 | /** 151 | * Sets the function which gets the body object as a parameter 152 | * which result would be used as a request body 153 | * @param {func} bodyProcessor - f(x) => valid_http_body 154 | * @returns {Object} Http object 155 | */ 156 | bodyProcessor (bodyProcessor) { 157 | return new Http(Object.assign({}, this.internals(), { bodyProcessor })) 158 | } 159 | 160 | /** 161 | * Sets the function which gets the response and produces another value 162 | * Useful for default HTTP error handling 163 | * 164 | * @example 165 | * response => { 166 | * switch(response.code) { 167 | * case "404": 168 | * return { message: 'Resource not found' } 169 | * } 170 | *} 171 | * 172 | * @param {func} responseProcessor - f(x) => y 173 | * @returns {Object} Http object 174 | */ 175 | responseProcessor (responseProcessor) { 176 | return new Http(Object.assign({}, this.internals(), { responseProcessor })) 177 | } 178 | 179 | /** 180 | * Executes HTTP request 181 | * @returns {Object} - Promise 182 | */ 183 | exec () { 184 | const { 185 | url, method, headers, responseType, dynamicSegments, queryParams, body, 186 | bodyProcessor, responseProcessor, executor 187 | } = this.internals() 188 | if (!executor) { 189 | throw new Error('executor was not set') 190 | } 191 | const errors = validate(url, method, headers, responseType) 192 | if (errors.length !== 0) 193 | throw new Error(errors.join('\n')) 194 | const urlWithDynamicSegments 195 | = mixinDynamicSegmentsValues(url, dynamicSegments) 196 | const fullUrl = addQueryParams(urlWithDynamicSegments, queryParams) 197 | return executor( 198 | fullUrl, method, headers, responseType, bodyProcessor(body) 199 | ).then(responseProcessor) 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /src/utils/url.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ignore 3 | * Mixins dynamic segments replacing the `:segment_name` parts with provide 4 | * values 5 | * @param {String} url – URL 6 | * @param {Object} dynamicSegments – dynamic segments 7 | * @returns {String} – URL 8 | */ 9 | export function mixinDynamicSegmentsValues (url, dynamicSegments) { 10 | return dynamicSegments.reduce((aggr, [key, value]) => 11 | aggr.replace(`:${key}`, value), url) 12 | } 13 | 14 | /** 15 | * @ignore 16 | * Adds query params string to url 17 | * @param {string} url – URL 18 | * @param {Array} queryParams – query params 19 | * @returns {String} – URL 20 | */ 21 | export function addQueryParams (url, queryParams) { 22 | const chanks = queryParams.map(([key, value]) => `${key}=${value}`) 23 | return url + (chanks.length !== 0 ? '?' + chanks.join('&') : '') 24 | } 25 | -------------------------------------------------------------------------------- /src/validate.js: -------------------------------------------------------------------------------- 1 | import option from 'option' 2 | 3 | const supportedMethods = ['GET', 'POST', 'PUT', 'DELETE'] 4 | const validTypes = [null, '', 'arraybuffer', 'blob', 'document', 'text', 'json'] 5 | 6 | /** 7 | * Validate HTTP method 8 | * @param {String} method – HTTP method 9 | * @return {String} error 10 | */ 11 | function validateMethod (method) { 12 | if (!method) { 13 | return option.some('HTTP method is not specified') 14 | } 15 | if (typeof method !== 'string') { 16 | return option.some('HTTP method should be type of string') 17 | } 18 | if (supportedMethods.indexOf(method.toUpperCase()) < 0) { 19 | return option.some(`Http method ${method} is not supported`) 20 | } 21 | return option.none 22 | } 23 | 24 | /** 25 | * Basicly validate url 26 | * @param {String} url – URL 27 | * @return {String} error 28 | */ 29 | function validateUrl (url) { 30 | if (!url) { 31 | return option.some('Url is not specified') 32 | } 33 | if (typeof url !== 'string') { 34 | return option.some('Url should be type of string') 35 | } 36 | return option.none 37 | } 38 | 39 | /** 40 | * Validate header to all parts be strings 41 | * @param {String} key – Header key 42 | * @param {String} value – Header value 43 | * @return {String} error 44 | */ 45 | function validateHeader (key, value) { 46 | if (typeof key !== 'string' || typeof value !== 'string') 47 | return option.some(`Parts of header ${key}:${value} must be strings`) 48 | return option.none 49 | } 50 | 51 | /** 52 | * Validate headers 53 | * @param {Object} headers – headers 54 | * @return {Array} error 55 | */ 56 | function validateHeaders (headers) { 57 | const aggr = [] 58 | for (let [key, value] of headers) 59 | aggr.push(validateHeader(key, value)) 60 | return aggr 61 | } 62 | 63 | /** 64 | * Validates response type 65 | * @param {string} type - response type 66 | * @return {String} error 67 | */ 68 | function validateResponseType (type) { 69 | if (validTypes.indexOf(type) < 0) 70 | return option.some(`Response content type ${type} is not supported`) 71 | return option.none 72 | } 73 | 74 | /** 75 | * @ignore 76 | * Validate HTTP request model 77 | * @param {String} url – url 78 | * @param {String} method – HTTP method 79 | * @param {Map} headers – HTTP headers 80 | * @param {String} responseType – response type 81 | * @return {Array} array of errors 82 | */ 83 | function validate (url, method, headers, responseType) { 84 | return [validateUrl(url), 85 | validateMethod(method), 86 | validateResponseType(responseType)] 87 | .concat(validateHeaders(headers)).filter(_ => _.isSome()).map(_ => _.value()) 88 | } 89 | 90 | export default validate 91 | -------------------------------------------------------------------------------- /test/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "max-nested-callbacks": [2, 4] 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/api_test.js: -------------------------------------------------------------------------------- 1 | /* global describe:true it:true */ 2 | /* eslint-disable no-unused-expressions */ 3 | 4 | import 'babel-polyfill' 5 | import { expect } from 'chai' 6 | import Http from '../src' 7 | 8 | describe('API', () => { 9 | it('has method `url`', () => { 10 | const http = new Http() 11 | expect(http.url).to.not.be.undefined 12 | }) 13 | 14 | it('has method `method`', () => { 15 | const http = new Http() 16 | expect(http.method).to.not.be.undefined 17 | }) 18 | 19 | it('has method `header`', () => { 20 | const http = new Http() 21 | expect(http.header).to.not.be.undefined 22 | }) 23 | 24 | it('has method `body`', () => { 25 | const http = new Http() 26 | expect(http.body).to.not.be.undefined 27 | }) 28 | 29 | it('has method `responseType`', () => { 30 | const http = new Http() 31 | expect(http.responseType).to.not.be.undefined 32 | }) 33 | 34 | it('has method `segment`', () => { 35 | const http = new Http() 36 | expect(http.segment).to.not.be.undefined 37 | }) 38 | 39 | it('has method `query`', () => { 40 | const http = new Http() 41 | expect(http.query).to.not.be.undefined 42 | }) 43 | 44 | it('has method `bodyProcessor`', () => { 45 | const http = new Http() 46 | expect(http.bodyProcessor).to.not.be.undefined 47 | }) 48 | 49 | it('has method `responseProcessor`', () => { 50 | const http = new Http() 51 | expect(http.responseProcessor).to.not.be.undefined 52 | }) 53 | }) 54 | -------------------------------------------------------------------------------- /test/execution_test.js: -------------------------------------------------------------------------------- 1 | /* global describe:true it:true */ 2 | 3 | import { expect } from 'chai' 4 | import Http from '../src' 5 | 6 | describe('Http GET', () => { 7 | describe('API', () => { 8 | it('execute simple get request without query', (done) => { 9 | const url = 'http://localhost:3000/:some_segment' 10 | const method = 'GET' 11 | const executor = (u, m, headers, responseType) => new Promise(() => { 12 | try { 13 | expect(u).to.equal('http://localhost:3000/test') 14 | expect(m).to.equal(method) 15 | expect(headers).to.eql([ 16 | ['Content-Type', 'application/json;charset=UTF-8'], 17 | ['Accept', 'application/json'] 18 | ]) 19 | expect(responseType).to.be.equal('json') 20 | } catch (e) { 21 | done(e) 22 | } finally { 23 | done() 24 | } 25 | }) 26 | const client = (new Http()).method(method) 27 | .executor(executor) 28 | .url(url) 29 | .segment('some_segment', 'test') 30 | .header('Content-Type', 'application/json;charset=UTF-8') 31 | .header('Accept', 'application/json') 32 | .responseType('json') 33 | .responseProcessor(response => { 34 | switch (response.code) { 35 | case '404': 36 | return { message: 'Resource not found' } 37 | default: 38 | return response 39 | } 40 | }) 41 | return client.exec() 42 | }) 43 | 44 | it('execute simple post request', (done) => { 45 | const url = 'http://localhost:3000/:some_segment' 46 | const method = 'POST' 47 | const obj = {some: 'body'} 48 | const executor = (u, m, headers, responseType, body) => new Promise(() => { 49 | try { 50 | expect(u).to.equal('http://localhost:3000/test?ping=pong') 51 | expect(m).to.equal(method) 52 | expect(headers).to.eql([ 53 | ['Content-Type', 'application/json;charset=UTF-8'], 54 | ['Accept', 'application/json'] 55 | ]) 56 | expect(responseType).to.be.equal('json') 57 | expect(body).to.be.equal(JSON.stringify(obj)) 58 | } catch (e) { 59 | done(e) 60 | } finally { 61 | done() 62 | } 63 | }) 64 | const client = (new Http()).method(method) 65 | .executor(executor) 66 | .url(url) 67 | .segment('some_segment', 'test') 68 | .query('ping', 'pong') 69 | .header('Content-Type', 'application/json;charset=UTF-8') 70 | .header('Accept', 'application/json') 71 | .responseType('json') 72 | .bodyProcessor(JSON.stringify) 73 | .responseProcessor(response => { 74 | switch (response.code) { 75 | case '404': 76 | return { message: 'Resource not found' } 77 | default: 78 | return response 79 | } 80 | }) 81 | .body(obj) 82 | return client.exec() 83 | }) 84 | }) 85 | }) 86 | -------------------------------------------------------------------------------- /test/url_test.js: -------------------------------------------------------------------------------- 1 | /* global describe:true it:true */ 2 | import { expect } from 'chai' 3 | import { addQueryParams } from '../src/utils/url' 4 | 5 | describe('addQueryParams', () => { 6 | it('combines url string with query params', () => { 7 | const url = 'http://localhost' 8 | const queryParams = [['ping', 'pong'], ['foo', 'bar']] 9 | const result = addQueryParams(url, queryParams) 10 | expect(result).to.equal('http://localhost?ping=pong&foo=bar') 11 | }) 12 | it('returns url itself if queryParams is empty', () => { 13 | const url = 'http://localhost' 14 | const queryParams = [] 15 | const result = addQueryParams(url, queryParams) 16 | expect(result).to.equal('http://localhost') 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /test/validate_test.js: -------------------------------------------------------------------------------- 1 | /* global describe:true it:true */ 2 | import { expect } from 'chai' 3 | import validate from '../src/validate' 4 | 5 | const supportedMethods = ['GET', 'POST', 'PUT', 'DELETE'] 6 | const validTypes = [null, '', 'arraybuffer', 'blob', 'document', 'text', 'json'] 7 | 8 | describe('validate function', () => { 9 | it('should return nothing if constraints are correct', () => { 10 | const url = 'http://my.com/blah?query=string&another=string' 11 | const headers = new Map().set('Authentication', 'Token blah==') 12 | for (let method of supportedMethods) 13 | for (let type of validTypes) 14 | expect(validate(url, method, headers, type)).to.be.empty //eslint-disable-line 15 | }) 16 | 17 | it('should return "HTTP method is not specified" if no method have been"' 18 | + '"provided', () => { 19 | const url = 'http://my.com/blah?query=string&another=string' 20 | const headers = new Map().set('Authentication', 'Token blah==') 21 | const [type] = validTypes 22 | expect(validate(url, null, headers, type)) 23 | .to.eql(['HTTP method is not specified']) 24 | }) 25 | 26 | it('should return "HTTP method should be type of string" if method is not ' 27 | + 'type of string', () => { 28 | const url = 'http://my.com/blah?query=string&another=string' 29 | const headers = new Map().set('Authentication', 'Token blah==') 30 | const [type] = validTypes 31 | expect(validate(url, 1, headers, type)) 32 | .to.eql(['HTTP method should be type of string']) 33 | }) 34 | 35 | it('should return "Http method ${method} is not supported" if method is not "' 36 | + '"supported', () => { 37 | const url = 'http://my.com/blah?query=string&another=string' 38 | const headers = new Map().set('Authentication', 'Token blah==') 39 | const [type] = validTypes 40 | expect(validate(url, 'BOOM!', headers, type)) 41 | .to.eql(['Http method BOOM! is not supported']) 42 | }) 43 | 44 | it('should return "Url is not specified" if no url provided', () => { 45 | const headers = new Map().set('Authentication', 'Token blah==') 46 | const [method] = supportedMethods 47 | const [type] = validTypes 48 | expect(validate(null, method, headers, type)) 49 | .to.eql(['Url is not specified']) 50 | }) 51 | 52 | it('should return "Url should be type of string" if no url provided', () => { 53 | const headers = new Map().set('Authentication', 'Token blah==') 54 | const [method] = supportedMethods 55 | const [type] = validTypes 56 | expect(validate(1, method, headers, type)) 57 | .to.eql(['Url should be type of string']) 58 | }) 59 | 60 | it('should return "Parts of header ${key}:${value} must be strings" if ' 61 | + 'headers are not of type string', () => { 62 | const url = 'http://my.com/blah?query=string&another=string' 63 | const headers = new Map().set(1, 2) 64 | const [method] = supportedMethods 65 | const [type] = validTypes 66 | expect(validate(url, method, headers, type)) 67 | .to.eql(['Parts of header 1:2 must be strings']) 68 | }) 69 | 70 | it('should return "Response content type ${type} is not currently supported" if ', () => { 71 | const url = 'http://my.com/blah?query=string&another=string' 72 | const headers = new Map().set('Authentication', 'Token blah==') 73 | const [method] = supportedMethods 74 | expect(validate(url, method, headers, 'BOOM!')) 75 | .to.eql(['Response content type BOOM! is not supported']) 76 | }) 77 | }) 78 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var webpack = require('webpack'); 3 | 4 | module.exports = { 5 | devtool: 'source-map', 6 | entry: { 7 | 'index': './src/index.js' 8 | }, 9 | output: { 10 | filename: '[name].js', 11 | path: path.join(__dirname, 'dist'), 12 | library: 'immutable-http', 13 | libraryTarget: 'umd' 14 | }, 15 | target: 'web', 16 | module: { 17 | loaders: [{ test: /\.js$/, exclude: /node_modules/, loader: "babel-loader"}] 18 | } 19 | }; 20 | --------------------------------------------------------------------------------