Git Product home page Git Product logo

garph's Introduction

Screen Recording 2023-10-04 at 15 43 17

Note We just announced Support Plan for Step CI

Important For users migrating from Postman and Insomnia, see issues #29 and #30 respectively

Welcome

Step CI is an open-source API Quality Assurance framework

  • Language-agnostic. Configure easily using YAML, JSON or JavaScript
  • REST, GraphQL, gRPC, tRPC, SOAP. Test different API types in one workflow
  • Self-hosted. Test services on your network, locally and CI/CD
  • Integrated. Play nicely with others

Read the Docs

Try the Online Playground

Join us on Discord

Get started

  1. Install the CLI

    Using Node.js

    npm install -g stepci
    

    Note: Make sure you're using the LTS version of Node.js

    Using Homebrew

    brew install stepci
    
  2. Create example workflow

    workflow.yml

    version: "1.1"
    name: Status Check
    env:
      host: example.com
    tests:
      example:
        steps:
          - name: GET request
            http:
              url: https://${{env.host}}
              method: GET
              check:
                status: /^20/

    Note: You can also also use JSON format to configure your workflow

  3. Run the workflow

    stepci run workflow.yml
    
    PASS  example
    
    Tests: 0 failed, 1 passed, 1 total
    Steps: 0 failed, 1 passed, 1 total
    Time:  0.559s, estimated 1s
    
    Workflow passed after 0.559s
    

Documentation

Documentation is available on docs.stepci.com

Examples

You can find example workflows under examples/

Community

Join our community on Discord and GitHub

Contributing

As an open-source project, we welcome contributions from the community. If you are experiencing any bugs or want to add some improvements, please feel free to open an issue or pull request

Support Plan

Get Pro-level support with SLA, onboarding, prioritized feature-requests and bugfixes.

Learn more

Book us with Cal.com

Privacy

By default, the CLI collects anonymous usage data, which includes:

  • Unique user ID
  • OS Name
  • Node Version
  • CLI Version
  • Command (stepci init, stepci run, stepci generate)
  • Environment (Local, Docker, CI/CD)

Note The usage analytics can be disabled by setting STEPCI_DISABLE_ANALYTICS environment variable

License

The source code is distributed under Mozilla Public License terms

garph's People

Contributors

gaiusvalerius avatar lorefnon avatar mishushakov avatar na2na-p avatar noverby avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

garph's Issues

Automatic Filters

Adds automatic filtering based on the shape of your data like in Gatsby.js

InferResolversStrict not checking resolver params correctly

Hey, here's something I'd like to understand:

Given the following code, InferResolversStrict will happily accept getUsername as a resolver, although its arguments are wrong. I think this is related to the fact that the first arg is supposed to be parent: any, which checks against id: string. However, the number of args isn't enforced either (it should be 4 instead of 1).

(I don't think it's a problem with Deno's TS compiler options as those are pretty strict by default.)

Please enlighten me. 😄

import { graphql } from "npm:graphql"
import { buildSchema, g, InferResolversStrict } from "npm:garph"

function getUsername(id: string): string {
  return "User#" + id
}

const queryType = g.type("Query", {
  username: g.string().args({
    id: g.id(),
  }),
})

const resolvers: InferResolversStrict<
  { Query: typeof queryType },
  {}
> = {
  Query: {
    username: getUsername, // wrong
    // username: (_, args, __, ___) => getUsername(args.id), // correct
  },
}

const query = Deno.args[0]
const schema = buildSchema({ g, resolvers })
const result = await graphql({
  schema,
  source: query,
  rootValue: resolvers,
})

console.log(JSON.stringify(result, null, 2))

Small details in example schema implementation

I was looking at your example in the readme and noticed a few issues:

  1. You specify a description for the greet field, but it is not shown in the Produces the following GraphQL schema code below. Assuming the description is preserved, it would be cool to show that!

This second one is a bit more pedantic (feel free to ignore!).

The name argument is specified as optional, but it is used as if it were non-optional.

The current implementation would take a query

query {
  greet
}

And return

{
  "greet": "Hello, null"
}

Yoga Next.js Edge

export const config = {
  runtime: 'edge'
}

export const schema = buildSchema({ g, resolvers })

// Next.JS + Yoga API
const yoga = createYoga({
  schema,
  graphqlEndpoint: '/api/graphql'
})

export default yoga.handleRequest

Type visibility

Some fields on the classes need to be readonly, some need to be private

Directives

Add support for specifying and implementing GraphQL directives in Garph

Example:

const d = g.directive('Name', { param: g.string() }, ['FIELD', 'ARGUMENT'])

g.type('Query', {
  test: g.string()
    .args({
      test: g.string().addDirective(d, { param: 'Hello' })
    })
    .addDirective(d, { param: 'Hello' })
})
.addDirective(d, { param: 'Hello' })

Need to resolve the type like pothos.

const builder = new SchemaBuilder({});

builder.queryType({
  fields: (t) => ({
    hello: t.string({
      args: {
        name: t.arg.string(),
      },
      resolve: (parent, { name }) => `hello, ${name || 'World'}`,
    }),
  }),
});

How to handle field level resolvers?

Say you have a relationship Authors to Books. The Book type has a field author, which could be a field level resolver to avoid the n+1 problem. Defining the schema for this would be like:

const authorType = g.type('Author', {
  name: g.string(),
})

const bookType = g.type('Book', {
  title: g.string(),
  author: g.ref(bookType)
})

const queryType = g.type('Query', {
  books: g.ref(authorType).list(),
})

The resolver would be something like:

const resolvers: InferResolvers<{ Query: typeof queryType }, {}> = {
  Query: {
    async books(parent, args, context, info) {
      const allBooks = db.findAllBooks()
      // does not include author - TS error saying it's missing `author`
      return allBooks
    },
  },
}

Is it possible for this to be setup to know that there's a field level resolver called author somewhere that will satisfy the requirement? As is, this is a TS error, and I have to use a DeepOmit utility type to ignore the need for books.

So far, I have thought about it being optional, but in reality, it's not optional. The schema needs to say this is required, but the resolver needs to be allowed to return without it. This is super challenging for TS to know there's a field resolver somewhere, but at least there could be something like g.fieldResolver() which makes the field optional when using InferResolvers. If someone leaves it off, it will throw a GraphQL error.

Helper methods: `resolve`

Specify resolvers directly in schema

Example:

g.type('Query', {
  test: g.string().resolve(() => 'Hello World')
})

Middleware

.use((parent, args, context, info) => {})

If used on an object, use should apply to all fields on that object

Subscriptions

Subscriptions are currently not supported by Garph. We want to fix this

  • Add subscriptions to resolvers' type-inference (InferResolvers)
  • Add subscriptions to the GraphQL layer
    Blocked by graphql-compose/graphql-compose#405
  • Add documentation article

Use Pothos as a GraphQL builder

Hi!

I discovered you this morning, great idea with GQL and tRPC-like experience!

I briefly reviewed the project. I know it's in a very early stage and much functionality will be added later. Maybe there is a way to accelerate it by using Pothos as a query builder? It has numerous useful plugins (prisma integration, errors as types and more). I miss these features in this project a lot. Also, it's battle-tested with many examples. Would be nice to have it there.

If this is completely absurd, sorry for the trouble, I'm not an expert 😄

Auth

Allow implementing auth rules and logic directly in Garph

Semantics

We want to propose a optional, but recommended field type which helps with semantics, especially on bigger projects

Before:

const blogType = g
  .type("Blog", {
    title: g
      .string()
      .optional()
      .list()
      .args({
        test: g.string(),
      })
      .description("The title of the blog"),
  })
  .description("The blog of the user");

After:

const newBlogType = g
  .type("Blog", {
    title: g
      .field(g.string().optional().list())
      .args({
        test: g.string(),
      })
      .description("The title of the blog"),
  })
  .description("The blog of the user");

Notice the change in LoC

Default nullability

I want to be able to configure default nullability of the schema. The nullability setting should change both the output of the schema and type inference

Helper Methods: `or`

or helper would help create a Union with the current type and the type specified in or

The use-case for the feature include error handling

Example:

const error = g.type('Error', {
  message: g.string()
})

g.type('Test', {
  test: g.string()
})
.or(error)

Validation

How this might look in Garph:

const queryType = g.type('Query', {
  greet: g.string().validate(s => s.length > 50)
})

How to handle schema declarations in separate files?

All of the examples have all the schemas in the same file, then build the schema at the end for the bottom of the file.

Is it possible to put these declarations in separate files?

I tried to use convertSchema, but to put them all as references into the types array and got the error:

Error: Type with name "undefined" does not exists

Then I tried to import g, and export g so I could use the same reference to g in separate files and got the error:

Error: Type with name "Query" does not exists

After that, I moved all of them into the same file, and it works fine. Is it possible to keep the schemas in separate files?

Extend field types when in reference

Example:

export const userType = g.type('User', {
    id: g.string(),
    email: g.string(),
    name: g.string().optional(),
});

const userMutationType = g.type('Mutation', {
    register: g.ref(userType)
        .args({
            email: g.string().required(),
            password: g.string().required(),
            name: g.string().optional()
        })
        .description('Register a new user')
});

const userQueryType = g.type('Query', {
    me: g.ref(userType)
    .extend({             // <-- extend the user type with additional fields
        createdAt: g.string(),
        updatedAt: g.string()
    })
        .description('User who is currently logged in')
})

This issue pertains to the userQueryType object and proposes extending it to include additional fields, createdAt and updatedAt, without duplicating the schema definition.

Zod Integration

Here's a proposal

  1. Create garph types from Zod types:
const type = g.zodType('name', yourZodType)
  1. Create garph scalars from Zod types:
const type = g.zodScalar('name', yourZodType)
  1. Create garph inputs from Zod types:
const type = g.zodInput('name', yourZodType)
  1. Create Zod types from Garph types:
type.toZod()

Where can I import convertSchema?

At the README, near the bottom, it mentions you can build your schema with convertSchema, but I can't seem to find that function anywhere.

Also, I believe there's a typo right above it, with buildSchema

Screen Shot 2023-03-22 at 5 20 38 PM

Dedicated support for loaders

Thank you for creating this library. The API for defining schemas is really nice.

I am curious if you'd be interested in supporting batch loaders at the framework level similar to mercurius or quarkus.

Having batching supported at framework level reduces quite a bit of boilerplate around the usual dance of defining data loaders, attaching them to context & later using them in actual resolver.

Drawing inspiration from mercurius loaders, I'd imagine we could have something like:

const batchResolvers: InferBatchResolvers<
  { Query: typeof queryType; },
  {}
> = {
  Query: {
    greet: (queries, context) => queries.map(({ parent, args, info }) => `Hello, ${args.name}`),
  },
};

export const schema = buildSchema({ g, batchResolvers });

So a batch resolver is similar to a normal resolver except it receives an array of queries rather than a single query.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.