Skip to content

Commit

Permalink
chore: remove fastify dependency on services
Browse files Browse the repository at this point in the history
  • Loading branch information
mrlubos committed Nov 17, 2024
1 parent 4a939d1 commit 8a15a35
Show file tree
Hide file tree
Showing 29 changed files with 198 additions and 1,033 deletions.
5 changes: 5 additions & 0 deletions .changeset/honest-rings-obey.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@hey-api/openapi-ts': patch
---

fix: deprecate types.tree option
28 changes: 2 additions & 26 deletions packages/openapi-ts/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,6 @@ import { sync } from 'cross-spawn';
import { generateLegacyOutput, generateOutput } from './generate/output';
import type { IRContext } from './ir/context';
import { parseExperimental, parseLegacy } from './openApi';
import type { ParserConfig } from './openApi/config';
import {
operationFilterFn,
operationNameFn,
operationParameterFilterFn,
operationParameterNameFn,
} from './openApi/config';
import type { ClientPlugins } from './plugins';
import { defaultPluginConfigs } from './plugins';
import type { DefaultPluginConfigsMap, PluginNames } from './plugins/types';
Expand Down Expand Up @@ -413,34 +406,17 @@ export async function createClient(
let context: IRContext | undefined;

Performance.start('parser');
const parserConfig: ParserConfig = {
filterFn: {
operation: operationFilterFn,
operationParameter: operationParameterFilterFn,
},
nameFn: {
operation: operationNameFn,
operationParameter: operationParameterNameFn,
},
};
if (
config.experimentalParser &&
!isLegacyClient(config) &&
!legacyNameFromConfig(config)
) {
context = parseExperimental({
config,
parserConfig,
spec,
});
context = parseExperimental({ config, spec });
}

// fallback to legacy parser
if (!context) {
const parsed = parseLegacy({
openApi: spec,
parserConfig,
});
const parsed = parseLegacy({ openApi: spec });
client = postProcessClient(parsed);
}
Performance.end('parser');
Expand Down
13 changes: 1 addition & 12 deletions packages/openapi-ts/src/ir/context.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import path from 'node:path';

import { TypeScriptFile } from '../generate/files';
import type { ParserConfig } from '../openApi/config';
import type { Config } from '../types/config';
import type { Files } from '../types/utils';
import { resolveRef } from '../utils/ref';
Expand Down Expand Up @@ -34,25 +33,15 @@ export class IRContext<Spec extends Record<string, any> = any> {
* Intermediate representation model obtained from `spec`.
*/
public ir: IR;
public parserConfig: ParserConfig;
/**
* Resolved specification from `input`.
*/
public spec: Spec;

constructor({
config,
parserConfig,
spec,
}: {
config: Config;
parserConfig: ParserConfig;
spec: Spec;
}) {
constructor({ config, spec }: { config: Config; spec: Spec }) {
this.config = config;
this.files = {};
this.ir = {};
this.parserConfig = parserConfig;
this.spec = spec;
}

Expand Down
7 changes: 4 additions & 3 deletions packages/openapi-ts/src/openApi/3.0.x/parser/operation.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { IRContext } from '../../../ir/context';
import type { IROperationObject, IRPathsObject } from '../../../ir/ir';
import { operationToId } from '../../shared/utils/operation';
import type {
OperationObject,
PathItemObject,
Expand Down Expand Up @@ -205,10 +206,10 @@ export const parseOperation = ({
context.ir.paths[path] = {};
}

operation.id = context.parserConfig.nameFn.operation({
config: context.config,
operation.id = operationToId({
context,
id: operation.operationId,

Check warning on line 211 in packages/openapi-ts/src/openApi/3.0.x/parser/operation.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/openApi/3.0.x/parser/operation.ts#L209-L211

Added lines #L209 - L211 were not covered by tests
method,
operationId: operation.operationId,
path,
});

Expand Down
7 changes: 4 additions & 3 deletions packages/openapi-ts/src/openApi/3.1.x/parser/operation.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { IRContext } from '../../../ir/context';
import type { IROperationObject, IRPathsObject } from '../../../ir/ir';
import { operationToId } from '../../shared/utils/operation';
import type {
OperationObject,
PathItemObject,
Expand Down Expand Up @@ -193,10 +194,10 @@ export const parseOperation = ({
context.ir.paths[path] = {};
}

operation.id = context.parserConfig.nameFn.operation({
config: context.config,
operation.id = operationToId({
context,
id: operation.operationId,
method,
operationId: operation.operationId,
path,
});

Expand Down
33 changes: 6 additions & 27 deletions packages/openapi-ts/src/openApi/__tests__/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import type { OpenApiV3_0_X } from '../3.0.x';
import { parseV3_0_X } from '../3.0.x';
import type { OpenApiV3_1_X } from '../3.1.x';
import { parseV3_1_X } from '../3.1.x';
import type { ParserConfig } from '../config';
import * as parseV2 from '../v2';
import * as parseV3 from '../v3';

Expand All @@ -16,17 +15,6 @@ vi.mock('../3.1.x', () => ({
parseV3_1_X: vi.fn(),
}));

const parserConfig: ParserConfig = {
filterFn: {
operation: () => true,
operationParameter: () => true,
},
nameFn: {
operation: () => 'operation',
operationParameter: () => 'operationParameter',
},
};

describe('parse', () => {
afterEach(() => {
vi.restoreAllMocks();
Expand All @@ -43,7 +31,7 @@ describe('parse', () => {
paths: {},
swagger: '2',
};
parseLegacy({ openApi: spec, parserConfig });
parseLegacy({ openApi: spec });
expect(spy).toHaveBeenCalledWith(spec);

const spec2: OpenApi = {
Expand All @@ -54,7 +42,7 @@ describe('parse', () => {
paths: {},
swagger: '2.0',
};
parseLegacy({ openApi: spec2, parserConfig });
parseLegacy({ openApi: spec2 });
expect(spy).toHaveBeenCalledWith(spec2);
});

Expand All @@ -69,7 +57,7 @@ describe('parse', () => {
openapi: '3',
paths: {},
};
parseLegacy({ openApi: spec, parserConfig });
parseLegacy({ openApi: spec });
expect(spy).toHaveBeenCalledWith(spec);

const spec2: OpenApi = {
Expand All @@ -80,7 +68,7 @@ describe('parse', () => {
openapi: '3.0',
paths: {},
};
parseLegacy({ openApi: spec2, parserConfig });
parseLegacy({ openApi: spec2 });
expect(spy).toHaveBeenCalledWith(spec2);

const spec3: OpenApi = {
Expand All @@ -91,14 +79,12 @@ describe('parse', () => {
openapi: '3.1.0',
paths: {},
};
parseLegacy({ openApi: spec3, parserConfig });
parseLegacy({ openApi: spec3 });
expect(spy).toHaveBeenCalledWith(spec3);
});

it('throws on unknown version', () => {
expect(() =>
parseLegacy({ openApi: { foo: 'bar' }, parserConfig }),
).toThrow(
expect(() => parseLegacy({ openApi: { foo: 'bar' } })).toThrow(
`Unsupported OpenAPI specification: ${JSON.stringify({ foo: 'bar' }, null, 2)}`,
);
});
Expand All @@ -121,7 +107,6 @@ describe('experimentalParser', () => {
parseExperimental({
// @ts-ignore
config: {},
parserConfig,
spec,
});
expect(parseV3_0_X).toHaveBeenCalled();
Expand All @@ -139,7 +124,6 @@ describe('experimentalParser', () => {
parseExperimental({
// @ts-ignore
config: {},
parserConfig,
spec,
});
expect(parseV3_0_X).toHaveBeenCalled();
Expand All @@ -157,7 +141,6 @@ describe('experimentalParser', () => {
parseExperimental({
// @ts-ignore
config: {},
parserConfig,
spec,
});
expect(parseV3_0_X).toHaveBeenCalled();
Expand All @@ -175,7 +158,6 @@ describe('experimentalParser', () => {
parseExperimental({
// @ts-ignore
config: {},
parserConfig,
spec,
});
expect(parseV3_0_X).toHaveBeenCalled();
Expand All @@ -193,7 +175,6 @@ describe('experimentalParser', () => {
parseExperimental({
// @ts-ignore
config: {},
parserConfig,
spec,
});
expect(parseV3_0_X).toHaveBeenCalled();
Expand All @@ -210,7 +191,6 @@ describe('experimentalParser', () => {
parseExperimental({
// @ts-ignore
config: {},
parserConfig,
spec,
});
expect(parseV3_1_X).toHaveBeenCalled();
Expand All @@ -227,7 +207,6 @@ describe('experimentalParser', () => {
parseExperimental({
// @ts-ignore
config: {},
parserConfig,
spec,
});
expect(parseV3_1_X).toHaveBeenCalled();
Expand Down
81 changes: 81 additions & 0 deletions packages/openapi-ts/src/openApi/common/parser/operation.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import type { Config } from '../../../types/config';
import { camelCase } from '../../../utils/camelCase';
import { getConfig, isLegacyClient } from '../../../utils/config';
import { transformTypeKeyName } from '../../../utils/type';
import type {
OperationParameter,
OperationResponse,
} from '../interfaces/client';
import { sanitizeNamespaceIdentifier } from './sanitize';

export const getOperationKey = (operation: {
method: string;
Expand Down Expand Up @@ -153,6 +158,82 @@ const inferDefaultResponseTypes = (
return types;
};

export const operationFilterFn = ({
config,
operationKey,
}: {
config: Config;
operationKey: string;
}): boolean => {
const regexp = config.plugins['@hey-api/services']?.filter
? new RegExp(config.plugins['@hey-api/services']?.filter)

Check warning on line 169 in packages/openapi-ts/src/openApi/common/parser/operation.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/openApi/common/parser/operation.ts#L169

Added line #L169 was not covered by tests
: undefined;
return !regexp || regexp.test(operationKey);
};

/**
* Convert the input value to a correct operation (method) class name.
* This will use the operation ID - if available - and otherwise fallback
* on a generated name from the URL
*/
export const operationNameFn = ({
config,
method,
operationId,
path,
}: {
config: Config;
method: string;
operationId: string | undefined;
path: string;
}): string => {
if (config.plugins['@hey-api/services']?.operationId && operationId) {
return camelCase({
input: sanitizeNamespaceIdentifier(operationId),
});
}

let urlWithoutPlaceholders = path;

// legacy clients ignore the "api-version" param since we do not want to
// add it as the first/default parameter for each of the service calls
if (isLegacyClient(config)) {
urlWithoutPlaceholders = urlWithoutPlaceholders.replace(
/[^/]*?{api-version}.*?\//g,
'',
);
}

urlWithoutPlaceholders = urlWithoutPlaceholders
.replace(/{(.*?)}/g, 'by-$1')
// replace slashes with hyphens for camelcase method at the end
.replace(/[/:]/g, '-');

return camelCase({
input: `${method}-${urlWithoutPlaceholders}`,
});
};

export const operationParameterFilterFn = (
parameter: OperationParameter,
): boolean => {
const config = getConfig();

// legacy clients ignore the "api-version" param since we do not want to
// add it as the first/default parameter for each of the service calls
return !isLegacyClient(config) || parameter.prop !== 'api-version';
};

export const operationParameterNameFn = (
parameter: Omit<OperationParameter, 'name'>,
): string => {
const config = getConfig();

return !isLegacyClient(config)
? parameter.prop
: transformTypeKeyName(parameter.prop);

Check warning on line 234 in packages/openapi-ts/src/openApi/common/parser/operation.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/openApi/common/parser/operation.ts#L234

Added line #L234 was not covered by tests
};

export const tagResponseTypes = (responses: OperationResponse[]) =>
responses.map((response) => {
const { code } = response;
Expand Down
Loading

0 comments on commit 8a15a35

Please sign in to comment.