Skip to content

Commit

Permalink
ref(Integration): delegating props quotation to specific cases (#2274)
Browse files Browse the repository at this point in the history
instead of `quoteProp()` helper there should be proper handling of
particular cases

Should be helpful for #2269
  • Loading branch information
RobinTail authored Dec 31, 2024
1 parent 20c5735 commit 2863dda
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 20 deletions.
7 changes: 2 additions & 5 deletions src/integration-helpers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import ts from "typescript";
import { Method } from "./method";
import { addJsDocComment } from "./zts-helpers";
import { addJsDocComment, makePropertyIdentifier } from "./zts-helpers";

export const f = ts.factory;

Expand Down Expand Up @@ -72,7 +71,7 @@ export const makeEmptyInitializingConstructor = (
export const makeInterfaceProp = (name: string | number, value: ts.TypeNode) =>
f.createPropertySignature(
undefined,
typeof name === "number" ? f.createNumericLiteral(name) : name,
makePropertyIdentifier(name),
undefined,
value,
);
Expand Down Expand Up @@ -265,8 +264,6 @@ export const makeObjectKeysReducer = (
],
);

export const quoteProp = (...parts: [Method, string]) =>
`"${parts.join(" ")}"` as `"${Method} ${string}"`;
export const propOf = <T>(name: keyof NoInfer<T>) => name as string;

export const makeTernary = (
Expand Down
30 changes: 19 additions & 11 deletions src/integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import {
parametricIndexNode,
propOf,
protectedReadonlyModifier,
quoteProp,
recordStringAny,
restToken,
makeAnd,
Expand All @@ -43,7 +42,12 @@ import { Routing } from "./routing";
import { OnEndpoint, walkRouting } from "./routing-walker";
import { HandlingRules } from "./schema-walker";
import { zodToTs } from "./zts";
import { ZTSContext, printNode, addJsDocComment } from "./zts-helpers";
import {
ZTSContext,
printNode,
addJsDocComment,
makePropertyIdentifier,
} from "./zts-helpers";
import type Prettier from "prettier";

type IOKind = "input" | "response" | ResponseVariant | "encoded";
Expand Down Expand Up @@ -107,7 +111,7 @@ export class Integration {
protected program: ts.Node[] = [this.someOf];
protected usage: Array<ts.Node | string> = [];
protected registry = new Map<
ReturnType<typeof quoteProp>, // method+path
string, // request (method+path)
Record<IOKind, ts.TypeNode> & {
isJson: boolean;
tags: ReadonlyArray<string>;
Expand Down Expand Up @@ -224,19 +228,22 @@ export class Integration {
const isJson = endpoint
.getResponses("positive")
.some(({ mimeTypes }) => mimeTypes?.includes(contentTypes.json));
const methodPath = quoteProp(method, path);
this.registry.set(methodPath, {
const request = `${method} ${path}`;
const literalIdx = f.createLiteralTypeNode(
f.createStringLiteral(request),
);
this.registry.set(request, {
input: f.createTypeReferenceNode(input.name),
positive: this.makeSomeOf(dictionaries.positive),
negative: this.makeSomeOf(dictionaries.negative),
response: f.createUnionTypeNode([
f.createIndexedAccessTypeNode(
f.createTypeReferenceNode(this.ids.posResponseInterface),
f.createTypeReferenceNode(methodPath),
literalIdx,
),
f.createIndexedAccessTypeNode(
f.createTypeReferenceNode(this.ids.negResponseInterface),
f.createTypeReferenceNode(methodPath),
literalIdx,
),
]),
encoded: f.createIntersectionTypeNode([
Expand Down Expand Up @@ -277,21 +284,22 @@ export class Integration {
// Single walk through the registry for making properties for the next three objects
const jsonEndpoints: ts.PropertyAssignment[] = [];
const endpointTags: ts.PropertyAssignment[] = [];
for (const [propName, { isJson, tags, ...rest }] of this.registry) {
for (const [request, { isJson, tags, ...rest }] of this.registry) {
// "get /v1/user/retrieve": GetV1UserRetrieveInput
for (const face of this.interfaces)
face.props.push(makeInterfaceProp(propName, rest[face.kind]));
face.props.push(makeInterfaceProp(request, rest[face.kind]));
if (variant !== "types") {
const literalIdx = makePropertyIdentifier(request);
if (isJson) {
// "get /v1/user/retrieve": true
jsonEndpoints.push(
f.createPropertyAssignment(propName, f.createTrue()),
f.createPropertyAssignment(literalIdx, f.createTrue()),
);
}
// "get /v1/user/retrieve": ["users"]
endpointTags.push(
f.createPropertyAssignment(
propName,
literalIdx,
f.createArrayLiteralExpression(
tags.map((tag) => f.createStringLiteral(tag)),
),
Expand Down
10 changes: 6 additions & 4 deletions src/zts-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,12 @@ export const printNode = (

const safePropRegex = /^[A-Za-z_$][A-Za-z0-9_$]*$/;

export const makePropertyIdentifier = (name: string) =>
safePropRegex.test(name)
? f.createIdentifier(name)
: f.createStringLiteral(name);
export const makePropertyIdentifier = (name: string | number) =>
typeof name === "number"
? f.createNumericLiteral(name)
: safePropRegex.test(name)
? f.createIdentifier(name)
: f.createStringLiteral(name);

const primitives: ts.KeywordTypeSyntaxKind[] = [
ts.SyntaxKind.AnyKeyword,
Expand Down

0 comments on commit 2863dda

Please sign in to comment.