This repository has been archived by the owner on Nov 26, 2024. It is now read-only.
forked from cdaringe/postgraphile-upsert
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 7fd625a
Showing
12 changed files
with
5,683 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
node_modules | ||
*.log | ||
build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
{ | ||
// Use IntelliSense to learn about possible attributes. | ||
// Hover to view descriptions of existing attributes. | ||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | ||
"version": "0.2.0", | ||
"configurations": [ | ||
{ | ||
"type": "node", | ||
"request": "launch", | ||
"name": "ava - file", | ||
"program": "${workspaceRoot}/node_modules/ava/profile.js", | ||
"args": [ | ||
"${workspaceRoot}/build/__tests__/main.test.js" | ||
// "${file}" | ||
], | ||
"skipFiles": [ | ||
"<node_internals>/**/*.js" | ||
], | ||
"console": "externalTerminal", | ||
"env": { | ||
"DEBUG": "*" | ||
} | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"emeraldwalk.runonsave": { | ||
"autoClearConsole": true, | ||
"commands": [ | ||
{ | ||
"match": "\\.ts$", | ||
"cmd": "npx prettier-standard ${file}" | ||
} | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
{ | ||
"name": "postgraphile-upsert", | ||
"version": "0.0.0-development", | ||
"main": "build/postgraphile-upsert.js", | ||
"files": [ | ||
"build/postgraphile-upsert.js" | ||
], | ||
"engines": { | ||
"node": ">=8" | ||
}, | ||
"author": "cdaringe <[email protected]>", | ||
"license": "MIT", | ||
"devDependencies": { | ||
"@types/bluebird": "^3.5.24", | ||
"@types/dockerode": "^2.5.9", | ||
"@types/execa": "^0.9.0", | ||
"@types/nanographql": "^2.0.1", | ||
"@types/pg": "^7.4.11", | ||
"ava": "1.0.0-rc.2", | ||
"bluebird": "^3.5.3", | ||
"dockerode": "^2.5.7", | ||
"execa": "^1.0.0", | ||
"freeport": "^1.0.5", | ||
"husky": "^1.2.0", | ||
"lint-staged": "^8.1.0", | ||
"nanographql": "^2.0.0", | ||
"node-fetch": "^2.3.0", | ||
"pg": "^7.6.1", | ||
"postgraphile": "^4.0.1", | ||
"postgraphile-core": "4.1.0-rc.0", | ||
"prettier-standard": "^8.0.1", | ||
"typescript": "^3.1.6", | ||
"semantic-release": "^15.12.1" | ||
}, | ||
"scripts": { | ||
"build": "tsc", | ||
"format": "prettier-standard '{src,test,scripts}/**/*.{js,jsx,ts,tsx}'", | ||
"test": "ava build/**/*.test.js", | ||
"semantic-release": "semantic-release" | ||
}, | ||
"husky": { | ||
"hooks": { | ||
"pre-commit": "lint-staged" | ||
} | ||
}, | ||
"lint-staged": { | ||
"linters": { | ||
"{src,test,scripts}/**/*.{js,jsx,ts,tsx}": [ | ||
"yarn format", | ||
"git add" | ||
] | ||
} | ||
}, | ||
"ava": { | ||
"babel": false, | ||
"compileEnhancements": false | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/cdaringe/postgraphile-upsert.git" | ||
} | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { Pool } from 'pg' | ||
import { DbContextDbConfig } from './db' | ||
|
||
export async function createPool (config: DbContextDbConfig) { | ||
const client = new Pool({ | ||
user: config.username, | ||
host: 'localhost', | ||
...config | ||
}) | ||
await client.connect() | ||
return client | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import { freeport } from './freeport' | ||
import Docker from 'dockerode' | ||
import execa from 'execa' | ||
|
||
const DB_IMAGE = 'postgres:11-alpine' | ||
|
||
export interface DbContextDbConfig { | ||
port: number | ||
username: 'postgres' | ||
password: 'postgres' | ||
database: 'postgres' | ||
} | ||
|
||
export interface DbContext { | ||
dbContainer: Docker.Container | ||
dbConfig: DbContextDbConfig | ||
} | ||
|
||
const containers = new Set() | ||
const docker = new Docker({ socketPath: '/var/run/docker.sock' }) | ||
|
||
export async function imageExists (imageName: string) { | ||
try { | ||
await execa('docker', ['image', 'inspect', imageName]) | ||
return true | ||
} catch (err) { | ||
// @TODO this is fragile, but dockerode is being a PIA | ||
return false | ||
} | ||
} | ||
|
||
export async function purgeContainer (container: Docker.Container) { | ||
try { | ||
await container.kill() | ||
} finally { | ||
containers.delete(container) | ||
try { | ||
await container.remove({ force: true }) | ||
} catch (err) { | ||
// if 404, we probably used the --rm flag on container launch. it's all good. | ||
if (err.statusCode !== 404 && err.statusCode !== 409) throw err | ||
} | ||
} | ||
} | ||
|
||
export const container = { | ||
async setup (ctx: any) { | ||
const port = await freeport() | ||
if (!await imageExists(DB_IMAGE)) await execa('docker', ['pull', DB_IMAGE]) | ||
const container = await docker.createContainer({ | ||
Image: DB_IMAGE, | ||
ExposedPorts: { | ||
'5432/tcp': {} | ||
}, | ||
HostConfig: { | ||
AutoRemove: true, | ||
PortBindings: { '5432/tcp': [{ HostPort: port.toString() }] } | ||
} | ||
}) | ||
await container.start() | ||
containers.add(container) | ||
ctx.dbContainer = container | ||
const dbConfig: Partial<DbContextDbConfig> = { | ||
port, | ||
username: 'postgres', | ||
password: 'postgres', | ||
database: 'postgres' | ||
} | ||
ctx.dbConfig = dbConfig as DbContextDbConfig | ||
}, | ||
async teardown (ctx: DbContext) { | ||
const container: Docker.Container = ctx.dbContainer | ||
if (!container) { | ||
throw new Error('attempted to kill container, but missing from context') | ||
} | ||
await purgeContainer(container) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import { promisify } from 'util' | ||
const freeportCb = require('freeport') | ||
export const freeport = promisify(freeportCb) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
import { container, DbContext } from './fixture/db' | ||
import { createPool } from './fixture/client' | ||
import { createServer, Server } from 'http' | ||
import { freeport } from './fixture/freeport' | ||
import { PgMutationUpsertPlugin } from '../postgraphile-upsert' | ||
import { Pool } from 'pg' | ||
import { postgraphile } from 'postgraphile' | ||
import ava, { TestInterface } from 'ava' | ||
import bluebird from 'bluebird' | ||
import nanographql = require('nanographql') | ||
|
||
const fetch = require('node-fetch') | ||
|
||
const test = ava as TestInterface< | ||
DbContext & { | ||
client: Pool | ||
server: Server | ||
serverPort: number | ||
} | ||
> | ||
|
||
test.beforeEach(async t => { | ||
await container.setup(t.context) | ||
await bluebird.delay(5000) | ||
t.context.client = await createPool(t.context.dbConfig) | ||
t.context.client.on('error', err => {}) | ||
await t.context.client.query(` | ||
create table bikes ( | ||
id serial, | ||
weight real, | ||
make varchar, | ||
model varchar, | ||
primary key (id) | ||
) | ||
`) | ||
const middleware = postgraphile(t.context.client, 'public', { | ||
graphiql: true, | ||
appendPlugins: [PgMutationUpsertPlugin as any] | ||
}) | ||
const serverPort = await freeport() | ||
t.context.serverPort = serverPort | ||
t.context.server = createServer(middleware).listen(serverPort) | ||
}) | ||
|
||
test.afterEach(async t => { | ||
t.context.client.end() | ||
t.context.server.close() | ||
await container.teardown(t.context) | ||
}) | ||
|
||
const all = async t => { | ||
const query = nanographql` | ||
query { | ||
allBikes { | ||
edges { | ||
node { | ||
id | ||
make | ||
model | ||
} | ||
} | ||
} | ||
} | ||
` | ||
const res = await fetch(`http://localhost:${t.context.serverPort}/graphql`, { | ||
body: query(), | ||
headers: { | ||
'Content-Type': 'application/json' | ||
}, | ||
method: 'POST' | ||
}) | ||
return res.json() | ||
} | ||
|
||
const create = async t => { | ||
const query = nanographql` | ||
mutation { | ||
upsertBike(input: { | ||
bike: { | ||
weight: 25.6 | ||
make: "kona" | ||
model: "cool-ie deluxe" | ||
} | ||
}) { | ||
clientMutationId | ||
} | ||
} | ||
` | ||
await fetch(`http://localhost:${t.context.serverPort}/graphql`, { | ||
body: query(), | ||
headers: { | ||
'Content-Type': 'application/json' | ||
}, | ||
method: 'POST' | ||
}) | ||
} | ||
|
||
test('test upsert crud', async t => { | ||
await create(t) | ||
const res = await all(t) | ||
t.is(res.data.allBikes.edges.length, 1) | ||
t.is(res.data.allBikes.edges[0].node.make, 'kona') | ||
}) |
Oops, something went wrong.