Skip to content

Commit

Permalink
fix: add sdk.throwOnError option
Browse files Browse the repository at this point in the history
  • Loading branch information
mrlubos committed Dec 26, 2024
1 parent dff8b81 commit d4e1ae8
Show file tree
Hide file tree
Showing 16 changed files with 4,772 additions and 47 deletions.
5 changes: 5 additions & 0 deletions .changeset/funny-donuts-call.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@hey-api/openapi-ts': patch
---

fix: add `sdk.throwOnError` option
1 change: 1 addition & 0 deletions packages/openapi-ts/src/compiler/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const compiler = {
anonymousFunction: types.createAnonymousFunction,
arrayLiteralExpression: types.createArrayLiteralExpression,
arrowFunction: types.createArrowFunction,
asExpression: types.createAsExpression,
assignment: types.createAssignment,
awaitExpression: types.createAwaitExpression,
binaryExpression: transform.createBinaryExpression,
Expand Down
15 changes: 7 additions & 8 deletions packages/openapi-ts/src/compiler/module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import ts from 'typescript';

import { createTypeReferenceNode } from './types';
import { createAsExpression, createTypeReferenceNode } from './types';
import {
addLeadingComments,
type Comments,
Expand Down Expand Up @@ -126,14 +126,13 @@ export const createConstVariable = ({
typeName?: string | ts.IndexedAccessTypeNode | ts.TypeNode;
}): ts.VariableStatement => {
const initializer = assertion
? ts.factory.createAsExpression(
? createAsExpression({
expression,
typeof assertion === 'string'
? createTypeReferenceNode({
typeName: assertion,
})
: assertion,
)
type:
typeof assertion === 'string'
? createTypeReferenceNode({ typeName: assertion })
: assertion,
})
: expression;
const nameIdentifier = createIdentifier({ text: name });
const declaration = ts.factory.createVariableDeclaration(
Expand Down
21 changes: 16 additions & 5 deletions packages/openapi-ts/src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ export const createFunctionTypeNode = ({

export type ObjectValue =
| {
assertion?: 'any';
assertion?: 'any' | ts.TypeNode;
comments?: Comments;
spread: string;
}
Expand Down Expand Up @@ -511,10 +511,13 @@ export const createObjectType = <
: createIdentifier({ text: value.spread });
assignment = ts.factory.createSpreadAssignment(
value.assertion
? ts.factory.createAsExpression(
nameIdentifier,
createKeywordTypeNode({ keyword: value.assertion }),
)
? createAsExpression({
expression: nameIdentifier,
type:
typeof value.assertion === 'string'
? createKeywordTypeNode({ keyword: value.assertion })
: value.assertion,
})
: nameIdentifier,
);
} else if (value.shorthand || (shorthand && canShorthand)) {
Expand Down Expand Up @@ -902,3 +905,11 @@ export const createRegularExpressionLiteral = ({
flags?: ReadonlyArray<'g' | 'i' | 'm' | 's' | 'u' | 'y'>;
text: string;
}) => ts.factory.createRegularExpressionLiteral(`/${text}/${flags.join('')}`);

export const createAsExpression = ({
expression,
type,
}: {
expression: ts.Expression;
type: ts.TypeNode;
}) => ts.factory.createAsExpression(expression, type);
1 change: 1 addition & 0 deletions packages/openapi-ts/src/plugins/@hey-api/sdk/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export const defaultConfig: Plugin.Config<Config> = {
output: 'sdk',
response: 'body',
serviceNameBuilder: '{{name}}Service',
throwOnError: false,
};

/**
Expand Down
85 changes: 60 additions & 25 deletions packages/openapi-ts/src/plugins/@hey-api/sdk/plugin-legacy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import type {
OperationParameter,
Service,
} from '../../../types/client';
import type { Config } from '../../../types/config';
import type { Config as ClientConfig } from '../../../types/config';
import {
getConfig,
isLegacyClient,
Expand All @@ -33,6 +33,7 @@ import { transformServiceName } from '../../../utils/transform';
import { setUniqueTypeName } from '../../../utils/type';
import { unique } from '../../../utils/unique';
import type { Plugin } from '../../types';
import type { Config } from './types';

type OnNode = (node: Node) => void;
type OnImport = (name: string) => void;
Expand Down Expand Up @@ -270,12 +271,17 @@ const toOperationComment = (operation: Operation): Comments => {
return comment;
};

const toRequestOptions = (
client: Client,
operation: Operation,
onImport: OnImport,
onClientImport: OnImport | undefined,
) => {
const toRequestOptions = ({
client,
onClientImport,
onImport,
operation,
}: {
client: Client;
onClientImport: OnImport | undefined;
onImport: OnImport;
operation: Operation;
}) => {
const config = getConfig();

const name = operationResponseTypeName(operation.name);
Expand Down Expand Up @@ -488,7 +494,7 @@ export const serviceFunctionIdentifier = ({
id,
operation,
}: {
config: Config;
config: ClientConfig;
handleIllegal?: boolean;
id: string;
operation: IR.OperationObject | Operation;
Expand All @@ -504,15 +510,25 @@ export const serviceFunctionIdentifier = ({
return id;
};

const toOperationStatements = (
client: Client,
operation: Operation,
onImport: OnImport,
onClientImport?: OnImport,
) => {
const toOperationStatements = ({
client,
onClientImport,
onImport,
operation,
}: {
client: Client;
onClientImport?: OnImport;
onImport: OnImport;
operation: Operation;
}) => {
const config = getConfig();

const options = toRequestOptions(client, operation, onImport, onClientImport);
const options = toRequestOptions({
client,
onClientImport,
onImport,
operation,
});

if (!isLegacyClient(config)) {
const errorType = setUniqueTypeName({
Expand Down Expand Up @@ -587,12 +603,14 @@ const processService = ({
onClientImport,
onImport,
onNode,
plugin,
service,
}: {
client: Client;
onClientImport: OnImport;
onImport: OnImport;
onNode: OnNode;
plugin: Plugin.Instance<Config>;
service: Service;
}) => {
const config = getConfig();
Expand Down Expand Up @@ -647,7 +665,7 @@ const processService = ({
}

const throwOnErrorTypeGeneric: FunctionTypeParameter = {
default: false,
default: plugin.throwOnError,
extends: 'boolean',
name: 'ThrowOnError',
};
Expand All @@ -662,12 +680,12 @@ const processService = ({
returnType: !isLegacy
? undefined
: toOperationReturnType(client, operation),
statements: toOperationStatements(
statements: toOperationStatements({
client,
operation,
onImport,
onClientImport,
),
onImport,
operation,
}),
types: !isLegacy ? [throwOnErrorTypeGeneric] : undefined,
};
const expression =
Expand Down Expand Up @@ -706,12 +724,12 @@ const processService = ({
returnType: !isLegacy
? undefined
: toOperationReturnType(client, operation),
statements: toOperationStatements(
statements: toOperationStatements({
client,
operation,
onImport,
onClientImport,
),
onImport,
operation,
}),
types: !isLegacy ? [throwOnErrorTypeGeneric] : undefined,
});
return node;
Expand Down Expand Up @@ -768,7 +786,11 @@ const processService = ({
onNode(statement);
};

export const handlerLegacy: Plugin.LegacyHandler<any> = ({ client, files }) => {
export const handlerLegacy: Plugin.LegacyHandler<Config> = ({
client,
files,
plugin,
}) => {
const config = getConfig();

if (!config.client.name) {
Expand Down Expand Up @@ -863,6 +885,18 @@ export const handlerLegacy: Plugin.LegacyHandler<any> = ({ client, files }) => {
parameters: [
compiler.callExpression({
functionName: 'createConfig',
parameters: [
plugin.throwOnError
? compiler.objectExpression({
obj: [
{
key: 'throwOnError',
value: plugin.throwOnError,
},
],
})
: undefined,
],
}),
],
}),
Expand Down Expand Up @@ -891,6 +925,7 @@ export const handlerLegacy: Plugin.LegacyHandler<any> = ({ client, files }) => {
onNode: (node) => {
files.sdk!.add(node);
},
plugin,
service,
});
}
Expand Down
16 changes: 14 additions & 2 deletions packages/openapi-ts/src/plugins/@hey-api/sdk/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ const generateClassSdk = ({
}),
types: [
{
default: false,
default: plugin.throwOnError,
extends: 'boolean',
name: 'ThrowOnError',
},
Expand Down Expand Up @@ -523,7 +523,7 @@ const generateFlatSdk = ({
}),
types: [
{
default: false,
default: plugin.throwOnError,
extends: 'boolean',
name: 'ThrowOnError',
},
Expand Down Expand Up @@ -585,6 +585,18 @@ export const handler: Plugin.Handler<Config> = ({ context, plugin }) => {
parameters: [
compiler.callExpression({
functionName: 'createConfig',
parameters: [
plugin.throwOnError
? compiler.objectExpression({
obj: [
{
key: 'throwOnError',
value: plugin.throwOnError,
},
],
})
: undefined,
],
}),
],
}),
Expand Down
6 changes: 6 additions & 0 deletions packages/openapi-ts/src/plugins/@hey-api/sdk/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ export interface Config extends Plugin.Name<'@hey-api/sdk'> {
* @default '{{name}}Service'
*/
serviceNameBuilder?: string;
/**
* Throw an error instead of returning it in the response?
*
* @default false
*/
throwOnError?: boolean;
/**
* Transform response data before returning. This is useful if you want to
* convert for example ISO strings into Date objects. However, transformation
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// This file is auto-generated by @hey-api/openapi-ts
export * from './types.gen';
export * from './sdk.gen';
Loading

0 comments on commit d4e1ae8

Please sign in to comment.