Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"test:eslint": "eslint --ext .js {src,ssr,lib,build}/**/*.js",
"test:types": "tsc -p types/test",
"test:e2e": "cd tests/demo && yarn test",
"test:unit": "yarn run jest",
"docs:dev": "vuepress dev docs",
"docs:build": "vuepress build docs"
},
Expand All @@ -41,6 +42,7 @@
},
"dependencies": {
"chalk": "^2.4.2",
"serialize-javascript": "^1.7.0",
"throttle-debounce": "^2.1.0"
},
"devDependencies": {
Expand All @@ -64,6 +66,7 @@
"eslint-plugin-standard": "^4.0.0",
"graphql": "^14.0.2",
"graphql-tag": "^2.5.0",
"jest": "^24.8.0",
"nodemon": "^1.18.4",
"rimraf": "^2.6.1",
"rollup": "^0.66.6",
Expand All @@ -77,5 +80,8 @@
"vue": "^2.5.16",
"vue-property-decorator": "^7.0.0",
"vuepress": "^0.14.2"
},
"jest": {
"testRegex": "tests/unit/.*\\.test.js$"
}
}
20 changes: 15 additions & 5 deletions ssr/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
exports.getStates = function (apolloProvider, options) {
const serializeJs = require('serialize-javascript');

exports.serializeStates = function(apolloProvider, options = {}) {
const state = exports.getStates(apolloProvider, options)

return options.useUnsafeSerializer
? JSON.stringify(state)
: serializeJs(state)
}

exports.getStates = function (apolloProvider, options = {}) {
const finalOptions = Object.assign({}, {
exportNamespace: '',
}, options)
Expand All @@ -15,8 +25,8 @@ exports.exportStates = function (apolloProvider, options) {
const finalOptions = Object.assign({}, {
globalName: '__APOLLO_STATE__',
attachTo: 'window',
}, options)
const states = exports.getStates(apolloProvider, finalOptions)
const js = `${finalOptions.attachTo}.${finalOptions.globalName} = ${JSON.stringify(states)};`
return js
useUnsafeSerializer: false,
}, options);

return `${finalOptions.attachTo}.${finalOptions.globalName} = ${exports.serializeStates(apolloProvider, options)};`
}
2 changes: 1 addition & 1 deletion tests/demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"test:e2e:dev:client": "vue-cli-service test:e2e --mode development",
"test:e2e": "start-server-and-test apollo:run http://localhost:4000/.well-known/apollo/server-health test:e2e:client",
"test:e2e:client": "vue-cli-service test:e2e --mode production --headless",
"test": "yarn run lint --no-fix && yarn run test:e2e"
"test": "yarn run lint --no-fix && yarn run test:unit && yarn run test:e2e"
},
"dependencies": {
"graphql-type-json": "^0.2.1",
Expand Down
61 changes: 61 additions & 0 deletions tests/unit/ssr.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
const ssr = require('../../ssr');

describe('ssr states', () => {
function buildClient(cache) {
return {
cache: {
extract() {
return cache
}
}
}
}

const defaultClient = buildClient({
"foo": "<alert>hiya!</alert>",
});

const otherClient = buildClient({
"foo": "bar",
});

const apolloProvider = {
clients: {
defaultClient,
profile: defaultClient,
other: otherClient,
}
};

describe('serializeStates', () => {
it('safely serializes by default', () => {
const safe = '{"defaultClient":{"foo":"\u003Calert\u003Ehiya!\u003C\u002Falert\u003E"},"profile":{"foo":"\u003Calert\u003Ehiya!\u003C\u002Falert\u003E"},"other":{"foo":"bar"}}'

expect(ssr.serializeStates(apolloProvider)).not.toMatch("<alert>hiya!</alert>");
});

it('allows option to use raw JSON stringify', () => {
const unsafe = '{"defaultClient":{"foo":"<alert>hiya!</alert>"},"profile":{"foo":"<alert>hiya!</alert>"},"other":{"foo":"bar"}}';

expect(ssr.serializeStates(apolloProvider, { useUnsafeSerializer: true })).toMatch(unsafe);
})
});

describe('getStates', () => {
it('exports provider clients to object', () => {
expect(ssr.getStates(apolloProvider)).toMatchObject({
defaultClient: { foo: '<alert>hiya!</alert>' },
profile: { foo: '<alert>hiya!</alert>' },
other: { foo: 'bar' }
});
});
});

describe('exportStates', () => {
it('sets attachTo and globalName equal to serializedstates', () => {
const string = ssr.exportStates(apolloProvider, { globalName: "NUXT", attachTo: "global" })

expect(string).toMatch(/^global\.NUXT/);
});
});
});
Loading