diff --git a/RELEASES.md b/RELEASES.md index 907afb0..c8040ed 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,10 +1,13 @@ ## Releases -## 1.0.1 to 1.0.3 -Adds proxy support. +## 1.0.6 +Automatically sends Content-Type and Accept application/json headers for \Json() helper methods if not set in the client or parameters. + +## 1.0.5 +Adds \Json() helper methods for json over http scenarios. ## 1.0.4 Started to add \Json() helper methods. Do not use this release for that. Use >= 1.0.5 since there was an issue with types. -## 1.0.5 -Adds \Json() helper methods for json over http scenarios. +## 1.0.1 to 1.0.3 +Adds proxy support. \ No newline at end of file diff --git a/__tests__/basics.test.ts b/__tests__/basics.test.ts index a260fc4..eb1c3e9 100644 --- a/__tests__/basics.test.ts +++ b/__tests__/basics.test.ts @@ -9,6 +9,7 @@ interface HttpBinData { url: string; data: any; json: any; + headers: any; args?: any } @@ -206,6 +207,8 @@ describe('basics', () => { expect(jsonObj.statusCode).toBe(200); expect(jsonObj.result).toBeDefined(); expect(jsonObj.result.url).toBe('https://httpbin.org/get'); + expect(jsonObj.result.headers["Accept"]).toBe(httpm.MediaTypes.ApplicationJson); + expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(httpm.MediaTypes.ApplicationJson); }); it('getting a non existent json object returns null', async() => { @@ -221,6 +224,9 @@ describe('basics', () => { expect(restRes.result).toBeDefined(); expect(restRes.result.url).toBe('https://httpbin.org/post'); expect(restRes.result.json.name).toBe('foo'); + expect(restRes.result.headers["Accept"]).toBe(httpm.MediaTypes.ApplicationJson); + expect(restRes.result.headers["Content-Type"]).toBe(httpm.MediaTypes.ApplicationJson); + expect(restRes.headers[httpm.Headers.ContentType]).toBe(httpm.MediaTypes.ApplicationJson); }); it('puts a json object', async() => { @@ -230,6 +236,10 @@ describe('basics', () => { expect(restRes.result).toBeDefined(); expect(restRes.result.url).toBe('https://httpbin.org/put'); expect(restRes.result.json.name).toBe('foo'); + + expect(restRes.result.headers["Accept"]).toBe(httpm.MediaTypes.ApplicationJson); + expect(restRes.result.headers["Content-Type"]).toBe(httpm.MediaTypes.ApplicationJson); + expect(restRes.headers[httpm.Headers.ContentType]).toBe(httpm.MediaTypes.ApplicationJson); }); it('patch a json object', async() => { @@ -239,5 +249,8 @@ describe('basics', () => { expect(restRes.result).toBeDefined(); expect(restRes.result.url).toBe('https://httpbin.org/patch'); expect(restRes.result.json.name).toBe('foo'); - }); -}) + expect(restRes.result.headers["Accept"]).toBe(httpm.MediaTypes.ApplicationJson); + expect(restRes.result.headers["Content-Type"]).toBe(httpm.MediaTypes.ApplicationJson); + expect(restRes.headers[httpm.Headers.ContentType]).toBe(httpm.MediaTypes.ApplicationJson); + }); +}); diff --git a/__tests__/headers.test.ts b/__tests__/headers.test.ts new file mode 100644 index 0000000..ca36191 --- /dev/null +++ b/__tests__/headers.test.ts @@ -0,0 +1,79 @@ +import * as httpm from '../_out'; +import * as ifm from '../_out/interfaces' + +describe('headers', () => { + let _http: httpm.HttpClient; + + beforeEach(() => { + _http = new httpm.HttpClient('http-client-tests'); + }); + + it('preserves existing headers on getJson', async() => { + let additionalHeaders = { [httpm.Headers.Accept]: "foo" }; + let jsonObj: ifm.ITypedResponse = await _http.getJson('https://httpbin.org/get', additionalHeaders); + expect(jsonObj.result.headers["Accept"]).toBe("foo"); + expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(httpm.MediaTypes.ApplicationJson); + + let httpWithHeaders = new httpm.HttpClient(); + httpWithHeaders.requestOptions = { + headers: { + [httpm.Headers.Accept]: "baz" + } + }; + jsonObj = await httpWithHeaders.getJson('https://httpbin.org/get'); + expect(jsonObj.result.headers["Accept"]).toBe("baz"); + expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(httpm.MediaTypes.ApplicationJson); + }); + + it('preserves existing headers on postJson', async() => { + let additionalHeaders = { [httpm.Headers.Accept]: "foo" }; + let jsonObj: ifm.ITypedResponse = await _http.postJson('https://httpbin.org/post', {}, additionalHeaders); + expect(jsonObj.result.headers["Accept"]).toBe("foo"); + expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(httpm.MediaTypes.ApplicationJson); + + let httpWithHeaders = new httpm.HttpClient(); + httpWithHeaders.requestOptions = { + headers: { + [httpm.Headers.Accept]: "baz" + } + }; + jsonObj = await httpWithHeaders.postJson('https://httpbin.org/post', {}); + expect(jsonObj.result.headers["Accept"]).toBe("baz"); + expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(httpm.MediaTypes.ApplicationJson); + }); + + it('preserves existing headers on putJson', async() => { + let additionalHeaders = { [httpm.Headers.Accept]: "foo" }; + let jsonObj: ifm.ITypedResponse = await _http.putJson('https://httpbin.org/put', {}, additionalHeaders); + expect(jsonObj.result.headers["Accept"]).toBe("foo"); + expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(httpm.MediaTypes.ApplicationJson); + + let httpWithHeaders = new httpm.HttpClient(); + httpWithHeaders.requestOptions = { + headers: { + [httpm.Headers.Accept]: "baz" + } + }; + jsonObj = await httpWithHeaders.putJson('https://httpbin.org/put', {}); + expect(jsonObj.result.headers["Accept"]).toBe("baz"); + expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(httpm.MediaTypes.ApplicationJson); + }); + + it('preserves existing headers on patchJson', async() => { + let additionalHeaders = { [httpm.Headers.Accept]: "foo" }; + let jsonObj: ifm.ITypedResponse = await _http.patchJson('https://httpbin.org/patch', {}, additionalHeaders); + expect(jsonObj.result.headers["Accept"]).toBe("foo"); + expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(httpm.MediaTypes.ApplicationJson); + + let httpWithHeaders = new httpm.HttpClient(); + httpWithHeaders.requestOptions = { + headers: { + [httpm.Headers.Accept]: "baz" + } + }; + jsonObj = await httpWithHeaders.patchJson('https://httpbin.org/patch', {}); + expect(jsonObj.result.headers["Accept"]).toBe("baz"); + expect(jsonObj.headers[httpm.Headers.ContentType]).toBe(httpm.MediaTypes.ApplicationJson); + }); + +}); diff --git a/index.ts b/index.ts index 8507e02..c21fd44 100644 --- a/index.ts +++ b/index.ts @@ -35,6 +35,15 @@ export enum HttpCodes { GatewayTimeout = 504, } +export enum Headers { + Accept = "accept", + ContentType = "content-type" +} + +export enum MediaTypes { + ApplicationJson = "application/json" +} + /** * Returns the proxy URL, depending upon the supplied url and proxy environment variables. * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com @@ -166,25 +175,32 @@ export class HttpClient { * Gets a typed object from an endpoint * Be aware that not found returns a null. Other errors (4xx, 5xx) reject the promise */ - public async getJson(requestUrl: string, additionalHeaders?: ifm.IHeaders): Promise> { + public async getJson(requestUrl: string, additionalHeaders: ifm.IHeaders = {}): Promise> { + additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson) let res: ifm.IHttpClientResponse = await this.get(requestUrl, additionalHeaders); return this._processResponse(res, this.requestOptions); } - public async postJson(requestUrl: string, obj: any, additionalHeaders?: ifm.IHeaders): Promise> { + public async postJson(requestUrl: string, obj: any, additionalHeaders: ifm.IHeaders = {}): Promise> { let data: string = JSON.stringify(obj, null, 2); + additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson) + additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); let res: ifm.IHttpClientResponse = await this.post(requestUrl, data, additionalHeaders); return this._processResponse(res, this.requestOptions); } - public async putJson(requestUrl: string, obj: any, additionalHeaders?: ifm.IHeaders): Promise> { + public async putJson(requestUrl: string, obj: any, additionalHeaders: ifm.IHeaders = {}): Promise> { let data: string = JSON.stringify(obj, null, 2); + additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson) + additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); let res: ifm.IHttpClientResponse = await this.put(requestUrl, data, additionalHeaders); return this._processResponse(res, this.requestOptions); } - public async patchJson(requestUrl: string, obj: any, additionalHeaders?: ifm.IHeaders): Promise> { + public async patchJson(requestUrl: string, obj: any, additionalHeaders: ifm.IHeaders = {}): Promise> { let data: string = JSON.stringify(obj, null, 2); + additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson) + additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); let res: ifm.IHttpClientResponse = await this.patch(requestUrl, data, additionalHeaders); return this._processResponse(res, this.requestOptions); } @@ -416,6 +432,14 @@ export class HttpClient { return lowercaseKeys(headers || {}); } + private _getExistingOrDefaultHeader(additionalHeaders: ifm.IHeaders, header: string, _default: string) { + let clientHeader: string; + if(this.requestOptions && this.requestOptions.headers) { + clientHeader = this.requestOptions.headers[header]; + } + return additionalHeaders[header] || clientHeader || _default; + } + private _getAgent(parsedUrl: url.Url): http.Agent { let agent; let proxyUrl: url.Url = pm.getProxyUrl(parsedUrl); diff --git a/package-lock.json b/package-lock.json index 710e48a..1631c03 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@actions/http-client", - "version": "1.0.5", + "version": "1.0.6", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index b566366..a34486d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@actions/http-client", - "version": "1.0.5", + "version": "1.0.6", "description": "Actions Http Client", "main": "index.js", "scripts": {