apollo-datasource-http
Advanced tools
Comparing version 0.2.1 to 0.3.0
@@ -17,4 +17,4 @@ import { DataSource, DataSourceConfig } from 'apollo-datasource'; | ||
context: TContext; | ||
private storageAdapter; | ||
private readonly abortController; | ||
private storageAdapter; | ||
private readonly memoizedResults; | ||
@@ -32,4 +32,5 @@ constructor(options?: HTTPDataSourceOptions | undefined); | ||
protected put<TResult = unknown>(url: string, request?: Request): Promise<Response<TResult>>; | ||
private performRequest; | ||
private request; | ||
} | ||
//# sourceMappingURL=http-data-source.d.ts.map |
@@ -37,3 +37,3 @@ "use strict"; | ||
async get(key) { | ||
return cache.get(key); | ||
return await cache.get(key); | ||
}, | ||
@@ -51,6 +51,6 @@ clear() { | ||
async set(key, value, ttl) { | ||
return cache.set(key, value, { | ||
ttl | ||
return await cache.set(key, value, { | ||
ttl, | ||
}); | ||
} | ||
}, | ||
}; | ||
@@ -63,3 +63,3 @@ } | ||
this.memoizedResults = new quick_lru_1.default({ | ||
maxSize: this.options?.lru?.maxSize ? this.options.lru.maxSize : 100 | ||
maxSize: this.options?.lru?.maxSize ? this.options.lru.maxSize : 100, | ||
}); | ||
@@ -71,3 +71,3 @@ this.abortController = new abort_controller_1.default(); | ||
this.storageAdapter = new keyv_1.default({ | ||
store: apolloKeyValueCacheToKeyv(config.cache) | ||
store: apolloKeyValueCacheToKeyv(config.cache), | ||
}); | ||
@@ -88,43 +88,27 @@ } | ||
async get(url, request) { | ||
return this.request(url, { | ||
return await this.request(url, { | ||
method: 'GET', | ||
...request | ||
...request, | ||
}); | ||
} | ||
async post(url, request) { | ||
return this.request(url, { | ||
return await this.request(url, { | ||
method: 'POST', | ||
...request | ||
...request, | ||
}); | ||
} | ||
async delete(url, request) { | ||
return this.request(url, { | ||
return await this.request(url, { | ||
method: 'DELETE', | ||
...request | ||
...request, | ||
}); | ||
} | ||
async put(url, request) { | ||
return this.request(url, { | ||
return await this.request(url, { | ||
method: 'PUT', | ||
...request | ||
...request, | ||
}); | ||
} | ||
async request(path, request) { | ||
const options = got_1.default.mergeOptions({ | ||
cache: this.storageAdapter, | ||
path, | ||
responseType: 'json', | ||
timeout: 5000, | ||
agent: HTTPDataSource.agents, | ||
prefixUrl: this.baseURL | ||
}, { | ||
...this.options?.request | ||
}, request); | ||
const cacheKey = this.cacheKey(options); | ||
if (options.method === 'GET') { | ||
const response = this.memoizedResults.get(cacheKey); | ||
if (response) | ||
return response; | ||
} | ||
if (this.willSendRequest) { | ||
async performRequest(options) { | ||
if (this.willSendRequest != null) { | ||
await this.willSendRequest(options); | ||
@@ -139,3 +123,2 @@ } | ||
const response = await cancelableRequest; | ||
this.memoizedResults.set(cacheKey, response); | ||
return this.didReceiveResponse(response, options); | ||
@@ -163,2 +146,24 @@ } | ||
} | ||
async request(path, request) { | ||
const options = got_1.default.mergeOptions({ | ||
cache: this.storageAdapter, | ||
path, | ||
responseType: 'json', | ||
timeout: 5000, | ||
agent: HTTPDataSource.agents, | ||
prefixUrl: this.baseURL, | ||
}, { | ||
...this.options?.request, | ||
}, request); | ||
const cacheKey = this.cacheKey(options); | ||
if (options.method === 'GET') { | ||
const cachedResponse = this.memoizedResults.get(cacheKey); | ||
if (cachedResponse) | ||
return cachedResponse; | ||
const response = await this.performRequest(options); | ||
this.memoizedResults.set(cacheKey, response); | ||
return response; | ||
} | ||
return this.performRequest(options); | ||
} | ||
} | ||
@@ -169,9 +174,9 @@ exports.HTTPDataSource = HTTPDataSource; | ||
keepAlive: true, | ||
scheduling: 'lifo' | ||
scheduling: 'lifo', | ||
}), | ||
https: new HttpsAgent({ | ||
keepAlive: true, | ||
scheduling: 'lifo' | ||
}) | ||
scheduling: 'lifo', | ||
}), | ||
}; | ||
//# sourceMappingURL=http-data-source.js.map |
export { HTTPDataSource, Request } from './http-data-source'; | ||
export { Response, CacheError, CancelError, MaxRedirectsError, ReadError, ParseError, UploadError, TimeoutError, RequestError, UnsupportedProtocolError } from 'got'; | ||
export { Response, CacheError, CancelError, MaxRedirectsError, ReadError, ParseError, UploadError, TimeoutError, RequestError, UnsupportedProtocolError, } from 'got'; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -1,25 +0,28 @@ | ||
import { DataSource, DataSourceConfig } from 'apollo-datasource'; | ||
import { NormalizedOptions, OptionsOfJSONResponseBody, Response } from 'got'; | ||
import AbortController from 'abort-controller'; | ||
export declare type Request = OptionsOfJSONResponseBody | NormalizedOptions; | ||
import { DataSource, DataSourceConfig } from 'apollo-datasource' | ||
import { NormalizedOptions, OptionsOfJSONResponseBody, Response } from 'got' | ||
import AbortController from 'abort-controller' | ||
export declare type Request = OptionsOfJSONResponseBody | NormalizedOptions | ||
export declare abstract class RESTDataSource<TContext = any> extends DataSource { | ||
private readonly globalRequestOptions?; | ||
baseURL?: string; | ||
context: TContext; | ||
abortController: AbortController; | ||
private storageAdapter; | ||
private readonly memoizedResults; | ||
private readonly agents; | ||
constructor(globalRequestOptions?: OptionsOfJSONResponseBody | undefined); | ||
initialize(config: DataSourceConfig<TContext>): void; | ||
protected didReceiveResponse<TResult = unknown>(response: Response<TResult>, _request: Request): Promise<Response<TResult>>; | ||
protected cacheKey(request: Request): string; | ||
protected willSendRequest?(request?: Request): Promise<void>; | ||
protected didEncounterError(_error: Error): void; | ||
protected get<TResult = unknown>(url: string, request?: Request): Promise<Response<TResult>>; | ||
protected post<TResult = unknown>(url: string, request?: Request): Promise<Response<TResult>>; | ||
protected delete<TResult = unknown>(url: string, request?: Request): Promise<Response<TResult>>; | ||
protected put<TResult = unknown>(url: string, request?: Request): Promise<Response<TResult>>; | ||
private request; | ||
private readonly globalRequestOptions? | ||
baseURL?: string | ||
context: TContext | ||
abortController: AbortController | ||
private storageAdapter | ||
private readonly memoizedResults | ||
private readonly agents | ||
constructor(globalRequestOptions?: OptionsOfJSONResponseBody | undefined) | ||
initialize(config: DataSourceConfig<TContext>): void | ||
protected didReceiveResponse<TResult = unknown>( | ||
response: Response<TResult>, | ||
_request: Request, | ||
): Promise<Response<TResult>> | ||
protected cacheKey(request: Request): string | ||
protected willSendRequest?(request?: Request): Promise<void> | ||
protected didEncounterError(_error: Error): void | ||
protected get<TResult = unknown>(url: string, request?: Request): Promise<Response<TResult>> | ||
protected post<TResult = unknown>(url: string, request?: Request): Promise<Response<TResult>> | ||
protected delete<TResult = unknown>(url: string, request?: Request): Promise<Response<TResult>> | ||
protected put<TResult = unknown>(url: string, request?: Request): Promise<Response<TResult>> | ||
private request | ||
} | ||
//# sourceMappingURL=rest-data-source.d.ts.map | ||
//# sourceMappingURL=rest-data-source.d.ts.map |
@@ -1,161 +0,180 @@ | ||
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.RESTDataSource = void 0; | ||
const apollo_datasource_1 = require("apollo-datasource"); | ||
const got_1 = __importStar(require("got")); | ||
const quick_lru_1 = __importDefault(require("@alloc/quick-lru")); | ||
const abort_controller_1 = __importDefault(require("abort-controller")); | ||
const agentkeepalive_1 = __importDefault(require("agentkeepalive")); | ||
const apollo_server_errors_1 = require("apollo-server-errors"); | ||
const keyv_1 = __importDefault(require("keyv")); | ||
const { HttpsAgent } = agentkeepalive_1.default; | ||
'use strict' | ||
var __createBinding = | ||
(this && this.__createBinding) || | ||
(Object.create | ||
? function (o, m, k, k2) { | ||
if (k2 === undefined) k2 = k | ||
Object.defineProperty(o, k2, { | ||
enumerable: true, | ||
get: function () { | ||
return m[k] | ||
}, | ||
}) | ||
} | ||
: function (o, m, k, k2) { | ||
if (k2 === undefined) k2 = k | ||
o[k2] = m[k] | ||
}) | ||
var __setModuleDefault = | ||
(this && this.__setModuleDefault) || | ||
(Object.create | ||
? function (o, v) { | ||
Object.defineProperty(o, 'default', { enumerable: true, value: v }) | ||
} | ||
: function (o, v) { | ||
o['default'] = v | ||
}) | ||
var __importStar = | ||
(this && this.__importStar) || | ||
function (mod) { | ||
if (mod && mod.__esModule) return mod | ||
var result = {} | ||
if (mod != null) | ||
for (var k in mod) | ||
if (k !== 'default' && Object.prototype.hasOwnProperty.call(mod, k)) | ||
__createBinding(result, mod, k) | ||
__setModuleDefault(result, mod) | ||
return result | ||
} | ||
var __importDefault = | ||
(this && this.__importDefault) || | ||
function (mod) { | ||
return mod && mod.__esModule ? mod : { default: mod } | ||
} | ||
Object.defineProperty(exports, '__esModule', { value: true }) | ||
exports.RESTDataSource = void 0 | ||
const apollo_datasource_1 = require('apollo-datasource') | ||
const got_1 = __importStar(require('got')) | ||
const quick_lru_1 = __importDefault(require('@alloc/quick-lru')) | ||
const abort_controller_1 = __importDefault(require('abort-controller')) | ||
const agentkeepalive_1 = __importDefault(require('agentkeepalive')) | ||
const apollo_server_errors_1 = require('apollo-server-errors') | ||
const keyv_1 = __importDefault(require('keyv')) | ||
const { HttpsAgent } = agentkeepalive_1.default | ||
function apolloKeyValueCacheToKeyv(cache) { | ||
return { | ||
async get(key) { | ||
return cache.get(key); | ||
}, | ||
clear() { }, | ||
async delete(key) { | ||
const result = await cache.delete(key); | ||
if (result === false) { | ||
return false; | ||
} | ||
return true; | ||
}, | ||
async set(key, value, ttl) { | ||
return cache.set(key, value, { | ||
ttl | ||
}); | ||
} | ||
}; | ||
return { | ||
async get(key) { | ||
return cache.get(key) | ||
}, | ||
clear() {}, | ||
async delete(key) { | ||
const result = await cache.delete(key) | ||
if (result === false) { | ||
return false | ||
} | ||
return true | ||
}, | ||
async set(key, value, ttl) { | ||
return cache.set(key, value, { | ||
ttl, | ||
}) | ||
}, | ||
} | ||
} | ||
class RESTDataSource extends apollo_datasource_1.DataSource { | ||
constructor(globalRequestOptions) { | ||
super(); | ||
this.globalRequestOptions = globalRequestOptions; | ||
this.memoizedResults = new quick_lru_1.default({ | ||
maxSize: 100, | ||
maxAge: 10000 | ||
}); | ||
this.abortController = new abort_controller_1.default(); | ||
this.agents = { | ||
http: new agentkeepalive_1.default({ | ||
keepAlive: true, | ||
scheduling: 'lifo' | ||
}), | ||
https: new HttpsAgent({ | ||
keepAlive: true, | ||
scheduling: 'lifo' | ||
}) | ||
}; | ||
constructor(globalRequestOptions) { | ||
super() | ||
this.globalRequestOptions = globalRequestOptions | ||
this.memoizedResults = new quick_lru_1.default({ | ||
maxSize: 100, | ||
maxAge: 10000, | ||
}) | ||
this.abortController = new abort_controller_1.default() | ||
this.agents = { | ||
http: new agentkeepalive_1.default({ | ||
keepAlive: true, | ||
scheduling: 'lifo', | ||
}), | ||
https: new HttpsAgent({ | ||
keepAlive: true, | ||
scheduling: 'lifo', | ||
}), | ||
} | ||
initialize(config) { | ||
this.context = config.context; | ||
this.storageAdapter = new keyv_1.default({ | ||
store: apolloKeyValueCacheToKeyv(config.cache) | ||
}); | ||
} | ||
initialize(config) { | ||
this.context = config.context | ||
this.storageAdapter = new keyv_1.default({ | ||
store: apolloKeyValueCacheToKeyv(config.cache), | ||
}) | ||
} | ||
async didReceiveResponse(response, _request) { | ||
return response | ||
} | ||
cacheKey(request) { | ||
if (request.url) return request.url.toString() | ||
throw new Error('No Cache key provided') | ||
} | ||
didEncounterError(_error) {} | ||
async get(url, request) { | ||
return this.request(url, { | ||
method: 'GET', | ||
...request, | ||
}) | ||
} | ||
async post(url, request) { | ||
return this.request(url, { | ||
method: 'POST', | ||
...request, | ||
}) | ||
} | ||
async delete(url, request) { | ||
return this.request(url, { | ||
method: 'DELETE', | ||
...request, | ||
}) | ||
} | ||
async put(url, request) { | ||
return this.request(url, { | ||
method: 'PUT', | ||
...request, | ||
}) | ||
} | ||
async request(path, request) { | ||
const options = got_1.default.mergeOptions( | ||
{ | ||
cache: this.storageAdapter, | ||
path, | ||
responseType: 'json', | ||
timeout: 5000, | ||
agent: this.agents, | ||
prefixUrl: this.baseURL, | ||
}, | ||
{ | ||
...this.globalRequestOptions, | ||
}, | ||
request, | ||
) | ||
const cacheKey = this.cacheKey(options) | ||
if (options.method === 'GET') { | ||
const response = this.memoizedResults.get(cacheKey) | ||
if (response) return response | ||
} | ||
async didReceiveResponse(response, _request) { | ||
return response; | ||
if (this.willSendRequest) { | ||
await this.willSendRequest(options) | ||
} | ||
cacheKey(request) { | ||
if (request.url) | ||
return request.url.toString(); | ||
throw new Error('No Cache key provided'); | ||
} | ||
didEncounterError(_error) { } | ||
async get(url, request) { | ||
return this.request(url, { | ||
method: 'GET', | ||
...request | ||
}); | ||
} | ||
async post(url, request) { | ||
return this.request(url, { | ||
method: 'POST', | ||
...request | ||
}); | ||
} | ||
async delete(url, request) { | ||
return this.request(url, { | ||
method: 'DELETE', | ||
...request | ||
}); | ||
} | ||
async put(url, request) { | ||
return this.request(url, { | ||
method: 'PUT', | ||
...request | ||
}); | ||
} | ||
async request(path, request) { | ||
const options = got_1.default.mergeOptions({ | ||
cache: this.storageAdapter, | ||
path, | ||
responseType: 'json', | ||
timeout: 5000, | ||
agent: this.agents, | ||
prefixUrl: this.baseURL | ||
}, { | ||
...this.globalRequestOptions | ||
}, request); | ||
const cacheKey = this.cacheKey(options); | ||
if (options.method === 'GET') { | ||
const response = this.memoizedResults.get(cacheKey); | ||
if (response) | ||
return response; | ||
const cancelableRequest = got_1.default(options) | ||
this.abortController.signal.addEventListener('abort', () => { | ||
cancelableRequest.cancel('abortController') | ||
}) | ||
try { | ||
const response = await cancelableRequest | ||
this.memoizedResults.set(cacheKey, response) | ||
return this.didReceiveResponse(response, options) | ||
} catch (error) { | ||
let error_ = error | ||
this.didEncounterError(error) | ||
if (error instanceof got_1.HTTPError) { | ||
if (error.response.statusCode === 401) { | ||
error_ = new apollo_server_errors_1.AuthenticationError(error.message) | ||
} else if (error.response.statusCode === 403) { | ||
error_ = new apollo_server_errors_1.ForbiddenError(error.message) | ||
} else { | ||
error_ = new apollo_server_errors_1.ApolloError(error.message) | ||
} | ||
if (this.willSendRequest) { | ||
await this.willSendRequest(options); | ||
} | ||
const cancelableRequest = got_1.default(options); | ||
this.abortController.signal.addEventListener('abort', () => { | ||
cancelableRequest.cancel('abortController'); | ||
}); | ||
try { | ||
const response = await cancelableRequest; | ||
this.memoizedResults.set(cacheKey, response); | ||
return this.didReceiveResponse(response, options); | ||
} | ||
catch (error) { | ||
let error_ = error; | ||
this.didEncounterError(error); | ||
if (error instanceof got_1.HTTPError) { | ||
if (error.response.statusCode === 401) { | ||
error_ = new apollo_server_errors_1.AuthenticationError(error.message); | ||
} | ||
else if (error.response.statusCode === 403) { | ||
error_ = new apollo_server_errors_1.ForbiddenError(error.message); | ||
} | ||
else { | ||
error_ = new apollo_server_errors_1.ApolloError(error.message); | ||
} | ||
} | ||
throw error_; | ||
} | ||
} | ||
throw error_ | ||
} | ||
} | ||
} | ||
exports.RESTDataSource = RESTDataSource; | ||
//# sourceMappingURL=rest-data-source.js.map | ||
exports.RESTDataSource = RESTDataSource | ||
//# sourceMappingURL=rest-data-source.js.map |
{ | ||
"name": "apollo-datasource-http", | ||
"version": "0.2.1", | ||
"version": "0.3.0", | ||
"author": "Dustin Deus <deusdustin@gmail.com>", | ||
@@ -16,6 +16,6 @@ "license": "MIT", | ||
"build": "tsc", | ||
"lint": "xo", | ||
"lint:fix": "xo --fix", | ||
"format": "prettier --write '**/*.{js,ts,json,md}'", | ||
"cov": "nyc --reporter=lcov --reporter=text-summary -- npm run test", | ||
"test": "ava", | ||
"bench": "npm run build && node benchmarks", | ||
"prepare": "npm run build", | ||
@@ -41,22 +41,2 @@ "release": "release-it --github.release" | ||
"sideEffects": false, | ||
"xo": { | ||
"prettier": true, | ||
"rules": { | ||
"@typescript-eslint/no-empty-function": "off", | ||
"promise/prefer-await-to-then": "off", | ||
"node/no-deprecated-api": "off", | ||
"node/prefer-global/url": "off", | ||
"node/prefer-global/url-search-params": "off", | ||
"@typescript-eslint/no-implicit-any-catch": "off", | ||
"unicorn/prefer-node-protocol": "off", | ||
"ava/assertion-arguments": "off", | ||
"@typescript-eslint/no-unsafe-member-access": "off", | ||
"@typescript-eslint/no-unsafe-return": "off", | ||
"@typescript-eslint/no-unsafe-assignment": "off", | ||
"@typescript-eslint/no-unsafe-call": "off", | ||
"@typescript-eslint/no-unsafe-argument": "off", | ||
"@typescript-eslint/no-non-null-assertion": "off", | ||
"import/order": "off" | ||
} | ||
}, | ||
"ava": { | ||
@@ -86,11 +66,12 @@ "files": [ | ||
"devDependencies": { | ||
"release-it": "^14.8.0", | ||
"apollo-datasource-rest": "^0.14.0", | ||
"ava": "^3.15.0", | ||
"nock": "^13.1.0", | ||
"nyc": "^15.1.0", | ||
"prettier": "^2.3.1", | ||
"release-it": "^14.8.0", | ||
"ts-node": "^10.0.0", | ||
"uid": "^2.0.0", | ||
"typescript": "^4.3.2", | ||
"xo": "^0.40.2" | ||
"uid": "^2.0.0" | ||
} | ||
} |
@@ -40,5 +40,5 @@ # Apollo HTTP Data Source | ||
moviesAPI: new MoviesAPI(), | ||
}; | ||
} | ||
}, | ||
}); | ||
}) | ||
``` | ||
@@ -45,0 +45,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
431
33151
9