Skip to content

Allow passing a schema directly to createSqlmancerClient #122

@yanickrochon

Description

@yanickrochon

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
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions