-
-
Notifications
You must be signed in to change notification settings - Fork 570
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to import postgraphql in a TypeScript project? #520
Comments
Did you tried just doing: import postgraphql from 'postgraphql' You would do Hope this helps. 🤞 |
I did indeed try that, but then it's an even simpler error: That is the same type of error that appears when I have not installed the typings for a module using e.g. |
Try
You can also add typings yourself; e.g. here's some I had to make for v4: We're probably going to be moving from TypeScript to Flow at some point, FYI. |
Still get the same I'm making my own typings now. Based upon this spec ( http://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html ) it seems like we should probably either have a |
Ok hm I'm not going to make a PR just yet because, well, I don't know enough about postgraphql's build process and structure to put the definitions in the right place. My guess is that it should go in Here is the type definition that I'm testing out in my project now, which seems to compile properly:
|
That looks about right. There's work in #383 to add typings to the compiled version but I've not had time to read up enough on it to be sure, this is the only TypeScript project I work on. |
@benjie are you still planing to change to Flow? Maybe I can take again a look my ticket cause typescript has evolved a lot during my absence. |
Honestly, both TypeScript and Flow cause quite significant maintenance issues - given I only work on PostGraphile a few days a month keeping either of them ticking over is a PITA. I'm considering removing them entirely. I've lost a good 5 hours of PostGraphile development time to TypeScript in the last 2 months due to library updates breaking types and thus breaking CI; and I'm currently (literally right now) having to fix a load of Flow stuff in graphile-build because I upgraded GraphQL which brings new types and suddenly I've got 269 errors to solve. For a project you're working on full time they are both great tools, but I sink too high a percentage of my PostGraphile time into solving issues with them. Both tools in both projects are out of date because updating them is too time consuming. In addition graphile-build being plugin based does not lend itself to strong typing - particularly it's Build object is highly dynamic. |
I can confirm this is annoying.
From my experience it will only get more worse without types. Especially when you only work part time on it. How do you remember which type which variable is? Especially in such a big system. These errors are normally something good. Without them it would be try and error and you need to hope that your unit tests will catch them. This does of cause only apply when the types are also applied correctly. I would also argue that it is easier to contribute to a good typed system that to something where you guess the whole time which variable is which type? Maybe I can find the time and take a look in upgrade typescript, so I can better understand where the problems are. |
I'm not too worried about myself forgetting the types; however there is defensiveness in that it'll protect from others breaking things in PRs, like linting and tests do 👍 Sending a PR to a typed project is good if you're adept at that tool however, many people are not - so having things in TypeScript or Flow can be a barrier to contributions over vanilla JS. So you generally have a smaller pool of possibly higher quality PRs. The amount of time spent just keeping these tools ticking over when you just want to update an unrelated dependency in package.json is not to be underestimated. You can probably tell I'm a bit annoyed about it today, so probably not in the right frame of mind to make any concrete decisions (the temptation to just throw all my toys out the pram (remove types from everything and stick with vanilla JS) has been intense today...). If you are able to upgrade PostGraphile to the latest TypeScript that would be brilliant - you can do it directly on the |
not that opinions are being solicited, here's an opinion from a random guy on the web 🌎 . i've started with and injected TS into many projects over the past two years, only to gut it soon after. it's been a constant annoyance with the same emotion you've expressed above. my latest effort however, has been much more fruitful & painless. my perception is that the community has grown, typings are updated much faster now, and there are provisions now to extend incomplete/broken interfaces so as to unblock users. long-term TS-hater here, now siding on slightly TS positive opinion 👍 TS editor support is >> than flow too, which is something to consider! |
Before the discussion here turned to TypeScript vs. Flow, it looks as if @zopf got pretty close to making a PR for his d.ts file. This seems to have stalled because this request is still pending an answer:
I don't currently have much knowledge of how DefinitelyTyped works, but I'm curious how close @zopf's proposed d.ts file is to the current API. (Clearly, the name of the project needs to be updated from postgraphql to postgraphile, but is everything else up to date?) And once the d.ts is brought up to date, how much effort would it take to publish it to DefinitelyTyped? |
I expect the options will need updating: https://github.com/graphile/postgraphile/blob/7761bb343c129d4a7ba502f772b40ac5acf04ad1/src/postgraphile/postgraphile.ts#L17-L159 There's also a few things missing: |
@benjie, Regarding the options, given that the source file is already in TypeScript, that should be pretty straightforward. While thinking about typings, it might make sense to update the documentation as well. The use as library page is up to date except for the absence of I'm not quite sure what to do about the backwards compatibility issue. I'll have to read up on that more. |
Made some progress this morning on the typings:
I sprinkled some todo comments throughout these files to point out types I may have captured incorrectly (e.g., there were some tricky/impossible conversions between flow and TypeScript). That said, even the things I haven't marked should be verified and tested by someone who's intimately familiar with these projects. |
Great work @devuxer; what you’ve done looks good from a cursory glance, but properly validating it would require more time and most likely a TypeScript project. Maybe others following this thread can try out your definitions and let us know 👍 or 👎 |
@benjie, Sounds good, and I am trying it out in a TypeScript project myself at the moment. though I'm not touching much of the surface area of the API. |
@devuxer -- I am also starting a TS project using Postgraphile and would love to try this. Do you have the steps needed to properly integrate your d.ts file(s) into a TS project? Thanks! |
@sjmcdowall, All you need to do is create a folder called "typings" where your server.ts file is, and place the d.ts files in that folder. |
@devuxer -- Just FYI -- I added (finally) all the typings to my project and I am getting some linting errors... I think bodySizeLimit is legit as a string ?? 2 -- Am I using the wrong type here?
Each of the above options are being flagged as not valid .. ?? Cheers! (Why don't you donate / add these to the @types thing?? These are pretty good starting points and better than anything else we don't have! :) |
BTW -- We found a problem in the postgraphile-core d.ts definition -- here is one that works
OH -- and FYI -- you need to add the following to your tsconfig.js to get it to work: "lib": ["esnext"], This will resolve some nasty AsyncInterface errors in graphql itself .. declare module "postgraphile-core" {
import { Client, Pool } from "pg";
import { Build, Context, Options, Plugin } from "graphile-build";
export type mixed = {} | string | number | boolean | undefined | null
type PostGraphileOptions = {
dynamicJson?: boolean;
classicIds?: boolean;
disableDefaultMutations?: boolean;
bodySizeLimit?: string;
graphqlRoute?: string;
graphiql?: boolean;
graphiqlRoute?: string;
nodeIdFieldName?: string;
graphileBuildOptions?: Options;
graphqlBuildOptions?: Options; // DEPRECATED!
replaceAllPlugins?: Array<(builder: mixed) => {}>;
appendPlugins?: Array<(builder: mixed) => {}>;
prependPlugins?: Array<(builder: mixed) => {}>;
skipPlugins?: Array<(builder: mixed) => {}>;
jwtPgTypeIdentifier?: string;
jwtSecret?: string;
inflector?: any; // NO LONGER SUPPORTED!
pgColumnFilter?: (mixed: any, Build: Build, Context: Context) => boolean; //
viewUniqueKey?: string;
enableTags?: boolean;
readCache?: string;
writeCache?: string;
setWriteCacheCallback?: (fn: () => Promise<void>) => void;
legacyRelations?: "only" | "deprecated";
setofFunctionsContainNulls?: boolean;
legacyJsonUuid?: boolean;
};
type PgConfig = Client | Pool | string;
export const createPostGraphileSchema: (
pgConfig: PgConfig,
schemas: string | string[],
options?: PostGraphileOptions
) => Promise<any>;
export const watchPostGraphileSchema: (
pgConfig: PgConfig,
schemas: string | string[],
options: PostGraphileOptions | undefined,
onNewSchema: any
) => Promise<() => Promise<void>>;
} |
TS can autogenerate typings for us. why not flip # change to tsconfig.json
"declaration": true, /* Generates corresponding '.d.ts' file. */
"declarationDir": "./build",
"allowJs": false, more testing to come... |
PR welcome 👍 |
BTW -- this is awesome. I also have some hacked files from the other guy who hacked some .d.ts files that work pretty well for me .. but I don't know what to do with them to contribute them (especially as they are my hacks of someone else's work...from maybe this discussion thread! LOL) ..
If you want these files just ask and I'll pop them somewhere (maybe here?) but this auto generate scheme seems much better and can be added to the commit git logic to auto-generate before a commit or pre-publish or something?
… On Jul 7, 2018, at 2:49 AM, Benjie Gillam ***@***.***> wrote:
PR welcome 👍
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <#520 (comment)>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AB8M7WXaAbQnT0UsC75itK4fL8Pwjnkgks5uEFnsgaJpZM4OdVAA>.
|
I was a little naive--there is a bit more to it, but not obscenely more. What to do about -core's typings is still unclear. I'm not sure if there's a way to ship those as part of this build effectively. I'd rather move those to -core itself personally |
Moving -core to the -core thing itself makes all the sense -- and isn't that where TS will rather look anyway for it's Typings?
I have a working set of -core typings that can be used as a comparison (as well as for postgraphile itself) if anyone is interested. Again, not my original work but hacked so it actually did work for my project .. (and what I did makes sense to me.. LOL)
… On Jul 7, 2018, at 12:24 PM, Christopher Dieringer ***@***.***> wrote:
I was a little naive--there is a bit more to it, but not obscenely more. What to do about -core's typings is still unclear. I'm not sure if there's a way to ship those as part of this build effectively. I'd rather move those to -core itself personally
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <#520 (comment)>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AB8M7RXVFR_Afr4pK8XmdIpQ8dIGPlEjks5uEOCogaJpZM4OdVAA>.
|
folks, critique and/or contribute to #794 if you can |
#794 is now merged; we're now 100% TypeScript 🎉 For anyone looking for simple things to do to improve our typings (a great way of contributing to the project):
Please keep pull requests small and focussed; it's rare that I have 4 hours to drop on code review! (Each of these tasks should be a separate PR.) |
Huge thanks to @cdaringe for undertaking this; I've been putting it off for a year because I had a suspicion how much work it would be! |
Woohoo! Can't wait to try it out and remove my old typings stuff in the project!
Is this available @next or whatever to give it a spin?
… On Jul 21, 2018, at 5:57 AM, Benjie Gillam ***@***.***> wrote:
Huge thanks to @cdaringe <https://github.com/cdaringe> for undertaking this; I've been putting it off for a year because I had a suspicion how much work it would be!
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <#520 (comment)>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AB8M7RUVo4oWgffv0o7Ud_586fUyFiirks5uIvsHgaJpZM4OdVAA>.
|
It will be 👍 Need to add the postgraphile-core typings first. Hoping to get an |
Here are mine I munged
```
declare module "postgraphile-core" {
import { GraphQLError, ExecutionResult } from "graphql";
import { IncomingMessage, ServerResponse, Server } from "http";
import * as jwt from "jsonwebtoken";
import { GraphQLErrorExtended, PluginHookFn } from "postgraphile";
import { Client, Pool, PoolConfig } from "pg";
import { Build, Context, Options, Plugin } from "graphile-build";
export type mixed = {} | string | number | boolean | undefined | null
export type PostGraphileOptions = {
/**
* When true, PostGraphile will watch your database schemas and re-create the
* GraphQL API whenever your schema changes, notifying you as it does. This
* feature requires an event trigger to be added to the database by a
* superuser. When enabled PostGraphile will try to add this trigger, if you
* did not connect as a superuser you will get a warning and the trigger
* won’t be added.
*/
watchPg?: boolean;
/**
* The default Postgres role to use. If no role was provided in a provided
* JWT token, this role will be used.
*/
pgDefaultRole?: string;
/**
* Setting this to `true` enables dynamic JSON which will allow you to use
* any JSON as input and get any arbitrary JSON as output. By default JSON
* types are just a JSON string.
*/
dynamicJson?: boolean;
/**
* If none of your `RETURNS SETOF compound_type` functions mix NULLs with the
* results then you may set this true to reduce the nullables in the GraphQL
* schema
*/
setofFunctionsContainNulls?: boolean;
/**
* Enables classic ids for Relay support. Instead of using the field name
* `nodeId` for globally unique ids, PostGraphile will instead use the field
* name `id` for its globally unique ids. This means that table `id` columns
* will also get renamed to `rowId`.
*/
classicIds?: boolean;
/**
* Setting this to `true` will prevent the creation of the default mutation
* types & fields. Database mutation will only be possible through Postgres
* functions.
*/
disableDefaultMutations?: boolean;
/**
* Enables adding a `stack` field to the error response. Can be either the
* boolean `true` (which results in a single stack string) or the string
* `json` (which causes the stack to become an array with elements for each
* line of the stack).
*/
showErrorStack?: boolean;
/**
* Enables ability to modify errors before sending them down to the client
* optionally can send down custom responses
* (@middlewareOnly)
*/
handleErrors?: ((
errors: Array<GraphQLError>,
req: IncomingMessage,
res: ServerResponse
) => Array<GraphQLErrorExtended>);
/**
* Extends the error response with additional details from the Postgres
* error. Can be any combination of `['hint', 'detail', 'errcode']`.
* Default is `[]`.
*/
extendedErrors?: Array<string>;
/**
* an array of [Graphile Build](/graphile-build/plugins/) plugins to load
* after the default plugins
*/
appendPlugins?: Array<(builder: mixed) => {}>;
/**
* an array of [Graphile Build](/graphile-build/plugins/) plugins to load
* before the default plugins (you probably don't want this)
*/
prependPlugins?: Array<(builder: mixed) => {}>;
/**
* the full array of [Graphile Build](/graphile-build/plugins/) plugins to
* use for schema generation (you almost definitely don't want this!)
*/
replaceAllPlugins?: Array<(builder: mixed) => {}>;
/**
* A file path string. Reads cached values from local cache file to improve
* startup time (you may want to do this in production).
*/
readCache?: string;
/**
* A file path string. Writes computed values to local cache file so startup
* can be faster (do this during the build phase).
*/
writeCache?: string;
/**
* Enables saving the detected schema, in JSON format, to the given location.
* The directories must exist already, if the file exists it will be
* overwritten.
* (@middlewareOnly)
*/
exportJsonSchemaPath?: string;
/**
* Enables saving the detected schema, in GraphQL schema format, to the given
* location. The directories must exist already, if the file exists it will
* be overwritten.
* (@middlewareOnly)
*/
exportGqlSchemaPath?: string;
/**
* The endpoint the GraphQL executer will listen on. Defaults to `/graphql`.
* (@middlewareOnly)
*/
graphqlRoute?: string;
/**
* The endpoint the GraphiQL query interface will listen on (**NOTE:**
* GraphiQL will not be enabled unless the `graphiql` option is set to
* `true`). Defaults to `/graphiql`.
* (@middlewareOnly)
*/
graphiqlRoute?: string;
/**
* Set this to `true` to enable the GraphiQL interface.
* (@middlewareOnly)
*/
graphiql?: boolean;
/**
* Enables some generous CORS settings for the GraphQL endpoint. There are
* some costs associated when enabling this, if at all possible try to put
* your API behind a reverse proxy.
* (@middlewareOnly)
*/
enableCors?: boolean;
/**
* Set the maximum size of JSON bodies that can be parsed (default 100kB).
* The size can be given as a human-readable string, such as '200kB' or '5MB'
* (case insensitive).
* (@middlewareOnly)
*/
bodySizeLimit?: string;
/**
* [Experimental] Enable the middleware to process multiple GraphQL queries
* in one request
* (@middlewareOnly)
*/
enableQueryBatching?: string;
/**
* The secret for your JSON web tokens. This will be used to verify tokens in
* the `Authorization` header, and signing JWT tokens you return in
* procedures.
*/
jwtSecret?: string;
/**
* Options with which to perform JWT verification - see
* https://github.com/auth0/node-jsonwebtoken#jwtverifytoken-secretorpublickey-options-callback
* (@middlewareOnly)
*/
jwtVerifyOptions?: jwt.VerifyOptions;
/**
* A comma separated list of strings that give a path in the jwt from which
* to extract the postgres role. If none is provided it will use the key
* `role` on the root of the jwt.
* (@middlewareOnly)
*/
jwtRole?: Array<string>;
/**
* The Postgres type identifier for the compound type which will be signed as
* a JWT token if ever found as the return type of a procedure. Can be of the
* form: `my_schema.my_type`. You may use quotes as needed:
* `"my-special-schema".my_type`.
*/
jwtPgTypeIdentifier?: string;
/**
* The audiences to use when verifing the JWT token. If not set the audience
* will be `['postgraphile']`.
* (@middlewareOnly)
*/
jwtAudiences?: Array<string>;
/**
* Some one-to-one relations were previously detected as one-to-many - should
* we export 'only' the old relation shapes, both new and old but mark the
* old ones as 'deprecated', or 'omit' the old relation shapes entirely
*/
legacyRelations?: "only" | "deprecated" | "omit";
/**
* ONLY use this option if you require the v3 typenames 'Json' and 'Uuid'
* over 'JSON' and 'UUID'
*/
legacyJsonUuid?: boolean;
/**
* Turns off GraphQL query logging. By default PostGraphile will log every
* GraphQL query it processes along with some other information. Set this to
* `true` to disable that feature.
* (@middlewareOnly)
*/
disableQueryLog?: boolean;
/**
* A plain object specifying custom config values to set in the PostgreSQL
* transaction (accessed via `current_setting('my.custom.setting')`) or a
* function which will return the same (or a Promise to the same) based on
* the incoming web request (e.g. to extract session data)
* (@middlewareOnly)
*/
pgSettings?: { [key: string]: mixed } | ((req: IncomingMessage) => Promise<{ [key: string]: mixed }>);
/**
* Some graphile-build plugins may need additional information available on
* the `context` argument to the resolver - you can use this function to
* provide such information based on the incoming request - you can even use
* this to change the response [experimental], e.g. setting cookies
* (@middlewareOnly)
*/
additionalGraphQLContextFromRequest?: (req: IncomingMessage, res: ServerResponse) => Promise<{}>;
/**
* [experimental] Plugin hook function, enables functionality within
* PostGraphile to be expanded with plugins. Generate with
* `makePluginHook(plugins)` passing a list of plugin objects.
* (@middlewareOnly)
*/
pluginHook?: PluginHookFn;
};
type PgConfig = Client | Pool | string;
export const createPostGraphileSchema: (
pgConfig: PgConfig,
schemas: string | string[],
options?: PostGraphileOptions
) => Promise<any>;
export const watchPostGraphileSchema: (
pgConfig: PgConfig,
schemas: string | string[],
options: PostGraphileOptions | undefined,
onNewSchema: any
) => Promise<() => Promise<void>>;
}
```
|
Should be able to pull |
YAY!!! |
[semi-automated message] We try and keep the open issues to actual issues (bugs, etc); this seems like more of a discussion right now, so I'm closing it but please feel free to keep discussing it below 👍 |
I am fairly new to TypeScript, so forgive me if I'm making a newbie mistake.
I am attempting to import the
postgraphql
module in myindex.ts
file, like so:TypeScript is telling me that
Module ''postgraphql'' resolves to a non-module entity and cannot be imported using this construct.
For my other imports, I installed their typings using e.g.
npm install --save-dev @types/underscore
, but it does not appear there is a@types/postgraphql
module. These typings come from https://github.com/DefinitelyTyped/DefinitelyTyped.How do I go about setting up the proper typings for the
postgraphql
module so that I can use it in a TypeScript project?The text was updated successfully, but these errors were encountered: