graphql-kit / graphql-faker

🎲 Mock or extend your GraphQL API with faked data. No coding required.
MIT License
2.69k stars 225 forks source link

CLI command to generate a valid graphQl schema from the faker one #147

Closed johannchopin closed 3 years ago

johannchopin commented 3 years ago

It could be useful to have a CLI command that would create a new schema file from the schema.faker.graphql without the faker directives (@fake, @examples and @listLength).

Example you have this schema.faker.graphql...

type Book {
  id: String!
  title: String! @fake(type: words)
  subtitle: String @fake(type: companyCatchPhrase)
  publication: Int @examples(values: [161213760, 163213760, 163513760])
  authors: [Author] @listLength(min: 1, max: 5)
}

...you run graphql-faker generate-schema and you get a new file schema.graphql:

type Book {
  id: String!
  title: String!
  subtitle: String
  publication: Int
  authors: [Author]
}

What do you think of this idea?

johannchopin commented 3 years ago

@IvanGoncharov I already implement the script for my use case so there won't be a lot of work there for you. What do you think of this idea? Could I have a green light to open a PR?

ojczeo commented 3 years ago

@johannchopin that's sounds interesting. Could you share it somewhere?

johannchopin commented 3 years ago

Sadly the maintainers (@IvanGoncharov, @RomanHotsiy) aren't really active on this repo so I won't waste time by opening PR. Here is the simple getSchemaFromContent helper that takes a faker shema string as a parameter and return it without the faker directives:

const FAKER_DIRECTIVE_MATCHER = / @fake\((.*?)\)\n/g
const EXAMPLES_DIRECTIVE_MATCHER = / @examples\(values: \[(.*?)\]\)\n/g
const LISTLENGTH_DIRECTIVE_MATCHER = / @listLength\((.*?)\)\n/g
const MATCHERS = [FAKER_DIRECTIVE_MATCHER, EXAMPLES_DIRECTIVE_MATCHER, LISTLENGTH_DIRECTIVE_MATCHER]

const replaceAll = (str: string, find: string, replace: string): string => {
  return str.split(find).join(replace)
}

const getAllFakerDirectivesFromContent = (content: string): string[] => {
  let directives: string[] = []
  MATCHERS.forEach((matcher) => {
    directives = [...directives, ...Array.from(content.matchAll(matcher), (m) => { return m[0] })]
  })

  return directives
}

export const getSchemaFromContent = (content: string): string => {
  const directives = getAllFakerDirectivesFromContent(content)

  directives.forEach((directive) => {
    content = replaceAll(content, directive, '\n')
  })

  return content
}

Hope it will help you @ojczeo 👍

ojczeo commented 3 years ago

@johannchopin thanks man!