├── .eslintrc ├── .github ├── FUNDING.yml └── workflows │ ├── node-aught.yml │ ├── node-pretest.yml │ ├── node-tens.yml │ ├── node-twenties.yml │ ├── rebase.yml │ └── require-allow-edits.yml ├── .gitignore ├── .npmrc ├── .nycrc ├── CHANGELOG.md ├── LICENSE ├── README.md ├── auto.js ├── implementation.js ├── index.js ├── package.json ├── polyfill.js ├── shim.js └── test ├── implementation.js ├── index.js ├── shimmed.js └── tests.js /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | 4 | "extends": "@ljharb", 5 | 6 | "rules": { 7 | "new-cap": [2, { 8 | "capIsNewExceptions": [ 9 | "ArraySpeciesCreate", 10 | "Call", 11 | "CreateDataPropertyOrThrow", 12 | "FlattenIntoArray", 13 | "Get", 14 | "HasProperty", 15 | "IsArray", 16 | "IsCallable", 17 | "Set", 18 | "ToLength", 19 | "ToObject", 20 | "ToString", 21 | ] 22 | }], 23 | "no-magic-numbers": 0, 24 | }, 25 | 26 | "overrides": [ 27 | { 28 | "files": "test/**", 29 | "rules": { 30 | "no-invalid-this": [1], 31 | }, 32 | }, 33 | ], 34 | } 35 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [ljharb] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: npm/array.prototype.flatmap 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.github/workflows/node-aught.yml: -------------------------------------------------------------------------------- 1 | name: 'Tests: node.js < 10' 2 | 3 | on: [pull_request, push] 4 | 5 | jobs: 6 | tests: 7 | uses: ljharb/actions/.github/workflows/node.yml@main 8 | with: 9 | range: '< 10' 10 | type: minors 11 | command: npm run tests-only 12 | 13 | node: 14 | name: 'node < 10' 15 | needs: [tests] 16 | runs-on: ubuntu-latest 17 | steps: 18 | - run: 'echo tests completed' 19 | -------------------------------------------------------------------------------- /.github/workflows/node-pretest.yml: -------------------------------------------------------------------------------- 1 | name: 'Tests: pretest/posttest' 2 | 3 | on: [pull_request, push] 4 | 5 | jobs: 6 | tests: 7 | uses: ljharb/actions/.github/workflows/pretest.yml@main 8 | -------------------------------------------------------------------------------- /.github/workflows/node-tens.yml: -------------------------------------------------------------------------------- 1 | name: 'Tests: node.js 10 - 20' 2 | 3 | on: [pull_request, push] 4 | 5 | permissions: 6 | contents: read 7 | 8 | jobs: 9 | tests: 10 | uses: ljharb/actions/.github/workflows/node.yml@main 11 | with: 12 | range: '>= 10 < 20' 13 | type: minors 14 | command: npm run tests-only 15 | 16 | node: 17 | name: 'node 10 - 20' 18 | needs: [tests] 19 | runs-on: ubuntu-latest 20 | steps: 21 | - run: true 22 | -------------------------------------------------------------------------------- /.github/workflows/node-twenties.yml: -------------------------------------------------------------------------------- 1 | name: 'Tests: node.js >= 20' 2 | 3 | on: [pull_request, push] 4 | 5 | permissions: 6 | contents: read 7 | 8 | jobs: 9 | tests: 10 | uses: ljharb/actions/.github/workflows/node.yml@main 11 | with: 12 | range: '>= 20' 13 | type: minors 14 | command: npm run tests-only 15 | 16 | node: 17 | name: 'node >= 20' 18 | needs: [tests] 19 | runs-on: ubuntu-latest 20 | steps: 21 | - run: true 22 | -------------------------------------------------------------------------------- /.github/workflows/rebase.yml: -------------------------------------------------------------------------------- 1 | name: Automatic Rebase 2 | 3 | on: [pull_request_target] 4 | 5 | jobs: 6 | _: 7 | uses: ljharb/actions/.github/workflows/rebase.yml@main 8 | secrets: 9 | token: ${{ secrets.GITHUB_TOKEN }} 10 | -------------------------------------------------------------------------------- /.github/workflows/require-allow-edits.yml: -------------------------------------------------------------------------------- 1 | name: Require “Allow Edits” 2 | 3 | on: [pull_request_target] 4 | 5 | jobs: 6 | _: 7 | name: "Require “Allow Edits”" 8 | 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: ljharb/require-allow-edits@main 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # Only apps should have lockfiles 61 | npm-shrinkwrap.json 62 | package-lock.json 63 | yarn.lock 64 | 65 | .npmignore 66 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | allow-same-version=true 3 | message=v%s 4 | -------------------------------------------------------------------------------- /.nycrc: -------------------------------------------------------------------------------- 1 | { 2 | "all": true, 3 | "check-coverage": false, 4 | "reporter": ["text-summary", "text", "html", "json"], 5 | "exclude": [ 6 | "coverage", 7 | "test" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## [v1.3.3](https://github.com/es-shims/Array.prototype.flatMap/compare/v1.3.2...v1.3.3) - 2024-12-15 9 | 10 | ### Commits 11 | 12 | - [actions] split out node 10-20, and 20+ [`8727281`](https://github.com/es-shims/Array.prototype.flatMap/commit/87272812ed6ade6935c7429ee1daf1cfa54115ef) 13 | - [Tests] add test coverage [`6e78327`](https://github.com/es-shims/Array.prototype.flatMap/commit/6e7832790c36b320880f4b6d38dc31388d1fae3a) 14 | - [Deps] update `call-bind`, `es-abstract` [`e027dd1`](https://github.com/es-shims/Array.prototype.flatMap/commit/e027dd10ee63b3c3a98cc7e6ce8ad42b1100bdc9) 15 | - [Dev Deps] update `@es-shims/api`, `@ljharb/eslint-config`, `auto-changelog`, `object-inspect`, `tape` [`7322d84`](https://github.com/es-shims/Array.prototype.flatMap/commit/7322d841e87ab17e4b929e92e73e8a20c3daf544) 16 | - [Dev Deps] update `aud`, `npmignore`, `object-inspect`, `tape` [`958bf5c`](https://github.com/es-shims/Array.prototype.flatMap/commit/958bf5c982cb0c4941dc2a6e873883e9f2c8d535) 17 | - [Deps] update `call-bind`, `define-properties`, `es-abstract`, `es-shim-unscopables` [`b3698fb`](https://github.com/es-shims/Array.prototype.flatMap/commit/b3698fb2320992f5ab85a486d1adef0105f739aa) 18 | - [Tests] replace `aud` with `npm audit` [`e0461ed`](https://github.com/es-shims/Array.prototype.flatMap/commit/e0461ed2288d37e2d878e3e64569313c04af6a64) 19 | - [Dev Deps] add missing peer dep [`e7160b5`](https://github.com/es-shims/Array.prototype.flatMap/commit/e7160b5ef9d624300cc189696e8019adaf6d67fc) 20 | 21 | ## [v1.3.2](https://github.com/es-shims/Array.prototype.flatMap/compare/v1.3.1...v1.3.2) - 2023-09-06 22 | 23 | ### Commits 24 | 25 | - [Deps] update `define-properties`, `es-abstract` [`1737863`](https://github.com/es-shims/Array.prototype.flatMap/commit/17378634d56fc4b75027764b54804d89c6f8d60f) 26 | - [Dev Deps] update `@es-shims/api`, `@ljharb/eslint-config`, `aud`, `object-inspect`, `tape` [`2337759`](https://github.com/es-shims/Array.prototype.flatMap/commit/23377597983440102805d36f701408505b433ccd) 27 | 28 | ## [v1.3.1](https://github.com/es-shims/Array.prototype.flatMap/compare/v1.3.0...v1.3.1) - 2022-11-02 29 | 30 | ### Commits 31 | 32 | - [meta] use `npmignore` to autogenerate an npmignore file [`3587a34`](https://github.com/es-shims/Array.prototype.flatMap/commit/3587a34ca111ec36ffc46b4131f5b32d4d8a357c) 33 | - [meta] add `auto-changelog` [`d66bdea`](https://github.com/es-shims/Array.prototype.flatMap/commit/d66bdeac56f2c1803a72695230c80d8270ab2ecf) 34 | - [Deps] update `define-properties`, `es-abstract` [`d64c486`](https://github.com/es-shims/Array.prototype.flatMap/commit/d64c48639ec4958ed9a2627a4d7315ac1404687a) 35 | - [actions] update rebase action to use reusable workflow [`8d657d0`](https://github.com/es-shims/Array.prototype.flatMap/commit/8d657d094a2aafa7948eee73eaa0e56047c5d60d) 36 | - [Dev Deps] update `aud`, `object-inspect`, `tape` [`aa22741`](https://github.com/es-shims/Array.prototype.flatMap/commit/aa22741a4bbe8db6d448cc4ca5417ddec90ac01d) 37 | - [Tests] use `for-each` instead of `foreach` [`748a78d`](https://github.com/es-shims/Array.prototype.flatMap/commit/748a78dbddb08462c75916fde07746d34cfd5c5c) 38 | 39 | 40 | 41 | 1.3.0 / 2022-04-11 42 | ================= 43 | * [New] `shim`/`auto`: add `flatMap` to `Symbol.unscopables` 44 | * [Deps] update `call-bind`, `es-abstract` 45 | * [actions] reuse common workflows 46 | * [actions] update codecov uploader 47 | * [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `@es-shims/api`, `aud`, `auto-changelog`, `object-inspect`, `safe-publish-latest`, `tape` 48 | 49 | 1.2.5 / 2021-10-01 50 | ================= 51 | * [readme] add github actions/codecov badges; update description; remove travis badge 52 | * [Deps] update `call-bind`, `es-abstract`; remove unused `function-bind` 53 | * [meta] use `prepublishOnly`, for npm 7+ 54 | * [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `@es-shims/api`, `aud`, `has-strict-mode`, `object-inspect`, `tape` 55 | * [actions] update workflows 56 | * [actions] use `node/install` instead of `node/run`; use `codecov` action 57 | * [Tests] increase coverage 58 | 59 | 1.2.4 / 2020-11-18 60 | ================= 61 | * [Deps] update `es-abstract`; use `call-bind` where applicable 62 | * [meta] do not publish github action workflows 63 | * [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `object-inspect`, `tape`; add `aud` 64 | * [Tests] migrate tests to Github Actions 65 | * [Tests] run `nyc` on all tests 66 | * [Tests] add `implementation` test; run `es-shim-api` in postlint; use `tape` runner 67 | * [actions] add "Allow Edits" workflow 68 | * [actions] switch Automatic Rebase workflow to `pull_request_target` event 69 | 70 | 1.2.3 / 2019-12-12 71 | ================= 72 | * [Refactor] use split-up `es-abstract` (65% bundle size decrease) 73 | * [Deps] update `es-abstract` 74 | * [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `safe-publish-latest`, `object-inspect` 75 | * [meta] add `funding` field 76 | * [Tests] use shared travis-ci configs 77 | * [actions] add automatic rebasing / merge commit blocking 78 | 79 | 1.2.2 / 2019-10-10 80 | ================= 81 | * [Refactor] rename callback argument to `mapperFunction`, to match spec 82 | * [Deps] update `es-abstract`, `define-properties` 83 | * [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `covert`, `evalmd`, `object-inspect`, `safe-publish-latest`, `tape` 84 | * [meta] create FUNDING.yml 85 | * [Tests] up to `node` `v12.11`, `v11.15`, `v10.16`, `v9.11`, `v8.16`, `v6.17`, `v4.9`; use `nvm install-latest-npm` 86 | * [Tests] use `npx aud` instead of `nsp` or `npm audit` with hoops 87 | 88 | 1.2.1 / 2018-02-23 89 | ================= 90 | * [Fix] Temporarily hack main entry, so it's compatible with other resolvers 91 | * [Dev Deps] update `eslint`, `nsp`, `tape` 92 | * [Tests] up to `node` `v9.6`, `v6.13` 93 | 94 | 1.2.0 / 2018-01-18 95 | ================= 96 | * [New] add "auto" entry point 97 | * [Fix] Move the receiver length check higher 98 | * [Fix] spec adjustments 99 | * [Refactor] adjust shouldFlatten logic 100 | * [Dev Deps] update `eslint`, `object-inspect` 101 | * [Tests] up to `node` `v9.4` 102 | 103 | 1.1.1 / 2017-11-29 104 | ================= 105 | * [Fix] avoid an extra hole in the array (#1) 106 | * [Deps] update `es-abstract` 107 | * [Dev Deps] update `eslint`, `nsp`, `object-inspect` 108 | * [Tests] up to `node` `v9.2`, `v8.9`, `v6.12`; pin included builds to LTS 109 | 110 | 1.1.0 / 2017-10-03 111 | ================= 112 | * [New] add explicit setting of “length” on target array 113 | * [Fix] `FlattenIntoArray`: add assertion that `thisArg` and `mapperFunction` are both passed together 114 | * [Tests] make coverage required 115 | 116 | 1.0.1 / 2017-10-02 117 | ================= 118 | * Add readme 119 | 120 | 1.0.0 / 2017-10-01 121 | ================= 122 | * Initial release 123 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 ECMAScript Shims 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # array.prototype.flatmap [![Version Badge][npm-version-svg]][package-url] 2 | 3 | [![github actions][actions-image]][actions-url] 4 | [![coverage][codecov-image]][codecov-url] 5 | [![dependency status][deps-svg]][deps-url] 6 | [![dev dependency status][dev-deps-svg]][dev-deps-url] 7 | [![License][license-image]][license-url] 8 | [![Downloads][downloads-image]][downloads-url] 9 | 10 | [![npm badge][npm-badge-png]][package-url] 11 | 12 | An ES2019 spec-compliant `Array.prototype.flatMap` shim/polyfill/replacement that works as far down as ES3. 13 | 14 | This package implements the [es-shim API](https://github.com/es-shims/api) interface. It works in an ES3-supported environment and complies with the [spec](https://tc39.es/ecma262/#sec-array.prototype.flatmap). 15 | 16 | Because `Array.prototype.flatMap` depends on a receiver (the `this` value), the main export takes the array to operate on as the first argument. 17 | 18 | ## Getting started 19 | 20 | ```sh 21 | npm install --save array.prototype.flatmap 22 | ``` 23 | 24 | ## Usage/Examples 25 | 26 | ```js 27 | var flatMap = require('array.prototype.flatmap'); 28 | var assert = require('assert'); 29 | 30 | var arr = [1, [2], [], 3]; 31 | 32 | var results = flatMap(arr, function (x, i) { 33 | assert.equal(x, arr[i]); 34 | return x; 35 | }); 36 | 37 | assert.deepEqual(results, [1, 2, 3]); 38 | ``` 39 | 40 | ```js 41 | var flatMap = require('array.prototype.flatmap'); 42 | var assert = require('assert'); 43 | /* when Array#flatMap is not present */ 44 | delete Array.prototype.flatMap; 45 | var shimmedFlatMap = flatMap.shim(); 46 | 47 | var mapper = function (x) { return [x, 1]; }; 48 | 49 | assert.equal(shimmedFlatMap, flatMap.getPolyfill()); 50 | assert.deepEqual(arr.flatMap(mapper), flatMap(arr, mapper)); 51 | ``` 52 | 53 | ```js 54 | var flatMap = require('array.prototype.flatmap'); 55 | var assert = require('assert'); 56 | /* when Array#flatMap is present */ 57 | var shimmedIncludes = flatMap.shim(); 58 | 59 | var mapper = function (x) { return [x, 1]; }; 60 | 61 | assert.equal(shimmedIncludes, Array.prototype.flatMap); 62 | assert.deepEqual(arr.flatMap(mapper), flatMap(arr, mapper)); 63 | ``` 64 | 65 | ## Tests 66 | Simply clone the repo, `npm install`, and run `npm test` 67 | 68 | [package-url]: https://npmjs.org/package/array.prototype.flatmap 69 | [npm-version-svg]: https://versionbadg.es/es-shims/Array.prototype.flatMap.svg 70 | [deps-svg]: https://david-dm.org/es-shims/Array.prototype.flatMap.svg 71 | [deps-url]: https://david-dm.org/es-shims/Array.prototype.flatMap 72 | [dev-deps-svg]: https://david-dm.org/es-shims/Array.prototype.flatMap/dev-status.svg 73 | [dev-deps-url]: https://david-dm.org/es-shims/Array.prototype.flatMap#info=devDependencies 74 | [npm-badge-png]: https://nodei.co/npm/array.prototype.flatmap.png?downloads=true&stars=true 75 | [license-image]: https://img.shields.io/npm/l/array.prototype.flatmap.svg 76 | [license-url]: LICENSE 77 | [downloads-image]: https://img.shields.io/npm/dm/array.prototype.flatmap.svg 78 | [downloads-url]: https://npm-stat.com/charts.html?package=array.prototype.flatmap 79 | [codecov-image]: https://codecov.io/gh/es-shims/Array.prototype.flatMap/branch/main/graphs/badge.svg 80 | [codecov-url]: https://app.codecov.io/gh/es-shims/Array.prototype.flatMap/ 81 | [actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/es-shims/Array.prototype.flatMap 82 | [actions-url]: https://github.com/es-shims/Array.prototype.flatMap/actions 83 | -------------------------------------------------------------------------------- /auto.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | require('./shim')(); 4 | -------------------------------------------------------------------------------- /implementation.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var ArraySpeciesCreate = require('es-abstract/2024/ArraySpeciesCreate'); 4 | var FlattenIntoArray = require('es-abstract/2024/FlattenIntoArray'); 5 | var Get = require('es-abstract/2024/Get'); 6 | var IsCallable = require('es-abstract/2024/IsCallable'); 7 | var ToLength = require('es-abstract/2024/ToLength'); 8 | var ToObject = require('es-abstract/2024/ToObject'); 9 | 10 | module.exports = function flatMap(mapperFunction) { 11 | var O = ToObject(this); 12 | var sourceLen = ToLength(Get(O, 'length')); 13 | 14 | if (!IsCallable(mapperFunction)) { 15 | throw new TypeError('mapperFunction must be a function'); 16 | } 17 | 18 | var T; 19 | if (arguments.length > 1) { 20 | T = arguments[1]; 21 | } 22 | 23 | var A = ArraySpeciesCreate(O, 0); 24 | FlattenIntoArray(A, O, sourceLen, 0, 1, mapperFunction, T); 25 | return A; 26 | }; 27 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var define = require('define-properties'); 4 | var callBind = require('call-bind'); 5 | 6 | var implementation = require('./implementation'); 7 | var getPolyfill = require('./polyfill'); 8 | var polyfill = getPolyfill(); 9 | var shim = require('./shim'); 10 | 11 | var boundFlatMap = callBind(polyfill); 12 | 13 | define(boundFlatMap, { 14 | getPolyfill: getPolyfill, 15 | implementation: implementation, 16 | shim: shim 17 | }); 18 | 19 | module.exports = boundFlatMap; 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "array.prototype.flatmap", 3 | "version": "1.3.3", 4 | "author": { 5 | "name": "Jordan Harband", 6 | "email": "ljharb@gmail.com", 7 | "url": "http://ljharb.codes" 8 | }, 9 | "funding": { 10 | "url": "https://github.com/sponsors/ljharb" 11 | }, 12 | "contributors": [ 13 | { 14 | "name": "Jordan Harband", 15 | "email": "ljharb@gmail.com", 16 | "url": "http://ljharb.codes" 17 | } 18 | ], 19 | "description": "An ES2019 spec-compliant `Array.prototype.flatMap` shim/polyfill/replacement that works as far down as ES3.", 20 | "license": "MIT", 21 | "main": "index", 22 | "scripts": { 23 | "prepack": "npmignore --auto --commentLines=autogenerated", 24 | "prepublishOnly": "safe-publish-latest", 25 | "prepublish": "not-in-publish || npm run prepublishOnly", 26 | "pretest": "npm run lint", 27 | "test": "npm run tests-only", 28 | "posttest": "npx npm@'>= 10.2' audit --production", 29 | "tests-only": "nyc tape 'test/**/*.js'", 30 | "prelint": "evalmd README.md", 31 | "lint": "eslint --ext=js,mjs .", 32 | "postlint": "es-shim-api --bound", 33 | "version": "auto-changelog && git add CHANGELOG.md", 34 | "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" 35 | }, 36 | "repository": { 37 | "type": "git", 38 | "url": "git://github.com/es-shims/Array.prototype.flatMap.git" 39 | }, 40 | "keywords": [ 41 | "Array.prototype.flatMap", 42 | "flatMap", 43 | "array", 44 | "ESnext", 45 | "shim", 46 | "polyfill", 47 | "flatten", 48 | "Array.prototype.flatten", 49 | "es-shim API" 50 | ], 51 | "dependencies": { 52 | "call-bind": "^1.0.8", 53 | "define-properties": "^1.2.1", 54 | "es-abstract": "^1.23.5", 55 | "es-shim-unscopables": "^1.0.2" 56 | }, 57 | "devDependencies": { 58 | "@es-shims/api": "^2.5.1", 59 | "@ljharb/eslint-config": "^21.1.1", 60 | "auto-changelog": "^2.5.0", 61 | "encoding": "^0.1.13", 62 | "eslint": "=8.8.0", 63 | "evalmd": "^0.0.19", 64 | "for-each": "^0.3.3", 65 | "has-strict-mode": "^1.0.1", 66 | "in-publish": "^2.0.1", 67 | "npmignore": "^0.3.1", 68 | "nyc": "^10.3.2", 69 | "object-inspect": "^1.13.3", 70 | "safe-publish-latest": "^2.0.0", 71 | "tape": "^5.9.0" 72 | }, 73 | "testling": { 74 | "files": [ 75 | "test/index.js", 76 | "test/shimmed.js" 77 | ], 78 | "browsers": [ 79 | "iexplore/6.0..latest", 80 | "firefox/3.0..6.0", 81 | "firefox/15.0..latest", 82 | "firefox/nightly", 83 | "chrome/4.0..10.0", 84 | "chrome/20.0..latest", 85 | "chrome/canary", 86 | "opera/10.0..latest", 87 | "opera/next", 88 | "safari/4.0..latest", 89 | "ipad/6.0..latest", 90 | "iphone/6.0..latest", 91 | "android-browser/4.2" 92 | ] 93 | }, 94 | "engines": { 95 | "node": ">= 0.4" 96 | }, 97 | "auto-changelog": { 98 | "output": "CHANGELOG.md", 99 | "template": "keepachangelog", 100 | "unreleased": false, 101 | "commitLimit": false, 102 | "backfillLimit": false, 103 | "hideCredit": true, 104 | "startingVersion": "1.3.1" 105 | }, 106 | "publishConfig": { 107 | "ignore": [ 108 | ".github/workflows" 109 | ] 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /polyfill.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var implementation = require('./implementation'); 4 | 5 | module.exports = function getPolyfill() { 6 | return Array.prototype.flatMap || implementation; 7 | }; 8 | -------------------------------------------------------------------------------- /shim.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var define = require('define-properties'); 4 | var shimUnscopables = require('es-shim-unscopables'); 5 | 6 | var getPolyfill = require('./polyfill'); 7 | 8 | module.exports = function shimFlatMap() { 9 | var polyfill = getPolyfill(); 10 | 11 | define( 12 | Array.prototype, 13 | { flatMap: polyfill }, 14 | { flatMap: function () { return Array.prototype.flatMap !== polyfill; } } 15 | ); 16 | 17 | shimUnscopables('flatMap'); 18 | 19 | return polyfill; 20 | }; 21 | -------------------------------------------------------------------------------- /test/implementation.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var flatMap = require('../implementation'); 4 | var callBind = require('call-bind'); 5 | var test = require('tape'); 6 | var hasStrictMode = require('has-strict-mode')(); 7 | var runTests = require('./tests'); 8 | 9 | test('as a function', function (t) { 10 | t.test('bad array/this value', { skip: !hasStrictMode }, function (st) { 11 | /* eslint no-useless-call: 0 */ 12 | st['throws'](function () { flatMap.call(undefined); }, TypeError, 'undefined is not an object'); 13 | st['throws'](function () { flatMap.call(null); }, TypeError, 'null is not an object'); 14 | st.end(); 15 | }); 16 | 17 | runTests(callBind(flatMap), t); 18 | 19 | t.end(); 20 | }); 21 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var flatMap = require('../'); 4 | var test = require('tape'); 5 | var runTests = require('./tests'); 6 | 7 | test('as a function', function (t) { 8 | t.test('bad array/this value', function (st) { 9 | /* eslint no-useless-call: 0 */ 10 | st['throws'](function () { flatMap.call(undefined, function () {}); }, TypeError, 'undefined is not an object'); 11 | st['throws'](function () { flatMap.call(null, function () {}); }, TypeError, 'null is not an object'); 12 | st.end(); 13 | }); 14 | 15 | runTests(flatMap, t); 16 | 17 | t.end(); 18 | }); 19 | -------------------------------------------------------------------------------- /test/shimmed.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | require('../auto'); 4 | 5 | var test = require('tape'); 6 | var defineProperties = require('define-properties'); 7 | var callBind = require('call-bind'); 8 | var isEnumerable = Object.prototype.propertyIsEnumerable; 9 | var functionsHaveNames = function f() {}.name === 'f'; 10 | 11 | var runTests = require('./tests'); 12 | 13 | test('shimmed', function (t) { 14 | t.equal(Array.prototype.flatMap.length, 1, 'Array#flatMap has a length of 1'); 15 | t.test('Function name', { skip: !functionsHaveNames }, function (st) { 16 | st.equal(Array.prototype.flatMap.name, 'flatMap', 'Array#flatMap has name "flatMap"'); 17 | st.end(); 18 | }); 19 | 20 | t.test('enumerability', { skip: !defineProperties.supportsDescriptors }, function (et) { 21 | et.equal(false, isEnumerable.call(Array.prototype, 'flatMap'), 'Array#flatMap is not enumerable'); 22 | et.end(); 23 | }); 24 | 25 | var supportsStrictMode = (function () { return typeof this === 'undefined'; }()); 26 | 27 | t.test('bad array/this value', { skip: !supportsStrictMode }, function (st) { 28 | st['throws'](function () { return Array.prototype.flatMap.call(undefined, 'a'); }, TypeError, 'undefined is not an object'); 29 | st['throws'](function () { return Array.prototype.flatMap.call(null, 'a'); }, TypeError, 'null is not an object'); 30 | st.end(); 31 | }); 32 | 33 | runTests(callBind(Array.prototype.flatMap), t); 34 | 35 | t.end(); 36 | }); 37 | -------------------------------------------------------------------------------- /test/tests.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var inspect = require('object-inspect'); 4 | var forEach = require('for-each'); 5 | 6 | module.exports = function (flatMap, t) { 7 | t.test('callback function', function (st) { 8 | forEach([[], {}, true, false, 42, 'foo', /a/g, null], function (nonFunction) { 9 | st['throws']( 10 | function () { flatMap([], nonFunction); }, 11 | TypeError, 12 | inspect(nonFunction) + ' is not a function' 13 | ); 14 | }); 15 | 16 | st.end(); 17 | }); 18 | 19 | t.test('flatMaps', function (st) { 20 | var mapped = flatMap([1, [2], [3, 4]], function (x, i) { 21 | return [x, i]; 22 | }); 23 | 24 | var expected = [1, 0, [2], 1, [3, 4], 2]; 25 | st.deepEqual(mapped, expected, 'array is flattened and mapped to tuples of item/index'); 26 | st.equal(mapped.length, expected.length, 'array has expected length'); 27 | 28 | var context = {}; 29 | var actual; 30 | flatMap([1], function () { actual = this; }, context); 31 | st.equal(actual, context, 'thisArg works as expected'); 32 | 33 | st.end(); 34 | }); 35 | 36 | t.test('sparse arrays', function (st) { 37 | var identity = function (x) { return x; }; 38 | // eslint-disable-next-line no-sparse-arrays 39 | st.deepEqual(flatMap([, [1]], identity), flatMap([[], [1]], identity), 'an array hole is treated the same as an empty array'); 40 | 41 | st.end(); 42 | }); 43 | 44 | t.test('test262: staging test from v8', function (st) { 45 | var arr1 = [0, 1, 2, 3]; 46 | var f = function (e) { 47 | arr1[4] = 42; 48 | return e; 49 | }; 50 | st.deepEqual(flatMap(arr1, f), [0, 1, 2, 3]); 51 | 52 | var arr2 = [0, 1, 2, 3]; 53 | var g = function (e) { 54 | arr2.length = 3; 55 | return e; 56 | }; 57 | st.deepEqual(flatMap(arr2, g), [0, 1, 2]); 58 | 59 | st.end(); 60 | }); 61 | }; 62 | --------------------------------------------------------------------------------