New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@bss-sbc/shopify-api-fetcher

Package Overview
Dependencies
Maintainers
3
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@bss-sbc/shopify-api-fetcher - npm Package Compare versions

Comparing version 2.0.1 to 2.0.3

115

dist/__test__/graphql.test.js

@@ -32,36 +32,95 @@ "use strict";

const token = process.env.TOKEN || '';
const version = process.env.API_VERSION || '2022-04';
describe('GraphQL API Test', () => {
test('intialize', () => {
(0, graphql_1.setConfig)({
version,
});
expect(graphql_1.QueueManager.initialize(domain)).toBe(1);
test('call api ok', async () => {
(0, graphql_1.setConfig)({ version: '2022-10' });
const query = `
query {
customers(first: 250) {
edges {
node {
id
displayName
email
firstName
lastName
tags
taxExempt
addresses {
address1
address2
city
company
country
countryCode
firstName
lastName
phone
province
provinceCode
zip
phone
}
}
cursor
}
pageInfo {
hasNextPage
hasPreviousPage
endCursor
startCursor
}
}
}
`;
const json = await (0, graphql_1.safeFetch)(domain, token, { query });
expect(json.data.customers).toBeTruthy();
});
test('call api', (done) => {
(0, graphql_1.safeFetch)(domain, token, {
query: `
query queryShop {
shop {
name
email
contactEmail
myshopifyDomain
ianaTimezone
currencyCode
currencyFormats {
moneyFormat
test('call api failed', async () => {
const query = `
query {
customers(first: ) {
edges {
node {
id
displayName
email
firstName
lastName
tags
taxExempt
addresses {
address1
address2
city
company
country
countryCode
firstName
lastName
phone
province
provinceCode
zip
phone
}
}
cursor
}
pageInfo {
hasNextPage
hasPreviousPage
endCursor
startCursor
}
}
`,
})
.then((data) => {
expect(data.data.shop.myshopifyDomain).toBe(domain);
done();
})
.catch((err) => {
done(err);
});
}
`;
try {
await (0, graphql_1.safeFetch)(domain, token, { query, variables: { 'x': 'x' } });
expect(true).toBe(true);
}
catch (err) {
expect(err instanceof graphql_1.GraphqlError).toBe(true);
}
});
});

@@ -1,9 +0,3 @@

import fetch, { RequestInfo, RequestInit } from 'node-fetch';
declare class Queue {
frontIndex: number;
backIndex: number;
constructor();
enqueue(): number;
dequeue(): boolean;
peek(): number;
export declare class GraphqlError extends Error {
constructor(message?: string, options?: ErrorOptions);
}

@@ -15,10 +9,2 @@ type CommonConfig = {

};
type Metric = {
total: number;
executions: number;
processing: number;
success: number;
errors: number;
throttles: number;
};
type Body = {

@@ -28,23 +14,4 @@ query: string;

};
declare class ShopifyGraphQL {
fetch: typeof fetch;
endpoint: RequestInfo;
queue: Queue;
_metrics: Metric;
constructor(endpoint: RequestInfo);
request(params: {
domain: string;
token: string;
body: Body;
}): Promise<unknown>;
_executeRequest(params: RequestInit): Promise<unknown>;
}
export declare class QueueManager {
private static queues;
static get(domain: string): ShopifyGraphQL;
static initialize(domain: string): number;
static clear(domain: string): void;
}
export declare function safeFetch(domain: string, token: string, body: Body): Promise<unknown>;
export declare function setConfig(cfg: Partial<CommonConfig>): void;
export {};

@@ -6,5 +6,12 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.setConfig = exports.safeFetch = exports.QueueManager = void 0;
exports.setConfig = exports.safeFetch = exports.GraphqlError = void 0;
const node_fetch_1 = __importDefault(require("node-fetch"));
const utils_1 = require("./utils");
class GraphqlError extends Error {
constructor(message, options) {
super(message, options);
this.name = ` GraphqlError`;
}
}
exports.GraphqlError = GraphqlError;
class Queue {

@@ -52,2 +59,3 @@ frontIndex;

_metrics;
lastActive;
constructor(endpoint) {

@@ -57,2 +65,3 @@ this.fetch = node_fetch_1.default;

this.queue = new Queue();
this.lastActive = new Date();
if (!this.endpoint) {

@@ -71,2 +80,3 @@ throw new Error('Missing Shop URL');

request(params) {
this.lastActive = new Date();
return new Promise(async (resolve, reject) => {

@@ -113,3 +123,3 @@ this._metrics.total += 1;

this._metrics.errors += 1;
return reject(new Error('', {
return reject(new GraphqlError('', {
cause: {

@@ -139,3 +149,3 @@ status: shopifyResult.status,

this._metrics.processing -= 1;
return reject(new Error('', {
return reject(new GraphqlError('', {
cause: {

@@ -170,3 +180,3 @@ status: isThrottled ? 'throttled' : shopifyResult.status,

this._metrics.errors += 1;
return reject(new Error('', {
return reject(new GraphqlError('', {
cause: {

@@ -185,6 +195,5 @@ status: shopifyResult.status,

.catch((shopifyError) => {
console.log(shopifyError);
this._metrics.processing -= 1;
this._metrics.errors += 1;
return reject(new Error('', { cause: shopifyError }));
return reject(new GraphqlError('', { cause: shopifyError }));
});

@@ -207,3 +216,3 @@ });

QueueManager.queues.set(domain, shopifyGraphQL);
return QueueManager.queues.size;
setInterval;
}

@@ -214,3 +223,2 @@ static clear(domain) {

}
exports.QueueManager = QueueManager;
async function safeFetch(domain, token, body) {

@@ -221,6 +229,20 @@ return QueueManager.get(domain).request({ domain, token, body });

function setConfig(cfg) {
globalCfg.version = cfg.version ?? '2022-04';
if (!cfg.version || cfg.version < '2022-10') {
throw new Error('Invalid version');
}
globalCfg.version = cfg.version;
globalCfg.retryThrottles = cfg.retryThrottles !== undefined ? cfg.retryThrottles : true;
globalCfg.maxConcurrentRequests = cfg.maxConcurrentRequests !== undefined ? cfg.maxConcurrentRequests : 50;
if (process.env.NODE_ENV === 'production') {
setInterval(() => {
for (const [key, value] of QueueManager.queues.entries()) {
const now = new Date();
now.setDate(now.getDate() - 1);
if (value.lastActive < now) {
QueueManager.clear(key);
}
}
}, 24 * 60 * 60);
}
}
exports.setConfig = setConfig;
{
"name": "@bss-sbc/shopify-api-fetcher",
"version": "2.0.1",
"version": "2.0.3",
"description": "",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

@@ -11,14 +11,6 @@ # Shopify API Fetcher

* `BucketManager`: Manage Token bucket rate limiter of active store
* `Rest.safeFetch: (domain: string, url: RequestInfo, params?: RequestInit) => Promise<Response>`: use this instead of normal `fetch`, with additional parameter `domain`, which specify a store.
* `initializeAll: (activeStores: Shop[]) => number;`: Initialize rate limiter for all given stores
* `GraphQL.safeFetch: (domain: string, token: string, { query: string, variables?: Object }) => Promise<Unknown>`: use this instead of normal `fetch`, with additional parameter `domain`, which specify a store.
* `initializeOne: (domain: string) => TokenBucketRateLimiter`: Initialize rate limiter for specific domain
* `get: (domain: string) => TokenBucketRateLimiter`: Get initialized rate limiter of a specific domain
* `clear: (domain: string) => void`: Clear rate limiter of a specific domain, used when app is uninstalled
* `safeFetch: (domain: string, url: RequestInfo, params?: RequestInit) => Promise<Response>`: use this instead of normal `fetch`, with additional parameter `domain`, which specify a store.
### Example

@@ -67,12 +59,5 @@

### Roadmap
Because of numbers of `services`, it is difficult to listen to `app/uninstalled` webhook event. So, auto clear bucket is necessary
- [x] REST
- [ ] GraphQL
- [ ] Time-to-live option
- [ ] (Updating)
- [ ] Time-to-live REST
- [x] GraphQL
- [x] Time-to-live GraphQL
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc