private/apigen/tsgen: Set query params better

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
This commit is contained in:
Moby von Briesen 2023-08-31 18:44:39 -04:00
parent 28d498f91d
commit b4c95a3b28
3 changed files with 32 additions and 13 deletions

View File

@ -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 );

View File

@ -104,7 +104,15 @@ func (f *tsGenFile) createAPIClient(group *EndpointGroup) {
returnStmt += ";"
f.pf("\tpublic async %s(%s): Promise<%s> {", method.RequestName, funcArgs, returnType)
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))
@ -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, "//", "/")

View File

@ -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);
@ -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>);
@ -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);