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.3.2 to 1.4.0-next.0

out/entity-storage/index.d.ts

6

CHANGELOG.md
# @forge/storage
## 1.4.0-next.0
### Minor Changes
- 85772008: Added capabilities for enabling Custom entities
## 1.3.2

@@ -4,0 +10,0 @@

220

out/__test__/global-storage.test.js

@@ -5,3 +5,3 @@ "use strict";

const global_storage_1 = require("../global-storage");
const queries_1 = require("../queries");
const gql_queries_1 = require("../gql-queries");
const contextAri = 'app-ari';

@@ -132,9 +132,2 @@ const getStorage = (apiClientMock) => new global_storage_1.GlobalStorage(() => contextAri, apiClientMock);

});
it('should throw an error if the storage API returns a non 200 status code', 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 if the response is not a valid JSON', async () => {

@@ -324,2 +317,207 @@ const apiClientMock = getApiClientMockInvalidJson('test', 200);

});
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);
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);
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
}
}
});
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);
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
}
}
}
});
const globalStorage = getStorage(apiClientMock);
await globalStorage.setEntity('testEntityName', 'testEntityKey', 'testValue');
verifyApiClientCalledWith(apiClientMock, {
input: {
contextAri,
entityName: 'testEntityName',
key: 'testEntityKey',
value: '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]
}
}
}
});
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
}
}
}
});
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'
}
});
});
});
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'
}
});
});
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'));
});
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', () => {

@@ -353,3 +551,3 @@ it('should call the storage API with the provided parameters', async () => {

limit
}, (0, queries_1.listQuery)(contextAri, {}).query);
}, gql_queries_1.UntypedQueries.listQuery(contextAri, {}).query);
expect(response).toEqual(expect.objectContaining({

@@ -391,3 +589,3 @@ results: [

limit
}, (0, queries_1.listQueryForCleanup)(contextAri, {}).query);
}, gql_queries_1.UntypedQueries.listQueryForCleanup(contextAri, {}).query);
expect(response).toEqual(expect.objectContaining({

@@ -417,3 +615,3 @@ results: [

limit: null
}, (0, queries_1.listQuery)(contextAri, {}).query);
}, gql_queries_1.UntypedQueries.listQuery(contextAri, {}).query);
});

