Skip to content

Commit

Permalink
feat(package): remove default exports, rename package
Browse files Browse the repository at this point in the history
EME-5329

BREAKING CHANGE: rename package and remove default exports

Co-authored-by: Gabor Nemeth <gabor.nemeth@emarsys.com>
  • Loading branch information
2 people authored and ngabor84 committed Sep 2, 2022
1 parent 97a3597 commit 1661269
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 114 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "escher-suiteapi-js",
"description": "Escher Request",
"name": "@emartech/escher-request",
"description": "Requests with Escher authentication",
"scripts": {
"test": "mocha --require ts-node/register ./src/ --recursive",
"lint": "eslint $(find ./src -name \"*.js\" -not -path \"./node_modules/*\")",
Expand Down
62 changes: 31 additions & 31 deletions src/request.spec.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
const SuiteRequest = require('./request');
const { EscherRequest, EscherRequestOption } = require('./request');
const axios = require('axios');
const Escher = require('escher-auth');
const http = require('http');
const https = require('https');

describe('SuiteRequest', function() {
describe('EscherRequest', function() {
const serviceConfig = {
host: 'localhost',
port: 1234,
Expand All @@ -23,37 +23,37 @@ describe('SuiteRequest', function() {

let requestOptions;
let requestStub;
let suiteRequest;
let escherRequest;

beforeEach(function() {
requestOptions = new SuiteRequest.Options(serviceConfig.host, serviceConfig);
requestOptions = new EscherRequestOption(serviceConfig.host, serviceConfig);
requestStub = this.sandbox.stub(axios, 'request').resolves(createDummyResponse());
suiteRequest = SuiteRequest.create('key-id', 'secret', requestOptions);
escherRequest = EscherRequest.create('key-id', 'secret', requestOptions);
});

it('should sign headers of GET request', async () => {
await suiteRequest.get('/path');
await escherRequest.get('/path');

const requestArgument = requestStub.args[0][0];
expect(requestArgument.headers['x-ems-auth']).to.have.string('SignedHeaders=content-type;host;x-ems-date,');
});

it('should sign headers of PATCH request', async () => {
await suiteRequest.patch('/path', { name: 'Almanach' });
await escherRequest.patch('/path', { name: 'Almanach' });

const requestArgument = requestStub.args[0][0];
expect(requestArgument.headers['x-ems-auth']).to.have.string('SignedHeaders=content-type;host;x-ems-date,');
});

it('should sign headers of POST request', async () => {
await suiteRequest.post('/path', { name: 'Almanach' });
await escherRequest.post('/path', { name: 'Almanach' });

const requestArgument = requestStub.args[0][0];
expect(requestArgument.headers['x-ems-auth']).to.have.string('SignedHeaders=content-type;host;x-ems-date,');
});

it('should sign headers of DELETE request', async () => {
await suiteRequest.delete('/path');
await escherRequest.delete('/path');

const requestArgument = requestStub.args[0][0];
expect(requestArgument.headers['x-ems-auth']).to.have.string('SignedHeaders=content-type;host;x-ems-date,');
Expand All @@ -62,21 +62,21 @@ describe('SuiteRequest', function() {
it('should sign headers with non string values', async () => {
requestOptions.setHeader(['x-customer-id', 15]);

await suiteRequest.post('/path', { name: 'Almanach' });
await escherRequest.post('/path', { name: 'Almanach' });

const requestArgument = requestStub.args[0][0];
expect(requestArgument.headers['x-ems-auth']).to.have.string('content-type;host;x-customer-id;x-ems-date,');
});

it('should encode payload when content type is json', async () => {
await suiteRequest.post('/path', { name: 'Almanach' });
await escherRequest.post('/path', { name: 'Almanach' });

const requestArgument = requestStub.args[0][0];
expect(requestArgument.data).to.eql('{"name":"Almanach"}');
});

it('should encode payload when content type is json and method is GET', async () => {
await suiteRequest.get('/path', { name: 'Almanach' });
await escherRequest.get('/path', { name: 'Almanach' });

const requestArgument = requestStub.args[0][0];
expect(requestArgument.data).to.eql('{"name":"Almanach"}');
Expand All @@ -85,7 +85,7 @@ describe('SuiteRequest', function() {
it('should encode payload when content type is utf8 json', async () => {
requestOptions.setHeader(['content-type', 'application/json;charset=utf-8']);

await suiteRequest.post('/path', { name: 'Almanach' });
await escherRequest.post('/path', { name: 'Almanach' });

const requestArgument = requestStub.args[0][0];
expect(requestArgument.data).to.eql('{"name":"Almanach"}');
Expand All @@ -94,7 +94,7 @@ describe('SuiteRequest', function() {
it('should skip encoding of payload when content type is not json', async () => {
requestOptions.setHeader(['content-type', 'text/csv']);

await suiteRequest.post('/path', 'header1;header2');
await escherRequest.post('/path', 'header1;header2');

const requestArgument = requestStub.args[0][0];
expect(requestArgument.data).to.eql('header1;header2');
Expand All @@ -103,15 +103,15 @@ describe('SuiteRequest', function() {
it('signs extra headers too', async () => {
requestOptions.setHeader(['extra-header', 'header-value']);

await suiteRequest.get('/path');
await escherRequest.get('/path');

const requestArgument = requestStub.args[0][0];
expect(requestArgument.headers['x-ems-auth'])
.to.have.string('SignedHeaders=content-type;extra-header;host;x-ems-date,');
});

it('should pass down parameters to request call from request options', async () => {
await suiteRequest.post('/path', { name: 'Almanach' });
await escherRequest.post('/path', { name: 'Almanach' });

const requestArgument = requestStub.args[0][0];

Expand All @@ -128,7 +128,7 @@ describe('SuiteRequest', function() {
const payload = { name: 'Test' };
this.sandbox.spy(Escher.prototype, 'signRequest');

await suiteRequest.patch('/path', payload);
await escherRequest.patch('/path', payload);

expect(Escher.prototype.signRequest.callCount).to.eql(1);
const firstCall = Escher.prototype.signRequest.getCall(0);
Expand All @@ -139,7 +139,7 @@ describe('SuiteRequest', function() {
const payload = { name: 'Test' };
this.sandbox.spy(Escher.prototype, 'signRequest');

await suiteRequest.post('/path', payload);
await escherRequest.post('/path', payload);

expect(Escher.prototype.signRequest.callCount).to.eql(1);
const firstCall = Escher.prototype.signRequest.getCall(0);
Expand All @@ -150,37 +150,37 @@ describe('SuiteRequest', function() {
const payload = { name: 'Test' };
this.sandbox.spy(Escher.prototype, 'signRequest');

await suiteRequest.get('/path', payload);
await escherRequest.get('/path', payload);

expect(Escher.prototype.signRequest.callCount).to.eql(1);
const firstCall = Escher.prototype.signRequest.getCall(0);
expect(firstCall.args[1]).to.eql(JSON.stringify(payload));
});

it('should not create http agents by default', function() {
suiteRequest = SuiteRequest.create('key-id', 'secret', requestOptions);
escherRequest = EscherRequest.create('key-id', 'secret', requestOptions);

expect(suiteRequest.httpAgent).to.be.undefined;
expect(suiteRequest.httpsAgent).to.be.undefined;
expect(escherRequest.httpAgent).to.be.undefined;
expect(escherRequest.httpsAgent).to.be.undefined;
});

it('should create http agents when connection is keep alive', function() {
requestOptions = new SuiteRequest.Options(serviceConfig.host, Object.assign({ keepAlive: true }, serviceConfig));
requestOptions = new EscherRequestOption(serviceConfig.host, Object.assign({ keepAlive: true }, serviceConfig));

suiteRequest = SuiteRequest.create('key-id', 'secret', requestOptions);
escherRequest = EscherRequest.create('key-id', 'secret', requestOptions);

expect(suiteRequest.httpAgent).to.be.an.instanceOf(http.Agent);
expect(suiteRequest.httpsAgent).to.be.an.instanceOf(https.Agent);
expect(escherRequest.httpAgent).to.be.an.instanceOf(http.Agent);
expect(escherRequest.httpsAgent).to.be.an.instanceOf(https.Agent);
});

it('should pass http agents to wrapper', async () => {
requestOptions = new SuiteRequest.Options(serviceConfig.host, Object.assign({ keepAlive: true }, serviceConfig));
suiteRequest = SuiteRequest.create('key-id', 'secret', requestOptions);
requestOptions = new EscherRequestOption(serviceConfig.host, Object.assign({ keepAlive: true }, serviceConfig));
escherRequest = EscherRequest.create('key-id', 'secret', requestOptions);

await suiteRequest.post('/path', { name: 'Almanach' });
await escherRequest.post('/path', { name: 'Almanach' });

const requestArgument = requestStub.args[0][0];
expect(requestArgument.httpAgent).to.eql(suiteRequest.httpAgent);
expect(requestArgument.httpsAgent).to.eql(suiteRequest.httpsAgent);
expect(requestArgument.httpAgent).to.eql(escherRequest.httpAgent);
expect(requestArgument.httpsAgent).to.eql(escherRequest.httpsAgent);
});
});
54 changes: 26 additions & 28 deletions src/request.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import Escher from 'escher-auth';
import { Agent as HttpAgent } from 'http';
import { Agent as HttpsAgent } from 'https';
import { SuiteRequestOption } from './requestOption';
import { RequestWrapper, ExtendedRequestOption } from './wrapper';
import { SuiteRequestError } from './requestError';
import { EscherRequestOption } from './requestOption';
export { EscherRequestOption } from './requestOption';
import { RequestWrapper, ExtendedRequestOption, TransformedResponse } from './wrapper';
export { TransformedResponse } from './wrapper';
import { EscherRequestError } from './requestError';
export { EscherRequestError } from './requestError';
import createLogger from '@emartech/json-logger';
const logger = createLogger('suiterequest');

export class SuiteRequest {
static Options = SuiteRequestOption;
static Error = SuiteRequestError;
export class EscherRequest {
static EscherConstants = {
algoPrefix: 'EMS',
vendorKey: 'EMS',
Expand All @@ -18,19 +19,19 @@ export class SuiteRequest {
dateHeaderName: 'X-Ems-Date'
};
_escher: Escher;
_options: SuiteRequestOption;
_options: EscherRequestOption;
httpAgent?: HttpAgent;
httpsAgent?: HttpsAgent;

static create(accessKeyId: string, apiSecret: string, requestOptions: SuiteRequestOption) {
return new SuiteRequest(accessKeyId, apiSecret, requestOptions);
static create(accessKeyId: string, apiSecret: string, requestOptions: EscherRequestOption) {
return new EscherRequest(accessKeyId, apiSecret, requestOptions);
}

constructor(accessKeyId: string, apiSecret: string, requestOptions: SuiteRequestOption) {
const escherConfig = Object.assign({}, SuiteRequest.EscherConstants, {
constructor(accessKeyId: string, apiSecret: string, requestOptions: EscherRequestOption) {
const escherConfig = Object.assign({}, EscherRequest.EscherConstants, {
accessKeyId: accessKeyId,
apiSecret: apiSecret,
credentialScope: requestOptions.credentialScope || SuiteRequest.EscherConstants.credentialScope
credentialScope: requestOptions.credentialScope || EscherRequest.EscherConstants.credentialScope
});

this._escher = new Escher(escherConfig);
Expand All @@ -42,26 +43,34 @@ export class SuiteRequest {
}
}

get(path: string, data: any) {
get<T = any>(path: string, data: any): Promise<TransformedResponse<T>> {
return this._request('GET', path, data);
}

patch(path: string, data: any) {
patch<T = any>(path: string, data: any): Promise<TransformedResponse<T>> {
return this._request('PATCH', path, data);
}

post(path: string, data: any) {
post<T = any>(path: string, data: any): Promise<TransformedResponse<T>> {
return this._request('POST', path, data);
}

put(path: string, data: any) {
put<T = any>(path: string, data: any): Promise<TransformedResponse<T>> {
return this._request('PUT', path, data);
}

delete(path: string) {
delete<T = any>(path: string): Promise<TransformedResponse<T>> {
return this._request('DELETE', path);
}

setOptions(requestOptions: EscherRequestOption): void {
this._options = requestOptions;
}

getOptions(): EscherRequestOption {
return this._options;
}

_request(method: string, path: string, data?: any) {
const options = this._getOptionsFor(method, path);
const payload = data ? this._getPayload(data) : '';
Expand All @@ -71,14 +80,6 @@ export class SuiteRequest {
return this._getRequestFor(signedOptions, payload).send();
}

setOptions(requestOptions: SuiteRequestOption) {
this._options = requestOptions;
}

getOptions() {
return this._options;
}

_getRequestFor(requestOptions: ExtendedRequestOption, payload: any) {
const protocol = (this._options.secure) ? 'https:' : 'http:';
return new RequestWrapper(requestOptions, protocol, payload);
Expand Down Expand Up @@ -118,6 +119,3 @@ export class SuiteRequest {
return JSON.stringify(data);
}
}

module.exports = SuiteRequest;
export default SuiteRequest;
12 changes: 6 additions & 6 deletions src/requestError.spec.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
const { SuiteRequestError } = require('./requestError');
const { EscherRequestError } = require('./requestError');

describe('SuiteRequestError', function() {
describe('EscherRequestError', function() {
it('should extend base Error class', function() {
const error = new SuiteRequestError();
const error = new EscherRequestError('Unauthorized', 401);

expect(error).to.be.an.instanceOf(Error);
});

it('should store constructor parameters', function() {
const error = new SuiteRequestError('Invalid request', 400, {
const error = new EscherRequestError('Invalid request', 400, {
data: {
replyText: 'Too long',
detailedMessage: 'Line too long'
Expand All @@ -25,7 +25,7 @@ describe('SuiteRequestError', function() {
});

it('should store response as is when no data attribute present', function() {
const error = new SuiteRequestError('Invalid request', 400, {
const error = new EscherRequestError('Invalid request', 400, {
replyText: 'Too long',
detailedMessage: 'Line too long'
});
Expand All @@ -39,7 +39,7 @@ describe('SuiteRequestError', function() {
});

it('should always contain data on error', function() {
const error = new SuiteRequestError('Unauthorized');
const error = new EscherRequestError('Unauthorized', 401);

expect(error.data).to.eql({ replyText: 'Unauthorized' });
});
Expand Down
4 changes: 2 additions & 2 deletions src/requestError.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { AxiosResponse } from 'axios';

export class SuiteRequestError extends Error {
export class EscherRequestError extends Error {
code: number;
originalCode: string | undefined;
data: any;
Expand All @@ -10,7 +10,7 @@ export class SuiteRequestError extends Error {

this.code = code;
this.originalCode = originalCode;
this.name = 'SuiteRequestError';
this.name = 'EscherRequestError';

if (response) {
this.data = (response as AxiosResponse).data || response;
Expand Down
Loading

0 comments on commit 1661269

Please sign in to comment.