Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(clients): add zod #785

Merged
merged 5 commits into from
Mar 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
476 changes: 0 additions & 476 deletions docs/generated/endpoints.ts

This file was deleted.

4 changes: 2 additions & 2 deletions packages/core/src/getters/array.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SchemaObject } from 'openapi3-ts';
import { ContextSpecs, ResolverValue } from '../types';
import { ContextSpecs, ScalarValue } from '../types';
import { resolveObject } from '../resolvers/object';

/**
Expand All @@ -15,7 +15,7 @@ export const getArray = ({
schema: SchemaObject;
name?: string;
context: ContextSpecs;
}): ResolverValue => {
}): ScalarValue => {
if (schema.items) {
const resolvedObject = resolveObject({
schema: schema.items,
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/getters/body.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { ReferenceObject, RequestBodyObject } from 'openapi3-ts';
import { generalJSTypesWithArray } from '../constants';
import { ContextSpecs, OverrideOutputContentType } from '../types';
import { GetterBody } from '../types';
import { ContextSpecs, GetterBody, OverrideOutputContentType } from '../types';
import { camel } from '../utils';
import { getResReqTypes } from './res-req-types';

Expand Down Expand Up @@ -51,6 +50,7 @@ export const getBody = ({
: camel(definition);

return {
originalSchema: requestBody,
definition,
implementation,
imports,
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/getters/combine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
ContextSpecs,
GeneratorImport,
GeneratorSchema,
ResolverValue,
ScalarValue,
SchemaType,
} from '../types';
import { getNumberWord, pascal } from '../utils';
Expand All @@ -30,7 +30,7 @@ const combineValues = ({
separator,
}: {
resolvedData: CombinedData;
resolvedValue?: ResolverValue;
resolvedValue?: ScalarValue;
separator: Separator;
}) => {
const isAllEnums = resolvedData.isEnum.every((v) => v);
Expand Down Expand Up @@ -68,7 +68,7 @@ export const combineSchemas = ({
separator: Separator;
context: ContextSpecs;
nullable: string;
}): ResolverValue => {
}): ScalarValue => {
const items = schema[separator] ?? [];

const resolvedData = items.reduce<CombinedData>(
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/getters/object.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ReferenceObject, SchemaObject } from 'openapi3-ts';
import { resolveObject, resolveValue } from '../resolvers';
import { ContextSpecs, ResolverValue, SchemaType } from '../types';
import { ContextSpecs, ScalarValue, SchemaType } from '../types';
import { isBoolean, isReference, jsDoc, pascal } from '../utils';
import { combineSchemas } from './combine';
import { getKey } from './keys';
Expand All @@ -21,7 +21,7 @@ export const getObject = ({
name?: string;
context: ContextSpecs;
nullable: string;
}): ResolverValue => {
}): ScalarValue => {
if (isReference(item)) {
const { name, specKey } = getRefInfo(item.$ref, context);
return {
Expand Down Expand Up @@ -137,7 +137,7 @@ export const getObject = ({
type: 'object' as SchemaType,
isRef: false,
schema: {},
} as ResolverValue,
} as ScalarValue,
);
}

Expand Down
1 change: 1 addition & 0 deletions packages/core/src/getters/params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ export const getParams = ({
default: resolvedValue.originalSchema!.default,
required,
imports: resolvedValue.imports,
originalSchema: resolvedValue.originalSchema,
};
});
};
18 changes: 10 additions & 8 deletions packages/core/src/getters/query-params.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,15 @@ describe('getQueryParams getter', () => {
operationName: '',
context,
});
expect(result?.schema.model.trim()).toBe([
'export type Params = {',
'/**',
' * Parameter description.',
' */',
'queryParamWithDescription?: string;',
'};',
].join('\n'));
expect(result?.schema.model.trim()).toBe(
[
'export type Params = {',
'/**',
' * Parameter description.',
' */',
'queryParamWithDescription?: string;',
'};',
].join('\n'),
);
});
});
4 changes: 4 additions & 0 deletions packages/core/src/getters/query-params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type QueryParamsType = {
definition: string;
imports: GeneratorImport[];
schemas: GeneratorSchema[];
originalSchema: SchemaObject;
};

