diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 84d808db..83a41a9f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: - run: yarn install --frozen-lockfile - run: yarn test env: - CI: true + CI: true eslint: runs-on: ubuntu-latest steps: @@ -41,6 +41,7 @@ jobs: ${{ runner.os }}-yarn- - run: yarn install --frozen-lockfile - run: yarn lint-fix + - run: yarn prettier - name: Auto commit fixed code id: auto-commit-action uses: stefanzweifel/git-auto-commit-action@v4 diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 00000000..0fea5603 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,6 @@ +{ + "trailingComma": "es5", + "printWidth": 120, + "singleQuote": true, + "arrowParens": "avoid" +} diff --git a/codegen.yml b/codegen.yml index 4b9016f8..af7c6a2a 100644 --- a/codegen.yml +++ b/codegen.yml @@ -1,5 +1,5 @@ overwrite: true -schema: "./test.graphql" +schema: './test.graphql' generates: gen/types.ts: plugins: @@ -17,11 +17,11 @@ generates: constraint: minLength: min # same as ['min', '$1'] maxLength: max - startsWith: ["matches", "/^$1/"] - endsWith: ["matches", "/$1$/"] - contains: ["matches", "/$1/"] - notContains: ["matches", "/^((?!$1).)*$/"] - pattern: ["matches", "/$1/"] + startsWith: ['matches', '/^$1/'] + endsWith: ['matches', '/$1$/'] + contains: ['matches', '/$1/'] + notContains: ['matches', '/^((?!$1).)*$/'] + pattern: ['matches', '/$1/'] format: # For example, `@constraint(format: "uri")`. this case $1 will be "uri". # Therefore the generator generates yup schema `.url()` followed by `uri: 'url'` @@ -33,7 +33,7 @@ generates: # you need to add the logic using `yup.addMethod`. # see: https://github.com/jquense/yup#addmethodschematype-schema-name-string-method--schema-void ipv4: ipv4 - min: ["min", "$1 - 1"] - max: ["max", "$1 + 1"] + min: ['min', '$1 - 1'] + max: ['max', '$1 + 1'] exclusiveMin: min - exclusiveMax: max \ No newline at end of file + exclusiveMax: max diff --git a/package.json b/package.json index 2c28541b..02f71900 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,8 @@ "build:module": "tsc -p tsconfig.module.json", "lint": "eslint --ext .ts .", "lint-fix": "eslint --fix --ext .ts .", + "prettier": "prettier --ignore-path .gitignore --write --list-different \"**/*.{ts,graphql,yml}\"", + "prettier:check": "prettier --ignore-path .gitignore --check \"**/*.{ts,graphql,yml}\"", "generate": "run-p build:* && graphql-codegen", "prepublish": "run-p build:*" }, @@ -54,6 +56,7 @@ "eslint": "^8.7.0", "jest": "^27.4.7", "npm-run-all": "^4.1.5", + "prettier": "2.5.1", "ts-jest": "^27.1.3", "typescript": "^4.5.4", "yup": "^0.32.11" diff --git a/src/config.ts b/src/config.ts index 2759b7f3..0125018d 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,6 +1,6 @@ -import { TypeScriptPluginConfig } from "@graphql-codegen/typescript"; +import { TypeScriptPluginConfig } from '@graphql-codegen/typescript'; -export type ValidationSchema = "yup"; +export type ValidationSchema = 'yup'; export interface DirectiveConfig { [directive: string]: { diff --git a/src/directive.ts b/src/directive.ts index 25590721..de72be2b 100644 --- a/src/directive.ts +++ b/src/directive.ts @@ -1,12 +1,6 @@ -import { - ConstArgumentNode, - ConstDirectiveNode, - ConstValueNode, - Kind, - valueFromASTUntyped, -} from "graphql"; -import { DirectiveConfig, DirectiveObjectArguments } from "./config"; -import { isConvertableRegexp } from "./regexp"; +import { ConstArgumentNode, ConstDirectiveNode, ConstValueNode, Kind, valueFromASTUntyped } from 'graphql'; +import { DirectiveConfig, DirectiveObjectArguments } from './config'; +import { isConvertableRegexp } from './regexp'; export interface FormattedDirectiveConfig { [directive: string]: FormattedDirectiveArguments; @@ -22,8 +16,7 @@ export interface FormattedDirectiveObjectArguments { const isFormattedDirectiveObjectArguments = ( arg: FormattedDirectiveArguments[keyof FormattedDirectiveArguments] -): arg is FormattedDirectiveObjectArguments => - arg !== undefined && !Array.isArray(arg); +): arg is FormattedDirectiveObjectArguments => arg !== undefined && !Array.isArray(arg); // ```yml // directives: @@ -49,9 +42,7 @@ const isFormattedDirectiveObjectArguments = ( // } // } // } -export const formatDirectiveConfig = ( - config: DirectiveConfig -): FormattedDirectiveConfig => { +export const formatDirectiveConfig = (config: DirectiveConfig): FormattedDirectiveConfig => { return Object.fromEntries( Object.entries(config).map(([directive, arg]) => { const formatted = Object.fromEntries( @@ -59,8 +50,8 @@ export const formatDirectiveConfig = ( if (Array.isArray(val)) { return [arg, val]; } - if (typeof val === "string") { - return [arg, [val, "$1"]]; + if (typeof val === 'string') { + return [arg, [val, '$1']]; } return [arg, formatDirectiveObjectArguments(val)]; }) @@ -84,14 +75,12 @@ export const formatDirectiveConfig = ( // 'uri': ['url', '$2'], // 'email': ['email'], // } -export const formatDirectiveObjectArguments = ( - args: DirectiveObjectArguments -): FormattedDirectiveObjectArguments => { +export const formatDirectiveObjectArguments = (args: DirectiveObjectArguments): FormattedDirectiveObjectArguments => { const formatted = Object.entries(args).map(([arg, val]) => { if (Array.isArray(val)) { return [arg, val]; } - return [arg, [val, "$2"]]; + return [arg, [val, '$2']]; }); return Object.fromEntries(formatted); }; @@ -118,34 +107,25 @@ export const formatDirectiveObjectArguments = ( // email: String! @required(msg: "message") @constraint(minLength: 100, format: "email") // } // ``` -export const buildApi = ( - config: FormattedDirectiveConfig, - directives: ReadonlyArray -): string => +export const buildApi = (config: FormattedDirectiveConfig, directives: ReadonlyArray): string => directives - .map((directive) => { + .map(directive => { const directiveName = directive.name.value; const argsConfig = config[directiveName]; - return buildApiFromDirectiveArguments( - argsConfig, - directive.arguments ?? [] - ); + return buildApiFromDirectiveArguments(argsConfig, directive.arguments ?? []); }) - .join(""); + .join(''); -const buildApiSchema = ( - validationSchema: string[] | undefined, - argValue: ConstValueNode -): string => { +const buildApiSchema = (validationSchema: string[] | undefined, argValue: ConstValueNode): string => { if (!validationSchema) { - return ""; + return ''; } const schemaApi = validationSchema[0]; - const schemaApiArgs = validationSchema.slice(1).map((templateArg) => { + const schemaApiArgs = validationSchema.slice(1).map(templateArg => { const gqlSchemaArgs = apiArgsFromConstValueNode(argValue); return applyArgToApiSchemaTemplate(templateArg, gqlSchemaArgs); }); - return `.${schemaApi}(${schemaApiArgs.join(", ")})`; + return `.${schemaApi}(${schemaApiArgs.join(', ')})`; }; const buildApiFromDirectiveArguments = ( @@ -153,18 +133,15 @@ const buildApiFromDirectiveArguments = ( args: ReadonlyArray ): string => { return args - .map((arg) => { + .map(arg => { const argName = arg.name.value; const validationSchema = config[argName]; if (isFormattedDirectiveObjectArguments(validationSchema)) { - return buildApiFromDirectiveObjectArguments( - validationSchema, - arg.value - ); + return buildApiFromDirectiveObjectArguments(validationSchema, arg.value); } return buildApiSchema(validationSchema, arg.value); }) - .join(""); + .join(''); }; const buildApiFromDirectiveObjectArguments = ( @@ -172,23 +149,20 @@ const buildApiFromDirectiveObjectArguments = ( argValue: ConstValueNode ): string => { if (argValue.kind !== Kind.STRING) { - return ""; + return ''; } const validationSchema = config[argValue.value]; return buildApiSchema(validationSchema, argValue); }; -const applyArgToApiSchemaTemplate = ( - template: string, - apiArgs: any[] -): string => { +const applyArgToApiSchemaTemplate = (template: string, apiArgs: any[]): string => { const matches = template.matchAll(/[$](\d+)/g); for (const match of matches) { const placeholder = match[0]; // `$1` const idx = parseInt(match[1], 10) - 1; // start with `1 - 1` const apiArg = apiArgs[idx]; if (!apiArg) { - template = template.replace(placeholder, ""); + template = template.replace(placeholder, ''); continue; } if (template === placeholder) { @@ -196,7 +170,7 @@ const applyArgToApiSchemaTemplate = ( } template = template.replace(placeholder, apiArg); } - if (template !== "") { + if (template !== '') { return stringify(template, true); } return template; @@ -204,9 +178,9 @@ const applyArgToApiSchemaTemplate = ( const stringify = (arg: any, quoteString?: boolean): string => { if (Array.isArray(arg)) { - return arg.map((v) => stringify(v, true)).join(","); + return arg.map(v => stringify(v, true)).join(','); } - if (typeof arg === "string") { + if (typeof arg === 'string') { if (isConvertableRegexp(arg)) { return arg; } @@ -214,11 +188,7 @@ const stringify = (arg: any, quoteString?: boolean): string => { return JSON.stringify(arg); } } - if ( - typeof arg === "boolean" || - typeof arg === "number" || - typeof arg === "bigint" - ) { + if (typeof arg === 'boolean' || typeof arg === 'number' || typeof arg === 'bigint') { return `${arg}`; } return JSON.stringify(arg); diff --git a/src/graphql.ts b/src/graphql.ts index 3f069e4b..871d60af 100644 --- a/src/graphql.ts +++ b/src/graphql.ts @@ -1,15 +1,7 @@ -import { - ListTypeNode, - NonNullTypeNode, - NamedTypeNode, - TypeNode, -} from "graphql"; +import { ListTypeNode, NonNullTypeNode, NamedTypeNode, TypeNode } from 'graphql'; -export const isListType = (typ?: TypeNode): typ is ListTypeNode => - typ?.kind === "ListType"; -export const isNonNullType = (typ?: TypeNode): typ is NonNullTypeNode => - typ?.kind === "NonNullType"; -export const isNamedType = (typ?: TypeNode): typ is NamedTypeNode => - typ?.kind === "NamedType"; +export const isListType = (typ?: TypeNode): typ is ListTypeNode => typ?.kind === 'ListType'; +export const isNonNullType = (typ?: TypeNode): typ is NonNullTypeNode => typ?.kind === 'NonNullType'; +export const isNamedType = (typ?: TypeNode): typ is NamedTypeNode => typ?.kind === 'NamedType'; -export const isInput = (kind: string) => kind.includes("Input"); +export const isInput = (kind: string) => kind.includes('Input'); diff --git a/src/index.ts b/src/index.ts index da4e0c32..b865b318 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,17 +1,10 @@ -import { transformSchemaAST } from "@graphql-codegen/schema-ast"; -import { YupSchemaVisitor } from "./yup/index"; -import { ValidationSchemaPluginConfig } from "./config"; -import { - oldVisit, - PluginFunction, - Types, -} from "@graphql-codegen/plugin-helpers"; -import { GraphQLSchema } from "graphql"; +import { transformSchemaAST } from '@graphql-codegen/schema-ast'; +import { YupSchemaVisitor } from './yup/index'; +import { ValidationSchemaPluginConfig } from './config'; +import { oldVisit, PluginFunction, Types } from '@graphql-codegen/plugin-helpers'; +import { GraphQLSchema } from 'graphql'; -export const plugin: PluginFunction< - ValidationSchemaPluginConfig, - Types.ComplexPluginOutput -> = ( +export const plugin: PluginFunction = ( schema: GraphQLSchema, _documents: Types.DocumentFile[], config: ValidationSchemaPluginConfig @@ -25,10 +18,10 @@ export const plugin: PluginFunction< // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - const generated = result.definitions.filter((def) => typeof def === "string"); + const generated = result.definitions.filter(def => typeof def === 'string'); return { prepend: buildImports(), - content: "\n" + [...generated].join("\n"), + content: '\n' + [...generated].join('\n'), }; }; diff --git a/src/regexp.ts b/src/regexp.ts index 2d4a52ba..4c33bd30 100644 --- a/src/regexp.ts +++ b/src/regexp.ts @@ -1,3 +1,2 @@ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#advanced_searching_with_flags -export const isConvertableRegexp = (maybeRegexp: string): boolean => - /^\/.*\/[dgimsuy]*$/.test(maybeRegexp); +export const isConvertableRegexp = (maybeRegexp: string): boolean => /^\/.*\/[dgimsuy]*$/.test(maybeRegexp); diff --git a/src/yup/index.ts b/src/yup/index.ts index 28eeebc4..5f275187 100644 --- a/src/yup/index.ts +++ b/src/yup/index.ts @@ -1,5 +1,5 @@ -import { isInput, isNonNullType, isListType, isNamedType } from "./../graphql"; -import { ValidationSchemaPluginConfig } from "../config"; +import { isInput, isNonNullType, isListType, isNamedType } from './../graphql'; +import { ValidationSchemaPluginConfig } from '../config'; import { InputValueDefinitionNode, NameNode, @@ -7,20 +7,14 @@ import { GraphQLSchema, InputObjectTypeDefinitionNode, EnumTypeDefinitionNode, -} from "graphql"; -import { - DeclarationBlock, - indent, -} from "@graphql-codegen/visitor-plugin-common"; -import { TsVisitor } from "@graphql-codegen/typescript"; -import { buildApi, formatDirectiveConfig } from "../directive"; +} from 'graphql'; +import { DeclarationBlock, indent } from '@graphql-codegen/visitor-plugin-common'; +import { TsVisitor } from '@graphql-codegen/typescript'; +import { buildApi, formatDirectiveConfig } from '../directive'; const importYup = `import * as yup from 'yup'`; -export const YupSchemaVisitor = ( - schema: GraphQLSchema, - config: ValidationSchemaPluginConfig -) => { +export const YupSchemaVisitor = (schema: GraphQLSchema, config: ValidationSchemaPluginConfig) => { const tsVisitor = new TsVisitor(schema, config); const importTypes: string[] = []; @@ -28,10 +22,7 @@ export const YupSchemaVisitor = ( return { buildImports: (): string[] => { if (config.importFrom && importTypes.length > 0) { - return [ - importYup, - `import { ${importTypes.join(", ")} } from '${config.importFrom}'`, - ]; + return [importYup, `import { ${importTypes.join(', ')} } from '${config.importFrom}'`]; } return [importYup]; }, @@ -40,18 +31,14 @@ export const YupSchemaVisitor = ( importTypes.push(name); const shape = node.fields - ?.map((field) => - generateInputObjectFieldYupSchema(config, tsVisitor, schema, field, 2) - ) - .join(",\n"); + ?.map(field => generateInputObjectFieldYupSchema(config, tsVisitor, schema, field, 2)) + .join(',\n'); return new DeclarationBlock({}) .export() - .asKind("function") + .asKind('function') .withName(`${name}Schema(): yup.SchemaOf<${name}>`) - .withBlock( - [indent(`return yup.object({`), shape, indent("})")].join("\n") - ).string; + .withBlock([indent(`return yup.object({`), shape, indent('})')].join('\n')).string; }, EnumTypeDefinition: (node: EnumTypeDefinitionNode) => { const enumname = tsVisitor.convertName(node.name.value); @@ -60,27 +47,25 @@ export const YupSchemaVisitor = ( if (config.enumsAsTypes) { return new DeclarationBlock({}) .export() - .asKind("const") + .asKind('const') .withName(`${enumname}Schema`) .withContent( - `yup.mixed().oneOf([${node.values - ?.map((enumOption) => `'${enumOption.name.value}'`) - .join(", ")}])` + `yup.mixed().oneOf([${node.values?.map(enumOption => `'${enumOption.name.value}'`).join(', ')}])` ).string; } const values = node.values ?.map( - (enumOption) => + enumOption => `${enumname}.${tsVisitor.convertName(enumOption.name, { useTypesPrefix: false, transformUnderscore: true, })}` ) - .join(", "); + .join(', '); return new DeclarationBlock({}) .export() - .asKind("const") + .asKind('const') .withName(`${enumname}Schema`) .withContent(`yup.mixed().oneOf([${values}])`).string; }, @@ -113,20 +98,12 @@ const generateInputObjectFieldYupSchema = ( field: InputValueDefinitionNode, indentCount: number ): string => { - let gen = generateInputObjectFieldTypeYupSchema( - config, - tsVisitor, - schema, - field.type - ); + let gen = generateInputObjectFieldTypeYupSchema(config, tsVisitor, schema, field.type); if (config.directives && field.directives) { const formatted = formatDirectiveConfig(config.directives); gen += buildApi(formatted, field.directives); } - return indent( - `${field.name.value}: ${maybeLazy(field.type, gen)}`, - indentCount - ); + return indent(`${field.name.value}: ${maybeLazy(field.type, gen)}`, indentCount); }; const generateInputObjectFieldTypeYupSchema = ( @@ -137,33 +114,21 @@ const generateInputObjectFieldTypeYupSchema = ( parentType?: TypeNode ): string => { if (isListType(type)) { - const gen = generateInputObjectFieldTypeYupSchema( - config, - tsVisitor, - schema, - type.type, - type - ); + const gen = generateInputObjectFieldTypeYupSchema(config, tsVisitor, schema, type.type, type); if (!isNonNullType(parentType)) { return `yup.array().of(${maybeLazy(type.type, gen)}).optional()`; } return `yup.array().of(${maybeLazy(type.type, gen)})`; } if (isNonNullType(type)) { - const gen = generateInputObjectFieldTypeYupSchema( - config, - tsVisitor, - schema, - type.type, - type - ); + const gen = generateInputObjectFieldTypeYupSchema(config, tsVisitor, schema, type.type, type); return maybeLazy(type.type, `${gen}.defined()`); } if (isNamedType(type)) { return generateNameNodeYupSchema(config, tsVisitor, schema, type.name); } - console.warn("unhandled type:", type); - return ""; + console.warn('unhandled type:', type); + return ''; }; const generateNameNodeYupSchema = ( @@ -174,12 +139,12 @@ const generateNameNodeYupSchema = ( ): string => { const typ = schema.getType(node.value); - if (typ && typ.astNode?.kind === "InputObjectTypeDefinition") { + if (typ && typ.astNode?.kind === 'InputObjectTypeDefinition') { const enumName = tsVisitor.convertName(typ.astNode.name.value); return `${enumName}Schema()`; } - if (typ && typ.astNode?.kind === "EnumTypeDefinition") { + if (typ && typ.astNode?.kind === 'EnumTypeDefinition') { const enumName = tsVisitor.convertName(typ.astNode.name.value); return `${enumName}Schema`; } @@ -199,13 +164,13 @@ const maybeLazy = (type: TypeNode, schema: string): string => { const yup4Scalar = (tsVisitor: TsVisitor, scalarName: string): string => { const tsType = tsVisitor.scalars[scalarName]; switch (tsType) { - case "string": + case 'string': return `yup.string()`; - case "number": + case 'number': return `yup.number()`; - case "boolean": + case 'boolean': return `yup.boolean()`; } - console.warn("unhandled name:", scalarName); + console.warn('unhandled name:', scalarName); return `yup.mixed()`; }; diff --git a/test.graphql b/test.graphql index d78c93ae..b5c4cfe7 100644 --- a/test.graphql +++ b/test.graphql @@ -92,4 +92,4 @@ directive @constraint( exclusiveMax: Float multipleOf: Float uniqueTypeName: String -) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION \ No newline at end of file +) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION diff --git a/tests/directive.spec.ts b/tests/directive.spec.ts index 8b96b011..43e8e02b 100644 --- a/tests/directive.spec.ts +++ b/tests/directive.spec.ts @@ -1,4 +1,4 @@ -import { DirectiveConfig, DirectiveObjectArguments } from "../src/config"; +import { DirectiveConfig, DirectiveObjectArguments } from '../src/config'; import { FormattedDirectiveConfig, FormattedDirectiveObjectArguments, @@ -7,30 +7,18 @@ import { FormattedDirectiveArguments, exportedForTesting, buildApi, -} from "../src/directive"; -import { - ConstArgumentNode, - ConstDirectiveNode, - ConstValueNode, - Kind, - NameNode, - parseConstValue, -} from "graphql"; +} from '../src/directive'; +import { ConstArgumentNode, ConstDirectiveNode, ConstValueNode, Kind, NameNode, parseConstValue } from 'graphql'; -const { - applyArgToApiSchemaTemplate, - buildApiFromDirectiveObjectArguments, - buildApiFromDirectiveArguments, -} = exportedForTesting; +const { applyArgToApiSchemaTemplate, buildApiFromDirectiveObjectArguments, buildApiFromDirectiveArguments } = + exportedForTesting; const buildNameNode = (name: string): NameNode => ({ kind: Kind.NAME, value: name, }); -const buildConstArgumentNodes = ( - args: Record -): ConstArgumentNode[] => +const buildConstArgumentNodes = (args: Record): ConstArgumentNode[] => Object.entries(args).map( ([argName, argValue]): ConstArgumentNode => ({ kind: Kind.ARGUMENT, @@ -39,42 +27,39 @@ const buildConstArgumentNodes = ( }) ); -const buildConstDirectiveNodes = ( - name: string, - args: Record -): ConstDirectiveNode => ({ +const buildConstDirectiveNodes = (name: string, args: Record): ConstDirectiveNode => ({ kind: Kind.DIRECTIVE, name: buildNameNode(name), arguments: buildConstArgumentNodes(args), }); -describe("format directive config", () => { - describe("formatDirectiveObjectArguments", () => { +describe('format directive config', () => { + describe('formatDirectiveObjectArguments', () => { const cases: { name: string; arg: DirectiveObjectArguments; want: FormattedDirectiveObjectArguments; }[] = [ { - name: "normal", + name: 'normal', arg: { - uri: "url", - email: "email", + uri: 'url', + email: 'email', }, want: { - uri: ["url", "$2"], - email: ["email", "$2"], + uri: ['url', '$2'], + email: ['email', '$2'], }, }, { - name: "contains array", + name: 'contains array', arg: { - startWith: ["matches", "/^$2/"], - email: "email", + startWith: ['matches', '/^$2/'], + email: 'email', }, want: { - startWith: ["matches", "/^$2/"], - email: ["email", "$2"], + startWith: ['matches', '/^$2/'], + email: ['email', '$2'], }, }, ]; @@ -86,62 +71,62 @@ describe("format directive config", () => { } }); - describe("formatDirectiveConfig", () => { + describe('formatDirectiveConfig', () => { const cases: { name: string; arg: DirectiveConfig; want: FormattedDirectiveConfig; }[] = [ { - name: "normal", + name: 'normal', arg: { required: { - msg: "required", + msg: 'required', }, constraint: { - minLength: "min", + minLength: 'min', format: { - uri: "url", - email: "email", + uri: 'url', + email: 'email', }, }, }, want: { required: { - msg: ["required", "$1"], + msg: ['required', '$1'], }, constraint: { - minLength: ["min", "$1"], + minLength: ['min', '$1'], format: { - uri: ["url", "$2"], - email: ["email", "$2"], + uri: ['url', '$2'], + email: ['email', '$2'], }, }, }, }, { - name: "complex", + name: 'complex', arg: { required: { - msg: "required", + msg: 'required', }, constraint: { - startWith: ["matches", "/^$1/g"], + startWith: ['matches', '/^$1/g'], format: { - uri: ["url", "$2"], - email: "email", + uri: ['url', '$2'], + email: 'email', }, }, }, want: { required: { - msg: ["required", "$1"], + msg: ['required', '$1'], }, constraint: { - startWith: ["matches", "/^$1/g"], + startWith: ['matches', '/^$1/g'], format: { - uri: ["url", "$2"], - email: ["email", "$2"], + uri: ['url', '$2'], + email: ['email', '$2'], }, }, }, @@ -155,7 +140,7 @@ describe("format directive config", () => { } }); - describe("applyArgToApiSchemaTemplate", () => { + describe('applyArgToApiSchemaTemplate', () => { const cases: { name: string; args: { @@ -165,82 +150,82 @@ describe("format directive config", () => { want: string; }[] = [ { - name: "string", + name: 'string', args: { - template: "$1", - apiArgs: ["hello"], + template: '$1', + apiArgs: ['hello'], }, want: `"hello"`, }, { - name: "regexp string", + name: 'regexp string', args: { - template: "$1", - apiArgs: ["/hello/g"], + template: '$1', + apiArgs: ['/hello/g'], }, want: `/hello/g`, }, { - name: "number", + name: 'number', args: { - template: "$1", + template: '$1', apiArgs: [10], }, - want: "10", + want: '10', }, { - name: "boolean", + name: 'boolean', args: { - template: "$1", + template: '$1', apiArgs: [true], }, - want: "true", + want: 'true', }, { - name: "array", + name: 'array', args: { - template: "$1", - apiArgs: [["hello", "world"]], + template: '$1', + apiArgs: [['hello', 'world']], }, want: `"hello","world"`, }, { - name: "object", + name: 'object', args: { - template: "$1", - apiArgs: [{ hello: "world" }], + template: '$1', + apiArgs: [{ hello: 'world' }], }, want: `{"hello":"world"}`, }, { - name: "multiple", + name: 'multiple', args: { - template: "^$1|$2", - apiArgs: ["hello", "world"], + template: '^$1|$2', + apiArgs: ['hello', 'world'], }, want: `"^hello|world"`, }, { - name: "use only $2", + name: 'use only $2', args: { - template: "$2$", - apiArgs: ["hello", "world"], + template: '$2$', + apiArgs: ['hello', 'world'], }, want: `"world$"`, }, { - name: "does not match all", + name: 'does not match all', args: { - template: "^$1", + template: '^$1', apiArgs: [], }, want: `"^"`, }, { - name: "if does not exists index", + name: 'if does not exists index', args: { - template: "$1 $2 $3", - apiArgs: ["hello", "world"], + template: '$1 $2 $3', + apiArgs: ['hello', 'world'], }, want: `"hello world "`, }, @@ -254,7 +239,7 @@ describe("format directive config", () => { } }); - describe("buildApiFromDirectiveObjectArguments", () => { + describe('buildApiFromDirectiveObjectArguments', () => { const cases: { name: string; args: { @@ -264,30 +249,30 @@ describe("format directive config", () => { want: string; }[] = [ { - name: "contains in config", + name: 'contains in config', args: { config: { - uri: ["url", "$2"], + uri: ['url', '$2'], }, argValue: parseConstValue(`"uri"`), }, want: `.url()`, }, { - name: "does not contains in config", + name: 'does not contains in config', args: { config: { - email: ["email", "$2"], + email: ['email', '$2'], }, argValue: parseConstValue(`"uri"`), }, want: ``, }, { - name: "const value does not string type", + name: 'const value does not string type', args: { config: { - email: ["email", "$2"], + email: ['email', '$2'], }, argValue: parseConstValue(`123`), }, @@ -303,7 +288,7 @@ describe("format directive config", () => { } }); - describe("buildApiFromDirectiveArguments", () => { + describe('buildApiFromDirectiveArguments', () => { const cases: { name: string; args: { @@ -313,10 +298,10 @@ describe("format directive config", () => { want: string; }[] = [ { - name: "string", + name: 'string', args: { config: { - msg: ["required", "$1"], + msg: ['required', '$1'], }, args: buildConstArgumentNodes({ msg: `"hello"`, @@ -325,10 +310,10 @@ describe("format directive config", () => { want: `.required("hello")`, }, { - name: "string with additional stuff", + name: 'string with additional stuff', args: { config: { - startWith: ["matched", "^$1"], + startWith: ['matched', '^$1'], }, args: buildConstArgumentNodes({ startWith: `"hello"`, @@ -337,10 +322,10 @@ describe("format directive config", () => { want: `.matched("^hello")`, }, { - name: "number", + name: 'number', args: { config: { - minLength: ["min", "$1"], + minLength: ['min', '$1'], }, args: buildConstArgumentNodes({ minLength: `1`, @@ -349,11 +334,11 @@ describe("format directive config", () => { want: `.min(1)`, }, { - name: "boolean", + name: 'boolean', args: { config: { // @strict(enabled: true) - enabled: ["strict", "$1"], + enabled: ['strict', '$1'], }, args: buildConstArgumentNodes({ enabled: `true`, @@ -362,10 +347,10 @@ describe("format directive config", () => { want: `.strict(true)`, }, { - name: "list", + name: 'list', args: { config: { - minLength: ["min", "$1", "$2"], + minLength: ['min', '$1', '$2'], }, args: buildConstArgumentNodes({ minLength: `[1, "message"]`, @@ -374,10 +359,10 @@ describe("format directive config", () => { want: `.min(1, "message")`, }, { - name: "object in list", + name: 'object in list', args: { config: { - matches: ["matches", "$1", "$2"], + matches: ['matches', '$1', '$2'], }, args: buildConstArgumentNodes({ matches: `["hello", {message:"message", excludeEmptyString:true}]`, @@ -386,10 +371,10 @@ describe("format directive config", () => { want: `.matches("hello", {"message":"message","excludeEmptyString":true})`, }, { - name: "two arguments but matched to first argument", + name: 'two arguments but matched to first argument', args: { config: { - msg: ["required", "$1"], + msg: ['required', '$1'], }, args: buildConstArgumentNodes({ msg: `"hello"`, @@ -399,10 +384,10 @@ describe("format directive config", () => { want: `.required("hello")`, }, { - name: "two arguments but matched to second argument", + name: 'two arguments but matched to second argument', args: { config: { - msg2: ["required", "$1"], + msg2: ['required', '$1'], }, args: buildConstArgumentNodes({ msg: `"hello"`, @@ -412,11 +397,11 @@ describe("format directive config", () => { want: `.required("world")`, }, { - name: "two arguments matched all", + name: 'two arguments matched all', args: { config: { - required: ["required", "$1"], - minLength: ["min", "$1"], + required: ['required', '$1'], + minLength: ['min', '$1'], }, args: buildConstArgumentNodes({ required: `"message"`, @@ -426,11 +411,11 @@ describe("format directive config", () => { want: `.required("message").min(1)`, }, { - name: "argument matches validation schema api", + name: 'argument matches validation schema api', args: { config: { format: { - uri: ["url"], + uri: ['url'], }, }, args: buildConstArgumentNodes({ @@ -444,7 +429,7 @@ describe("format directive config", () => { args: { config: { format: { - uri: ["url"], + uri: ['url'], }, }, args: buildConstArgumentNodes({ @@ -454,12 +439,12 @@ describe("format directive config", () => { want: ``, }, { - name: "complex", + name: 'complex', args: { config: { - required: ["required", "$1"], + required: ['required', '$1'], format: { - uri: ["url"], + uri: ['url'], }, }, args: buildConstArgumentNodes({ @@ -470,12 +455,12 @@ describe("format directive config", () => { want: `.required("message").url()`, }, { - name: "complex 2", + name: 'complex 2', args: { config: { - required: ["required", "$1"], + required: ['required', '$1'], format: { - uri: ["url"], + uri: ['url'], }, }, args: buildConstArgumentNodes({ @@ -495,7 +480,7 @@ describe("format directive config", () => { } }); - describe("buildApi", () => { + describe('buildApi', () => { const cases: { name: string; args: { @@ -505,27 +490,27 @@ describe("format directive config", () => { want: string; }[] = [ { - name: "valid", + name: 'valid', args: { config: { required: { - msg: ["required", "$1"], + msg: ['required', '$1'], }, constraint: { - minLength: ["min", "$1"], + minLength: ['min', '$1'], format: { - uri: ["url"], - email: ["email"], + uri: ['url'], + email: ['email'], }, }, }, args: [ // @required(msg: "message") - buildConstDirectiveNodes("required", { + buildConstDirectiveNodes('required', { msg: `"message"`, }), // @constraint(minLength: 100, format: "email") - buildConstDirectiveNodes("constraint", { + buildConstDirectiveNodes('constraint', { minLength: `100`, format: `"email"`, }), diff --git a/tests/regexp.spec.ts b/tests/regexp.spec.ts index 01d76c54..e3ed075d 100644 --- a/tests/regexp.spec.ts +++ b/tests/regexp.spec.ts @@ -1,38 +1,33 @@ -import { isConvertableRegexp } from "../src/regexp"; +import { isConvertableRegexp } from '../src/regexp'; -describe("isConvertableRegexp", () => { - describe("match", () => { +describe('isConvertableRegexp', () => { + describe('match', () => { test.each([ - "//", - "/hello/", - "/hello/d", - "/hello/g", - "/hello/i", - "/hello/m", - "/hello/s", - "/hello/u", - "/hello/y", - "/hello/dgimsuy", + '//', + '/hello/', + '/hello/d', + '/hello/g', + '/hello/i', + '/hello/m', + '/hello/s', + '/hello/u', + '/hello/y', + '/hello/dgimsuy', `/\\w+\\s/g`, // eslint-disable-next-line no-useless-escape `/^[a-z]+:[\\\/]$/i`, // eslint-disable-next-line no-useless-escape `/^(?:\d{3}|\(\d{3}\))([-\/\.])\d{3}\\1\d{4}$/`, - ])("%s", (maybeRegexp) => { + ])('%s', maybeRegexp => { expect(isConvertableRegexp(maybeRegexp)).toBeTruthy(); }); }); - describe("does not match", () => { - test.each([ - "hello", - "/world", - "world/", - "https://example.com/", - " /hello/", - "/hello/d ", - "/hello/dgimsuy ", - ])("%s", (maybeRegexp) => { - expect(isConvertableRegexp(maybeRegexp)).toBeFalsy(); - }); + describe('does not match', () => { + test.each(['hello', '/world', 'world/', 'https://example.com/', ' /hello/', '/hello/d ', '/hello/dgimsuy '])( + '%s', + maybeRegexp => { + expect(isConvertableRegexp(maybeRegexp)).toBeFalsy(); + } + ); }); }); diff --git a/tests/yup.spec.ts b/tests/yup.spec.ts index a442661f..0eeaa9ed 100644 --- a/tests/yup.spec.ts +++ b/tests/yup.spec.ts @@ -1,10 +1,10 @@ -import { buildSchema } from "graphql"; -import { plugin } from "../src/index"; +import { buildSchema } from 'graphql'; +import { plugin } from '../src/index'; -describe("yup", () => { +describe('yup', () => { test.each([ [ - "defined", + 'defined', /* GraphQL */ ` input PrimitiveInput { a: ID! @@ -15,16 +15,16 @@ describe("yup", () => { } `, [ - "export function PrimitiveInputSchema(): yup.SchemaOf", - "a: yup.string().defined()", - "b: yup.string().defined()", - "c: yup.boolean().defined()", - "d: yup.number().defined()", - "e: yup.number().defined()", + 'export function PrimitiveInputSchema(): yup.SchemaOf', + 'a: yup.string().defined()', + 'b: yup.string().defined()', + 'c: yup.boolean().defined()', + 'd: yup.number().defined()', + 'e: yup.number().defined()', ], ], [ - "optional", + 'optional', /* GraphQL */ ` input PrimitiveInput { a: ID @@ -36,17 +36,17 @@ describe("yup", () => { } `, [ - "export function PrimitiveInputSchema(): yup.SchemaOf", + 'export function PrimitiveInputSchema(): yup.SchemaOf', // alphabet order - "a: yup.string(),", - "b: yup.string(),", - "c: yup.boolean(),", - "d: yup.number(),", - "e: yup.number(),", + 'a: yup.string(),', + 'b: yup.string(),', + 'c: yup.boolean(),', + 'd: yup.number(),', + 'e: yup.number(),', ], ], [ - "array", + 'array', /* GraphQL */ ` input ArrayInput { a: [String] @@ -58,17 +58,17 @@ describe("yup", () => { } `, [ - "export function ArrayInputSchema(): yup.SchemaOf", - "a: yup.array().of(yup.string()).optional(),", - "b: yup.array().of(yup.string().defined()).optional(),", - "c: yup.array().of(yup.string().defined()).defined(),", - "d: yup.array().of(yup.array().of(yup.string()).optional()).optional(),", - "e: yup.array().of(yup.array().of(yup.string()).defined()).optional(),", - "f: yup.array().of(yup.array().of(yup.string()).defined()).defined()", + 'export function ArrayInputSchema(): yup.SchemaOf', + 'a: yup.array().of(yup.string()).optional(),', + 'b: yup.array().of(yup.string().defined()).optional(),', + 'c: yup.array().of(yup.string().defined()).defined(),', + 'd: yup.array().of(yup.array().of(yup.string()).optional()).optional(),', + 'e: yup.array().of(yup.array().of(yup.string()).defined()).optional(),', + 'f: yup.array().of(yup.array().of(yup.string()).defined()).defined()', ], ], [ - "ref input object", + 'ref input object', /* GraphQL */ ` input AInput { b: BInput! @@ -81,16 +81,16 @@ describe("yup", () => { } `, [ - "export function AInputSchema(): yup.SchemaOf", - "b: yup.lazy(() => BInputSchema().defined()) as never", - "export function BInputSchema(): yup.SchemaOf", - "c: yup.lazy(() => CInputSchema().defined()) as never", - "export function CInputSchema(): yup.SchemaOf", - "a: yup.lazy(() => AInputSchema().defined()) as never", + 'export function AInputSchema(): yup.SchemaOf', + 'b: yup.lazy(() => BInputSchema().defined()) as never', + 'export function BInputSchema(): yup.SchemaOf', + 'c: yup.lazy(() => CInputSchema().defined()) as never', + 'export function CInputSchema(): yup.SchemaOf', + 'a: yup.lazy(() => AInputSchema().defined()) as never', ], ], [ - "nested input object", + 'nested input object', /* GraphQL */ ` input NestedInput { child: NestedInput @@ -98,13 +98,13 @@ describe("yup", () => { } `, [ - "export function NestedInputSchema(): yup.SchemaOf", - "child: yup.lazy(() => NestedInputSchema()) as never,", - "childrens: yup.array().of(yup.lazy(() => NestedInputSchema()) as never).optional()", + 'export function NestedInputSchema(): yup.SchemaOf', + 'child: yup.lazy(() => NestedInputSchema()) as never,', + 'childrens: yup.array().of(yup.lazy(() => NestedInputSchema()) as never).optional()', ], ], [ - "enum", + 'enum', /* GraphQL */ ` enum PageType { PUBLIC @@ -115,13 +115,13 @@ describe("yup", () => { } `, [ - "export const PageTypeSchema = yup.mixed().oneOf([PageType.Public, PageType.BasicAuth])", - "export function PageInputSchema(): yup.SchemaOf", - "pageType: PageTypeSchema.defined()", + 'export const PageTypeSchema = yup.mixed().oneOf([PageType.Public, PageType.BasicAuth])', + 'export function PageInputSchema(): yup.SchemaOf', + 'pageType: PageTypeSchema.defined()', ], ], [ - "camelcase", + 'camelcase', /* GraphQL */ ` input HTTPInput { method: HTTPMethod @@ -136,13 +136,13 @@ describe("yup", () => { scalar URL # unknown scalar, should be any (yup.mixed()) `, [ - "export function HttpInputSchema(): yup.SchemaOf", - "export const HttpMethodSchema = yup.mixed().oneOf([HttpMethod.Get, HttpMethod.Post])", - "method: HttpMethodSchema", - "url: yup.mixed().defined()", + 'export function HttpInputSchema(): yup.SchemaOf', + 'export const HttpMethodSchema = yup.mixed().oneOf([HttpMethod.Get, HttpMethod.Post])', + 'method: HttpMethodSchema', + 'url: yup.mixed().defined()', ], ], - ])("%s", async (_, textSchema, wantContains) => { + ])('%s', async (_, textSchema, wantContains) => { const schema = buildSchema(textSchema); const result = await plugin(schema, [], {}, {}); expect(result.prepend).toContain("import * as yup from 'yup'"); @@ -152,7 +152,7 @@ describe("yup", () => { } }); - it("with scalars", async () => { + it('with scalars', async () => { const schema = buildSchema(/* GraphQL */ ` input Say { phrase: Text! @@ -167,17 +167,17 @@ describe("yup", () => { [], { scalars: { - Text: "string", - Count: "number", + Text: 'string', + Count: 'number', }, }, {} ); - expect(result.content).toContain("phrase: yup.string().defined()"); - expect(result.content).toContain("times: yup.number().defined()"); + expect(result.content).toContain('phrase: yup.string().defined()'); + expect(result.content).toContain('times: yup.number().defined()'); }); - it("with importFrom", async () => { + it('with importFrom', async () => { const schema = buildSchema(/* GraphQL */ ` input Say { phrase: String! @@ -187,15 +187,15 @@ describe("yup", () => { schema, [], { - importFrom: "./types", + importFrom: './types', }, {} ); expect(result.prepend).toContain("import { Say } from './types'"); - expect(result.content).toContain("phrase: yup.string().defined()"); + expect(result.content).toContain('phrase: yup.string().defined()'); }); - it("with enumsAsTypes", async () => { + it('with enumsAsTypes', async () => { const schema = buildSchema(/* GraphQL */ ` enum PageType { PUBLIC @@ -210,8 +210,6 @@ describe("yup", () => { }, {} ); - expect(result.content).toContain( - "export const PageTypeSchema = yup.mixed().oneOf(['PUBLIC', 'BASIC_AUTH'])" - ); + expect(result.content).toContain("export const PageTypeSchema = yup.mixed().oneOf(['PUBLIC', 'BASIC_AUTH'])"); }); }); diff --git a/yarn.lock b/yarn.lock index 832f6d75..03a0d6d7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4730,6 +4730,11 @@ prepend-http@^2.0.0: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= +prettier@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a" + integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg== + pretty-format@^27.0.0, pretty-format@^27.4.6: version "27.4.6" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.4.6.tgz#1b784d2f53c68db31797b2348fa39b49e31846b7"