├── .babelrc ├── .codeclimate.yml ├── .editorconfig ├── .gitignore ├── .jscsrc ├── .jshintrc ├── .travis.yml ├── MIT-LICENSE.txt ├── README.md ├── bower.json ├── demo ├── github-extended.bundle.min.js └── index.html ├── dist ├── github-extended.min.js └── github-extended.min.js.map ├── doc ├── ast │ ├── source │ │ └── github-extended.js.json │ └── test │ │ └── spec │ │ └── test.js.json ├── badge.svg ├── class │ └── src │ │ └── github-extended.js~Github.html ├── coverage.json ├── css │ ├── prettify-tomorrow.css │ └── style.css ├── dump.json ├── file │ └── src │ │ └── github-extended.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 ├── test-file │ └── test │ │ └── spec │ │ └── test.js.html └── test.html ├── esdoc.json ├── gulpfile.js ├── karma.conf.js ├── package.json ├── src └── github-extended.js └── test ├── fixtures └── user.json └── spec └── test.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "moduleId": "Github", 3 | "plugins": [ 4 | [ 5 | "transform-es2015-modules-umd", 6 | { 7 | "browserGlobals": { 8 | "github-api": "Github" 9 | } 10 | } 11 | ] 12 | ], 13 | "presets": ["es2015"], 14 | } -------------------------------------------------------------------------------- /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | engines: 2 | csslint: 3 | enabled: true 4 | eslint: 5 | enabled: true 6 | fixme: 7 | enabled: true 8 | ratings: 9 | paths: 10 | - "src/**" -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 3 6 | 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = false 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules 3 | coverage -------------------------------------------------------------------------------- /.jscsrc: -------------------------------------------------------------------------------- 1 | { 2 | "disallowDanglingUnderscores": true, 3 | "disallowIdentifierNames": [], 4 | "disallowImplicitTypeConversion": [], 5 | "disallowKeywordsOnNewLine": [ 6 | "catch", 7 | "else" 8 | ], 9 | "disallowKeywords": [ 10 | "void", 11 | "with" 12 | ], 13 | "disallowMixedSpacesAndTabs": true, 14 | "disallowMultipleLineBreaks": true, 15 | "disallowMultipleLineStrings": true, 16 | "disallowMultipleSpaces": true, 17 | "disallowMultipleVarDecl": "exceptUndefined", 18 | "disallowNewlineBeforeBlockStatements": true, 19 | "disallowPaddingNewlinesBeforeKeywords": [ 20 | "case", 21 | "typeof" 22 | ], 23 | "disallowPaddingNewlinesInBlocks": true, 24 | "disallowQuotedKeysInObjects": true, 25 | "disallowSpaceAfterKeywords": [ 26 | "catch", 27 | "for", 28 | "switch", 29 | "while" 30 | ], 31 | "disallowSpaceAfterObjectKeys": true, 32 | "disallowSpaceAfterPrefixUnaryOperators": true, 33 | "disallowSpaceBeforePostfixUnaryOperators": true, 34 | "disallowSpacesInCallExpression": true, 35 | "disallowSpacesInFunction": { 36 | "beforeOpeningRoundBrace": true 37 | }, 38 | "disallowSpacesInsideParentheses": true, 39 | "disallowTrailingComma": true, 40 | "disallowTrailingWhitespace": true, 41 | "disallowYodaConditions": true, 42 | "maximumLineLength": 120, 43 | "requireBlocksOnNewline": true, 44 | "requireCamelCaseOrUpperCaseIdentifiers": true, 45 | "requireCapitalizedComments": { 46 | "allExcept": [ 47 | "exported", 48 | "global", 49 | "jshint" 50 | ] 51 | }, 52 | "requireCapitalizedConstructors": true, 53 | "requireCommaBeforeLineBreak": true, 54 | "requireCurlyBraces": [ 55 | "catch", 56 | "do", 57 | "else", 58 | "for", 59 | "if", 60 | "try", 61 | "while" 62 | ], 63 | "requireDollarBeforejQueryAssignment": true, 64 | "requireDotNotation": true, 65 | "requireKeywordsOnNewLine": [ 66 | "break", 67 | "case", 68 | "default" 69 | ], 70 | "requireLineBreakAfterVariableAssignment": true, 71 | "requireObjectKeysOnNewLine": true, 72 | "requireOperatorBeforeLineBreak": true, 73 | "requirePaddingNewLineAfterVariableDeclaration": true, 74 | "requirePaddingNewLinesAfterBlocks": { 75 | "allExcept": [ 76 | "inArrayExpressions", 77 | "inCallExpressions", 78 | "inProperties" 79 | ] 80 | }, 81 | "requirePaddingNewLinesAfterUseStrict": true, 82 | "requirePaddingNewLinesBeforeExport": true, 83 | "requirePaddingNewlinesBeforeKeywords": [ 84 | "do", 85 | "for", 86 | "function", 87 | "if", 88 | "return", 89 | "switch", 90 | "try", 91 | "void", 92 | "while", 93 | "with" 94 | ], 95 | "requirePaddingNewLinesBeforeLineComments": { 96 | "allExcept": "firstAfterCurly" 97 | }, 98 | "requirePaddingNewLinesInObjects": true, 99 | "requireParenthesesAroundIIFE": true, 100 | "requireSemicolons": true, 101 | "requireSpaceAfterBinaryOperators": true, 102 | "requireSpaceAfterKeywords": [ 103 | "case", 104 | "do", 105 | "else", 106 | "if", 107 | "return", 108 | "try", 109 | "typeof" 110 | ], 111 | "requireSpaceAfterLineComment": true, 112 | "requireSpaceBeforeBinaryOperators": true, 113 | "requireSpaceBeforeBlockStatements": true, 114 | "requireSpaceBeforeKeywords": [ 115 | "catch", 116 | "else" 117 | ], 118 | "requireSpaceBeforeObjectValues": true, 119 | "requireSpaceBetweenArguments": true, 120 | "requireSpacesInAnonymousFunctionExpression": { 121 | "beforeOpeningCurlyBrace": true 122 | }, 123 | "requireSpacesInConditionalExpression": true, 124 | "requireSpacesInForStatement": true, 125 | "requireSpacesInFunctionDeclaration": { 126 | "beforeOpeningCurlyBrace": true 127 | }, 128 | "requireSpacesInFunctionExpression": { 129 | "beforeOpeningCurlyBrace": true 130 | }, 131 | "requireSpacesInFunction": { 132 | "beforeOpeningCurlyBrace": true 133 | }, 134 | "requireSpacesInNamedFunctionExpression": { 135 | "beforeOpeningCurlyBrace": true 136 | }, 137 | "safeContextKeyword": ["that"], 138 | "validateAlignedFunctionParameters": true, 139 | "validateIndentation": 3, 140 | "validateLineBreaks": "LF", 141 | "validateNewlineAfterArrayElements": { 142 | "maximum": 3 143 | }, 144 | "validateParameterSeparator": ", ", 145 | "validateQuoteMarks": "'" 146 | } -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "bitwise": true, 3 | "curly": true, 4 | "eqeqeq": true, 5 | "esnext": true, 6 | // "esversion": 6, To enable in the next version of JSHint 7 | "forin": false, 8 | "freeze": true, 9 | "funcscope": false, 10 | "futurehostile": true, 11 | "globals": [], 12 | "globalstrict": true, 13 | "iterator": false, 14 | "latedef": true, 15 | "maxcomplexity": 6, 16 | "maxdepth": 3, 17 | "maxerr": 50, 18 | "maxparams": 4, 19 | "maxstatements": 20, 20 | "noarg": true, 21 | "nocomma": true, 22 | "nonbsp": true, 23 | "nonew": true, 24 | "notypeof": true, 25 | "predef": [], 26 | "shadow": "inner", 27 | "singleGroups": true, 28 | "strict": true, 29 | "undef": true, 30 | "unused": true, 31 | "varstmt": false, 32 | 33 | "browser": true 34 | } -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - "4.1" 5 | - "4.0" 6 | - "0.12" 7 | - "0.11" 8 | 9 | cache: 10 | directories: 11 | - node_modules 12 | 13 | before_install: 14 | - npm i -g npm@^3.3.0 15 | 16 | script: 17 | - npm run-script test -------------------------------------------------------------------------------- /MIT-LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Aurelio De Rosa 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GitHub Extended 2 | 3 | [![Code Climate](https://codeclimate.com/github/github-tools/github-extended/badges/gpa.svg)](https://codeclimate.com/github/github-tools/github-extended) 4 | [![Build Status](https://travis-ci.org/github-tools/github-extended.svg?branch=master)](https://travis-ci.org/github-tools/github-extended) 5 | [![Coverage Status](https://coveralls.io/repos/github-tools/github-extended/badge.svg?branch=master&service=github)](https://coveralls.io/github/github-tools/github-extended?branch=master) 6 | 7 | [GitHub Extended](https://github.com/github-tools/github-extended) is a collection of methods to extend the 8 | functionality of [Github.js](https://github.com/michael/github) (known on [npm](https://www.npmjs.com) as 9 | [github-api](https://www.npmjs.com/package/github-api)). 10 | 11 | ## Requirements 12 | 13 | Being an extension for Github.js, the only requirement is to install and include 14 | [Github.js](https://github.com/michael/github) before 15 | [GitHub Extended](https://github.com/github-tools/github-extended). 16 | 17 | ## Installation 18 | 19 | You can install GitHub Extended by using [npm](https://www.npmjs.com): 20 | 21 | ``` 22 | npm install github-extended 23 | ``` 24 | 25 | Alternatively, you can install it via [Bower](http://bower.io): 26 | 27 | ``` 28 | bower install github-extended --save 29 | ``` 30 | 31 | Another possibility is to manually download it. 32 | 33 | ## Methods 34 | 35 | The sections below describe the methods provided. 36 | 37 | ### repository.search(string, options = {}) 38 | 39 | Searches files and folders 40 | 41 | ### repository.mergePullRequest(pullRequest, options = {}) 42 | 43 | Merges a pull request 44 | 45 | ### repository.remove(branchName = 'master', path = '') 46 | 47 | Deletes a file or a folder and all of its content from a given branch 48 | 49 | ### repository.fork() 50 | 51 | Creates a fork of the repository 52 | 53 | ## License 54 | 55 | [GitHub Extended](https://github.com/github-tools/github-extended) is dual licensed under 56 | [MIT](http://www.opensource.org/licenses/MIT) and [GPL-3.0](http://opensource.org/licenses/GPL-3.0). 57 | 58 | ## Author 59 | 60 | [Aurelio De Rosa](http://www.audero.it) ([@AurelioDeRosa](https://twitter.com/AurelioDeRosa)) -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "github-extended", 3 | "description": "A collection of methods to extend the functionality of Github.js (known on npm as github-api)", 4 | "main": "src/github-extended.js", 5 | "authors": [ 6 | "Aurelio De Rosa (http://audero.it)" 7 | ], 8 | "license": "(MIT OR GPL-3.0)", 9 | "keywords": [ 10 | "github", 11 | "github-api", 12 | "api", 13 | "javascript", 14 | "library", 15 | "umd" 16 | ], 17 | "moduleType": [ 18 | "es6" 19 | ], 20 | "homepage": "https://github.com/AurelioDeRosa/github-extended", 21 | "ignore": [ 22 | "**/.*", 23 | "node_modules", 24 | "bower_components", 25 | "test", 26 | "tests" 27 | ] 28 | } -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | GitHub Extended - Demo 6 | 13 | 14 | 15 |

GitHub Extended Demo

16 | 17 | 26 | 27 |

Results

