Vulcan/packages/vulcan-lib/lib/modules/graphql_templates.js

531 lines
11 KiB
JavaScript
Raw Normal View History

2018-06-05 10:17:59 +09:00
import { Utils } from './utils';
export const convertToGraphQL = (fields, indentation) => {
return fields.length > 0 ? fields.map(f => fieldTemplate(f, indentation)).join(`\n`) : '';
}
export const arrayToGraphQL = fields => fields.map(f => `${f.name}: ${f.type}`).join(', ');
/*
For backwards-compatibility reasons, args can either be a string or an array of objects
*/
export const getArguments = args => {
if (Array.isArray(args) && args.length > 0) {
return `(${arrayToGraphQL(args)})`;
} else if (typeof args === 'string') {
return `(${args})`;
} else {
return '';
}
}
/* ------------------------------------- Generic Field Template ------------------------------------- */
export const fieldTemplate = ({ name, type, args, directive, description, required }, indentation = '') =>
`${description ? `${indentation}# ${description}\n` : ''}${indentation}${name}${getArguments(args)}: ${type}${required ? '!' : ''} ${directive ? directive : ''}`;
/* ------------------------------------- Main Type ------------------------------------- */
2018-06-04 17:59:18 +09:00
/*
The main type
type Movie{
_id: String
title: String
description: String
createdAt: Date
}
*/
export const mainTypeTemplate = ({ typeName, description, interfaces, fields }) =>
`# ${description}
type ${typeName} ${interfaces.length ? `implements ${interfaces.join(`, `)} ` : ''}{
${convertToGraphQL(fields, ' ')}
}
2018-06-04 15:45:13 +09:00
`;
/* ------------------------------------- Selector Types ------------------------------------- */
/*
2018-06-04 17:59:18 +09:00
The selector type is used to query for one or more documents
type MovieSelectorInput {
2018-06-04 15:45:13 +09:00
AND: [MovieSelectorInput]
OR: [MovieSelectorInput]
id: String
id_not: String
id_in: [String!]
id_not_in: [String!]
...
name: String
name_not: String
name_in: [String!]
name_not_in: [String!]
...
}
2018-06-04 15:45:13 +09:00
see https://www.opencrud.org/#sec-Data-types
2018-06-04 15:45:13 +09:00
*/
export const selectorInputTemplate = ({ typeName, fields }) =>
`input ${typeName}SelectorInput {
AND: [${typeName}SelectorInput]
OR: [${typeName}SelectorInput]
${convertToGraphQL(fields, ' ')}
}`;
/*
2018-06-04 17:59:18 +09:00
The unique selector type is used to query for exactly one document
type MovieSelectorUniqueInput {
_id: String
2018-06-04 15:45:13 +09:00
slug: String
}
*/
export const selectorUniqueInputTemplate = ({ typeName, fields }) =>
`input ${typeName}SelectorUniqueInput {
documentId: String
slug: String
${convertToGraphQL(fields, ' ')}
}`;
/*
2018-06-04 17:59:18 +09:00
The orderBy type defines which fields a query can be ordered by
2018-06-04 15:45:13 +09:00
enum MovieOrderByInput {
title
createdAt
}
*/
export const orderByInputTemplate = ({ typeName, fields }) =>
`enum ${typeName}OrderByInput {
foobar
${fields.join('\n ')}
}`;
2018-06-04 15:45:13 +09:00
/* ------------------------------------- Query Types ------------------------------------- */
/*
2018-06-04 17:59:18 +09:00
A query for a single document
2018-06-04 15:45:13 +09:00
movie(input: SingleMovieInput) : SingleMovieOutput
*/
2018-06-05 10:17:59 +09:00
export const singleQueryTemplate = ({ typeName }) => `${Utils.camelCaseify(typeName)}(input: Single${typeName}Input): Single${typeName}Output`;
2018-06-04 15:45:13 +09:00
/*
2018-06-04 17:59:18 +09:00
A query for multiple documents
2018-06-04 15:45:13 +09:00
movies(input: MultiMovieInput) : MultiMovieOutput
*/
2018-06-05 10:17:59 +09:00
export const multiQueryTemplate = ({ typeName }) => `${Utils.camelCaseify(typeName)}s(input: Multi${typeName}Input): Multi${typeName}Output`;
/* ------------------------------------- Query Input Types ------------------------------------- */
/*
The argument type when querying for a single document
type SingleMovieInput {
documentId: String
slug: String
enableCache: Boolean
}
*/
export const singleInputTemplate = ({ typeName }) =>
`input Single${typeName}Input {
selector: ${typeName}SelectorUniqueInput
# Whether to enable caching for this query
enableCache: Boolean
}`;
/*
2018-06-04 17:59:18 +09:00
The argument type when querying for multiple documents
2018-06-04 15:45:13 +09:00
type MultiMovieInput {
terms: JSON
offset: Int
limit: Int
enableCache: Boolean
}
*/
2018-06-04 15:45:13 +09:00
export const multiInputTemplate = ({ typeName }) =>
`input Multi${typeName}Input {
# A JSON object that contains the query terms used to fetch data
terms: JSON,
# How much to offset the results by
offset: Int,
# A limit for the query
limit: Int,
# Whether to enable caching for this query
enableCache: Boolean
2018-06-04 15:45:13 +09:00
# OpenCRUD fields
where: ${typeName}SelectorInput
orderBy: ${typeName}OrderByInput
skip: Int
after: String
before: String
first: Int
last: Int
}`;
/* ------------------------------------- Query Output Types ------------------------------------- */
/*
The type for the return value when querying for a single document
2018-06-04 17:59:18 +09:00
type SingleMovieOuput{
2018-06-05 11:51:25 +09:00
result: Movie
}
*/
export const singleOutputTemplate = ({ typeName }) =>
`type Single${typeName}Output{
2018-06-05 11:51:25 +09:00
result: ${typeName}
2018-06-04 15:45:13 +09:00
}`;
/*
2018-06-04 17:59:18 +09:00
The type for the return value when querying for multiple documents
2018-06-04 15:45:13 +09:00
type MultiMovieOuput{
2018-06-05 11:51:25 +09:00
results: [Movie]
2018-06-04 15:45:13 +09:00
totalCount: Int
}
*/
export const multiOutputTemplate = ({ typeName }) =>
2018-06-04 15:45:13 +09:00
`type Multi${typeName}Output{
2018-06-05 11:51:25 +09:00
results: [${typeName}]
totalCount: Int
2018-06-04 15:45:13 +09:00
}`;
2018-06-05 11:51:25 +09:00
/* ------------------------------------- Query Queries ------------------------------------- */
2018-06-06 10:35:06 +09:00
/*
Single query used on the client
query singleMovieQuery($input: SingleMovieInput) {
movie(input: $input) {
result {
_id
name
__typename
}
__typename
}
}
*/
export const singleClientTemplate = ({ typeName, fragmentName, extraQueries }) =>
2018-06-06 10:35:06 +09:00
`query single${typeName}Query($input: Single${typeName}Input) {
2018-06-05 11:51:25 +09:00
${Utils.camelCaseify(typeName)}(input: $input) {
result {
...${fragmentName}
2018-06-05 11:51:25 +09:00
}
2018-06-06 10:35:06 +09:00
__typename
2018-06-05 11:51:25 +09:00
}
${extraQueries ? extraQueries : ''}
}`;
2018-06-06 10:35:06 +09:00
/*
Multi query used on the client
mutation multiMovieQuery($input: MultiMovieInput) {
movies(input: $input) {
results {
_id
name
__typename
}
totalCount
__typename
}
}
*/
export const multiClientTemplate = ({ typeName, fragmentName, extraQueries }) =>
2018-06-06 10:35:06 +09:00
`query multi${typeName}Query($input: Multi${typeName}Input) {
2018-06-05 11:51:25 +09:00
${Utils.camelCaseify(typeName)}s(input: $input) {
results {
...${fragmentName}
2018-06-05 11:51:25 +09:00
}
totalCount
2018-06-06 10:35:06 +09:00
__typename
2018-06-05 11:51:25 +09:00
}
${extraQueries ? extraQueries : ''}
}`;
/* ------------------------------------- Mutation Types ------------------------------------- */
/*
2018-06-04 17:59:18 +09:00
Mutation for creating a new document
2018-06-04 15:45:13 +09:00
createMovie(input: CreateMovieInput) : MovieOutput
*/
2018-06-04 15:45:13 +09:00
export const createMutationTemplate = ({ typeName }) =>
`create${typeName}(input: Create${typeName}Input) : ${typeName}Output`;
/*
2018-06-04 17:59:18 +09:00
Mutation for updating an existing document
2018-06-04 15:45:13 +09:00
updateMovie(input: UpdateMovieInput) : MovieOutput
*/
2018-06-04 15:45:13 +09:00
export const updateMutationTemplate = ({ typeName }) =>
`update${typeName}(input: Update${typeName}Input) : ${typeName}Output`;
/*
2018-06-04 17:59:18 +09:00
Mutation for updating an existing document; or creating it if it doesn't exist yet
2018-06-04 15:45:13 +09:00
upsertMovie(input: UpsertMovieInput) : MovieOutput
*/
2018-06-04 15:45:13 +09:00
export const upsertMutationTemplate = ({ typeName }) =>
`upsert${typeName}(input: Upsert${typeName}Input) : ${typeName}Output`;
/*
2018-06-04 17:59:18 +09:00
Mutation for deleting an existing document
2018-06-04 15:45:13 +09:00
deleteMovie(input: DeleteMovieInput) : MovieOutput
*/
2018-06-04 15:45:13 +09:00
export const deleteMutationTemplate = ({ typeName }) =>
`delete${typeName}(input: Delete${typeName}Input) : ${typeName}Output`;
/* ------------------------------------- Mutation Input Types ------------------------------------- */
/*
2018-06-04 17:59:18 +09:00
Type for create mutation input argument
type CreateMovieInput {
data: CreateMovieDataInput!
}
*/
export const createInputTemplate = ({ typeName }) =>
`input Create${typeName}Input{
data: Create${typeName}DataInput!
2018-06-04 15:45:13 +09:00
}`;
/*
2018-06-04 17:59:18 +09:00
Type for update mutation input argument
type UpdateMovieInput {
selector: MovieSelectorUniqueInput!
data: UpdateMovieDataInput!
}
*/
2018-06-04 15:45:13 +09:00
export const updateInputTemplate = ({ typeName }) =>
`input Update${typeName}Input{
selector: ${typeName}SelectorUniqueInput!
data: Update${typeName}DataInput!
2018-06-04 15:45:13 +09:00
}`;
/*
2018-06-04 17:59:18 +09:00
Type for upsert mutation input argument
Note: upsertInputTemplate uses same data type as updateInputTemplate
type UpsertMovieInput {
selector: MovieSelectorUniqueInput!
data: UpdateMovieDataInput!
}
*/
export const upsertInputTemplate = ({ typeName }) =>
`input Upsert${typeName}Input{
selector: ${typeName}SelectorUniqueInput!
data: Update${typeName}DataInput!
2018-06-04 15:45:13 +09:00
}`;
/*
2018-06-04 17:59:18 +09:00
Type for delete mutation input argument
type DeleteMovieInput {
selector: MovieSelectorUniqueInput!
}
*/
export const deleteInputTemplate = ({ typeName }) =>
`input Delete${typeName}Input{
selector: ${typeName}SelectorUniqueInput!
2018-06-04 15:45:13 +09:00
}`;
/*
2018-06-04 17:59:18 +09:00
Type for the create mutation input argument's data property
type CreateMovieDataInput {
title: String
description: String
}
*/
export const createDataInputTemplate = ({ typeName, fields }) =>
`input Create${typeName}DataInput {
${convertToGraphQL(fields, ' ')}
}`;
/*
2018-06-04 17:59:18 +09:00
Type for the update mutation input argument's data property
type UpdateMovieDataInput {
title: String
description: String
}
*/
export const updateDataInputTemplate = ({ typeName, fields }) =>
`input Update${typeName}DataInput {
${convertToGraphQL(fields, ' ')}
}`;
2018-06-04 15:45:13 +09:00
/* ------------------------------------- Mutation Output Type ------------------------------------- */
/*
2018-06-04 17:59:18 +09:00
Type for the return value of all mutations
2018-06-04 15:45:13 +09:00
type MovieOutput {
data: Movie
}
*/
2018-06-04 15:45:13 +09:00
export const mutationOutputTemplate = ({ typeName }) =>
`type ${typeName}Output{
data: ${typeName}
2018-06-04 15:45:13 +09:00
}`;
2018-06-05 11:51:25 +09:00
/* ------------------------------------- Mutation Queries ------------------------------------- */
2018-06-06 10:35:06 +09:00
/*
Create mutation query used on the client
mutation createMovie($input: CreateMovieInput) {
createMovie(input: $input) {
data {
_id
name
__typename
}
__typename
}
}
*/
export const createClientTemplate = ({ typeName, fragmentName }) =>
`mutation create${typeName}($input: Create${typeName}Input) {
create${typeName}(input: $input) {
data {
...${fragmentName}
}
}
}`;
2018-06-06 10:35:06 +09:00
/*
Update mutation query used on the client
mutation updateMovie($input: UpdateMovieInput) {
updateMovie(input: $input) {
data {
_id
name
__typename
}
__typename
}
}
*/
export const updateClientTemplate = ({ typeName, fragmentName }) =>
`mutation update${typeName}($input: Update${typeName}Input) {
update${typeName}(input: $input) {
data {
...${fragmentName}
}
}
}`;
2018-06-06 10:35:06 +09:00
/*
Upsert mutation query used on the client
mutation upsertMovie($input: UpsertMovieInput) {
upsertMovie(input: $input) {
data {
_id
name
__typename
}
__typename
}
}
*/
export const upsertClientTemplate = ({ typeName, fragmentName }) =>
`mutation upsert${typeName}($input: Upsert${typeName}Input) {
upsert${typeName}(input: $input) {
data {
...${fragmentName}
}
}
}`;
2018-06-06 10:35:06 +09:00
/*
Delete mutation query used on the client
mutation deleteMovie($input: DeleteMovieInput) {
deleteMovie(input: $input) {
data {
_id
name
__typename
}
__typename
}
}
*/
export const deleteClientTemplate = ({ typeName, fragmentName }) =>
`mutation delete${typeName}($input: Delete${typeName}Input) {
delete${typeName}(input: $input) {
data {
...${fragmentName}
}
}
}`;