Skip to content

Commit

Permalink
Add EXPORTABLE methods for schema export support (#202)
Browse files Browse the repository at this point in the history
  • Loading branch information
benjie committed Jan 5, 2024
2 parents ce40268 + ff53836 commit 8f6c590
Show file tree
Hide file tree
Showing 16 changed files with 4,099 additions and 1,532 deletions.
40 changes: 38 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,55 @@
module.exports = {
root: true,
parser: "@typescript-eslint/parser",
parser: "@babel/eslint-parser",
parserOptions: {
sourceType: "module",
},
env: {
jest: true,
node: true,
es6: true,
"jest/globals": true,
},
plugins: ["@typescript-eslint", "jest"],
plugins: [
"@typescript-eslint",
"jest",
//"tsdoc",
//"simple-import-sort",
//"import",
"graphile-export",
],
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
// "plugin:import/errors",
// "plugin:import/typescript",
"plugin:graphile-export/recommended",
"plugin:jest/recommended",
"prettier",
],
rules: {
"jest/expect-expect": ["off"],
"no-fallthrough": ["error", { allowEmptyCase: true }],
"@typescript-eslint/no-var-requires": ["off"],
"@typescript-eslint/no-explicit-any": ["off"],
// We need this for our `GraphileBuild`/`GraphileConfig`/etc namespaces
"@typescript-eslint/no-namespace": "off",
"@typescript-eslint/no-unused-vars": [
"warn",
{
argsIgnorePattern: "^_",
varsIgnorePattern: "^_",
args: "after-used",
ignoreRestSiblings: true,
},
],
},
overrides: [
// Rules for TypeScript only
{
files: ["*.ts", "*.tsx"],
parser: "@typescript-eslint/parser",
},
],
};
3 changes: 1 addition & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: Node CI

on: push
on: [push, pull_request]

jobs:
lint:
Expand Down Expand Up @@ -51,7 +51,6 @@ jobs:
- 14
- 15
node-version:
- 14.x
- 16.x
- 18.x

Expand Down
57 changes: 50 additions & 7 deletions __tests__/customOperatorsPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,72 @@ const CustomOperatorsPlugin: GraphileConfig.Plugin = {
sql,
graphql: { GraphQLInt, GraphQLBoolean },
addConnectionFilterOperator,
EXPORTABLE,
} = build;

// simple
addConnectionFilterOperator("InternetAddress", "familyEqualTo", {
description: "Address family equal to specified value.",
resolveInputCodec: () => TYPES.int,
resolve: (i, v) => sql.fragment`family(${i}) = ${v}`,
resolveInputCodec: EXPORTABLE(
(TYPES) =>
function () {
return TYPES.int;
},
[TYPES]
),
resolve: EXPORTABLE(
(sql) =>
function (i, v) {
return sql.fragment`family(${i}) = ${v}`;
},
[sql]
),
});

// using resolveSqlIdentifier
addConnectionFilterOperator("InternetAddress", "familyNotEqualTo", {
description: "Address family equal to specified value.",
resolveInputCodec: () => TYPES.int,
resolve: (i, v) => sql.fragment`${i} <> ${v}`,
resolveSqlIdentifier: (i) => [sql.fragment`family(${i})`, TYPES.int],
resolveInputCodec: EXPORTABLE(
(TYPES) =>
function () {
return TYPES.int;
},
[TYPES]
),
resolve: EXPORTABLE(
(sql) =>
function (i, v) {
return sql.fragment`${i} <> ${v}`;
},
[sql]
),
resolveSqlIdentifier: EXPORTABLE(
(TYPES, sql) =>
function (i) {
return [sql.fragment`family(${i})`, TYPES.int];
},
[TYPES, sql]
),
});

// using resolveInput // typeNames: string | string[]
addConnectionFilterOperator(["InternetAddress"], "isV4", {
description: "Address family equal to specified value.",
resolve: (i, v) => sql.fragment`family(${i}) = ${v}`,
resolve: EXPORTABLE(
(sql) =>
function (i, v) {
return sql.fragment`family(${i}) = ${v}`;
},
[sql]
),
resolveInput: (input) => (input === true ? 4 : 6),
resolveInputCodec: () => TYPES.int,
resolveInputCodec: EXPORTABLE(
(TYPES) =>
function () {
return TYPES.int;
},
[TYPES]
),
resolveType: () => GraphQLBoolean,
});

Expand Down
126 changes: 94 additions & 32 deletions __tests__/integration/queries.test.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,38 @@
import * as fs from "fs";
import * as path from "path";
import * as pg from "pg";

