diff --git a/.changeset/versioned-typecoder-paths.md b/.changeset/versioned-typecoder-paths.md new file mode 100644 index 00000000..92983e75 --- /dev/null +++ b/.changeset/versioned-typecoder-paths.md @@ -0,0 +1,12 @@ +--- +"counterfact": patch +--- + +generator: `ParametersTypeCoder` and `ParameterExportTypeCoder` now emit output under `types//paths/...` + +`ParametersTypeCoder.modulePath()` and `ParameterExportTypeCoder.modulePath()` now insert the version segment between `types/` and the rest of the path when `this.version` is non-empty, matching the convention already used by `SchemaTypeCoder` and `ResponseTypeCoder`: + +- `types/v1/paths/pets.parameters.ts` (versioned) +- `types/paths/pets.parameters.ts` (no version) + +Single-spec (no version) generation produces identical output to before. diff --git a/src/typescript-generator/operation-type-coder.ts b/src/typescript-generator/operation-type-coder.ts index 9decc11c..53342af3 100644 --- a/src/typescript-generator/operation-type-coder.ts +++ b/src/typescript-generator/operation-type-coder.ts @@ -100,8 +100,8 @@ export class OperationTypeCoder extends TypeCoder { } /** - * Generates and exports a named parameter type (e.g. `ListPets_Query`) from - * `modulePath` and returns the exported type name. + * Generates and exports a named parameter type (e.g. `ListPets_Query`) and + * returns the exported type name. * * Returns `"never"` without creating an export when `inlineType` is * `"never"`. @@ -110,14 +110,12 @@ export class OperationTypeCoder extends TypeCoder { * @param parameterKind - `"query"`, `"path"`, `"headers"`, or `"cookie"`. * @param inlineType - The inline TypeScript type string to export. * @param baseName - The base identifier prefix for the exported type name. - * @param modulePath - The repository-relative path of the type file. */ public exportParameterType( script: Script, parameterKind: string, inlineType: string, baseName: string, - modulePath: string, ): string { if (inlineType === "never") { return "never"; @@ -134,7 +132,6 @@ export class OperationTypeCoder extends TypeCoder { inlineType, parameterKind, ); - coder._modulePath = modulePath; return script.export(coder, true); } @@ -229,13 +226,8 @@ export class OperationTypeCoder extends TypeCoder { * * @param script - The script to write imports and parameter-type exports into. * @param baseName - Identifier prefix used for named parameter-type exports. - * @param modulePath - Repository-relative path for parameter-type exports. */ - protected buildDollarArgType( - script: Script, - baseName: string, - modulePath: string, - ): string { + protected buildDollarArgType(script: Script, baseName: string): string { const xType = script.importSharedType("WideOperationArgument"); script.importSharedType("OmitValueWhenNever"); @@ -311,21 +303,18 @@ export class OperationTypeCoder extends TypeCoder { "query", queryType, baseName, - modulePath, ); const pathTypeName = this.exportParameterType( script, "path", pathType, baseName, - modulePath, ); const headersTypeName = this.exportParameterType( script, "headers", headersType, baseName, - modulePath, ); const cookieTypeName = this.exportParameterType( @@ -333,7 +322,6 @@ export class OperationTypeCoder extends TypeCoder { "cookie", cookieType, baseName, - modulePath, ); const versionLiteralType = @@ -385,8 +373,7 @@ export class OperationTypeCoder extends TypeCoder { script.importSharedType("COUNTERFACT_RESPONSE"); const baseName = this.getOperationBaseName(); - const modulePath = this.modulePath(); - const dollarArgType = this.buildDollarArgType(script, baseName, modulePath); + const dollarArgType = this.buildDollarArgType(script, baseName); return `($: ${dollarArgType}) => MaybePromise`; } @@ -469,6 +456,6 @@ export class VersionedArgTypeCoder extends OperationTypeCoder { script.comments = READ_ONLY_COMMENTS; const baseName = this.getOperationBaseName(); - return this.buildDollarArgType(script, baseName, this.modulePath()); + return this.buildDollarArgType(script, baseName); } } diff --git a/src/typescript-generator/parameter-export-type-coder.ts b/src/typescript-generator/parameter-export-type-coder.ts index fedf6dd3..a7c05b7d 100644 --- a/src/typescript-generator/parameter-export-type-coder.ts +++ b/src/typescript-generator/parameter-export-type-coder.ts @@ -1,3 +1,4 @@ +import { pathJoin } from "../util/forward-slash-path.js"; import { TypeCoder } from "./type-coder.js"; import type { Requirement } from "./requirement.js"; @@ -5,7 +6,6 @@ export class ParameterExportTypeCoder extends TypeCoder { public _typeName: string; public _typeCode: string; public _parameterKind: string; - public _modulePath!: string; public constructor( requirement: Requirement, @@ -34,7 +34,16 @@ export class ParameterExportTypeCoder extends TypeCoder { } public override modulePath(): string { - // Use the same module path as the parent operation - return this._modulePath; + const pathString = this.requirement.url + .split("/") + .at(-2)! + .replaceAll("~1", "/"); + + return `${pathJoin( + "types", + this.version, + "paths", + pathString === "/" ? "/index" : pathString, + )}.types.ts`; } } diff --git a/src/typescript-generator/parameters-type-coder.ts b/src/typescript-generator/parameters-type-coder.ts index a8757e19..e1d683b3 100644 --- a/src/typescript-generator/parameters-type-coder.ts +++ b/src/typescript-generator/parameters-type-coder.ts @@ -62,6 +62,6 @@ export class ParametersTypeCoder extends TypeCoder { .at(-2)! .replaceAll("~1", "/"); - return `${pathJoin("parameters", pathString)}.types.ts`; + return `${pathJoin("types", this.version, "paths", pathString)}.parameters.ts`; } } diff --git a/test/typescript-generator/parameter-export-type-coder.test.ts b/test/typescript-generator/parameter-export-type-coder.test.ts new file mode 100644 index 00000000..3745cc90 --- /dev/null +++ b/test/typescript-generator/parameter-export-type-coder.test.ts @@ -0,0 +1,44 @@ +import { describe, expect, it } from "@jest/globals"; + +import { ParameterExportTypeCoder } from "../../src/typescript-generator/parameter-export-type-coder.js"; +import { Requirement } from "../../src/typescript-generator/requirement.js"; + +describe("a ParameterExportTypeCoder", () => { + describe("modulePath", () => { + it("returns types/paths/... path without version", () => { + const coder = new ParameterExportTypeCoder( + new Requirement({}, "/paths/~1pets/get"), + "", + "HTTP_GET_$_Query", + "{ id: string }", + "query", + ); + + expect(coder.modulePath()).toBe("types/paths/pets.types.ts"); + }); + + it("includes the version in the path when version is set", () => { + const coder = new ParameterExportTypeCoder( + new Requirement({}, "/paths/~1pets/get"), + "v1", + "HTTP_GET_$_v1_Query", + "{ id: string }", + "query", + ); + + expect(coder.modulePath()).toBe("types/v1/paths/pets.types.ts"); + }); + + it("omits the version segment from the path when version is empty", () => { + const coder = new ParameterExportTypeCoder( + new Requirement({}, "/paths/~1pets/get"), + "", + "HTTP_GET_$_Query", + "{ id: string }", + "query", + ); + + expect(coder.modulePath()).toBe("types/paths/pets.types.ts"); + }); + }); +}); diff --git a/test/typescript-generator/parameters-type-coder.test.ts b/test/typescript-generator/parameters-type-coder.test.ts index f13fe195..b682fb8c 100644 --- a/test/typescript-generator/parameters-type-coder.test.ts +++ b/test/typescript-generator/parameters-type-coder.test.ts @@ -125,6 +125,24 @@ describe("a ParametersTypeCoder", () => { new Requirement({}, "/components/parameters/foo"), ); - expect(coder.modulePath()).toBe("parameters/parameters.types.ts"); + expect(coder.modulePath()).toBe("types/paths/parameters.parameters.ts"); + }); + + it("includes the version in modulePath when version is set", () => { + const coder = new ParametersTypeCoder( + new Requirement({}, "/components/parameters/foo"), + "v1", + ); + + expect(coder.modulePath()).toBe("types/v1/paths/parameters.parameters.ts"); + }); + + it("omits the version segment from modulePath when version is empty", () => { + const coder = new ParametersTypeCoder( + new Requirement({}, "/components/parameters/foo"), + "", + ); + + expect(coder.modulePath()).toBe("types/paths/parameters.parameters.ts"); }); });