diff --git a/.eslintrc.json b/.eslintrc.json index bd86da7..b13cc80 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -7,7 +7,9 @@ }, "extends": ["eslint:recommended", "google", "prettier"], "globals": {}, - "parserOptions": {}, + "parserOptions": { + "ecmaVersion": 2022 + }, "rules": { "indent": ["error", 4, {"SwitchCase": 1}], "max-len": ["off"], diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index f77672c..0c7dc96 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -2,10 +2,6 @@ name: "Build" on: push: - branches: [master, develop] - pull_request: - # The branches below must be a subset of the branches above - branches: [master, develop] workflow_dispatch: inputs: reason: @@ -16,12 +12,17 @@ jobs: build: name: Build runs-on: ubuntu-latest - + strategy: + matrix: + node-version: [16.x, 18.x, 20.x, 22.x] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - name: Check out repo + uses: actions/checkout@v4 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 with: - node-version: 12 + node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Skip post-install scripts here, as a malicious # script could steal NODE_AUTH_TOKEN. @@ -40,10 +41,10 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: - node-version: 12 + node-version: 20 registry-url: https://registry.npmjs.org/ # Skip post-install scripts here, as a malicious # script could steal NODE_AUTH_TOKEN. diff --git a/.github/workflows/ci-codeql-analysis.yml b/.github/workflows/ci-codeql-analysis.yml index 1bb21bf..876c8ca 100644 --- a/.github/workflows/ci-codeql-analysis.yml +++ b/.github/workflows/ci-codeql-analysis.yml @@ -2,10 +2,6 @@ name: "CodeQL Analysis" on: push: - branches: [master, develop] - pull_request: - # The branches below must be a subset of the branches above - branches: [master, develop] workflow_dispatch: inputs: reason: @@ -26,11 +22,11 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -39,4 +35,4 @@ jobs: # queries: ./path/to/local/query, your-org/your-repo/queries@main - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/ci-npm-publish.yml b/.github/workflows/ci-npm-publish.yml index 5da634b..0fae415 100644 --- a/.github/workflows/ci-npm-publish.yml +++ b/.github/workflows/ci-npm-publish.yml @@ -8,12 +8,17 @@ jobs: build: name: Build runs-on: ubuntu-latest - + strategy: + matrix: + node-version: [16.x, 18.x, 20.x, 22.x] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - name: Check out repo + uses: actions/checkout@v4 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 with: - node-version: 12 + node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Skip post-install scripts here, as a malicious # script could steal NODE_AUTH_TOKEN. @@ -32,10 +37,10 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: - node-version: 12 + node-version: 20 registry-url: https://registry.npmjs.org/ # Skip post-install scripts here, as a malicious # script could steal NODE_AUTH_TOKEN. diff --git a/lib/JSONPointer.js b/lib/JSONPointer.js index 79d4996..93205db 100644 --- a/lib/JSONPointer.js +++ b/lib/JSONPointer.js @@ -173,7 +173,17 @@ api.walk = function walk(obj, iterator, descend) { descend || function (value) { const type = Object.prototype.toString.call(value); - return type === '[object Object]' || type === '[object Array]'; + if (type === '[object Object]') { + // descend if the value is not a BSONValue + // todo: this should rather be (value instanceof BSONValue) if we didn't have to support node 12 + if (!!value._bsontype && !!value[Symbol.for('@@mdb.bson.version')]) { + return false; + } else { + return true; + } + } else { + return type === '[object Array]'; + } }; (function next(cur) { diff --git a/package.json b/package.json index a59c0d7..b42b3ac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@synatic/json-magic", - "version": "1.0.2", + "version": "1.1.0", "description": "Utilities for manipulating JSON objects.", "main": "index.js", "files": [ @@ -19,7 +19,8 @@ "url": "https://github.com/synatic/json-magic.git" }, "keywords": [ - "json" + "json", + "bson" ], "author": { "name": "Synatic Inc", @@ -42,15 +43,16 @@ "node": ">=12" }, "dependencies": { - "check-types": "11.2.2", + "check-types": "11.2.3", "serialize-error": "8.1.0" }, "devDependencies": { + "bson": "^6.8.0", "eslint": "^8.16.0", "eslint-config-google": "^0.14.0", "eslint-config-prettier": "^8.5.0", "mocha": "^10.0.0", - "nyc": "^15.1.0", - "prettier": "^2.6.2" + "nyc": "^17.0.0", + "prettier": "^3.3.3" } } diff --git a/test/test.js b/test/test.js index 4d59950..ac9c937 100644 --- a/test/test.js +++ b/test/test.js @@ -1,5 +1,6 @@ const assert = require('assert'); const $check = require('check-types'); +const {ObjectId, Binary, Timestamp} = require('bson'); const $json = require('../index.js'); @@ -248,11 +249,13 @@ describe('JSON Magic', function () { $json.set(val, '/a/b', {c: 1}); assert.deepStrictEqual(val, {a: {b: {c: 1}}}, 'Invalid set'); }); + it('should set a value 4', function () { const val = {}; $json.set(val, 'a', '1'); assert.deepStrictEqual(val, {a: '1'}, 'Invalid set'); }); + it('should set a value 5 ', function () { const val = []; $json.set(val, '/0', 'Val1'); @@ -621,7 +624,8 @@ describe('JSON Magic', function () { val = $json.changeValue(val, (val, path) => { return val; }); - assert.deepStrictEqual(val, {a: {b: {c: 1, d: 2}, x: 'abc'}}, 'Invalid kchange val'); + + assert.deepStrictEqual(val, {a: {b: {c: 1, d: 2}, x: 'abc'}}, 'Invalid change val'); }); it('should change a value', function () { @@ -664,6 +668,26 @@ describe('JSON Magic', function () { ); }); + it('should change a value containing BSON data and be able to stringify the output', function () { + const value = { + a: 'a', + _id: new ObjectId(), + binary: new Binary(Buffer.from('binary')), + nested: { + b: 1, + timestamp: new Timestamp(0xffffffffffffffffn) + } + }; + + const newValue = $json.changeValue(value, (val, path) => { + return {value: val}; + }); + + const newValueString = JSON.stringify(newValue); + + assert.strictEqual(JSON.stringify(value), newValueString, 'Invalid change val'); + }); + it('should change a string ', function () { let val = 'abc';