Skip to content

Commit cebdb2e

Browse files
authoredMar 27, 2023
feat(clients): add zod (#785)
* feat(clients): add zod * feat(zod): add validations variables * feat(zod): handling some format and escap regex * fix(zod): package json version
1 parent 623b7e3 commit cebdb2e

18 files changed

+504
-502
lines changed
 

‎docs/generated/endpoints.ts

-476
This file was deleted.

‎packages/core/src/getters/array.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { SchemaObject } from 'openapi3-ts';
2-
import { ContextSpecs, ResolverValue } from '../types';
2+
import { ContextSpecs, ScalarValue } from '../types';
33
import { resolveObject } from '../resolvers/object';
44

55
/**
@@ -15,7 +15,7 @@ export const getArray = ({
1515
schema: SchemaObject;
1616
name?: string;
1717
context: ContextSpecs;
18-
}): ResolverValue => {
18+
}): ScalarValue => {
1919
if (schema.items) {
2020
const resolvedObject = resolveObject({
2121
schema: schema.items,

‎packages/core/src/getters/body.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { ReferenceObject, RequestBodyObject } from 'openapi3-ts';
22
import { generalJSTypesWithArray } from '../constants';
3-
import { ContextSpecs, OverrideOutputContentType } from '../types';
4-
import { GetterBody } from '../types';
3+
import { ContextSpecs, GetterBody, OverrideOutputContentType } from '../types';
54
import { camel } from '../utils';
65
import { getResReqTypes } from './res-req-types';
76

@@ -51,6 +50,7 @@ export const getBody = ({
5150
: camel(definition);
5251

5352
return {
53+
originalSchema: requestBody,
5454
definition,
5555
implementation,
5656
imports,

‎packages/core/src/getters/combine.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
ContextSpecs,
66
GeneratorImport,
77
GeneratorSchema,
8-
ResolverValue,
8+
ScalarValue,
99
SchemaType,
1010
} from '../types';
1111
import { getNumberWord, pascal } from '../utils';
@@ -30,7 +30,7 @@ const combineValues = ({
3030
separator,
3131
}: {
3232
resolvedData: CombinedData;
33-
resolvedValue?: ResolverValue;
33+
resolvedValue?: ScalarValue;
3434
separator: Separator;
3535
}) => {
3636
const isAllEnums = resolvedData.isEnum.every((v) => v);
@@ -68,7 +68,7 @@ export const combineSchemas = ({
6868
separator: Separator;
6969
context: ContextSpecs;
7070
nullable: string;
71-
}): ResolverValue => {
71+
}): ScalarValue => {
7272
const items = schema[separator] ?? [];
7373

7474
const resolvedData = items.reduce<CombinedData>(

‎packages/core/src/getters/object.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { ReferenceObject, SchemaObject } from 'openapi3-ts';
22
import { resolveObject, resolveValue } from '../resolvers';
3-
import { ContextSpecs, ResolverValue, SchemaType } from '../types';
3+
import { ContextSpecs, ScalarValue, SchemaType } from '../types';
44
import { isBoolean, isReference, jsDoc, pascal } from '../utils';
55
import { combineSchemas } from './combine';
66
import { getKey } from './keys';
@@ -21,7 +21,7 @@ export const getObject = ({
2121
name?: string;
2222
context: ContextSpecs;
2323
nullable: string;
24-
}): ResolverValue => {
24+
}): ScalarValue => {
2525
if (isReference(item)) {
2626
const { name, specKey } = getRefInfo(item.$ref, context);
2727
return {
@@ -137,7 +137,7 @@ export const getObject = ({
137137
type: 'object' as SchemaType,
138138
isRef: false,
139139
schema: {},
140-
} as ResolverValue,
140+
} as ScalarValue,
141141
);
142142
}
143143

‎packages/core/src/getters/params.ts

+1
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ export const getParams = ({
102102
default: resolvedValue.originalSchema!.default,
103103
required,
104104
imports: resolvedValue.imports,
105+
originalSchema: resolvedValue.originalSchema,
105106
};
106107
});
107108
};

‎packages/core/src/getters/query-params.test.ts

+10-8
Original file line numberDiff line numberDiff line change
@@ -139,13 +139,15 @@ describe('getQueryParams getter', () => {
139139
operationName: '',
140140
context,
141141
});
142-
expect(result?.schema.model.trim()).toBe([
143-
'export type Params = {',
144-
'/**',
145-
' * Parameter description.',
146-
' */',
147-
'queryParamWithDescription?: string;',
148-
'};',
149-
].join('\n'));
142+
expect(result?.schema.model.trim()).toBe(
143+
[
144+
'export type Params = {',
145+
'/**',
146+
' * Parameter description.',
147+
' */',
148+
'queryParamWithDescription?: string;',
149+
'};',
150+
].join('\n'),
151+
);
150152
});
151153
});

