appknit-platform-sdk
Advanced tools
Comparing version 1.0.24-0 to 1.0.24-1
@@ -1,8 +0,6 @@ | ||
import { AxiosRequestConfig, AxiosInstance } from 'axios'; | ||
import { HttpHeaders, StopExecutionStatus, LogLevel, LogEntry } from './types'; | ||
import { HttpHeaders, StopExecutionStatus, LogLevel, LogEntry, HttpRequestOptions, HttpRequestTrace, HttpResponse } from './types'; | ||
export declare class AppknitSDK { | ||
protected authenticationBeforeRequestHook: (request: AxiosRequestConfig) => {}; | ||
protected axios: AxiosInstance; | ||
constructor(axiosInterceptorSetup?: (axios: AxiosInstance) => void); | ||
protected authenticationBeforeRequestHook: (request: HttpRequestOptions) => {}; | ||
protected logs: Array<LogEntry>; | ||
protected traces: Array<HttpRequestTrace>; | ||
protected httpResponse: { | ||
@@ -40,7 +38,8 @@ status: number; | ||
}; | ||
request(options: AxiosRequestConfig): Promise<import("axios").AxiosResponse<any>>; | ||
request(options: HttpRequestOptions): Promise<HttpResponse>; | ||
setHttpResponse(status: number, headers: HttpHeaders, body: string): void; | ||
setStopExecution(status: StopExecutionStatus, comment: string): void; | ||
setAuthenticationBeforeRequestHook(interceptor: (request: AxiosRequestConfig) => {}): void; | ||
setAuthenticationBeforeRequestHook(interceptor: (request: HttpRequestOptions) => {}): void; | ||
getLogs(): LogEntry[]; | ||
getTraces(): HttpRequestTrace[]; | ||
getHttpResponse(): { | ||
@@ -47,0 +46,0 @@ status: number; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.AppknitSDK = void 0; | ||
const axios_1 = require("axios"); | ||
const nodePath = require("path"); | ||
const http = require("http"); | ||
const https = require("https"); | ||
const YAML = require("yaml"); | ||
const XML = require("fast-xml-parser"); | ||
const shortUuid = require("short-uuid"); | ||
const types_1 = require("./types"); | ||
class AppknitSDK { | ||
constructor(axiosInterceptorSetup) { | ||
constructor() { | ||
this.logs = []; | ||
this.traces = []; | ||
this.serialization = { | ||
@@ -66,15 +70,145 @@ json: { | ||
}; | ||
this.axios = axios_1.default.create(); | ||
if (axiosInterceptorSetup) { | ||
axiosInterceptorSetup(this.axios); | ||
} | ||
} | ||
async request(options) { | ||
const config = options; | ||
config.responseType = 'arraybuffer'; | ||
config.headers = Object.assign({}, options.headers); | ||
let maxRedirects = options.maxRedirects; | ||
if (options.body && !(Buffer.isBuffer(options.body) || typeof options.body === "string")) { | ||
throw new types_1.ExecutionError(types_1.GenericErrorCodes.invalidArgument, 'body should be Buffer'); | ||
} | ||
options.headers = options.headers || {}; | ||
options.query = options.query || {}; | ||
if (this.authenticationBeforeRequestHook) { | ||
await this.authenticationBeforeRequestHook(config); | ||
await this.authenticationBeforeRequestHook(options); | ||
} | ||
const response = await this.axios(config); | ||
const internalRequest = (httpRequestOptions, parentRequestId) => { | ||
return new Promise((resolve, reject) => { | ||
let transport, defaultPort; | ||
if (httpRequestOptions.url.protocol === 'https:') { | ||
transport = https; | ||
defaultPort = 443; | ||
} | ||
else if (httpRequestOptions.url.protocol === 'http:') { | ||
transport = http; | ||
defaultPort = 80; | ||
} | ||
else { | ||
throw new types_1.ExecutionError(types_1.GenericErrorCodes.invalidArgument, 'request method could be used to query only http or https requests'); | ||
} | ||
const timings = { | ||
startedAt: new Date(), | ||
startAt: process.hrtime.bigint(), | ||
dnsLookupAt: null, | ||
tcpConnectionAt: null, | ||
tlsHandshakeAt: null, | ||
firstByteAt: null, | ||
endAt: null, | ||
}; | ||
const trace = { | ||
requestId: shortUuid.generate(), | ||
parentRequestId, | ||
request: { | ||
url: httpRequestOptions.url.toString(), | ||
method: httpRequestOptions.method, | ||
headers: Object.assign(Object.assign({}, httpRequestOptions.headers), { 'user-agent': 'Appknit/http-v1' }), | ||
body: httpRequestOptions.body, | ||
}, | ||
response: null, | ||
timings: null, | ||
error: null, | ||
}; | ||
this.traces.push(trace); | ||
const request = transport.request({ | ||
hostname: httpRequestOptions.url.hostname, | ||
port: httpRequestOptions.url.port ? httpRequestOptions.url.port : defaultPort, | ||
method: httpRequestOptions.method, | ||
path: `${httpRequestOptions.url.pathname}?${httpRequestOptions.url.search}`, | ||
headers: Object.assign({}, httpRequestOptions.headers), | ||
}, (res) => { | ||
const responseBody = []; | ||
request.setTimeout(10000); | ||
res.once('readable', () => { | ||
timings.firstByteAt = process.hrtime.bigint(); | ||
}); | ||
res.on('data', (chunk) => responseBody.push(Buffer.from(chunk))); | ||
res.on('end', async () => { | ||
timings.endAt = process.hrtime.bigint(); | ||
trace.timings = new types_1.HttpRequestTimings(timings.startAt, timings.dnsLookupAt, timings.tcpConnectionAt, timings.tlsHandshakeAt, timings.firstByteAt, timings.endAt); | ||
const httpResponse = { | ||
status: res.statusCode, | ||
headers: res.headers, | ||
body: Buffer.concat(responseBody), | ||
}; | ||
trace.response = httpResponse; | ||
if (res.statusCode > 300 && res.statusCode < 400 && res.headers.location) { | ||
if (--maxRedirects < 0) { | ||
trace.error = { code: types_1.GenericErrorCodes.maxRedirectsReached }; | ||
return reject(new types_1.ExecutionError(types_1.GenericErrorCodes.maxRedirectsReached, 'Max redirects reached')); | ||
} | ||
const redirectUrl = new URL(res.headers.location); | ||
let redirectMethod; | ||
let redirectHeaders; | ||
let redirectBody; | ||
if (res.statusCode === 301 || res.statusCode === 302 || res.statusCode === 303) { | ||
redirectMethod = types_1.HttpMethod.get; | ||
redirectBody = null; | ||
} | ||
if (res.statusCode == 307 || res.statusCode === 308) { | ||
redirectMethod = httpRequestOptions.method; | ||
redirectHeaders = httpRequestOptions.headers; | ||
redirectBody = httpRequestOptions.body; | ||
} | ||
try { | ||
const repsonse = await internalRequest({ | ||
url: redirectUrl, | ||
method: redirectMethod, | ||
headers: Object.assign(Object.assign({}, redirectHeaders), { referer: httpRequestOptions.url.toString() }), | ||
body: redirectBody, | ||
}, trace.requestId); | ||
resolve(repsonse); | ||
} | ||
catch (error) { | ||
return reject(error); | ||
} | ||
} | ||
resolve(httpResponse); | ||
}); | ||
}); | ||
request.on('socket', (socket) => { | ||
socket.on('lookup', () => { | ||
timings.dnsLookupAt = process.hrtime.bigint(); | ||
}); | ||
socket.on('connect', () => { | ||
timings.tcpConnectionAt = process.hrtime.bigint(); | ||
}); | ||
socket.on('secureConnect', () => { | ||
timings.tlsHandshakeAt = process.hrtime.bigint(); | ||
}); | ||
socket.on('timeout', () => { | ||
request.destroy(); | ||
trace.error = { code: types_1.GenericErrorCodes.requestTimeout }; | ||
reject(new types_1.ExecutionError(types_1.GenericErrorCodes.requestTimeout, 'Timeout occurred')); | ||
}); | ||
}); | ||
request.on('error', (error) => { | ||
trace.error = { code: types_1.GenericErrorCodes.networkError, details: error }; | ||
reject(error); | ||
}); | ||
if (options.body) { | ||
request.write(options.body); | ||
} | ||
request.end(); | ||
}); | ||
}; | ||
const url = new URL(options.baseURL); | ||
url.pathname = nodePath.join(url.pathname, options.path); | ||
if (options.query) { | ||
for (const queryId of Object.keys(options.query)) { | ||
url.searchParams.append(queryId, options.query[queryId]); | ||
} | ||
} | ||
const response = await internalRequest({ | ||
url, | ||
method: options.method, | ||
headers: options.headers, | ||
body: options.body, | ||
}); | ||
return response; | ||
@@ -101,2 +235,5 @@ } | ||
} | ||
getTraces() { | ||
return this.traces; | ||
} | ||
getHttpResponse() { | ||
@@ -103,0 +240,0 @@ return this.httpResponse; |
{ | ||
"name": "appknit-platform-sdk", | ||
"version": "1.0.24-0", | ||
"version": "1.0.24-1", | ||
"description": "", | ||
"homepage": "https://appknit.io", | ||
"engines": { | ||
"node": ">=10.0.0", | ||
"npm": ">=6.0.0" | ||
}, | ||
"main": "dist/src/index.js", | ||
@@ -26,4 +30,4 @@ "types": "dist/src/index.d.ts", | ||
"dependencies": { | ||
"axios": "^0.19.2", | ||
"fast-xml-parser": "^3.17.4", | ||
"short-uuid": "^3.1.1", | ||
"yaml": "^1.10.0" | ||
@@ -30,0 +34,0 @@ }, |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 2 instances in 1 package
39513
23
614
3
+ Addedshort-uuid@^3.1.1
+ Addedany-base@1.1.0(transitive)
+ Addedshort-uuid@3.1.1(transitive)
+ Addeduuid@3.4.0(transitive)
- Removedaxios@^0.19.2
- Removedaxios@0.19.2(transitive)
- Removedfollow-redirects@1.5.10(transitive)