Skip to content

Commit

Permalink
enumerate the verbs
Browse files Browse the repository at this point in the history
  • Loading branch information
BBB committed Sep 21, 2023
1 parent 3ed260b commit 5adcbc3
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 112 deletions.
76 changes: 30 additions & 46 deletions packages/builder/src/effect-schema/EffectBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import ts, {
} from "typescript";

import {
HttpVerb,
httpVerbs,
isReferenceObject,
OpenApiObject,
ReferenceObject,
Expand All @@ -28,6 +30,23 @@ type PathResponses = {
responses: ResponsesObject;
};

class DefaultDict<T, Q> extends Map<T, Q> {
defaultFactory: () => Q;
constructor(defaultFactory: () => Q) {
super();
this.defaultFactory = defaultFactory;
}
get(name: T): Q {
if (this.has(name)) {
return super.get(name)!;
} else {
const value = this.defaultFactory();
this.set(name, value);
return value;
}
}
}

class MethodPaths {
constructor(private resolveReference: ReturnType<typeof getReference>) {}

Expand All @@ -37,24 +56,10 @@ class MethodPaths {
private postPaths: Array<PathResponses> = [];
private deletePaths: Array<PathResponses> = [];

public addGetPath(path: PathResponses) {
this.getPaths.push(path);
}

public addPutPath(path: PathResponses) {
this.putPaths.push(path);
}

public addPostPath(path: PathResponses) {
this.postPaths.push(path);
}

public addPatchPath(path: PathResponses) {
this.patchPaths.push(path);
}
private paths = new DefaultDict<HttpVerb, Array<PathResponses>>(() => []);

public addDeletePath(path: PathResponses) {
this.deletePaths.push(path);
public addPath(verb: HttpVerb, path: PathResponses) {
this.paths.set(verb, this.paths.get(verb).concat([path]));
}

schemaObjectToCodec(
Expand Down Expand Up @@ -299,35 +304,14 @@ export class EffectBuilder implements Builder {
const methodPaths = new MethodPaths(getReference(input));

visitPathItemObjects(input)((pathItem) => {
if (pathItem.node.definition.get?.responses) {
methodPaths.addGetPath({
path: pathItem.node.path,
responses: pathItem.node.definition.get.responses,
});
}
if (pathItem.node.definition.put?.responses) {
methodPaths.addPutPath({
path: pathItem.node.path,
responses: pathItem.node.definition.put.responses,
});
}
if (pathItem.node.definition.post?.responses) {
methodPaths.addPostPath({
path: pathItem.node.path,
responses: pathItem.node.definition.post.responses,
});
}
if (pathItem.node.definition.patch?.responses) {
methodPaths.addPatchPath({
path: pathItem.node.path,
responses: pathItem.node.definition.patch.responses,
});
}
if (pathItem.node.definition.delete?.responses) {
methodPaths.addDeletePath({
path: pathItem.node.path,
responses: pathItem.node.definition.delete.responses,
});
for (const verb of httpVerbs) {
const responses = pathItem.node.definition[verb]?.responses;
if (responses) {
methodPaths.addPath(verb, {
path: pathItem.node.path,
responses: responses,
});
}
}
});

Expand Down
43 changes: 1 addition & 42 deletions packages/builder/test/effect-schema/EffectBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,48 +13,7 @@ it("should create a paths dictionary", () => {
`
// typescript
import * as S from "@effect/schema/Schema";
export const paths = {
get: {
"/a": {
responses: S.union(
S.struct({
status: S.literal(200),
contentType: S.literal("application/json"),
body: S.literal(),
}),
),
},
"/b": {
responses: S.union(
S.struct({
status: S.literal(200),
contentType: S.literal("application/json"),
body: S.struct({ foo: S.literal(), bingo: S.optional(S.literal()) }),
}),
),
},
},
post: {
"/a": {
responses: S.union(
S.struct({
status: S.literal(200),
contentType: S.literal("application/json"),
body: S.literal(),
}),
),
},
"/b": {
responses: S.union(
S.struct({
status: S.literal(200),
contentType: S.literal("application/json"),
body: S.struct({ foo: S.literal(), bingo: S.optional(S.literal()) }),
}),
),
},
},
};
export const paths = {};
`,
);
});
Expand Down
2 changes: 2 additions & 0 deletions packages/parser/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export {
export {
PathItemObjectCodec,
PathItemObject,
httpVerbs,
HttpVerb
} from "./parsers/effect-schema/schemas/PathItemObject";
export {
SchemaObjectCodec,
Expand Down
54 changes: 30 additions & 24 deletions packages/parser/src/parsers/effect-schema/schemas/PathItemObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,42 @@ import { ParameterObject, ParameterObjectCodec } from "./ParameterObject";
import { ReferenceObject, ReferenceObjectCodec } from "./ReferenceObject";
import * as S from "@effect/schema/Schema";

export const httpVerbsWithBody = ["put", "post", "patch"] as const;
export const httpVerbs = [
"put",
"post",
"patch",
"get",
"delete",
"options",
"head",
"trace",
] as const;

export type HttpVerb = (typeof httpVerbs)[number];

export type PathItemObject = {
summary?: string;
description?: string;
get?: OperationObject;
put?: OperationObject;
post?: OperationObject;
delete?: OperationObject;
options?: OperationObject;
head?: OperationObject;
patch?: OperationObject;
trace?: OperationObject;
servers?: ReadonlyArray<ServerObject>;
parameters?: ReadonlyArray<ParameterObject | ReferenceObject>;
};
} & Partial<Record<HttpVerb, OperationObject>>;

export const PathItemObjectCodec: S.Schema<any, PathItemObject> = S.lazy(() =>
S.struct({
summary: S.optional(S.string),
description: S.optional(S.string),
get: S.optional(OperationObjectCodec),
put: S.optional(OperationObjectCodec),
post: S.optional(OperationObjectCodec),
delete: S.optional(OperationObjectCodec),
options: S.optional(OperationObjectCodec),
head: S.optional(OperationObjectCodec),
patch: S.optional(OperationObjectCodec),
trace: S.optional(OperationObjectCodec),
servers: S.optional(S.array(ServerObject)),
parameters: S.optional(
S.array(S.union(ParameterObjectCodec, ReferenceObjectCodec)),
S.struct(
httpVerbs.reduce(
(agg, verb) => ({
...agg,
[verb]: S.optional(OperationObjectCodec),
}),
{
summary: S.optional(S.string),
description: S.optional(S.string),
servers: S.optional(S.array(ServerObject)),
parameters: S.optional(
S.array(S.union(ParameterObjectCodec, ReferenceObjectCodec)),
),
},
),
}),
),
);

0 comments on commit 5adcbc3

Please sign in to comment.