UNPKG

@typespec/openapi3

Version:

TypeSpec library for emitting OpenAPI 3.0 and OpenAPI 3.1 from the TypeSpec REST protocol binding and converting OpenAPI3 to TypeSpec

75 lines 2.52 kB
import { isGlobalNamespace, isService } from "@typespec/compiler"; import { getOperationId } from "@typespec/openapi"; export class OperationIdResolver { #program; #strategy; #used = new Set(); #cache = new Map(); #separator; constructor(program, options) { this.#program = program; this.#strategy = options.strategy; this.#separator = options.separator ?? "."; } /** * Resolve the OpenAPI operation ID for the given operation using the following logic: * - If `@operationId` was specified use that value * - Otherwise follow the {@link OperationIdStrategy} * * This will deduplicate operation ids */ resolve(operation) { const existing = this.#cache.get(operation); if (existing) return existing; const explicitOperationId = getOperationId(this.#program, operation); if (explicitOperationId) { return explicitOperationId; } let name = this.#resolveInternal(operation); if (name === undefined) return undefined; if (this.#used.has(name)) { name = this.#findNextAvailableName(name); } this.#used.add(name); this.#cache.set(operation, name); return name; } #findNextAvailableName(name) { let count = 1; while (true) { count++; const newName = `${name}_${count}`; if (!this.#used.has(newName)) { return newName; } } } #resolveInternal(operation) { const operationPath = this.#getOperationPath(operation); switch (this.#strategy) { case "parent-container": return operationPath.slice(-2).join(this.#separator); case "fqn": return operationPath.join(this.#separator); case "explicit-only": return undefined; } } #getOperationPath(operation) { const path = [operation.name]; let current = operation.interface ?? operation.namespace; while (current) { if (current === undefined || (current.kind === "Namespace" && (isGlobalNamespace(this.#program, current) || isService(this.#program, current)))) { break; } path.unshift(current.name); current = current.namespace; } return path; } } //# sourceMappingURL=operation-id-resolver.js.map