Skip to content

Commit 1f46128

Browse files
committed
render types correctly when cookies only
1 parent f9a3547 commit 1f46128

File tree

9 files changed

+164
-48
lines changed

9 files changed

+164
-48
lines changed

parser/encoding/rpc.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,11 @@ func (e *ResponseEncoding) ParameterEncodingMapByName() map[string][]*ParameterE
171171
return toEncodingMultiMap(nameKey, e.HeaderParameters, e.CookieParameters, e.BodyParameters)
172172
}
173173

174+
func (e *ResponseEncoding) HasResponseInBrowser() bool {
175+
// We don't care about cookie parameters, as they are handled by the browser
176+
return len(e.BodyParameters) > 0 || len(e.HeaderParameters) > 0
177+
}
178+
174179
// RequestEncoding expresses how a request should be encoded for an explicit set of HTTPMethods
175180
type RequestEncoding struct {
176181
// The HTTP methods these field configurations can be used for

pkg/clientgen/testdata/tsapp/expected_golang.go

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/clientgen/testdata/tsapp/expected_javascript.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,10 @@ class SvcServiceClient {
4646
constructor(baseClient) {
4747
this.baseClient = baseClient
4848
this.cookieDummy = this.cookieDummy.bind(this)
49+
this.cookiesOnly = this.cookiesOnly.bind(this)
4950
this.dummy = this.dummy.bind(this)
5051
this.imported = this.imported.bind(this)
52+
this.noTypes = this.noTypes.bind(this)
5153
this.onlyPathParams = this.onlyPathParams.bind(this)
5254
this.root = this.root.bind(this)
5355
}
@@ -75,6 +77,12 @@ class SvcServiceClient {
7577
return await resp.json()
7678
}
7779

80+
async cookiesOnly(params) {
81+
// Now make the actual call to the API
82+
const resp = await this.baseClient.callTypedAPI("POST", `/cookies-only`)
83+
return await resp.json()
84+
}
85+
7886
async dummy(params) {
7987
// Convert our params into the objects we need for the request
8088
const headers = makeRecord({
@@ -102,6 +110,10 @@ class SvcServiceClient {
102110
return await resp.json()
103111
}
104112

113+
async noTypes() {
114+
await this.baseClient.callTypedAPI("POST", `/type-less`)
115+
}
116+
105117
async onlyPathParams(pathParam, pathParam2) {
106118
// Now make the actual call to the API
107119
const resp = await this.baseClient.callTypedAPI("POST", `/path/${encodeURIComponent(pathParam)}/${encodeURIComponent(pathParam2)}`)

pkg/clientgen/testdata/tsapp/expected_list_of_union_shared.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,25 @@ export namespace svc {
108108

109109
type PickMethods<Type> = Omit<CallParameters, "method"> & {method?: Type}
110110

111+
// Helper type to omit all fields that are cookies.
111112
type OmitCookie<T> = {
112113
[K in keyof T as T[K] extends CookieWithOptions<any> ? never : K]: T[K];
113114
};
114115

115-
type RequestType<Type extends (...args: any[]) => any> =
116-
Parameters<Type> extends [infer H, ...any[]] ? OmitCookie<H> : void;
116+
// Helper type to check if an object type is empty (has no properties)
117+
type IsEmptyObject<T> = [keyof T] extends [never] ? true : false;
117118

118-
type ResponseType<Type extends (...args: any[]) => any> = OmitCookie<Awaited<ReturnType<Type>>>;
119+
type RequestType<Type extends (...args: any[]) => any> =
120+
Parameters<Type> extends [infer H, ...any[]]
121+
? IsEmptyObject<OmitCookie<H>> extends true
122+
? void
123+
: OmitCookie<H>
124+
: void;
125+
126+
type ResponseType<Type extends (...args: any[]) => any> =
127+
IsEmptyObject<OmitCookie<Awaited<ReturnType<Type>>>> extends true
128+
? void
129+
: OmitCookie<Awaited<ReturnType<Type>>>;
119130

120131
function dateReviver(key: string, value: any): any {
121132
if (

pkg/clientgen/testdata/tsapp/expected_shared.ts

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ export interface ClientOptions {
9696
*/
9797
import {
9898
cookieDummy as api_svc_svc_cookieDummy,
99+
cookiesOnly as api_svc_svc_cookiesOnly,
99100
dummy as api_svc_svc_dummy,
100101
imported as api_svc_svc_imported,
101102
onlyPathParams as api_svc_svc_onlyPathParams,
@@ -110,8 +111,10 @@ export namespace svc {
110111
constructor(baseClient: BaseClient) {
111112
this.baseClient = baseClient
112113
this.cookieDummy = this.cookieDummy.bind(this)
114+
this.cookiesOnly = this.cookiesOnly.bind(this)
113115
this.dummy = this.dummy.bind(this)
114116
this.imported = this.imported.bind(this)
117+
this.noTypes = this.noTypes.bind(this)
115118
this.onlyPathParams = this.onlyPathParams.bind(this)
116119
this.root = this.root.bind(this)
117120
}
@@ -134,9 +137,11 @@ export namespace svc {
134137
foo: params.foo,
135138
}
136139

137-
// Now make the actual call to the API
138-
const resp = await this.baseClient.callTypedAPI(`/cookie-dummy`, {headers, query, method: "POST", body: JSON.stringify(body)})
139-
return JSON.parse(await resp.text(), dateReviver) as ResponseType<typeof api_svc_svc_cookieDummy>
140+
await this.baseClient.callTypedAPI(`/cookie-dummy`, {headers, query, method: "POST", body: JSON.stringify(body)})
141+
}
142+
143+
public async cookiesOnly(params: RequestType<typeof api_svc_svc_cookiesOnly>): Promise<ResponseType<typeof api_svc_svc_cookiesOnly>> {
144+
await this.baseClient.callTypedAPI(`/cookies-only`, {method: "POST", body: undefined})
140145
}
141146

142147
public async dummy(params: RequestType<typeof api_svc_svc_dummy>): Promise<void> {
@@ -166,6 +171,10 @@ export namespace svc {
166171
return JSON.parse(await resp.text(), dateReviver) as ResponseType<typeof api_svc_svc_imported>
167172
}
168173

174+
public async noTypes(): Promise<void> {
175+
await this.baseClient.callTypedAPI(`/type-less`, {method: "POST", body: undefined})
176+
}
177+
169178
public async onlyPathParams(params: { pathParam: string, pathParam2: string }): Promise<ResponseType<typeof api_svc_svc_onlyPathParams>> {
170179
// Now make the actual call to the API
171180
const resp = await this.baseClient.callTypedAPI(`/path/${encodeURIComponent(params.pathParam)}/${encodeURIComponent(params.pathParam2)}`, {method: "POST", body: undefined})
@@ -198,14 +207,25 @@ export namespace svc {
198207

199208
type PickMethods<Type> = Omit<CallParameters, "method"> & {method?: Type}
200209

210+
// Helper type to omit all fields that are cookies.
201211
type OmitCookie<T> = {
202212
[K in keyof T as T[K] extends CookieWithOptions<any> ? never : K]: T[K];
203213
};
204214

205-
type RequestType<Type extends (...args: any[]) => any> =
206-
Parameters<Type> extends [infer H, ...any[]] ? OmitCookie<H> : void;
215+
// Helper type to check if an object type is empty (has no properties)
216+
type IsEmptyObject<T> = [keyof T] extends [never] ? true : false;
207217

208-
type ResponseType<Type extends (...args: any[]) => any> = OmitCookie<Awaited<ReturnType<Type>>>;
218+
type RequestType<Type extends (...args: any[]) => any> =
219+
Parameters<Type> extends [infer H, ...any[]]
220+
? IsEmptyObject<OmitCookie<H>> extends true
221+
? void
222+
: OmitCookie<H>
223+
: void;
224+
225+
type ResponseType<Type extends (...args: any[]) => any> =
226+
IsEmptyObject<OmitCookie<Awaited<ReturnType<Type>>>> extends true
227+
? void
228+
: OmitCookie<Awaited<ReturnType<Type>>>;
209229

210230
function dateReviver(key: string, value: any): any {
211231
if (

pkg/clientgen/testdata/tsapp/expected_stream_shared.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,14 +193,25 @@ export namespace svc {
193193

194194
type PickMethods<Type> = Omit<CallParameters, "method"> & {method?: Type}
195195

196+
// Helper type to omit all fields that are cookies.
196197
type OmitCookie<T> = {
197198
[K in keyof T as T[K] extends CookieWithOptions<any> ? never : K]: T[K];
198199
};
199200

200-
type RequestType<Type extends (...args: any[]) => any> =
201-
Parameters<Type> extends [infer H, ...any[]] ? OmitCookie<H> : void;
201+
// Helper type to check if an object type is empty (has no properties)
202+
type IsEmptyObject<T> = [keyof T] extends [never] ? true : false;
202203

203-
type ResponseType<Type extends (...args: any[]) => any> = OmitCookie<Awaited<ReturnType<Type>>>;
204+
type RequestType<Type extends (...args: any[]) => any> =
205+
Parameters<Type> extends [infer H, ...any[]]
206+
? IsEmptyObject<OmitCookie<H>> extends true
207+
? void
208+
: OmitCookie<H>
209+
: void;
210+
211+
type ResponseType<Type extends (...args: any[]) => any> =
212+
IsEmptyObject<OmitCookie<Awaited<ReturnType<Type>>>> extends true
213+
? void
214+
: OmitCookie<Awaited<ReturnType<Type>>>;
204215

205216
function dateReviver(key: string, value: any): any {
206217
if (

pkg/clientgen/testdata/tsapp/expected_typescript.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,14 +148,15 @@ export namespace svc {
148148
constructor(baseClient: BaseClient) {
149149
this.baseClient = baseClient
150150
this.cookieDummy = this.cookieDummy.bind(this)
151+
this.cookiesOnly = this.cookiesOnly.bind(this)
151152
this.dummy = this.dummy.bind(this)
152153
this.imported = this.imported.bind(this)
154+
this.noTypes = this.noTypes.bind(this)
153155
this.onlyPathParams = this.onlyPathParams.bind(this)
154156
this.root = this.root.bind(this)
155157
}
156158

157-
public async cookieDummy(params: Request): Promise<{
158-
}> {
159+
public async cookieDummy(params: Request): Promise<void> {
159160
// Convert our params into the objects we need for the request
160161
const headers = makeRecord<string, string>({
161162
baz: params.headerBaz,
@@ -173,10 +174,11 @@ export namespace svc {
173174
foo: params.foo,
174175
}
175176

176-
// Now make the actual call to the API
177-
const resp = await this.baseClient.callTypedAPI("POST", `/cookie-dummy`, JSON.stringify(body), {headers, query})
178-
return await resp.json() as {
179-
}
177+
await this.baseClient.callTypedAPI("POST", `/cookie-dummy`, JSON.stringify(body), {headers, query})
178+
}
179+
180+
public async cookiesOnly(params: void): Promise<void> {
181+
await this.baseClient.callTypedAPI("POST", `/cookies-only`)
180182
}
181183

182184
public async dummy(params: Request): Promise<void> {
@@ -206,6 +208,10 @@ export namespace svc {
206208
return await resp.json() as common_stuff.ImportedResponse
207209
}
208210

211+
public async noTypes(): Promise<void> {
212+
await this.baseClient.callTypedAPI("POST", `/type-less`)
213+
}
214+
209215
public async onlyPathParams(pathParam: string, pathParam2: string): Promise<common_stuff.ImportedResponse> {
210216
// Now make the actual call to the API
211217
const resp = await this.baseClient.callTypedAPI("POST", `/path/${encodeURIComponent(pathParam)}/${encodeURIComponent(pathParam2)}`)

pkg/clientgen/testdata/tsapp/input.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,17 @@ export const dummy = api(
4444
);
4545

4646

47+
export const noTypes = api(
48+
{ expose: true, method: "POST", path: "/type-less" },
49+
async () => { },
50+
)
51+
export const cookiesOnly = api(
52+
{ expose: true, method: "POST", path: "/cookies-only" },
53+
async (req: { field: Cookie<'cookie'> }): Promise<{ cookie: Cookie<'cookie'> }> => {
54+
return { cookie: { value: "value" } }
55+
},
56+
)
57+
4758
export const cookieDummy = api(
4859
{ expose: true, method: "POST", path: "/cookie-dummy" },
4960
async (req: Request): Promise<{ cookie: Cookie<'cookie'> }> => { return { cookie: { value: "value" } } },

0 commit comments

Comments
 (0)