@@ -420,0 +618,0 @@ it('should handle an empty result set', async () => {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const query_api_1 = require("../query-api");
const query_api_2 = require("../entity-storage/query-api");
const conditions_1 = require("../conditions");
const conditions_2 = require("../eap/conditions");
describe('DefaultQueryBuilder', () => {
const query_interfaces_1 = require("../query-interfaces");
describe('DefaultQueryBuilder Untyped entities', () => {
function newGlobalStorage() {

@@ -112,1 +114,538 @@ return {

});
describe('DefaultQueryBuilder CustomEntities', () => {
function newGlobalStorage() {
return {
listCustomEntities: jest.fn()
};
}
it('should only have "entity" as option for default base query builder', () => {
const globalStorage = newGlobalStorage();
const baseQueryBuilderInstance = new query_api_2.CustomEntityBuilder(globalStorage);
expect(baseQueryBuilderInstance).toHaveProperty('entity');
expect(baseQueryBuilderInstance).not.toHaveProperty('index');
expect(baseQueryBuilderInstance).not.toHaveProperty('where');
expect(baseQueryBuilderInstance).not.toHaveProperty('andFilter');
expect(baseQueryBuilderInstance).not.toHaveProperty('orFilter');
expect(baseQueryBuilderInstance).not.toHaveProperty('cursor');
expect(baseQueryBuilderInstance).not.toHaveProperty('limit');
expect(baseQueryBuilderInstance).not.toHaveProperty('getOne');
expect(baseQueryBuilderInstance).not.toHaveProperty('getMany');
expect(baseQueryBuilderInstance).not.toHaveProperty('sort');
});
it('should only have "index" as option once "entity" is initialized', () => {
const globalStorage = newGlobalStorage();
const baseQueryBuilderInstanceWithEntity = new query_api_2.CustomEntityBuilder(globalStorage).entity('books');
expect(baseQueryBuilderInstanceWithEntity).not.toHaveProperty('entity');
expect(baseQueryBuilderInstanceWithEntity).toHaveProperty('index');
expect(baseQueryBuilderInstanceWithEntity).not.toHaveProperty('where');
expect(baseQueryBuilderInstanceWithEntity).not.toHaveProperty('andFilter');
expect(baseQueryBuilderInstanceWithEntity).not.toHaveProperty('orFilter');
expect(baseQueryBuilderInstanceWithEntity).not.toHaveProperty('cursor');
expect(baseQueryBuilderInstanceWithEntity).not.toHaveProperty('limit');
expect(baseQueryBuilderInstanceWithEntity).not.toHaveProperty('getOne');
expect(baseQueryBuilderInstanceWithEntity).not.toHaveProperty('getMany');
expect(baseQueryBuilderInstanceWithEntity).not.toHaveProperty('sort');
});
it('should have "where", "andFilter", "orFilter", "cursor", "limit", "sort", "getOne", "getMany" as options once "index" is initialized', () => {
const globalStorage = newGlobalStorage();
const queryBuilderInstanceWithIndex = new query_api_2.CustomEntityBuilder(globalStorage).entity('books').index('by-key');
expect(queryBuilderInstanceWithIndex).not.toHaveProperty('entity');
expect(queryBuilderInstanceWithIndex).not.toHaveProperty('index');
expect(queryBuilderInstanceWithIndex).toHaveProperty('where');
expect(queryBuilderInstanceWithIndex).toHaveProperty('andFilter');
expect(queryBuilderInstanceWithIndex).toHaveProperty('orFilter');
expect(queryBuilderInstanceWithIndex).toHaveProperty('cursor');
expect(queryBuilderInstanceWithIndex).toHaveProperty('limit');
expect(queryBuilderInstanceWithIndex).toHaveProperty('sort');
expect(queryBuilderInstanceWithIndex).toHaveProperty('getOne');
expect(queryBuilderInstanceWithIndex).toHaveProperty('getMany');
});
it('should not have "orFilter" once "andFilter" is used', () => {
const globalStorage = newGlobalStorage();
const queryBuilderInstanceWithAndFilter = new query_api_2.CustomEntityBuilder(globalStorage)
.entity('books')
.index('by-key')
.andFilter('first_name', conditions_2.FilterConditions.beginsWith('John'));
expect(queryBuilderInstanceWithAndFilter).not.toHaveProperty('entity');
expect(queryBuilderInstanceWithAndFilter).not.toHaveProperty('index');
expect(queryBuilderInstanceWithAndFilter).not.toHaveProperty('orFilter');
expect(queryBuilderInstanceWithAndFilter).toHaveProperty('where');
expect(queryBuilderInstanceWithAndFilter).toHaveProperty('andFilter');
expect(queryBuilderInstanceWithAndFilter).toHaveProperty('cursor');
expect(queryBuilderInstanceWithAndFilter).toHaveProperty('limit');
expect(queryBuilderInstanceWithAndFilter).toHaveProperty('sort');
expect(queryBuilderInstanceWithAndFilter).toHaveProperty('getOne');
expect(queryBuilderInstanceWithAndFilter).toHaveProperty('getMany');
});
it('should not have "andFilter" once "orFilter" is used', () => {
const globalStorage = newGlobalStorage();
const queryBuilderInstanceWithOrFilter = new query_api_2.CustomEntityBuilder(globalStorage)
.entity('books')
.index('by-key')
.orFilter('first_name', conditions_2.FilterConditions.beginsWith('John'));
expect(queryBuilderInstanceWithOrFilter).not.toHaveProperty('entity');
expect(queryBuilderInstanceWithOrFilter).not.toHaveProperty('index');
expect(queryBuilderInstanceWithOrFilter).not.toHaveProperty('andFilter');
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('where');
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('orFilter');
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('cursor');
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('limit');
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('sort');
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('getOne');
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('getMany');
});
it('should be able to call "where", "cursor", "limit", "getOne", "getMany" after chaining multiple "orFilter"', async () => {
const globalStorage = newGlobalStorage();
const queryBuilderInstanceWithOrFilter = new query_api_2.CustomEntityBuilder(globalStorage)
.entity('books')
.index('by-rating-and-year', {
partition: [2019, 'John']
})
.orFilter('author', conditions_2.FilterConditions.contains('Doyle'))
.orFilter('genre', conditions_2.FilterConditions.equalsTo('horror'))
.where(conditions_2.WhereConditions.beginsWith('harry'))
.cursor('DUMMY_CURSOR_1234')
.limit(10)
.sort(query_interfaces_1.SortOrder.DESC);
expect(queryBuilderInstanceWithOrFilter).not.toHaveProperty('entity');
expect(queryBuilderInstanceWithOrFilter).not.toHaveProperty('index');
expect(queryBuilderInstanceWithOrFilter).not.toHaveProperty('andFilter');
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('where');
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('orFilter');
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('cursor');
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('limit');
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('sort');
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('getOne');
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('getMany');
await queryBuilderInstanceWithOrFilter.getMany();
expect(globalStorage.listCustomEntities).toHaveBeenCalledWith(expect.objectContaining({
sort: query_interfaces_1.SortOrder.DESC,
entityName: 'books',
indexName: 'by-rating-and-year',
partition: [2019, 'John'],
filterOperator: 'or',
range: {
condition: 'BEGINS_WITH',
values: ['harry']
},
filters: [
{
property: 'author',
condition: 'CONTAINS',
values: ['Doyle']
},
{
property: 'genre',
condition: 'EQUAL_TO',
values: ['horror']
}
],
limit: 10,
cursor: 'DUMMY_CURSOR_1234'
}));
});
it('should be able to call "where", "cursor", "limit", "getOne", "getMany" after chaining multiple "andFilter"', async () => {
const globalStorage = newGlobalStorage();
const queryBuilderInstanceWithOrFilter = new query_api_2.CustomEntityBuilder(globalStorage)
.entity('books')
.index('by-rating-and-year', {
partition: [2019, 'John']
})
.andFilter('author', conditions_2.FilterConditions.contains('Doyle'))
.andFilter('genre', conditions_2.FilterConditions.equalsTo('horror'))
.where(conditions_2.WhereConditions.beginsWith('harry'))
.cursor('DUMMY_CURSOR_1234')
.limit(10)
.sort(query_interfaces_1.SortOrder.DESC);
expect(queryBuilderInstanceWithOrFilter).not.toHaveProperty('entity');
expect(queryBuilderInstanceWithOrFilter).not.toHaveProperty('index');
expect(queryBuilderInstanceWithOrFilter).not.toHaveProperty('orFilter');
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('where');
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('andFilter');
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('cursor');
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('limit');
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('sort');
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('getOne');
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('getMany');
await queryBuilderInstanceWithOrFilter.getMany();
expect(globalStorage.listCustomEntities).toHaveBeenCalledWith(expect.objectContaining({
sort: query_interfaces_1.SortOrder.DESC,
entityName: 'books',
indexName: 'by-rating-and-year',
partition: [2019, 'John'],
filterOperator: 'and',
range: {
condition: 'BEGINS_WITH',
values: ['harry']
},
filters: [
{
property: 'author',
condition: 'CONTAINS',
values: ['Doyle']
},
{
property: 'genre',
condition: 'EQUAL_TO',
values: ['horror']
}
],
limit: 10,
cursor: 'DUMMY_CURSOR_1234'
}));
});
it('should pass when BETWEEN filter and range are passed', async () => {
const globalStorage = newGlobalStorage();
await new query_api_2.CustomEntityBuilder(globalStorage)
.entity('books')
.index('by-author')
.where(conditions_2.WhereConditions.between([1, 2]))
.andFilter('author', conditions_2.FilterConditions.between([3, 4]))
.getMany();
expect(globalStorage.listCustomEntities).toHaveBeenCalledWith(expect.objectContaining({
entityName: 'books',
indexName: 'by-author',
filterOperator: 'and',
range: {
condition: 'BETWEEN',
values: [1, 2]
},
filters: [
{
property: 'author',
condition: 'BETWEEN',
values: [3, 4]
}
]
}));
});
it('should pass when BEGINS_WITH filter and range are passed', async () => {
const globalStorage = newGlobalStorage();
await new query_api_2.CustomEntityBuilder(globalStorage)
.entity('books')
.index('by-author')
.where(conditions_2.WhereConditions.beginsWith(1))
.andFilter('author', conditions_2.FilterConditions.beginsWith(2))
.getMany();
expect(globalStorage.listCustomEntities).toHaveBeenCalledWith(expect.objectContaining({
entityName: 'books',
indexName: 'by-author',
filterOperator: 'and',
range: {
condition: 'BEGINS_WITH',
values: [1]
},
filters: [
{
property: 'author',
condition: 'BEGINS_WITH',
values: [2]
}
]
}));
});
it('should pass when EXISTS filter is passed', async () => {
const globalStorage = newGlobalStorage();
await new query_api_2.CustomEntityBuilder(globalStorage)
.entity('books')
.index('by-rating')
.andFilter('rating', conditions_2.FilterConditions.exists())
.getMany();
expect(globalStorage.listCustomEntities).toHaveBeenCalledWith(expect.objectContaining({
entityName: 'books',
indexName: 'by-rating',
filterOperator: 'and',
filters: [
{
property: 'rating',
condition: 'EXISTS',
values: [true]
}
]
}));
});
it('should pass when DOES_NOT_EXIST filter is passed', async () => {
const globalStorage = newGlobalStorage();
await new query_api_2.CustomEntityBuilder(globalStorage)
.entity('books')
.index('by-rating')
.andFilter('rating', conditions_2.FilterConditions.doesNotExist())
.getMany();
expect(globalStorage.listCustomEntities).toHaveBeenCalledWith(expect.objectContaining({
entityName: 'books',
indexName: 'by-rating',
filterOperator: 'and',
filters: [
{
property: 'rating',
condition: 'NOT_EXISTS',
values: [true]
}
]
}));
});
it('should pass when GREATER_THAN filter is passed', async () => {
const globalStorage = newGlobalStorage();
await new query_api_2.CustomEntityBuilder(globalStorage)
.entity('books')
.index('by-author')
.where(conditions_2.WhereConditions.isGreaterThan(1))
.andFilter('rating', conditions_2.FilterConditions.isGreaterThan(1))
.getMany();
expect(globalStorage.listCustomEntities).toHaveBeenCalledWith(expect.objectContaining({
entityName: 'books',
indexName: 'by-author',
range: {
condition: 'GREATER_THAN',
values: [1]
},
filterOperator: 'and',
filters: [
{
property: 'rating',
condition: 'GREATER_THAN',
values: [1]
}
]
}));
});
it('should pass when GREATER_THAN_EQUAL_TO filter is passed', async () => {
const globalStorage = newGlobalStorage();
await new query_api_2.CustomEntityBuilder(globalStorage)
.entity('books')
.index('by-author')
.where(conditions_2.WhereConditions.isGreaterThanEqualTo(1))
.andFilter('rating', conditions_2.FilterConditions.isGreaterThanEqualTo(1))
.getMany();
expect(globalStorage.listCustomEntities).toHaveBeenCalledWith(expect.objectContaining({
entityName: 'books',
indexName: 'by-author',
range: {
condition: 'GREATER_THAN_EQUAL_TO',
values: [1]
},
filterOperator: 'and',
filters: [
{
property: 'rating',
condition: 'GREATER_THAN_EQUAL_TO',
values: [1]
}
]
}));
});
it('should pass when LESS_THAN filter is passed', async () => {
const globalStorage = newGlobalStorage();
await new query_api_2.CustomEntityBuilder(globalStorage)
.entity('books')
.index('by-author')
.where(conditions_2.WhereConditions.isLessThan(1))
.andFilter('rating', conditions_2.FilterConditions.isLessThan(1))
.getMany();
expect(globalStorage.listCustomEntities).toHaveBeenCalledWith(expect.objectContaining({
entityName: 'books',
indexName: 'by-author',
range: {
condition: 'LESS_THAN',
values: [1]
},
filterOperator: 'and',
filters: [
{
property: 'rating',
condition: 'LESS_THAN',
values: [1]
}
]
}));
});
it('should pass when LESS_THAN_EQUAL_TO filter is passed', async () => {
const globalStorage = newGlobalStorage();
await new query_api_2.CustomEntityBuilder(globalStorage)
.entity('books')
.index('by-author')
.where(conditions_2.WhereConditions.isLessThanEqualTo(1))
.andFilter('rating', conditions_2.FilterConditions.isLessThanEqualTo(1))
.getMany();
expect(globalStorage.listCustomEntities).toHaveBeenCalledWith(expect.objectContaining({
entityName: 'books',
indexName: 'by-author',
range: {
condition: 'LESS_THAN_EQUAL_TO',
values: [1]
},
filterOperator: 'and',
filters: [
{
property: 'rating',
condition: 'LESS_THAN_EQUAL_TO',
values: [1]
}
]
}));
});
it('should pass when CONTAINS filter is passed', async () => {
const globalStorage = newGlobalStorage();
await new query_api_2.CustomEntityBuilder(globalStorage)
.entity('books')
.index('by-author')
.andFilter('rating', conditions_2.FilterConditions.contains('Conan'))
.getMany();
expect(globalStorage.listCustomEntities).toHaveBeenCalledWith(expect.objectContaining({
entityName: 'books',
indexName: 'by-author',
filterOperator: 'and',
filters: [
{
property: 'rating',
condition: 'CONTAINS',
values: ['Conan']
}
]
}));
});
it('should pass when NOT_CONTAINS filter is passed', async () => {
const globalStorage = newGlobalStorage();
await new query_api_2.CustomEntityBuilder(globalStorage)
.entity('books')
.index('by-author')
.andFilter('rating', conditions_2.FilterConditions.doesNotContain('Conan'))
.getMany();
expect(globalStorage.listCustomEntities).toHaveBeenCalledWith(expect.objectContaining({
entityName: 'books',
indexName: 'by-author',
filterOperator: 'and',
filters: [
{
property: 'rating',
condition: 'NOT_CONTAINS',
values: ['Conan']
}
]
}));
});
it('should pass when EQUAL_TO filter is passed', async () => {
const globalStorage = newGlobalStorage();
await new query_api_2.CustomEntityBuilder(globalStorage)
.entity('books')
.index('by-author')
.andFilter('rating', conditions_2.FilterConditions.equalsTo('Conan'))
.getMany();
expect(globalStorage.listCustomEntities).toHaveBeenCalledWith(expect.objectContaining({
entityName: 'books',
indexName: 'by-author',
filterOperator: 'and',
filters: [
{
property: 'rating',
condition: 'EQUAL_TO',
values: ['Conan']
}
]
}));
});
it('should pass when NOT_EQUAL_TO filter is passed', async () => {
const globalStorage = newGlobalStorage();
await new query_api_2.CustomEntityBuilder(globalStorage)
.entity('books')
.index('by-author')
.andFilter('rating', conditions_2.FilterConditions.notEqualsTo('Conan'))
.getMany();
expect(globalStorage.listCustomEntities).toHaveBeenCalledWith(expect.objectContaining({
entityName: 'books',
indexName: 'by-author',
filterOperator: 'and',
filters: [
{
property: 'rating',
condition: 'NOT_EQUAL_TO',
values: ['Conan']
}
]
}));
});
it('should pass when filter operator is passed', async () => {
const globalStorage = newGlobalStorage();
await new query_api_2.CustomEntityBuilder(globalStorage)
.entity('books')
.index('by-author')
.where(conditions_2.WhereConditions.between([1, 2]))
.orFilter('author', conditions_2.FilterConditions.between([3, 4]))
.getMany();
expect(globalStorage.listCustomEntities).toHaveBeenCalledWith(expect.objectContaining({
entityName: 'books',
indexName: 'by-author',
filterOperator: 'or',
range: {
condition: 'BETWEEN',
values: [1, 2]
},
filters: [
{
property: 'author',
condition: 'BETWEEN',
values: [3, 4]
}
]
}));
});
it('should pass when ASC sort is passed', async () => {
const globalStorage = newGlobalStorage();
await new query_api_2.CustomEntityBuilder(globalStorage)
.entity('books')
.index('by-rating-and-year', {
partition: [2019]
})
.where(conditions_2.WhereConditions.between([1, 2]))
.sort(query_interfaces_1.SortOrder.ASC)
.limit(10)
.cursor('DUMMY_CURSOR_1234')
.getMany();
expect(globalStorage.listCustomEntities).toHaveBeenCalledWith(expect.objectContaining({
sort: query_interfaces_1.SortOrder.ASC,
entityName: 'books',
indexName: 'by-rating-and-year',
partition: [2019],
range: {
condition: 'BETWEEN',
values: [1, 2]
},
limit: 10,
cursor: 'DUMMY_CURSOR_1234'
}));
});
it('should pass when All entity queries operator are passed', async () => {
const globalStorage = newGlobalStorage();
await new query_api_2.CustomEntityBuilder(globalStorage)
.entity('books')
.index('by-rating-and-year', {
partition: [2019, 'John']
})
.where(conditions_2.WhereConditions.between([1, 2]))
.sort(query_interfaces_1.SortOrder.DESC)
.orFilter('author', conditions_2.FilterConditions.contains('Doyle'))
.limit(10)
.cursor('DUMMY_CURSOR_1234')
.getMany();
expect(globalStorage.listCustomEntities).toHaveBeenCalledWith(expect.objectContaining({
sort: query_interfaces_1.SortOrder.DESC,
entityName: 'books',
indexName: 'by-rating-and-year',
partition: [2019, 'John'],
filterOperator: 'or',
range: {
condition: 'BETWEEN',
values: [1, 2]
},
filters: [
{
property: 'author',
condition: 'CONTAINS',
values: ['Doyle']
}
],
limit: 10,
cursor: 'DUMMY_CURSOR_1234'
}));
});
});

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

import { Predicate } from '../storage-adapter';
import { FilterPredicate, WherePredicate, Predicate } from '../storage-adapter';
export declare function isNotEqualTo(value: string[]): Predicate;
export declare function isIn(values: string[]): Predicate;
declare function beginsWith(value: string | number): WherePredicate;
declare function between(values: [string, string] | [number, number]): WherePredicate;
declare function exists(): FilterPredicate;
declare function doesNotExist(): FilterPredicate;
declare function isGreaterThan(value: string | number): WherePredicate;
declare function isGreaterThanEqualTo(value: string | number): WherePredicate;
declare function isLessThan(value: string | number): WherePredicate;
declare function isLessThanEqualTo(value: string | number): WherePredicate;
declare function contains(value: string): FilterPredicate;
declare function doesNotContain(value: string): FilterPredicate;
declare function equalsTo(value: number | string | boolean): WherePredicate;
declare function notEqualsTo(value: number | string | boolean): FilterPredicate;
export declare const WhereConditions: {
beginsWith: typeof beginsWith;
between: typeof between;
equalsTo: typeof equalsTo;
isGreaterThan: typeof isGreaterThan;
isGreaterThanEqualTo: typeof isGreaterThanEqualTo;
isLessThan: typeof isLessThan;
isLessThanEqualTo: typeof isLessThanEqualTo;
};
export declare const FilterConditions: {
beginsWith: typeof beginsWith;
between: typeof between;
contains: typeof contains;
doesNotContain: typeof doesNotContain;
equalsTo: typeof equalsTo;
notEqualsTo: typeof notEqualsTo;
exists: typeof exists;
doesNotExist: typeof doesNotExist;
isGreaterThan: typeof isGreaterThan;
isGreaterThanEqualTo: typeof isGreaterThanEqualTo;
isLessThan: typeof isLessThan;
isLessThanEqualTo: typeof isLessThanEqualTo;
};
export {};
//# sourceMappingURL=conditions.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isIn = exports.isNotEqualTo = void 0;
exports.FilterConditions = exports.WhereConditions = exports.isIn = exports.isNotEqualTo = void 0;
function isNotEqualTo(value) {

@@ -18,1 +18,96 @@ return {

exports.isIn = isIn;
function beginsWith(value) {
return {
condition: 'BEGINS_WITH',
values: [value]
};
}
function between(values) {
return {
condition: 'BETWEEN',
values
};
}
function exists() {
return {
condition: 'EXISTS',
values: [true]
};
}
function doesNotExist() {
return {
condition: 'NOT_EXISTS',
values: [true]
};
}
function isGreaterThan(value) {
return {
condition: 'GREATER_THAN',
values: [value]
};
}
function isGreaterThanEqualTo(value) {
return {
condition: 'GREATER_THAN_EQUAL_TO',
values: [value]
};
}
function isLessThan(value) {
return {
condition: 'LESS_THAN',
values: [value]
};
}
function isLessThanEqualTo(value) {
return {
condition: 'LESS_THAN_EQUAL_TO',
values: [value]
};
}
function contains(value) {
return {
condition: 'CONTAINS',
values: [value]
};
}
function doesNotContain(value) {
return {
condition: 'NOT_CONTAINS',
values: [value]
};
}
function equalsTo(value) {
return {
condition: 'EQUAL_TO',
values: [value]
};
}
function notEqualsTo(value) {
return {
condition: 'NOT_EQUAL_TO',
values: [value]
};
}
exports.WhereConditions = {
beginsWith,
between,
equalsTo,
isGreaterThan,
isGreaterThanEqualTo,
isLessThan,
isLessThanEqualTo
};
exports.FilterConditions = {
beginsWith,
between,
contains,
doesNotContain,
equalsTo,
notEqualsTo,
exists,
doesNotExist,
isGreaterThan,
isGreaterThanEqualTo,
isLessThan,
isLessThanEqualTo
};

11

out/global-storage.d.ts
import { FetchMethod } from './index';
import { ListOptions } from './queries';
import { StorageAdapter } from './storage-adapter';
import { CustomEntityListOptions, ListOptions } from './query-interfaces';
import { SharedStorageAdapter } from './storage-adapter';
interface ListResults {

@@ -11,3 +11,3 @@ results: {

}
export declare class GlobalStorage implements StorageAdapter {
export declare class GlobalStorage implements SharedStorageAdapter {
private getAppContextAri;

@@ -21,2 +21,3 @@ private apiClient;

list(options: ListOptions): Promise<ListResults>;
listCustomEntities(options: CustomEntityListOptions): Promise<ListResults>;
set(key: string, value: any): Promise<void>;

@@ -26,3 +27,7 @@ setSecret(key: string, value: any): Promise<void>;

deleteSecret(key: string): Promise<void>;
getEntity<T>(entityName: string, entityKey: string): Promise<T>;
setEntity<T>(entityName: string, entityKey: string, value: T): Promise<void>;
deleteEntity(entityName: string, entityKey: string): Promise<void>;
private getInternal;
private getEntityInternal;
private buildRequest;

@@ -29,0 +34,0 @@ private query;

@@ -5,3 +5,3 @@ "use strict";

const errors_1 = require("./errors");
const queries_1 = require("./queries");
const gql_queries_1 = require("./gql-queries");
function assertNoErrors(errors) {

@@ -45,4 +45,4 @@ if (errors && errors.length > 0) {

const requestBody = process.env.IS_CLEANUP_FUNCTION === 'true'
? (0, queries_1.listQueryForCleanup)(this.doGetAppContextAri(), options)
: (0, queries_1.listQuery)(this.doGetAppContextAri(), options);
? gql_queries_1.UntypedQueries.listQueryForCleanup(this.doGetAppContextAri(), options)
: gql_queries_1.UntypedQueries.listQuery(this.doGetAppContextAri(), options);
const response = await this.query(requestBody);

@@ -59,23 +59,51 @@ const edges = process.env.IS_CLEANUP_FUNCTION === 'true'

}
async listCustomEntities(options) {
var _a;
const requestBody = gql_queries_1.CustomEntityQueries.listQuery(this.doGetAppContextAri(), options);
const response = await this.query(requestBody);
const edges = response.appStoredCustomEntities.edges;
const nextCursor = (_a = edges === null || edges === void 0 ? void 0 : edges[edges.length - 1]) === null || _a === void 0 ? void 0 : _a.cursor;
const results = edges.map(({ node }) => node);
return {
results,
nextCursor
};
}
async set(key, value) {
const requestBody = (0, queries_1.setQuery)(this.doGetAppContextAri(), key, value, false);
await this.mutation(requestBody, 'setAppStoredEntity');
const requestBody = gql_queries_1.UntypedQueries.set(this.doGetAppContextAri(), key, value, false);
await this.mutation(requestBody, 'appStorage', 'setAppStoredEntity');
}
async setSecret(key, value) {
const requestBody = (0, queries_1.setQuery)(this.doGetAppContextAri(), key, value, true);
await this.mutation(requestBody, 'setAppStoredEntity');
const requestBody = gql_queries_1.UntypedQueries.set(this.doGetAppContextAri(), key, value, true);
await this.mutation(requestBody, 'appStorage', 'setAppStoredEntity');
}
async delete(key) {
const requestBody = (0, queries_1.deleteQuery)(this.doGetAppContextAri(), key, false);
await this.mutation(requestBody, 'deleteAppStoredEntity');
const requestBody = gql_queries_1.UntypedQueries.delete(this.doGetAppContextAri(), key, false);
await this.mutation(requestBody, 'appStorage', 'deleteAppStoredEntity');
}
async deleteSecret(key) {
const requestBody = (0, queries_1.deleteQuery)(this.doGetAppContextAri(), key, true);
await this.mutation(requestBody, 'deleteAppStoredEntity');
const requestBody = gql_queries_1.UntypedQueries.delete(this.doGetAppContextAri(), key, true);
await this.mutation(requestBody, 'appStorage', 'deleteAppStoredEntity');
}
async getEntity(entityName, entityKey) {
return this.getEntityInternal(entityName, entityKey);
}
async setEntity(entityName, entityKey, value) {
const requestBody = gql_queries_1.CustomEntityQueries.set(this.doGetAppContextAri(), entityName, entityKey, value);
await this.mutation(requestBody, 'appStorageCustomEntity', 'setAppStoredCustomEntity');
}
async deleteEntity(entityName, entityKey) {
const requestBody = gql_queries_1.CustomEntityQueries.delete(this.doGetAppContextAri(), entityName, entityKey);
await this.mutation(requestBody, 'appStorageCustomEntity', 'deleteAppStoredCustomEntity');
}
async getInternal(key, encrypted) {
const requestBody = (0, queries_1.getQuery)(this.doGetAppContextAri(), key, encrypted);
const requestBody = gql_queries_1.UntypedQueries.get(this.doGetAppContextAri(), key, encrypted);
const { appStoredEntity: { value } } = await this.query(requestBody);
return value !== null && value !== void 0 ? value : undefined;
}
async getEntityInternal(entityName, entityKey) {
const requestBody = gql_queries_1.CustomEntityQueries.get(this.doGetAppContextAri(), entityName, entityKey);
const { appStoredCustomEntity: { value } } = await this.query(requestBody);
return value !== null && value !== void 0 ? value : undefined;
}
buildRequest(requestBody) {

@@ -94,5 +122,5 @@ return {

}
async mutation(body, mutationMethod) {
async mutation(body, namespace, mutationMethod) {
const response = await this.apiClient(this.endpoint, this.buildRequest(body));
const { appStorage: { [mutationMethod]: { success, errors } } } = await getResponseBody(response);
const { [namespace]: { [mutationMethod]: { success, errors } } } = await getResponseBody(response);
assertNoErrors(errors);

@@ -99,0 +127,0 @@ if (!success) {

import { RequestInit, Response } from 'node-fetch';
import { EntityStorageBuilder } from './entity-storage';
import { GlobalStorage } from './global-storage';

@@ -14,7 +15,10 @@ import { DefaultQueryBuilder } from './query-api';

query: () => DefaultQueryBuilder;
entity: <T>(entityName: string) => EntityStorageBuilder<T>;
};
export { GlobalStorage } from './global-storage';
export { startsWith } from './conditions';
export { QueryBuilder, QueryApi, Condition, ListResult, Predicate, Result, Value } from './storage-adapter';
export { WhereConditions, FilterConditions } from './eap/conditions';
export { QueryBuilder, QueryApi, Condition, ListResult, Predicate, Result, EntityStorageApi, WherePredicate, FilterPredicate } from './storage-adapter';
export { Value } from './query-interfaces';
export { APIError } from './errors';
//# sourceMappingURL=index.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.APIError = exports.startsWith = exports.GlobalStorage = exports.getStorageInstanceWithQuery = void 0;
exports.APIError = exports.FilterConditions = exports.WhereConditions = exports.startsWith = exports.GlobalStorage = exports.getStorageInstanceWithQuery = void 0;
const entity_storage_1 = require("./entity-storage");
const query_api_1 = require("./query-api");

@@ -13,3 +14,4 @@ const getStorageInstanceWithQuery = (adapter) => {

deleteSecret: adapter.deleteSecret.bind(adapter),
query: () => new query_api_1.DefaultQueryBuilder(adapter)
query: () => new query_api_1.DefaultQueryBuilder(adapter),
entity: (entityName) => new entity_storage_1.EntityStorageBuilder(entityName, adapter)
};

@@ -22,3 +24,6 @@ };

Object.defineProperty(exports, "startsWith", { enumerable: true, get: function () { return conditions_1.startsWith; } });
var conditions_2 = require("./eap/conditions");
Object.defineProperty(exports, "WhereConditions", { enumerable: true, get: function () { return conditions_2.WhereConditions; } });
Object.defineProperty(exports, "FilterConditions", { enumerable: true, get: function () { return conditions_2.FilterConditions; } });
var errors_1 = require("./errors");
Object.defineProperty(exports, "APIError", { enumerable: true, get: function () { return errors_1.APIError; } });
import { GlobalStorage } from './global-storage';
import { ListOptions } from './queries';
import { ListOptions } from './query-interfaces';
import { QueryBuilder, Condition, Result, ListResult } from './storage-adapter';

@@ -4,0 +4,0 @@ export declare class DefaultQueryBuilder implements QueryBuilder {

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

import { EntityStorageBuilderType } from './entity-storage';
import { BeginsWithClause, BetweenClause, ExistsClause, DoesNotExistClause, FilterOperator, GreaterThanClause, GreaterThanEqualToClause, StartsWith, NotEqualTo, In, LessThanClause, LessThanEqualToClause, ContainsClause, DoesNotContainClause, IsNotEqualToClause, EqualToClause, SortOrder, CustomEntityQueryIndexOptions } from './query-interfaces';
export interface StorageAdapter {

@@ -9,18 +11,14 @@ get(key: string): Promise<any>;

}
export interface EntityStorageAdapter {
getEntity<T>(entityName: string, entityKey: string): Promise<T>;
setEntity<T>(entityName: string, entityKey: string, value: T): Promise<void>;
deleteEntity(entityName: string, entityKey: string): Promise<void>;
}
export interface EntityStorageApi {
entity<T>(entityKey: string): EntityStorageBuilderType<T>;
}
export declare type SharedStorageAdapter = StorageAdapter & EntityStorageAdapter;
export interface QueryApi {
query(): QueryBuilder;
}
export declare type Value = string;
export interface StartsWith {
condition: 'STARTS_WITH';
value: Value;
}
export interface NotEqualTo {
condition: 'NOT_EQUAL_TO';
value: Value[];
}
export interface In {
condition: 'IN';
value: Value[];
}
export declare type Predicate = StartsWith | NotEqualTo | In;

@@ -35,10 +33,23 @@ export declare type Condition = Predicate;

}
export interface Result {
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 CustomEntityQueryBuilder<T> {
index(indexName: string, indexOptions?: CustomEntityQueryIndexOptions): CustomEntityQueryBuilder<T>;
where(condition: WherePredicate): CustomEntityQueryBuilder<T>;
sort(sort: SortOrder): CustomEntityQueryBuilder<T>;
filters(property: string, condition: FilterPredicate): CustomEntityQueryBuilder<T>;
filterOperator(operator: FilterOperator): CustomEntityQueryBuilder<T>;
cursor(cursor: string): CustomEntityQueryBuilder<T>;
limit(limit: number): CustomEntityQueryBuilder<T>;
getMany(): Promise<ListResult<T>>;
getOne(): Promise<Result<T> | undefined>;
}
export interface Result<T = object> {
key: string;
value: object;
value: T;
}
export interface ListResult {
results: Result[];
export interface ListResult<T = object> {
results: Result<T>[];
nextCursor?: string;
}
//# sourceMappingURL=storage-adapter.d.ts.map
{
"name": "@forge/storage",
"version": "1.3.2",
"version": "1.4.0-next.0",
"description": "Forge Storage methods",

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

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