Skip to content

Best practice to mantain scalarSchemas option #655

Closed

Description

@taprile314

Is ther a way to keep up to date the scalarSchemas option with my zodValidations in a shared package?

The only way that I can think of right now is copying & pasting my zodValidations and setting them in the scalarSchemas as a string but I think there has to be another way like generating the zod string reading the source code of another function (but at the same time that sounds like overengineering to me).

Did anyone face this challenge?

Activity

  1. MH4GF commented on May 31, 2024

    @MH4GF
    Contributor

    I would think that if the scalarSchemas were out of date, the type-check would give an error, but isn't that what you are talking about?

  2. taprile314 commented on May 31, 2024

    @taprile314
    Author

    I would think that if the scalarSchemas were out of date, the type-check would give an error, but isn't that what you are talking about?

    No, that isn't what I was talking about in my issue.

  3. taprile314 commented on May 31, 2024

    @taprile314
    Author

    What I did to "resolve" this the following:

    I created a scalars package in my monorepo so frontend & backend can share the scalars code. In this repo y also export my zod schemas

    Then I did added an import line in the codegen generated files with the graphql-codegen add plugin and imported all my scalar package exports with an import alias

    Also I configured the schalarsSchema entry for each custom schema that I have I call the mapToScalarSchemasMap to map the schema function reference to a string that is a function call to my custom schema.

    Here is my codegen.ts

    import { CuitScalarSchema, NameScalarSchema, PasswordScalarSchema, PermissionScalarSchema, UsernameScalarSchema } from;
    const GRAPHQL_SCHEMA_URL = process.env.NEXT_PUBLIC_APP_GRAPHQL_API_URL;
    const CODEGEN_FOLDER_PATH = "./__generated/";
    const SCALARS_MODULE_IMPORT_ALIAS = 'scalars'
    
    const config: CodegenConfig = {
      overwrite: true,
      schema: GRAPHQL_SCHEMA_URL,
      documents: ["./src/**/*.{ts,tsx}"],
      generates: {
        [pathInsideFolder(CODEGEN_FOLDER_PATH, "gql/client/")]: {
          preset: "client",
          plugins: [],
          presetConfig: {
            gqlTagName: "gql"
          }
        },
        [pathInsideFolder(CODEGEN_FOLDER_PATH, "gql/zod-schemas.ts")]: {
          plugins: [
            "typescript-validation-schema",
            {
              add: { // here add an import line in the `typescript-validation-schema` generated files
                content: `import * as ${SCALARS_MODULE_IMPORT_ALIAS} from '@package/scalars';`
              }
            }
          ],
          config: {
            schema: "zod",
            importFrom: "./client/graphql",
            strictScalars: true,
            scalars: {
              CUIT: "string",
              Name: "number",
              Password: "string",
              Permission: "string",
              Username: "string",
            },
            scalarSchemas: { // here map each scalar with its schema reference to build a string calling that schema function
              CUIT: mapToScalarSchemasMap(CuitScalarSchema),
              Name: mapToScalarSchemasMap(NameScalarSchema),
              Password: mapToScalarSchemasMap(PasswordScalarSchema),
              Permimssion: mapToScalarSchemasMap(PermissionScalarSchema),
              Username: mapToScalarSchemasMap(UsernameScalarSchema)
            },
          }
        }
      }
    };
    
    export default config;
    
    function pathInsideFolder(folderPath: string, subpath: string): string {
      return path.join(folderPath, subpath);
    };
    
    function mapToScalarSchemasMap(reference: () => any) {
      return `${SCALARS_MODULE_IMPORT_ALIAS}.${reference.name}()`;
    }

    so the generated file looks like this:

    image

    and it works!!

    This way I can have all my scalar schema definition in one place and simply reuse them in frontend/backend

  4. Repository owner locked and limited conversation to collaborators on Jul 13, 2024
  5. converted this issue into a discussion #736 on Jul 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions