Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .changeset/versioned-typecoder-paths.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
"counterfact": patch
---

generator: `ParametersTypeCoder` and `ParameterExportTypeCoder` now emit output under `types/<version>/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.
23 changes: 5 additions & 18 deletions src/typescript-generator/operation-type-coder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"`.
Expand All @@ -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";
Expand All @@ -134,7 +132,6 @@ export class OperationTypeCoder extends TypeCoder {
inlineType,
parameterKind,
);
coder._modulePath = modulePath;

return script.export(coder, true);
}
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -311,29 +303,25 @@ 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(
script,
"cookie",
cookieType,
baseName,
modulePath,
);

const versionLiteralType =
Expand Down Expand Up @@ -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<COUNTERFACT_RESPONSE>`;
}
Expand Down Expand Up @@ -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);
}
}
15 changes: 12 additions & 3 deletions src/typescript-generator/parameter-export-type-coder.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { pathJoin } from "../util/forward-slash-path.js";
import { TypeCoder } from "./type-coder.js";
import type { Requirement } from "./requirement.js";

export class ParameterExportTypeCoder extends TypeCoder {
public _typeName: string;
public _typeCode: string;
public _parameterKind: string;
public _modulePath!: string;

public constructor(
requirement: Requirement,
Expand Down Expand Up @@ -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`;
}
}
2 changes: 1 addition & 1 deletion src/typescript-generator/parameters-type-coder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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`;
}
}
44 changes: 44 additions & 0 deletions test/typescript-generator/parameter-export-type-coder.test.ts
Original file line number Diff line number Diff line change
@@ -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");
});
});
});
20 changes: 19 additions & 1 deletion test/typescript-generator/parameters-type-coder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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");
});
});
Loading