‎packages/core/src/getters/query-params.ts

+4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ type QueryParamsType = {
1515
definition: string;
1616
imports: GeneratorImport[];
1717
schemas: GeneratorSchema[];
18+
originalSchema: SchemaObject;
1819
};
1920

2021
const getQueryParamsTypes = (
@@ -61,6 +62,7 @@ const getQueryParamsTypes = (
6162
};`,
6263
imports: parameterImports,
6364
schemas: [],
65+
originalSchema: resolvedeValue.originalSchema,
6466
};
6567
}
6668

@@ -82,6 +84,7 @@ const getQueryParamsTypes = (
8284
...resolvedeValue.schemas,
8385
{ name: enumName, model: enumValue, imports: resolvedeValue.imports },
8486
],
87+
originalSchema: resolvedeValue.originalSchema,
8588
};
8689
}
8790

@@ -93,6 +96,7 @@ const getQueryParamsTypes = (
9396
definition,
9497
imports: resolvedeValue.imports,
9598
schemas: resolvedeValue.schemas,
99+
originalSchema: resolvedeValue.originalSchema,
96100
};
97101
});
98102
};

‎packages/core/src/getters/response.ts

+1
Original file line numberDiff line numberDiff line change
@@ -93,5 +93,6 @@ export const getResponse = ({
9393
types: groupedByStatus,
9494
contentTypes,
9595
schemas,
96+
originalSchema: responses,
9697
};
9798
};

‎packages/core/src/getters/scalar.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { SchemaObject } from 'openapi3-ts';
2-
import { ContextSpecs, ResolverValue } from '../types';
2+
import { ContextSpecs, ScalarValue } from '../types';
33
import { escape, isString } from '../utils';
44
import { getArray } from './array';
55
import { getObject } from './object';
@@ -18,7 +18,7 @@ export const getScalar = ({
1818
item: SchemaObject;
1919
name?: string;
2020
context: ContextSpecs;
21-
}): ResolverValue => {
21+
}): ScalarValue => {
2222
const nullable = item.nullable ? ' | null' : '';
2323

2424
if (!item.type && item.items) {

‎packages/core/src/types.ts

+16-4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ import {
44
OpenAPIObject,
55
OperationObject,
66
ParameterObject,
7+
ReferenceObject,
8+
RequestBodyObject,
9+
ResponsesObject,
710
SchemaObject,
811
} from 'openapi3-ts';
912
import swagger2openapi from 'swagger2openapi';
@@ -175,7 +178,8 @@ export type OutputClient =
175178
| 'react-query'
176179
| 'svelte-query'
177180
| 'vue-query'
178-
| 'swr';
181+
| 'swr'
182+
| 'zod';
179183

180184
export const OutputClient = {
181185
ANGULAR: 'angular' as OutputClient,
@@ -591,9 +595,12 @@ export type GetterResponse = {
591595
};
592596
contentTypes: string[];
593597
schemas: GeneratorSchema[];
598+
599+
originalSchema?: ResponsesObject;
594600
};
595601

596602
export type GetterBody = {
603+
originalSchema: ReferenceObject | RequestBodyObject;
597604
imports: GeneratorImport[];
598605
definition: string;
599606
implementation: string;
@@ -623,6 +630,7 @@ export type GetterQueryParam = {
623630
schema: GeneratorSchema;
624631
deps: GeneratorSchema[];
625632
isOptional: boolean;
633+
originalSchema?: SchemaObject;
626634
};
627635

628636
export type GetterPropType = 'param' | 'body' | 'queryParam' | 'header';
@@ -668,22 +676,26 @@ export const SchemaType = {
668676
unknown: 'unknown',
669677
};
670678

671-
export type ResolverValue = {
679+
export type ScalarValue = {
672680
value: string;
673681
isEnum: boolean;
674682
type: SchemaType;
675683
imports: GeneratorImport[];
676684
schemas: GeneratorSchema[];
677-
originalSchema?: SchemaObject;
678685
isRef: boolean;
679686
};
680687

681-
export type ResReqTypesValue = ResolverValue & {
688+
export type ResolverValue = ScalarValue & {
689+
originalSchema: SchemaObject;
690+
};
691+
692+
export type ResReqTypesValue = ScalarValue & {
682693
formData?: string;
683694
formUrlEncoded?: string;
684695
isRef?: boolean;
685696
key: string;
686697
contentType: string;
698+
originalSchema?: SchemaObject;
687699
};
688700

689701
export type WriteSpecsBuilder = {

‎packages/orval/package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@
4343
},
4444
"scripts": {
4545
"build": "tsup ./src/bin/orval.ts ./src/index.ts --target node12 --minify --clean --dts --splitting",
46-
"dev": "tsup ./src/bin/orval.ts ./src/index.ts --target node12 --clean --watch src --onSuccess 'yarn generate-api'",
46+
"dev": "tsup ./src/bin/orval.ts ./src/index.ts --target node12 --clean --watch ./src --onSuccess 'yarn generate-api'",
4747
"lint": "eslint src/**/*.ts",
48-
"generate-api": "node ./dist/bin/orval.js --config ../../samples/react-query/basic/orval.config.ts --watch"
48+
"generate-api": "node ./dist/bin/orval.js --config ../../samples/react-query/basic/orval.config.ts"
4949
},
5050
"devDependencies": {
5151
"@types/chalk": "^2.2.0",
@@ -60,6 +60,7 @@
6060
"@orval/msw": "6.12.1",
6161
"@orval/query": "6.12.1",
6262
"@orval/swr": "6.12.1",
63+
"@orval/zod": "6.12.1",
6364
"ajv": "^8.11.0",
6465
"cac": "^6.7.12",
6566
"chalk": "^4.1.2",

‎packages/orval/src/client.ts

+6
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
import { generateMSW } from '@orval/msw';
2121
import query from '@orval/query';
2222
import swr from '@orval/swr';
23+
import zod from '@orval/zod';
2324

2425
const DEFAULT_CLIENT = OutputClient.AXIOS;
2526

@@ -31,6 +32,7 @@ export const GENERATOR_CLIENT: GeneratorClients = {
3132
'svelte-query': query({ type: 'svelte-query' })(),
3233
'vue-query': query({ type: 'vue-query' })(),
3334
swr: swr()(),
35+
zod: zod()(),
3436
};
3537

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

206+
if (!client.implementation) {
207+
return acc;
208+
}
209+
204210
acc[verbOption.operationId] = {
205211
implementation: verbOption.doc + client.implementation,
206212
imports: client.imports,

‎packages/query/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,7 @@ const generateQueryHook = async (
909909
}${body.implementation ? `, ${body.implementation}` : ''}];`;
910910

911911
const implementation = `${!queryKeyMutator ? queryKeyFn : ''}
912+
912913
913914
${queries.reduce(
914915
(acc, queryOption) =>

‎packages/zod/README.md

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
[![npm version](https://badge.fury.io/js/orval.svg)](https://badge.fury.io/js/orval)
2+
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
3+
[![tests](https://github.com/anymaniax/orval/actions/workflows/tests.yaml/badge.svg)](https://github.com/anymaniax/orval/actions/workflows/tests.yaml)
4+
5+
<p align="center">
6+
<img src="./logo/orval-logo-horizontal.svg?raw=true" width="500" height="160" alt="orval - Restfull Client Generator" />
7+
</p>
8+
<h1 align="center">
9+
Visit <a href="https://orval.dev" target="_blank">orval.dev</a> for docs, guides, API and beer!
10+
</h1>
11+
12+
### Code Generation
13+
14+
`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.
15+
16+
`Generate`, `valid`, `cache` and `mock` in your React, Vue, Svelte and Angular applications all with your OpenAPI specification.
17+
18+
### Samples
19+
20+
You can find below some samples
21+
22+
- [react app](https://github.com/anymaniax/orval/tree/master/samples/react-app)
23+
- [react query](https://github.com/anymaniax/orval/tree/master/samples/react-query)
24+
- [svelte query](https://github.com/anymaniax/orval/tree/master/samples/svelte-query)
25+
- [vue query](https://github.com/anymaniax/orval/tree/master/samples/vue-query)
26+
- [react app with swr](https://github.com/anymaniax/orval/tree/master/samples/react-app-with-swr)
27+
- [nx fastify react](https://github.com/anymaniax/orval/tree/master/samples/nx-fastify-react)
28+
- [angular app](https://github.com/anymaniax/orval/tree/master/samples/angular-app)

‎packages/zod/package.json

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "@orval/zod",
3+
"version": "6.12.1",
4+
"license": "MIT",
5+
"main": "./dist/index.js",
6+
"types": "./dist/index.d.ts",
7+
"files": [
8+
"dist"
9+
],
10+
"scripts": {
11+
"build": "tsup ./src/index.ts --target node12 --minify --clean --dts --splitting",
12+
"dev": "tsup ./src/index.ts --target node12 --clean --watch src",
13+
"lint": "eslint src/**/*.ts"
14+
},
15+
"dependencies": {
16+
"@orval/core": "6.12.1"
17+
}
18+
}

‎packages/zod/src/index.ts

+400
Large diffs are not rendered by default.

‎packages/zod/tsconfig.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"extends": "../../tsconfig.base.json",
3+
"include": ["src/**/*.ts"]
4+
}

1 commit comments

Comments
 (1)

vercel[bot] commented on Mar 27, 2023

@vercel[bot]
Please sign in to comment.