Configure Prettier option semi to the default, true.

This commit is contained in:
Jayden Seric 2020-03-30 19:51:05 +11:00
parent f8553c6f59
commit fd75f4658c
18 changed files with 137 additions and 140 deletions

View File

@ -1,5 +1,4 @@
{ {
"proseWrap": "never", "proseWrap": "never",
"singleQuote": true, "singleQuote": true
"semi": false
} }

View File

@ -1,5 +1,4 @@
{ {
"proseWrap": "never", "proseWrap": "never",
"singleQuote": true, "singleQuote": true
"semi": false
} }

View File

@ -1,10 +1,10 @@
'use strict' 'use strict';
const { GraphQLSchema } = require('graphql') const { GraphQLSchema } = require('graphql');
const { MutationType } = require('./types/Mutation') const { MutationType } = require('./types/Mutation');
const { QueryType } = require('./types/Query') const { QueryType } = require('./types/Query');
exports.schema = new GraphQLSchema({ exports.schema = new GraphQLSchema({
query: QueryType, query: QueryType,
mutation: MutationType, mutation: MutationType,
}) });

View File

@ -1,22 +1,22 @@
'use strict' 'use strict';
const { createWriteStream, unlink } = require('fs') const { createWriteStream, unlink } = require('fs');
const { ApolloServer } = require('apollo-server-koa') const { ApolloServer } = require('apollo-server-koa');
const Koa = require('koa') const Koa = require('koa');
const lowdb = require('lowdb') const lowdb = require('lowdb');
const FileSync = require('lowdb/adapters/FileSync') const FileSync = require('lowdb/adapters/FileSync');
const mkdirp = require('mkdirp') const mkdirp = require('mkdirp');
const shortid = require('shortid') const shortid = require('shortid');
const { schema } = require('./schema') const { schema } = require('./schema');
const UPLOAD_DIR = './uploads' const UPLOAD_DIR = './uploads';
const db = lowdb(new FileSync('db.json')) const db = lowdb(new FileSync('db.json'));
// Seed an empty DB. // Seed an empty DB.
db.defaults({ uploads: [] }).write() db.defaults({ uploads: [] }).write();
// Ensure upload directory exists. // Ensure upload directory exists.
mkdirp.sync(UPLOAD_DIR) mkdirp.sync(UPLOAD_DIR);
/** /**
* Stores a GraphQL file upload. The file is stored in the filesystem and its * Stores a GraphQL file upload. The file is stored in the filesystem and its
@ -25,44 +25,44 @@ mkdirp.sync(UPLOAD_DIR)
* @returns {object} File metadata. * @returns {object} File metadata.
*/ */
const storeUpload = async (upload) => { const storeUpload = async (upload) => {
const { createReadStream, filename, mimetype } = await upload const { createReadStream, filename, mimetype } = await upload;
const stream = createReadStream() const stream = createReadStream();
const id = shortid.generate() const id = shortid.generate();
const path = `${UPLOAD_DIR}/${id}-${filename}` const path = `${UPLOAD_DIR}/${id}-${filename}`;
const file = { id, filename, mimetype, path } const file = { id, filename, mimetype, path };
// Store the file in the filesystem. // Store the file in the filesystem.
await new Promise((resolve, reject) => { await new Promise((resolve, reject) => {
// Create a stream to which the upload will be written. // Create a stream to which the upload will be written.
const writeStream = createWriteStream(path) const writeStream = createWriteStream(path);
// When the upload is fully written, resolve the promise. // When the upload is fully written, resolve the promise.
writeStream.on('finish', resolve) writeStream.on('finish', resolve);
// If there's an error writing the file, remove the partially written file // If there's an error writing the file, remove the partially written file
// and reject the promise. // and reject the promise.
writeStream.on('error', (error) => { writeStream.on('error', (error) => {
unlink(path, () => { unlink(path, () => {
reject(error) reject(error);
}) });
}) });
// In node <= 13, errors are not automatically propagated between piped // In node <= 13, errors are not automatically propagated between piped
// streams. If there is an error receiving the upload, destroy the write // streams. If there is an error receiving the upload, destroy the write
// stream with the corresponding error. // stream with the corresponding error.
stream.on('error', (error) => writeStream.destroy(error)) stream.on('error', (error) => writeStream.destroy(error));
// Pipe the upload into the write stream. // Pipe the upload into the write stream.
stream.pipe(writeStream) stream.pipe(writeStream);
}) });
// Record the file metadata in the DB. // Record the file metadata in the DB.
db.get('uploads').push(file).write() db.get('uploads').push(file).write();
return file return file;
} };
const app = new Koa() const app = new Koa();
const server = new ApolloServer({ const server = new ApolloServer({
uploads: { uploads: {
// Limits here should be stricter than config for surrounding // Limits here should be stricter than config for surrounding
@ -74,14 +74,14 @@ const server = new ApolloServer({
}, },
schema, schema,
context: { db, storeUpload }, context: { db, storeUpload },
}) });
server.applyMiddleware({ app }) server.applyMiddleware({ app });
app.listen(process.env.PORT, (error) => { app.listen(process.env.PORT, (error) => {
if (error) throw error if (error) throw error;
console.info( console.info(
`Serving http://localhost:${process.env.PORT} for ${process.env.NODE_ENV}.` `Serving http://localhost:${process.env.PORT} for ${process.env.NODE_ENV}.`
) );
}) });

View File

@ -1,11 +1,11 @@
'use strict' 'use strict';
const { const {
GraphQLNonNull, GraphQLNonNull,
GraphQLObjectType, GraphQLObjectType,
GraphQLString, GraphQLString,
GraphQLID, GraphQLID,
} = require('graphql') } = require('graphql');
exports.FileType = new GraphQLObjectType({ exports.FileType = new GraphQLObjectType({
name: 'File', name: 'File',
@ -28,4 +28,4 @@ exports.FileType = new GraphQLObjectType({
type: GraphQLNonNull(GraphQLString), type: GraphQLNonNull(GraphQLString),
}, },
}), }),
}) });

