这是indexloc提供的服务,不要输入任何密码
Skip to content
Draft
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
12 changes: 7 additions & 5 deletions dev/openapi-ts.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,11 +272,13 @@ export default defineConfig(() => {
// signature: 'object',
// transformer: '@hey-api/transformers',
// transformer: true,
// validator: true,
// validator: {
// request: 'zod',
// response: 'zod',
// validator(operation) {
// return 'zod';
// },
validator: {
request: 'valibot',
response: 'zod',
},
'~hooks': {
symbols: {
// getFilePath: (symbol) => {
Expand Down Expand Up @@ -339,7 +341,7 @@ export default defineConfig(() => {
},
},
{
name: 'arktype',
// name: 'arktype',
// types: {
// infer: true,
// },
Expand Down
52 changes: 31 additions & 21 deletions packages/openapi-ts/src/plugins/@hey-api/sdk/config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { definePluginConfig } from '~/plugins/shared/utils/config';
import type { PluginValidatorNames } from '~/plugins/types';

import { Api } from './api';
import { handler } from './plugin';
Expand Down Expand Up @@ -47,32 +48,40 @@ export const defaultConfig: HeyApiSdkPlugin['Config'] = {
plugin.config.transformer = false;
}

if (typeof plugin.config.validator !== 'object') {
plugin.config.validator = {
request: plugin.config.validator,
response: plugin.config.validator,
};
}

if (plugin.config.validator.request) {
if (typeof plugin.config.validator.request === 'boolean') {
plugin.config.validator.request = context.pluginByTag('validator');
const { validator } = plugin.config;
plugin.config.validator = ((operation) => {
if (typeof validator === 'boolean') {
const validatorPlugin = validator
? context.pluginByTag('validator')
: undefined;
const validatorValue = validatorPlugin
? (validatorPlugin as PluginValidatorNames)
: false;
return {
request: validatorValue,
response: validatorValue,
};
}

plugin.dependencies.add(plugin.config.validator.request!);
} else {
plugin.config.validator.request = false;
}
if (typeof validator === 'string') {
return {
request: validator,
response: validator,
};
}

if (plugin.config.validator.response) {
if (typeof plugin.config.validator.response === 'boolean') {
plugin.config.validator.response = context.pluginByTag('validator');
if (typeof validator === 'function') {
const result = validator(operation);
if (typeof result === 'object') {
// result.request
}
}

plugin.dependencies.add(plugin.config.validator.response!);
} else {
plugin.config.validator.response = false;
}
return {
request: false,
response: false,
};
}) satisfies HeyApiSdkPlugin['Types']['resolvedConfig']['validator'];

if (plugin.config.instance) {
if (typeof plugin.config.instance !== 'string') {
Expand All @@ -91,6 +100,7 @@ export const defaultConfig: HeyApiSdkPlugin['Config'] = {
}
}
},
tags: ['sdk'],
};

/**
Expand Down
13 changes: 6 additions & 7 deletions packages/openapi-ts/src/plugins/@hey-api/sdk/shared/operation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import type { HeyApiSdkPlugin } from '../types';
import { operationAuth } from './auth';
import { nuxtTypeComposable, nuxtTypeDefault } from './constants';
import { getSignatureParameters } from './signature';
import { createRequestValidator, createResponseValidator } from './validator';
import { createValidators } from './validator';

interface ClassNameEntry {
/**
Expand Down Expand Up @@ -502,11 +502,11 @@ export const operationStatements = ({
});
}

const requestValidator = createRequestValidator({ operation, plugin });
if (requestValidator) {
const validators = createValidators({ operation, plugin });
if (validators.request) {
requestOptions.push({
key: 'requestValidator',
value: requestValidator,
value: validators.request,
});
}

Expand Down Expand Up @@ -553,11 +553,10 @@ export const operationStatements = ({
}
}

const responseValidator = createResponseValidator({ operation, plugin });
if (responseValidator) {
if (validators.response) {
requestOptions.push({
key: 'responseValidator',
value: responseValidator,
value: validators.response,
});
}

Expand Down
62 changes: 31 additions & 31 deletions packages/openapi-ts/src/plugins/@hey-api/sdk/shared/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,39 @@ import type { IR } from '~/ir/types';

import type { HeyApiSdkPlugin } from '../types';

interface ValidatorProps {
operation: IR.OperationObject;
plugin: HeyApiSdkPlugin['Instance'];
}

export const createRequestValidator = ({
operation,
plugin,
}: ValidatorProps): ts.ArrowFunction | undefined => {
if (!plugin.config.validator.request) return;

const validator = plugin.getPluginOrThrow(plugin.config.validator.request);
if (!validator.api.createRequestValidator) return;

return validator.api.createRequestValidator({
operation,
// @ts-expect-error
plugin: validator,
});
type Validators = {
request?: ts.ArrowFunction;
response?: ts.ArrowFunction;
};

export const createResponseValidator = ({
export const createValidators = ({
operation,
plugin,
}: ValidatorProps): ts.ArrowFunction | undefined => {
if (!plugin.config.validator.response) return;

const validator = plugin.getPluginOrThrow(plugin.config.validator.response);
if (!validator.api.createResponseValidator) return;

return validator.api.createResponseValidator({
operation,
// @ts-expect-error
plugin: validator,
});
}: {
operation: IR.OperationObject;
plugin: HeyApiSdkPlugin['Instance'];
}): Validators => {
const validators: Validators = {};
const values = plugin.config.validator(operation);
if (values.request) {
const validator = plugin.getPluginOrThrow(values.request);
if (validator.api.createRequestValidator) {
validators.request = validator.api.createRequestValidator({
operation,
// @ts-expect-error
plugin: validator,
});
}
}
if (values.response) {
const validator = plugin.getPluginOrThrow(values.response);
if (validator.api.createResponseValidator) {
validators.response = validator.api.createResponseValidator({
operation,
// @ts-expect-error
plugin: validator,
});
}
}
return validators;
};
82 changes: 33 additions & 49 deletions packages/openapi-ts/src/plugins/@hey-api/sdk/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,34 @@ import type { StringName } from '~/types/case';

import type { IApi } from './api';

type ValidatorValue = PluginValidatorNames | boolean;
type ValidatorResult =
| ValidatorValue
| {
/**
* Validate request data against schema before sending.
*
* Can be a validator plugin name or boolean (true to auto-select, false
* to disable).
*
* @default false
*/
request?:
| ValidatorValue
| ((operation: IR.OperationObject) => ValidatorValue);
/**
* Validate response data against schema before returning.
*
* Can be a validator plugin name or boolean (true to auto-select, false
* to disable).
*
* @default false
*/
response?:
| ValidatorValue
| ((operation: IR.OperationObject) => ValidatorValue);
};

export type UserConfig = Plugin.Name<'@hey-api/sdk'> &
Plugin.Hooks & {
/**
Expand Down Expand Up @@ -137,50 +165,18 @@ export type UserConfig = Plugin.Name<'@hey-api/sdk'> &
* @default false
*/
validator?:
| PluginValidatorNames
| boolean
| {
/**
* Validate request data against schema before sending.
*
* Can be a validator plugin name or boolean (true to auto-select, false
* to disable).
*
* @default false
*/
request?: PluginValidatorNames | boolean;
/**
* Validate response data against schema before returning.
*
* Can be a validator plugin name or boolean (true to auto-select, false
* to disable).
*
* @default false
*/
response?: PluginValidatorNames | boolean;
};
| ValidatorResult
| ((operation: IR.OperationObject) => ValidatorResult);

// DEPRECATED OPTIONS BELOW

/**
* **This feature works only with the legacy parser**
*
* Filter endpoints to be included in the generated SDK. The provided
* string should be a regular expression where matched results will be
* included in the output. The input pattern this string will be tested
* against is `{method} {path}`. For example, you can match
* `POST /api/v1/foo` with `^POST /api/v1/foo$`.
*
* @deprecated
*/
// eslint-disable-next-line typescript-sort-keys/interface
filter?: string;
/**
* Define shape of returned value from service calls
*
* @deprecated
* @default 'body'
*/
// eslint-disable-next-line typescript-sort-keys/interface
response?: 'body' | 'response';
};

Expand Down Expand Up @@ -303,7 +299,7 @@ export type Config = Plugin.Name<'@hey-api/sdk'> &
* to a desired shape. However, validation adds runtime overhead, so it's
* not recommended to use unless absolutely necessary.
*/
validator: {
validator: (operation: IR.OperationObject) => {
/**
* The validator plugin to use for request validation, or false to disable.
*
Expand All @@ -320,25 +316,13 @@ export type Config = Plugin.Name<'@hey-api/sdk'> &

// DEPRECATED OPTIONS BELOW

/**
* **This feature works only with the legacy parser**
*
* Filter endpoints to be included in the generated SDK. The provided
* string should be a regular expression where matched results will be
* included in the output. The input pattern this string will be tested
* against is `{method} {path}`. For example, you can match
* `POST /api/v1/foo` with `^POST /api/v1/foo$`.
*
* @deprecated
*/
// eslint-disable-next-line typescript-sort-keys/interface
filter?: string;
/**
* Define shape of returned value from service calls
*
* @deprecated
* @default 'body'
*/
// eslint-disable-next-line typescript-sort-keys/interface
response: 'body' | 'response';
};

Expand Down
Loading