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

Merge pull request #2883 from hey-api/refactor/selector-angular

refactor: remove selectors from angular plugin

authored by

Lubos and committed by
GitHub
ff89df22 4bf4e946

+172 -192
+3
packages/openapi-ts/src/index.ts
··· 21 21 | 'hook' 22 22 | 'schema' 23 23 | 'sdk' 24 + | 'transform' 24 25 | 'type' 25 26 | 'utility' 26 27 | (string & {}); ··· 52 53 */ 53 54 tags?: ReadonlyArray<string>; 54 55 tool?: 56 + | 'angular' 55 57 | 'arktype' 56 58 | 'fastify' 59 + | 'json-schema' 57 60 | 'typescript' 58 61 | 'valibot' 59 62 | 'zod'
+2 -34
packages/openapi-ts/src/plugins/@angular/common/api.ts
··· 1 - import type { Selector } from '@hey-api/codegen-core'; 2 - 3 - import type { Plugin } from '~/plugins'; 4 - 5 - type SelectorType = 6 - | 'class' 7 - | 'httpRequest' 8 - | 'httpResource' 9 - | 'HttpRequest' 10 - | 'inject' 11 - | 'Injectable'; 12 - 13 - export type IApi = { 14 - /** 15 - * @param type Selector type. 16 - * @param value Depends on `type`: 17 - * - `class`: raw string entry from path 18 - * - `httpRequest`: `operation.id` string 19 - * - `httpResource`: never 20 - * - `HttpRequest`: never 21 - * - `inject`: never 22 - * - `Injectable`: never 23 - * @returns Selector array 24 - * @deprecated 25 - */ 26 - selector: (type: SelectorType, value?: string) => Selector; 27 - }; 1 + export type IApi = any; 28 2 29 - export class Api implements IApi { 30 - constructor(public meta: Plugin.Name<'@angular/common'>) {} 31 - 32 - selector(...args: ReadonlyArray<string | undefined>): Selector { 33 - return [this.meta.name, ...(args as Selector)]; 34 - } 35 - } 3 + export class Api implements IApi {}
+1 -3
packages/openapi-ts/src/plugins/@angular/common/config.ts
··· 5 5 import type { AngularCommonPlugin } from './types'; 6 6 7 7 export const defaultConfig: AngularCommonPlugin['Config'] = { 8 - api: new Api({ 9 - name: '@angular/common', 10 - }), 8 + api: new Api(), 11 9 config: { 12 10 exportFromIndex: false, 13 11 },
+25 -11
packages/openapi-ts/src/plugins/@angular/common/httpRequests.ts
··· 135 135 } 136 136 } 137 137 138 - const symbolInjectable = plugin.referenceSymbol( 139 - plugin.api.selector('Injectable'), 140 - ); 138 + const symbolInjectable = plugin.referenceSymbol({ 139 + category: 'external', 140 + resource: '@angular/core.Injectable', 141 + }); 141 142 const symbolClass = plugin.registerSymbol({ 142 143 exported: true, 144 + meta: { 145 + category: 'utility', 146 + resource: 'class', 147 + resourceId: currentClass.className, 148 + tool: 'angular', 149 + }, 143 150 name: buildName({ 144 151 config: { 145 152 case: 'preserve', ··· 147 154 }, 148 155 name: currentClass.className, 149 156 }), 150 - selector: plugin.api.selector('class', currentClass.className), 151 157 }); 152 158 const node = tsc.classDeclaration({ 153 159 decorator: currentClass.root ··· 185 191 186 192 const symbol = plugin.registerSymbol({ 187 193 exported: true, 194 + meta: { 195 + category: 'utility', 196 + resource: 'operation', 197 + resourceId: operation.id, 198 + role: 'data', 199 + tool: 'angular', 200 + }, 188 201 name: plugin.config.httpRequests.methodNameBuilder(operation), 189 - selector: plugin.api.selector('httpRequest', operation.id), 190 202 }); 191 203 const node = generateAngularRequestFunction({ 192 204 isRequiredOptions, ··· 272 284 operation: IR.OperationObject; 273 285 plugin: AngularCommonPlugin['Instance']; 274 286 }) => { 275 - const symbolHttpRequest = plugin.referenceSymbol( 276 - plugin.api.selector('HttpRequest'), 277 - ); 287 + const symbolHttpRequest = plugin.referenceSymbol({ 288 + category: 'external', 289 + resource: '@angular/common/http.HttpRequest', 290 + }); 278 291 279 292 const sdkPlugin = plugin.getPluginOrThrow('@hey-api/sdk'); 280 293 const symbolOptions = plugin.referenceSymbol( ··· 331 344 plugin: AngularCommonPlugin['Instance']; 332 345 symbol: Symbol; 333 346 }) => { 334 - const symbolHttpRequest = plugin.referenceSymbol( 335 - plugin.api.selector('HttpRequest'), 336 - ); 347 + const symbolHttpRequest = plugin.referenceSymbol({ 348 + category: 'external', 349 + resource: '@angular/common/http.HttpRequest', 350 + }); 337 351 338 352 const sdkPlugin = plugin.getPluginOrThrow('@hey-api/sdk'); 339 353 const symbolOptions = plugin.referenceSymbol(
+25 -15
packages/openapi-ts/src/plugins/@angular/common/httpResources.ts
··· 135 135 } 136 136 } 137 137 138 - const symbolInjectable = plugin.referenceSymbol( 139 - plugin.api.selector('Injectable'), 140 - ); 138 + const symbolInjectable = plugin.referenceSymbol({ 139 + category: 'external', 140 + resource: '@angular/core.Injectable', 141 + }); 141 142 const symbolClass = plugin.registerSymbol({ 142 143 exported: true, 143 144 name: buildName({ ··· 209 210 }) => { 210 211 const sdkPlugin = plugin.getPluginOrThrow('@hey-api/sdk'); 211 212 212 - const symbolHttpResource = plugin.referenceSymbol( 213 - plugin.api.selector('httpResource'), 214 - ); 213 + const symbolHttpResource = plugin.referenceSymbol({ 214 + category: 'external', 215 + resource: '@angular/common/http.httpResource', 216 + }); 215 217 216 218 const symbolResponseType = plugin.querySymbol({ 217 219 category: 'type', ··· 233 235 if (firstEntry) { 234 236 // Import the root class from HTTP requests 235 237 const rootClassName = firstEntry.path[0]!; 236 - const symbolClass = plugin.referenceSymbol( 237 - plugin.api.selector('class', rootClassName), 238 - ); 238 + const symbolClass = plugin.referenceSymbol({ 239 + category: 'utility', 240 + resource: 'class', 241 + resourceId: rootClassName, 242 + tool: 'angular', 243 + }); 239 244 240 245 // Build the method access path using inject 241 - const symbolInject = plugin.referenceSymbol( 242 - plugin.api.selector('inject'), 243 - ); 246 + const symbolInject = plugin.referenceSymbol({ 247 + category: 'external', 248 + resource: '@angular/core.inject', 249 + }); 244 250 let methodAccess: ts.Expression = tsc.callExpression({ 245 251 functionName: symbolInject.placeholder, 246 252 parameters: [tsc.identifier({ text: symbolClass.placeholder })], ··· 299 305 }); 300 306 } 301 307 } else { 302 - const symbolHttpRequest = plugin.referenceSymbol( 303 - plugin.api.selector('httpRequest', operation.id), 304 - ); 308 + const symbolHttpRequest = plugin.referenceSymbol({ 309 + category: 'utility', 310 + resource: 'operation', 311 + resourceId: operation.id, 312 + role: 'data', 313 + tool: 'angular', 314 + }); 305 315 306 316 return tsc.callExpression({ 307 317 functionName: symbolHttpResource.placeholder,
+16 -4
packages/openapi-ts/src/plugins/@angular/common/plugin.ts
··· 6 6 plugin.registerSymbol({ 7 7 external: '@angular/common/http', 8 8 kind: 'type', 9 + meta: { 10 + category: 'external', 11 + resource: '@angular/common/http.HttpRequest', 12 + }, 9 13 name: 'HttpRequest', 10 - selector: plugin.api.selector('HttpRequest'), 11 14 }); 12 15 plugin.registerSymbol({ 13 16 external: '@angular/core', 17 + meta: { 18 + category: 'external', 19 + resource: '@angular/core.inject', 20 + }, 14 21 name: 'inject', 15 - selector: plugin.api.selector('inject'), 16 22 }); 17 23 plugin.registerSymbol({ 18 24 external: '@angular/core', 25 + meta: { 26 + category: 'external', 27 + resource: '@angular/core.Injectable', 28 + }, 19 29 name: 'Injectable', 20 - selector: plugin.api.selector('Injectable'), 21 30 }); 22 31 plugin.registerSymbol({ 23 32 external: '@angular/common/http', 33 + meta: { 34 + category: 'external', 35 + resource: '@angular/common/http.httpResource', 36 + }, 24 37 name: 'httpResource', 25 - selector: plugin.api.selector('httpResource'), 26 38 }); 27 39 28 40 if (plugin.config.httpRequests.enabled) {
+2 -23
packages/openapi-ts/src/plugins/@hey-api/schemas/api.ts
··· 1 - import type { Selector } from '@hey-api/codegen-core'; 1 + export type IApi = any; 2 2 3 - import type { Plugin } from '~/plugins'; 4 - 5 - type SelectorType = 'ref'; 6 - 7 - export type IApi = { 8 - /** 9 - * @param type Selector type. 10 - * @param value Depends on `type`: 11 - * - `ref`: `$ref` JSON pointer 12 - * @returns Selector array 13 - * @deprecated 14 - */ 15 - selector: (type: SelectorType, value?: string) => Selector; 16 - }; 17 - 18 - export class Api implements IApi { 19 - constructor(public meta: Plugin.Name<'@hey-api/schemas'>) {} 20 - 21 - selector(...args: ReadonlyArray<string | undefined>): Selector { 22 - return [this.meta.name, ...(args as Selector)]; 23 - } 24 - } 3 + export class Api implements IApi {}
+1 -3
packages/openapi-ts/src/plugins/@hey-api/schemas/config.ts
··· 6 6 import type { HeyApiSchemasPlugin } from './types'; 7 7 8 8 export const defaultConfig: HeyApiSchemasPlugin['Config'] = { 9 - api: new Api({ 10 - name: '@hey-api/schemas', 11 - }), 9 + api: new Api(), 12 10 config: { 13 11 exportFromIndex: false, 14 12 nameBuilder: (name) => `${name}Schema`,
+18 -3
packages/openapi-ts/src/plugins/@hey-api/schemas/plugin.ts
··· 370 370 const schema = context.spec.definitions[name]!; 371 371 const symbol = plugin.registerSymbol({ 372 372 exported: true, 373 + meta: { 374 + category: 'schema', 375 + resource: 'definition', 376 + resourceId: name, 377 + tool: 'json-schema', 378 + }, 373 379 name: schemaName({ name, plugin, schema }), 374 - selector: plugin.api.selector('ref', name), 375 380 }); 376 381 const obj = schemaToJsonSchemaDraft_04({ 377 382 context, ··· 403 408 const schema = context.spec.components.schemas[name]!; 404 409 const symbol = plugin.registerSymbol({ 405 410 exported: true, 411 + meta: { 412 + category: 'schema', 413 + resource: 'definition', 414 + resourceId: name, 415 + tool: 'json-schema', 416 + }, 406 417 name: schemaName({ name, plugin, schema }), 407 - selector: plugin.api.selector('ref', name), 408 418 }); 409 419 const obj = schemaToJsonSchemaDraft_05({ 410 420 context, ··· 436 446 const schema = context.spec.components.schemas[name]!; 437 447 const symbol = plugin.registerSymbol({ 438 448 exported: true, 449 + meta: { 450 + category: 'schema', 451 + resource: 'definition', 452 + resourceId: name, 453 + tool: 'json-schema', 454 + }, 439 455 name: schemaName({ name, plugin, schema }), 440 - selector: plugin.api.selector('ref', name), 441 456 }); 442 457 const obj = schemaToJsonSchema2020_12({ 443 458 context,
-2
packages/openapi-ts/src/plugins/@hey-api/sdk/api.ts
··· 9 9 | 'Composable' 10 10 | 'formDataBodySerializer' 11 11 | 'function' 12 - | 'Injectable' 13 12 | 'Options' 14 13 | 'urlSearchParamsBodySerializer'; 15 14 ··· 23 22 * - `Composable`: never 24 23 * - `formDataBodySerializer`: never 25 24 * - `function`: `operation.id` string 26 - * - `Injectable`: never 27 25 * - `Options`: never 28 26 * - `urlSearchParamsBodySerializer`: never 29 27 * @returns Selector array
+4 -2
packages/openapi-ts/src/plugins/@hey-api/sdk/shared/class.ts
··· 339 339 providedIn: 'root', 340 340 }, 341 341 ], 342 - name: plugin.referenceSymbol(plugin.api.selector('Injectable')) 343 - .placeholder, 342 + name: plugin.referenceSymbol({ 343 + category: 'external', 344 + resource: '@angular/core.Injectable', 345 + }).placeholder, 344 346 } 345 347 : undefined, 346 348 exportClass: symbol.exported,
+10 -7
packages/openapi-ts/src/plugins/@hey-api/sdk/shared/operation.ts
··· 1 + import type { SymbolMeta } from '@hey-api/codegen-core'; 1 2 import type ts from 'typescript'; 2 3 3 4 import { statusCodeToGroup } from '~/ir/operation'; ··· 525 526 }); 526 527 } 527 528 528 - if (plugin.config.transformer === '@hey-api/transformers') { 529 - const pluginTransformers = plugin.getPluginOrThrow( 530 - plugin.config.transformer, 531 - ); 532 - const selector = pluginTransformers.api.selector('response', operation.id); 533 - if (plugin.isSymbolRegistered(selector)) { 534 - const ref = plugin.referenceSymbol(selector); 529 + if (plugin.config.transformer) { 530 + const query: SymbolMeta = { 531 + category: 'transform', 532 + resource: 'operation', 533 + resourceId: operation.id, 534 + role: 'response', 535 + }; 536 + if (plugin.isSymbolRegistered(query)) { 537 + const ref = plugin.referenceSymbol(query); 535 538 requestOptions.push({ 536 539 key: 'responseTransformer', 537 540 value: ref.placeholder,
+4 -1
packages/openapi-ts/src/plugins/@hey-api/sdk/v1/plugin.ts
··· 39 39 if (isAngularClient && plugin.config.asClass) { 40 40 plugin.registerSymbol({ 41 41 external: '@angular/core', 42 + meta: { 43 + category: 'external', 44 + resource: '@angular/core.Injectable', 45 + }, 42 46 name: 'Injectable', 43 - selector: plugin.api.selector('Injectable'), 44 47 }); 45 48 } 46 49
+2 -24
packages/openapi-ts/src/plugins/@hey-api/transformers/api.ts
··· 1 - import type { Selector } from '@hey-api/codegen-core'; 2 - 3 - import type { Plugin } from '~/plugins'; 4 - 5 - type SelectorType = 'response' | 'response-ref'; 6 - 7 - export type IApi = { 8 - /** 9 - * @param type Selector type. 10 - * @param value Depends on `type`: 11 - * - `response`: `operation.id` string 12 - * - `response-ref`: `$ref` JSON pointer 13 - * @returns Selector array 14 - * @deprecated 15 - */ 16 - selector: (type: SelectorType, value?: string) => Selector; 17 - }; 1 + export type IApi = any; 18 2 19 - export class Api implements IApi { 20 - constructor(public meta: Plugin.Name<'@hey-api/transformers'>) {} 21 - 22 - selector(...args: ReadonlyArray<string | undefined>): Selector { 23 - return [this.meta.name, ...(args as Selector)]; 24 - } 25 - } 3 + export class Api implements IApi {}
+1 -3
packages/openapi-ts/src/plugins/@hey-api/transformers/config.ts
··· 7 7 import type { HeyApiTransformersPlugin } from './types'; 8 8 9 9 export const defaultConfig: HeyApiTransformersPlugin['Config'] = { 10 - api: new Api({ 11 - name: '@hey-api/transformers', 12 - }), 10 + api: new Api(), 13 11 config: { 14 12 bigInt: true, 15 13 dates: true,
+16 -6
packages/openapi-ts/src/plugins/@hey-api/transformers/plugin.ts
··· 1 + import type { SymbolMeta } from '@hey-api/codegen-core'; 1 2 import ts from 'typescript'; 2 3 3 4 import { createOperationKey, operationResponsesMap } from '~/ir/operation'; ··· 58 59 schema: IR.SchemaObject; 59 60 }): Array<ts.Expression | ts.Statement> => { 60 61 if (schema.$ref) { 61 - const selector = plugin.api.selector('response-ref', schema.$ref); 62 + const query: SymbolMeta = { 63 + category: 'transform', 64 + resource: 'definition', 65 + resourceId: schema.$ref, 66 + }; 62 67 63 - if (!plugin.getSymbol(selector)) { 68 + if (!plugin.getSymbol(query)) { 64 69 // TODO: remove 65 70 // create each schema response transformer only once 66 71 67 72 // Register symbol early to prevent infinite recursion with self-referential schemas 68 73 const symbol = plugin.registerSymbol({ 74 + meta: query, 69 75 name: buildName({ 70 76 config: { 71 77 case: 'camelCase', ··· 73 79 }, 74 80 name: refToName(schema.$ref), 75 81 }), 76 - selector, 77 82 }); 78 83 79 84 const refSchema = plugin.context.resolveIrRef<IR.SchemaObject>( ··· 103 108 } 104 109 } 105 110 106 - if (plugin.isSymbolRegistered(selector)) { 107 - const ref = plugin.referenceSymbol(selector); 111 + if (plugin.isSymbolRegistered(query)) { 112 + const ref = plugin.referenceSymbol(query); 108 113 const callExpression = tsc.callExpression({ 109 114 functionName: ref.placeholder, 110 115 parameters: [dataExpression], ··· 350 355 if (!nodes.length) return; 351 356 const symbol = plugin.registerSymbol({ 352 357 exported: true, 358 + meta: { 359 + category: 'transform', 360 + resource: 'operation', 361 + resourceId: operation.id, 362 + role: 'response', 363 + }, 353 364 name: buildName({ 354 365 config: { 355 366 case: 'camelCase', ··· 357 368 }, 358 369 name: operation.id, 359 370 }), 360 - selector: plugin.api.selector('response', operation.id), 361 371 }); 362 372 const value = tsc.constVariable({ 363 373 exportConst: symbol.exported,
+2 -32
packages/openapi-ts/src/plugins/@pinia/colada/api.ts
··· 1 - import type { Selector } from '@hey-api/codegen-core'; 2 - 3 - import type { Plugin } from '~/plugins'; 4 - 5 - type SelectorType = 6 - | '_JSONValue' 7 - | 'defineQueryOptions' 8 - | 'serializeQueryKeyValue' 9 - | 'UseMutationOptions' 10 - | 'UseQueryOptions'; 11 - 12 - export type IApi = { 13 - /** 14 - * @param type Selector type. 15 - * @param value Depends on `type`: 16 - * - `_JSONValue`: never 17 - * - `defineQueryOptions`: never 18 - * - `serializeQueryKeyValue`: never 19 - * - `UseMutationOptions`: never 20 - * - `UseQueryOptions`: never 21 - * @returns Selector array 22 - * @deprecated 23 - */ 24 - selector: (type: SelectorType, value?: string) => Selector; 25 - }; 1 + export type IApi = any; 26 2 27 - export class Api implements IApi { 28 - constructor(public meta: Plugin.Name<'@pinia/colada'>) {} 29 - 30 - selector(...args: ReadonlyArray<string | undefined>): Selector { 31 - return [this.meta.name, ...(args as Selector)]; 32 - } 33 - } 3 + export class Api implements IApi {}
+1 -3
packages/openapi-ts/src/plugins/@pinia/colada/config.ts
··· 5 5 import type { PiniaColadaPlugin } from './types'; 6 6 7 7 export const defaultConfig: PiniaColadaPlugin['Config'] = { 8 - api: new Api({ 9 - name: '@pinia/colada', 10 - }), 8 + api: new Api(), 11 9 config: { 12 10 case: 'camelCase', 13 11 comments: true,
+4 -3
packages/openapi-ts/src/plugins/@pinia/colada/mutationOptions.ts
··· 19 19 plugin: PiniaColadaPlugin['Instance']; 20 20 queryFn: string; 21 21 }): void => { 22 - const symbolMutationOptionsType = plugin.referenceSymbol( 23 - plugin.api.selector('UseMutationOptions'), 24 - ); 22 + const symbolMutationOptionsType = plugin.referenceSymbol({ 23 + category: 'external', 24 + resource: `${plugin.name}.UseMutationOptions`, 25 + }); 25 26 26 27 const typeData = useTypeData({ operation, plugin }); 27 28 const typeError = useTypeError({ operation, plugin });
+20 -3
packages/openapi-ts/src/plugins/@pinia/colada/plugin.ts
··· 8 8 export const handler: PiniaColadaPlugin['Handler'] = ({ plugin }) => { 9 9 plugin.registerSymbol({ 10 10 external: plugin.name, 11 + meta: { 12 + category: 'external', 13 + resource: `${plugin.name}.defineQueryOptions`, 14 + }, 15 + name: 'defineQueryOptions', 16 + }); 17 + plugin.registerSymbol({ 18 + external: plugin.name, 11 19 kind: 'type', 20 + meta: { 21 + category: 'external', 22 + resource: `${plugin.name}.UseMutationOptions`, 23 + }, 12 24 name: 'UseMutationOptions', 13 - selector: plugin.api.selector('UseMutationOptions'), 14 25 }); 15 26 plugin.registerSymbol({ 16 27 external: plugin.name, 17 28 kind: 'type', 29 + meta: { 30 + category: 'external', 31 + resource: `${plugin.name}.UseQueryOptions`, 32 + }, 18 33 name: 'UseQueryOptions', 19 - selector: plugin.api.selector('UseQueryOptions'), 20 34 }); 21 35 plugin.registerSymbol({ 22 36 external: plugin.name, 23 37 kind: 'type', 38 + meta: { 39 + category: 'external', 40 + resource: `${plugin.name}._JSONValue`, 41 + }, 24 42 name: '_JSONValue', 25 - selector: plugin.api.selector('_JSONValue'), 26 43 }); 27 44 plugin.registerSymbol({ 28 45 external: 'axios',
+12 -6
packages/openapi-ts/src/plugins/@pinia/colada/queryKey.ts
··· 39 39 resource: 'QueryKey', 40 40 tool: plugin.name, 41 41 }); 42 - const symbolJsonValue = plugin.referenceSymbol( 43 - plugin.api.selector('_JSONValue'), 44 - ); 42 + const symbolJsonValue = plugin.referenceSymbol({ 43 + category: 'external', 44 + resource: `${plugin.name}._JSONValue`, 45 + }); 45 46 46 47 const returnType = tsc.indexedAccessTypeNode({ 47 48 indexType: tsc.literalTypeNode({ ··· 66 67 const clientModule = clientFolderAbsolutePath(plugin.context.config); 67 68 const symbolSerializeQueryValue = plugin.registerSymbol({ 68 69 external: clientModule, 70 + meta: { 71 + category: 'external', 72 + resource: `${clientModule}.serializeQueryKeyValue`, 73 + }, 69 74 name: 'serializeQueryKeyValue', 70 75 }); 71 76 ··· 304 309 }: { 305 310 plugin: PiniaColadaPlugin['Instance']; 306 311 }) => { 307 - const symbolJsonValue = plugin.referenceSymbol( 308 - plugin.api.selector('_JSONValue'), 309 - ); 312 + const symbolJsonValue = plugin.referenceSymbol({ 313 + category: 'external', 314 + resource: `${plugin.name}._JSONValue`, 315 + }); 310 316 311 317 const properties: Array<Property> = [ 312 318 { name: '_id', type: tsc.keywordTypeNode({ keyword: 'string' }) },
+3 -4
packages/openapi-ts/src/plugins/@pinia/colada/queryOptions.ts
··· 171 171 name: operation.id, 172 172 }), 173 173 }); 174 - const symbolDefineQueryOptions = plugin.registerSymbol({ 175 - external: plugin.name, 176 - name: 'defineQueryOptions', 177 - selector: plugin.api.selector('defineQueryOptions'), 174 + const symbolDefineQueryOptions = plugin.referenceSymbol({ 175 + category: 'external', 176 + resource: `${plugin.name}.defineQueryOptions`, 178 177 }); 179 178 const statement = tsc.constVariable({ 180 179 comment: plugin.config.comments