const getQueryParamsTypes = (
Expand Down Expand Up @@ -61,6 +62,7 @@ const getQueryParamsTypes = (
};`,
imports: parameterImports,
schemas: [],
originalSchema: resolvedeValue.originalSchema,
};
}

Expand All @@ -82,6 +84,7 @@ const getQueryParamsTypes = (
...resolvedeValue.schemas,
{ name: enumName, model: enumValue, imports: resolvedeValue.imports },
],
originalSchema: resolvedeValue.originalSchema,
};
}

Expand All @@ -93,6 +96,7 @@ const getQueryParamsTypes = (
definition,
imports: resolvedeValue.imports,
schemas: resolvedeValue.schemas,
originalSchema: resolvedeValue.originalSchema,
};
});
};
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/getters/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,5 +93,6 @@ export const getResponse = ({
types: groupedByStatus,
contentTypes,
schemas,
originalSchema: responses,
};
};
4 changes: 2 additions & 2 deletions packages/core/src/getters/scalar.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SchemaObject } from 'openapi3-ts';
import { ContextSpecs, ResolverValue } from '../types';
import { ContextSpecs, ScalarValue } from '../types';
import { escape, isString } from '../utils';
import { getArray } from './array';
import { getObject } from './object';
Expand All @@ -18,7 +18,7 @@ export const getScalar = ({
item: SchemaObject;
name?: string;
context: ContextSpecs;
}): ResolverValue => {
}): ScalarValue => {
const nullable = item.nullable ? ' | null' : '';

if (!item.type && item.items) {
Expand Down
20 changes: 16 additions & 4 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import {
OpenAPIObject,
OperationObject,
ParameterObject,
ReferenceObject,
RequestBodyObject,
ResponsesObject,
SchemaObject,
} from 'openapi3-ts';
import swagger2openapi from 'swagger2openapi';
Expand Down Expand Up @@ -175,7 +178,8 @@ export type OutputClient =
| 'react-query'
| 'svelte-query'
| 'vue-query'
| 'swr';
| 'swr'
| 'zod';

export const OutputClient = {
ANGULAR: 'angular' as OutputClient,
Expand Down Expand Up @@ -591,9 +595,12 @@ export type GetterResponse = {
};
contentTypes: string[];
schemas: GeneratorSchema[];

originalSchema?: ResponsesObject;
};

export type GetterBody = {
originalSchema: ReferenceObject | RequestBodyObject;
imports: GeneratorImport[];
definition: string;
implementation: string;
Expand Down Expand Up @@ -623,6 +630,7 @@ export type GetterQueryParam = {
schema: GeneratorSchema;
deps: GeneratorSchema[];
isOptional: boolean;
originalSchema?: SchemaObject;
};

export type GetterPropType = 'param' | 'body' | 'queryParam' | 'header';
Expand Down Expand Up @@ -668,22 +676,26 @@ export const SchemaType = {
unknown: 'unknown',
};

export type ResolverValue = {
export type ScalarValue = {
value: string;
isEnum: boolean;
type: SchemaType;
imports: GeneratorImport[];
schemas: GeneratorSchema[];
originalSchema?: SchemaObject;
isRef: boolean;
};

export type ResReqTypesValue = ResolverValue & {
export type ResolverValue = ScalarValue & {
originalSchema: SchemaObject;
};

export type ResReqTypesValue = ScalarValue & {
formData?: string;
formUrlEncoded?: string;
isRef?: boolean;
key: string;
contentType: string;
originalSchema?: SchemaObject;
};

export type WriteSpecsBuilder = {
Expand Down
5 changes: 3 additions & 2 deletions packages/orval/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@
},
"scripts": {
"build": "tsup ./src/bin/orval.ts ./src/index.ts --target node12 --minify --clean --dts --splitting",
"dev": "tsup ./src/bin/orval.ts ./src/index.ts --target node12 --clean --watch src --onSuccess 'yarn generate-api'",
"dev": "tsup ./src/bin/orval.ts ./src/index.ts --target node12 --clean --watch ./src --onSuccess 'yarn generate-api'",
"lint": "eslint src/**/*.ts",
"generate-api": "node ./dist/bin/orval.js --config ../../samples/react-query/basic/orval.config.ts --watch"
"generate-api": "node ./dist/bin/orval.js --config ../../samples/react-query/basic/orval.config.ts"
},
"devDependencies": {
"@types/chalk": "^2.2.0",
Expand All @@ -60,6 +60,7 @@
"@orval/msw": "6.12.1",
"@orval/query": "6.12.1",
"@orval/swr": "6.12.1",
"@orval/zod": "6.12.1",
"ajv": "^8.11.0",
"cac": "^6.7.12",
"chalk": "^4.1.2",
Expand Down
6 changes: 6 additions & 0 deletions packages/orval/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
import { generateMSW } from '@orval/msw';
import query from '@orval/query';
import swr from '@orval/swr';
import zod from '@orval/zod';

const DEFAULT_CLIENT = OutputClient.AXIOS;

Expand All @@ -31,6 +32,7 @@ export const GENERATOR_CLIENT: GeneratorClients = {
'svelte-query': query({ type: 'svelte-query' })(),
'vue-query': query({ type: 'vue-query' })(),
swr: swr()(),
zod: zod()(),
};

const getGeneratorClient = (outputClient: OutputClient | OutputClientFunc) => {
Expand Down Expand Up @@ -201,6 +203,10 @@ export const generateOperations = (
const client = await generatorClient(verbOption, options, outputClient);
const msw = generateMock(verbOption, options);

if (!client.implementation) {
return acc;
}

acc[verbOption.operationId] = {
implementation: verbOption.doc + client.implementation,
imports: client.imports,
Expand Down
1 change: 1 addition & 0 deletions packages/query/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -909,6 +909,7 @@ const generateQueryHook = async (
}${body.implementation ? `, ${body.implementation}` : ''}];`;

const implementation = `${!queryKeyMutator ? queryKeyFn : ''}


${queries.reduce(
(acc, queryOption) =>
Expand Down
28 changes: 28 additions & 0 deletions packages/zod/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[![npm version](https://badge.fury.io/js/orval.svg)](https://badge.fury.io/js/orval)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![tests](https://github.com/anymaniax/orval/actions/workflows/tests.yaml/badge.svg)](https://github.com/anymaniax/orval/actions/workflows/tests.yaml)

<p align="center">
<img src="./logo/orval-logo-horizontal.svg?raw=true" width="500" height="160" alt="orval - Restfull Client Generator" />
</p>
<h1 align="center">
Visit <a href="https://orval.dev" target="_blank">orval.dev</a> for docs, guides, API and beer!
</h1>

### Code Generation

`orval` is able to generate client with appropriate type-signatures (TypeScript) from any valid OpenAPI v3 or Swagger v2 specification, either in `yaml` or `json` formats.

`Generate`, `valid`, `cache` and `mock` in your React, Vue, Svelte and Angular applications all with your OpenAPI specification.

### Samples

You can find below some samples

- [react app](https://github.com/anymaniax/orval/tree/master/samples/react-app)
- [react query](https://github.com/anymaniax/orval/tree/master/samples/react-query)
- [svelte query](https://github.com/anymaniax/orval/tree/master/samples/svelte-query)
- [vue query](https://github.com/anymaniax/orval/tree/master/samples/vue-query)
- [react app with swr](https://github.com/anymaniax/orval/tree/master/samples/react-app-with-swr)
- [nx fastify react](https://github.com/anymaniax/orval/tree/master/samples/nx-fastify-react)
- [angular app](https://github.com/anymaniax/orval/tree/master/samples/angular-app)
18 changes: 18 additions & 0 deletions packages/zod/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "@orval/zod",
"version": "6.12.1",
"license": "MIT",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": [
"dist"
],
"scripts": {
"build": "tsup ./src/index.ts --target node12 --minify --clean --dts --splitting",
"dev": "tsup ./src/index.ts --target node12 --clean --watch src",
"lint": "eslint src/**/*.ts"
},
"dependencies": {
"@orval/core": "6.12.1"
}
}
Loading