import { promisify } from "util";
import { ExecutionArgs, parse, validate } from "graphql";
import {
ExecutionArgs,
GraphQLError,
GraphQLSchema,
parse,
validate,
} from "graphql";
import { withPgClient, withPgPool } from "../helpers";
import { PgConditionArgumentPlugin } from "graphile-build-pg";
import { postgraphilePresetAmber } from "postgraphile/presets/amber";
import { makeV4Preset, V4Options } from "postgraphile/presets/v4";
import { makeSchema } from "postgraphile";
import { PostGraphileConnectionFilterPreset } from "../../src/index";
import CustomOperatorsPlugin from "./../customOperatorsPlugin";
import { execute, hookArgs } from "grafast";
import { execute, hookArgs, isSafeError } from "grafast";
import { SchemaResult } from "graphile-build";
import { makeWithPgClientViaPgClientAlreadyInTransaction } from "@dataplan/pg/adaptors/pg";
import { exportSchemaAsString } from "graphile-export";
import { importFromStringSync } from "module-from-string";

// TODO: remove this once Grafast gets it's planning under control :D
jest.setTimeout(30000);
jest.setTimeout(300000);

const vmEval = (code: string) => {
const { schema } = importFromStringSync(code, {
transformOptions: { loader: "js" },
useCurrentGlobal: true,
});
return schema as GraphQLSchema;
};

const createPostGraphileSchema = async (
pool: pg.Pool,
Expand Down Expand Up @@ -44,7 +61,23 @@ const createPostGraphileSchema = async (
],
};
const params = await makeSchema(preset);
return params;
if (process.env.TEST_EXPORTED_SCHEMA) {
return {
...params,
schema: vmEval(
(
await exportSchemaAsString(params.schema, {
mode: "graphql-js",
// or:
// mode: "typeDefs",
modules: {},
})
).code
),
};
} else {
return params;
}
};

const readFile = promisify(fs.readFile);
Expand Down Expand Up @@ -91,36 +124,66 @@ beforeAll(async () => {
nullAndEmptyAllowed,
addConnectionFilterOperator,
] = await Promise.all([
createPostGraphileSchema(pool, ["p"], {
skipPlugins: [PgConditionArgumentPlugin],
}),
createPostGraphileSchema(pool, ["p"], {
skipPlugins: [PgConditionArgumentPlugin],
dynamicJson: true,
}),
createPostGraphileSchema(pool, ["p"], {
skipPlugins: [PgConditionArgumentPlugin],
graphileBuildOptions: {
pgUseCustomNetworkScalars: true,
createPostGraphileSchema(
pool,
["p"],
{
skipPlugins: [PgConditionArgumentPlugin],
},
{}
),
createPostGraphileSchema(
pool,
["p"],
{
skipPlugins: [PgConditionArgumentPlugin],
dynamicJson: true,
},
{}
),
createPostGraphileSchema(
pool,
["p"],
{
skipPlugins: [PgConditionArgumentPlugin],
graphileBuildOptions: {
pgUseCustomNetworkScalars: true,
},
},
{}
),
createPostGraphileSchema(
pool,
["p"],
{
skipPlugins: [PgConditionArgumentPlugin],
graphileBuildOptions: {
connectionFilterRelations: true,
},
},
}),
createPostGraphileSchema(pool, ["p"], {
skipPlugins: [PgConditionArgumentPlugin],
graphileBuildOptions: {
connectionFilterRelations: true,
{}
),
createPostGraphileSchema(
pool,
["p"],
{
skipPlugins: [PgConditionArgumentPlugin],
simpleCollections: "only",
},
}),
createPostGraphileSchema(pool, ["p"], {
skipPlugins: [PgConditionArgumentPlugin],
simpleCollections: "only",
}),
createPostGraphileSchema(pool, ["p"], {
skipPlugins: [PgConditionArgumentPlugin],
graphileBuildOptions: {
connectionFilterAllowNullInput: true,
connectionFilterAllowEmptyObjectInput: true,
{}
),
createPostGraphileSchema(
pool,
["p"],
{
skipPlugins: [PgConditionArgumentPlugin],
graphileBuildOptions: {
connectionFilterAllowNullInput: true,
connectionFilterAllowEmptyObjectInput: true,
},
},
}),
{}
),
createPostGraphileSchema(
pool,
["p"],
Expand Down Expand Up @@ -173,7 +236,6 @@ for (const queryFileName of queryFileNames) {
queryFileName in gqlSchemaByQueryFileName
? gqlSchemaByQueryFileName[queryFileName]
: gqlSchemas.normal;

const document = parse(query);
const errors = validate(schema, document);
if (errors.length > 0) {
Expand Down
31 changes: 31 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Babel config, used by Jest
module.exports = {
plugins: ["@babel/plugin-transform-modules-commonjs"],
presets: [
[
"@babel/env",
{
targets: {
node: "16.12",
},
},
],
"@babel/preset-typescript",
],
env: {
test: {
plugins: ["babel-plugin-transform-import-meta"],
presets: [
[
"@babel/env",
{
targets: {
node: "current",
},
},
],
"@babel/preset-typescript",
],
},
},
};
Loading

0 comments on commit 8f6c590

Please sign in to comment.