Skip to content

Commit 75cbb3e

Browse files
authored
feat: add requestBuilder (#1107)
1 parent 7a8023b commit 75cbb3e

File tree

7 files changed

+167
-1
lines changed

7 files changed

+167
-1
lines changed

.changeset/silent-pianos-cheer.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@smithy/core": minor
3+
---
4+
5+
add requestBuilder

packages/core/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"@smithy/middleware-retry": "workspace:^",
2828
"@smithy/middleware-serde": "workspace:^",
2929
"@smithy/protocol-http": "workspace:^",
30+
"@smithy/smithy-client": "workspace:^",
3031
"@smithy/types": "workspace:^",
3132
"tslib": "^2.5.0"
3233
},

packages/core/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ export * from "./middleware-http-signing";
33
export * from "./util-identity-and-auth";
44
export * from "./getSmithyContext";
55
export * from "./normalizeProvider";
6+
export * from "./protocols/requestBuilder";
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { HttpRequest } from "@smithy/protocol-http";
2+
3+
import { requestBuilder } from "./requestBuilder";
4+
5+
describe(requestBuilder.name, () => {
6+
it("can build requests", async () => {
7+
expect(
8+
await requestBuilder(
9+
{
10+
Key: "MyKey",
11+
Bucket: "MyBucket",
12+
},
13+
{
14+
endpoint: async () => {
15+
return {
16+
hostname: "localhost",
17+
protocol: "https",
18+
port: 8080,
19+
path: "/a",
20+
};
21+
},
22+
} as any
23+
)
24+
.bp("/{Key+}")
25+
.p("Bucket", () => "MyBucket", "{Bucket}", false)
26+
.p("Key", () => "MyKey", "{Key+}", false)
27+
.m("PUT")
28+
.h({
29+
"my-header": "my-header-value",
30+
})
31+
.q({
32+
"my-query": "my-query-value",
33+
})
34+
.b("test-body")
35+
.build()
36+
).toEqual(
37+
new HttpRequest({
38+
protocol: "https",
39+
hostname: "localhost",
40+
port: 8080,
41+
method: "PUT",
42+
path: "/a/MyKey",
43+
query: {
44+
"my-query": "my-query-value",
45+
},
46+
headers: {
47+
"my-header": "my-header-value",
48+
},
49+
body: "test-body",
50+
})
51+
);
52+
});
53+
});
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import { HttpRequest } from "@smithy/protocol-http";
2+
import { resolvedPath } from "@smithy/smithy-client";
3+
import type { SerdeContext } from "@smithy/types";
4+
5+
/**
6+
* @internal
7+
* used in code-generated serde.
8+
*/
9+
export function requestBuilder(input: any, context: SerdeContext): RequestBuilder {
10+
return new RequestBuilder(input, context);
11+
}
12+
13+
/**
14+
* @internal
15+
*/
16+
export class RequestBuilder {
17+
private query: Record<string, string> = {};
18+
private method = "";
19+
private headers: Record<string, string> = {};
20+
private path = "";
21+
private body: any = null;
22+
private hostname = "";
23+
24+
private resolvePathStack: Array<(path: string) => void> = [];
25+
26+
public constructor(private input: any, private context: SerdeContext) {}
27+
28+
public async build() {
29+
const { hostname, protocol = "https", port, path: basePath } = await this.context.endpoint();
30+
this.path = basePath;
31+
for (const resolvePath of this.resolvePathStack) {
32+
resolvePath(this.path);
33+
}
34+
return new HttpRequest({
35+
protocol,
36+
hostname: this.hostname || hostname,
37+
port,
38+
method: this.method,
39+
path: this.path,
40+
query: this.query,
41+
body: this.body,
42+
headers: this.headers,
43+
});
44+
}
45+
46+
/**
47+
* Brevity setter for "hostname".
48+
*/
49+
public hn(hostname: string) {
50+
this.hostname = hostname;
51+
return this;
52+
}
53+
54+
/**
55+
* Brevity initial builder for "basepath".
56+
*/
57+
public bp(uriLabel: string) {
58+
this.resolvePathStack.push((basePath: string) => {
59+
this.path = `${basePath?.endsWith("/") ? basePath.slice(0, -1) : basePath || ""}` + uriLabel;
60+
});
61+
return this;
62+
}
63+
64+
/**
65+
* Brevity incremental builder for "path".
66+
*/
67+
public p(memberName: string, labelValueProvider: () => string | undefined, uriLabel: string, isGreedyLabel: boolean) {
68+
this.resolvePathStack.push((path: string) => {
69+
this.path = resolvedPath(path, this.input, memberName, labelValueProvider, uriLabel, isGreedyLabel);
70+
});
71+
return this;
72+
}
73+
74+
/**
75+
* Brevity setter for "headers".
76+
*/
77+
public h(headers: Record<string, string>) {
78+
this.headers = headers;
79+
return this;
80+
}
81+
82+
/**
83+
* Brevity setter for "query".
84+
*/
85+
public q(query: Record<string, string>) {
86+
this.query = query;
87+
return this;
88+
}
89+
90+
/**
91+
* Brevity setter for "body".
92+
*/
93+
public b(body: any) {
94+
this.body = body;
95+
return this;
96+
}
97+
98+
/**
99+
* Brevity setter for "method".
100+
*/
101+
public m(method: string) {
102+
this.method = method;
103+
return this;
104+
}
105+
}

turbo.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"build": {
66
"dependsOn": ["^build"],
77
"inputs": ["src/**/*", "package.json"],
8-
"outputs": ["dist-types", "dist-cjs", "dist-es"]
8+
"outputs": ["dist-types/**", "dist-cjs/**", "dist-es/**"]
99
},
1010
"test": {
1111
"dependsOn": ["build"],

yarn.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1779,6 +1779,7 @@ __metadata:
17791779
"@smithy/middleware-retry": "workspace:^"
17801780
"@smithy/middleware-serde": "workspace:^"
17811781
"@smithy/protocol-http": "workspace:^"
1782+
"@smithy/smithy-client": "workspace:^"
17821783
"@smithy/types": "workspace:^"
17831784
"@tsconfig/recommended": 1.0.1
17841785
concurrently: 7.0.0

0 commit comments

Comments
 (0)