2018-05-07 17:41:22 +09:00
// see https://github.com/apollographql/graphql-tools/blob/master/docs/source/schema-directives.md#marking-strings-for-internationalization
2018-05-08 12:23:42 +09:00
import { addGraphQLDirective , addGraphQLSchema } from '../modules/graphql' ;
2018-05-07 17:41:22 +09:00
import { SchemaDirectiveVisitor } from 'graphql-tools' ;
import { defaultFieldResolver } from 'graphql' ;
2018-05-09 10:38:21 +09:00
import { Collections } from '../modules/collections' ;
import Vulcan from '../modules/config' ;
import { isIntlField } from '../modules/intl' ;
import { Connectors } from './connectors' ;
import pickBy from 'lodash/pickBy' ;
2018-05-07 17:41:22 +09:00
class IntlDirective extends SchemaDirectiveVisitor {
visitFieldDefinition ( field , details ) {
const { resolve = defaultFieldResolver } = field ;
field . resolve = async function ( ... args ) {
const fieldValue = await resolve . apply ( this , args ) ;
const context = args [ 2 ] ;
const graphQLArguments = args [ 1 ] ;
const locale = graphQLArguments . locale || context . locale ;
if ( typeof fieldValue === 'object' ) {
2018-05-09 11:22:19 +09:00
// intl'd field, return current locale
return fieldValue [ locale ] ;
2018-05-07 17:41:22 +09:00
} else {
2018-05-09 11:22:19 +09:00
// not an object, return field itself
2018-05-07 17:41:22 +09:00
return fieldValue ;
}
} ;
}
}
addGraphQLDirective ( { intl : IntlDirective } ) ;
2018-05-09 10:38:21 +09:00
addGraphQLSchema ( ` directive @intl on FIELD_DEFINITION ` ) ;
const migrateIntlFields = async ( defaultLocale ) => {
if ( ! defaultLocale ) {
throw new Error ( ` Please pass the id of the locale to which to migrate your current content (e.g. migrateIntlFields('en')) ` ) ;
}
Collections . forEach ( async collection => {
const schema = collection . simpleSchema ( ) . _schema ;
const intlFields = pickBy ( schema , isIntlField ) ;
const intlFieldsNames = Object . keys ( intlFields ) ;
if ( intlFieldsNames . length ) {
2018-05-09 11:22:19 +09:00
console . log ( ` ### Found ${ intlFieldsNames . length } field to migrate for collection ${ collection . options . collectionName } : ${ intlFieldsNames . join ( ', ' ) } ### \n ` ) ; // eslint-disable-line no-console
2018-05-09 10:38:21 +09:00
const intlFieldsWithLocale = intlFieldsNames . map ( f => ` ${ f } . ${ defaultLocale } ` ) ;
// find all documents with one or more unmigrated intl fields
const selector = { $or : intlFieldsWithLocale . map ( f => ( { [ f ] : { $exists : false } } ) ) } ;
const documentsToMigrate = await Connectors . find ( collection , selector ) ;
if ( documentsToMigrate . length ) {
2018-05-09 11:22:19 +09:00
console . log ( ` -> found ${ documentsToMigrate . length } documents to migrate \n ` ) ; // eslint-disable-line no-console
2018-05-09 10:38:21 +09:00
documentsToMigrate . forEach ( doc => {
2018-05-09 11:22:19 +09:00
console . log ( ` // Migrating document ${ doc . _id } ` ) ; // eslint-disable-line no-console
2018-05-09 10:38:21 +09:00
const modifier = { $set : { } } ;
intlFieldsNames . forEach ( f => {
if ( doc [ f ] && ! doc [ f ] [ defaultLocale ] ) {
2018-05-09 11:22:19 +09:00
console . log ( ` -> migrating field ${ f } : ${ doc [ f ] } ` ) ; // eslint-disable-line no-console
2018-05-09 10:38:21 +09:00
modifier . $set [ f ] = { [ defaultLocale ] : doc [ f ] }
}
} ) ;
// update document
Connectors . update ( collection , { _id : doc . _id } , modifier ) ;
2018-05-09 11:22:19 +09:00
console . log ( '\n' ) ; // eslint-disable-line no-console
2018-05-09 10:38:21 +09:00
} ) ;
}
}
} ) ;
}
Vulcan . migrateIntlFields = migrateIntlFields ;