diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..fe8a7e5 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,20 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "npm" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" + ignore: + # For all packages, ignore all patch updates + - dependency-name: "*" + update-types: ["version-update:semver-major"] + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml new file mode 100644 index 0000000..bc2d176 --- /dev/null +++ b/.github/workflows/main.yaml @@ -0,0 +1,22 @@ +name: CI +on: + - push + - pull_request +jobs: + test: + name: Node.js ${{ matrix.node-version }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + node-version: + - 21 + - 20 + - 18 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + - run: npm install + - run: npm test diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml new file mode 100644 index 0000000..18a369a --- /dev/null +++ b/.github/workflows/npm-publish.yml @@ -0,0 +1,28 @@ +name: Publish Package to npmjs +on: + release: + types: [published] +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: "20.x" + - run: npm i + - run: npm test + + publish-npm: + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: "20.x" + registry-url: "https://registry.npmjs.org" + - run: npm i + - run: npm publish + env: + NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000..5158023 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,26 @@ +# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time. +# +# You can adjust the behavior by modifying this file. +# For more information, see: +# https://github.com/actions/stale +name: Mark stale issues and pull requests +on: + schedule: + - cron: "*/10 5 * * *" +jobs: + stale: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/stale@v9 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + days-before-stale: 365 + stale-issue-message: 'This issue is stale because it has been open 365 days with no activity. Remove stale label or comment or this will be closed in 7 days.' + stale-pr-message: 'This PR is stale because it has been open 365 days with no activity. Remove stale label or comment or this will be closed in 7 days.' + close-issue-message: 'This issue was closed because it has been stalled for 7 days with no activity.' + close-pr-message: 'This PR was closed because it has been stalled for 7 days with no activity.' + exempt-issue-labels: 'Help Wanted, Good first issue, Never gets stale' + exempt-pr-labels: 'Help Wanted, Never gets stale' diff --git a/.mergify.yml b/.mergify.yml new file mode 100644 index 0000000..f2a253f --- /dev/null +++ b/.mergify.yml @@ -0,0 +1,8 @@ +pull_request_rules: + - name: automatic merge for Greenkeeper pull requests + conditions: + - author=greenkeeper[bot] + - status-success=greenkeeper/verify + actions: + merge: + method: merge diff --git a/.travis.yml b/.travis.yml index afc313a..2f689b2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ language: node_js node_js: - - '10' - '8' notifications: email: false diff --git a/index.js b/index.js index cbf90dd..4cedda9 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,15 @@ -module.exports = (arrayInput = []) => { +function cloneArrayObjects(arrayInput = []) { if (!Array.isArray(arrayInput)) { throw new TypeError(`Expected an array, got ${typeof arrayInput}`); } - return arrayInput.map(obj => ({...obj})); -}; + + return arrayInput.map(object => { + if (typeof object !== 'object' || object === null) { + throw new TypeError(`Expected an object, got ${typeof object}`); + } + + return {...object}; + }); +} + +export default cloneArrayObjects; diff --git a/package.json b/package.json index ae5ed99..2279492 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "clone-array-objects", - "version": "1.0.0", + "version": "1.0.2", "description": "Clone an array of objects", "license": "MIT", "repository": "https://github.com/palashmon/clone-array-objects", @@ -10,7 +10,7 @@ "url": "https://github.com/palashmon" }, "engines": { - "node": ">=8" + "node": ">=14" }, "scripts": { "test": "xo && ava", @@ -30,8 +30,9 @@ "test" ], "devDependencies": { - "ava": "^1.0.1", - "nyc": "^14.0.0", - "xo": "^0.24.0" - } -} + "ava": "^6.0.1", + "nyc": "^15.0.0", + "xo": "^0.58.0" + }, + "type": "module" +} \ No newline at end of file diff --git a/readme.md b/readme.md index 1e1a580..b2392e9 100644 --- a/readme.md +++ b/readme.md @@ -1,11 +1,6 @@ -# clone-array-objects +# clone-array-objects ![CI](https://github.com/palashmon/clone-array-objects/actions/workflows/main.yaml/badge.svg) -[![Build Status](https://travis-ci.org/palashmon/clone-array-objects.svg?branch=master)](https://travis-ci.org/palashmon/clone-array-objects) -[![npm](https://img.shields.io/npm/v/clone-array-objects.svg)](https://www.npmjs.org/package/clone-array-objects) -[![codecov](https://codecov.io/gh/palashmon/clone-array-objects/branch/master/graph/badge.svg)](https://codecov.io/gh/palashmon/clone-array-objects) -[![Gzip Size](https://img.badgesize.io/https://unpkg.com/clone-array-objects?compression=gzip)](https://bundlephobia.com/result?p=clone-array-objects) [![Greenkeeper badge](https://badges.greenkeeper.io/palashmon/clone-array-objects.svg)](https://greenkeeper.io/) - -Tiny module to clone an array of objects +> Tiny module to clone an array of objects ## Install diff --git a/test.js b/test.js index 59711ae..7d62404 100644 --- a/test.js +++ b/test.js @@ -1,24 +1,44 @@ import test from 'ava'; -import cloneArrayObjects from '.'; +import cloneArrayObjects from './index.js'; -test('Return typeerror when arrayInput is not an array.', t => { - const err = t.throws(() => { - cloneArrayObjects(23); - }, TypeError); - t.is(err.message, 'Expected an array, got number'); +test('should return a new array with cloned objects', t => { + const input = [ + {name: 'John', age: 30}, + {name: 'Jane', age: 25}, + ]; + const output = cloneArrayObjects(input); + + t.not(output, input); // Should not modify the original array + t.deepEqual(output, input); // Should have the same values as the input +}); + +test('should throw a TypeError if the input is not an array', t => { + const input = 'not an array'; + + const error = t.throws(() => cloneArrayObjects(input)); + + t.is(error.message, `Expected an array, got ${typeof input}`); +}); + +test('should throw a TypeError if any object in the array is null', t => { + const input = [{name: 'John', age: 30}, null]; + + const error = t.throws(() => cloneArrayObjects(input)); + + t.is(error.message, 'Expected an object, got object'); }); -test('Return empty array when no valid input passed.', t => { - t.deepEqual(cloneArrayObjects(), []); - t.deepEqual(cloneArrayObjects([]), []); +test('should throw a TypeError if any object in the array is not an object', t => { + const input = [{name: 'John', age: 30}, 'not an object']; + + const error = t.throws(() => cloneArrayObjects(input)); + + t.is(error.message, 'Expected an object, got string'); }); -test('Test clone', t => { - const actual = [{a: 1}, {b: 2}]; - const expected = [{a: 1}, {b: 2}]; - const modified = [{a: 1}, {b: 3}]; - t.deepEqual(cloneArrayObjects(actual), expected); - expected[1].b = 3; - t.notDeepEqual(cloneArrayObjects(actual), expected); - t.deepEqual(modified, expected); +test('should return an empty array if the input is an empty array', t => { + const input = []; + const output = cloneArrayObjects(input); + + t.deepEqual(output, []); });