View File

@ -1,9 +1,9 @@
'use strict' 'use strict';
const { GraphQLUpload } = require('apollo-server-koa') const { GraphQLUpload } = require('apollo-server-koa');
const { GraphQLList, GraphQLObjectType, GraphQLNonNull } = require('graphql') const { GraphQLList, GraphQLObjectType, GraphQLNonNull } = require('graphql');
const promisesAll = require('promises-all') const promisesAll = require('promises-all');
const { FileType } = require('./File') const { FileType } = require('./File');
exports.MutationType = new GraphQLObjectType({ exports.MutationType = new GraphQLObjectType({
name: 'Mutation', name: 'Mutation',
@ -31,15 +31,15 @@ exports.MutationType = new GraphQLObjectType({
async resolve(parent, { files }, { storeUpload }) { async resolve(parent, { files }, { storeUpload }) {
const { resolve, reject } = await promisesAll.all( const { resolve, reject } = await promisesAll.all(
files.map(storeUpload) files.map(storeUpload)
) );
if (reject.length) if (reject.length)
reject.forEach(({ name, message }) => reject.forEach(({ name, message }) =>
console.error(`${name}: ${message}`) console.error(`${name}: ${message}`)
) );
return resolve return resolve;
}, },
}, },
}), }),
}) });

View File

@ -1,7 +1,7 @@
'use strict' 'use strict';
const { GraphQLList, GraphQLObjectType, GraphQLNonNull } = require('graphql') const { GraphQLList, GraphQLObjectType, GraphQLNonNull } = require('graphql');
const { FileType } = require('./File') const { FileType } = require('./File');
exports.QueryType = new GraphQLObjectType({ exports.QueryType = new GraphQLObjectType({
name: 'Query', name: 'Query',
@ -12,4 +12,4 @@ exports.QueryType = new GraphQLObjectType({
resolve: (source, args, { db }) => db.get('uploads').value(), resolve: (source, args, { db }) => db.get('uploads').value(),
}, },
}), }),
}) });

View File

@ -1,5 +1,4 @@
{ {
"proseWrap": "never", "proseWrap": "never",
"singleQuote": true, "singleQuote": true
"semi": false
} }

View File

@ -7,4 +7,4 @@ export const Header = (props) => (
} }
`}</style> `}</style>
</> </>
) );

View File

@ -1,4 +1,4 @@
import Head from 'next/head' import Head from 'next/head';
export const Page = ({ title, children }) => ( export const Page = ({ title, children }) => (
<> <>
@ -7,4 +7,4 @@ export const Page = ({ title, children }) => (
</Head> </Head>
{children} {children}
</> </>
) );

View File

@ -7,4 +7,4 @@ export const Section = (props) => (
} }
`}</style> `}</style>
</> </>
) );

View File

