Skip to content
Merged
10 changes: 0 additions & 10 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,6 @@ module.exports = {
trailingComma: "es5",
},
],
"comma-dangle": [
2,
{
arrays: "always-multiline",
objects: "always-multiline",
imports: "always-multiline",
exports: "always-multiline",
functions: "never",
},
],
"no-confusing-arrow": 0,
"no-else-return": 0,
"no-underscore-dangle": 0,
Expand Down
2 changes: 1 addition & 1 deletion packages/graphile-build-pg/src/QueryBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ class QueryBuilder {
// https://github.com/graphql/graphql-js/blob/680685dd14bd52c6475305e150e5f295ead2aa7e/src/language/lexer.js#L551-L581
//
// so this should not cause any issues in practice.
if (/^(@+|[_A-Za-z])[_0-9A-Za-z]*$/.test(alias) !== true) {
if (/^(\$+|@+|[_A-Za-z])[_0-9A-Za-z]*$/.test(alias) !== true) {
throw new Error(`Disallowed alias '${alias}'.`);
}
}
Expand Down
16 changes: 10 additions & 6 deletions packages/graphile-utils/__tests__/ExtendSchemaPlugin-pg.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ it("allows adding a custom single field to PG schema", async () => {
expect(data.randomUser.name).toBeTruthy();
expect(data.randomUser.email).toBeTruthy();
} finally {
pgClient.release();
await pgClient.release();
}
});

Expand Down Expand Up @@ -194,7 +194,7 @@ it("allows adding a simple mutation field to PG schema", async () => {
Mutation: {
async registerUser(_query, args, context, resolveInfo) {
const { pgClient } = context;
await pgClient.query("begin");
await pgClient.query("SAVEPOINT graphql_mutation");
try {
const {
rows: [user],
Expand All @@ -218,12 +218,14 @@ it("allows adding a simple mutation field to PG schema", async () => {
`You're user ${user.id} - thanks for being awesome`
);

await pgClient.query("commit");
await pgClient.query("RELEASE SAVEPOINT graphql_mutation");
return {
data: row,
};
} catch (e) {
await pgClient.query("rollback");
await pgClient.query(
"ROLLBACK TO SAVEPOINT graphql_mutation"
);
throw e;
}
},
Expand All @@ -236,6 +238,7 @@ it("allows adding a simple mutation field to PG schema", async () => {
const printedSchema = printSchema(schema);
expect(printedSchema).toMatchSnapshot();
const pgClient = await pgPool.connect();
await pgClient.query("begin");
try {
const { data, errors } = await graphql(
schema,
Expand Down Expand Up @@ -282,7 +285,8 @@ it("allows adding a simple mutation field to PG schema", async () => {
expect(data.user1.user.id).not.toEqual(data.user2.user.id);
expect(clean(data)).toMatchSnapshot();
} finally {
pgClient.release();
await pgClient.query("rollback");
await pgClient.release();
}
});

Expand Down Expand Up @@ -332,6 +336,6 @@ it("allows adding a field to an existing table, and requesting necessary data al
`User 1 fetched (name: Alice) [{"number_int":1,"string_text":"hi"},{"number_int":2,"string_text":"bye"}]`
);
} finally {
pgClient.release();
await pgClient.release();
}
});
172 changes: 172 additions & 0 deletions packages/graphile-utils/__tests__/makeWrapResolversPlugin-pg.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import { makeWrapResolversPlugin, makeChangeNullabilityPlugin } from "../";
import { graphql } from "graphql";
import { createPostGraphileSchema } from "postgraphile-core";
import pg from "pg";

let pgPool;

beforeAll(() => {
pgPool = new pg.Pool({
connectionString: process.env.TEST_DATABASE_URL,
});
});

afterAll(() => {
if (pgPool) {
pgPool.end();
pgPool = null;
}
});

const makeSchemaWithPlugins = plugins =>
createPostGraphileSchema(pgPool, ["a"], {
appendPlugins: plugins,
});

it("requests the required sibling columns", async () => {
const schema = await makeSchemaWithPlugins([
makeChangeNullabilityPlugin({
User: {
email: true,
},
}),
makeWrapResolversPlugin({
User: {
email: {
requires: {
siblingColumns: [{ column: "id", alias: "$user_id" }],
},
resolve(resolver, user, args, context, _resolveInfo) {
if (context.jwtClaims.user_id !== user.$user_id) {
return null; // Don't allow users to see other users' emails
}
return resolver();
},
},
},
}),
]);
const pgClient = await pgPool.connect();
await pgClient.query("begin");
try {
const result = await graphql(
schema,
`
{
allUsers {
nodes {
nodeId
id
email
}
}
}
`,
null,
{
pgClient,
jwtClaims: {
user_id: 2,
},
}
);
expect(result.errors).toBeFalsy();
result.data.allUsers.nodes.forEach(user => {
if (user.id === 2) {
expect(user.email).not.toBeNull();
} else {
expect(user.email).toBeNull();
}
});
expect(result.data).toMatchInlineSnapshot(`
Object {
"allUsers": Object {
"nodes": Array [
Object {
"email": null,
"id": 1,
"nodeId": "WyJ1c2VycyIsMV0=",
},
Object {
"email": "bob@example.com",
"id": 2,
"nodeId": "WyJ1c2VycyIsMl0=",
},
Object {
"email": null,
"id": 3,
"nodeId": "WyJ1c2VycyIsM10=",
},
],
},
}
`);
} finally {
await pgClient.query("rollback");
await pgClient.release();
}
});

it("requests the required child columns", async () => {
let newUserId;
const schema = await makeSchemaWithPlugins([
makeWrapResolversPlugin({
Mutation: {
createUser: {
requires: {
childColumns: [{ column: "id", alias: "$new_id" }],
},
async resolve(resolver, mutation, args, _context, _resolveInfo) {
const {
input: {
user: { name },
},
} = args;
if (name.length < 3) throw new Error("Name is too short");
const result = await resolver();
const { data: user } = result;
newUserId = user.$new_id;
return result;
},
},
},
}),
]);
const pgClient = await pgPool.connect();
await pgClient.query("begin");
try {
const result = await graphql(
schema,
`
mutation {
createUser(
input: { user: { name: "Bobby Tables", email: "drop@table.plz" } }
) {
user {
nodeId
id
name
email
}
}
}
`,
null,
{
pgClient,
jwtClaims: {
user_id: 2,
},
}
);
expect(result.errors).toBeFalsy();
expect(result.data.createUser).toBeTruthy();
expect(newUserId).not.toBeUndefined();
const { user } = result.data.createUser;
expect(user.id).toEqual(newUserId);
expect(user.name).toEqual("Bobby Tables");
} finally {
await pgClient.query("rollback");
await pgClient.release();
}
});
Loading