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

Allow passing a schema directly to createSqlmancerClient #122

Open
yanickrochon opened this issue Jun 18, 2020 · 0 comments
Open

Allow passing a schema directly to createSqlmancerClient #122

yanickrochon opened this issue Jun 18, 2020 · 0 comments
Labels
enhancement New feature or request

Comments

@yanickrochon
Copy link

The current implementation currently requires loading the schema and definitions twice

import Knex from 'knex';
import { 
  createSqlmancerClient,
  makeSqlmancerSchema
} from 'sqlmancer';
import { typeDefs, resolvers } from './schema';

const knex = Knex({
  client: 'pg',
  connection: process.env.PG_CONNECTION_STRING,
});
const client = createSqlmancerClient('./src/**/*.graphql', knex);
const schema = makeSqlmancerSchema({ typeDefs, resolvers });
const apollo = new ApolloServer({ schema });

The function should allow passing the schema directly instead, or treating any first String argument as a glob, essentially being backward compatible with current implementation.

Implementation

export function createSqlmancerClient<T extends GenericSqlmancerClient = GenericSqlmancerClient>(
  schema: string | object,
  knex: Knex
): T {
  // load schema from glob pattern
  if (typeof schema === 'string') {
    const glob = schema;
    const typeDefs = getTypeDefsFromGlob(glob)

    if (!typeDefs || !typeDefs.definitions.length) {
      throw new Error(`Found no files with valid type definitions using glob pattern "${glob}"`)
    }

    schema = makeSqlmancerSchema({ typeDefs })
  }

  const { dialect, models } = getSqlmancerConfig(schema)

  return Object.assign(knex, {
    models: _.mapValues(models, (model: Model) => {
      const options = { knex, dialect }
      const { builders, readOnly } = model
      return {
        findById: (id: ID) => new builders.findById(options, id),
        findMany: () => new builders.findMany(options),
        findOne: () => new builders.findOne(options),
        paginate: () => new builders.paginate(options),
        createOne: readOnly ? undefined : (input: any) => new builders.createOne!(options, input),
        createMany: readOnly ? undefined : (input: Array<any>) => new builders.createMany!(options, input),
        deleteById: readOnly ? undefined : (id: ID) => new builders.deleteById!(options, id),
        deleteMany: readOnly ? undefined : () => new builders.deleteMany!(options),
        updateById: readOnly ? undefined : (id: ID, input: any) => new builders.updateById!(options, id, input),
        updateMany: readOnly ? undefined : (input: any) => new builders.updateMany!(options, input),
      }
    }),
  }) as any
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants