function updateDirectives (oldVnode , vnode ) { if (oldVnode.data.directives || vnode.data.directives) { _update(oldVnode, vnode) } }
test('camelcase fieldNames', () => { const { field_name, an_object } = createFieldDefinitions([{ field_name: true, an_object: { sub_field: true } }], { camelCase: true }) expect(field_name.key).toEqual('field_name') expect(field_name.fieldName).toEqual('fieldName') expect(field_name.extensions.directives[0]).toMatchObject({ name: 'proxy', args: { from: 'field_name' } }) expect(an_object.fieldName).toEqual('anObject') expect(an_object.value.sub_field.fieldName).toEqual('subField') })
test('setup custom filter input type @reference by', async () => { const schema = await buildSchema(api => { api.loadSource(({ addSchemaTypes }) => { addSchemaTypes(` type Product implements Node { related: Product @reference(by:"test") } `) }) }) const inputType = schema.getType('ProductFilterInput').toConfig() const { related: { type, extensions } } = inputType.fields expect(Object.keys(inputType.fields).sort()).toEqual(['id', 'item', 'items', 'related']) expect(type).toEqual(schema.getType('ProductQueryOperatorInput')) expect(extensions.directives[0]).toMatchObject({ name: 'reference', args: { by: 'test' } }) expect(extensions.isInferred).toBeUndefined() })
function applyFieldExtensions (typeComposer, customExtensions = {}) { const allFieldExtensions = { ...customExtensions, ...fieldExtensions } typeComposer.getFieldNames().forEach(fieldName => { const extensions = typeComposer.getFieldExtensions(fieldName) const directives = (extensions.directives || []).filter(({ name }) => allFieldExtensions.hasOwnProperty(name) ) directives.forEach(({ name, args }) => { const { apply } = allFieldExtensions[name] || {} if (typeof apply === 'function') { const fieldConfig = typeComposer.getFieldConfig(fieldName) const resolve = fieldConfig.resolve || defaultFieldResolver const newFieldConfig = apply(args, { ...fieldConfig, resolve }, { typeComposer, fieldName }) if (newFieldConfig) { typeComposer.extendField(fieldName, newFieldConfig) } } }) }) }
describe('pagination with @paginate directive', () => { test('get @paginate directive info', async () => { const query = ` query { custom: allCustomContentType(perPage: 5) @paginate { edges { node } } } ` const res = parseQuery(app.schema.getSchema(), query) expect(res.directives.paginate.belongsToArgs).toBeNull() expect(res.directives.paginate.typeName).toEqual('CustomContentType') expect(res.directives.paginate.fieldName).toEqual('allCustomContentType') expect(res.directives.paginate.args).toHaveProperty('perPage') expect(res.directives.paginate.args.perPage.value).toEqual('5') }) })
test('create page with pagination', async () => { const { pages } = await createApp(api => { api.loadSource(store => { store.addCollection('Post') }) }) const page = pages.createPage({ path: '/page', component: './__fixtures__/PagedPage.vue' }) expect(page.id).toEqual('76a99cb48c7cfa8dbb91bba1ced599cd') expect(page.path).toEqual('/page') expect(page.publicPath).toEqual('/page/') expect(page.internal.query.paginate.typeName).toEqual('Post') const route = pages.getRoute(page.internal.route) expect(route.path).toEqual('/page/:page(\\d+)?/') expect(route.internal.path).toEqual('/page') expect(route.internal.regexp).toEqual(/^\/page(?:\/(\d+))?(?:\/)?$/i) expect(route.internal.query.directives).toHaveProperty('paginate') })
/** * Normalize raw function directives into object format. */ function normalizeDirectives(options) { const dirs = options.directives if (dirs) { for (const key in dirs) { const def = dirs[key] if (typeof def === 'function') { dirs[key] = { bind: def, update: def } } } } }
describe('pagination belongsTo with @paginate directive', () => { test('get @paginate directive info for belongsTo', async () => { const query = ` query { customContentType(id: "1", path: { eq: "/test" }) { belongsTo(perPage: 5) @paginate { edges { item: node { ... on Node { id } } } } } } ` const res = parseQuery(app.schema.getSchema(), query) expect(res.directives.paginate.typeName).toEqual('CustomContentType') expect(res.directives.paginate.fieldName).toEqual('customContentType') expect(res.directives.paginate.belongsToArgs).toHaveProperty('id') expect(res.directives.paginate.belongsToArgs).toHaveProperty('path') expect(res.directives.paginate.args).toHaveProperty('perPage') expect(res.directives.paginate.args.perPage.value).toEqual('5') }) })
test('camelcase fieldNames', () => { const { field_name, an_object } = createFieldDefinitions([{ field_name: true, an_object: { sub_field: true } }], { camelCase: true }) expect(field_name.key).toEqual('field_name') expect(field_name.fieldName).toEqual('fieldName') expect(field_name.extensions.directives[0]).toMatchObject({ name: 'proxy', args: { from: 'field_name' } }) expect(an_object.fieldName).toEqual('anObject') expect(an_object.value.sub_field.fieldName).toEqual('subField') })
test('setup custom filter input type with @proxy', async () => { const schema = await buildSchema(api => { api.loadSource(({ addSchemaTypes }) => { addSchemaTypes(` type Product implements Node { testRelated: Product @proxy(from:"related") } `) }) }) const inputType = schema.getType('ProductFilterInput').toConfig() const { testRelated: { type, extensions } } = inputType.fields expect(Object.keys(inputType.fields).sort()).toEqual(['id', 'item', 'items', 'testRelated']) expect(type).toEqual(schema.getType('ProductQueryOperatorInput')) expect(extensions.directives[0]).toMatchObject({ name: 'proxy', args: { from: 'related' } }) expect(extensions.isInferred).toBeUndefined() })
test('setup custom filter input type @reference by', async () => { const schema = await buildSchema(api => { api.loadSource(({ addSchemaTypes }) => { addSchemaTypes(` type Product implements Node { related: Product @reference(by:"test") } `) }) }) const inputType = schema.getType('ProductFilterInput').toConfig() const { related: { type, extensions } } = inputType.fields expect(Object.keys(inputType.fields).sort()).toEqual(['id', 'item', 'items', 'related']) expect(type).toEqual(schema.getType('ProductQueryOperatorInput')) expect(extensions.directives[0]).toMatchObject({ name: 'reference', args: { by: 'test' } }) expect(extensions.isInferred).toBeUndefined() })
test('setup custom filter input type with @proxy', async () => { const schema = await buildSchema(api => { api.loadSource(({ addSchemaTypes }) => { addSchemaTypes(` type Product implements Node { testRelated: Product @proxy(from:"related") } `) }) }) const inputType = schema.getType('ProductFilterInput').toConfig() const { testRelated: { type, extensions } } = inputType.fields expect(Object.keys(inputType.fields).sort()).toEqual(['id', 'item', 'items', 'testRelated']) expect(type).toEqual(schema.getType('ProductQueryOperatorInput')) expect(extensions.directives[0]).toMatchObject({ name: 'proxy', args: { from: 'related' } }) expect(extensions.isInferred).toBeUndefined() })
describe('pagination with @paginate directive', () => { test('get @paginate directive info', async () => { const query = ` query { custom: allCustomContentType(perPage: 5) @paginate { edges { node } } } ` const res = parseQuery(app.schema.getSchema(), query) expect(res.directives.paginate.belongsToArgs).toBeNull() expect(res.directives.paginate.typeName).toEqual('CustomContentType') expect(res.directives.paginate.fieldName).toEqual('allCustomContentType') expect(res.directives.paginate.args).toHaveProperty('perPage') expect(res.directives.paginate.args.perPage.value).toEqual('5') }) })
test('create page with pagination', async () => { const { pages } = await createApp(api => { api.loadSource(store => { store.addCollection('Post') }) }) const page = pages.createPage({ path: '/page', component: './__fixtures__/PagedPage.vue' }) expect(page.id).toEqual('76a99cb48c7cfa8dbb91bba1ced599cd') expect(page.path).toEqual('/page') expect(page.publicPath).toEqual('/page/') expect(page.internal.query.paginate.typeName).toEqual('Post') const route = pages.getRoute(page.internal.route) expect(route.path).toEqual('/page/:page(\\d+)?/') expect(route.internal.path).toEqual('/page') expect(route.internal.regexp).toEqual(/^\/page(?:\/(\d+))?(?:\/)?$/i) expect(route.internal.query.directives).toHaveProperty('paginate') })
function applyFieldExtensions (typeComposer, customExtensions = {}) { const allFieldExtensions = { ...customExtensions, ...fieldExtensions } typeComposer.getFieldNames().forEach(fieldName => { const extensions = typeComposer.getFieldExtensions(fieldName) const directives = (extensions.directives || []).filter(({ name }) => allFieldExtensions.hasOwnProperty(name) ) directives.forEach(({ name, args }) => { const { apply } = allFieldExtensions[name] || {} if (typeof apply === 'function') { const fieldConfig = typeComposer.getFieldConfig(fieldName) const resolve = fieldConfig.resolve || defaultFieldResolver const newFieldConfig = apply(args, { ...fieldConfig, resolve }, { typeComposer, fieldName }) if (newFieldConfig) { typeComposer.extendField(fieldName, newFieldConfig) } } }) }) }