Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@forge/storage

Package Overview
Dependencies
Maintainers
2
Versions
109
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@forge/storage - npm Package Compare versions

Comparing version 1.5.13 to 1.5.14-experimental-6adbba3

1093

out/__test__/global-storage.test.js

@@ -46,606 +46,667 @@ "use strict";

});
describe('get', () => {
it('should call the storage API, passing the provided key and returning the stored value', async () => {
const apiClientMock = getApiClientMock({
data: {
appStoredEntity: {
value: 'testValue'
describe('Untyped entities', () => {
describe('get', () => {
it('should call the storage API, passing the provided key and returning the stored value', async () => {
const apiClientMock = getApiClientMock({
data: {
appStoredEntity: {
value: 'testValue'
}
}
}
});
const globalStorage = getStorage(apiClientMock);
const returnedValue = await globalStorage.get('testKey');
verifyApiClientCalledWith(apiClientMock, {
contextAri,
key: 'testKey',
encrypted: false
});
expect(returnedValue).toEqual('testValue');
});
const globalStorage = getStorage(apiClientMock);
const returnedValue = await globalStorage.get('testKey');
verifyApiClientCalledWith(apiClientMock, {
contextAri,
key: 'testKey',
encrypted: false
it('should call the storage API, passing the provided key and returning undefined if the key doesnt exist', async () => {
const apiClientMock = getApiClientMock({
data: {
appStoredEntity: {
value: null
}
}
});
const globalStorage = getStorage(apiClientMock);
const returnedValue = await globalStorage.get('testKey');
verifyApiClientCalledWith(apiClientMock, {
contextAri,
key: 'testKey',
encrypted: false
});
expect(returnedValue).toEqual(undefined);
});
expect(returnedValue).toEqual('testValue');
});
it('should call the storage API, passing the provided key and returning undefined if the key doesnt exist', async () => {
const apiClientMock = getApiClientMock({
data: {
appStoredEntity: {
value: null
it('should call the storage API, passing the provided key and returning the stored falsey value 0', async () => {
const apiClientMock = getApiClientMock({
data: {
appStoredEntity: {
value: 0
}
}
}
});
const globalStorage = getStorage(apiClientMock);
const returnedValue = await globalStorage.get('testKey');
verifyApiClientCalledWith(apiClientMock, {
contextAri,
key: 'testKey',
encrypted: false
});
expect(returnedValue).toEqual(0);
});
const globalStorage = getStorage(apiClientMock);
const returnedValue = await globalStorage.get('testKey');
verifyApiClientCalledWith(apiClientMock, {
contextAri,
key: 'testKey',
encrypted: false
});
expect(returnedValue).toEqual(undefined);
});
it('should call the storage API, passing the provided key and returning the stored falsey value 0', async () => {
const apiClientMock = getApiClientMock({
data: {
appStoredEntity: {
value: 0
it('should call the storage API, passing the provided key and returning the stored empty string', async () => {
const apiClientMock = getApiClientMock({
data: {
appStoredEntity: {
value: ''
}
}
}
});
const globalStorage = getStorage(apiClientMock);
const returnedValue = await globalStorage.get('testKey');
verifyApiClientCalledWith(apiClientMock, {
contextAri,
key: 'testKey',
encrypted: false
});
expect(returnedValue).toEqual('');
});
const globalStorage = getStorage(apiClientMock);
const returnedValue = await globalStorage.get('testKey');
verifyApiClientCalledWith(apiClientMock, {
contextAri,
key: 'testKey',
encrypted: false
it('should throw an error with the returned status for non-200 status codes', async () => {
const apiClientMock = getApiClientMock(undefined, 400);
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.get('testKey');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forStatus(400));
});
expect(returnedValue).toEqual(0);
});
it('should call the storage API, passing the provided key and returning the stored empty string', async () => {
const apiClientMock = getApiClientMock({
data: {
appStoredEntity: {
value: ''
}
}
it('should throw an error with the returned error message for failed responses', async () => {
const apiClientMock = getApiClientMock({
errors: [INVALID_CURSOR_ERROR]
}, 200);
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.get('testKey');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forErrorCode('CURSOR_INVALID', 'error message'));
});
const globalStorage = getStorage(apiClientMock);
const returnedValue = await globalStorage.get('testKey');
verifyApiClientCalledWith(apiClientMock, {
contextAri,
key: 'testKey',
encrypted: false
it('should throw an error if the response is not a valid JSON', async () => {
const apiClientMock = getApiClientMockInvalidJson('test', 200);
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.get('testKey');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forUnexpected('Response text was not a valid JSON: test'));
});
expect(returnedValue).toEqual('');
});
it('should throw an error with the returned status for non-200 status codes', async () => {
const apiClientMock = getApiClientMock(undefined, 400);
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.get('testKey');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forStatus(400));
});
it('should throw an error with the returned error message for failed responses', async () => {
const apiClientMock = getApiClientMock({
errors: [INVALID_CURSOR_ERROR]
}, 200);
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.get('testKey');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forErrorCode('CURSOR_INVALID', 'error message'));
});
it('should throw an error if the response is not a valid JSON', async () => {
const apiClientMock = getApiClientMockInvalidJson('test', 200);
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.get('testKey');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forUnexpected('Response text was not a valid JSON: test'));
});
});
describe('get secret', () => {
it('should call the storage API, passing the provided key and returning the stored value', async () => {
const apiClientMock = getApiClientMock({
data: {
appStoredEntity: {
value: 'testValue'
describe('set', () => {
it('should call the storage API, passing the provided key and value', async () => {
const apiClientMock = getApiClientMock({
data: {
appStorage: {
setAppStoredEntity: {
success: true
}
}
}
}
});
const globalStorage = getStorage(apiClientMock);
await globalStorage.set('testKey', 'testValue');
verifyApiClientCalledWith(apiClientMock, {
input: {
contextAri,
key: 'testKey',
value: 'testValue',
encrypted: false
}
});
});
const globalStorage = getStorage(apiClientMock);
const returnedValue = await globalStorage.getSecret('testKey');
verifyApiClientCalledWith(apiClientMock, {
contextAri,
key: 'testKey',
encrypted: true
});
expect(returnedValue).toEqual('testValue');
});
});
describe('set', () => {
it('should call the storage API, passing the provided key and value', async () => {
const apiClientMock = getApiClientMock({
data: {
appStorage: {
setAppStoredEntity: {
success: true
it('should throw an error if the storage API returns successful = false', async () => {
const apiClientMock = getApiClientMock({
data: {
appStorage: {
setAppStoredEntity: {
success: false,
errors: [INVALID_CURSOR_ERROR]
}
}
}
}
});
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.set('testKey', 'testValue');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forErrorCode('INVALID_CURSOR', 'error message'));
});
const globalStorage = getStorage(apiClientMock);
await globalStorage.set('testKey', 'testValue');
verifyApiClientCalledWith(apiClientMock, {
input: {
contextAri,
key: 'testKey',
value: 'testValue',
encrypted: false
}
it('should throw an error if the storage API returns a non 200 status code', async () => {
const apiClientMock = getApiClientMockInvalidJson('', 400);
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.set('testKey', 'testValue');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forStatus(400));
});
});
it('should throw an error if the storage API returns successful = false', async () => {
const apiClientMock = getApiClientMock({
data: {
appStorage: {
setAppStoredEntity: {
success: false,
errors: [INVALID_CURSOR_ERROR]
it('should throw a 500 error if success=false but no errors were returned', async () => {
const apiClientMock = getApiClientMock({
data: {
appStorage: {
setAppStoredEntity: {
success: false
}
}
}
}
});
const globalStorage = getStorage(apiClientMock);
await expect(globalStorage.set('testKey', 'testValue')).rejects.toThrow(errors_1.APIError.forStatus(500));
verifyApiClientCalledWith(apiClientMock, {
input: {
contextAri,
key: 'testKey',
value: 'testValue',
encrypted: false
}
});
});
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.set('testKey', 'testValue');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forErrorCode('INVALID_CURSOR', 'error message'));
});
it('should throw an error if the storage API returns a non 200 status code', async () => {
const apiClientMock = getApiClientMockInvalidJson('', 400);
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.set('testKey', 'testValue');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forStatus(400));
});
it('should throw a 500 error if success=false but no errors were returned', async () => {
const apiClientMock = getApiClientMock({
data: {
appStorage: {
setAppStoredEntity: {
success: false
describe('delete', () => {
it('should call the storage API, passing the provided key', async () => {
const apiClientMock = getApiClientMock({
data: {
appStorage: {
deleteAppStoredEntity: {
success: true
}
}
}
}
});
const globalStorage = getStorage(apiClientMock);
await globalStorage.delete('testKey');
verifyApiClientCalledWith(apiClientMock, {
input: {
contextAri,
key: 'testKey',
encrypted: false
}
});
});
const globalStorage = getStorage(apiClientMock);
await expect(globalStorage.set('testKey', 'testValue')).rejects.toThrow(errors_1.APIError.forStatus(500));
verifyApiClientCalledWith(apiClientMock, {
input: {
contextAri,
key: 'testKey',
value: 'testValue',
encrypted: false
}
});
});
});
describe('set secret', () => {
it('should call the storage API, passing the provided key and value', async () => {
const apiClientMock = getApiClientMock({
data: {
appStorage: {
setAppStoredEntity: {
success: true
it('should throw an error if the storage API returns successful = false', async () => {
const apiClientMock = getApiClientMock({
data: {
appStorage: {
deleteAppStoredEntity: {
success: false,
errors: [INVALID_CURSOR_ERROR]
}
}
}
}
});
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.delete('testKey');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forErrorCode('CURSOR_INVALID', 'error message'));
});
const globalStorage = getStorage(apiClientMock);
await globalStorage.setSecret('testKey', 'testValue');
verifyApiClientCalledWith(apiClientMock, {
input: {
contextAri,
key: 'testKey',
value: 'testValue',
encrypted: true
}
it('should throw an error if the storage API returns a non 200 status code and has no body', async () => {
const apiClientMock = getApiClientMockInvalidJson('', 400);
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.delete('testKey');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forStatus(400));
});
});
});
describe('delete', () => {
it('should call the storage API, passing the provided key', async () => {
const apiClientMock = getApiClientMock({
data: {
appStorage: {
deleteAppStoredEntity: {
success: true
describe('bulkSet', () => {
it('should call the storage API for bulkSet and return savedKeys', async () => {
const apiClientMock = getApiClientMock({
data: {
appStorage: {
setAppStoredEntities: {
success: true,
savedKeys: ['testKey'],
failedKeys: []
}
}
}
}
});
const globalStorage = getStorage(apiClientMock);
await globalStorage.bulkSet([
{
key: 'testKey',
value: 'testValue'
}
]);
verifyApiClientCalledWith(apiClientMock, {
input: {
contextAri,
entities: [
{
key: 'testKey',
value: 'testValue'
}
],
encrypted: false
}
});
});
const globalStorage = getStorage(apiClientMock);
await globalStorage.delete('testKey');
verifyApiClientCalledWith(apiClientMock, {
input: {
contextAri,
key: 'testKey',
encrypted: false
}
});
});
it('should throw an error if the storage API returns successful = false', async () => {
const apiClientMock = getApiClientMock({
data: {
appStorage: {
deleteAppStoredEntity: {
success: false,
errors: [INVALID_CURSOR_ERROR]
it('should throw an error if the storage API returns successful = false', async () => {
const apiClientMock = getApiClientMock({
data: {
appStorage: {
setAppStoredEntities: {
success: false,
errors: [INVALID_CURSOR_ERROR]
}
}
}
}
});
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.bulkSet([
{
key: 'testKey',
value: 'testValue'
}
]);
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forErrorCode('INVALID_CURSOR', 'error message'));
});
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.delete('testKey');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forErrorCode('CURSOR_INVALID', 'error message'));
});
it('should throw an error if the storage API returns a non 200 status code and has no body', async () => {
const apiClientMock = getApiClientMockInvalidJson('', 400);
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.delete('testKey');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forStatus(400));
});
});
describe('delete secret', () => {
it('should call the storage API, passing the provided key', async () => {
const apiClientMock = getApiClientMock({
data: {
appStorage: {
deleteAppStoredEntity: {
success: true
describe('Secret storage', () => {
describe('get secret', () => {
it('should call the storage API, passing the provided key and returning the stored value', async () => {
const apiClientMock = getApiClientMock({
data: {
appStoredEntity: {
value: 'testValue'
}
}
}
});
const globalStorage = getStorage(apiClientMock);
await globalStorage.deleteSecret('testKey');
verifyApiClientCalledWith(apiClientMock, {
input: {
});
const globalStorage = getStorage(apiClientMock);
const returnedValue = await globalStorage.getSecret('testKey');
verifyApiClientCalledWith(apiClientMock, {
contextAri,
key: 'testKey',
encrypted: true
}
});
expect(returnedValue).toEqual('testValue');
});
});
});
describe('getEntity', () => {
it('should call the storage API, passing the provided entity name and entity key and returning the stored value', async () => {
const apiClientMock = getApiClientMock({
data: {
appStoredCustomEntity: {
value: 'testValue'
describe('set secret', () => {
it('should call the storage API, passing the provided key and value', async () => {
const apiClientMock = getApiClientMock({
data: {
appStorage: {
setAppStoredEntity: {
success: true
}
}
}
}
});
const globalStorage = getStorage(apiClientMock);
const returnedValue = await globalStorage.getEntity('testEntityName', 'testEntityKey');
verifyApiClientCalledWith(apiClientMock, {
contextAri,
entityName: 'testEntityName',
key: 'testEntityKey'
});
expect(returnedValue).toEqual('testValue');
});
it('should call the storage API, passing the provided entity key and returning undefined if the key doesnt exist', async () => {
const apiClientMock = getApiClientMock({
data: {
appStoredCustomEntity: {
value: null
});
const globalStorage = getStorage(apiClientMock);
await globalStorage.setSecret('testKey', 'testValue');
verifyApiClientCalledWith(apiClientMock, {
input: {
contextAri,
key: 'testKey',
value: 'testValue',
encrypted: true
}
}
});
});
const globalStorage = getStorage(apiClientMock);
const returnedValue = await globalStorage.getEntity('testEntityName', 'testEntityKey');
verifyApiClientCalledWith(apiClientMock, {
contextAri,
entityName: 'testEntityName',
key: 'testEntityKey'
});
expect(returnedValue).toEqual(undefined);
});
it('should call the storage API, passing the provided key and returning the stored falsey value 0', async () => {
const apiClientMock = getApiClientMock({
data: {
appStoredCustomEntity: {
value: 0
describe('delete secret', () => {
it('should call the storage API, passing the provided key', async () => {
const apiClientMock = getApiClientMock({
data: {
appStorage: {
deleteAppStoredEntity: {
success: true
}
}
}
}
});
const globalStorage = getStorage(apiClientMock);
const returnedValue = await globalStorage.getEntity('testEntityName', 'testEntityKey');
verifyApiClientCalledWith(apiClientMock, {
contextAri,
entityName: 'testEntityName',
key: 'testEntityKey'
});
expect(returnedValue).toEqual(0);
});
it('should call the storage API, passing the provided key and returning the stored empty string', async () => {
const apiClientMock = getApiClientMock({
data: {
appStoredCustomEntity: {
value: ''
});
const globalStorage = getStorage(apiClientMock);
await globalStorage.deleteSecret('testKey');
verifyApiClientCalledWith(apiClientMock, {
input: {
contextAri,
key: 'testKey',
encrypted: true
}
}
});
});
const globalStorage = getStorage(apiClientMock);
const returnedValue = await globalStorage.getEntity('testEntityName', 'testEntityKey');
verifyApiClientCalledWith(apiClientMock, {
contextAri,
entityName: 'testEntityName',
key: 'testEntityKey'
});
expect(returnedValue).toEqual('');
});
it('should throw an error with the returned status for non-200 status codes', async () => {
const apiClientMock = getApiClientMock(undefined, 400);
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.getEntity('testEntityName', 'testEntityKey');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forStatus(400));
});
it('should throw an error with the returned error message for failed responses', async () => {
const apiClientMock = getApiClientMock({
errors: [INVALID_CURSOR_ERROR]
}, 200);
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.getEntity('testEntityName', 'testEntityKey');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forErrorCode('CURSOR_INVALID', 'error message'));
});
it('should throw an error if the response is not a valid JSON', async () => {
const apiClientMock = getApiClientMockInvalidJson('test', 200);
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.getEntity('testEntityName', 'testEntityKey');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forUnexpected('Response text was not a valid JSON: test'));
});
});
describe('setEntity', () => {
it('should call the storage API, passing the provided entity name, entity key and value', async () => {
const apiClientMock = getApiClientMock({
data: {
appStorageCustomEntity: {
setAppStoredCustomEntity: {
success: true
describe('Custom entities', () => {
describe('getEntity', () => {
it('should call the storage API, passing the provided entity name and entity key and returning the stored value', async () => {
const apiClientMock = getApiClientMock({
data: {
appStoredCustomEntity: {
value: 'testValue'
}
}
}
});
const globalStorage = getStorage(apiClientMock);
await globalStorage.setEntity('testEntityName', 'testEntityKey', 'testValue');
verifyApiClientCalledWith(apiClientMock, {
input: {
});
const globalStorage = getStorage(apiClientMock);
const returnedValue = await globalStorage.getEntity('testEntityName', 'testEntityKey');
verifyApiClientCalledWith(apiClientMock, {
contextAri,
entityName: 'testEntityName',
key: 'testEntityKey',
value: 'testValue'
}
key: 'testEntityKey'
});
expect(returnedValue).toEqual('testValue');
});
});
it('should throw an error if the storage API returns successful = false', async () => {
const apiClientMock = getApiClientMock({
data: {
appStorageCustomEntity: {
setAppStoredCustomEntity: {
success: false,
errors: [INVALID_CURSOR_ERROR]
it('should call the storage API, passing the provided entity key and returning undefined if the key doesnt exist', async () => {
const apiClientMock = getApiClientMock({
data: {
appStoredCustomEntity: {
value: null
}
}
}
});
const globalStorage = getStorage(apiClientMock);
const returnedValue = await globalStorage.getEntity('testEntityName', 'testEntityKey');
verifyApiClientCalledWith(apiClientMock, {
contextAri,
entityName: 'testEntityName',
key: 'testEntityKey'
});
expect(returnedValue).toEqual(undefined);
});
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.setEntity('testEntityName', 'testEntityKey', 'testValue');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forErrorCode('INVALID_CURSOR', 'error message'));
});
it('should throw an error if the storage API returns a non 200 status code', async () => {
const apiClientMock = getApiClientMockInvalidJson('', 400);
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.setEntity('testEntityName', 'testEntityKey', 'testValue');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forStatus(400));
});
it('should throw a 500 error if success=false but no errors were returned', async () => {
const apiClientMock = getApiClientMock({
data: {
appStorageCustomEntity: {
setAppStoredCustomEntity: {
success: false
it('should call the storage API, passing the provided key and returning the stored falsey value 0', async () => {
const apiClientMock = getApiClientMock({
data: {
appStoredCustomEntity: {
value: 0
}
}
}
});
const globalStorage = getStorage(apiClientMock);
await expect(globalStorage.setEntity('testEntityName', 'testEntityKey', 'testValue')).rejects.toThrow(errors_1.APIError.forStatus(500));
verifyApiClientCalledWith(apiClientMock, {
input: {
});
const globalStorage = getStorage(apiClientMock);
const returnedValue = await globalStorage.getEntity('testEntityName', 'testEntityKey');
verifyApiClientCalledWith(apiClientMock, {
contextAri,
entityName: 'testEntityName',
key: 'testEntityKey',
value: 'testValue'
}
key: 'testEntityKey'
});
expect(returnedValue).toEqual(0);
});
});
});
describe('deleteEntity', () => {
it('should call the storage API, passing the provided entity name and key', async () => {
const apiClientMock = getApiClientMock({
data: {
appStorageCustomEntity: {
deleteAppStoredCustomEntity: {
success: true
it('should call the storage API, passing the provided key and returning the stored empty string', async () => {
const apiClientMock = getApiClientMock({
data: {
appStoredCustomEntity: {
value: ''
}
}
}
});
const globalStorage = getStorage(apiClientMock);
await globalStorage.deleteEntity('testEntityName', 'testEntityKey');
verifyApiClientCalledWith(apiClientMock, {
input: {
});
const globalStorage = getStorage(apiClientMock);
const returnedValue = await globalStorage.getEntity('testEntityName', 'testEntityKey');
verifyApiClientCalledWith(apiClientMock, {
contextAri,
entityName: 'testEntityName',
key: 'testEntityKey'
}
});
expect(returnedValue).toEqual('');
});
it('should throw an error with the returned status for non-200 status codes', async () => {
const apiClientMock = getApiClientMock(undefined, 400);
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.getEntity('testEntityName', 'testEntityKey');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forStatus(400));
});
it('should throw an error with the returned error message for failed responses', async () => {
const apiClientMock = getApiClientMock({
errors: [INVALID_CURSOR_ERROR]
}, 200);
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.getEntity('testEntityName', 'testEntityKey');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forErrorCode('CURSOR_INVALID', 'error message'));
});
it('should throw an error if the response is not a valid JSON', async () => {
const apiClientMock = getApiClientMockInvalidJson('test', 200);
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.getEntity('testEntityName', 'testEntityKey');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forUnexpected('Response text was not a valid JSON: test'));
});
});
it('should throw an error if the storage API returns successful = false', async () => {
const apiClientMock = getApiClientMock({
data: {
appStorageCustomEntity: {
deleteAppStoredCustomEntity: {
success: false,
errors: [INVALID_CURSOR_ERROR]
describe('setEntity', () => {
it('should call the storage API, passing the provided entity name, entity key and value', async () => {
const apiClientMock = getApiClientMock({
data: {
appStorageCustomEntity: {
setAppStoredCustomEntity: {
success: true
}
}
}
}
});
const globalStorage = getStorage(apiClientMock);
await globalStorage.setEntity('testEntityName', 'testEntityKey', 'testValue');
verifyApiClientCalledWith(apiClientMock, {
input: {
contextAri,
entityName: 'testEntityName',
key: 'testEntityKey',
value: 'testValue'
}
});
});
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.deleteEntity('testEntityKey', 'testEntityKey');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forErrorCode('CURSOR_INVALID', 'error message'));
});
it('should throw an error if the storage API returns a non 200 status code and has no body', async () => {
const apiClientMock = getApiClientMockInvalidJson('', 400);
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.deleteEntity('testEntityKey', 'testEntityKey');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forStatus(400));
});
});
describe('list', () => {
it('should call the storage API with the provided parameters', async () => {
const apiClientMock = getApiClientMock({
data: {
appStoredEntities: {
edges: [
{ node: { key: 'key1', value: 'testValue' }, cursor: 'cursor1' },
{ node: { key: 'key2', value: 'testValue' }, cursor: 'cursor2' }
]
it('should throw an error if the storage API returns successful = false', async () => {
const apiClientMock = getApiClientMock({
data: {
appStorageCustomEntity: {
setAppStoredCustomEntity: {
success: false,
errors: [INVALID_CURSOR_ERROR]
}
}
}
}
});
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.setEntity('testEntityName', 'testEntityKey', 'testValue');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forErrorCode('INVALID_CURSOR', 'error message'));
});
const globalStorage = getStorage(apiClientMock);
const where = [
{
field: 'key',
condition: 'STARTS_WITH',
value: 'test'
}
];
const cursor = 'cursor';
const limit = 10;
const response = await globalStorage.list({ where, cursor, limit });
verifyApiClientCalledWith(apiClientMock, {
contextAri,
where,
cursor,
limit
}, gql_queries_1.UntypedQueries.listQuery(contextAri, {}).query);
expect(response).toEqual(expect.objectContaining({
results: [
{ key: 'key1', value: 'testValue' },
{ key: 'key2', value: 'testValue' }
],
nextCursor: 'cursor2'
}));
});
it('should query the appStoredEntitiesForCleanup endpoint given process.env.IS_CLEANUP_FUNCTION is set to true', async () => {
process.env.IS_CLEANUP_FUNCTION = 'true';
const apiClientMock = getApiClientMock({
data: {
appStoredEntitiesForCleanup: {
edges: [
{ node: { key: 'key1', value: 'testValue' }, cursor: 'cursor1' },
{ node: { key: 'key2', value: 'testValue' }, cursor: 'cursor2' }
]
it('should throw an error if the storage API returns a non 200 status code', async () => {
const apiClientMock = getApiClientMockInvalidJson('', 400);
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.setEntity('testEntityName', 'testEntityKey', 'testValue');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forStatus(400));
});
it('should throw a 500 error if success=false but no errors were returned', async () => {
const apiClientMock = getApiClientMock({
data: {
appStorageCustomEntity: {
setAppStoredCustomEntity: {
success: false
}
}
}
}
});
const globalStorage = getStorage(apiClientMock);
await expect(globalStorage.setEntity('testEntityName', 'testEntityKey', 'testValue')).rejects.toThrow(errors_1.APIError.forStatus(500));
verifyApiClientCalledWith(apiClientMock, {
input: {
contextAri,
entityName: 'testEntityName',
key: 'testEntityKey',
value: 'testValue'
}
});
});
const globalStorage = getStorage(apiClientMock);
const where = [
{
field: 'key',
condition: 'STARTS_WITH',
value: 'test'
}
];
const cursor = 'cursor';
const limit = 10;
const response = await globalStorage.list({ where, cursor, limit });
verifyApiClientCalledWith(apiClientMock, {
contextAri,
where,
cursor,
limit
}, gql_queries_1.UntypedQueries.listQueryForCleanup(contextAri, {}).query);
expect(response).toEqual(expect.objectContaining({
results: [
{ key: 'key1', value: 'testValue' },
{ key: 'key2', value: 'testValue' }
],
nextCursor: 'cursor2'
}));
process.env.IS_CLEANUP_FUNCTION = '';
});
it('should use default values', async () => {
const apiClientMock = getApiClientMock({
data: {
appStoredEntities: {
edges: []
describe('deleteEntity', () => {
it('should call the storage API, passing the provided entity name and key', async () => {
const apiClientMock = getApiClientMock({
data: {
appStorageCustomEntity: {
deleteAppStoredCustomEntity: {
success: true
}
}
}
}
});
const globalStorage = getStorage(apiClientMock);
await globalStorage.deleteEntity('testEntityName', 'testEntityKey');
verifyApiClientCalledWith(apiClientMock, {
input: {
contextAri,
entityName: 'testEntityName',
key: 'testEntityKey'
}
});
});
const globalStorage = getStorage(apiClientMock);
await globalStorage.list({});
verifyApiClientCalledWith(apiClientMock, {
contextAri,
where: null,
cursor: null,
limit: null
}, gql_queries_1.UntypedQueries.listQuery(contextAri, {}).query);
});
it('should handle an empty result set', async () => {
const apiClientMock = getApiClientMock({
data: {
appStoredEntities: {
edges: []
it('should throw an error if the storage API returns successful = false', async () => {
const apiClientMock = getApiClientMock({
data: {
appStorageCustomEntity: {
deleteAppStoredCustomEntity: {
success: false,
errors: [INVALID_CURSOR_ERROR]
}
}
}
}
});
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.deleteEntity('testEntityKey', 'testEntityKey');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forErrorCode('CURSOR_INVALID', 'error message'));
});
const globalStorage = getStorage(apiClientMock);
const where = [
{
field: 'key',
condition: 'STARTS_WITH',
value: 'test'
}
];
const response = await globalStorage.list({ where });
expect(response).toEqual(expect.objectContaining({
results: [],
nextCursor: undefined
}));
it('should throw an error if the storage API returns a non 200 status code and has no body', async () => {
const apiClientMock = getApiClientMockInvalidJson('', 400);
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.deleteEntity('testEntityKey', 'testEntityKey');
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forStatus(400));
});
});
it('should throw an error if the storage API returns an error', async () => {
const apiClientMock = getApiClientMock({
errors: [INVALID_CURSOR_ERROR]
describe('list', () => {
it('should call the storage API with the provided parameters', async () => {
const apiClientMock = getApiClientMock({
data: {
appStoredEntities: {
edges: [
{ node: { key: 'key1', value: 'testValue' }, cursor: 'cursor1' },
{ node: { key: 'key2', value: 'testValue' }, cursor: 'cursor2' }
]
}
}
});
const globalStorage = getStorage(apiClientMock);
const where = [
{
field: 'key',
condition: 'STARTS_WITH',
value: 'test'
}
];
const cursor = 'cursor';
const limit = 10;
const response = await globalStorage.list({ where, cursor, limit });
verifyApiClientCalledWith(apiClientMock, {
contextAri,
where,
cursor,
limit
}, gql_queries_1.UntypedQueries.listQuery(contextAri, {}).query);
expect(response).toEqual(expect.objectContaining({
results: [
{ key: 'key1', value: 'testValue' },
{ key: 'key2', value: 'testValue' }
],
nextCursor: 'cursor2'
}));
});
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.list({});
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forErrorCode('CURSOR_INVALID', 'error message'));
it('should query the appStoredEntitiesForCleanup endpoint given process.env.IS_CLEANUP_FUNCTION is set to true', async () => {
process.env.IS_CLEANUP_FUNCTION = 'true';
const apiClientMock = getApiClientMock({
data: {
appStoredEntitiesForCleanup: {
edges: [
{ node: { key: 'key1', value: 'testValue' }, cursor: 'cursor1' },
{ node: { key: 'key2', value: 'testValue' }, cursor: 'cursor2' }
]
}
}
});
const globalStorage = getStorage(apiClientMock);
const where = [
{
field: 'key',
condition: 'STARTS_WITH',
value: 'test'
}
];
const cursor = 'cursor';
const limit = 10;
const response = await globalStorage.list({ where, cursor, limit });
verifyApiClientCalledWith(apiClientMock, {
contextAri,
where,
cursor,
limit
}, gql_queries_1.UntypedQueries.listQueryForCleanup(contextAri, {}).query);
expect(response).toEqual(expect.objectContaining({
results: [
{ key: 'key1', value: 'testValue' },
{ key: 'key2', value: 'testValue' }
],
nextCursor: 'cursor2'
}));
process.env.IS_CLEANUP_FUNCTION = '';
});
it('should use default values', async () => {
const apiClientMock = getApiClientMock({
data: {
appStoredEntities: {
edges: []
}
}
});
const globalStorage = getStorage(apiClientMock);
await globalStorage.list({});
verifyApiClientCalledWith(apiClientMock, {
contextAri,
where: null,
cursor: null,
limit: null
}, gql_queries_1.UntypedQueries.listQuery(contextAri, {}).query);
});
it('should handle an empty result set', async () => {
const apiClientMock = getApiClientMock({
data: {
appStoredEntities: {
edges: []
}
}
});
const globalStorage = getStorage(apiClientMock);
const where = [
{
field: 'key',
condition: 'STARTS_WITH',
value: 'test'
}
];
const response = await globalStorage.list({ where });
expect(response).toEqual(expect.objectContaining({
results: [],
nextCursor: undefined
}));
});
it('should throw an error if the storage API returns an error', async () => {
const apiClientMock = getApiClientMock({
errors: [INVALID_CURSOR_ERROR]
});
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.list({});
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forErrorCode('CURSOR_INVALID', 'error message'));
});
it('should throw an error if the storage API returns a non 200 status code and has no body', async () => {
const apiClientMock = getApiClientMockInvalidJson('', 400);
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.list({});
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forStatus(400));
});
});
it('should throw an error if the storage API returns a non 200 status code and has no body', async () => {
const apiClientMock = getApiClientMockInvalidJson('', 400);
const globalStorage = getStorage(apiClientMock);
const response = globalStorage.list({});
expect(apiClientMock).toHaveBeenCalled();
await expect(response).rejects.toThrow(errors_1.APIError.forStatus(400));
});
});

@@ -652,0 +713,0 @@ describe('listCustomEntities', () => {

import { GlobalStorage } from '../global-storage';
import { CustomEntityIndexBuilder } from './query-api';
type EntityGlobalStorage = Pick<GlobalStorage, 'setEntity' | 'getEntity' | 'deleteEntity' | 'listCustomEntities'>;
declare type EntityGlobalStorage = Pick<GlobalStorage, 'setEntity' | 'getEntity' | 'deleteEntity' | 'listCustomEntities'>;
export interface EntityStorageBuilderType<T> {

@@ -5,0 +5,0 @@ query(): CustomEntityIndexBuilder<T>;

@@ -1,4 +0,4 @@

import { FetchMethod } from './index';
import { BulkResponse, FetchMethod } from './index';
import { CustomEntityListOptions, ListOptions } from './query-interfaces';
import { SharedStorageAdapter } from './storage-adapter';
import { BulkItem, SharedStorageAdapter } from './storage-adapter';
interface ListResults {

@@ -23,2 +23,3 @@ results: {

setSecret(key: string, value: any): Promise<void>;
bulkSet(items: BulkItem[]): Promise<BulkResponse>;
delete(key: string): Promise<void>;

@@ -25,0 +26,0 @@ deleteSecret(key: string): Promise<void>;

@@ -75,2 +75,13 @@ "use strict";

}
async bulkSet(items) {
const requestBody = gql_queries_1.UntypedQueries.bulkSet(this.doGetAppContextAri(), items, false);
const response = await this.mutation(requestBody, 'appStorage', 'setAppStoredEntities');
const parsedResponse = await getResponseBody(response);
const failedKeys = parsedResponse.appStorage.setAppStoredEntities.failedKeys;
const savedKeys = parsedResponse.appStorage.setAppStoredEntities.savedKeys;
return {
savedKeys,
failedKeys
};
}
async delete(key) {

@@ -77,0 +88,0 @@ const requestBody = gql_queries_1.UntypedQueries.delete(this.doGetAppContextAri(), key, false);

import { CustomEntityListOptions, ListOptions } from './query-interfaces';
import { BulkItem } from './storage-adapter';
export declare class UntypedQueries {

@@ -50,2 +51,12 @@ static get: (contextAri: string, key: string, encrypted: boolean) => {

};
static bulkSet: (contextAri: string, values: BulkItem[], encrypted: boolean) => {
query: string;
variables: {
input: {
contextAri: string;
entities: BulkItem[];
encrypted: boolean;
};
};
};
}

@@ -52,0 +63,0 @@ export declare class CustomEntityQueries {

@@ -125,2 +125,29 @@ "use strict";

};
UntypedQueries.bulkSet = (contextAri, values, encrypted) => ({
query: `
mutation forge_app_setApplicationStorageEntities($input: SetAppStoredEntitiesMutationInput!) {
appStorage{
setAppStoredEntities(input: $input) {
success
savedKeys
failedKeys
errors {
message
extensions {
errorType
statusCode
}
}
}
}
}
`,
variables: {
input: {
contextAri,
entities: values,
encrypted
}
}
});
class CustomEntityQueries {

@@ -127,0 +154,0 @@ }

@@ -5,4 +5,4 @@ import { RequestInit, Response } from 'node-fetch';

import { DefaultQueryBuilder } from './query-api';
export type APIResponse = Pick<Response, 'json' | 'text' | 'arrayBuffer' | 'ok' | 'status' | 'statusText'>;
export type FetchMethod = (url: string, init: RequestInit) => Promise<APIResponse>;
export declare type APIResponse = Pick<Response, 'json' | 'text' | 'arrayBuffer' | 'ok' | 'status' | 'statusText'>;
export declare type FetchMethod = (url: string, init: RequestInit) => Promise<APIResponse>;
export declare const getStorageInstanceWithQuery: (adapter: GlobalStorage) => {

@@ -15,2 +15,3 @@ get: (key: string) => Promise<any>;

deleteSecret: (key: string) => Promise<void>;
bulkSet: (items: import("./storage-adapter").BulkItem[]) => Promise<import("./storage-adapter").BulkResponse>;
query: () => DefaultQueryBuilder;

@@ -26,3 +27,4 @@ entity: <T>(entityName: string) => EntityStorageBuilder<T>;

export { APIError } from './errors';
export { BulkItem, BulkResponse } from './storage-adapter';
export { CustomEntityIndexBuilder } from './entity-storage/query-api';
//# sourceMappingURL=index.d.ts.map

@@ -14,2 +14,3 @@ "use strict";

deleteSecret: adapter.deleteSecret.bind(adapter),
bulkSet: adapter.bulkSet.bind(adapter),
query: () => new query_api_1.DefaultQueryBuilder(adapter),

@@ -16,0 +17,0 @@ entity: (entityName) => new entity_storage_1.EntityStorageBuilder(entityName, adapter)

@@ -1,2 +0,2 @@

export type Value = string;
export declare type Value = string;
export interface StartsWith {

@@ -17,6 +17,6 @@ condition: 'STARTS_WITH';

}
export type StartsWithClause = FieldClause & StartsWith;
export type NotEqualToClause = FieldClause & NotEqualTo;
export type InClause = FieldClause & In;
export type WhereClause = StartsWithClause | NotEqualToClause | InClause;
export declare type StartsWithClause = FieldClause & StartsWith;
export declare type NotEqualToClause = FieldClause & NotEqualTo;
export declare type InClause = FieldClause & In;
export declare type WhereClause = StartsWithClause | NotEqualToClause | InClause;
export interface ListOptions {

@@ -27,3 +27,3 @@ where?: Array<WhereClause>;

}
export type CustomEntityQueryValue = string | number | boolean;
export declare type CustomEntityQueryValue = string | number | boolean;
export interface BetweenClause {

@@ -77,20 +77,20 @@ condition: 'BETWEEN';

}
export type FilterOperator = 'or' | 'and';
export declare type FilterOperator = 'or' | 'and';
export interface FilterPropertyClause {
property: string;
}
export type BetweenFilterClause = FilterPropertyClause & BetweenClause;
export type BeginsWithFilterClause = FilterPropertyClause & BeginsWithClause;
export type ExistsFilterClause = FilterPropertyClause & ExistsClause;
export type DoesNotExistFilterClause = FilterPropertyClause & DoesNotExistClause;
export type GreaterThanFilterClause = FilterPropertyClause & GreaterThanClause;
export type GreaterThanEqualToFilterClause = FilterPropertyClause & GreaterThanEqualToClause;
export type LessThanFilterClause = FilterPropertyClause & LessThanClause;
export type LessThanEqualToFilterClause = FilterPropertyClause & LessThanEqualToClause;
export type ContainsFilterClause = FilterPropertyClause & ContainsClause;
export type DoesNotContainFilterClause = FilterPropertyClause & DoesNotContainClause;
export type EqualToFilterClause = FilterPropertyClause & EqualToClause;
export type IsNotEqualToFilterClause = FilterPropertyClause & IsNotEqualToClause;
export type RangeClause = BetweenClause | BeginsWithClause | EqualToClause | GreaterThanClause | GreaterThanEqualToClause | LessThanClause | LessThanEqualToClause;
export type FilterClause = BetweenFilterClause | BeginsWithFilterClause | ExistsFilterClause | DoesNotExistFilterClause | GreaterThanFilterClause | GreaterThanEqualToFilterClause | LessThanFilterClause | LessThanEqualToFilterClause | ContainsFilterClause | DoesNotContainFilterClause | EqualToFilterClause | IsNotEqualToFilterClause;
export declare type BetweenFilterClause = FilterPropertyClause & BetweenClause;
export declare type BeginsWithFilterClause = FilterPropertyClause & BeginsWithClause;
export declare type ExistsFilterClause = FilterPropertyClause & ExistsClause;
export declare type DoesNotExistFilterClause = FilterPropertyClause & DoesNotExistClause;
export declare type GreaterThanFilterClause = FilterPropertyClause & GreaterThanClause;
export declare type GreaterThanEqualToFilterClause = FilterPropertyClause & GreaterThanEqualToClause;
export declare type LessThanFilterClause = FilterPropertyClause & LessThanClause;
export declare type LessThanEqualToFilterClause = FilterPropertyClause & LessThanEqualToClause;
export declare type ContainsFilterClause = FilterPropertyClause & ContainsClause;
export declare type DoesNotContainFilterClause = FilterPropertyClause & DoesNotContainClause;
export declare type EqualToFilterClause = FilterPropertyClause & EqualToClause;
export declare type IsNotEqualToFilterClause = FilterPropertyClause & IsNotEqualToClause;
export declare type RangeClause = BetweenClause | BeginsWithClause | EqualToClause | GreaterThanClause | GreaterThanEqualToClause | LessThanClause | LessThanEqualToClause;
export declare type FilterClause = BetweenFilterClause | BeginsWithFilterClause | ExistsFilterClause | DoesNotExistFilterClause | GreaterThanFilterClause | GreaterThanEqualToFilterClause | LessThanFilterClause | LessThanEqualToFilterClause | ContainsFilterClause | DoesNotContainFilterClause | EqualToFilterClause | IsNotEqualToFilterClause;
export declare enum SortOrder {

@@ -103,3 +103,3 @@ ASC = "ASC",

}
export type CustomEntityPartitionValue = string | number | boolean;
export declare type CustomEntityPartitionValue = string | number | boolean;
export interface CustomEntityListOptions {

@@ -106,0 +106,0 @@ sort?: SortOrder;

import { EntityStorageBuilderType } from './entity-storage';
import { BeginsWithClause, BetweenClause, ExistsClause, DoesNotExistClause, GreaterThanClause, GreaterThanEqualToClause, StartsWith, NotEqualTo, In, LessThanClause, LessThanEqualToClause, ContainsClause, DoesNotContainClause, IsNotEqualToClause, EqualToClause } from './query-interfaces';
export interface BulkItem {
key: string;
value: string | number | boolean | Record<string, any> | any[];
}
interface FailedKey {
key: string;
reason: string;
}
export interface BulkResponse {
savedKeys: string[];
failedKeys: FailedKey[];
}
export interface StorageAdapter {

@@ -10,2 +22,3 @@ get(key: string): Promise<any>;

deleteSecret(key: string): Promise<void>;
bulkSet(items: BulkItem[]): Promise<BulkResponse>;
}

@@ -20,8 +33,8 @@ export interface EntityStorageAdapter {

}
export type SharedStorageAdapter = StorageAdapter & EntityStorageAdapter;
export declare type SharedStorageAdapter = StorageAdapter & EntityStorageAdapter;
export interface QueryApi {
query(): QueryBuilder;
}
export type Predicate = StartsWith | NotEqualTo | In;
export type Condition = Predicate;
export declare type Predicate = StartsWith | NotEqualTo | In;
export declare type Condition = Predicate;
export interface QueryBuilder {

@@ -34,4 +47,4 @@ where(field: 'key', condition: Condition): QueryBuilder;

}
export type FilterPredicate = BetweenClause | BeginsWithClause | ExistsClause | DoesNotExistClause | GreaterThanClause | GreaterThanEqualToClause | LessThanClause | LessThanEqualToClause | ContainsClause | DoesNotContainClause | EqualToClause | IsNotEqualToClause;
export type WherePredicate = BetweenClause | BeginsWithClause | EqualToClause | GreaterThanClause | GreaterThanEqualToClause | LessThanClause | LessThanEqualToClause;
export declare type FilterPredicate = BetweenClause | BeginsWithClause | ExistsClause | DoesNotExistClause | GreaterThanClause | GreaterThanEqualToClause | LessThanClause | LessThanEqualToClause | ContainsClause | DoesNotContainClause | EqualToClause | IsNotEqualToClause;
export declare type WherePredicate = BetweenClause | BeginsWithClause | EqualToClause | GreaterThanClause | GreaterThanEqualToClause | LessThanClause | LessThanEqualToClause;
export interface Result<T = object> {

@@ -45,2 +58,3 @@ key: string;

}
export {};
//# sourceMappingURL=storage-adapter.d.ts.map
{
"name": "@forge/storage",
"version": "1.5.13",
"version": "1.5.14-experimental-6adbba3",
"description": "Forge Storage methods",

@@ -19,5 +19,5 @@ "author": "Atlassian",

"@types/node": "14.18.63",
"@types/node-fetch": "^2.6.9",
"@types/node-fetch": "^2.6.10",
"node-fetch": "2.7.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

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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