├── .editorconfig ├── .eslintignore ├── .eslintrc.json ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── CONTRIBUTORS.md ├── HISTORY.md ├── LICENSE ├── README.md ├── build.js ├── fetch-browser.js ├── fetch-node.js ├── index.d.ts ├── package-lock.json ├── package.json ├── testem.json └── tests ├── .eslintrc.json ├── fetch-browser.spec.html ├── fetch-browser.spec.js └── fetch-node.spec.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | indent_style = space 8 | indent_size = 2 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | build 2 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "node": true, 4 | "browser": true, 5 | "amd": true 6 | }, 7 | "extends": "qubyte", 8 | "rules": { 9 | "indent": ["error", 2], 10 | "no-extra-parens": "off", 11 | "no-nested-ternary": "off", 12 | "no-sync": "off", 13 | "no-unused-vars": "off", 14 | "strict": "off" 15 | }, 16 | "globals": { 17 | "Promise": true, 18 | "XMLHttpRequest": true, 19 | "globalThis": true 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | branches: 8 | - main 9 | jobs: 10 | test-node: 11 | runs-on: ubuntu-latest 12 | strategy: 13 | matrix: 14 | node_version: [12, 14, 16] 15 | steps: 16 | - name: checkout 17 | uses: actions/checkout@main 18 | - name: use node ${{ matrix.node_version }} 19 | uses: actions/setup-node@v1 20 | with: 21 | node-version: ${{ matrix.node_version }} 22 | - run: npm ci 23 | - run: npm test 24 | test-browser: 25 | runs-on: ubuntu-latest 26 | strategy: 27 | matrix: 28 | bundler: [browserify, webpack, "webpack:node"] 29 | steps: 30 | - name: checkout 31 | uses: actions/checkout@main 32 | - name: use node 14 33 | uses: actions/setup-node@v1 34 | with: 35 | node-version: 14.x 36 | - run: npm ci 37 | - run: npm run test:${{ matrix.bundler }} 38 | lint: 39 | runs-on: ubuntu-latest 40 | steps: 41 | - name: checkout 42 | uses: actions/checkout@master 43 | - name: use node 14 44 | uses: actions/setup-node@v1 45 | with: 46 | node-version: 14.x 47 | - run: npm ci 48 | - run: npm run lint 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # Compiled binary addons (http://nodejs.org/api/addons.html) 20 | build/Release 21 | 22 | # Dependency directory 23 | # Commenting this out is preferred by some people, see 24 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 25 | node_modules 26 | 27 | # Users Environment Variables 28 | .lock-wscript 29 | 30 | # Release assets 31 | build 32 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | education, socio-economic status, nationality, personal appearance, race, 10 | religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at mark.s.everitt+contributor-covenant@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | For both issues and pull requests, please begin with the following: 4 | 5 | - Read the [code of conduct](CODE_OF_CONDUCT.md). 6 | - Read about [ponyfills](https://ponyfill.com/). 7 | 8 | Pull requests are welcome! A pull request must include tests to accompany code 9 | changes. 10 | -------------------------------------------------------------------------------- /CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | # Contributors 2 | 3 | Many thanks to the contributors to this project! 4 | 5 | - [Mark S. Everitt](https://github.com/qubyte) 6 | - [kPherox](https://github.com/kPherox) 7 | - [Moritz Peters](https://github.com/maritz) 8 | - [Paul Melnikow](https://github.com/paulmelnikow) 9 | - [Duc Tri Le](https://github.com/duclet) 10 | - [Daniel Bickett](https://github.com/freen) 11 | - [Hongbo LU](https://github.com/gitawego) 12 | - [Samuel Reed](https://github.com/STRML) 13 | - [Sindre Sorhus](https://github.com/sindresorhus) 14 | - [Robin Millette](https://github.com/millette) 15 | - [Friedel Ziegelmayer](https://github.com/dignifiedquire) 16 | - Artur Ciocanu 17 | -------------------------------------------------------------------------------- /HISTORY.md: -------------------------------------------------------------------------------- 1 | # History 2 | 3 | # 7.1.0 4 | 5 | - Updates whatwg-fetch to 3.5.0 to address an issue with IE11. 6 | 7 | ## 7.0.0 8 | 9 | - Drops support for node 8. Adds node 14 to tests. 10 | - Updates whatwg-fetch to ~3.4.1. 11 | - Exposes `DOMException` from whatwg-fetch. 12 | - Tests against webpack 5 and browserify 17. 13 | 14 | ## 6.1.0 15 | 16 | - Adds a types field to package.json for TypeScript integration. 17 | - Updates node-fetch to 2.6.0 18 | 19 | ## 6.0.2 20 | 21 | - Fixes WHATWG URL object handling when this module is used in Node. 22 | 23 | ## 6.0.1 24 | 25 | - Fixes to the TypeScript declaration file. 26 | 27 | ## 6.0.0 28 | 29 | - Adjusts the way the global object is sniffed for use with Metro. 30 | 31 | ## 5.0.0 32 | 33 | - Bumps node-fetch from ~1.7.1 to ~2.0.0. This is a potentially breaking 34 | change. Refer to the node-fetch [upgrade guide](https://github.com/bitinn/node-fetch/blob/master/UPGRADE-GUIDE.md) 35 | for details. 36 | 37 | ## 4.1.0 38 | 39 | - Bumps node fetch from ~1.6.0 to ~1.7.1. 40 | - Bumps whatwg-fetch from ~2.0.1 to ~2.0.3. 41 | 42 | ## 4.0.0 43 | 44 | This release: 45 | 46 | - Bumps whatwg-fetch from ~1.0.0 to ~2.0.1. 47 | - Better handling of self/this for browser fetch (more testing friendly). 48 | 49 | ## 3.0.2 50 | 51 | Dependencies now use tilde to allow patch versions to be tracked (this was 52 | waiting for whatwg-fetch to reach version 1). 53 | 54 | ## 3.0.1 55 | 56 | A link was added to the README to point to the ponyfill definition. 57 | 58 | ## 3.0.0 59 | 60 | Fixes an issue with detection of features like `URLSearchParams`. This is a 61 | major version bump since apparent behaviour could change in a breaking way in 62 | browsers which support detected features. 63 | 64 | ## 2.0.0 65 | 66 | Now exposes associated constructors along with `fetch` like: 67 | 68 | ```javascript 69 | const {fetch, Request, Response, Headers} = require('fetch-ponyfill')(options); 70 | ``` 71 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Mark Stanley Everitt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fetch Ponyfill 2 | 3 | > WHATWG `fetch` [ponyfill](https://ponyfill.com) 4 | 5 | This module wraps the [github/fetch](https://github.com/github/fetch) polyfill in a CommonJS module 6 | for browserification, and avoids appending anything to the window, instead returning a setup 7 | function when `fetch-ponyfill` is required. Inspired by 8 | [object-assign](https://github.com/sindresorhus/object-assign). 9 | 10 | When used in Node, delegates to `node-fetch` instead. 11 | 12 | ## Usage 13 | 14 | ### Browserify 15 | 16 | ```javascript 17 | const {fetch, Request, Response, Headers} = require('fetch-ponyfill')(options); 18 | ``` 19 | 20 | ### Webpack 21 | 22 | ```javascript 23 | import fetchPonyfill from 'fetch-ponyfill'; 24 | const {fetch, Request, Response, Headers} = fetchPonyfill(options); 25 | ``` 26 | 27 | ### Options 28 | 29 | Where `options` is an object with the following optional properties: 30 | 31 | | option | description | 32 | | ------ | ----------- | 33 | | `Promise` | An A+ Promise implementation. Defaults to `window.Promise` in the browser, and `global.Promise` in Node. | 34 | | `XMLHttpRequest` | The XMLHttpRequest constructor. This is useful to feed in when working with Firefox OS. Defaults to `window.XMLHttpRequest`. Has no effect in Node. | 35 | -------------------------------------------------------------------------------- /build.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function indent(line) { 4 | return line === '' ? '' : ' ' + line; 5 | } 6 | 7 | var fs = require('fs'); 8 | 9 | // Get the fetch source as a string. 10 | var whatwgFetchSource = fs.readFileSync(require.resolve('whatwg-fetch'), 'utf8'); 11 | 12 | // Get the wrapper source as a string. 13 | var wrapperSource = fs.readFileSync(require.resolve('./fetch-browser'), 'utf8'); 14 | 15 | // Indent and place the fetch source inside the wrapper. 16 | var indented = whatwgFetchSource 17 | .split('\n') 18 | .map(indent) 19 | .join('\n'); 20 | 21 | var builtSource = wrapperSource.replace(' // {{whatwgFetch}}', indented); 22 | 23 | console.log(builtSource); // eslint-disable-line no-console 24 | -------------------------------------------------------------------------------- /fetch-browser.js: -------------------------------------------------------------------------------- 1 | (function (global) { 2 | 'use strict'; 3 | 4 | function fetchPonyfill(options) { 5 | var Promise = options && options.Promise || global.Promise; 6 | var XMLHttpRequest = options && options.XMLHttpRequest || global.XMLHttpRequest; 7 | 8 | return (function () { 9 | var globalThis = Object.create(global, { 10 | fetch: { 11 | value: undefined, 12 | writable: true 13 | } 14 | }); 15 | 16 | // {{whatwgFetch}} 17 | 18 | return { 19 | fetch: globalThis.fetch, 20 | Headers: globalThis.Headers, 21 | Request: globalThis.Request, 22 | Response: globalThis.Response, 23 | DOMException: globalThis.DOMException 24 | }; 25 | }()); 26 | } 27 | 28 | if (typeof define === 'function' && define.amd) { 29 | define(function () { 30 | return fetchPonyfill; 31 | }); 32 | } else if (typeof exports === 'object') { 33 | module.exports = fetchPonyfill; 34 | } else { 35 | global.fetchPonyfill = fetchPonyfill; 36 | } 37 | }(typeof globalThis !== 'undefined' ? globalThis : typeof self !== 'undefined' ? self : typeof global !== 'undefined' ? global : this)); 38 | -------------------------------------------------------------------------------- /fetch-node.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var fetch = require('node-fetch'); 4 | 5 | function wrapFetchForNode(fetch) { 6 | // Support schemaless URIs on the server for parity with the browser. 7 | // https://github.com/matthew-andrews/isomorphic-fetch/pull/10 8 | return function (u, options) { 9 | if (typeof u === 'string' && u.slice(0, 2) === '//') { 10 | return fetch('https:' + u, options); 11 | } 12 | 13 | return fetch(u, options); 14 | }; 15 | } 16 | 17 | module.exports = function (context) { 18 | // Support webpack module import weirdness. 19 | var fetchFn = fetch.default ? fetch.default : fetch; 20 | 21 | // This modifies the global `node-fetch` object, which isn't great, since 22 | // different callers to `fetch-ponyfill` which pass a different Promise 23 | // implementation would each expect to have their implementation used. But, 24 | // given the way `node-fetch` is implemented, this is the only way to make 25 | // it work at all. 26 | if (context && context.Promise) { 27 | fetchFn.Promise = context.Promise; 28 | } 29 | 30 | return { 31 | fetch: wrapFetchForNode(fetchFn), 32 | Headers: fetch.Headers, 33 | Request: fetch.Request, 34 | Response: fetch.Response 35 | }; 36 | }; 37 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | export = fetchPonyfill; 2 | 3 | declare function fetchPonyfill(options?: fetchPonyfill.BootstrapOptions): fetchPonyfill.BootstrapRetVal; 4 | 5 | declare namespace fetchPonyfill { 6 | interface BootstrapOptions { 7 | Promise?: Function; 8 | XMLHttpRequest?: Function; 9 | } 10 | 11 | interface BootstrapRetVal { 12 | fetch: typeof fetch; 13 | Headers: typeof Headers; 14 | Request: typeof Request; 15 | Response: typeof Response; 16 | DOMException: typeof DOMException; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fetch-ponyfill", 3 | "version": "7.1.0", 4 | "description": "A ponyfill (doesn't overwrite the native fetch) for the Fetch specification https://fetch.spec.whatwg.org.", 5 | "main": "fetch-node.js", 6 | "browser": "build/fetch-browser.js", 7 | "types": "./index.d.ts", 8 | "config": { 9 | "web_port": "8088" 10 | }, 11 | "scripts": { 12 | "test": "mocha tests/fetch-node.spec.js", 13 | "lint": "eslint .", 14 | "pretest:browserify": "npm run build && browserify tests/fetch-browser.spec.js --outfile build/browser-test/main.js", 15 | "test:browserify": "testem ci", 16 | "pretest:webpack": "npm run build && webpack --mode development --entry ./tests/fetch-browser.spec.js -o build/browser-test", 17 | "test:webpack": "testem ci", 18 | "pretest:webpack:node": "webpack --mode development --target node --entry ./tests/fetch-node.spec.js -o build/node-test", 19 | "test:webpack:node": "mocha build/node-test/main.js", 20 | "build": "rimraf build && mkdirp build && node build.js > build/fetch-browser.js", 21 | "prepublishOnly": "npm run build" 22 | }, 23 | "author": "Mark Stanley Everitt", 24 | "repository": { 25 | "type": "git", 26 | "url": "git://github.com/qubyte/fetch-ponyfill.git" 27 | }, 28 | "license": "MIT", 29 | "keywords": [ 30 | "fetch", 31 | "ponyfill" 32 | ], 33 | "dependencies": { 34 | "node-fetch": "~2.6.1" 35 | }, 36 | "devDependencies": { 37 | "browserify": "^17.0.0", 38 | "eslint": "^8.7.0", 39 | "eslint-config-qubyte": "^4.1.0", 40 | "mkdirp": "^1.0.4", 41 | "mocha": "^9.2.0", 42 | "nock": "^13.1.0", 43 | "promise": "^8.1.0", 44 | "rimraf": "^3.0.2", 45 | "sinon": "^12.0.1", 46 | "testem": "^3.4.2", 47 | "webpack": "^5.38.1", 48 | "webpack-cli": "^4.7.0", 49 | "whatwg-fetch": "^3.6.2" 50 | }, 51 | "files": [ 52 | "fetch-node.js", 53 | "build/fetch-browser.js", 54 | "index.d.ts" 55 | ] 56 | } 57 | -------------------------------------------------------------------------------- /testem.json: -------------------------------------------------------------------------------- 1 | { 2 | "test_page": "tests/fetch-browser.spec.html", 3 | "launch_in_ci": [ 4 | "Chrome" 5 | ], 6 | "launch_in_dev": [ 7 | "Chrome" 8 | ], 9 | "browser_args": { 10 | "Chrome": [ 11 | "--headless", 12 | "--disable-gpu", 13 | "--remote-debugging-port=9222", 14 | "--privileged", 15 | "--no-sandbox" 16 | ] 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "mocha": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /tests/fetch-browser.spec.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |