Postgraphile v5 Support (#58)#66
Conversation
After bumping to the v5 package versions, tests would fail with the
following error:
```
● Test suite failed to run
ReferenceError: TextEncoder is not defined
> 1 | import * as pg from "pg";
| ^
2 |
3 | export async function withPgPool<T = any>(
4 | cb: (pool: pg.Pool) => Promise<T>
at Object.<anonymous> (node_modules/pg/lib/crypto/utils-webcrypto.js:22:21)
at Object.<anonymous> (node_modules/pg/lib/crypto/utils.js:8:20)
at Object.<anonymous> (node_modules/pg/lib/crypto/sasl.js:2:16)
at Object.<anonymous> (node_modules/pg/lib/client.js:5:12)
at Object.<anonymous> (node_modules/pg/lib/index.js:3:14)
at Object.<anonymous> (__tests__/helpers.ts:1:1)
at Object.<anonymous> (__tests__/schema.minimal_type.test.ts:2:1)
```
Based on [information from @SimenB](
jsdom/jsdom#2524 (comment)
), it seems like you probably should not be using
`jest-environment-jsdom` to start with if you need access to
`TextEncoder` or `TextDecoder`.
Based on [this](
https://stackoverflow.com/a/72369912/1137077
) answer on SO, I was able to verify that `@jest-environment node` at
the top of test files fixed the issue. However, it would seem more
logical to apply this as a global setting, given that postgraphile is
meant to run in a node context.
After setting `testEnvironment: jest-environment-node` in the global
config, I found that tests again started failing. However, the new
failures seem related to the v5 changes to plugins which is expected at
this stage.
The previous `moduleResolution: node` setting prevent importing types from `graphile-build-pg/pg-introspection`. `NodeNext` was chosen based on https://github.com/graphile/crystal/blob/91e87ab6516490a4cc7b7fc6400efb7623fbd331/graphile-build/graphile-build/tsconfig.json#L9
`postgraphile-core` is no more according to documentation: https://postgraphile.org/postgraphile/next/migrating-from-v4/#postgraphile-core
This seems to be better in line with other v5 plugins and the new `GraphileConfig.Preset` type.
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
50762eb to
9e8dd58
Compare
| pgGISTypeName, | ||
| pgGISSubtype, | ||
| pgGISHasZ, | ||
| pgGISHasM, |
There was a problem hiding this comment.
This is going to make the field scope quite noisy, might be better to wrap these all up in a single attribute instead?
There was a problem hiding this comment.
I refactored the types overall, please check again and let me know what you think
| graphql: { GraphQLNonNull, GraphQLFloat }, | ||
| inflection, | ||
| } = build; | ||
| const xFieldName = inflection.gisXFieldName(pgGISTypeName!); |
There was a problem hiding this comment.
Ideally you want to provide more details to an inflector, so it has more choice as to what to call it. Passing just the type name is very limiting in choice, you can't for example attach smart tags or use the database schema from which it originates to make naming choices.
There was a problem hiding this comment.
I did some refactoring on this, let me know if that went into a good direction
| (attribute.extensions as any).postgisTypeModifier = | ||
| pgAttribute.atttypmod; |
There was a problem hiding this comment.
I'm as yet undecided on the best way to handle type modifiers in V5.
| @@ -1 +0,0 @@ | |||
| export const version = ""; | |||
There was a problem hiding this comment.
A "postversion" script could be used to update the version to be used in each of the plugins; this would be helpful for consumers of the preset. Something like a scripts/postversion.mjs file:
#!/usr/bin/env node
import * as fs from "node:fs/promises";
const VERSION_TS = "src/vesion.ts";
const packageJsonString = await fs.readFile("package.json", "utf8");
const packageJson = JSON.parse(packageJsonString);
await fs.writeFile(
VERSION_TS,
`\
// This file is autogenerated by /scripts/postversion.mjs
export const version = ${JSON.stringify(packageJson.version)};
`,
);and then add it to package.json:
npm pkg set scripts.postversion="node scripts/postversion.mjs"There was a problem hiding this comment.
I'm currently proposing to just include the version via an package (JSON) import. That way the version should always match the package version, at least after a release, I think. What would the benefit of the script be in contrast? 🙌
There was a problem hiding this comment.
The advantage of the script version is that it means you don't need to import JSON, which makes the plugin compatible with a wider array of runtimes and tooling. Importing JSON has complexities in certain bundlers/etc and consumes more memory.
There was a problem hiding this comment.
I see, thanks for sharing! I made the suggested change.
| ```json | ||
| { | ||
| "extends": ["PostgisPreset"], | ||
| } |
There was a problem hiding this comment.
import { PostgisPreset } from "@graphile/postgis";
const preset: GraphileConfig.Preset = {
extends: [
// ... Amber/V4/etc presets
PostgisPreset,
],
// ...
};
export default preset;| "noUnusedLocals": true, | ||
| "preserveWatchOutput": true | ||
| "preserveWatchOutput": true, | ||
| "resolveJsonModule": true, |
There was a problem hiding this comment.
For importing the version from package.json it should be needed, I'd say. Let's discuss above.
benjie
left a comment
There was a problem hiding this comment.
Not a thorough review; but it's looking good! Try and minimize the difference with previous code as that makes review easier (and also eases migration for people who may have custom inflectors or other integrations/extensions). Thanks for your work on this!
945249d to
818de0b
Compare
818de0b to
a311f06
Compare
dargmuesli
left a comment
There was a problem hiding this comment.
I'm trying out real world use of this at the moment. There are still things to discuss for sure that I'm not certain about yet. I was a (pure) consumer of these things before and just relied on them working, now this is me looking into their core which I always like to do when I have the time. Now there is the missing 20% or 10% maybe that I would spend very much time on compared to its result so maybe I should not do this. But I'd definitely collaborate on this further! If more brains share how to get this done, I'll keep this PR up to speed.
1179293 to
25b9a29
Compare
|
@benjie I think this is ready for a full review now from my side, I have this running for some time in my dev setup now and outputs seem to fit! |
|
I tested the PR but I have issues with geometry(geometry, 4326) columns from Postgis returning "geom": null in postgraphile v5. I only get GeometryGeometry as subtype, it seems that the plugin is currently unable to infer the specific subtype like GeometryPoint. Since our postgraphile v4 server is doing that just fine with the same database, I assume that due to migrating it from postgraphile v4 to v5 the PostGIS plugin is now stricter about how it decides geometry subtypes? |
Description
Further work on the v5 migration started by @FelixZY in #60.
Resolves #58
Performance impact
unknown
Security impact
unknown
Checklist
yarn lint:fixpasses.yarn testpasses.RELEASE_NOTES.mdfile (if one exists).