Skip to content

Commit

Permalink
clientgen: allow specifying RequestInit for ts/js clients
Browse files Browse the repository at this point in the history
  • Loading branch information
PhakornKiong authored and eandre committed May 31, 2023
1 parent 133cc09 commit e82f18b
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 41 deletions.
6 changes: 4 additions & 2 deletions e2e-tests/testdata/echo_client/js/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,7 @@ class BaseClient {
"Content-Type": "application/json",
"User-Agent": "slug-Generated-JS-Client (Encore/devel)",
}
this.requestInit = options.requestInit ?? {}

// Setup what fetch function we'll be using in the base client
if (options.fetcher !== undefined) {
Expand All @@ -581,15 +582,16 @@ class BaseClient {

// callAPI is used by each generated API method to actually make the request
async callAPI(method, path, body, params) {
let { query, ...rest } = params ?? {}
let { query, headers, ...rest } = params ?? {}
const init = {
...this.requestInit,
...rest,
method,
body: body ?? null,
}

// Merge our headers with any predefined headers
init.headers = {...this.headers, ...init.headers}
init.headers = {...this.headers, ...init.headers, ...headers}

// If authorization data generator is present, call it and add the returned data to the request
let authData
Expand Down
18 changes: 12 additions & 6 deletions e2e-tests/testdata/echo_client/ts/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ export interface ClientOptions {
*/
fetcher?: Fetcher

/** Default RequestInit to be used for the client */
requestInit?: Omit<RequestInit, "headers"> & { headers?: Record<string, string> }

/**
* Allows you to set the authentication data to be used for each
* request either by passing in a static object or by passing in
Expand Down Expand Up @@ -763,11 +766,11 @@ function mustBeSet<A>(field: string, value: A | null | undefined): A {
}

// CallParameters is the type of the parameters to a method call, but require headers to be a Record type
type CallParameters = Omit<RequestInit, "method" | "body"> & {
/** Any headers to be sent with the request */
headers?: Record<string, string>;
type CallParameters = Omit<RequestInit, "method" | "body" | "headers"> & {
/** Headers to be sent with the request */
headers?: Record<string, string>

/** Any query parameters to be sent with the request */
/** Query parameters to be sent with the request */
query?: Record<string, string | string[]>
}

Expand All @@ -783,6 +786,7 @@ class BaseClient {
readonly baseURL: string
readonly fetcher: Fetcher
readonly headers: Record<string, string>
readonly requestInit: Omit<RequestInit, "headers"> & { headers?: Record<string, string> }
readonly authGenerator?: AuthDataGenerator

constructor(baseURL: string, options: ClientOptions) {
Expand All @@ -791,6 +795,7 @@ class BaseClient {
"Content-Type": "application/json",
"User-Agent": "slug-Generated-TS-Client (Encore/devel)",
}
this.requestInit = options.requestInit ?? {};

// Setup what fetch function we'll be using in the base client
if (options.fetcher !== undefined) {
Expand All @@ -813,15 +818,16 @@ class BaseClient {

// callAPI is used by each generated API method to actually make the request
public async callAPI(method: string, path: string, body?: BodyInit, params?: CallParameters): Promise<Response> {
let { query, ...rest } = params ?? {}
let { query, headers, ...rest } = params ?? {}
const init = {
...this.requestInit,
...rest,
method,
body: body ?? null,
}

// Merge our headers with any predefined headers
init.headers = {...this.headers, ...init.headers}
init.headers = {...this.headers, ...init.headers, ...headers}

// If authorization data generator is present, call it and add the returned data to the request
let authData: echo.AuthParams | undefined
Expand Down
6 changes: 4 additions & 2 deletions internal/clientgen/javascript.go
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,7 @@ class BaseClient {`)
"Content-Type": "application/json",
"User-Agent": "` + userAgent + `",
}
this.requestInit = options.requestInit ?? {}
// Setup what fetch function we'll be using in the base client
if (options.fetcher !== undefined) {
Expand Down Expand Up @@ -506,15 +507,16 @@ class BaseClient {`)
// callAPI is used by each generated API method to actually make the request
async callAPI(method, path, body, params) {
let { query, ...rest } = params ?? {}
let { query, headers, ...rest } = params ?? {}
const init = {
...this.requestInit,
...rest,
method,
body: body ?? null,
}
// Merge our headers with any predefined headers
init.headers = {...this.headers, ...init.headers}
init.headers = {...this.headers, ...init.headers, ...headers}
`)
w := js.newIdentWriter(2)

Expand Down
6 changes: 4 additions & 2 deletions internal/clientgen/testdata/expected_baseauth_javascript.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class BaseClient {
"Content-Type": "application/json",
"User-Agent": "app-Generated-JS-Client (Encore/devel)",
}
this.requestInit = options.requestInit ?? {}

// Setup what fetch function we'll be using in the base client
if (options.fetcher !== undefined) {
Expand All @@ -128,15 +129,16 @@ class BaseClient {

// callAPI is used by each generated API method to actually make the request
async callAPI(method, path, body, params) {
let { query, ...rest } = params ?? {}
let { query, headers, ...rest } = params ?? {}
const init = {
...this.requestInit,
...rest,
method,
body: body ?? null,
}

// Merge our headers with any predefined headers
init.headers = {...this.headers, ...init.headers}
init.headers = {...this.headers, ...init.headers, ...headers}

// If authorization data generator is present, call it and add the returned data to the request
let authData
Expand Down
18 changes: 12 additions & 6 deletions internal/clientgen/testdata/expected_baseauth_typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ export interface ClientOptions {
*/
fetcher?: Fetcher

/** Default RequestInit to be used for the client */
requestInit?: Omit<RequestInit, "headers"> & { headers?: Record<string, string> }

/**
* Allows you to set the auth token to be used for each request
* either by passing in a static token string or by passing in a function
Expand Down Expand Up @@ -135,11 +138,11 @@ function makeRecord<K extends string | number | symbol, V>(record: Record<K, V |
}

// CallParameters is the type of the parameters to a method call, but require headers to be a Record type
type CallParameters = Omit<RequestInit, "method" | "body"> & {
/** Any headers to be sent with the request */
headers?: Record<string, string>;
type CallParameters = Omit<RequestInit, "method" | "body" | "headers"> & {
/** Headers to be sent with the request */
headers?: Record<string, string>

/** Any query parameters to be sent with the request */
/** Query parameters to be sent with the request */
query?: Record<string, string | string[]>
}

Expand All @@ -155,6 +158,7 @@ class BaseClient {
readonly baseURL: string
readonly fetcher: Fetcher
readonly headers: Record<string, string>
readonly requestInit: Omit<RequestInit, "headers"> & { headers?: Record<string, string> }
readonly authGenerator?: AuthDataGenerator

constructor(baseURL: string, options: ClientOptions) {
Expand All @@ -163,6 +167,7 @@ class BaseClient {
"Content-Type": "application/json",
"User-Agent": "app-Generated-TS-Client (Encore/devel)",
}
this.requestInit = options.requestInit ?? {};

// Setup what fetch function we'll be using in the base client
if (options.fetcher !== undefined) {
Expand All @@ -185,15 +190,16 @@ class BaseClient {

// callAPI is used by each generated API method to actually make the request
public async callAPI(method: string, path: string, body?: BodyInit, params?: CallParameters): Promise<Response> {
let { query, ...rest } = params ?? {}
let { query, headers, ...rest } = params ?? {}
const init = {
...this.requestInit,
...rest,
method,
body: body ?? null,
}

// Merge our headers with any predefined headers
init.headers = {...this.headers, ...init.headers}
init.headers = {...this.headers, ...init.headers, ...headers}

// If authorization data generator is present, call it and add the returned data to the request
let authData: string | undefined
Expand Down
6 changes: 4 additions & 2 deletions internal/clientgen/testdata/expected_javascript.js
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ class BaseClient {
"Content-Type": "application/json",
"User-Agent": "app-Generated-JS-Client (Encore/devel)",
}
this.requestInit = options.requestInit ?? {}

// Setup what fetch function we'll be using in the base client
if (options.fetcher !== undefined) {
Expand All @@ -258,15 +259,16 @@ class BaseClient {

// callAPI is used by each generated API method to actually make the request
async callAPI(method, path, body, params) {
let { query, ...rest } = params ?? {}
let { query, headers, ...rest } = params ?? {}
const init = {
...this.requestInit,
...rest,
method,
body: body ?? null,
}

// Merge our headers with any predefined headers
init.headers = {...this.headers, ...init.headers}
init.headers = {...this.headers, ...init.headers, ...headers}

// If authorization data generator is present, call it and add the returned data to the request
let authData
Expand Down
6 changes: 4 additions & 2 deletions internal/clientgen/testdata/expected_noauth_javascript.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ class BaseClient {
"Content-Type": "application/json",
"User-Agent": "app-Generated-JS-Client (Encore/devel)",
}
this.requestInit = options.requestInit ?? {}

// Setup what fetch function we'll be using in the base client
if (options.fetcher !== undefined) {
Expand All @@ -101,15 +102,16 @@ class BaseClient {

// callAPI is used by each generated API method to actually make the request
async callAPI(method, path, body, params) {
let { query, ...rest } = params ?? {}
let { query, headers, ...rest } = params ?? {}
const init = {
...this.requestInit,
...rest,
method,
body: body ?? null,
}

// Merge our headers with any predefined headers
init.headers = {...this.headers, ...init.headers}
init.headers = {...this.headers, ...init.headers, ...headers}

// Make the actual request
const queryString = query ? '?' + encodeQuery(query) : ''
Expand Down
18 changes: 12 additions & 6 deletions internal/clientgen/testdata/expected_noauth_typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ export interface ClientOptions {
* code on each API request made or response received.
*/
fetcher?: Fetcher

/** Default RequestInit to be used for the client */
requestInit?: Omit<RequestInit, "headers"> & { headers?: Record<string, string> }
}

export namespace svc {
Expand Down Expand Up @@ -103,11 +106,11 @@ function makeRecord<K extends string | number | symbol, V>(record: Record<K, V |
}

// CallParameters is the type of the parameters to a method call, but require headers to be a Record type
type CallParameters = Omit<RequestInit, "method" | "body"> & {
/** Any headers to be sent with the request */
headers?: Record<string, string>;
type CallParameters = Omit<RequestInit, "method" | "body" | "headers"> & {
/** Headers to be sent with the request */
headers?: Record<string, string>

/** Any query parameters to be sent with the request */
/** Query parameters to be sent with the request */
query?: Record<string, string | string[]>
}

Expand All @@ -121,13 +124,15 @@ class BaseClient {
readonly baseURL: string
readonly fetcher: Fetcher
readonly headers: Record<string, string>
readonly requestInit: Omit<RequestInit, "headers"> & { headers?: Record<string, string> }

constructor(baseURL: string, options: ClientOptions) {
this.baseURL = baseURL
this.headers = {
"Content-Type": "application/json",
"User-Agent": "app-Generated-TS-Client (Encore/devel)",
}
this.requestInit = options.requestInit ?? {};

// Setup what fetch function we'll be using in the base client
if (options.fetcher !== undefined) {
Expand All @@ -139,15 +144,16 @@ class BaseClient {

// callAPI is used by each generated API method to actually make the request
public async callAPI(method: string, path: string, body?: BodyInit, params?: CallParameters): Promise<Response> {
let { query, ...rest } = params ?? {}
let { query, headers, ...rest } = params ?? {}
const init = {
...this.requestInit,
...rest,
method,
body: body ?? null,
}

// Merge our headers with any predefined headers
init.headers = {...this.headers, ...init.headers}
init.headers = {...this.headers, ...init.headers, ...headers}

// Make the actual request
const queryString = query ? '?' + encodeQuery(query) : ''
Expand Down
18 changes: 12 additions & 6 deletions internal/clientgen/testdata/expected_typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ export interface ClientOptions {
*/
fetcher?: Fetcher

/** Default RequestInit to be used for the client */
requestInit?: Omit<RequestInit, "headers"> & { headers?: Record<string, string> }

/**
* Allows you to set the authentication data to be used for each
* request either by passing in a static object or by passing in
Expand Down Expand Up @@ -369,11 +372,11 @@ function mustBeSet<A>(field: string, value: A | null | undefined): A {
}

// CallParameters is the type of the parameters to a method call, but require headers to be a Record type
type CallParameters = Omit<RequestInit, "method" | "body"> & {
/** Any headers to be sent with the request */
headers?: Record<string, string>;
type CallParameters = Omit<RequestInit, "method" | "body" | "headers"> & {
/** Headers to be sent with the request */
headers?: Record<string, string>

/** Any query parameters to be sent with the request */
/** Query parameters to be sent with the request */
query?: Record<string, string | string[]>
}

Expand All @@ -389,6 +392,7 @@ class BaseClient {
readonly baseURL: string
readonly fetcher: Fetcher
readonly headers: Record<string, string>
readonly requestInit: Omit<RequestInit, "headers"> & { headers?: Record<string, string> }
readonly authGenerator?: AuthDataGenerator

constructor(baseURL: string, options: ClientOptions) {
Expand All @@ -397,6 +401,7 @@ class BaseClient {
"Content-Type": "application/json",
"User-Agent": "app-Generated-TS-Client (Encore/devel)",
}
this.requestInit = options.requestInit ?? {};

// Setup what fetch function we'll be using in the base client
if (options.fetcher !== undefined) {
Expand All @@ -419,15 +424,16 @@ class BaseClient {

// callAPI is used by each generated API method to actually make the request
public async callAPI(method: string, path: string, body?: BodyInit, params?: CallParameters): Promise<Response> {
let { query, ...rest } = params ?? {}
let { query, headers, ...rest } = params ?? {}
const init = {
...this.requestInit,
...rest,
method,
body: body ?? null,
}

// Merge our headers with any predefined headers
init.headers = {...this.headers, ...init.headers}
init.headers = {...this.headers, ...init.headers, ...headers}

// If authorization data generator is present, call it and add the returned data to the request
let authData: authentication.AuthData | undefined
Expand Down
Loading

0 comments on commit e82f18b

Please sign in to comment.