Skip to content

Commit

Permalink
private/apigen/tsgen: Set query params better
Browse files Browse the repository at this point in the history
The old way did not properly handle escaping, e.g. if the value of a
query param contained `&` or `=` inside it. By using
url.searchParams.set, we can safely add these types of arguments to the
path.

Change-Id: I62d3883b14f9d5a517e4a3d58f019014b46fd1b4
  • Loading branch information
mobyvb committed Sep 1, 2023
1 parent 28d498f commit b4c95a3
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 13 deletions.
5 changes: 4 additions & 1 deletion private/apigen/example/client-api.gen.ts
Expand Up @@ -20,7 +20,10 @@ export class docsHttpApiV0 {
private readonly ROOT_PATH: string = '/api/v0/docs';

public async (request: , path: string, id: UUID, date: Time): Promise<> {
const path = `${this.ROOT_PATH}/${path}?id=${id}&date=${date}`;
const u = new URL(`${this.ROOT_PATH}/${path}`);
u.searchParams.set('id', id);
u.searchParams.set('date', date);
const path = u.toString();
const response = await this.http.post(path, JSON.stringify(request));
if (response.ok) {
return response.json().then((body) => body as );
Expand Down
19 changes: 10 additions & 9 deletions private/apigen/tsgen.go
Expand Up @@ -104,7 +104,15 @@ func (f *tsGenFile) createAPIClient(group *EndpointGroup) {
returnStmt += ";"

f.pf("\tpublic async %s(%s): Promise<%s> {", method.RequestName, funcArgs, returnType)
f.pf("\t\tconst path = `%s`;", path)
if len(method.QueryParams) > 0 {
f.pf("\t\tconst u = new URL(`%s`);", path)
for _, p := range method.QueryParams {
f.pf("\t\tu.searchParams.set('%s', %s);", p.Name, p.Name)
}
f.pf("\t\tconst path = u.toString();")
} else {
f.pf("\t\tconst path = `%s`;", path)
}

if method.Request != nil {
f.pf("\t\tconst response = await this.http.%s(path, JSON.stringify(request));", strings.ToLower(method.Method))
Expand Down Expand Up @@ -141,15 +149,8 @@ func (f *tsGenFile) getArgsAndPath(method *fullEndpoint) (funcArgs, path string)
path += fmt.Sprintf("/${%s}", p.Name)
}

for i, p := range method.QueryParams {
if i == 0 {
path += "?"
} else {
path += "&"
}

for _, p := range method.QueryParams {
funcArgs += fmt.Sprintf("%s: %s, ", p.Name, TypescriptTypeName(p.Type))
path += fmt.Sprintf("%s=${%s}", p.Name, p.Name)
}

path = strings.ReplaceAll(path, "//", "/")
Expand Down
21 changes: 18 additions & 3 deletions web/satellite/src/api/v0.gen.ts
Expand Up @@ -139,7 +139,12 @@ export class projectsHttpApiV0 {
}

public async getBucketRollup(projectID: UUID, bucket: string, since: Time, before: Time): Promise<BucketUsageRollup> {
const path = `${this.ROOT_PATH}/bucket-rollup?projectID=${projectID}&bucket=${bucket}&since=${since}&before=${before}`;
const u = new URL(`${this.ROOT_PATH}/bucket-rollup`);
u.searchParams.set('projectID', projectID);
u.searchParams.set('bucket', bucket);
u.searchParams.set('since', since);
u.searchParams.set('before', before);
const path = u.toString();
const response = await this.http.get(path);
if (response.ok) {
return response.json().then((body) => body as BucketUsageRollup);
Expand All @@ -149,7 +154,11 @@ export class projectsHttpApiV0 {
}

public async getBucketRollups(projectID: UUID, since: Time, before: Time): Promise<Array<BucketUsageRollup>> {
const path = `${this.ROOT_PATH}/bucket-rollups?projectID=${projectID}&since=${since}&before=${before}`;
const u = new URL(`${this.ROOT_PATH}/bucket-rollups`);
u.searchParams.set('projectID', projectID);
u.searchParams.set('since', since);
u.searchParams.set('before', before);
const path = u.toString();
const response = await this.http.get(path);
if (response.ok) {
return response.json().then((body) => body as Array<BucketUsageRollup>);
Expand All @@ -159,7 +168,13 @@ export class projectsHttpApiV0 {
}

public async getAPIKeys(projectID: UUID, search: string, limit: number, page: number, order: number, orderDirection: number): Promise<APIKeyPage> {
const path = `${this.ROOT_PATH}/apikeys/${projectID}?search=${search}&limit=${limit}&page=${page}&order=${order}&orderDirection=${orderDirection}`;
const u = new URL(`${this.ROOT_PATH}/apikeys/${projectID}`);
u.searchParams.set('search', search);
u.searchParams.set('limit', limit);
u.searchParams.set('page', page);
u.searchParams.set('order', order);
u.searchParams.set('orderDirection', orderDirection);
const path = u.toString();
const response = await this.http.get(path);
if (response.ok) {
return response.json().then((body) => body as APIKeyPage);
Expand Down

0 comments on commit b4c95a3

Please sign in to comment.