relay-tools / relay-compiler-language-typescript Goto Github PK
View Code? Open in Web Editor NEW⛔️ Obsolete - A language plugin for Relay that adds TypeScript support, including emitting type definitions.
License: MIT License
⛔️ Obsolete - A language plugin for Relay that adds TypeScript support, including emitting type definitions.
License: MIT License
I don't know whether it's broken because of @types/relay-runtime 1.3.9 (1.3.8 works) or generated types are obsolete.
generated/AppQuery.graphql.ts:96:7 - error TS2739: Type '{ "kind": string; "fragment": { "kind": string; "name": string; "type": string; "metadata": null; "argumentDefinitions": { "kind": string; "name": string; "type": string; "defaultValue": null; }[]; "selections": ({ "kind": string; ... 4 more ...; "selections"?: undefined; } | { ...; } | { ...; })[]; }; "operation": ...' is missing the following properties from type 'ConcreteRequest': operationKind, name, id, text, metadata
96 const node: ConcreteRequest = (function(){
~~~~
generated/CreateWebMutation.graphql.ts:43:7 - error TS2739: Type '{ "kind": string; "fragment": { "kind": string; "name": string; "type": string; "metadata": null; "argumentDefinitions": { "kind": string; "name": string; "type": string; "defaultValue": null; }[]; "selections": { "kind": string; "alias": null; ... 5 more ...; "selections": { ...; }[]; }[]; }; "operation": { ...; };...' is missing the following properties from type 'ConcreteRequest': operationKind, name, id, text, metadata
43 const node: ConcreteRequest = (function(){
~~~~
generated/DeleteWebMutation.graphql.ts:36:7 - error TS2739: Type '{ "kind": string; "fragment": { "kind": string; "name": string; "type": string; "metadata": null; "argumentDefinitions": { "kind": string; "name": string; "type": string; "defaultValue": null; }[]; "selections": { "kind": string; "alias": null; ... 5 more ...; "selections": { ...; }[]; }[]; }; "operation": { ...; };...' is missing the following properties from type 'ConcreteRequest': operationKind, name, id, text, metadata
36 const node: ConcreteRequest = (function(){
~~~~
generated/SetUserThemeMutation.graphql.ts:37:7 - error TS2739: Type '{ "kind": string; "fragment": { "kind": string; "name": string; "type": string; "metadata": null; "argumentDefinitions": { "kind": string; "name": string; "type": string;"defaultValue": null; }[]; "selections": { "kind": string; "alias": null; ... 5 more ...; "selections": { ...; }[]; }[]; }; "operation": { ...; };...' is missing the following properties from type 'ConcreteRequest': operationKind, name, id, text, metadata
37 const node: ConcreteRequest = (function(){
~~~~
generated/signinMutation.graphql.ts:44:7 - error TS2739: Type '{ "kind": string; "fragment": { "kind": string; "name": string; "type": string; "metadata": null; "argumentDefinitions": { "kind": string; "name": string; "type": string; "defaultValue": null; }[]; "selections": { "kind": string; "alias": null; ... 5 more ...; "selections": ({ ...; } | { ...; })[]; }[]; }; "operatio...' is missing the following properties from type 'ConcreteRequest': operationKind, name, id, text, metadata
44 const node: ConcreteRequest = (function(){
~~~~
generated/webMutation.graphql.ts:46:7 - error TS2739: Type '{ "kind": string; "fragment": { "kind": string; "name": string; "type": string; "metadata": null; "argumentDefinitions": { "kind": string; "name": string; "type": string; "defaultValue": null; }[]; "selections": { "kind": string; "alias": null; ... 5 more ...; "selections": { ...; }[]; }[]; }; "operation": { ...; };...' is missing the following properties from type 'ConcreteRequest': operationKind, name, id, text, metadata
46 const node: ConcreteRequest = (function(){
~~~~
pages/_app.tsx:67:49 - error TS2339: Property 'text' does not exist on type 'RequestNode'.
Property 'text' does not exist on type 'ConcreteBatchRequest'.
67 body: JSON.stringify({ query: operation.text, variables }),
Related este/este#1642
@alloy Thanks a lot for the great work here. Will there be a new release of this library with the plugin-updates from today?
Best regards,
Ariel
Right now we transform non-standard scalar types to any
.
It should be somewhat straight forward to allow this to be user configurable in such a way that a user can specify that Email
should be a string
etc.
This is just an issue to keep track of the idea - and to open up the discussion for possible implementation details.
Things to consider:
{"Email": "string"}
) or should we allow for more complex scenarios (ie. importing types from other modules which is then the actual type?)When cloning the repo and attempting to run example for the first time this error appears:
example [master●] % yarn install
yarn install v1.3.2
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
error "../relay-compiler-language-typescript-1.0.0-alpha.6.tgz": Tarball is not in network and can not be located in cache (["/Users/damassi/Sites/github/relay-compiler-language-typescript/relay-compiler-language-typescript-1.0.0-alpha.6.tgz","/Users/damassi/Library/Caches/Yarn/v1/npm-relay-compiler-language-typescript-1.0.0-alpha.6-471eb1864600c1c97656e50bff8e6bd66de607ef/.yarn-tarball.tgz"])
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
It seems like yarn pack
needs to be run in the root so that it's picked up by package.json
, but when attempting to run that command it outputs the wrong version:
relay-compiler-language-typescript [master●] % yarn pack
yarn pack v1.3.2
success Wrote tarball to "/Users/damassi/Sites/github/relay-compiler-language-typescript/relay-compiler-language-typescript-v0.9.0.tgz".
✨ Done in 0.13s.
(v0.9.0.tgz
)
Currently the example expects a package to have been built in the root of the repo.
OK bear with me on this one: All Animals
make noise
. A Dog
is an Animal
. A Bark
is the kind of Noise
a Dog
makes.
IDL:
interface Animal {
id: ID
noise: Noise!
}
interface Noise {
name: String!
}
type Dog implements Animal {
id: ID
noise: Bark!
}
type Bark implements Noise {
name: String!
}
fragment:
animal {
... on Dog {
noise {
... on Bark {
name
}
}
}
}
artifact:
readonly animal: ({
readonly noise?: {
readonly name: string;
};
})
I believe it's a bug that noise
is marked as optional here. Noise is guaranteed for all Animals, and therefore all Dogs (graphql forces all sub-type to be sub-classed & to have matching nullability).
This seems very close to #64, but it's a little nuanced since it only crops up when 2 interfaces are used.
Reproduction branch is here: https://github.com/mattkrick/relay-compiler-language-typescript/tree/double-int-null/example
Often we need to have a reference to a type that’s being used somewhere deeper into a fragment’s query. For instance, consider this fragment’s typings:
export type ArtworkSidebarArtists_artwork = {
readonly artists: ReadonlyArray<({
readonly name: string | null;
readonly href: string | null;
}) | null> | null;
};
To some functions we end up passing a single element of the artists
array, so currently in our code we do the following:
type Artist = ArtworkSidebarArtists_artwork["artists"][0]
It would be easy to emit the following artefact instead:
export type Artist = {
readonly name: string | null;
readonly href: string | null;
};
export type ArtworkSidebarArtists_artwork = {
readonly artists: ReadonlyArray<Artist | null> | null;
};
The only situation I imagine where it gets more complex is around naming the types when you have multiple selections on the same type in a single fragment. For instance, let’s say we had the following fragment typing:
export type ArtworkSidebarArtists_artwork = {
readonly artists: ReadonlyArray<({
readonly name: string | null;
readonly related_artists: ReadonlyArray<({
href: string | null;
}) | null> | null;
}) | null> | null;
};
In this case we can’t just call the type Artist
, because we have to differentiate between the artwork’s artist and the artists related to the artwork’s artist.
Encoding the path into the name of the type (e.g. ArtworkSidebarArtists_artwork_artists_related_artists_Artist
) would be counter-productive, as in that case you could just as well use plain TS code to get the type reference (e.g. ArtworkSidebarArtists_artwork["artists"][0]["related_artists"][0]
).
Maybe this is enough of an edge-case that we simply don’t emit named typings for such situations at all, which could instead encourage people to refactor that nested part of the query into a container/fragment of its own?
It would be nice to be able to use devOnlyAssignments
(https://github.com/facebook/relay/blob/f8585ab4f90f2e707d5555c9f7b423de3ea553bd/packages/relay-compiler/language/RelayLanguagePluginInterface.js#L176) to provide the text in dev when using persisted queries.
With my current setup it would make working non-local backends easier since there is no need to upload persisted queries every time queries change when developing.
I was able to hack my local version to produce this:
if (__DEV__) {
(node as any).params.text = "query ...";
}
I guess we could add a flag to enable this and configure the if dev check or maybe just use process.env.NODE_ENV
.
It might be nice for people to be able to quickly see real world artefacts and also for us to update those along with plugin changes so that we can review this besides any other tests. What do you think?
I'm using --noImplicitAny
, and I can't compile when I include the generated mutation files.
Is there a way to add the required : any
and as any
annotations to the generated files?
E.g.
const node: ConcreteRequest = (function(){
var v0: any = [],
v1: any = [...];
return {
"kind": "Request",
...
} as any)();
Thanks for the efforts
Hi,
I cannot seem to get the Babel transform running on my generated typescript code. Perhaps you can shed some light on what I am doing wrong. Both relay-compiler and webpack-dev-server start up fine without any errors, generated .graphql.ts
files show up in my artifact directory, but in browser console I get
Uncaught Error: graphql: Unexpected invocation at runtime. Either the Babel transform was not set up, or it failed to identify this call site`
Using v1.5.0-plugin.5
from alloy/relay
. I run webpack with webpack-dev-server
, this is how I run my compiler:
relay-compiler --src ./src --artifactDirectory ./__generated__ --schema ../schema.graphql --language=typescript
This is my .babelrc
{
"plugins": [
["relay", { "artifactDirectory": "./__generated__" }]
]
}
I have this in my webpack config:
module: {
rules: [
{
test: /\.tsx?$/,
exclude: /node_modules/,
use: [
{ loader: 'babel-loader' },
{ loader: 'ts-loader', options: { transpileOnly: true } },
],
},
],
},
Relevant packages:
"react-relay": "https://github.com/alloy/relay/releases/download/v1.5.0-plugin.5/react-relay-1.5.0-plugin.5.tgz",
"relay-compiler": "https://github.com/alloy/relay/releases/download/v1.5.0-plugin.5/relay-compiler-1.5.0-plugin.5.tgz",
"relay-runtime": "https://github.com/alloy/relay/releases/download/v1.5.0-plugin.5/relay-runtime-1.5.0-plugin.5.tgz",
"babel-plugin-relay": "https://github.com/alloy/relay/releases/download/v1.5.0-plugin.5/babel-plugin-relay-1.5.0-plugin.5.tgz",
"relay-compiler-language-typescript": "0.9.0",
"webpack": "4.2.0",
"webpack-cli": "2.0.13",
"webpack-dev-server": "3.1.1"
"ts-loader": "4.1.0",
"ts-node": "4.1.0",
Any help would be greatly appreciated. Thanks!
Filing a ticket here to keep track of this external work https://github.com/alloy/relay/pull/5
This is just me shoving ideas out of my head, we don’t need this for initial release.
I’d like to improve on the experience on this when writing components, ie. having to import the fragment types and making sure you use the right ones, even when adding new properties seem... like not a great experience to me.
I’ve been thinking about this, and so far I’ve come to the conclusion that creating a d.ts file as part of the plugin run which could declare a bunch of types usable throughout ones entire codebase might be helpful. Ie. if we can create a type MyComponentFragmentContainerProps<TProps>
(better name needed) which more or less does the opposite of the types we need for the definitelytyped repo, ie takes a type object of non relay props and returns a new type containing all that + the fragment types and then the relay prop. We’d probably need different types for the 3 different kind of containers due to differences in the relay prop.
I’m not entirely sure if this is doable without adding more support in the relay compiler itself or not, but if any is needed it shouldn’t be that much, and I’m sure we could make something flow users can use as well.
Let me know if I need to elaborate (I’m typing this from my iPad atm) the ideas, or if you have different ideas for making this nicer.
First & foremost, THANK YOU. The amount of work that you've put into making this a reality is no short of monumental & it's amazing! My app is a hot mess of JS, Flow, and TS and this plugin handles it all with ease.
I've been using it for about a week and there's just one thing I can't seem to do:
I've got a fragment like this:
fragment Foo_item on Item {
...Bar_item
id
}
I tried writing something like this: <Bar item={item}/>
i got this:
TS2322: Type 'Foo_item' is not assignable to type 'Bar_item'.
Types of property '" $refType"' are incompatible.
Type 'typeof _Foo_item$ref' is not assignable to type 'typeof _Bar_item$ref'.
I tried running the example (used npm pack
and updated the example version to 1.0.1) to make sure i wasn't crazy & i got this:
Error:(56, 21) TS2322: Type '{ viewer: TodoApp_viewer; }' is not assignable to type 'IntrinsicAttributes & Pick<Props & { relay: never; }, "viewer"> & ComponentRef & { children?: Rea...'.
Type '{ viewer: TodoApp_viewer; }' is not assignable to type 'Pick<Props & { relay: never; }, "viewer">'.
Types of property 'viewer' are incompatible.
Type 'TodoApp_viewer' is not assignable to type 'TodoList_viewer'.
Property 'todos' is missing in type 'TodoApp_viewer'.
Seems related to #58, although just like the example I've got all my artifacts in a single folder.
FWIW I wouldn't mind if the symbol was removed from the types. I use relay with storybook & if the symbol were removed then I wouldn't have to cast my mock input data to the appropriate type.
@kastermester Once we’re done and decide to publish, what do you think of moving to the https://github.com/relay-tools org so that people can more easily find it amongst other Relay tools?
Hi there!
Bug: I get the following error when running
relay-compiler --src ./client --schema server/graphql/schema.graphql --language typescript --artifactDirectory ./client/__generated__
ERROR:
GraphQLCompilerContext: Unknown document `ProductListItem_product`.
When I console log this._documents in GraphQLCompilerContext._get
when using the npm command with the language plugin I get a list of documents that do not include the missing fragment.
documents OrderedMap { "SignUpSignInForm_user": [object Object], "AddressBookItemStreet_address": [object Object], "Step4Payment_user": [object Object], "CorporatePageDiscountsAvailable_Query": [object Object], "RecentPostTile_blogPost": [object Object], "Step3GiftingOptions_cart": [object Object], "TestingQueryRendererTestQuery_Query": [object Object], "TestComponent_user": [object Object], "GuestSignUpStep_user": [object Object], "PaymentForm_user": [object Object], "BlogPostTile_blogPost": [object Object], "BlogPageRefetchQuery": [object Object], "BlogPage_viewer": [object Object], "CorporatePage_viewer": [object Object], "BlogPostPageRefetchQuery": [object Object], "BlogPostPage_viewer": [object Object], "CheckoutStepper_viewer": [object Object], "CorporatePageBestSellers_Query": [object Object], "RecentPosts_viewer": [object Object], "BecomeACeoPage_viewer": [object Object], "WeddingsPage_viewer": [object Object], "AddressBookItemName_address": [object Object], "HostATastingPage_viewer": [object Object] }
If I run the regular npm command
relay-compiler --src ./client --schema server/graphql/schema.graphql --extensions js ts tsx
then I get a much larger list of documents
{ "NextAndPrevButtonsMainQuery": [object Object], "App_Query": [object Object], "AddressBookEditMutation": [object Object], "ProductTIAT_Query": [object Object], "BlogPostPage_Query": [object Object], "BlogPage_Query": [object Object], "UserLogoutMutation": [object Object], "ProductReviewUpdateMutation": [object Object], "ThisIsATreePage_Query": [object Object], "CartDeleteMutation": [object Object], "WishListDeleteMutation": [object Object], "CartUpdateShippingAddressMutation": [object Object], "ProductReviewDeleteMutation": [object Object], "AuthDialogRefetchQuery": [object Object], "AddressValidationMutation": [object Object], "CorporatePageDiscountsAvailable_Query": [object Object], "UserRecoverPasswordMutation": [object Object], "CartUpdateGiftReceiptMutation": [object Object], "OrderAddMutation": [object Object], "CartUpdateBillingInfoMutation": [object Object], "ReferralCodeLookupRefetchQuery": [object Object], "ProductReviewAddMutation": [object Object], "DisconnectSSOaccountMutation": [object Object], "WishListAddMutation": [object Object], "CartAddMutation": [object Object], "CartUpdateTaxRateMutation": [object Object], "AppComponentRefetchQuery": [object Object], "ProductDetailsPageRefetchQuery": [object Object], "CartUpdateShippingCostsAndTaxRateMutation": [object Object], "TestingQueryRendererTestQuery_Query": [object Object], "AddressBookAddMutation": [object Object], "CartDeleteTaxRatesMutation": [object Object], "CreateConciergeRequestMutation": [object Object], "CartPromoCodeDeleteMutation": [object Object], "UserSetDefaultPaymentMutation": [object Object], "UserSetDefaultShippingAddressMutation": [object Object], "ShopLandingPage_Query": [object Object], "ReferralCodeGenerate_Query": [object Object], "CorporateGiftingSendFormMutation": [object Object], "CartPromoCodeAutoAddMutation": [object Object], "UserLoginMutation": [object Object], "UserUpdateInfoMutation": [object Object], "queries_WeddingsPage_Query": [object Object], "queries_ReturnPage_Query": [object Object], "queries_FaqPage_Query": [object Object], "queries_PrivacyPolicyPage_Query": [object Object], "queries_PaymentsPage_Query": [object Object], "queries_AddressesPage_Query": [object Object], "queries_FavoritesPage_Query": [object Object], "queries_OrdersPage_Query": [object Object], "queries_MyAccountPage_Query": [object Object], "queries_ResetPasswordPage_Query": [object Object], "queries_ReceiptPage_Query": [object Object], "RegisterMutation": [object Object], "UserResetPasswordMutation": [object Object], "BlogPageRefetchQuery": [object Object], "CartUpdateShippingInfoAndTaxRateMutation": [object Object], "ProductsCatalogRefetchQuery": [object Object], "BlogPostPageRefetchQuery": [object Object], "CorporatePage_Query": [object Object], "BecomeACeoPage_Query": [object Object], "CeoSignUpFormMutation": [object Object], "OrdersPageRefetchQuery": [object Object], "OrderCancelMutation": [object Object], "CartDeleteShippingCostsMutation": [object Object], "StripePaymentAddMutation": [object Object], "ReferralCodeLookup_Query": [object Object], "CartUpdateGiftMessageMutation": [object Object], "HostATastingFormMutation": [object Object], "CartUpdateShippingCostsMutation": [object Object], "Checkout_Query": [object Object], "CartUpdateRecipientBirthDateMutation": [object Object], "HomePageRefetchQuery": [object Object], "CartDeleteEverythingMutation": [object Object], "CartUpdatePromoCodesMutation": [object Object], "CorporatePageBestSellers_Query": [object Object], "ProductCatalog_Query": [object Object], "HostATastingPage_Query": [object Object], "BuyAgainButtonContainerQuery": [object Object], "CartAddBulkMutation": [object Object], "ProductDetails_Query": [object Object], "CartUpdateShippingInfoMutation": [object Object], "HomePage_Query": [object Object], "AuthDialog_user": [object Object], "ProductListItem_product": [object Object], "HomePage_viewer": [object Object], "SignUpSignInForm_user": [object Object], "GuestSignUpStep_user": [object Object], "SelectShippingMethod_user": [object Object], "AddressBookItemStreet_address": [object Object], "AddressBookItemName_address": [object Object], "AddressBookItemText_address": [object Object], "AddressBookItemTextMobile_address": [object Object], "AddressBookItem_address": [object Object], "AccountAddressBook_user": [object Object], "AccountAddAddressDialog_user": [object Object], "SelectShippingMethod_cart": [object Object], "AccountShippingForm_user": [object Object], "AddressForm_user": [object Object], "AddressForm_cart": [object Object], "ShippingForm_user": [object Object], "ShippingCompletedView_cart": [object Object], "Step2Shipping_user": [object Object], "SummaryPromoCode_cart": [object Object], "GuestPaymentView_user": [object Object], "AccountAddAddressForm_user": [object Object], "EditPaymentDialogContent_user": [object Object], "AccountEditPaymentDialog_user": [object Object], "AccountAddPaymentDialog_user": [object Object], "EditPaymentInformation_stripePayment": [object Object], "EditPaymentDialogContent_stripePayment": [object Object], "AccountEditPaymentDialog_stripePayment": [object Object], "StripePaymentV2_stripePayment": [object Object], "StripePaymentCollectionV2_stripePaymentCollection": [object Object], "SelectedStripePayment_stripePaymentCollection": [object Object], "AccountPaymentView_user": [object Object], "PaymentForm_user": [object Object], "Step4Payment_user": [object Object], "CartEntry_cartEntry": [object Object], "ReviewProductList_user": [object Object], "GiftMessageDialog_cart": [object Object], "GiftMessageReview_cart": [object Object], "ReviewForm_user": [object Object], "Step5Review_user": [object Object], "AlcoholForm_cart": [object Object], "StepAlcoholDOB_cart": [object Object], "GiftingOptionsForm_cart": [object Object], "GiftingCompletedView_cart": [object Object], "Step3GiftingOptions_cart": [object Object], "CheckoutStepper_viewer": [object Object], "SummaryPanel_viewer": [object Object], "Checkout_viewer": [object Object], "NavbarComponent_viewer": [object Object], "ShopLeftNavComponent_viewer": [object Object], "OrderItem_order": [object Object], "Cart_viewer": [object Object], "CartRightNavComponent_viewer": [object Object], "ProductDetailPurchaseInfo_product": [object Object], "ProductDetailsInfo_product": [object Object], "ProductReviewComment_productReview": [object Object], "ProductDetailsPage_viewer": [object Object], "AppComponent_viewer": [object Object], "RecentPostTile_blogPost": [object Object], "RecentPosts_viewer": [object Object], "BlogPostPage_viewer_20J5Pl": [object Object], "BlogPostTile_blogPost": [object Object], "BlogPage_viewer_1G22uz": [object Object], "ThisIsATreePage_viewer": [object Object], "AuthDialog_user_20e7Da": [object Object], "ReferralCodeLookup_viewer_1KiJL6": [object Object], "ProductDetailsPage_viewer_1iVCTk": [object Object], "TestComponent_user": [object Object], "ShopLandingPage_viewer": [object Object], "ReferralCodeGenerate_viewer": [object Object], "WeddingsPage_viewer": [object Object], "ReturnPage_viewer": [object Object], "FaqPage_viewer": [object Object], "PrivacyPolicyPage_viewer": [object Object], "PaymentsPage_viewer": [object Object], "AddressesPage_viewer": [object Object], "FavoritesPage_viewer": [object Object], "OrderItem_cart": [object Object], "OrdersPage_viewer": [object Object], "MyAccountPage_viewer": [object Object], "ResetPasswordPage_viewer": [object Object], "ReceiptPage_viewer_xeX6W": [object Object], "ProductsCatalog_viewer_4muyEu": [object Object], "CorporatePage_viewer": [object Object], "BecomeACeoPage_viewer": [object Object], "OrdersPage_viewer_3Qq0NA": [object Object], "HostATastingPage_viewer": [object Object], "BuyAgainButton_product": [object Object], "ProductDetailsPage_viewer_3VRWUf": [object Object] }
The strange part is that if I wipe node_modules
, and then run the regular command, it will not emit the artifacts because it cannot read .tsx. But if I run the language plugin command (which will fail and give the Unknown Document error), and then run the regular command, then the artifacts are created.
I've attempted to make a project to reproduce this error, but I haven't had luck reproducing it.
Any thoughts on what it could be?
Thanks!
When you are sending an input type undefined values are treated the same as nulls, It would be nice to not need to supply these when usng the variables types
Btw, thank you a lot for this library!
Reading through the changelog of VS Code 1.20 i found this:
Spaces got you down? When you type ., VS Code now shows all known properties for JavaScript and TypeScript, even if a property name contain whitespaces or other non-identifier characters.
It seems we need a new way to deal with hiding members other than simply prefixing a whitespace. I'm not sure if it is possible to use symbols or something similiar to accomplish this?
My project compiles the typescript files in the src
folder and writes it to a outputs
folder.
It always generates the __generated__
folder inside my src
folder, I may be wrong but I thought the artifactDirectory
should be used to specify on where everything should be written to.
Here is my yarn relay
:
"relay": "relay-compiler --src ./src --schema schema.graphql --extensions=tsx --extensions=ts --language typescript --artifactDirectory ./outputs/__generated__",
My .babelrc
:
...
"plugins": [
"@babel/plugin-transform-modules-commonjs",
["relay", { "artifactDirectory": "./outputs/__generated__" }]
]
I am using:
"react-relay": "^1.6.2",
"relay-runtime": "1.7.0-rc.1"
"babel-plugin-relay": "^1.6.2",
"relay-compiler": "^1.6.2",
"relay-compiler-language-typescript": "^1.1.1",
The __generated__
is always compiled at src/__generated__
and so the app doesn't start.
Am I missing something?
As reported by @ckknight https://twitter.com/ckknight/status/1026846806930468864, it appears that when one does not enable a single artefact directory –and thus fragment references get typed as any
rather than being imported from other artefacts– TS is unable to work with the types:
Type 'any' is not assignable to type 'unique symbol'.
I haven’t yet been able to find any issues on the TS issue tracker about this, so unsure right now how to proceed.
Maybe we should not emit the fragment reference typings when not using the single artefact directory feature, because those typings are moot in that case anyways?
Filing a ticket here to keep track of this external work alloy/DefinitelyTyped#1
So, I'm trying to get this working with CreateReactApp and running into some issues.
Typescript is complaining about the graphql.ts artifacts, lots of errors like this:
Given that this is a CreateReactApp which hasn't been ejected, I had to make these exceptions to these instructions:
I'm still compiling the artifacts into the subfolders rather than the root directory because CreateReactApp doesn't allow .babelrc
.
package.json
:
"relay": "relay-compiler --src ./src --schema ./../components/api/app/assets/javascripts/api/relay/schema.json --language typescript",
tsconfig.json
:
{
"compilerOptions": {
"target": "es2015",
"module": "esnext", // CreateReactApp won't let me change this
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strictNullChecks": false,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve"
},
"include": [
"src"
]
}
Hoping to find a workaround without ejecting my app; any insight into what causes these errors?
Just adding this issue to remind ourselves to get this added.
I attempted to do this earlier, but given that I still cannot install stuff with our lock-file, yarn shouted in my face.
Once we can npm install
without all this manual npm pack stuff I think we should look into setting up some CI stuff :)
From https://github.com/alloy/relay/pull/5#issuecomment-358279558
I think as soon as we have something running in the repo that sort of works - we should look into porting as many tests as possible from the relay-compiler repo - I'm just not sure where to start with that.
I don’t think we really need to do too much. Having a bunch of input/output tests like the ones merged in #4 and maybe some extra unit tests around the GraphQL tag finding aspect would probably be enough imo.
Are there specifics you were thinking of that need extra testing?
First - Thanks for all your work on this ❤️
I'm running into an issue with nested Fragment Containers and types after updating to 1.1.0.
My components are like this:
QueryRenderer
FragmentContainerOne
...
FragmentContainerTwo
My query contains both fragments:
query ContainerQuery() {
foo {
...FragmentContainerOne_foo
}
bar {
...FragmentContainerTwo_bar
}
}
FragmentContainerOne works fine and has the following Props:
interface Props {
foo: FragmentContainerOne_foo;
bar: FragmentContainerTwo_bar;
}
When I go to pass bar
into FragmentContainerTwo I get a type error:
Type 'ReadonlyArray<{ readonly id: string; readonly name: string; readonly " $refType": any; }>' is not assignable to type 'ReadonlyArray<_FragmentRefs<any>>'.
Type '{ readonly id: string; readonly name: string; readonly " $refType": any; }' is not assignable to type '_FragmentRefs<any>'.
Property '" $fragmentRefs"' is missing in type '{ readonly id: string; readonly name: string; readonly " $refType": any; }'.
Sorry this one is not edited to be a generic example since I think its more useful to have the exact error and my actual type is pretty simple.
If you've got any ideas let me know and I am happy to help figure this out. I can also create an example to reproduce if nothing jumps out at you from my description.
E.g. could there be a feature that causes the relay to create mocked data for a particular component.
It's a lot of files, sure, but it would make the initial buildout much easier (and keeps those initial data stubs up to date as the component / fragments change )
@alloy I have been fiddling around for several hours as I need to incorporate Relay in a module that is currently compiled with TS to a commonjs-module.
The result is that then the babel-relay-transform does not work. Changing to es2015 module fixes that part but breaks the interaction with other modules. I changed my babelrc to apply "transform-es2015-modules-commonjs" after the relay-transform, but that does not fix the issue.
Do you have any experience with this issue? I know this is not an issue directly related to this library, but I was thinking it was worth asking as I would assume it could also be an issue other people with experience. Feel free to just close this issue if it does not belong here.
When I run relay-compiler while using this plugin to generate TypeScript output, I get the following output and error:
> relay-compiler --src ./frontend/src --schema mydb_schema.graphql --language typescript --artifactDirectory relay-generated
Watchman: Watchman was not found in PATH. See https://facebook.github.io/watchman/docs/install.html for installation instructions
HINT: pass --watch to keep watching for changes.
Writing ts
ERROR:
Error writing modules:
RangeError: Maximum call stack size exceeded
at Object.createIdentifier (/src/node_modules/typescript/lib/typescript.js:48807:30)
at transformGraphQLEnumType (/src/node_modules/relay-compiler-language-typescript/lib/TypeScriptTypeTransformers.js:55:42)
at transformNonNullableInputType (/src/node_modules/relay-compiler-language-typescript/lib/TypeScriptTypeTransformers.js:79:16)
at transformInputType (/src/node_modules/relay-compiler-language-typescript/lib/TypeScriptTypeTransformers.js:63:13)
at /src/node_modules/relay-compiler-language-typescript/lib/TypeScriptTypeTransformers.js:89:30
at Array.map (<anonymous>)
at transformNonNullableInputType (/src/node_modules/relay-compiler-language-typescript/lib/TypeScriptTypeTransformers.js:86:14)
at transformInputType (/src/node_modules/relay-compiler-language-typescript/lib/TypeScriptTypeTransformers.js:63:13)
at /src/node_modules/relay-compiler-language-typescript/lib/TypeScriptTypeTransformers.js:89:30
at Array.map (<anonymous>)
Although I haven't yet created a minimal repro of the issue, the crash is caused when I use a particular type as input parameter to a query. The query is:
const query = graphql`
query DashboardRepoQuery($filter: DbRepoFilter) {
allDbRepos(filter: $filter) {
nodes {
slug
}
}
}
`;
And the DbRepoFilter type (which is auto-generated by Postgraphile) is:
input DbRepoFilter {
"""Filter by the object’s `slug` field."""
slug: StringFilter
"""Filter by the object’s `content` field."""
content: JSONFilter
"""Checks for all expressions in this list."""
and: [DbRepoFilter!]
"""Checks for any expressions in this list."""
or: [DbRepoFilter!]
"""Negates the expression."""
not: DbRepoFilter
}
If this info isn't sufficient, let me know and I can try to create a simpler and more self-contained repro.
ts/__generated__/appQuery.graphql.ts(3,10): error TS2305: Module '"/Users/eloy/Code/React/typescript-relay-modern-compiler/example/node_modules/@types/relay-runtime/index"' has no exported member 'ConcreteRequest'.
3 import { ConcreteRequest } from 'relay-runtime';
~~~~~~~~~~~~~~~
ts/components/__generated__/TodoApp_viewer.graphql.ts(4,10): error TS2305: Module '"/Users/eloy/Code/React/typescript-relay-modern-compiler/example/node_modules/@types/relay-runtime/index"' has no exported member 'FragmentReference'.
4 import { FragmentReference } from "relay-runtime";
~~~~~~~~~~~~~~~~~
ts/__generated__/appQuery.graphql.ts(8,33): error TS2304: Cannot find name 'TodoApp_viewer_ref'.
8 readonly " $fragments": TodoApp_viewer_ref;
~~~~~~~~~~~~~~~~~~
ts/app.tsx(74,25): error TS2322: Type '{ viewer: any; }' is not assignable to type 'IntrinsicAttributes & Props & { children?: ReactNode; }'.
Type '{ viewer: any; }' is not assignable to type 'Props'.
Property 'relay' is missing in type '{ viewer: any; }'.
74 return <TodoApp viewer={props.viewer} />;
~~~~~~~~~~~~~~~~~~~~~
ts/components/TodoApp.tsx(56,21): error TS2322: Type '{ viewer: TodoApp_viewer; }' is not assignable to type 'IntrinsicAttributes & Props & { children?: ReactNode; }'.
Type '{ viewer: TodoApp_viewer; }' is not assignable to type 'Props'.
Property 'relay' is missing in type '{ viewer: TodoApp_viewer; }'.
56 <TodoList viewer={this.props.viewer} />
~~~~~~~~~~~~~~~~~~~~~~~~~~
ts/components/TodoApp.tsx(57,40): error TS2322: Type '{ viewer: TodoApp_viewer; }' is not assignable to type 'IntrinsicAttributes & Props & { children?: ReactNode; }'.
Type '{ viewer: TodoApp_viewer; }' is not assignable to type 'Props'.
Property 'relay' is missing in type '{ viewer: TodoApp_viewer; }'.
57 {hasTodos && <TodoListFooter viewer={this.props.viewer} />}
~~~~~~~~~~~~~~~~~~~~~~~~~~
ts/components/TodoList.tsx(49,9): error TS2322: Type '{ key: string; todo: { readonly id: string; readonly complete: boolean | null; readonly " $fragme...' is not assignable to type 'IntrinsicAttributes & Props & { children?: ReactNode; }'.
Type '{ key: string; todo: { readonly id: string; readonly complete: boolean | null; readonly " $fragme...' is not assignable to type 'Props'.
Property 'relay' is missing in type '{ key: string; todo: { readonly id: string; readonly complete: boolean | null; readonly " $fragme...'.
49 key={node.id}
~~~~~~~~~~~~~50 todo={node}
~~~~~~~~~~~~~~~~~~~51 viewer={this.props.viewer}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ts/components/__generated__/TodoApp_viewer.graphql.ts(10,29): error TS2304: Cannot find name 'TodoListFooter_viewer_ref'.
10 readonly " $fragments": TodoListFooter_viewer_ref & TodoList_viewer_ref;
~~~~~~~~~~~~~~~~~~~~~~~~~
ts/components/__generated__/TodoApp_viewer.graphql.ts(10,57): error TS2304: Cannot find name 'TodoList_viewer_ref'.
10 readonly " $fragments": TodoListFooter_viewer_ref & TodoList_viewer_ref;
~~~~~~~~~~~~~~~~~~~
ts/components/__generated__/TodoList_viewer.graphql.ts(13,45): error TS2304: Cannot find name 'Todo_todo_ref'.
13 readonly " $fragments": Todo_todo_ref;
~~~~~~~~~~~~~
ts/components/__generated__/TodoList_viewer.graphql.ts(20,29): error TS2304: Cannot find name 'Todo_viewer_ref'.
20 readonly " $fragments": Todo_viewer_ref;
~~~~~~~~~~~~~~~
Hi there,
At the time of writing this issue, Relay is on 1.7.0-rc.1, so it is a little early to fix.
So I'm testing out the latest master branch of FB with persisted queries, and I'm running into the following error
> relay-compiler --src ./client --schema server/graphql/schema.graphql --extensions=js --extensions=tsx --extensions=ts --language typescript --persist --persist-output ./server/queryMap.json
HINT: pass --watch to keep watching for changes.
Writing ts
ERROR:
Error writing modules:
TypeError: Cannot read property 'indexOf' of undefined
at /node_modules/relay-compiler-language-typescript/lib/TypeScriptTypeTransformers.js:93:73
at Array.filter (<anonymous>)
at transformNonNullableInputType (/node_modules/relay-compiler-language-typescript/lib/TypeScriptTypeTransformers.js:93:14)
at Object.transformInputType (/node_modules/relay-compiler-language-typescript/lib/TypeScriptTypeTransformers.js:62:16)
at /node_modules/relay-compiler-language-typescript/lib/TypeScriptGenerator.js:296:82
at Array.map (<anonymous>)
at generateInputVariablesType (/node_modules/relay-compiler-language-typescript/lib/TypeScriptGenerator.js:295:99)
at Object.Root (/node_modules/relay-compiler-language-typescript/lib/TypeScriptGenerator.js:174:42)
at Object.visit (/node_modules/graphql/language/visitor.js:254:26)
at Object.visitIR [as visit] (/node_modules/graphql-compiler/lib/GraphQLIRVisitor.js:32:29)
Seems to be related to this line:
https://github.com/relay-tools/relay-compiler-language-typescript/blob/master/src/TypeScriptTypeTransformers.ts#L137
When I console.log state
, the shape is now
{
customScalars: {},
existingFragmentNames: {},
generatedInputObjectTypes: { DonationUpdateInput: 'pending' },
generatedFragments: {},
usedEnums: {},
usedFragments: {},
useHaste: false,
useSingleArtifactDirectory: false,
};
Where DonationUpdateInput
is a GraphQL Mutation Input.
It seems like inputFieldWhiteList
is no longer a part of TypeGeneratorOptions
Because it was renamed to optionalInputFields
Renaming all instances of inputFieldWhiteList
to optionalInputFields
fixed it for me.
You can check out the changes here: ONEHOPEWINE@120f447
After applying the above fix, only Queries (that are used for the third parameter for createRefetchContainer
) and Mutations are able to be parsed. All other fragments are not parsed, which includes the second parameter of RefetchContainer & createFragmentContainer, where a GQL query is a value to a key that is a React prop name. Not sure how to go forward from here.
Build files for persisted queries if you are curious. It requires React 16.5.2 because RelayContainer hooks into React.context.unstable_read. Its currently breaking for my use case because we use found-relay, which mutates the Relay context, and it seems like the Relay team are migrating to the new React.context API: https://github.com/ONEHOPEWINE/relay/releases/tag/1.7.1-rc.1
Facebook internally uses the Haste module system, which makes imports work without having to specify the directory where the module resides. This makes it naturally resistant against issues such as moving files around.
Here’s the maintained OSS version of Haste that’s used by Jest https://github.com/facebook/jest/tree/master/packages/jest-haste-map. I have never used it before, so not sure if we can easily use it for our needs, but I assume it would require a custom Babel plugin that would take a persisted map and rewrites imports at compile time.
As we discussed there's some options here:
1 Write in flow
2 Write in TS
3 A mix of the two. I'm thinking here that maintaining d.ts files for the GraphQLIR types is actually quite simple, it's almost a direct copy/paste from the official repo's flow types. This way we can implement in TS (and the remaining bits in flow)
DocumentNode[]
from the graphql
package.GraphQLIR
(and possibly a few other options) and return the TypeScript type definitions as text.If we can get the flow definitions for the relay-compiler package into flow - I'm actually thinking the 3rd approach might be the best way forward? It would allow us to not rely on too many handwritten typings and let each language do what they do best (in this regard).
For those that test their Relay containers by manually stubbing data, it would be nice to have the fragment reference related properties be optional so that those don’t need to be specified.
I don’t recall the exact mechanics of the future fragment reference support when TS 2.8 comes out, but would an alternative option be to somehow use a union, so that either the exact data or a correct fragment reference can be passed in?
const enum foo$ref { }
interface Props {
bar: string
}
function foo(x: Props | { " $refType": foo$ref }) { }
foo({ bar: "bar" })
foo({ " $refType": ({} as any) as foo$ref })
relay-compiler --src . --include 'components/**' 'pages/**' --schema 'api/schema.graphql' --language typescript --artifactDirectory 'generated'
Error: Cannot find module 'graphql-compiler'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:581:15)
at Function.Module._load (internal/modules/cjs/loader.js:507:25)
at Module.require (internal/modules/cjs/loader.js:637:17)
at require (internal/modules/cjs/helpers.js:22:18)
at Object.<anonymous> (/Users/steida/dev/este/node_modules/relay-compiler-language-typescript/lib/TypeScriptGenerator.js:21:23)
at Module._compile (internal/modules/cjs/loader.js:689:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
at Module.load (internal/modules/cjs/loader.js:599:32)
at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
at Function.Module._load (internal/modules/cjs/loader.js:530:3)
For example, using github
graphql schema.graphql
:
"""The possible states of an issue."""
enum IssueState {
"""An issue that is still open"""
OPEN
"""An issue that has been closed"""
CLOSED
}
It is generated in the following type, containing an extra and rare "%future added value"
.
export type IssueState = "CLOSED" | "OPEN" | "%future added value";
Source code:
Has this extra entry in the alias some especial meaning? It seems error prone.
If I try to update to Relay v2, still using v1.1.1 of this package, I get and error in TypeScriptTypeTransformers
regarding the breaking change inputFieldWhiteList
=> optionalInputFields
.
This code was fixed in master #78, but not released as a new npm package.
Is it possible?
I forgot to reply to your comments regarding runtime transformation.
My idea regarding transforming the typescript code (converting graphql
tagged template literals into require's) was simply that if we could create a single typescript transformer to handle both relay modern and relay classic (in pure classic or in compat mode) it would be much easier to set up a Relay project using TypeScript. I would like to get the experience regarding this into a state where one simply installs a plugin for the relay-compiler and a typescript transformer and then configures the way the typescript code is compiled and then moves along.
However, this is obviously something that needs to happen after we've gotten the relay-compiler stuff working.
Is there a reason to keep this private? I’ve already ran into a few situations where I may, for instance, want to CC one of the Relay team members.
Hi @alloy, thanks for the project.
I've tried it with my project and I get the following error when I use webpack-dev-server with react hot loader:
This error happen on page refresh, on HMR the page renders without such problems.
I would appreciate any ideas how that can be mitigated.
@kastermester What’s your NPM account, if any? So I can add you here https://www.npmjs.com/package/relay-compiler-language-typescript
Menu: [Dessert!]!
[{id: 'cakes'}, {id: 'pies'}]
from the serverstore.delete('cakes')
[null, {id: 'pies'}]
even though my typing says Dessert is guaranteedhow do you guys handle this?
is there some secret way to clean up all arrays & connections outside of the view layer?
should the type always list a possible null
?
Flagging an issue for future reference, this was merged recently into relay
:
facebook/relay#2677
This will break importing here: https://github.com/relay-tools/relay-compiler-language-typescript/blob/master/src/TypeScriptGenerator.ts#L6
Happy to open PR when a new release is cut with this change.
To save you the hassle of running what is currently in this repo, here's a simple test script:
#!/bin/bash
git clone [email protected]:kastermester/relay
cd relay
git checkout configurable-artifact-extensions
npm install && npm run build
cd dist/relay-runtime && npm pack && mv relay-runtime-1.4.1.tgz ..
cd ../relay-compiler && npm pack && mv relay-compiler-1.4.1.tgz ..
cd ../../..
git clone [email protected]:kastermester/typescript-relay-modern-compiler
cd typescript-relay-modern-compiler
npm install && npm install ../relay/dist/relay-compiler-1.4.1.tgz
npm run build && npm test
I suggest that I simply create a new repo with the new code (including tests) once we've fully determined the exact approach we're gonna take with implementing the plugin, and then we can simply leave this as a place for discussion the more general decisions. I'm really looking forward to getting this working :)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.