diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..574da77 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +version: 2 +updates: + - package-ecosystem: npm + directory: "/" + schedule: + interval: monthly + time: "13:00" + open-pull-requests-limit: 10 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..8059138 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,22 @@ +name: Test + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [18.x, 20.x] + steps: + - uses: actions/checkout@v3 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + - run: npm ci + - run: npm test diff --git a/.gitignore b/.gitignore index be2ee44..76b1021 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -artifacts/ -coverage/ -node_modules/ +.nyc_output +coverage +node_modules diff --git a/.npmignore b/.npmignore index c22b205..20ab70d 100644 --- a/.npmignore +++ b/.npmignore @@ -3,4 +3,6 @@ coverage/ test/ .gitignore .npmignore -.travis.yml +.nyc_output +.vscode +.github diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 71b650d..0000000 --- a/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: node_js -node_js: - - "4" - - "6" - - "8" diff --git a/README.md b/README.md index b374ee8..e6523ba 100644 --- a/README.md +++ b/README.md @@ -5,18 +5,19 @@ Serialize JavaScript to a _superset_ of JSON that includes regular expressions, [![npm Version][npm-badge]][npm] [![Dependency Status][david-badge]][david] -[![Build Status][travis-badge]][travis] +![Test](https://github.com/yahoo/serialize-javascript/workflows/Test/badge.svg) ## Overview The code in this package began its life as an internal module to [express-state][]. To expand its usefulness, it now lives as `serialize-javascript` — an independent package on npm. -You're probably wondering: **What about `JSON.stringify()`!?** We've found that sometimes we need to serialize JavaScript **functions**, **regexps** or **dates**. A great example is a web app that uses client-side URL routing where the route definitions are regexps that need to be shared from the server to the client. But this module is also great for communicating between node processes. +You're probably wondering: **What about `JSON.stringify()`!?** We've found that sometimes we need to serialize JavaScript **functions**, **regexps**, **dates**, **sets** or **maps**. A great example is a web app that uses client-side URL routing where the route definitions are regexps that need to be shared from the server to the client. But this module is also great for communicating between node processes. The string returned from this package's single export function is literal JavaScript which can be saved to a `.js` file, or be embedded into an HTML document by making the content of a `')).to.equal('"\\u003C\\u002Fscript\\u003E"'); expect(JSON.parse(serialize(''))).to.equal(''); expect(eval(serialize(''))).to.equal(''); + expect(serialize(new URL('x:'))).to.equal('new URL("x:\\u003C\\u002Fscript\\u003E")'); + expect(eval(serialize(new URL('x:'))).href).to.equal('x:'); }); }); @@ -253,6 +529,29 @@ describe('serialize( obj )', function () { expect(serialize(["<"], {space: 2})).to.equal('[\n "\\u003C"\n]'); expect(serialize(["<"], {unsafe: true, space: 2})).to.equal('[\n "<"\n]'); }); + + it("should accept a `ignoreFunction` option", function() { + function fn() { return true; } + var obj = { + fn: fn, + fn_arrow: () => { + return true; + } + }; + var obj2 = { + num: 123, + str: 'str', + fn: fn + } + // case 1. Pass function to serialize + expect(serialize(fn, { ignoreFunction: true })).to.equal('undefined'); + // case 2. Pass function(arrow) in object to serialze + expect(serialize(obj, { ignoreFunction: true })).to.equal('{}'); + // case 3. Other features should work + expect(serialize(obj2, { ignoreFunction: true })).to.equal( + '{"num":123,"str":"str"}' + ); + }); }); describe('backwards-compatability', function () { @@ -268,4 +567,17 @@ describe('serialize( obj )', function () { expect(serialize([1], 2)).to.equal('[\n 1\n]'); }); }); + + describe('placeholders', function() { + it('should not be replaced within string literals', function () { + // Since we made the UID deterministic this should always be the placeholder + var fakePlaceholder = '"@__R-0000000000000000-0__@'; + var serialized = serialize({bar: /1/i, foo: fakePlaceholder}, {uid: 'foo'}); + var obj = eval('(' + serialized + ')'); + expect(obj).to.be.a('Object'); + expect(obj.foo).to.be.a('String'); + expect(obj.foo).to.equal(fakePlaceholder); + }); + }); + });