28 | 29 | 30 | 31 | 52 | 53 | -------------------------------------------------------------------------------- /dist/github-extended.min.js: -------------------------------------------------------------------------------- 1 | "use strict";function _typeof(e){return e&&"undefined"!=typeof Symbol&&e.constructor===Symbol?"symbol":typeof e}!function(e,n){if("function"==typeof define&&define.amd)define("Github",["exports","github-api"],n);else if("undefined"!=typeof exports)n(exports,require("github-api"));else{var t={exports:{}};n(t.exports,e.Github),e.Github=t.exports}}(this,function(e,n){function t(e){return e&&e.__esModule?e:{"default":e}}function r(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}function o(e,n){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!n||"object"!==("undefined"==typeof n?"undefined":_typeof(n))&&"function"!=typeof n?e:n}function u(e,n){if("function"!=typeof n&&null!==n)throw new TypeError("Super expression must either be null or a function, not "+typeof n);e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),n&&(Object.setPrototypeOf?Object.setPrototypeOf(e,n):e.__proto__=n)}Object.defineProperty(e,"__esModule",{value:!0});var i=t(n),s=function(e){function n(e){r(this,n);var t=o(this,Object.getPrototypeOf(n).call(this,e)),u=t.getRepo,i=t.request||t._request;return t.getRepo=function(n,t){function r(e){return new Promise(function(n,t){e.show(function(e,r){e&&t(e),n(r)})})}var o=u(n,t),s=o.remove,f=o.fork;return o.search=function(e){var n=arguments.length<=1||void 0===arguments[1]?{}:arguments[1],t="blob",r="tree";return n=Object.assign({branch:"master",caseSensitive:!1,excludeFiles:!1,excludeFolders:!1},n),new Promise(function(e,t){o.getSha(n.branch,"",function(n,r){n&&t(n),e(r)})}).then(function(e){return new Promise(function(n,t){o.getTree(e+"?recursive=true",function(e,r){e&&(404===e.error?n([]):t(e)),n(r)})})}).then(function(o){var u=new RegExp(e,n.caseSensitive?"":"i");return o.filter(function(e){var o=n.excludeFiles?e.type!==t:!0,i=n.excludeFolders?e.type!==r:!0,s=function(e){return e.substring(e.lastIndexOf("/")+1)};return o&&i&&u.test(s(e.path))})})},o.mergePullRequest=function(e){var n=arguments.length<=1||void 0===arguments[1]?{}:arguments[1];return n=Object.assign({commitMessage:"Merged pull request gh-"+e.number},n),r(o).then(function(t){return new Promise(function(r,o){i("PUT","/repos/"+t.full_name+"/pulls/"+e.number+"/merge",{commit_message:n.commitMessage,sha:e.head.sha},function(e,n){e&&o(e),r(n)})})})},o.remove=function(){function e(e,n){return new Promise(function(t,r){s(e,n,function(e){e&&r(e),t()})})}function n(){return new Promise(function(e,n){o.getRef("heads/"+t,function(t,r){t&&n(t),e(r)})}).then(function(e){return new Promise(function(n,t){o.getTree(e+"?recursive=true",function(e,r){e&&t(e),n(r)})})}).then(function(n){var o=Promise.resolve();return n.filter(function(e){return 0===e.path.indexOf(r)&&"blob"===e.type}).map(function(e){return e.path}).forEach(function(n){o=o.then(function(){return e(t,n)})}),o})}var t=arguments.length<=0||void 0===arguments[0]?"master":arguments[0],r=arguments.length<=1||void 0===arguments[1]?"":arguments[1];r=r.replace(/\/$/,"");var u=e(t,r);return u.then(function(){return u},function(e){if(422!==e.error)throw e;return n()})},o.fork=function(){return new Promise(function(n,r){f(function(o,i){function s(e){e.contents("master","",function(t,r){r?n(i):setTimeout(s.bind(null,e),250)})}o?r(o):s(u(e.username,t))})})},o},t}return u(n,e),n}(i["default"]);e["default"]=s}); 2 | //# sourceMappingURL=github-extended.min.js.map 3 | -------------------------------------------------------------------------------- /dist/github-extended.min.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["github-extended.js","github-extended.min.js"],"names":["_typeof","obj","Symbol","constructor","global","factory","define","amd","exports","require","mod","Github","this","_githubApi","_interopRequireDefault","__esModule","default","_classCallCheck","instance","Constructor","TypeError","_possibleConstructorReturn","self","call","ReferenceError","_inherits","subClass","superClass","prototype","Object","create","value","enumerable","writable","configurable","setPrototypeOf","__proto__","defineProperty","_githubApi2","_GithubApi","options","_this","getPrototypeOf","superGetRepo","getRepo","request","_request","user","repo","getRepositoryInfo","repository","Promise","resolve","reject","show","error","superRemove","remove","superFork","fork","search","string","arguments","length","undefined","FILE","FOLDER","assign","branch","caseSensitive","excludeFiles","excludeFolders","getSha","sha","then","getTree","list","regex","RegExp","filter","content","fileCondition","type","folderCondition","extractName","path","substring","lastIndexOf","test","mergePullRequest","pullRequest","commitMessage","number","repositoryInfo","full_name","commit_message","head","mergeInfo","removeFile","branchName","removeFolder","getRef","tree","filesPromises","item","indexOf","map","forEach","replace","removeFilePromise","err","forkInfo","pollFork","contents","setTimeout","bind","username"],"mappings":"AAAA,YCEA,SAASA,SAAQC,GAAO,MAAOA,IAAyB,mBAAXC,SAA0BD,EAAIE,cAAgBD,OAAS,eAAkBD,IAEtH,SAAWG,EAAQC,GAChB,GAAsB,kBAAXC,SAAyBA,OAAOC,IACxCD,OAAO,UAAW,UAAW,cAAeD,OACxC,IAAuB,mBAAZG,SACfH,EAAQG,QAASC,QAAQ,mBACrB,CACJ,GAAIC,IACDF,WAEHH,GAAQK,EAAIF,QAASJ,EAAOO,QAC5BP,EAAOO,OAASD,EAAIF,UAEvBI,KAAM,SAAUJ,EAASK,GAOzB,QAASC,GAAuBb,GAC7B,MAAOA,IAAOA,EAAIc,WAAad,GAC5Be,UAASf,GAIf,QAASgB,GAAgBC,EAAUC,GAChC,KAAMD,YAAoBC,IACvB,KAAM,IAAIC,WAAU,qCAI1B,QAASC,GAA2BC,EAAMC,GACvC,IAAKD,EACF,KAAM,IAAIE,gBAAe,4DAG5B,QAAOD,GAAyE,YAA/C,mBAATA,GAAuB,YAAcvB,QAAQuB,KAAuC,kBAATA,GAA8BD,EAAPC,EAG7H,QAASE,GAAUC,EAAUC,GAC1B,GAA0B,kBAAfA,IAA4C,OAAfA,EACrC,KAAM,IAAIP,WAAU,iEAAoEO,GAG3FD,GAASE,UAAYC,OAAOC,OAAOH,GAAcA,EAAWC,WACzDzB,aACG4B,MAAOL,EACPM,YAAY,EACZC,UAAU,EACVC,cAAc,KAGhBP,IAAYE,OAAOM,eAAiBN,OAAOM,eAAeT,EAAUC,GAAcD,EAASU,UAAYT,GAvC9GE,OAAOQ,eAAe7B,EAAS,cAC5BuB,OAAO,GAGV,IAAIO,GAAcxB,EAAuBD,GDX7BF,EAAM,SAAA4B,GCoDf,QDpDS5B,GAAM6B,GCqDZvB,EAAgBL,KDrDVD,ECuDN,IAAI8B,GAAQpB,EAA2BT,KAAMiB,OAAOa,eDvD9C/B,GAAMY,KAAAX,KAAA4B,ICyDRG,EAAeF,EAAMG,QACrBC,EAAUJ,EAAMI,SAAWJ,EAAMK,QA+KrC,OA7KAL,GAAMG,QAAU,SAAUG,EAAMC,GAK7B,QAASC,GAAkBC,GACxB,MAAO,IAAIC,SAAQ,SAAUC,EAASC,GACnCH,EAAWI,KAAK,SAAUC,EAAOP,GAC1BO,GACDF,EAAOE,GAGVH,EAAQJ,OAXjB,GAAIE,GAAaP,EAAaI,EAAMC,GAChCQ,EAAcN,EAAWO,OACzBC,EAAYR,EAAWS,IAuK3B,OAzJAT,GAAWU,OAAS,SAAUC,GAC3B,GD1BuBrB,GAAOsB,UAAAC,QAAA,GAAAC,SAAAF,UAAA,MAAKA,UAAA,GC2B/BG,EAAO,OACPC,EAAS,MAOb,OANA1B,GAAUX,OAAOsC,QACdC,OAAQ,SACRC,eAAe,EACfC,cAAc,EACdC,gBAAgB,GAChB/B,GACI,GAAIW,SAAQ,SAAUC,EAASC,GACnCH,EAAWsB,OAAOhC,EAAQ4B,OAAQ,GAAI,SAAUb,EAAOkB,GAChDlB,GACDF,EAAOE,GAGVH,EAAQqB,OAEXC,KAAK,SAAUD,GACf,MAAO,IAAItB,SAAQ,SAAUC,EAASC,GACnCH,EAAWyB,QAAQF,EAAM,kBAAmB,SAAUlB,EAAOqB,GACtDrB,IACmB,MAAhBA,EAAMA,MACPH,MAEAC,EAAOE,IAIbH,EAAQwB,SAGdF,KAAK,SAAUE,GACf,GAAIC,GAAQ,GAAIC,QAAOjB,EAAQrB,EAAQ6B,cAAgB,GAAK,IAC5D,OAAOO,GAAKG,OAAO,SAAUC,GAC1B,GAAIC,GAAgBzC,EAAQ8B,aAAeU,EAAQE,OAASjB,GAAO,EAC/DkB,EAAkB3C,EAAQ+B,eAAiBS,EAAQE,OAAShB,GAAS,EAErEkB,EAAc,SAAqBC,GACpC,MAAOA,GAAKC,UAAUD,EAAKE,YAAY,KAAO,GAGjD,OAAON,IAAiBE,GAAmBN,EAAMW,KAAKJ,EAAYJ,EAAQK,YAKnFnC,EAAWuC,iBAAmB,SAAUC,GACrC,GDfsClD,GAAOsB,UAAAC,QAAA,GAAAC,SAAAF,UAAA,MAAKA,UAAA,ECmBlD,OAHAtB,GAAUX,OAAOsC,QACdwB,cAAe,0BAA4BD,EAAYE,QACvDpD,GACIS,EAAkBC,GAAYwB,KAAK,SAAUmB,GACjD,MAAO,IAAI1C,SAAQ,SAAUC,EAASC,GACnCR,EAAQ,MAAO,UAAYgD,EAAeC,UAAY,UAAYJ,EAAYE,OAAS,UACpFG,eAAgBvD,EAAQmD,cACxBlB,IAAKiB,EAAYM,KAAKvB,KACtB,SAAUlB,EAAO0C,GACb1C,GACDF,EAAOE,GAGVH,EAAQ6C,UAMpB/C,EAAWO,OAAS,WAIjB,QAASyC,GAAWC,EAAYd,GAC7B,MAAO,IAAIlC,SAAQ,SAAUC,EAASC,GACnCG,EAAY2C,EAAYd,EAAM,SAAU9B,GACjCA,GACDF,EAAOE,GAGVH,QAKT,QAASgD,KACN,MAAO,IAAIjD,SAAQ,SAAUC,EAASC,GACnCH,EAAWmD,OAAO,SAAWF,EAAY,SAAU5C,EAAOkB,GACnDlB,GACDF,EAAOE,GAGVH,EAAQqB,OAEXC,KAAK,SAAUD,GACf,MAAO,IAAItB,SAAQ,SAAUC,EAASC,GACnCH,EAAWyB,QAAQF,EAAM,kBAAmB,SAAUlB,EAAO+C,GACtD/C,GACDF,EAAOE,GAGVH,EAAQkD,SAGd5B,KAAK,SAAU4B,GACf,GAAIC,GAAgBpD,QAAQC,SAU5B,OATAkD,GAAKvB,OAAO,SAAUyB,GACnB,MAAmC,KAA5BA,EAAKnB,KAAKoB,QAAQpB,IAA6B,SAAdmB,EAAKtB,OAC7CwB,IAAI,SAAUF,GACd,MAAOA,GAAKnB,OACZsB,QAAQ,SAAUtB,GAClBkB,EAAgBA,EAAc7B,KAAK,WAChC,MAAOwB,GAAWC,EAAYd,OAG7BkB,IA7Cb,GDEeJ,GAAUrC,UAAAC,QAAA,GAAAC,SAAAF,UAAA,GAAG,SAAQA,UAAA,GAAEuB,EAAIvB,UAAAC,QAAA,GAAAC,SAAAF,UAAA,GAAG,GAAEA,UAAA,EC+C/CuB,GAAOA,EAAKuB,QAAQ,MAAO,GAC3B,IAAIC,GAAoBX,EAAWC,EAAYd,EAC/C,OAAOwB,GAAkBnC,KAAK,WAC3B,MAAOmC,IACP,SAAUtD,GACV,GAAoB,MAAhBA,EAAMA,MACP,KAAMA,EAGT,OAAO6C,QAIblD,EAAWS,KAAO,WACf,MAAO,IAAIR,SAAQ,SAAUC,EAASC,GACnCK,EAAU,SAAUoD,EAAKC,GACtB,QAASC,GAASrD,GACfA,EAAKsD,SAAS,SAAU,GAAI,SAAUH,EAAKG,GACpCA,EACD7D,EAAQ2D,GAERG,WAAWF,EAASG,KAAK,KAAMxD,GAAO,OAK3CmD,EACDzD,EAAOyD,GAEPE,EAASrE,EAAaH,EAAQ4E,SAAUpE,SAM7CE,GAGHT,EAGV,MA1LAhB,GDlDSd,EAAM4B,GAAN5B,GC6OT2B,EAAAA,WAEH9B,GAAAA,WD/OYG","file":"github-extended.min.js","sourcesContent":["'use strict';\n\nimport GithubApi from 'github-api';\n\n/**\n * The class that extends Github.js\n *\n * @extends GithubApi\n */\nexport\n default class Github extends GithubApi {\n /**\n * @constructor\n * @param {Object} options The object containing the information to work with the GitHub API\n * @param {string} options.username The username used on GitHub\n * @param {string} options.password The password of the GitHub account\n * @param {string} options.auth The type of authentication to use. It can be either `basic` or `oauth`\n * @param {string} options.token The token to access the GitHub API\n */\n constructor(options) {\n super(options);\n\n let superGetRepo = this.getRepo;\n let request = this.request || this._request; // jscs:ignore disallowDanglingUnderscores\n\n /**\n * Returns an object representing a specific repository\n *\n * @param {string} user The username that possesses the repository\n * @param {string} repo The name of the repository to work on\n *\n * @returns {Object}\n */\n this.getRepo = (user, repo) => {\n let repository = superGetRepo(user, repo);\n let superRemove = repository.remove;\n let superFork = repository.fork;\n\n function getRepositoryInfo(repository) {\n return new Promise((resolve, reject) => {\n repository.show((error, repo) => {\n if (error) {\n reject(error);\n }\n\n resolve(repo);\n });\n });\n }\n\n /**\n * Searches files and folders\n *\n * @param {string} string The string to search\n * @param {Object} [options={}] Possible options\n * @param {string} [options.branch] The name of the branch in which the search must be performed\n * @param {boolean} [options.caseSensitive=false] If the search must be case sensitive\n * @param {boolean} [options.excludeFiles=false] If the result must exclude files\n * @param {boolean} [options.excludeFolders=false] If the result must exclude folders\n *\n * @returns {Promise}\n */\n repository.search = (string, options = {}) => {\n const FILE = 'blob';\n const FOLDER = 'tree';\n\n options = Object.assign({\n branch: 'master',\n caseSensitive: false,\n excludeFiles: false,\n excludeFolders: false\n }, options);\n\n return new Promise((resolve, reject) => {\n repository.getSha(options.branch, '', (error, sha) => {\n if (error) {\n reject(error);\n }\n\n resolve(sha);\n });\n })\n .then(sha => {\n return new Promise((resolve, reject) => {\n repository.getTree(`${sha}?recursive=true`, (error, list) => {\n if (error) {\n // No matches\n if (error.error === 404) {\n resolve([]);\n } else {\n reject(error);\n }\n }\n\n resolve(list);\n });\n });\n })\n .then(list => {\n let regex = new RegExp(string, options.caseSensitive ? '' : 'i');\n\n return list.filter(content => {\n let fileCondition = options.excludeFiles ? content.type !== FILE : true;\n let folderCondition = options.excludeFolders ? content.type !== FOLDER : true;\n let extractName = (path) => path.substring(path.lastIndexOf('/') + 1);\n\n return fileCondition && folderCondition && regex.test(extractName(content.path));\n });\n });\n };\n\n /**\n * Merges a pull request\n *\n * @param {Object} pullRequest The pull request to merge\n * @param {Object} [options={}] Possible options\n * @param {string} [options.commitMessage] The commit message for the merge\n *\n * @returns {Promise}\n */\n repository.mergePullRequest = (pullRequest, options = {}) => {\n options = Object.assign(\n {\n commitMessage: `Merged pull request gh-${pullRequest.number}`\n },\n options\n );\n\n return getRepositoryInfo(repository)\n .then(repositoryInfo => {\n return new Promise((resolve, reject) => {\n request(\n 'PUT',\n `/repos/${repositoryInfo.full_name}/pulls/${pullRequest.number}/merge`, // jscs:ignore\n {\n commit_message: options.commitMessage, // jscs:ignore\n sha: pullRequest.head.sha\n },\n (error, mergeInfo) => {\n if (error) {\n reject(error);\n }\n\n resolve(mergeInfo);\n }\n );\n });\n });\n };\n\n /**\n * Deletes a file or a folder and all of its content from a given branch\n *\n * @param {string} [branchName='master'] The name of the branch in which the deletion must be performed\n * @param {string} [path=''] The path of the file or the folder to delete\n *\n * @returns {Promise}\n */\n repository.remove = (branchName = 'master', path = '') => {\n function removeFile(branchName, path) {\n return new Promise((resolve, reject) => {\n superRemove(branchName, path, error => {\n if (error) {\n reject(error);\n }\n\n resolve();\n });\n });\n }\n\n function removeFolder() {\n return new Promise((resolve, reject) => {\n repository.getRef(`heads/${branchName}`, (error, sha) => {\n if (error) {\n reject(error);\n }\n\n resolve(sha);\n });\n })\n .then(sha => {\n return new Promise((resolve, reject) => {\n repository.getTree(`${sha}?recursive=true`, (error, tree) => {\n if (error) {\n reject(error);\n }\n\n resolve(tree);\n });\n });\n })\n .then(tree => {\n let filesPromises = Promise.resolve();\n\n // Filters all items that aren't in the path of interest and aren't files\n // and delete them.\n tree\n .filter(item => item.path.indexOf(path) === 0 && item.type === 'blob')\n .map(item => item.path)\n .forEach(path => {\n filesPromises = filesPromises.then(() => removeFile(branchName, path));\n });\n\n return filesPromises;\n });\n }\n\n // Remove any trailing slash from the path.\n // GitHub does not accept it even when dealing with folders.\n path = path.replace(/\\/$/, '');\n\n let removeFilePromise = removeFile(branchName, path);\n\n return removeFilePromise\n .then(\n () => removeFilePromise,\n error => {\n // If the operation fails because the path specified is that of a folder\n // keep going to retrieve the files recursively\n if (error.error !== 422) {\n throw error;\n }\n\n return removeFolder();\n });\n };\n\n /**\n * Creates a fork of the repository\n *\n * @returns {Promise}\n */\n repository.fork = () => {\n return new Promise((resolve, reject) => {\n superFork((err, forkInfo) => {\n function pollFork(fork) {\n fork.contents('master', '', (err, contents) => {\n if (contents) {\n resolve(forkInfo);\n } else {\n setTimeout(pollFork.bind(null, fork), 250);\n }\n });\n }\n\n if (err) {\n reject(err);\n } else {\n pollFork(superGetRepo(options.username, repo));\n }\n });\n });\n };\n\n return repository;\n };\n }\n}","'use strict';\n\nfunction _typeof(obj) { return obj && typeof Symbol !== \"undefined\" && obj.constructor === Symbol ? \"symbol\" : typeof obj; }\n\n(function (global, factory) {\n if (typeof define === \"function\" && define.amd) {\n define('Github', ['exports', 'github-api'], factory);\n } else if (typeof exports !== \"undefined\") {\n factory(exports, require('github-api'));\n } else {\n var mod = {\n exports: {}\n };\n factory(mod.exports, global.Github);\n global.Github = mod.exports;\n }\n})(this, function (exports, _githubApi) {\n Object.defineProperty(exports, \"__esModule\", {\n value: true\n });\n\n var _githubApi2 = _interopRequireDefault(_githubApi);\n\n function _interopRequireDefault(obj) {\n return obj && obj.__esModule ? obj : {\n default: obj\n };\n }\n\n function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n }\n\n function _possibleConstructorReturn(self, call) {\n if (!self) {\n throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n }\n\n return call && ((typeof call === 'undefined' ? 'undefined' : _typeof(call)) === \"object\" || typeof call === \"function\") ? call : self;\n }\n\n function _inherits(subClass, superClass) {\n if (typeof superClass !== \"function\" && superClass !== null) {\n throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass);\n }\n\n subClass.prototype = Object.create(superClass && superClass.prototype, {\n constructor: {\n value: subClass,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;\n }\n\n var Github = (function (_GithubApi) {\n _inherits(Github, _GithubApi);\n\n function Github(options) {\n _classCallCheck(this, Github);\n\n var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Github).call(this, options));\n\n var superGetRepo = _this.getRepo;\n var request = _this.request || _this._request;\n\n _this.getRepo = function (user, repo) {\n var repository = superGetRepo(user, repo);\n var superRemove = repository.remove;\n var superFork = repository.fork;\n\n function getRepositoryInfo(repository) {\n return new Promise(function (resolve, reject) {\n repository.show(function (error, repo) {\n if (error) {\n reject(error);\n }\n\n resolve(repo);\n });\n });\n }\n\n repository.search = function (string) {\n var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n var FILE = 'blob';\n var FOLDER = 'tree';\n options = Object.assign({\n branch: 'master',\n caseSensitive: false,\n excludeFiles: false,\n excludeFolders: false\n }, options);\n return new Promise(function (resolve, reject) {\n repository.getSha(options.branch, '', function (error, sha) {\n if (error) {\n reject(error);\n }\n\n resolve(sha);\n });\n }).then(function (sha) {\n return new Promise(function (resolve, reject) {\n repository.getTree(sha + '?recursive=true', function (error, list) {\n if (error) {\n if (error.error === 404) {\n resolve([]);\n } else {\n reject(error);\n }\n }\n\n resolve(list);\n });\n });\n }).then(function (list) {\n var regex = new RegExp(string, options.caseSensitive ? '' : 'i');\n return list.filter(function (content) {\n var fileCondition = options.excludeFiles ? content.type !== FILE : true;\n var folderCondition = options.excludeFolders ? content.type !== FOLDER : true;\n\n var extractName = function extractName(path) {\n return path.substring(path.lastIndexOf('/') + 1);\n };\n\n return fileCondition && folderCondition && regex.test(extractName(content.path));\n });\n });\n };\n\n repository.mergePullRequest = function (pullRequest) {\n var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n options = Object.assign({\n commitMessage: 'Merged pull request gh-' + pullRequest.number\n }, options);\n return getRepositoryInfo(repository).then(function (repositoryInfo) {\n return new Promise(function (resolve, reject) {\n request('PUT', '/repos/' + repositoryInfo.full_name + '/pulls/' + pullRequest.number + '/merge', {\n commit_message: options.commitMessage,\n sha: pullRequest.head.sha\n }, function (error, mergeInfo) {\n if (error) {\n reject(error);\n }\n\n resolve(mergeInfo);\n });\n });\n });\n };\n\n repository.remove = function () {\n var branchName = arguments.length <= 0 || arguments[0] === undefined ? 'master' : arguments[0];\n var path = arguments.length <= 1 || arguments[1] === undefined ? '' : arguments[1];\n\n function removeFile(branchName, path) {\n return new Promise(function (resolve, reject) {\n superRemove(branchName, path, function (error) {\n if (error) {\n reject(error);\n }\n\n resolve();\n });\n });\n }\n\n function removeFolder() {\n return new Promise(function (resolve, reject) {\n repository.getRef('heads/' + branchName, function (error, sha) {\n if (error) {\n reject(error);\n }\n\n resolve(sha);\n });\n }).then(function (sha) {\n return new Promise(function (resolve, reject) {\n repository.getTree(sha + '?recursive=true', function (error, tree) {\n if (error) {\n reject(error);\n }\n\n resolve(tree);\n });\n });\n }).then(function (tree) {\n var filesPromises = Promise.resolve();\n tree.filter(function (item) {\n return item.path.indexOf(path) === 0 && item.type === 'blob';\n }).map(function (item) {\n return item.path;\n }).forEach(function (path) {\n filesPromises = filesPromises.then(function () {\n return removeFile(branchName, path);\n });\n });\n return filesPromises;\n });\n }\n\n path = path.replace(/\\/$/, '');\n var removeFilePromise = removeFile(branchName, path);\n return removeFilePromise.then(function () {\n return removeFilePromise;\n }, function (error) {\n if (error.error !== 422) {\n throw error;\n }\n\n return removeFolder();\n });\n };\n\n repository.fork = function () {\n return new Promise(function (resolve, reject) {\n superFork(function (err, forkInfo) {\n function pollFork(fork) {\n fork.contents('master', '', function (err, contents) {\n if (contents) {\n resolve(forkInfo);\n } else {\n setTimeout(pollFork.bind(null, fork), 250);\n }\n });\n }\n\n if (err) {\n reject(err);\n } else {\n pollFork(superGetRepo(options.username, repo));\n }\n });\n });\n };\n\n return repository;\n };\n\n return _this;\n }\n\n return Github;\n })(_githubApi2.default);\n\n exports.default = Github;\n});"],"sourceRoot":"/source/"} -------------------------------------------------------------------------------- /doc/badge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | document 13 | document 14 | 100% 15 | 100% 16 | 17 | 18 | -------------------------------------------------------------------------------- /doc/class/src/github-extended.js~Github.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Github | API Document 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | Home 18 | 19 | Reference 20 | Source 21 | Test 22 | Repository 23 | 30 |
31 | 32 | 39 | 40 |
41 |
import Github from 'github-extended'
42 | public 43 | class 44 | 45 | 46 | 47 | | source 48 |
49 | 50 |
51 |

Github

52 | 53 | 54 | 55 | 56 | 57 |

Extends:

* → Github
58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 |

The class that extends Github.js

68 |
69 | 70 | 71 | 72 | 73 | 74 |
75 |

Test:

76 | 80 |
81 | 82 | 83 |
84 | 85 | 86 | 87 |

Constructor Summary

88 | 89 | 90 | 91 | 92 | 99 | 111 | 115 | 116 | 117 |
Public Constructor
93 | public 94 | 95 | 96 | 97 | 98 | 100 |
101 |

102 | constructor(options: Object) 103 |

104 |
105 |
106 | 107 | 108 | 109 |
110 |
112 | 113 | 114 |
118 |
119 |

Member Summary

120 | 121 | 122 | 123 | 124 | 131 | 144 | 148 | 149 | 150 |
Public Members
125 | public 126 | 127 | 128 | 129 | 130 | 132 |
133 |

134 | getRepo(user: string, repo: string): Object: * 135 |

136 |
137 |
138 | 139 | 140 |

Returns an object representing a specific repository

141 |
142 |
143 |
145 | 146 | 147 |
151 |
152 | 153 | 154 | 155 | 156 | 157 | 158 |

Public Constructors

159 | 160 |
161 |

162 | public 163 | 164 | 165 | 166 | 167 | constructor(options: Object) 168 | 169 | 170 | 171 | source 172 | 173 |

174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 |
183 |

Params:

184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 196 | 197 | 198 | 199 | 200 | 201 | 203 | 204 | 205 | 206 | 207 | 208 | 210 | 211 | 212 | 213 | 214 | 215 | 217 | 218 | 219 | 220 | 221 | 222 | 224 | 225 | 226 |
NameTypeAttributeDescription
optionsObject

The object containing the information to work with the GitHub API

195 |
options.usernamestring

The username used on GitHub

202 |
options.passwordstring

The password of the GitHub account

209 |
options.authstring

The type of authentication to use. It can be either basic or oauth

216 |
options.tokenstring

The token to access the GitHub API

223 |
227 |
228 |
229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 |
245 |
246 |

Public Members

247 | 248 |
249 |

250 | public 251 | 252 | 253 | 254 | 255 | getRepo(user: string, repo: string): Object: * 256 | 257 | 258 | 259 | source 260 | 261 |

262 | 263 | 264 | 265 | 266 |

Returns an object representing a specific repository

267 |
268 | 269 | 270 | 271 |
272 |
273 | 274 |
275 |

Return:

276 | 277 | 278 | 279 | 280 | 281 |
Object
282 |
283 |
284 |
285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 |
299 |
300 | 301 |
302 | 303 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | -------------------------------------------------------------------------------- /doc/coverage.json: -------------------------------------------------------------------------------- 1 | { 2 | "coverage": "100%", 3 | "expectCount": 3, 4 | "actualCount": 3, 5 | "files": { 6 | "src/github-extended.js": { 7 | "expectCount": 3, 8 | "actualCount": 3, 9 | "undocumentLines": [] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /doc/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 | -------------------------------------------------------------------------------- /doc/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 | -------------------------------------------------------------------------------- /doc/file/src/github-extended.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | src/github-extended.js | API Document 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | Home 18 | 19 | Reference 20 | Source 21 | Test 22 | Repository 23 | 30 |
31 | 32 | 39 | 40 |

src/github-extended.js

41 |
'use strict';
 42 | 
 43 | import GithubApi from 'github-api';
 44 | 
 45 | /**
 46 |  * The class that extends Github.js
 47 |  *
 48 |  * @extends GithubApi
 49 |  */
 50 | export
 51 |  default class Github extends GithubApi {
 52 |    /**
 53 |     * @constructor
 54 |     * @param {Object} options The object containing the information to work with the GitHub API
 55 |     * @param {string} options.username The username used on GitHub
 56 |     * @param {string} options.password The password of the GitHub account
 57 |     * @param {string} options.auth The type of authentication to use. It can be either `basic` or `oauth`
 58 |     * @param {string} options.token The token to access the GitHub API
 59 |     */
 60 |    constructor(options) {
 61 |       super(options);
 62 | 
 63 |       let superGetRepo = this.getRepo;
 64 |       let request = this.request || this._request; // jscs:ignore disallowDanglingUnderscores
 65 | 
 66 |       /**
 67 |        * Returns an object representing a specific repository
 68 |        *
 69 |        * @param {string} user The username that possesses the repository
 70 |        * @param {string} repo The name of the repository to work on
 71 |        *
 72 |        * @returns {Object}
 73 |        */
 74 |       this.getRepo = (user, repo) => {
 75 |          let repository = superGetRepo(user, repo);
 76 |          let superRemove = repository.remove;
 77 |          let superFork = repository.fork;
 78 | 
 79 |          function getRepositoryInfo(repository) {
 80 |             return new Promise((resolve, reject) => {
 81 |                repository.show((error, repo) => {
 82 |                   if (error) {
 83 |                      reject(error);
 84 |                   }
 85 | 
 86 |                   resolve(repo);
 87 |                });
 88 |             });
 89 |          }
 90 | 
 91 |          /**
 92 |           * Searches files and folders
 93 |           *
 94 |           * @param {string} string The string to search
 95 |           * @param {Object} [options={}] Possible options
 96 |           * @param {string} [options.branch] The name of the branch in which the search must be performed
 97 |           * @param {boolean} [options.caseSensitive=false] If the search must be case sensitive
 98 |           * @param {boolean} [options.excludeFiles=false] If the result must exclude files
 99 |           * @param {boolean} [options.excludeFolders=false] If the result must exclude folders
100 |           *
101 |           * @returns {Promise}
102 |           */
103 |          repository.search = (string, options = {}) => {
104 |             const FILE = 'blob';
105 |             const FOLDER = 'tree';
106 | 
107 |             options = Object.assign({
108 |                branch: 'master',
109 |                caseSensitive: false,
110 |                excludeFiles: false,
111 |                excludeFolders: false
112 |             }, options);
113 | 
114 |             return new Promise((resolve, reject) => {
115 |                repository.getSha(options.branch, '', (error, sha) => {
116 |                   if (error) {
117 |                      reject(error);
118 |                   }
119 | 
120 |                   resolve(sha);
121 |                });
122 |             })
123 |                .then(sha => {
124 |                   return new Promise((resolve, reject) => {
125 |                      repository.getTree(`${sha}?recursive=true`, (error, list) => {
126 |                         if (error) {
127 |                            // No matches
128 |                            if (error.error === 404) {
129 |                               resolve([]);
130 |                            } else {
131 |                               reject(error);
132 |                            }
133 |                         }
134 | 
135 |                         resolve(list);
136 |                      });
137 |                   });
138 |                })
139 |                .then(list => {
140 |                   let regex = new RegExp(string, options.caseSensitive ? '' : 'i');
141 | 
142 |                   return list.filter(content => {
143 |                      let fileCondition = options.excludeFiles ? content.type !== FILE : true;
144 |                      let folderCondition = options.excludeFolders ? content.type !== FOLDER : true;
145 |                      let extractName = (path) => path.substring(path.lastIndexOf('/') + 1);
146 | 
147 |                      return fileCondition && folderCondition && regex.test(extractName(content.path));
148 |                   });
149 |                });
150 |          };
151 | 
152 |          /**
153 |           * Merges a pull request
154 |           *
155 |           * @param {Object} pullRequest The pull request to merge
156 |           * @param {Object} [options={}] Possible options
157 |           * @param {string} [options.commitMessage] The commit message for the merge
158 |           *
159 |           * @returns {Promise}
160 |           */
161 |          repository.mergePullRequest = (pullRequest, options = {}) => {
162 |             options = Object.assign(
163 |                {
164 |                   commitMessage: `Merged pull request gh-${pullRequest.number}`
165 |                },
166 |                options
167 |             );
168 | 
169 |             return getRepositoryInfo(repository)
170 |                .then(repositoryInfo => {
171 |                   return new Promise((resolve, reject) => {
172 |                      request(
173 |                         'PUT',
174 |                         `/repos/${repositoryInfo.full_name}/pulls/${pullRequest.number}/merge`, // jscs:ignore
175 |                         {
176 |                            commit_message: options.commitMessage, // jscs:ignore
177 |                            sha: pullRequest.head.sha
178 |                         },
179 |                         (error, mergeInfo) => {
180 |                            if (error) {
181 |                               reject(error);
182 |                            }
183 | 
184 |                            resolve(mergeInfo);
185 |                         }
186 |                      );
187 |                   });
188 |                });
189 |          };
190 | 
191 |          /**
192 |           * Deletes a file or a folder and all of its content from a given branch
193 |           *
194 |           * @param {string} [branchName='master'] The name of the branch in which the deletion must be performed
195 |           * @param {string} [path=''] The path of the file or the folder to delete
196 |           *
197 |           * @returns {Promise}
198 |           */
199 |          repository.remove = (branchName = 'master', path = '') => {
200 |             function removeFile(branchName, path) {
201 |                return new Promise((resolve, reject) => {
202 |                   superRemove(branchName, path, error => {
203 |                      if (error) {
204 |                         reject(error);
205 |                      }
206 | 
207 |                      resolve();
208 |                   });
209 |                });
210 |             }
211 | 
212 |             function removeFolder() {
213 |                return new Promise((resolve, reject) => {
214 |                   repository.getRef(`heads/${branchName}`, (error, sha) => {
215 |                      if (error) {
216 |                         reject(error);
217 |                      }
218 | 
219 |                      resolve(sha);
220 |                   });
221 |                })
222 |                   .then(sha => {
223 |                      return new Promise((resolve, reject) => {
224 |                         repository.getTree(`${sha}?recursive=true`, (error, tree) => {
225 |                            if (error) {
226 |                               reject(error);
227 |                            }
228 | 
229 |                            resolve(tree);
230 |                         });
231 |                      });
232 |                   })
233 |                   .then(tree => {
234 |                      let filesPromises = Promise.resolve();
235 | 
236 |                      // Filters all items that aren't in the path of interest and aren't files
237 |                      // and delete them.
238 |                      tree
239 |                         .filter(item => item.path.indexOf(path) === 0 && item.type === 'blob')
240 |                         .map(item => item.path)
241 |                         .forEach(path => {
242 |                            filesPromises = filesPromises.then(() => removeFile(branchName, path));
243 |                         });
244 | 
245 |                      return filesPromises;
246 |                   });
247 |             }
248 | 
249 |             // Remove any trailing slash from the path.
250 |             // GitHub does not accept it even when dealing with folders.
251 |             path = path.replace(/\/$/, '');
252 | 
253 |             let removeFilePromise = removeFile(branchName, path);
254 | 
255 |             return removeFilePromise
256 |                .then(
257 |                   () => removeFilePromise,
258 |                   error => {
259 |                      // If the operation fails because the path specified is that of a folder
260 |                      // keep going to retrieve the files recursively
261 |                      if (error.error !== 422) {
262 |                         throw error;
263 |                      }
264 | 
265 |                      return removeFolder();
266 |                   });
267 |          };
268 | 
269 |          /**
270 |           * Creates a fork of the repository
271 |           *
272 |           * @returns {Promise}
273 |           */
274 |          repository.fork = () => {
275 |             return new Promise((resolve, reject) => {
276 |                superFork((err, forkInfo) => {
277 |                   function pollFork(fork) {
278 |                      fork.contents('master', '', (err, contents) => {
279 |                         if (contents) {
280 |                            resolve(forkInfo);
281 |                         } else {
282 |                            setTimeout(pollFork.bind(null, fork), 250);
283 |                         }
284 |                      });
285 |                   }
286 | 
287 |                   if (err) {
288 |                      reject(err);
289 |                   } else {
290 |                      pollFork(superGetRepo(options.username, repo));
291 |                   }
292 |                });
293 |             });
294 |          };
295 | 
296 |          return repository;
297 |       };
298 |    }
299 | }
300 | 301 |
302 | 303 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | -------------------------------------------------------------------------------- /doc/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 | Test 22 | Repository 23 | 30 |
31 | 32 | 39 | 40 |

References

41 |

Class Summary

42 | 43 | 44 | 45 | 46 | 53 | 66 | 70 | 71 | 72 |
Static Public Class Summary
47 | public 48 | 49 | 50 | 51 | 52 | 54 |
55 |

56 | Github 57 |

58 |
59 |
60 | 61 | 62 |

The class that extends Github.js

63 |
64 |
65 |
67 | 68 | 69 |
73 |
74 | 75 | 76 | 77 | 78 | 79 |
80 | 81 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /doc/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 | -------------------------------------------------------------------------------- /doc/image/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/github-tools/github-extended/de1825e29a9347acb1f68ad4a82f9a12d387f98d/doc/image/github.png -------------------------------------------------------------------------------- /doc/image/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/github-tools/github-extended/de1825e29a9347acb1f68ad4a82f9a12d387f98d/doc/image/search.png -------------------------------------------------------------------------------- /doc/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 | Test 22 | Repository 23 | 30 |
31 | 32 | 39 | 40 |

GitHub Extended

41 |

GitHub Extended is a collection of methods to extend the 42 | functionality of Github.js (known on npm as 43 | github-api).

44 |

Requirements

45 |

Being an extension for Github.js, the only requirement is to install and include 46 | Github.js before 47 | GitHub Extended.

48 |

Installation

49 |

You can install GitHub Extended by using npm:

50 |
npm install github-extended
51 | 

Alternatively, you can install it via Bower:

52 |
bower install github-extended --save
53 | 

Another possibility is to manually download it.

54 |

Methods

55 |

The sections below describe the methods provided.

56 |

repository.search(string, options = {})

57 |

Searches files and folders

58 |

repository.mergePullRequest(pullRequest, options = {})

59 |

Merges a pull request

60 |

repository.remove(branchName = 'master', path = '')

61 |

Deletes a file or a folder and all of its content from a given branch

62 |

repository.fork()

63 |

Creates a fork of the repository

64 |

License

65 |

GitHub Extended is dual licensed under 66 | MIT and GPL-3.0.

67 |

Author

68 |

Aurelio De Rosa (@AurelioDeRosa)

69 |
70 |
71 | 72 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /doc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "github-extended", 3 | "version": "0.1.0", 4 | "description": "A collection of methods to extend the functionality of Github.js (known on npm as github-api)", 5 | "main": "src/github-extended.js", 6 | "scripts": { 7 | "test": "karma start" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/AurelioDeRosa/github-extended.git" 12 | }, 13 | "keywords": [ 14 | "github", 15 | "github-api", 16 | "api", 17 | "javascript", 18 | "library", 19 | "umd" 20 | ], 21 | "author": "Aurelio De Rosa (http://audero.it)", 22 | "contributors": [ 23 | { 24 | "name": "Aurelio De Rosa", 25 | "email": "a.derosa@audero.it", 26 | "url": "http://audero.it" 27 | } 28 | ], 29 | "license": "(MIT OR GPL-3.0)", 30 | "bugs": "https://github.com/AurelioDeRosa/github-extended/issues", 31 | "homepage": "https://github.com/AurelioDeRosa/github-extended", 32 | "dependencies": { 33 | "github-api": "^0.10.7" 34 | }, 35 | "devDependencies": { 36 | "babel-plugin-transform-es2015-modules-umd": "^6.3.13", 37 | "babel-polyfill": "^6.3.14", 38 | "babel-preset-es2015": "^6.3.13", 39 | "babelify": "^7.2.0", 40 | "browserify": "^12.0.1", 41 | "browserify-istanbul": "^0.2.1", 42 | "chai": "^3.4.1", 43 | "chai-as-promised": "^5.2.0", 44 | "del": "^2.2.0", 45 | "gulp": "^3.9.0", 46 | "gulp-babel": "^6.1.1", 47 | "gulp-esdoc": "^0.2.0", 48 | "gulp-jscs": "^3.0.2", 49 | "gulp-jshint": "^2.0.0", 50 | "gulp-rename": "^1.2.2", 51 | "gulp-sourcemaps": "^1.6.0", 52 | "gulp-uglify": "^1.5.1", 53 | "isparta": "^4.0.0", 54 | "istanbul": "^0.4.1", 55 | "jshint": "^2.8.0", 56 | "karma": "^0.13.15", 57 | "karma-browserify": "^4.4.2", 58 | "karma-chai": "^0.1.0", 59 | "karma-chai-as-promised": "^0.1.2", 60 | "karma-coverage": "git://github.com/douglasduteil/karma-coverage#next", 61 | "karma-mocha": "^0.2.1", 62 | "karma-mocha-reporter": "^1.1.3", 63 | "karma-phantomjs-launcher": "^0.2.1", 64 | "mocha": "^2.3.4", 65 | "phantomjs": "^1.9.19", 66 | "vinyl-buffer": "^1.0.0", 67 | "vinyl-source-stream": "^1.1.0" 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /doc/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 | -------------------------------------------------------------------------------- /doc/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 | -------------------------------------------------------------------------------- /doc/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 | -------------------------------------------------------------------------------- /doc/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 | -------------------------------------------------------------------------------- /doc/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 | -------------------------------------------------------------------------------- /doc/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 | -------------------------------------------------------------------------------- /doc/script/search_index.js: -------------------------------------------------------------------------------- 1 | window.esdocSearchIndex = [ 2 | [ 3 | "github-extended~github", 4 | "class/src/github-extended.js~Github.html", 5 | "Github github-extended", 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 | "github src/github-extended.js~github,github", 340 | "test-file/test/spec/test.js.html#lineNumber7", 341 | "Github", 342 | "test" 343 | ], 344 | [ 345 | "", 346 | "test-file/test/spec/test.js.html#lineNumber431", 347 | "Github fork()", 348 | "test" 349 | ], 350 | [ 351 | "", 352 | "test-file/test/spec/test.js.html#lineNumber441", 353 | "Github fork() should be able to fork an existent repository", 354 | "test" 355 | ], 356 | [ 357 | "", 358 | "test-file/test/spec/test.js.html#lineNumber456", 359 | "Github fork() should throw an error if the repository to fork does not exist", 360 | "test" 361 | ], 362 | [ 363 | "", 364 | "test-file/test/spec/test.js.html#lineNumber239", 365 | "Github mergePullRequest()", 366 | "test" 367 | ], 368 | [ 369 | "", 370 | "test-file/test/spec/test.js.html#lineNumber307", 371 | "Github mergePullRequest() should merge a valid pull request with a custom merge commit message", 372 | "test" 373 | ], 374 | [ 375 | "", 376 | "test-file/test/spec/test.js.html#lineNumber297", 377 | "Github mergePullRequest() should merge a valid pull request with the default merge commit message", 378 | "test" 379 | ], 380 | [ 381 | "", 382 | "test-file/test/spec/test.js.html#lineNumber320", 383 | "Github mergePullRequest() should throw an error for an invalid pull request", 384 | "test" 385 | ], 386 | [ 387 | "", 388 | "test-file/test/spec/test.js.html#lineNumber328", 389 | "Github remove()", 390 | "test" 391 | ], 392 | [ 393 | "", 394 | "test-file/test/spec/test.js.html#lineNumber380", 395 | "Github remove() should delete a file", 396 | "test" 397 | ], 398 | [ 399 | "", 400 | "test-file/test/spec/test.js.html#lineNumber405", 401 | "Github remove() should delete a folder and all its content", 402 | "test" 403 | ], 404 | [ 405 | "", 406 | "test-file/test/spec/test.js.html#lineNumber84", 407 | "Github search()", 408 | "test" 409 | ], 410 | [ 411 | "", 412 | "test-file/test/spec/test.js.html#lineNumber145", 413 | "Github search() should find matches with the caseSensitive option", 414 | "test" 415 | ], 416 | [ 417 | "", 418 | "test-file/test/spec/test.js.html#lineNumber118", 419 | "Github search() should find matches with the default configuration", 420 | "test" 421 | ], 422 | [ 423 | "", 424 | "test-file/test/spec/test.js.html#lineNumber173", 425 | "Github search() should find only files with the excludeFolders option", 426 | "test" 427 | ], 428 | [ 429 | "", 430 | "test-file/test/spec/test.js.html#lineNumber201", 431 | "Github search() should find only folders with the excludeFolders option", 432 | "test" 433 | ], 434 | [ 435 | "", 436 | "test-file/test/spec/test.js.html#lineNumber229", 437 | "Github search() should not find any match with a non-matching string with the default configuration", 438 | "test" 439 | ], 440 | [ 441 | "src/github-extended.js", 442 | "file/src/github-extended.js.html", 443 | "src/github-extended.js", 444 | "file" 445 | ], 446 | [ 447 | "src/github-extended.js~github#constructor", 448 | "class/src/github-extended.js~Github.html#instance-constructor-constructor", 449 | "src/github-extended.js~Github#constructor", 450 | "method" 451 | ], 452 | [ 453 | "src/github-extended.js~github#getrepo", 454 | "class/src/github-extended.js~Github.html#instance-member-getRepo", 455 | "src/github-extended.js~Github#getRepo", 456 | "member" 457 | ], 458 | [ 459 | "test/spec/test.js", 460 | "test-file/test/spec/test.js.html", 461 | "test/spec/test.js", 462 | "testFile" 463 | ] 464 | ] -------------------------------------------------------------------------------- /doc/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 | -------------------------------------------------------------------------------- /doc/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 | Test 22 | Repository 23 | 30 |
    31 | 32 | 39 | 40 |

    Source 3/3

    41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 |
    FileIdentifierDocumentSizeLinesUpdated
    src/github-extended.jsGithub100 %3/39222 byte2582015-12-04 02:04:15 (UTC)
    65 |
    66 | 67 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /doc/test-file/test/spec/test.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | test/spec/test.js | API Document 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
    17 | Home 18 | 19 | Reference 20 | Source 21 | Test 22 | Repository 23 | 30 |
    31 | 32 | 39 | 40 |

    test/spec/test.js

    41 |
    'use strict';
     42 | 
     43 | import Github from '../../src/github-extended';
     44 | import testUser from '../fixtures/user.json';
     45 | 
     46 | /** @test {Github} */
     47 | describe('Github', () => {
     48 |    let github, repository, testRepositoryName;
     49 | 
     50 |    function promisifiedWrite(data) {
     51 |       return new Promise((resolve, reject) => {
     52 |          data.repository.write(data.branch, data.filename, data.content, data.commitMessage, error => {
     53 |             if (error) {
     54 |                reject(error);
     55 |             }
     56 | 
     57 |             resolve();
     58 |          });
     59 |       });
     60 |    }
     61 | 
     62 |    /**
     63 |     * Delete one or more repositories
     64 |     *
     65 |     * @param {string|Array} repository
     66 |     *
     67 |     * @returns {Promise}
     68 |     */
     69 |    function deleteRepository(repository) {
     70 |       if (typeof repository === 'string') {
     71 |          repository = [repository];
     72 |       }
     73 | 
     74 |       let repositoriesPromises = repository.map(name => {
     75 |          return new Promise((resolve, reject) => {
     76 |             github
     77 |                .getRepo(testUser.username, name)
     78 |                .deleteRepo((error, result) => {
     79 |                   if (error) {
     80 |                      reject(error);
     81 |                   }
     82 | 
     83 |                   resolve(result);
     84 |                });
     85 |          })
     86 |       });
     87 | 
     88 |       return Promise.all(repositoriesPromises);
     89 |    }
     90 | 
     91 |    before(done => {
     92 |       github = new Github({
     93 |          username: testUser.username,
     94 |          password: testUser.password,
     95 |          auth: 'basic'
     96 |       });
     97 |       let user = github.getUser();
     98 | 
     99 |       testRepositoryName = 'github-extended-' + Math.floor(Math.random() * 100000);
    100 |       user.createRepo({
    101 |             name: testRepositoryName
    102 |          },
    103 |          error => {
    104 |             if (error) {
    105 |                throw error;
    106 |             }
    107 | 
    108 |             repository = github.getRepo(testUser.username, testRepositoryName);
    109 |             promisifiedWrite({
    110 |                repository: repository,
    111 |                branch: 'master',
    112 |                filename: 'README.md',
    113 |                content: '# GitHub Extended',
    114 |                commitMessage: 'Initial commit'
    115 |             })
    116 |                .then(() => done());
    117 |          }
    118 |       );
    119 |       repository = github.getRepo(testUser.username, testRepositoryName);
    120 |    });
    121 | 
    122 |    after(done => repository.deleteRepo(() => done()));
    123 | 
    124 |    describe('search()', () => {
    125 |       let branchName = 'search';
    126 |       let files = [
    127 |          'package.json',
    128 |          'Hello world.md',
    129 |          'README.md',
    130 |          'app/index.html',
    131 |          'app/scripts/main.js'
    132 |       ];
    133 | 
    134 |       before(done => {
    135 |          repository.branch('master', branchName, error => {
    136 |             if (error) {
    137 |                throw error;
    138 |             }
    139 | 
    140 |             let promise = Promise.resolve();
    141 | 
    142 |             files.forEach(file => {
    143 |                promise = promise.then(() => {
    144 |                   return promisifiedWrite({
    145 |                      repository: repository,
    146 |                      branch: branchName,
    147 |                      filename: file,
    148 |                      content: 'THIS IS A TEST',
    149 |                      commitMessage: 'Commit message'
    150 |                   });
    151 |                });
    152 |             });
    153 | 
    154 |             promise.then(() => done());
    155 |          });
    156 |       });
    157 | 
    158 |       it('should find matches with the default configuration', () => {
    159 |          let search = repository.search('PAC', {
    160 |             branch: branchName
    161 |          });
    162 |          let results = search.then(result => {
    163 |             return result.map(item => {
    164 |                return {
    165 |                   type: item.type,
    166 |                   path: item.path
    167 |                };
    168 |             });
    169 |          });
    170 | 
    171 |          return Promise.all([
    172 |             assert.eventually.isArray(search, 'An array is returned'),
    173 |             assert.eventually.lengthOf(search, 1, 'One file found'),
    174 |             assert.eventually.sameDeepMembers(
    175 |                results,
    176 |                [{
    177 |                   type: 'blob',
    178 |                   path: 'package.json'
    179 |                }],
    180 |                'Correct information returned'
    181 |             )
    182 |          ]);
    183 |       });
    184 | 
    185 |       it('should find matches with the caseSensitive option', () => {
    186 |          let search = repository.search('acka', {
    187 |             branch: branchName,
    188 |             caseSensitive: true
    189 |          });
    190 |          let results = search.then(result => {
    191 |             return result.map(item => {
    192 |                return {
    193 |                   type: item.type,
    194 |                   path: item.path
    195 |                };
    196 |             });
    197 |          });
    198 | 
    199 |          return Promise.all([
    200 |             assert.eventually.isArray(search, 'An array is returned'),
    201 |             assert.eventually.lengthOf(search, 1, 'One file found'),
    202 |             assert.eventually.sameDeepMembers(
    203 |                results,
    204 |                [{
    205 |                   type: 'blob',
    206 |                   path: 'package.json'
    207 |                }],
    208 |                'Correct information returned'
    209 |             )
    210 |          ]);
    211 |       });
    212 | 
    213 |       it('should find only files with the excludeFolders option', () => {
    214 |          let search = repository.search('PAC', {
    215 |             branch: branchName,
    216 |             excludeFolders: true
    217 |          });
    218 |          let results = search.then(result => {
    219 |             return result.map(item => {
    220 |                return {
    221 |                   type: item.type,
    222 |                   path: item.path
    223 |                };
    224 |             });
    225 |          });
    226 | 
    227 |          return Promise.all([
    228 |             assert.eventually.isArray(search, 'An array is returned'),
    229 |             assert.eventually.lengthOf(search, 1, 'One file found'),
    230 |             assert.eventually.sameDeepMembers(
    231 |                results,
    232 |                [{
    233 |                   type: 'blob',
    234 |                   path: 'package.json'
    235 |                }],
    236 |                'Correct information returned'
    237 |             )
    238 |          ]);
    239 |       });
    240 | 
    241 |       it('should find only folders with the excludeFolders option', () => {
    242 |          let search = repository.search('app', {
    243 |             branch: branchName,
    244 |             excludeFiles: true
    245 |          });
    246 |          let results = search.then(result => {
    247 |             return result.map(item => {
    248 |                return {
    249 |                   type: item.type,
    250 |                   path: item.path
    251 |                };
    252 |             });
    253 |          });
    254 | 
    255 |          return Promise.all([
    256 |             assert.eventually.isArray(search, 'An array is returned'),
    257 |             assert.eventually.lengthOf(search, 1, 'One folder found'),
    258 |             assert.eventually.sameDeepMembers(
    259 |                results,
    260 |                [{
    261 |                   type: 'tree',
    262 |                   path: 'app'
    263 |                }],
    264 |                'Correct information returned'
    265 |             )
    266 |          ]);
    267 |       });
    268 | 
    269 |       it('should not find any match with a non-matching string with the default configuration', () => {
    270 |          let search = repository.search('random.unknown');
    271 | 
    272 |          return Promise.all([
    273 |             assert.eventually.isArray(search, 'An array is returned'),
    274 |             assert.eventually.lengthOf(search, 0, 'Zero files found')
    275 |          ]);
    276 |       });
    277 |    });
    278 | 
    279 |    describe('mergePullRequest()', () => {
    280 |       let branchName = 'mergePullRequest';
    281 |       let branchIndex = 0;
    282 |       let filename = 'index.md';
    283 |       let pullRequest;
    284 | 
    285 |       before(done => {
    286 |          repository.branch('master', branchName, error => {
    287 |             if (error) {
    288 |                throw error;
    289 |             }
    290 | 
    291 |             promisifiedWrite({
    292 |                repository: repository,
    293 |                branch: branchName,
    294 |                filename: filename,
    295 |                content: 'This is a text',
    296 |                commitMessage: 'Commit'
    297 |             })
    298 |                .then(() => done());
    299 |          });
    300 |       });
    301 | 
    302 |       beforeEach(done => {
    303 |          branchIndex++;
    304 |          let updatesBranchName = branchName + branchIndex;
    305 |          repository.branch(branchName, updatesBranchName, error => {
    306 |             if (error) {
    307 |                throw error;
    308 |             }
    309 | 
    310 |             promisifiedWrite({
    311 |                repository: repository,
    312 |                branch: updatesBranchName,
    313 |                filename: filename,
    314 |                content: 'This is a different text',
    315 |                commitMessage: 'Commit message'
    316 |             })
    317 |                .then(() => {
    318 |                   repository.createPullRequest({
    319 |                         title: 'Pull request',
    320 |                         body: 'Pull request',
    321 |                         base: branchName,
    322 |                         head: `${testUser.username}:${updatesBranchName}`
    323 |                      },
    324 |                      (error, pullRequestInfo) => {
    325 |                         if (error) {
    326 |                            throw error;
    327 |                         }
    328 | 
    329 |                         pullRequest = pullRequestInfo;
    330 |                         done();
    331 |                      }
    332 |                   );
    333 |                });
    334 |          });
    335 |       });
    336 | 
    337 |       it('should merge a valid pull request with the default merge commit message', () => {
    338 |          let merge = repository.mergePullRequest(pullRequest);
    339 | 
    340 |          return Promise.all([
    341 |             assert.isFulfilled(merge, 'The request is successful'),
    342 |             assert.eventually.isObject(merge, 'The information about the merged pull request are returned'),
    343 |             assert.eventually.propertyVal(merge, 'merged', true, 'The pull request is merged')
    344 |          ]);
    345 |       });
    346 | 
    347 |       it('should merge a valid pull request with a custom merge commit message', () => {
    348 |          let options = {
    349 |             commitMessage: 'Custom message'
    350 |          };
    351 |          let merge = repository.mergePullRequest(pullRequest, options);
    352 | 
    353 |          return Promise.all([
    354 |             assert.isFulfilled(merge, 'The request is successful'),
    355 |             assert.eventually.isObject(merge, 'The information about the merged pull request are returned'),
    356 |             assert.eventually.propertyVal(merge, 'merged', true, 'The pull request is merged')
    357 |          ]);
    358 |       });
    359 | 
    360 |       it('should throw an error for an invalid pull request', () => {
    361 |          pullRequest.head.sha += 'random-text';
    362 |          let merge = repository.mergePullRequest(pullRequest);
    363 | 
    364 |          return assert.isRejected(merge, 'The pull request is not merged');
    365 |       });
    366 |    });
    367 | 
    368 |    describe('remove()', () => {
    369 |       let branchName = 'remove';
    370 |       let files = [
    371 |          'package.json',
    372 |          'Hello world.md',
    373 |          'README.md',
    374 |          'app/index.html',
    375 |          'app/scripts/main.js'
    376 |       ];
    377 | 
    378 |       function promisifiedGetTree(repository, branchName) {
    379 |          return new Promise((resolve, reject) => {
    380 |             repository.getRef(`heads/${branchName}`, (error, sha) => {
    381 |                if (error) {
    382 |                   reject(error);
    383 |                }
    384 | 
    385 |                repository.getTree(`${sha}?recursive=true`, (error, tree) => {
    386 |                   if (error) {
    387 |                      reject(error);
    388 |                   }
    389 | 
    390 |                   resolve(tree);
    391 |                });
    392 |             });
    393 |          })
    394 |       }
    395 | 
    396 |       before(done => {
    397 |          repository.branch('master', branchName, error => {
    398 |             if (error) {
    399 |                throw error;
    400 |             }
    401 | 
    402 |             let promise = Promise.resolve();
    403 | 
    404 |             files.forEach(file => {
    405 |                promise = promise.then(() => {
    406 |                   return promisifiedWrite({
    407 |                      repository: repository,
    408 |                      branch: branchName,
    409 |                      filename: file,
    410 |                      content: 'THIS IS A TEST',
    411 |                      commitMessage: 'Commit message'
    412 |                   });
    413 |                });
    414 |             });
    415 | 
    416 |             promise.then(() => done());
    417 |          });
    418 |       });
    419 | 
    420 |       it('should delete a file', () => {
    421 |          let itemsNumber;
    422 | 
    423 |          return promisifiedGetTree(repository, branchName)
    424 |             .then(tree => itemsNumber = tree.length)
    425 |             .then(() => repository.remove(branchName, 'package.json'))
    426 |             .then(() => promisifiedGetTree(repository, branchName))
    427 |             .then(tree => {
    428 |                let readContent = new Promise((resolve, reject) => {
    429 |                   repository.read(branchName, 'package.json', (error, data) => {
    430 |                      if (error) {
    431 |                         reject(error);
    432 |                      }
    433 | 
    434 |                      resolve(data);
    435 |                   });
    436 |                });
    437 | 
    438 |                return Promise.all([
    439 |                   assert.strictEqual(tree.length, itemsNumber - 1, 'The items count is decreased'),
    440 |                   assert.isRejected(readContent, 'The file is not found')
    441 |                ]);
    442 |             });
    443 |       });
    444 | 
    445 |       it('should delete a folder and all its content', () => {
    446 |          let itemsNumber;
    447 | 
    448 |          return promisifiedGetTree(repository, branchName)
    449 |             .then(tree => itemsNumber = tree.length)
    450 |             .then(() => repository.remove(branchName, 'app'))
    451 |             .then(() => promisifiedGetTree(repository, branchName))
    452 |             .then(tree => {
    453 |                let readContent = new Promise((resolve, reject) => {
    454 |                   repository.contents(branchName, 'app/', (error, contents) => {
    455 |                      if (error) {
    456 |                         reject(error);
    457 |                      }
    458 | 
    459 |                      resolve(contents);
    460 |                   });
    461 |                });
    462 | 
    463 |                return Promise.all([
    464 |                   assert.strictEqual(tree.length, itemsNumber - 4, 'The items count is decreased'),
    465 |                   assert.isRejected(readContent, 'The folder is not found')
    466 |                ]);
    467 |             });
    468 |       });
    469 |    });
    470 | 
    471 |    describe('fork()', () => {
    472 |       let forkUsername = 'AurelioDeRosa';
    473 |       let forkRepositoryName = 'HTML5-API-demos';
    474 | 
    475 |       afterEach(done => {
    476 |          let fork = github.getRepo(testUser.username, forkRepositoryName);
    477 | 
    478 |          fork.deleteRepo(() => done());
    479 |       });
    480 | 
    481 |       it('should be able to fork an existent repository', () => {
    482 |          let repositoryToFork = github.getRepo(forkUsername, forkRepositoryName);
    483 |          let fork = repositoryToFork.fork();
    484 | 
    485 |          return Promise.all([
    486 |             assert.eventually.propertyVal(fork, 'fork', true, 'The repository is a fork'),
    487 |             assert.eventually.propertyVal(
    488 |                fork,
    489 |                'full_name',
    490 |                `${testUser.username}/${forkRepositoryName}`,
    491 |                'The fork is created in the account of the user'
    492 |             )
    493 |          ]);
    494 |       });
    495 | 
    496 |       it('should throw an error if the repository to fork does not exist', () => {
    497 |          let repositoryToFork = github.getRepo(forkUsername, 'non-existent-repository');
    498 |          let fork = repositoryToFork.fork();
    499 | 
    500 |          return assert.isRejected(fork, 'The fork is not created');
    501 |       });
    502 |    });
    503 | });
    504 | 505 |
    506 | 507 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | -------------------------------------------------------------------------------- /doc/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Test | API Document 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
    17 | Home 18 | 19 | Reference 20 | Source 21 | Test 22 | Repository 23 | 30 |
    31 | 32 | 39 | 40 |

    Test

    41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 63 | 64 | 65 | 66 | 67 | 68 | 70 | 71 | 72 | 73 | 74 | 76 | 77 | 78 | 79 | 80 | 82 | 83 | 84 | 85 | 86 | 88 | 89 | 90 | 91 | 92 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 102 | 103 | 104 | 105 | 106 | 107 | 109 | 110 | 111 | 112 | 113 | 115 | 116 | 117 | 118 | 119 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 129 | 130 | 131 | 132 | 133 | 134 | 136 | 137 | 138 | 139 | 140 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 150 | 151 | 152 | 153 | 154 | 155 | 157 | 158 | 159 | 160 | 161 | 163 | 164 | 165 | 166 | 167 | 168 |
    DescriptionIdentifierCount

    should find matches with the default configuration

    69 |
    -

    should find matches with the caseSensitive option

    75 |
    -

    should find only files with the excludeFolders option

    81 |
    -

    should find only folders with the excludeFolders option

    87 |
    -

    should not find any match with a non-matching string with the default configuration

    93 |
    -

    should merge a valid pull request with the default merge commit message

    108 |
    -

    should merge a valid pull request with a custom merge commit message

    114 |
    -

    should throw an error for an invalid pull request

    120 |
    -

    should delete a file

    135 |
    -

    should delete a folder and all its content

    141 |
    -

    should be able to fork an existent repository

    156 |
    -

    should throw an error if the repository to fork does not exist

    162 |
    -
    169 |
    170 | 171 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | -------------------------------------------------------------------------------- /esdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "source": "src", 3 | "destination": "doc", 4 | "test": { 5 | "type": "mocha", 6 | "source": "test" 7 | } 8 | } -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var jscs = require('gulp-jscs'); 3 | var jshint = require('gulp-jshint'); 4 | var babel = require('gulp-babel'); 5 | var browserify = require('browserify'); 6 | var babelify = require('babelify'); 7 | var source = require('vinyl-source-stream'); 8 | var buffer = require('vinyl-buffer'); 9 | var sourcemaps = require('gulp-sourcemaps'); 10 | var uglify = require('gulp-uglify'); 11 | var rename = require('gulp-rename'); 12 | var del = require('del'); 13 | var karma = require('karma'); 14 | var esdoc = require('gulp-esdoc'); 15 | 16 | gulp.task('lint', function() { 17 | return gulp.src('src/*.js') 18 | .pipe(jscs({ 19 | fix: true 20 | })) 21 | .pipe(jscs.reporter()) 22 | .pipe(jscs.reporter('fail')) 23 | .pipe(jshint()) 24 | .pipe(jshint.reporter('default')) 25 | .pipe(jshint.reporter('fail')) 26 | .pipe(gulp.dest('src')); 27 | }); 28 | 29 | gulp.task('test', function(done) { 30 | new karma.Server({ 31 | configFile: __dirname + '/karma.conf.js' 32 | }, done).start(); 33 | }); 34 | 35 | gulp.task('documentation', function () { 36 | return gulp.src('src') 37 | .pipe(esdoc()); 38 | }); 39 | 40 | gulp.task('clean', function () { 41 | return del([ 42 | 'dist/*', 43 | 'doc/**/*', 44 | 'coverage/**/*' 45 | ]); 46 | }); 47 | 48 | gulp.task('build', function() { 49 | var browserifyInstance = browserify({ 50 | entries: 'src/github-extended.js', 51 | standalone: 'Github', 52 | transform: [babelify] 53 | }); 54 | 55 | browserifyInstance 56 | .bundle() 57 | .pipe(source('github-extended.js')) 58 | .pipe(buffer()) 59 | .pipe(uglify()) 60 | .pipe(rename({ 61 | extname: '.bundle.min.js' 62 | })) 63 | .pipe(gulp.dest('demo')); 64 | 65 | return gulp.src('src/github-extended.js') 66 | .pipe(sourcemaps.init()) 67 | .pipe(babel()) 68 | .pipe(rename({ 69 | extname: '.min.js' 70 | })) 71 | .pipe(uglify()) 72 | .pipe(sourcemaps.write('.')) 73 | .pipe(gulp.dest('dist')); 74 | }); 75 | 76 | gulp.task('default', ['clean', 'lint', 'test', 'documentation', 'build']); -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var browserifyIstanbul = require('browserify-istanbul'); 4 | var isparta = require('isparta'); 5 | 6 | module.exports = function(config) { 7 | config.set({ 8 | browserify: { 9 | debug: true, 10 | transform: [ 11 | 'babelify', 12 | browserifyIstanbul({ 13 | istrumenter: isparta 14 | }) 15 | ] 16 | }, 17 | browsers: ['PhantomJS'], 18 | browserNoActivityTimeout: 15000, 19 | captureTimeout: 3000, 20 | client: { 21 | mocha: { 22 | timeout: 15000, 23 | ui: 'bdd' 24 | } 25 | }, 26 | coverageReporter: { 27 | dir: 'coverage', 28 | reporters: [ 29 | { 30 | type: 'text-summary' 31 | }, 32 | { 33 | type : 'html' 34 | }, 35 | { 36 | type: 'lcovonly', 37 | subdir: 'lcov' 38 | } 39 | ] 40 | }, 41 | files: [ 42 | 'node_modules/babel-polyfill/dist/polyfill.js', 43 | 'test/spec/*.js' 44 | ], 45 | frameworks: [ 46 | 'browserify', 47 | 'mocha', 48 | 'chai-as-promised', 49 | 'chai' 50 | ], 51 | port: 9001, 52 | preprocessors: { 53 | 'test/spec/*.js': ['browserify'] 54 | }, 55 | reporters: [ 56 | 'mocha', 57 | 'coverage', 58 | 'coveralls' 59 | ], 60 | reportSlowerThan: 800, 61 | singleRun: true 62 | }); 63 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "github-extended", 3 | "version": "0.1.0", 4 | "description": "A collection of methods to extend the functionality of Github.js (known on npm as github-api)", 5 | "main": "src/github-extended.js", 6 | "scripts": { 7 | "test": "karma start" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/AurelioDeRosa/github-extended.git" 12 | }, 13 | "keywords": [ 14 | "github", 15 | "github-api", 16 | "api", 17 | "javascript", 18 | "library", 19 | "umd" 20 | ], 21 | "author": "Aurelio De Rosa (http://audero.it)", 22 | "contributors": [ 23 | { 24 | "name": "Aurelio De Rosa", 25 | "email": "a.derosa@audero.it", 26 | "url": "http://audero.it" 27 | } 28 | ], 29 | "license": "(MIT OR GPL-3.0)", 30 | "bugs": "https://github.com/AurelioDeRosa/github-extended/issues", 31 | "homepage": "https://github.com/AurelioDeRosa/github-extended", 32 | "dependencies": { 33 | "github-api": "^0.10.7" 34 | }, 35 | "devDependencies": { 36 | "babel-plugin-transform-es2015-modules-umd": "^6.3.13", 37 | "babel-polyfill": "^6.3.14", 38 | "babel-preset-es2015": "^6.3.13", 39 | "babelify": "^7.2.0", 40 | "browserify": "^12.0.1", 41 | "browserify-istanbul": "^0.2.1", 42 | "chai": "^3.4.1", 43 | "chai-as-promised": "^5.2.0", 44 | "del": "^2.2.0", 45 | "gulp": "^3.9.0", 46 | "gulp-babel": "^6.1.1", 47 | "gulp-esdoc": "^0.2.0", 48 | "gulp-jscs": "^3.0.2", 49 | "gulp-jshint": "^2.0.0", 50 | "gulp-rename": "^1.2.2", 51 | "gulp-sourcemaps": "^1.6.0", 52 | "gulp-uglify": "^1.5.1", 53 | "isparta": "^4.0.0", 54 | "istanbul": "^0.4.1", 55 | "jshint": "^2.8.0", 56 | "karma": "^0.13.15", 57 | "karma-browserify": "^4.4.2", 58 | "karma-chai": "^0.1.0", 59 | "karma-chai-as-promised": "^0.1.2", 60 | "karma-coverage": "git://github.com/douglasduteil/karma-coverage#next", 61 | "karma-coveralls": "^1.1.2", 62 | "karma-mocha": "^0.2.1", 63 | "karma-mocha-reporter": "^1.1.3", 64 | "karma-phantomjs-launcher": "^0.2.1", 65 | "mocha": "^2.3.4", 66 | "phantomjs": "^1.9.19", 67 | "vinyl-buffer": "^1.0.0", 68 | "vinyl-source-stream": "^1.1.0" 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/github-extended.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import GithubApi from 'github-api'; 4 | 5 | /** 6 | * The class that extends Github.js 7 | * 8 | * @extends GithubApi 9 | */ 10 | export 11 | default class Github extends GithubApi { 12 | /** 13 | * @constructor 14 | * @param {Object} options The object containing the information to work with the GitHub API 15 | * @param {string} options.username The username used on GitHub 16 | * @param {string} options.password The password of the GitHub account 17 | * @param {string} options.auth The type of authentication to use. It can be either `basic` or `oauth` 18 | * @param {string} options.token The token to access the GitHub API 19 | */ 20 | constructor(options) { 21 | super(options); 22 | 23 | let superGetRepo = this.getRepo; 24 | let request = this.request || this._request; // jscs:ignore disallowDanglingUnderscores 25 | 26 | /** 27 | * Returns an object representing a specific repository 28 | * 29 | * @param {string} user The username that possesses the repository 30 | * @param {string} repo The name of the repository to work on 31 | * 32 | * @returns {Object} 33 | */ 34 | this.getRepo = (user, repo) => { 35 | let repository = superGetRepo(user, repo); 36 | let superRemove = repository.remove; 37 | let superFork = repository.fork; 38 | 39 | function getRepositoryInfo(repository) { 40 | return new Promise((resolve, reject) => { 41 | repository.show((error, repo) => { 42 | if (error) { 43 | reject(error); 44 | } 45 | 46 | resolve(repo); 47 | }); 48 | }); 49 | } 50 | 51 | /** 52 | * Searches files and folders 53 | * 54 | * @param {string} string The string to search 55 | * @param {Object} [options={}] Possible options 56 | * @param {string} [options.branch] The name of the branch in which the search must be performed 57 | * @param {boolean} [options.caseSensitive=false] If the search must be case sensitive 58 | * @param {boolean} [options.excludeFiles=false] If the result must exclude files 59 | * @param {boolean} [options.excludeFolders=false] If the result must exclude folders 60 | * 61 | * @returns {Promise} 62 | */ 63 | repository.search = (string, options = {}) => { 64 | const FILE = 'blob'; 65 | const FOLDER = 'tree'; 66 | 67 | options = Object.assign({ 68 | branch: 'master', 69 | caseSensitive: false, 70 | excludeFiles: false, 71 | excludeFolders: false 72 | }, options); 73 | 74 | return new Promise((resolve, reject) => { 75 | repository.getSha(options.branch, '', (error, sha) => { 76 | if (error) { 77 | reject(error); 78 | } 79 | 80 | resolve(sha); 81 | }); 82 | }) 83 | .then(sha => { 84 | return new Promise((resolve, reject) => { 85 | repository.getTree(`${sha}?recursive=true`, (error, list) => { 86 | if (error) { 87 | // No matches 88 | if (error.error === 404) { 89 | resolve([]); 90 | } else { 91 | reject(error); 92 | } 93 | } 94 | 95 | resolve(list); 96 | }); 97 | }); 98 | }) 99 | .then(list => { 100 | let regex = new RegExp(string, options.caseSensitive ? '' : 'i'); 101 | 102 | return list.filter(content => { 103 | let fileCondition = options.excludeFiles ? content.type !== FILE : true; 104 | let folderCondition = options.excludeFolders ? content.type !== FOLDER : true; 105 | let extractName = (path) => path.substring(path.lastIndexOf('/') + 1); 106 | 107 | return fileCondition && folderCondition && regex.test(extractName(content.path)); 108 | }); 109 | }); 110 | }; 111 | 112 | /** 113 | * Merges a pull request 114 | * 115 | * @param {Object} pullRequest The pull request to merge 116 | * @param {Object} [options={}] Possible options 117 | * @param {string} [options.commitMessage] The commit message for the merge 118 | * 119 | * @returns {Promise} 120 | */ 121 | repository.mergePullRequest = (pullRequest, options = {}) => { 122 | options = Object.assign( 123 | { 124 | commitMessage: `Merged pull request gh-${pullRequest.number}` 125 | }, 126 | options 127 | ); 128 | 129 | return getRepositoryInfo(repository) 130 | .then(repositoryInfo => { 131 | return new Promise((resolve, reject) => { 132 | request( 133 | 'PUT', 134 | `/repos/${repositoryInfo.full_name}/pulls/${pullRequest.number}/merge`, // jscs:ignore 135 | { 136 | commit_message: options.commitMessage, // jscs:ignore 137 | sha: pullRequest.head.sha 138 | }, 139 | (error, mergeInfo) => { 140 | if (error) { 141 | reject(error); 142 | } 143 | 144 | resolve(mergeInfo); 145 | } 146 | ); 147 | }); 148 | }); 149 | }; 150 | 151 | /** 152 | * Deletes a file or a folder and all of its content from a given branch 153 | * 154 | * @param {string} [branchName='master'] The name of the branch in which the deletion must be performed 155 | * @param {string} [path=''] The path of the file or the folder to delete 156 | * 157 | * @returns {Promise} 158 | */ 159 | repository.remove = (branchName = 'master', path = '') => { 160 | function removeFile(branchName, path) { 161 | return new Promise((resolve, reject) => { 162 | superRemove(branchName, path, error => { 163 | if (error) { 164 | reject(error); 165 | } 166 | 167 | resolve(); 168 | }); 169 | }); 170 | } 171 | 172 | function removeFolder() { 173 | return new Promise((resolve, reject) => { 174 | repository.getRef(`heads/${branchName}`, (error, sha) => { 175 | if (error) { 176 | reject(error); 177 | } 178 | 179 | resolve(sha); 180 | }); 181 | }) 182 | .then(sha => { 183 | return new Promise((resolve, reject) => { 184 | repository.getTree(`${sha}?recursive=true`, (error, tree) => { 185 | if (error) { 186 | reject(error); 187 | } 188 | 189 | resolve(tree); 190 | }); 191 | }); 192 | }) 193 | .then(tree => { 194 | let filesPromises = Promise.resolve(); 195 | 196 | // Filters all items that aren't in the path of interest and aren't files 197 | // and delete them. 198 | tree 199 | .filter(item => item.path.indexOf(path) === 0 && item.type === 'blob') 200 | .map(item => item.path) 201 | .forEach(path => { 202 | filesPromises = filesPromises.then(() => removeFile(branchName, path)); 203 | }); 204 | 205 | return filesPromises; 206 | }); 207 | } 208 | 209 | // Remove any trailing slash from the path. 210 | // GitHub does not accept it even when dealing with folders. 211 | path = path.replace(/\/$/, ''); 212 | 213 | let removeFilePromise = removeFile(branchName, path); 214 | 215 | return removeFilePromise 216 | .then( 217 | () => removeFilePromise, 218 | error => { 219 | // If the operation fails because the path specified is that of a folder 220 | // keep going to retrieve the files recursively 221 | if (error.error !== 422) { 222 | throw error; 223 | } 224 | 225 | return removeFolder(); 226 | }); 227 | }; 228 | 229 | /** 230 | * Creates a fork of the repository 231 | * 232 | * @returns {Promise} 233 | */ 234 | repository.fork = () => { 235 | return new Promise((resolve, reject) => { 236 | superFork((err, forkInfo) => { 237 | function pollFork(fork) { 238 | fork.contents('master', '', (err, contents) => { 239 | if (contents) { 240 | resolve(forkInfo); 241 | } else { 242 | setTimeout(pollFork.bind(null, fork), 250); 243 | } 244 | }); 245 | } 246 | 247 | if (err) { 248 | reject(err); 249 | } else { 250 | pollFork(superGetRepo(options.username, repo)); 251 | } 252 | }); 253 | }); 254 | }; 255 | 256 | return repository; 257 | }; 258 | } 259 | } -------------------------------------------------------------------------------- /test/fixtures/user.json: -------------------------------------------------------------------------------- 1 | { 2 | "username": "mikedeboertest", 3 | "password": "test1324" 4 | } -------------------------------------------------------------------------------- /test/spec/test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import Github from '../../src/github-extended'; 4 | import testUser from '../fixtures/user.json'; 5 | 6 | /** @test {Github} */ 7 | describe('Github', () => { 8 | let github, repository, testRepositoryName; 9 | 10 | /** 11 | * Creates or update a file 12 | * 13 | * @param {Object} data The data to create or update the file 14 | * @param {string} data.repository The repository to work with 15 | * @param {string} data.branch The branch in which the file has to be created or updated 16 | * @param {string} data.filename The full path of the file 17 | * @param {string} data.content The content of the file 18 | * @param {string} data.commitMessage The commit message to use 19 | * 20 | * @returns {Promise} 21 | */ 22 | function promisifiedWrite(data) { 23 | return new Promise((resolve, reject) => { 24 | data.repository.write(data.branch, data.filename, data.content, data.commitMessage, error => { 25 | if (error) { 26 | reject(error); 27 | } 28 | 29 | // Fixes an issue when writing multiple files in succession. 30 | // This issue only happens in Travis CI. 31 | // (http://stackoverflow.com/questions/19576601/github-api-issue-with-file-upload#comment29076073_19576601) 32 | setTimeout(resolve, 500); 33 | }); 34 | }); 35 | } 36 | 37 | /** 38 | * Delete one or more repositories 39 | * 40 | * @param {string|Array} repository 41 | * 42 | * @returns {Promise} 43 | */ 44 | function deleteRepository(repository) { 45 | if (typeof repository === 'string') { 46 | repository = [repository]; 47 | } 48 | 49 | let repositoriesPromises = repository.map(name => { 50 | return new Promise((resolve, reject) => { 51 | github 52 | .getRepo(testUser.username, name) 53 | .deleteRepo((error, result) => { 54 | if (error) { 55 | reject(error); 56 | } 57 | 58 | resolve(result); 59 | }); 60 | }) 61 | }); 62 | 63 | return Promise.all(repositoriesPromises); 64 | } 65 | 66 | before(done => { 67 | github = new Github({ 68 | username: testUser.username, 69 | password: testUser.password, 70 | auth: 'basic' 71 | }); 72 | let user = github.getUser(); 73 | 74 | testRepositoryName = 'github-extended-' + Math.floor(Math.random() * 100000); 75 | user.createRepo({ 76 | name: testRepositoryName 77 | }, 78 | error => { 79 | if (error) { 80 | throw error; 81 | } 82 | 83 | repository = github.getRepo(testUser.username, testRepositoryName); 84 | promisifiedWrite({ 85 | repository: repository, 86 | branch: 'master', 87 | filename: 'README.md', 88 | content: '# GitHub Extended', 89 | commitMessage: 'Initial commit' 90 | }) 91 | .then(() => done()); 92 | } 93 | ); 94 | repository = github.getRepo(testUser.username, testRepositoryName); 95 | }); 96 | 97 | after(done => repository.deleteRepo(() => done())); 98 | 99 | describe('search()', () => { 100 | let branchName = 'search'; 101 | let files = [ 102 | 'package.json', 103 | 'Hello world.md', 104 | 'README.md', 105 | 'app/index.html', 106 | 'app/scripts/main.js' 107 | ]; 108 | 109 | before(done => { 110 | repository.branch('master', branchName, error => { 111 | if (error) { 112 | throw error; 113 | } 114 | 115 | let promise = Promise.resolve(); 116 | 117 | files.forEach(file => { 118 | promise = promise.then(() => { 119 | return promisifiedWrite({ 120 | repository: repository, 121 | branch: branchName, 122 | filename: file, 123 | content: 'THIS IS A TEST', 124 | commitMessage: 'Commit message' 125 | }); 126 | }); 127 | }); 128 | 129 | promise.then(() => done()); 130 | }); 131 | }); 132 | 133 | it('should find matches with the default configuration', () => { 134 | let search = repository.search('PAC', { 135 | branch: branchName 136 | }); 137 | let results = search.then(result => { 138 | return result.map(item => { 139 | return { 140 | type: item.type, 141 | path: item.path 142 | }; 143 | }); 144 | }); 145 | 146 | return Promise.all([ 147 | assert.eventually.isArray(search, 'An array is returned'), 148 | assert.eventually.lengthOf(search, 1, 'One file found'), 149 | assert.eventually.sameDeepMembers( 150 | results, 151 | [{ 152 | type: 'blob', 153 | path: 'package.json' 154 | }], 155 | 'Correct information returned' 156 | ) 157 | ]); 158 | }); 159 | 160 | it('should find matches with the caseSensitive option', () => { 161 | let search = repository.search('acka', { 162 | branch: branchName, 163 | caseSensitive: true 164 | }); 165 | let results = search.then(result => { 166 | return result.map(item => { 167 | return { 168 | type: item.type, 169 | path: item.path 170 | }; 171 | }); 172 | }); 173 | 174 | return Promise.all([ 175 | assert.eventually.isArray(search, 'An array is returned'), 176 | assert.eventually.lengthOf(search, 1, 'One file found'), 177 | assert.eventually.sameDeepMembers( 178 | results, 179 | [{ 180 | type: 'blob', 181 | path: 'package.json' 182 | }], 183 | 'Correct information returned' 184 | ) 185 | ]); 186 | }); 187 | 188 | it('should find only files with the excludeFolders option', () => { 189 | let search = repository.search('PAC', { 190 | branch: branchName, 191 | excludeFolders: true 192 | }); 193 | let results = search.then(result => { 194 | return result.map(item => { 195 | return { 196 | type: item.type, 197 | path: item.path 198 | }; 199 | }); 200 | }); 201 | 202 | return Promise.all([ 203 | assert.eventually.isArray(search, 'An array is returned'), 204 | assert.eventually.lengthOf(search, 1, 'One file found'), 205 | assert.eventually.sameDeepMembers( 206 | results, 207 | [{ 208 | type: 'blob', 209 | path: 'package.json' 210 | }], 211 | 'Correct information returned' 212 | ) 213 | ]); 214 | }); 215 | 216 | it('should find only folders with the excludeFolders option', () => { 217 | let search = repository.search('app', { 218 | branch: branchName, 219 | excludeFiles: true 220 | }); 221 | let results = search.then(result => { 222 | return result.map(item => { 223 | return { 224 | type: item.type, 225 | path: item.path 226 | }; 227 | }); 228 | }); 229 | 230 | return Promise.all([ 231 | assert.eventually.isArray(search, 'An array is returned'), 232 | assert.eventually.lengthOf(search, 1, 'One folder found'), 233 | assert.eventually.sameDeepMembers( 234 | results, 235 | [{ 236 | type: 'tree', 237 | path: 'app' 238 | }], 239 | 'Correct information returned' 240 | ) 241 | ]); 242 | }); 243 | 244 | it('should not find any match with a non-matching string with the default configuration', () => { 245 | let search = repository.search('random.unknown'); 246 | 247 | return Promise.all([ 248 | assert.eventually.isArray(search, 'An array is returned'), 249 | assert.eventually.lengthOf(search, 0, 'Zero files found') 250 | ]); 251 | }); 252 | }); 253 | 254 | describe('mergePullRequest()', () => { 255 | let branchName = 'mergePullRequest'; 256 | let branchIndex = 0; 257 | let filename = 'index.md'; 258 | let pullRequest; 259 | 260 | before(done => { 261 | repository.branch('master', branchName, error => { 262 | if (error) { 263 | throw error; 264 | } 265 | 266 | promisifiedWrite({ 267 | repository: repository, 268 | branch: branchName, 269 | filename: filename, 270 | content: 'This is a text', 271 | commitMessage: 'Commit' 272 | }) 273 | .then(() => done()); 274 | }); 275 | }); 276 | 277 | beforeEach(done => { 278 | branchIndex++; 279 | let updatesBranchName = branchName + branchIndex; 280 | repository.branch(branchName, updatesBranchName, error => { 281 | if (error) { 282 | throw error; 283 | } 284 | 285 | promisifiedWrite({ 286 | repository: repository, 287 | branch: updatesBranchName, 288 | filename: filename, 289 | content: 'This is a different text', 290 | commitMessage: 'Commit message' 291 | }) 292 | .then(() => { 293 | repository.createPullRequest({ 294 | title: 'Pull request', 295 | body: 'Pull request', 296 | base: branchName, 297 | head: `${testUser.username}:${updatesBranchName}` 298 | }, 299 | (error, pullRequestInfo) => { 300 | if (error) { 301 | throw error; 302 | } 303 | 304 | pullRequest = pullRequestInfo; 305 | done(); 306 | } 307 | ); 308 | }); 309 | }); 310 | }); 311 | 312 | it('should merge a valid pull request with the default merge commit message', () => { 313 | let merge = repository.mergePullRequest(pullRequest); 314 | 315 | return Promise.all([ 316 | assert.isFulfilled(merge, 'The request is successful'), 317 | assert.eventually.isObject(merge, 'The information about the merged pull request are returned'), 318 | assert.eventually.propertyVal(merge, 'merged', true, 'The pull request is merged') 319 | ]); 320 | }); 321 | 322 | it('should merge a valid pull request with a custom merge commit message', () => { 323 | let options = { 324 | commitMessage: 'Custom message' 325 | }; 326 | let merge = repository.mergePullRequest(pullRequest, options); 327 | 328 | return Promise.all([ 329 | assert.isFulfilled(merge, 'The request is successful'), 330 | assert.eventually.isObject(merge, 'The information about the merged pull request are returned'), 331 | assert.eventually.propertyVal(merge, 'merged', true, 'The pull request is merged') 332 | ]); 333 | }); 334 | 335 | it('should throw an error for an invalid pull request', () => { 336 | pullRequest.head.sha += 'random-text'; 337 | let merge = repository.mergePullRequest(pullRequest); 338 | 339 | return assert.isRejected(merge, 'The pull request is not merged'); 340 | }); 341 | }); 342 | 343 | describe('remove()', () => { 344 | let branchName = 'remove'; 345 | let files = [ 346 | 'package.json', 347 | 'Hello world.md', 348 | 'README.md', 349 | 'app/index.html', 350 | 'app/scripts/main.js' 351 | ]; 352 | 353 | function promisifiedGetTree(repository, branchName) { 354 | return new Promise((resolve, reject) => { 355 | repository.getRef(`heads/${branchName}`, (error, sha) => { 356 | if (error) { 357 | reject(error); 358 | } 359 | 360 | repository.getTree(`${sha}?recursive=true`, (error, tree) => { 361 | if (error) { 362 | reject(error); 363 | } 364 | 365 | resolve(tree); 366 | }); 367 | }); 368 | }) 369 | } 370 | 371 | before(done => { 372 | repository.branch('master', branchName, error => { 373 | if (error) { 374 | throw error; 375 | } 376 | 377 | let promise = Promise.resolve(); 378 | 379 | files.forEach(file => { 380 | promise = promise.then(() => { 381 | return promisifiedWrite({ 382 | repository: repository, 383 | branch: branchName, 384 | filename: file, 385 | content: 'THIS IS A TEST', 386 | commitMessage: 'Commit message' 387 | }); 388 | }); 389 | }); 390 | 391 | promise.then(() => done()); 392 | }); 393 | }); 394 | 395 | it('should delete a file', () => { 396 | let itemsNumber; 397 | 398 | return promisifiedGetTree(repository, branchName) 399 | .then(tree => itemsNumber = tree.length) 400 | .then(() => repository.remove(branchName, 'package.json')) 401 | .then(() => promisifiedGetTree(repository, branchName)) 402 | .then(tree => { 403 | let readContent = new Promise((resolve, reject) => { 404 | repository.read(branchName, 'package.json', (error, data) => { 405 | if (error) { 406 | reject(error); 407 | } 408 | 409 | resolve(data); 410 | }); 411 | }); 412 | 413 | return Promise.all([ 414 | assert.strictEqual(tree.length, itemsNumber - 1, 'The items count is decreased'), 415 | assert.isRejected(readContent, 'The file is not found') 416 | ]); 417 | }); 418 | }); 419 | 420 | it('should delete a folder and all its content', () => { 421 | let itemsNumber; 422 | 423 | return promisifiedGetTree(repository, branchName) 424 | .then(tree => itemsNumber = tree.length) 425 | .then(() => repository.remove(branchName, 'app')) 426 | .then(() => promisifiedGetTree(repository, branchName)) 427 | .then(tree => { 428 | let readContent = new Promise((resolve, reject) => { 429 | repository.contents(branchName, 'app/', (error, contents) => { 430 | if (error) { 431 | reject(error); 432 | } 433 | 434 | resolve(contents); 435 | }); 436 | }); 437 | 438 | return Promise.all([ 439 | assert.strictEqual(tree.length, itemsNumber - 4, 'The items count is decreased'), 440 | assert.isRejected(readContent, 'The folder is not found') 441 | ]); 442 | }); 443 | }); 444 | }); 445 | 446 | describe('fork()', () => { 447 | let forkUsername = 'jquery'; 448 | let forkRepositoryName = 'irc.jquery.org'; 449 | 450 | afterEach(done => { 451 | let fork = github.getRepo(testUser.username, forkRepositoryName); 452 | 453 | fork.deleteRepo(() => done()); 454 | }); 455 | 456 | it('should be able to fork an existent repository', () => { 457 | let repositoryToFork = github.getRepo(forkUsername, forkRepositoryName); 458 | let fork = repositoryToFork.fork(); 459 | 460 | return Promise.all([ 461 | assert.eventually.propertyVal(fork, 'fork', true, 'The repository is a fork'), 462 | assert.eventually.propertyVal( 463 | fork, 464 | 'full_name', 465 | `${testUser.username}/${forkRepositoryName}`, 466 | 'The fork is created in the account of the user' 467 | ) 468 | ]); 469 | }); 470 | 471 | it('should throw an error if the repository to fork does not exist', () => { 472 | let repositoryToFork = github.getRepo(forkUsername, 'non-existent-repository'); 473 | let fork = repositoryToFork.fork(); 474 | 475 | return assert.isRejected(fork, 'The fork is not created'); 476 | }); 477 | }); 478 | }); --------------------------------------------------------------------------------