test: migrate server to typescript
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env node
|
||||
'use strict'
|
||||
|
||||
import './src/index.mjs'
|
||||
import './dist/index.js'
|
||||
|
||||
@@ -5,6 +5,11 @@
|
||||
"bin": {
|
||||
"test-server": "./bin.mjs"
|
||||
},
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "tsc -d",
|
||||
"prepare": "pnpm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@apollo/server": "^4.7.3",
|
||||
"@graphql-tools/schema": "^10.0.0",
|
||||
@@ -19,6 +24,11 @@
|
||||
"ws": "^8.13.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/shortid": "^0.0.29"
|
||||
"@types/body-parser": "^1.19.2",
|
||||
"@types/cors": "^2.8.13",
|
||||
"@types/express": "^4.17.17",
|
||||
"@types/shortid": "^0.0.29",
|
||||
"@types/ws": "^8.5.5",
|
||||
"typescript": "^4.7.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
export let channels = []
|
||||
|
||||
export function resetDatabase () {
|
||||
channels = [
|
||||
{
|
||||
id: 'general',
|
||||
label: 'General',
|
||||
messages: [],
|
||||
},
|
||||
{
|
||||
id: 'random',
|
||||
label: 'Random',
|
||||
messages: [],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
resetDatabase()
|
||||
@@ -0,0 +1,30 @@
|
||||
export interface Channel {
|
||||
id: string
|
||||
label: string
|
||||
messages: Message[]
|
||||
}
|
||||
|
||||
export interface Message {
|
||||
id: string
|
||||
channel: Channel
|
||||
text: string
|
||||
}
|
||||
|
||||
export let channels: Channel[] = []
|
||||
|
||||
export function resetDatabase (): void {
|
||||
channels = [
|
||||
{
|
||||
id: 'general',
|
||||
label: 'General',
|
||||
messages: [],
|
||||
},
|
||||
{
|
||||
id: 'random',
|
||||
label: 'Random',
|
||||
messages: [],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
resetDatabase()
|
||||
@@ -6,12 +6,15 @@ import { ApolloServer } from '@apollo/server'
|
||||
import { expressMiddleware } from '@apollo/server/express4'
|
||||
import { WebSocketServer } from 'ws'
|
||||
import { useServer } from 'graphql-ws/lib/use/ws'
|
||||
import { schema } from './schema.mjs'
|
||||
import { resetDatabase } from './data.mjs'
|
||||
import { schema } from './schema.js'
|
||||
import { resetDatabase } from './data.js'
|
||||
import { simulateLatency } from './util.js'
|
||||
|
||||
const app = express()
|
||||
|
||||
app.use(cors('*'))
|
||||
app.use(cors({
|
||||
origin: '*',
|
||||
}))
|
||||
|
||||
app.use(bodyParser.json())
|
||||
|
||||
@@ -22,9 +25,6 @@ app.get('/_reset', (req, res) => {
|
||||
|
||||
const server = new ApolloServer({
|
||||
schema,
|
||||
context: () => new Promise(resolve => {
|
||||
setTimeout(() => resolve({}), 50)
|
||||
}),
|
||||
plugins: [
|
||||
// Proper shutdown for the WebSocket server.
|
||||
{
|
||||
@@ -42,7 +42,12 @@ const server = new ApolloServer({
|
||||
|
||||
await server.start()
|
||||
|
||||
app.use('/graphql', expressMiddleware(server))
|
||||
app.use('/graphql', expressMiddleware(server, {
|
||||
context: async () => {
|
||||
await simulateLatency()
|
||||
return {}
|
||||
},
|
||||
}))
|
||||
|
||||
const httpServer = createServer(app)
|
||||
|
||||
@@ -2,8 +2,8 @@ import { makeExecutableSchema } from '@graphql-tools/schema'
|
||||
import { PubSub, withFilter } from 'graphql-subscriptions'
|
||||
import shortid from 'shortid'
|
||||
import gql from 'graphql-tag'
|
||||
import { channels } from './data.mjs'
|
||||
import { simulateLatency, GraphQLErrorWithCode } from './util.mjs'
|
||||
import { channels } from './data.js'
|
||||
import { GraphQLErrorWithCode } from './util.js'
|
||||
|
||||
const pubsub = new PubSub()
|
||||
|
||||
@@ -51,21 +51,31 @@ type Subscription {
|
||||
}
|
||||
`
|
||||
|
||||
interface AddMessageInput {
|
||||
channelId: string
|
||||
text: string
|
||||
}
|
||||
|
||||
interface UpdateMessageInput {
|
||||
id: string
|
||||
channelId: string
|
||||
text: string
|
||||
}
|
||||
|
||||
const resolvers = {
|
||||
Query: {
|
||||
hello: () => simulateLatency().then(() => 'Hello world!'),
|
||||
channels: () => simulateLatency().then(() => channels),
|
||||
channel: (root, { id }) => simulateLatency().then(() => channels.find(c => c.id === id)),
|
||||
list: () => simulateLatency().then(() => ['a', 'b', 'c']),
|
||||
good: () => simulateLatency().then(() => 'good'),
|
||||
hello: () => 'Hello world!',
|
||||
channels: () => channels,
|
||||
channel: (root: any, { id }: { id: string }) => channels.find(c => c.id === id),
|
||||
list: () => ['a', 'b', 'c'],
|
||||
good: () => 'good',
|
||||
bad: async () => {
|
||||
await simulateLatency()
|
||||
throw new Error('An error')
|
||||
},
|
||||
},
|
||||
|
||||
Mutation: {
|
||||
addMessage: (root, { input }) => {
|
||||
addMessage: (root: any, { input }: { input: AddMessageInput }) => {
|
||||
const channel = channels.find(c => c.id === input.channelId)
|
||||
if (!channel) {
|
||||
throw new GraphQLErrorWithCode(`Channel ${input.channelId} not found`, 'not-found')
|
||||
@@ -80,12 +90,15 @@ const resolvers = {
|
||||
return message
|
||||
},
|
||||
|
||||
updateMessage: (root, { input }) => {
|
||||
updateMessage: (root: any, { input }: { input: UpdateMessageInput }) => {
|
||||
const channel = channels.find(c => c.id === input.channelId)
|
||||
if (!channel) {
|
||||
throw new GraphQLErrorWithCode(`Channel ${input.channelId} not found`, 'not-found')
|
||||
}
|
||||
const message = channel.messages.find(m => m.id === input.id)
|
||||
if (!message) {
|
||||
throw new GraphQLErrorWithCode(`Message ${input.id} not found`, 'not-found')
|
||||
}
|
||||
Object.assign(message, {
|
||||
text: input.text,
|
||||
})
|
||||
@@ -1,4 +1,4 @@
|
||||
import { GraphQLError } from 'graphql'
|
||||
import { GraphQLError, GraphQLErrorExtensions } from 'graphql'
|
||||
|
||||
const shouldSimulateLatency = process.argv.includes('--simulate-latency')
|
||||
|
||||
@@ -11,7 +11,7 @@ if (shouldSimulateLatency) {
|
||||
}
|
||||
|
||||
export function simulateLatency () {
|
||||
return new Promise(resolve => {
|
||||
return new Promise<void>(resolve => {
|
||||
if (shouldSimulateLatency) {
|
||||
setTimeout(resolve, latency)
|
||||
} else {
|
||||
@@ -21,8 +21,8 @@ export function simulateLatency () {
|
||||
}
|
||||
|
||||
export class GraphQLErrorWithCode extends GraphQLError {
|
||||
constructor (message, code, extensions) {
|
||||
super(message, {
|
||||
constructor (message: string, code: string, extensions?: GraphQLErrorExtensions) {
|
||||
super(message, null, null, null, null, null, {
|
||||
extensions: {
|
||||
code,
|
||||
...extensions,
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"module": "esnext",
|
||||
"strict": true,
|
||||
"importHelpers": true,
|
||||
"moduleResolution": "node",
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"sourceMap": true,
|
||||
"lib": [
|
||||
"esnext"
|
||||
],
|
||||
"outDir": "dist",
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
Generated
+32
-4
@@ -279,9 +279,24 @@ importers:
|
||||
specifier: ^8.13.0
|
||||
version: 8.13.0
|
||||
devDependencies:
|
||||
'@types/body-parser':
|
||||
specifier: ^1.19.2
|
||||
version: 1.19.2
|
||||
'@types/cors':
|
||||
specifier: ^2.8.13
|
||||
version: 2.8.13
|
||||
'@types/express':
|
||||
specifier: ^4.17.17
|
||||
version: 4.17.17
|
||||
'@types/shortid':
|
||||
specifier: ^0.0.29
|
||||
version: 0.0.29
|
||||
'@types/ws':
|
||||
specifier: ^8.5.5
|
||||
version: 8.5.5
|
||||
typescript:
|
||||
specifier: ^4.7.4
|
||||
version: 4.9.5
|
||||
|
||||
packages/vue-apollo-components:
|
||||
dependencies:
|
||||
@@ -2800,6 +2815,13 @@ packages:
|
||||
dependencies:
|
||||
'@types/connect': 3.4.35
|
||||
'@types/node': 18.14.0
|
||||
dev: false
|
||||
|
||||
/@types/body-parser@1.19.2:
|
||||
resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==}
|
||||
dependencies:
|
||||
'@types/connect': 3.4.35
|
||||
'@types/node': 18.14.0
|
||||
|
||||
/@types/bonjour@3.5.10:
|
||||
resolution: {integrity: sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==}
|
||||
@@ -2836,6 +2858,12 @@ packages:
|
||||
resolution: {integrity: sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ==}
|
||||
dev: false
|
||||
|
||||
/@types/cors@2.8.13:
|
||||
resolution: {integrity: sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==}
|
||||
dependencies:
|
||||
'@types/node': 18.14.0
|
||||
dev: true
|
||||
|
||||
/@types/eslint-scope@3.7.4:
|
||||
resolution: {integrity: sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==}
|
||||
dependencies:
|
||||
@@ -2868,7 +2896,7 @@ packages:
|
||||
/@types/express@4.17.17:
|
||||
resolution: {integrity: sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==}
|
||||
dependencies:
|
||||
'@types/body-parser': 1.19.0
|
||||
'@types/body-parser': 1.19.2
|
||||
'@types/express-serve-static-core': 4.17.33
|
||||
'@types/qs': 6.9.7
|
||||
'@types/serve-static': 1.15.0
|
||||
@@ -3069,8 +3097,8 @@ packages:
|
||||
'@types/node': 18.14.0
|
||||
dev: false
|
||||
|
||||
/@types/ws@8.5.4:
|
||||
resolution: {integrity: sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==}
|
||||
/@types/ws@8.5.5:
|
||||
resolution: {integrity: sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==}
|
||||
dependencies:
|
||||
'@types/node': 18.14.0
|
||||
dev: true
|
||||
@@ -14036,7 +14064,7 @@ packages:
|
||||
'@types/serve-index': 1.9.1
|
||||
'@types/serve-static': 1.15.0
|
||||
'@types/sockjs': 0.3.33
|
||||
'@types/ws': 8.5.4
|
||||
'@types/ws': 8.5.5
|
||||
ansi-html-community: 0.0.8
|
||||
bonjour-service: 1.1.0
|
||||
chokidar: 3.5.3
|
||||
|
||||
Reference in New Issue
Block a user