Skip to content

Commit

Permalink
Merge pull request #191 from hey-api/fix/options-experimental
Browse files Browse the repository at this point in the history
fix(api): add experimental flag
  • Loading branch information
mrlubos authored Mar 30, 2024
2 parents 3921a57 + a2f521e commit 1def4fa
Show file tree
Hide file tree
Showing 54 changed files with 4,779 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/strange-colts-smell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hey-api/openapi-ts": patch
---

fix(api): add experimental flag
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ jobs:
- name: Run linter
run: npm run lint

- name: Run type check
run: npm run typecheck

- name: Run unit tests
run: npm run test

Expand Down
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ const getConfig = async (userConfig: UserConfig, dependencies: Dependencies) =>
base,
debug = false,
enums = false,
experimental = false,
exportCore = true,
exportModels = true,
exportSchemas = true,
Expand Down Expand Up @@ -148,6 +149,7 @@ const getConfig = async (userConfig: UserConfig, dependencies: Dependencies) =>
client,
debug,
enums,
experimental,
exportCore,
exportModels,
exportSchemas,
Expand Down
2 changes: 2 additions & 0 deletions src/openApi/__tests__/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ describe('parse', () => {

const options: Parameters<typeof parse>[1] = {
client: 'fetch',
debug: false,
enums: 'javascript',
experimental: false,
exportCore: true,
exportModels: true,
exportSchemas: true,
Expand Down
2 changes: 2 additions & 0 deletions src/openApi/v2/parser/__tests__/getServices.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ describe('getServices', () => {
it('should create a unnamed service if tags are empty', () => {
const options: Parameters<typeof getServices>[1] = {
client: 'fetch',
debug: false,
enums: false,
experimental: false,
exportCore: true,
exportModels: true,
exportSchemas: true,
Expand Down
2 changes: 2 additions & 0 deletions src/openApi/v3/parser/__tests__/getServices.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ describe('getServices', () => {
it('should create a unnamed service if tags are empty', () => {
const options: Parameters<typeof getServices>[1] = {
client: 'fetch',
debug: false,
enums: false,
experimental: false,
exportCore: true,
exportModels: true,
exportSchemas: true,
Expand Down
9 changes: 9 additions & 0 deletions src/templates/partials/dataDestructure.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,17 @@ const {
{{~#notEquals @root.$config.serviceResponse 'generics'~}}
{{~#if parameters~}}
const {
{{#if @root.$config.experimental}}
query,
{{/if}}
{{#each parameters}}
{{#if @root.$config.experimental}}
{{#notEquals in 'query'}}
{{{name}}}{{#if default}} = {{{default}}}{{/if}},
{{/notEquals}}
{{else}}
{{{name}}}{{#if default}} = {{{default}}}{{/if}},
{{/if}}
{{/each}}
} = data;
{{/if}}
Expand Down
5 changes: 5 additions & 0 deletions src/types/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ export interface UserConfig {
* @default false
*/
enums?: 'javascript' | 'typescript' | false;
/**
* Generate an experimental build?
* @default false
*/
experimental?: boolean;
/**
* Generate core client classes?
* @default true
Expand Down
4 changes: 4 additions & 0 deletions src/utils/__tests__/handlebars.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ describe('registerHandlebarHelpers', () => {
registerHandlebarHelpers(
{
client: 'fetch',
debug: false,
enums: 'javascript',
experimental: false,
exportCore: true,
exportModels: true,
exportSchemas: true,
Expand Down Expand Up @@ -60,7 +62,9 @@ describe('registerHandlebarTemplates', () => {
const templates = registerHandlebarTemplates(
{
client: 'fetch',
debug: false,
enums: 'javascript',
experimental: false,
exportCore: true,
exportModels: true,
exportSchemas: true,
Expand Down
51 changes: 49 additions & 2 deletions src/utils/handlebars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,24 @@ const modelImports = (model: Service, path: string) => {
return `import type { ${model.imports.join(',')} } from '${path}';`;
};

const dataParameters = (parameters: OperationParameter[]) => {
const dataParameters = (config: Config, parameters: OperationParameter[]) => {
if (config.experimental) {
let output = parameters
.filter(parameter => parameter.default !== undefined)
.map(parameter => {
const key = parameter.prop;
const value = parameter.name;
if (key === value || escapeName(key) === key) {
return `${key}: ${parameter.default}`;
}
return `'${key}': ${parameter.default}`;
});
if (parameters.every(parameter => parameter.in === 'query')) {
output = [...output, '...query'];
}
return output.join(', ');
}

const output = parameters.map(parameter => {
const key = parameter.prop;
const value = parameter.name;
Expand Down Expand Up @@ -132,6 +149,12 @@ const operationDataType = (config: Config, service: Service) => {
const name = nameOperationDataType(operation.name);
return `export type ${name} = {
${sortByName(operation.parameters)
.filter(parameter => {
if (!config.experimental) {
return true;
}
return parameter.in !== 'query';
})
.map(parameter => {
let comment: string[] = [];
if (parameter.description) {
Expand All @@ -143,6 +166,26 @@ const operationDataType = (config: Config, service: Service) => {
].join('\n');
})
.join('\n')}
${
config.experimental
? `
query${operation.parametersQuery.every(parameter => !parameter.isRequired) ? '?' : ''}: {
${sortByName(operation.parametersQuery)
.map(parameter => {
let comment: string[] = [];
if (parameter.description) {
comment = ['/**', ` * ${escapeComment(parameter.description)}`, ' */'];
}
return [
...comment,
`${parameter.name + isRequired(parameter)}: ${partialType({ $config: config, ...parameter })}`,
].join('\n');
})
.join('\n')}
}
`
: ''
}
}`;
});
return output.join('\n');
Expand All @@ -151,7 +194,11 @@ const operationDataType = (config: Config, service: Service) => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export const registerHandlebarHelpers = (config: Config, client: Client): void => {
Handlebars.registerHelper('camelCase', camelCase);
Handlebars.registerHelper('dataParameters', dataParameters);

Handlebars.registerHelper('dataParameters', function (parameters: OperationParameter[]) {
return dataParameters(config, parameters);
});

Handlebars.registerHelper('enumKey', enumKey);
Handlebars.registerHelper('enumName', enumName);
Handlebars.registerHelper('enumUnionType', enumUnionType);
Expand Down
2 changes: 2 additions & 0 deletions src/utils/write/__tests__/class.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ describe('writeClientClass', () => {

await writeClientClass(client, mockTemplates, './dist', {
client: 'fetch',
debug: false,
enums: 'javascript',
experimental: false,
exportCore: true,
exportModels: true,
exportSchemas: true,
Expand Down
2 changes: 2 additions & 0 deletions src/utils/write/__tests__/client.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ describe('writeClient', () => {

await writeClient(client, mockTemplates, {
client: 'fetch',
debug: false,
enums: 'javascript',
experimental: false,
exportCore: true,
exportModels: true,
exportSchemas: true,
Expand Down
6 changes: 6 additions & 0 deletions src/utils/write/__tests__/core.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ describe('writeClientCore', () => {

const config: Parameters<typeof writeClientCore>[3] = {
client: 'fetch',
debug: false,
enums: 'javascript',
experimental: false,
exportCore: true,
exportModels: true,
exportSchemas: true,
Expand Down Expand Up @@ -64,7 +66,9 @@ describe('writeClientCore', () => {

const config: Parameters<typeof writeClientCore>[3] = {
client: 'fetch',
debug: false,
enums: 'javascript',
experimental: false,
exportCore: true,
exportModels: true,
exportSchemas: true,
Expand Down Expand Up @@ -104,7 +108,9 @@ describe('writeClientCore', () => {
const config: Parameters<typeof writeClientCore>[3] = {
base: 'foo',
client: 'fetch',
debug: false,
enums: 'javascript',
experimental: false,
exportCore: true,
exportModels: true,
exportSchemas: true,
Expand Down
2 changes: 2 additions & 0 deletions src/utils/write/__tests__/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ describe('writeClientIndex', () => {

await writeClientIndex(client, mockTemplates, '/', {
client: 'fetch',
debug: false,
enums: 'javascript',
experimental: false,
exportCore: true,
exportModels: true,
exportSchemas: true,
Expand Down
2 changes: 2 additions & 0 deletions src/utils/write/__tests__/models.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ describe('writeClientModels', () => {

await writeClientModels(client, mockTemplates, '/', {
client: 'fetch',
debug: false,
enums: 'javascript',
experimental: false,
exportCore: true,
exportModels: true,
exportSchemas: true,
Expand Down
2 changes: 2 additions & 0 deletions src/utils/write/__tests__/schemas.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ describe('writeClientSchemas', () => {

await writeClientSchemas(client, mockTemplates, '/', {
client: 'fetch',
debug: false,
enums: 'javascript',
experimental: false,
exportCore: true,
exportModels: true,
exportSchemas: true,
Expand Down
2 changes: 2 additions & 0 deletions src/utils/write/__tests__/services.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ describe('writeClientServices', () => {

await writeClientServices(client, mockTemplates, '/', {
client: 'fetch',
debug: false,
enums: false,
experimental: false,
exportCore: true,
exportModels: true,
exportSchemas: true,
Expand Down
21 changes: 21 additions & 0 deletions test/__snapshots__/v3_experimental/core/ApiError.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { ApiRequestOptions } from './ApiRequestOptions';
import type { ApiResult } from './ApiResult';

export class ApiError extends Error {
public readonly url: string;
public readonly status: number;
public readonly statusText: string;
public readonly body: unknown;
public readonly request: ApiRequestOptions;

constructor(request: ApiRequestOptions, response: ApiResult, message: string) {
super(message);

this.name = 'ApiError';
this.url = response.url;
this.status = response.status;
this.statusText = response.statusText;
this.body = response.body;
this.request = request;
}
}
13 changes: 13 additions & 0 deletions test/__snapshots__/v3_experimental/core/ApiRequestOptions.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export type ApiRequestOptions = {
readonly method: 'GET' | 'PUT' | 'POST' | 'DELETE' | 'OPTIONS' | 'HEAD' | 'PATCH';
readonly url: string;
readonly path?: Record<string, unknown>;
readonly cookies?: Record<string, unknown>;
readonly headers?: Record<string, unknown>;
readonly query?: Record<string, unknown>;
readonly formData?: Record<string, unknown>;
readonly body?: any;
readonly mediaType?: string;
readonly responseHeader?: string;
readonly errors?: Record<number, string>;
};
7 changes: 7 additions & 0 deletions test/__snapshots__/v3_experimental/core/ApiResult.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export type ApiResult<TData = any> = {
readonly body: TData;
readonly ok: boolean;
readonly status: number;
readonly statusText: string;
readonly url: string;
};
Loading

0 comments on commit 1def4fa

Please sign in to comment.