Support latest client and server alphas.

Also:

- Update deps.
- Lock `apollo-cache-inmemory` to v1.0.0 since newer versions are buggy.
- New file naming approach for stored uploads.
- More intuitive mixed ESM/CJS module imports in the API.
This commit is contained in:
Jayden Seric 2017-11-20 00:40:10 +11:00
parent fc2fbbb077
commit 3f33fb16d8
11 changed files with 194 additions and 98 deletions

157
api/package-lock.json generated
View File

@ -147,12 +147,11 @@
}
},
"apollo-upload-server": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/apollo-upload-server/-/apollo-upload-server-2.0.4.tgz",
"integrity": "sha512-GwkxlrCqo/JLRlBDmXl6cyNZwnZ3j2tbWGRbhyFn1S8jNivUoZr0ROOpQPpzwFwzrmfm6kJI01HGa7QAxA3keA==",
"version": "4.0.0-alpha.1",
"resolved": "https://registry.npmjs.org/apollo-upload-server/-/apollo-upload-server-4.0.0-alpha.1.tgz",
"integrity": "sha512-uW0TtcSXDkOoJD6NlMwD4I4deMaZO61GpnouvCLiDRm4FwpeEVLVUVpSk4/s++La+TXXgzoKNb8ixfPwUAjiGw==",
"requires": {
"formidable": "1.1.1",
"mkdirp": "0.5.1",
"busboy": "0.2.14",
"object-path": "0.11.4"
}
},
@ -260,9 +259,9 @@
"dev": true
},
"binary-extensions": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.10.0.tgz",
"integrity": "sha1-muuabF6IY4qtFx4Wf1kAq+JINdA=",
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz",
"integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=",
"dev": true
},
"boxen": {
@ -307,6 +306,15 @@
"integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
"dev": true
},
"busboy": {
"version": "0.2.14",
"resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz",
"integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=",
"requires": {
"dicer": "0.2.5",
"readable-stream": "1.1.14"
}
},
"bytes": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
@ -480,6 +488,38 @@
"inherits": "2.0.3",
"readable-stream": "2.3.3",
"typedarray": "0.0.6"
},
"dependencies": {
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
"dev": true
},
"readable-stream": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
"integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
"dev": true,
"requires": {
"core-util-is": "1.0.2",
"inherits": "2.0.3",
"isarray": "1.0.0",
"process-nextick-args": "1.0.7",
"safe-buffer": "5.1.1",
"string_decoder": "1.0.3",
"util-deprecate": "1.0.2"
}
},
"string_decoder": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
"dev": true,
"requires": {
"safe-buffer": "5.1.1"
}
}
}
},
"configstore": {
@ -534,8 +574,7 @@
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
"dev": true
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"create-error-class": {
"version": "3.0.2",
@ -631,6 +670,15 @@
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
},
"dicer": {
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz",
"integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=",
"requires": {
"readable-stream": "1.1.14",
"streamsearch": "0.1.2"
}
},
"doctrine": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz",
@ -1097,11 +1145,6 @@
"for-in": "1.0.2"
}
},
"formidable": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/formidable/-/formidable-1.1.1.tgz",
"integrity": "sha1-lriIb3w8NQi5Mta9cMTTqI818ak="
},
"fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
@ -2075,9 +2118,9 @@
}
},
"global-dirs": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.0.tgz",
"integrity": "sha1-ENNAOeDfBCcuJizyQiT3IJQ0308=",
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
"integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=",
"dev": true,
"requires": {
"ini": "1.3.4"
@ -2309,7 +2352,7 @@
"integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
"dev": true,
"requires": {
"binary-extensions": "1.10.0"
"binary-extensions": "1.11.0"
}
},
"is-buffer": {
@ -2380,7 +2423,7 @@
"integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=",
"dev": true,
"requires": {
"global-dirs": "0.1.0",
"global-dirs": "0.1.1",
"is-path-inside": "1.0.0"
}
},
@ -3444,26 +3487,14 @@
}
},
"readable-stream": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
"integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
"dev": true,
"version": "1.1.14",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
"requires": {
"core-util-is": "1.0.2",
"inherits": "2.0.3",
"isarray": "1.0.0",
"process-nextick-args": "1.0.7",
"safe-buffer": "5.1.1",
"string_decoder": "1.0.3",
"util-deprecate": "1.0.2"
},
"dependencies": {
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
"dev": true
}
"isarray": "0.0.1",
"string_decoder": "0.10.31"
}
},
"readdirp": {
@ -3476,6 +3507,38 @@
"minimatch": "3.0.4",
"readable-stream": "2.3.3",
"set-immediate-shim": "1.0.1"
},
"dependencies": {
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
"dev": true
},
"readable-stream": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
"integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
"dev": true,
"requires": {
"core-util-is": "1.0.2",
"inherits": "2.0.3",
"isarray": "1.0.0",
"process-nextick-args": "1.0.7",
"safe-buffer": "5.1.1",
"string_decoder": "1.0.3",
"util-deprecate": "1.0.2"
}
},
"string_decoder": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
"dev": true,
"requires": {
"safe-buffer": "5.1.1"
}
}
}
},
"regex-cache": {
@ -3639,6 +3702,11 @@
"integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
"dev": true
},
"shortid": {
"version": "2.2.8",
"resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.8.tgz",
"integrity": "sha1-AzsRfWoul1gE9vCWnb59PQs1UTE="
},
"signal-exit": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
@ -3725,6 +3793,11 @@
"duplexer": "0.1.1"
}
},
"streamsearch": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz",
"integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo="
},
"string-width": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
@ -3736,13 +3809,9 @@
}
},
"string_decoder": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
"dev": true,
"requires": {
"safe-buffer": "5.1.1"
}
"version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
},
"strip-ansi": {
"version": "4.0.0",

View File

@ -7,7 +7,7 @@
},
"dependencies": {
"@std/esm": "^0.16.0",
"apollo-upload-server": "^2.0.4",
"apollo-upload-server": "^4.0.0-alpha.1",
"dotenv": "^4.0.0",
"graphql": "^0.11.7",
"graphql-server-koa": "^1.2.0",
@ -17,7 +17,9 @@
"koa-bodyparser": "^4.2.0",
"koa-compress": "^2.0.0",
"koa-router": "^7.3.0",
"lowdb": "^1.0.0"
"lowdb": "^1.0.0",
"mkdirp": "^0.5.1",
"shortid": "^2.2.8"
},
"devDependencies": {
"eslint": "^4.11.0",
@ -33,6 +35,7 @@
"dev": "nodemon --ext mjs",
"start": "node --require @std/esm --require dotenv/config server.mjs"
},
"@std/esm": "cjs",
"eslintConfig": {
"parserOptions": {
"sourceType": "module",

View File

@ -1,22 +1,51 @@
import low from 'lowdb'
import { createWriteStream } from 'fs'
import mkdirp from 'mkdirp'
import shortid from 'shortid'
import lowdb from 'lowdb'
import FileSync from 'lowdb/adapters/FileSync'
import { GraphQLUpload } from 'apollo-upload-server'
const db = low(new FileSync('db.json'))
const uploadDir = './uploads'
const db = lowdb(new FileSync('db.json'))
// Seed an empty DB
db.defaults({ uploads: [] }).write()
const saveFile = file =>
// Ensure upload directory exists
mkdirp.sync(uploadDir)
const storeUpload = async ({ stream, filename }) => {
const id = shortid.generate()
const path = `${uploadDir}/${id}-${filename}`
return new Promise((resolve, reject) => {
stream
.pipe(createWriteStream(path))
.on('finish', () => resolve({ id, path }))
.on('error', reject)
})
}
const recordFile = file =>
db
.get('uploads')
.push({ id: file.path, ...file })
.push(file)
.last()
.write()
const processUpload = async upload => {
const { stream, filename, mimetype, encoding } = await upload
const { id, path } = await storeUpload({ stream, filename })
return recordFile({ id, filename, mimetype, encoding, path })
}
export default {
Upload: GraphQLUpload,
Query: {
uploads: () => db.get('uploads').value()
},
Mutation: {
singleUpload: (_, { file }) => saveFile(file),
multipleUpload: (_, { files }) => Promise.all(files.map(saveFile))
singleUpload: (obj, { file }) => processUpload(file),
multipleUpload: (obj, { files }) => Promise.all(files.map(processUpload))
}
}

View File

@ -1,17 +1,12 @@
export default /* GraphQL */ `
type File {
id: String!
name: String!
type: String!
size: Int!
path: String!
}
scalar Upload
input Upload {
name: String!
type: String!
size: Int!
type File {
id: ID!
path: String!
filename: String!
mimetype: String!
encoding: String!
}
type Query {

View File

@ -3,9 +3,9 @@ import cors from 'kcors'
import compress from 'koa-compress'
import KoaRouter from 'koa-router'
import koaBody from 'koa-bodyparser'
import graphqlTools from 'graphql-tools'
import graphqlServerKoa from 'graphql-server-koa'
import apolloUploadServer from 'apollo-upload-server'
import { makeExecutableSchema } from 'graphql-tools'
import { graphqlKoa } from 'graphql-server-koa'
import { apolloUploadKoa } from 'apollo-upload-server'
import types from './schema.mjs'
import resolvers from './resolvers.mjs'
@ -22,9 +22,9 @@ server
router.post(
'/graphql',
koaBody(),
apolloUploadServer.apolloUploadKoa({ uploadDir: './uploads' }),
graphqlServerKoa.graphqlKoa({
schema: graphqlTools.makeExecutableSchema({ typeDefs: [types], resolvers })
apolloUploadKoa(),
graphqlKoa({
schema: makeExecutableSchema({ typeDefs: [types], resolvers })
})
)

View File

@ -22,9 +22,9 @@ export default graphql(gql`
mutation($files: [Upload!]!) {
multipleUpload(files: $files) {
id
name
type
size
filename
encoding
mimetype
path
}
}

View File

@ -22,9 +22,9 @@ export default graphql(gql`
mutation($file: Upload!) {
singleUpload(file: $file) {
id
name
type
size
filename
encoding
mimetype
path
}
}

View File

@ -6,17 +6,17 @@ const UploadList = ({ data: { uploads = [] } }) => (
<Table
thead={
<tr>
<Head>Name</Head>
<Head>Type</Head>
<Head>Size</Head>
<Head>Filename</Head>
<Head>MIME type</Head>
<Head>Encoding</Head>
<Head>Path</Head>
</tr>
}
tbody={uploads.map(({ id, name, type, size, path }) => (
tbody={uploads.map(({ id, filename, mimetype, encoding, path }) => (
<tr key={id}>
<Cell>{name}</Cell>
<Cell>{type}</Cell>
<Cell>{size}</Cell>
<Cell>{filename}</Cell>
<Cell>{mimetype}</Cell>
<Cell>{encoding}</Cell>
<Cell>{path}</Cell>
</tr>
))}

20
app/package-lock.json generated
View File

@ -424,9 +424,9 @@
"integrity": "sha512-ECzXORE+fk+kjf+zOugcfaa9Tf/mX+vpNZa+oVAuKhzmRaWST3wsm6TUNfQOx25mF4g3ocw0Kv2OIa921TSKIw=="
},
"apollo-upload-client": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/apollo-upload-client/-/apollo-upload-client-6.0.2.tgz",
"integrity": "sha512-PMyc29yVohy53YDq9jE50hm50dbwqnjGDHcZonq7gml0jSfUGSuJPbJ26U4xpLLpq5a26GU7w2ICpicGrZe3Bw==",
"version": "7.0.0-alpha.1",
"resolved": "https://registry.npmjs.org/apollo-upload-client/-/apollo-upload-client-7.0.0-alpha.1.tgz",
"integrity": "sha512-eNWzl3VWjjLuZLsrX0UcuG+AscPabvoF874aWg9D9QoumyFMrdGA9E2Ol3kFbgDsY/wD+8DtkRPKwcGVfL854w==",
"requires": {
"@babel/polyfill": "7.0.0-beta.32",
"@babel/runtime": "7.0.0-beta.32",
@ -1362,9 +1362,9 @@
"integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q=="
},
"binary-extensions": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.10.0.tgz",
"integrity": "sha1-muuabF6IY4qtFx4Wf1kAq+JINdA="
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz",
"integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU="
},
"bl": {
"version": "1.1.2",
@ -2689,9 +2689,9 @@
}
},
"eslint-plugin-react": {
"version": "7.4.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.4.0.tgz",
"integrity": "sha512-tvjU9u3VqmW2vVuYnE8Qptq+6ji4JltjOjJ9u7VAOxVYkUkyBZWRvNYKbDv5fN+L6wiA+4we9+qQahZ0m63XEA==",
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.5.0.tgz",
"integrity": "sha512-swd5j/3Fp+xa9I/HOIKLWuEzBqVX2GlWp6g63hpP/BToaA43qYTEi2Hg+BfYz4WdOBCoDNh9NMBZ45DqW6sWpQ==",
"dev": true,
"requires": {
"doctrine": "2.0.0",
@ -4626,7 +4626,7 @@
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
"integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
"requires": {
"binary-extensions": "1.10.0"
"binary-extensions": "1.11.0"
}
},
"is-buffer": {

View File

@ -6,10 +6,10 @@
"npm": ">=5.4"
},
"dependencies": {
"apollo-cache-inmemory": "^1.0.0",
"apollo-cache-inmemory": "1.0.0",
"apollo-client": "^2.0.3",
"apollo-link": "^1.0.3",
"apollo-upload-client": "^6.0.2",
"apollo-upload-client": "^7.0.0-alpha.1",
"babel-plugin-transform-inline-environment-variables": "^0.2.0",
"dotenv-cli": "^1.4.0",
"graphql": "^0.11.7",
@ -28,7 +28,7 @@
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-node": "^5.2.1",
"eslint-plugin-prettier": "^2.3.1",
"eslint-plugin-react": "^7.4.0",
"eslint-plugin-react": "^7.5.0",
"prettier": "^1.8.2"
},
"scripts": {

View File

@ -4,9 +4,9 @@ export default gql`
query uploads {
uploads {
id
name
type
size
filename
encoding
mimetype
path
}
}