Skip to content
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

Can't import enum from generated GraphQL type definition files #765

Closed
vincaslt opened this issue Jan 11, 2024 · 10 comments
Closed

Can't import enum from generated GraphQL type definition files #765

vincaslt opened this issue Jan 11, 2024 · 10 comments

Comments

@vincaslt
Copy link

The GraphQL type definitions are generated into admin.types.d.ts file as per: https://github.com/Shopify/shopify-api-js/blob/3e55838fe4f192d5d639670834f2a002800ba271/packages/api-codegen-preset/src/helpers/api-configs.ts#L24

The problem I'm facing is that I can't import enum from the generated file - .d.ts files are discarded during compilation.

So this import won't work:

import { ImageContentType } from "~/types/admin.types";

[ERROR] Could not resolve "~/types/admin.types":
image

Am I maybe wrong to try to import stuff from those files and they should be used somehow differently?

@vincaslt
Copy link
Author

For the time being this is a workaround (in .graphqlrc.ts):

  const defaultCfg = shopifyApiProject({
    apiType: ApiType.Admin,
    apiVersion: LATEST_API_VERSION,
    documents: ["./app/**/*.{js,ts,jsx,tsx}"],
    outputDir: "./app/types",
  });

  // Change the output file of extension for enum exports to work
  defaultCfg.extensions.codegen.generates[`${outputDir}/admin.types.ts`] =
    defaultCfg.extensions.codegen.generates[`${outputDir}/admin.types.d.ts`];
  delete defaultCfg.extensions.codegen.generates[
    `${outputDir}/admin.types.d.ts`
  ];

  const config = {
    default: defaultCfg,
    // ...
  }

@matteodepalo
Copy link
Contributor

Hi @vincaslt, would it work if you used import type { ImageContentType } from "~/types/admin.types"; instead of import?

@dan-gamble
Copy link

I've just hit this too. Unfortunately you can't use enums from a .d.ts file. A couple of examples where I'm doing that:

const metafieldTypes = Object.values(MetafieldOwnerType)
		const response = await client.request(metafieldDefinitionsQuery, {
			variables: {
				first: 10,
				after,
				ownerType: type,
				sortKey: MetafieldDefinitionSortKeys.PinnedPosition,
				reverse: true,
			},
		})

The import type doesn't work either. Still getting the same error message

✘ [ERROR] Could not resolve "../../../types/admin.types"

    src/resources/metafield-definition/utils.ts:4:64:
      4 │ ...onSortKeys, MetafieldOwnerType } from '../../../types/admin.types';~~~~~~~~~~~~~~~~~~~~~~~~~~~~


✘ [ERROR] Could not resolve "../../../types/admin.types"

    src/resources/metafield-definition/utils.ts:4:64:
      4 │ ...onSortKeys, MetafieldOwnerType } from '../../../types/admin.types';

@vincaslt
Copy link
Author

Hi @vincaslt, would it work if you used import type { ImageContentType } from "~/types/admin.types"; instead of import?

No, I have tried it, enum is not used as a type here, so it's double issue.

image

image

@matteodepalo
Copy link
Contributor

Ok thank you for trying that, we've put this issue in our backlog and we'll work on it.

@kusyka911
Copy link

kusyka911 commented Jan 22, 2024

@vincaslt This should be solved in @shopify/api-codegen-preset. But while it's not solved, you can fix it on project level.
Modify .graphqlrc.ts file with the following code. And you will get union types instead of enums. (at least this works for me).

  for (const key in defaultProject.extensions.codegen.generates) {
    if (Object.prototype.hasOwnProperty.call(defaultProject.extensions.codegen.generates, key)) {
      const element = defaultProject.extensions.codegen.generates[key] as unknown as CodegenConfig;
      if (!element) continue;
      if (element.config) element.config.enumsAsTypes = true;
      else element.config = { enumsAsTypes: true }
    }
  }
Full config here
import fs from "fs";

import { LATEST_API_VERSION } from "@shopify/shopify-api";
import { shopifyApiProject, ApiType } from "@shopify/api-codegen-preset";
import type { IGraphQLConfig } from "graphql-config";
import type { CodegenConfig } from '@graphql-codegen/cli';

function getConfig() {
  const defaultProject = shopifyApiProject({
    apiType: ApiType.Admin,
    apiVersion: LATEST_API_VERSION,
    documents: ["./app/**/*.{js,ts,jsx,tsx}"],
    outputDir: "./app/types",
  });

  // customize graphql-codegen configuration
  for (const key in defaultProject.extensions.codegen.generates) {
    if (Object.prototype.hasOwnProperty.call(defaultProject.extensions.codegen.generates, key)) {
      const element = defaultProject.extensions.codegen.generates[key] as unknown as CodegenConfig;
      if (!element) continue;
      if (element.config) element.config.enumsAsTypes = true;
      else element.config = { enumsAsTypes: true }
    }
  }

  const config: IGraphQLConfig = {
    projects: {
      default: defaultProject,
    },
  };

  let extensions: string[] = [];
  try {
    extensions = fs.readdirSync("./extensions");
  } catch {
    // ignore if no extensions
  }

  for (const entry of extensions) {
    const extensionPath = `./extensions/${entry}`;
    const schema = `${extensionPath}/schema.graphql`;
    if (!fs.existsSync(schema)) {
      continue;
    }
    config.projects[entry] = {
      schema,
      documents: [`${extensionPath}/**/*.graphql`],
    };
  }

  return config;
}

module.exports = getConfig();

In case you want to use enums - you can modify configuration in a way to generate .ts files instead of .d.ts. See graphql-codegen typescript docs for more details.

@muchisx
Copy link

muchisx commented Jan 26, 2024

@kusyka911

Hi! Thank you for the proposed solution, I want to use enums to be compiled into values for run-time usage. I entered the docs documentation that you added but I don't understand exactly how or where to create the config file, do you have info? Do I need to install another package?

Copy link
Contributor

We're labeling this issue as stale because there hasn't been any activity on it for 60 days. While the issue will stay open and we hope to resolve it, this helps us prioritize community requests.

You can add a comment to remove the label if it's still relevant, and we can re-evaluate it.

@github-actions github-actions bot added the Stale label Mar 27, 2024
@paulomarg paulomarg transferred this issue from Shopify/shopify-api-js Apr 11, 2024
@github-actions github-actions bot removed the Stale label Apr 12, 2024
@aborchew
Copy link

Just want to give @kusyka911 a shoutout here - thanks! 🙏🏻

@paulomarg
Copy link
Contributor

paulomarg commented May 30, 2024

Hey folks, we've recently made some improvements to the @shopify/graphql-codegen package, which now allows configuring .ts outputs. Apps should be able to pull enums from those files directly and use them in your code normally.

To use that, you can:

  • If you're using the preset directly: change your output from *.d.ts to .ts in your codegen config
  • If you're using shopifyApiTypes or shopifyApiProject: pass in the declarations: false setting

Please see the README for more details. This will be available in the next release, but for extra context this is the PR that made the change: #939.

I'm going to close this issue since I believe the original issue is resolved, but please let us know if you still get errors with the next version!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants