fork of hey-api/openapi-ts because I need some additional things
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #573 from hey-api/fix/enums-clash

fix: deduplicate inlined enums

authored by

Lubos and committed by
GitHub
56e31bf0 67beaab2

+38 -21
+5
.changeset/mean-phones-beg.md
··· 1 + --- 2 + "@hey-api/openapi-ts": patch 3 + --- 4 + 5 + fix: deduplicate inlined enums
+2 -8
packages/openapi-ts/src/openApi/v3/parser/getModel.ts
··· 1 - import { unescapeName } from '../../../utils/escape'; 1 + import { enumMeta } from '../../../utils/enum'; 2 2 import type { Model, ModelMeta } from '../../common/interfaces/client'; 3 3 import { getDefault } from '../../common/parser/getDefault'; 4 4 import { getEnums } from '../../common/parser/getEnums'; 5 5 import { getPattern } from '../../common/parser/getPattern'; 6 - import { ensureValidTypeScriptJavaScriptIdentifier } from '../../common/parser/sanitize'; 7 6 import { getType } from '../../common/parser/type'; 8 7 import type { OpenApi } from '../interfaces/OpenApi'; 9 8 import type { OpenApiSchema } from '../interfaces/OpenApiSchema'; ··· 99 98 model.type = 'string'; 100 99 model.default = getDefault(definition, model); 101 100 if (!model.meta) { 102 - model.meta = { 103 - $ref: `enum/${model.name}`, 104 - name: ensureValidTypeScriptJavaScriptIdentifier( 105 - unescapeName(model.name), 106 - ), 107 - }; 101 + model.meta = enumMeta(model); 108 102 } 109 103 return model; 110 104 }
+2 -8
packages/openapi-ts/src/openApi/v3/parser/getOperationParameter.ts
··· 1 - import { unescapeName } from '../../../utils/escape'; 1 + import { enumMeta } from '../../../utils/enum'; 2 2 import type { OperationParameter } from '../../common/interfaces/client'; 3 3 import { getDefault } from '../../common/parser/getDefault'; 4 4 import { getPattern } from '../../common/parser/getPattern'; 5 5 import { getRef } from '../../common/parser/getRef'; 6 6 import { getOperationParameterName } from '../../common/parser/operation'; 7 - import { ensureValidTypeScriptJavaScriptIdentifier } from '../../common/parser/sanitize'; 8 7 import { getType } from '../../common/parser/type'; 9 8 import type { OpenApi } from '../interfaces/OpenApi'; 10 9 import type { OpenApiParameter } from '../interfaces/OpenApiParameter'; ··· 110 109 (operationParameter.enum.length || operationParameter.enums.length) && 111 110 !operationParameter.meta 112 111 ) { 113 - operationParameter.meta = { 114 - $ref: `enum/${operationParameter.name}`, 115 - name: ensureValidTypeScriptJavaScriptIdentifier( 116 - unescapeName(operationParameter.name), 117 - ), 118 - }; 112 + operationParameter.meta = enumMeta(operationParameter); 119 113 } 120 114 operationParameter.default = model.default; 121 115 return operationParameter;
+26 -1
packages/openapi-ts/src/utils/enum.ts
··· 1 - import type { Enum } from '../openApi'; 1 + import type { Enum, Model } from '../openApi'; 2 + import { ensureValidTypeScriptJavaScriptIdentifier } from '../openApi/common/parser/sanitize'; 3 + import { unescapeName } from './escape'; 4 + import { sort } from './sort'; 2 5 import { unique } from './unique'; 3 6 4 7 /** ··· 49 52 } 50 53 return value; 51 54 }; 55 + 56 + export const enumEntry = (enumerator: Enum) => { 57 + const key = enumKey(enumerator.value, enumerator.customName); 58 + const value = enumValue(enumerator.value); 59 + return { key, value }; 60 + }; 61 + 62 + /** 63 + * Represent enum in `meta` object for deduplication 64 + */ 65 + export const enumMeta = (model: Model): Required<Model>['meta'] => { 66 + // serialize enum values in namespace for quick lookup 67 + const serialized = model.enum 68 + .map((enumerator) => enumEntry(enumerator)) 69 + .sort((a, b) => sort(a.key, b.key)) 70 + .map((enumerator) => `${enumerator.key}=${enumerator.value}`) 71 + .join('&'); 72 + return { 73 + $ref: `enum/${model.name}/${serialized}`, 74 + name: ensureValidTypeScriptJavaScriptIdentifier(unescapeName(model.name)), 75 + }; 76 + };
+2 -3
packages/openapi-ts/src/utils/write/types.ts
··· 7 7 import type { Model, OperationParameter, Service } from '../../openApi'; 8 8 import type { Client } from '../../types/client'; 9 9 import { getConfig } from '../config'; 10 - import { enumKey, enumUnionType, enumValue } from '../enum'; 10 + import { enumEntry, enumUnionType } from '../enum'; 11 11 import { escapeComment } from '../escape'; 12 12 import { sortByName, sorterByName } from '../sort'; 13 13 import { operationDataTypeName, operationResponseTypeName } from './services'; ··· 103 103 const properties: Record<string | number, unknown> = {}; 104 104 const comments: Record<string | number, Comments> = {}; 105 105 model.enum.forEach((enumerator) => { 106 - const key = enumKey(enumerator.value, enumerator.customName); 107 - const value = enumValue(enumerator.value); 106 + const { key, value } = enumEntry(enumerator); 108 107 properties[key] = value; 109 108 const comment = enumerator.customDescription || enumerator.description; 110 109 if (comment) {
+1 -1
packages/openapi-ts/test/sample.cjs
··· 15 15 // export: false, 16 16 }, 17 17 types: { 18 - // enums: 'javascript', 18 + enums: 'typescript', 19 19 // include: '^NestedAnyOfArraysNullable', 20 20 // name: 'PascalCase', 21 21 },