Skip to content

Commit

Permalink
Merge pull request #68 from blitz-js/exclude-props
Browse files Browse the repository at this point in the history
exclude-props
  • Loading branch information
Skn0tt authored May 4, 2021
2 parents 653e2ee + cd91c28 commit cad3738
Show file tree
Hide file tree
Showing 15 changed files with 144 additions and 36 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,20 @@ That's it! Now you're free to use all values and type supported by SuperJSON in

<!-- Potential new section: how it works -->

### Options

You can use the `exclude` option to exclude specific properties from serialisation.

```json5
{
presets: ['next/babel'],
plugins: [
...
['superjson-next', { exclude: ["someProp"] }]
]
}
```

## Contributing

1. Clone the repo
Expand Down
13 changes: 10 additions & 3 deletions example/.babelrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
{
"presets": ["next/babel"],
"plugins": ["superjson-next"]
}
"presets": ["next/babel"],
"plugins": [
[
"superjson-next",
{
"exclude": ["superJsonSkipped"]
}
]
]
}
19 changes: 19 additions & 0 deletions example/pages/excluded-props.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { InferGetStaticPropsType } from 'next';

export async function getStaticProps() {
return {
props: {
superJsonSkipped: new Date(0).toISOString(),
date: new Date(0)
},
};
}

const Page = (props: InferGetStaticPropsType<typeof getStaticProps>) => {
return (
'props.superJsonSkipped is string: ' +
(typeof props.superJsonSkipped === 'string')
);
};

export default Page;
10 changes: 10 additions & 0 deletions example/tests/excluded-props.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Selector } from 'testcafe';

fixture`Excluded Props`.page`http://localhost:3099/excluded-props`;

test('works', async (t) => {
const result = Selector('#__next');
await t
.expect(result.innerText)
.eql('props.superJsonSkipped is string: true');
});
9 changes: 9 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import {
isVariableDeclaration,
variableDeclaration,
variableDeclarator,
arrayExpression,
stringLiteral,
} from '@babel/types';
import * as nodePath from 'path';

Expand Down Expand Up @@ -170,6 +172,10 @@ function superJsonWithNext(): PluginObj {
name: 'add superjson to pages with prop getters',
visitor: {
Program(path, state) {
const propsToBeExcluded = (state.opts as any).exclude as
| string[]
| undefined;

const filePath =
getFileName(state) ?? nodePath.join('pages', 'Default.js');

Expand All @@ -187,6 +193,9 @@ function superJsonWithNext(): PluginObj {
(decl) => {
return callExpression(addWithSuperJSONPropsImport(path), [
decl,
arrayExpression(
propsToBeExcluded?.map((prop) => stringLiteral(prop))
),
]);
}
);
Expand Down
16 changes: 15 additions & 1 deletion src/tools.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ type SuperJSONProps<P> = P & {
};

export function withSuperJSONProps<P>(
gssp: GetServerSideProps<P>
gssp: GetServerSideProps<P>,
exclude: string[] = []
): GetServerSideProps<SuperJSONProps<P>> {
return async function withSuperJSON(...args) {
const result = await gssp(...args);
Expand All @@ -21,13 +22,26 @@ export function withSuperJSONProps<P>(
return result;
}

const excludedPropValues = exclude.map((propKey) => {
const value = (result.props as any)[propKey];
delete (result.props as any)[propKey];
return value;
});

const { json, meta } = SuperJSON.serialize(result.props);
const props = json as any;

if (meta) {
props._superjson = meta;
}

exclude.forEach((key, index) => {
const excludedPropValue = excludedPropValues[index];
if (typeof excludedPropValue !== 'undefined') {
props[key] = excludedPropValue;
}
});

return {
...result,
props,
Expand Down
2 changes: 1 addition & 1 deletion test/pages/class component/output.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const getServerSideProps = _withSuperJSONProps(async () => {
products,
},
};
});
}, ['smth']);

class Page {
render({ products }) {
Expand Down
13 changes: 8 additions & 5 deletions test/pages/gSP arrow function with implicit return/output.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { withSuperJSONPage as _withSuperJSONPage } from 'babel-plugin-superjson-next/tools';
import { withSuperJSONProps as _withSuperJSONProps } from 'babel-plugin-superjson-next/tools';
export const getStaticProps = _withSuperJSONProps(() => ({
props: {
today: new Date(),
},
}));
export const getStaticProps = _withSuperJSONProps(
() => ({
props: {
today: new Date(),
},
}),
['smth']
);

function IndexPage({ today }) {
return JSON.stringify({
Expand Down
2 changes: 1 addition & 1 deletion test/pages/gSP arrow function/output.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const getStaticProps = _withSuperJSONProps(async () => {
products,
},
};
});
}, ['smth']);

function Page({ products }) {
return JSON.stringify(products);
Expand Down
3 changes: 2 additions & 1 deletion test/pages/gSP function declaration/output.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ export const getStaticProps = _withSuperJSONProps(
products,
},
};
}
},
['smth']
);

function Page({ products }) {
Expand Down
3 changes: 2 additions & 1 deletion test/pages/gSSP function declaration/output.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ export const getServerSideProps = _withSuperJSONProps(
products,
},
};
}
},
['smth']
);

function Page({ products }) {
Expand Down
2 changes: 1 addition & 1 deletion test/pages/separate export declaration/output.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const getServerSideProps = _withSuperJSONProps(async () => {
products,
},
};
});
}, ['smth']);

function Page({ products }) {
return JSON.stringify(products);
Expand Down
2 changes: 1 addition & 1 deletion test/pages/transforms a valid example/output.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const getServerSideProps = _withSuperJSONProps(async () => {
products,
},
};
});
}, ['smth']);

function Page({ products }) {
return JSON.stringify(products);
Expand Down
3 changes: 3 additions & 0 deletions test/plugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@ import * as path from 'path';

pluginTester({
plugin: superJsonWithNext,
pluginOptions: {
exclude: ['smth'],
},
fixtures: path.join(__dirname, 'pages'),
});
69 changes: 48 additions & 21 deletions test/tools.test.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,55 @@
import { withSuperJSONPage } from "../src/tools"
import { render } from "@testing-library/react-native"
import * as React from "react"
import { withSuperJSONPage, withSuperJSONProps } from '../src/tools';
import { render } from '@testing-library/react-native';
import * as React from 'react';

describe("tools", () => {
describe("a component wrapped withSuperJSONPage", () => {
describe("when used from a test", () => {
it("works", () => {
describe('tools', () => {
describe('a component wrapped withSuperJSONPage', () => {
describe('when used from a test', () => {
it('works', () => {
function Greeter(props: { name: string }) {
return (
<p>
Greetings, {props.name}!
</p>
)
return <p>Greetings, {props.name}!</p>;
}

const WrappedGreeter = withSuperJSONPage(Greeter)
const WrappedGreeter = withSuperJSONPage(Greeter);

const GreeterFromTest = WrappedGreeter as any as typeof Greeter
const GreeterFromTest = (WrappedGreeter as any) as typeof Greeter;

const result = render(<GreeterFromTest name="Earthling" />)
const result = render(<GreeterFromTest name="Earthling" />);
expect(result.toJSON().children).toEqual([
"Greetings, ", "Earthling", "!"
])
})
})
})
})
'Greetings, ',
'Earthling',
'!',
]);
});
});
});

describe('withSuperJSONProps', () => {
it('respects `exclude`', async () => {
const aDate = new Date();
const bDate = new Date();
async function gSSP() {
return {
props: {
a: aDate,
b: bDate,
},
};
}
const wrappedGssp = withSuperJSONProps(gSSP, ['a']);

const result = await wrappedGssp(null as any);
expect(result).toEqual({
props: {
a: aDate,
b: bDate.toISOString(),
_superjson: {
values: {
b: ['Date'],
},
},
},
});
});
});
});

0 comments on commit cad3738

Please sign in to comment.