@ -1,7 +1,7 @@
import { useApolloClient, useMutation } from '@apollo/react-hooks' import { useApolloClient, useMutation } from '@apollo/react-hooks';
import { ButtonSubmit, Code, Fieldset, Textbox } from 'device-agnostic-ui' import { ButtonSubmit, Code, Fieldset, Textbox } from 'device-agnostic-ui';
import gql from 'graphql-tag' import gql from 'graphql-tag';
import React from 'react' import React from 'react';
const SINGLE_UPLOAD_MUTATION = gql` const SINGLE_UPLOAD_MUTATION = gql`
mutation singleUpload($file: Upload!) { mutation singleUpload($file: Upload!) {
@ -9,28 +9,28 @@ const SINGLE_UPLOAD_MUTATION = gql`
id id
} }
} }
` `;
export const UploadBlob = () => { export const UploadBlob = () => {
const [name, setName] = React.useState('') const [name, setName] = React.useState('');
const [content, setContent] = React.useState('') const [content, setContent] = React.useState('');
const [singleUploadMutation, { loading }] = useMutation( const [singleUploadMutation, { loading }] = useMutation(
SINGLE_UPLOAD_MUTATION SINGLE_UPLOAD_MUTATION
) );
const apolloClient = useApolloClient() const apolloClient = useApolloClient();
const onNameChange = ({ target: { value } }) => setName(value) const onNameChange = ({ target: { value } }) => setName(value);
const onContentChange = ({ target: { value } }) => setContent(value) const onContentChange = ({ target: { value } }) => setContent(value);
const onSubmit = (event) => { const onSubmit = (event) => {
event.preventDefault() event.preventDefault();
const file = new Blob([content], { type: 'text/plain' }) const file = new Blob([content], { type: 'text/plain' });
file.name = `${name}.txt` file.name = `${name}.txt`;
singleUploadMutation({ variables: { file } }).then(() => { singleUploadMutation({ variables: { file } }).then(() => {
apolloClient.resetStore() apolloClient.resetStore();
}) });
} };
return ( return (
<form onSubmit={onSubmit}> <form onSubmit={onSubmit}>
@ -59,5 +59,5 @@ export const UploadBlob = () => {
</Fieldset> </Fieldset>
<ButtonSubmit loading={loading}>Upload</ButtonSubmit> <ButtonSubmit loading={loading}>Upload</ButtonSubmit>
</form> </form>
) );
} };

View File

@ -1,5 +1,5 @@
import { useApolloClient, useMutation } from '@apollo/react-hooks' import { useApolloClient, useMutation } from '@apollo/react-hooks';
import gql from 'graphql-tag' import gql from 'graphql-tag';
const SINGLE_UPLOAD_MUTATION = gql` const SINGLE_UPLOAD_MUTATION = gql`
mutation singleUpload($file: Upload!) { mutation singleUpload($file: Upload!) {
@ -7,11 +7,11 @@ const SINGLE_UPLOAD_MUTATION = gql`
id id
} }
} }
` `;
export const UploadFile = () => { export const UploadFile = () => {
const [uploadFileMutation] = useMutation(SINGLE_UPLOAD_MUTATION) const [uploadFileMutation] = useMutation(SINGLE_UPLOAD_MUTATION);
const apolloClient = useApolloClient() const apolloClient = useApolloClient();
const onChange = ({ const onChange = ({
target: { target: {
@ -21,8 +21,8 @@ export const UploadFile = () => {
}) => }) =>
validity.valid && validity.valid &&
uploadFileMutation({ variables: { file } }).then(() => { uploadFileMutation({ variables: { file } }).then(() => {
apolloClient.resetStore() apolloClient.resetStore();
}) });
return <input type="file" required onChange={onChange} /> return <input type="file" required onChange={onChange} />;
} };

View File

@ -1,5 +1,5 @@
import { useApolloClient, useMutation } from '@apollo/react-hooks' import { useApolloClient, useMutation } from '@apollo/react-hooks';
import gql from 'graphql-tag' import gql from 'graphql-tag';
const MULTIPLE_UPLOAD_MUTATION = gql` const MULTIPLE_UPLOAD_MUTATION = gql`
mutation multipleUpload($files: [Upload!]!) { mutation multipleUpload($files: [Upload!]!) {
@ -7,17 +7,17 @@ const MULTIPLE_UPLOAD_MUTATION = gql`
id id
} }
} }
` `;
export const UploadFileList = () => { export const UploadFileList = () => {
const [multipleUploadMutation] = useMutation(MULTIPLE_UPLOAD_MUTATION) const [multipleUploadMutation] = useMutation(MULTIPLE_UPLOAD_MUTATION);
const apolloClient = useApolloClient() const apolloClient = useApolloClient();
const onChange = ({ target: { validity, files } }) => const onChange = ({ target: { validity, files } }) =>
validity.valid && validity.valid &&
multipleUploadMutation({ variables: { files } }).then(() => { multipleUploadMutation({ variables: { files } }).then(() => {
apolloClient.resetStore() apolloClient.resetStore();
}) });
return <input type="file" multiple required onChange={onChange} /> return <input type="file" multiple required onChange={onChange} />;
} };

View File

@ -1,6 +1,6 @@
import { useQuery } from '@apollo/react-hooks' import { useQuery } from '@apollo/react-hooks';
import { Scroll, Table } from 'device-agnostic-ui' import { Scroll, Table } from 'device-agnostic-ui';
import gql from 'graphql-tag' import gql from 'graphql-tag';
const UPLOADS_QUERY = gql` const UPLOADS_QUERY = gql`
query uploads { query uploads {
@ -11,10 +11,10 @@ const UPLOADS_QUERY = gql`
path path
} }
} }
` `;
export const Uploads = () => { export const Uploads = () => {
const { data: { uploads = [] } = {} } = useQuery(UPLOADS_QUERY) const { data: { uploads = [] } = {} } = useQuery(UPLOADS_QUERY);
return ( return (
<Scroll> <Scroll>
@ -37,5 +37,5 @@ export const Uploads = () => {
</tbody> </tbody>
</Table> </Table>
</Scroll> </Scroll>
) );
} };

View File

@ -2,4 +2,4 @@ module.exports = {
env: { env: {
API_URI: process.env.API_URI, API_URI: process.env.API_URI,
}, },
} };

View File

@ -1,17 +1,17 @@
import 'cross-fetch/polyfill' import 'cross-fetch/polyfill';
import { ApolloProvider } from '@apollo/react-hooks' import { ApolloProvider } from '@apollo/react-hooks';
import { InMemoryCache } from 'apollo-cache-inmemory' import { InMemoryCache } from 'apollo-cache-inmemory';
import { ApolloClient } from 'apollo-client' import { ApolloClient } from 'apollo-client';
import { createUploadLink } from 'apollo-upload-client' import { createUploadLink } from 'apollo-upload-client';
import { stylesGlobal, stylesGlobalTheme } from 'device-agnostic-ui' import { stylesGlobal, stylesGlobalTheme } from 'device-agnostic-ui';
import Head from 'next/head' import Head from 'next/head';
const createApolloClient = (cache = {}) => const createApolloClient = (cache = {}) =>
new ApolloClient({ new ApolloClient({
ssrMode: typeof window !== 'undefined', ssrMode: typeof window !== 'undefined',
cache: new InMemoryCache().restore(cache), cache: new InMemoryCache().restore(cache),
link: createUploadLink({ uri: process.env.API_URI }), link: createUploadLink({ uri: process.env.API_URI }),
}) });
const App = ({ const App = ({
Component, Component,
@ -34,19 +34,19 @@ const App = ({
{stylesGlobal} {stylesGlobal}
</style> </style>
</ApolloProvider> </ApolloProvider>
) );
App.getInitialProps = async (context) => { App.getInitialProps = async (context) => {
const props = { const props = {
pageProps: context.Component.getInitialProps pageProps: context.Component.getInitialProps
? await context.Component.getInitialProps(context) ? await context.Component.getInitialProps(context)
: {}, : {},
} };
if (context.ctx.req) { if (context.ctx.req) {
const apolloClient = createApolloClient() const apolloClient = createApolloClient();
try { try {
const { getDataFromTree } = await import('@apollo/react-ssr') const { getDataFromTree } = await import('@apollo/react-ssr');
await getDataFromTree( await getDataFromTree(
<App <App
{...props} {...props}
@ -54,18 +54,18 @@ App.getInitialProps = async (context) => {
router={context.router} router={context.router}
Component={context.Component} Component={context.Component}
/> />
) );
} catch (error) { } catch (error) {
// Prevent crash from GraphQL errors. // Prevent crash from GraphQL errors.
console.error(error) console.error(error);
} }
Head.rewind() Head.rewind();
props.apolloCache = apolloClient.cache.extract() props.apolloCache = apolloClient.cache.extract();
} }
return props return props;
} };
export default App export default App;

View File

@ -1,11 +1,11 @@
import { Code, Heading, Margin } from 'device-agnostic-ui' import { Code, Heading, Margin } from 'device-agnostic-ui';
import { Header } from '../components/Header' import { Header } from '../components/Header';
import { Page } from '../components/Page' import { Page } from '../components/Page';
import { Section } from '../components/Section' import { Section } from '../components/Section';
import { UploadBlob } from '../components/UploadBlob' import { UploadBlob } from '../components/UploadBlob';
import { UploadFile } from '../components/UploadFile' import { UploadFile } from '../components/UploadFile';
import { UploadFileList } from '../components/UploadFileList' import { UploadFileList } from '../components/UploadFileList';
import { Uploads } from '../components/Uploads' import { Uploads } from '../components/Uploads';
const IndexPage = () => ( const IndexPage = () => (
<Page title="Apollo upload examples"> <Page title="Apollo upload examples">
@ -51,6 +51,6 @@ const IndexPage = () => (
<Uploads /> <Uploads />
</Section> </Section>
</Page> </Page>
) );
export default IndexPage export default IndexPage;