@forge/storage
Advanced tools
Comparing version 0.0.0-experimental-4e6084f to 0.0.0-experimental-6d39f4e
@@ -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'; | ||
@@ -29,2 +29,46 @@ const getStorage = (apiClientMock) => new global_storage_1.GlobalStorage(() => contextAri, apiClientMock); | ||
}; | ||
const inputSchemas = [ | ||
{ | ||
name: 'cars', | ||
attributes: { | ||
model: { type: 'string' }, | ||
make: { type: 'string' }, | ||
year: { type: 'float' } | ||
}, | ||
indexes: [ | ||
{ | ||
name: 'by-year', | ||
partition: ['year'], | ||
range: 'model' | ||
}, | ||
{ | ||
name: 'by-make', | ||
partition: ['make'], | ||
range: 'model' | ||
} | ||
] | ||
} | ||
]; | ||
const schemas = [ | ||
{ | ||
name: 'cars', | ||
attributes: { | ||
model: { type: 'string' }, | ||
make: { type: 'string' }, | ||
year: { type: 'float' } | ||
}, | ||
indexes: [ | ||
{ | ||
name: 'by-year', | ||
partition: ['year'], | ||
range: ['model'] | ||
}, | ||
{ | ||
name: 'by-make', | ||
partition: ['make'], | ||
range: ['model'] | ||
} | ||
] | ||
} | ||
]; | ||
describe('GlobalStorage', () => { | ||
@@ -61,3 +105,4 @@ function verifyApiClientCalledWith(apiClientMock, variables, query) { | ||
contextAri, | ||
key: 'testKey' | ||
key: 'testKey', | ||
encrypted: false | ||
}); | ||
@@ -78,3 +123,4 @@ expect(returnedValue).toEqual('testValue'); | ||
contextAri, | ||
key: 'testKey' | ||
key: 'testKey', | ||
encrypted: false | ||
}); | ||
@@ -95,3 +141,4 @@ expect(returnedValue).toEqual(undefined); | ||
contextAri, | ||
key: 'testKey' | ||
key: 'testKey', | ||
encrypted: false | ||
}); | ||
@@ -112,3 +159,4 @@ expect(returnedValue).toEqual(0); | ||
contextAri, | ||
key: 'testKey' | ||
key: 'testKey', | ||
encrypted: false | ||
}); | ||
@@ -133,9 +181,2 @@ expect(returnedValue).toEqual(''); | ||
}); | ||
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 () => { | ||
@@ -149,2 +190,21 @@ const apiClientMock = getApiClientMockInvalidJson('test', 200); | ||
}); | ||
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); | ||
const returnedValue = await globalStorage.getSecret('testKey'); | ||
verifyApiClientCalledWith(apiClientMock, { | ||
contextAri, | ||
key: 'testKey', | ||
encrypted: true | ||
}); | ||
expect(returnedValue).toEqual('testValue'); | ||
}); | ||
}); | ||
describe('set', () => { | ||
@@ -167,3 +227,4 @@ it('should call the storage API, passing the provided key and value', async () => { | ||
key: 'testKey', | ||
value: 'testValue' | ||
value: 'testValue', | ||
encrypted: false | ||
} | ||
@@ -211,3 +272,4 @@ }); | ||
key: 'testKey', | ||
value: 'testValue' | ||
value: 'testValue', | ||
encrypted: false | ||
} | ||
@@ -217,2 +279,25 @@ }); | ||
}); | ||
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); | ||
await globalStorage.setSecret('testKey', 'testValue'); | ||
verifyApiClientCalledWith(apiClientMock, { | ||
input: { | ||
contextAri, | ||
key: 'testKey', | ||
value: 'testValue', | ||
encrypted: true | ||
} | ||
}); | ||
}); | ||
}); | ||
describe('delete', () => { | ||
@@ -234,3 +319,4 @@ it('should call the storage API, passing the provided key', async () => { | ||
contextAri, | ||
key: 'testKey' | ||
key: 'testKey', | ||
encrypted: false | ||
} | ||
@@ -263,2 +349,229 @@ }); | ||
}); | ||
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); | ||
await globalStorage.deleteSecret('testKey'); | ||
verifyApiClientCalledWith(apiClientMock, { | ||
input: { | ||
contextAri, | ||
key: 'testKey', | ||
encrypted: true | ||
} | ||
}); | ||
}); | ||
}); | ||
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', () => { | ||
@@ -292,3 +605,3 @@ it('should call the storage API with the provided parameters', async () => { | ||
limit | ||
}, queries_1.listQuery(contextAri, {}).query); | ||
}, gql_queries_1.UntypedQueries.listQuery(contextAri, {}).query); | ||
expect(response).toEqual(expect.objectContaining({ | ||
@@ -330,3 +643,3 @@ results: [ | ||
limit | ||
}, queries_1.listQueryForCleanup(contextAri, {}).query); | ||
}, gql_queries_1.UntypedQueries.listQueryForCleanup(contextAri, {}).query); | ||
expect(response).toEqual(expect.objectContaining({ | ||
@@ -356,3 +669,3 @@ results: [ | ||
limit: null | ||
}, queries_1.listQuery(contextAri, {}).query); | ||
}, gql_queries_1.UntypedQueries.listQuery(contextAri, {}).query); | ||
}); | ||
@@ -398,2 +711,63 @@ it('should handle an empty result set', async () => { | ||
}); | ||
describe('upsertCustomEntity', () => { | ||
it('should call the storage API, passing the provided entities', async () => { | ||
const apiClientMock = getApiClientMock({ | ||
data: { | ||
customSchema: { | ||
createCustomSchemas: { | ||
success: true | ||
} | ||
} | ||
} | ||
}); | ||
const globalStorage = getStorage(apiClientMock); | ||
await globalStorage.upsertCustomEntities(inputSchemas); | ||
verifyApiClientCalledWith(apiClientMock, { | ||
input: { | ||
schemas | ||
} | ||
}); | ||
}); | ||
it('should throw an error if the storage API returns successful = false', async () => { | ||
const apiClientMock = getApiClientMock({ | ||
data: { | ||
customSchema: { | ||
createCustomSchemas: { | ||
success: false, | ||
errors: [INVALID_CURSOR_ERROR] | ||
} | ||
} | ||
} | ||
}); | ||
const globalStorage = getStorage(apiClientMock); | ||
const response = globalStorage.upsertCustomEntities(inputSchemas); | ||
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.upsertCustomEntities(inputSchemas); | ||
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: { | ||
customSchema: { | ||
createCustomSchemas: { | ||
success: false | ||
} | ||
} | ||
} | ||
}); | ||
const globalStorage = getStorage(apiClientMock); | ||
await expect(globalStorage.upsertCustomEntities(inputSchemas)).rejects.toThrow(errors_1.APIError.forStatus(500)); | ||
verifyApiClientCalledWith(apiClientMock, { | ||
input: { | ||
schemas | ||
} | ||
}); | ||
}); | ||
}); | ||
}); |
"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"); | ||
describe('DefaultQueryBuilder', () => { | ||
const conditions_2 = require("../eap/conditions"); | ||
const query_interfaces_1 = require("../query-interfaces"); | ||
describe('DefaultQueryBuilder Untyped entities', () => { | ||
function newGlobalStorage() { | ||
@@ -51,5 +54,44 @@ return { | ||
}); | ||
it('should allow specifying a "starts with" condition', async () => { | ||
const globalStorage = newGlobalStorage(); | ||
await new query_api_1.DefaultQueryBuilder(globalStorage).where('key', (0, conditions_1.startsWith)('test')).getMany(); | ||
expect(globalStorage.list).toHaveBeenCalledWith(expect.objectContaining({ | ||
where: [ | ||
{ | ||
field: 'key', | ||
condition: 'STARTS_WITH', | ||
value: 'test' | ||
} | ||
] | ||
})); | ||
}); | ||
it('should allow specifying a "not equal to" condition', async () => { | ||
const globalStorage = newGlobalStorage(); | ||
await new query_api_1.DefaultQueryBuilder(globalStorage).where('key', (0, conditions_2.isNotEqualTo)(['test', 'test2'])).getMany(); | ||
expect(globalStorage.list).toHaveBeenCalledWith(expect.objectContaining({ | ||
where: [ | ||
{ | ||
field: 'key', | ||
condition: 'NOT_EQUAL_TO', | ||
value: ['test', 'test2'] | ||
} | ||
] | ||
})); | ||
}); | ||
it('should allow specifying an "is in" condition', async () => { | ||
const globalStorage = newGlobalStorage(); | ||
await new query_api_1.DefaultQueryBuilder(globalStorage).where('key', (0, conditions_2.isIn)(['test', 'test2'])).getMany(); | ||
expect(globalStorage.list).toHaveBeenCalledWith(expect.objectContaining({ | ||
where: [ | ||
{ | ||
field: 'key', | ||
condition: 'IN', | ||
value: ['test', 'test2'] | ||
} | ||
] | ||
})); | ||
}); | ||
it('should allow specifying a condition', async () => { | ||
const globalStorage = newGlobalStorage(); | ||
await new query_api_1.DefaultQueryBuilder(globalStorage).where('key', conditions_1.startsWith('test')).getMany(); | ||
await new query_api_1.DefaultQueryBuilder(globalStorage).where('key', (0, conditions_1.startsWith)('test')).getMany(); | ||
expect(globalStorage.list).toHaveBeenCalledWith(expect.objectContaining({ | ||
@@ -73,1 +115,541 @@ where: [ | ||
}); | ||
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('partition'); | ||
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('sortOrder'); | ||
}); | ||
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('partition'); | ||
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('sortOrder'); | ||
}); | ||
it('should have "partition", "where", "andFilter", "orFilter", "cursor", "limit", "sortOrder", "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('partition'); | ||
expect(queryBuilderInstanceWithIndex).toHaveProperty('andFilter'); | ||
expect(queryBuilderInstanceWithIndex).toHaveProperty('orFilter'); | ||
expect(queryBuilderInstanceWithIndex).toHaveProperty('cursor'); | ||
expect(queryBuilderInstanceWithIndex).toHaveProperty('limit'); | ||
expect(queryBuilderInstanceWithIndex).toHaveProperty('sortOrder'); | ||
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('partition'); | ||
expect(queryBuilderInstanceWithAndFilter).toHaveProperty('andFilter'); | ||
expect(queryBuilderInstanceWithAndFilter).toHaveProperty('cursor'); | ||
expect(queryBuilderInstanceWithAndFilter).toHaveProperty('limit'); | ||
expect(queryBuilderInstanceWithAndFilter).toHaveProperty('sortOrder'); | ||
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('partition'); | ||
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('orFilter'); | ||
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('cursor'); | ||
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('limit'); | ||
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('sortOrder'); | ||
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('getOne'); | ||
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('getMany'); | ||
}); | ||
it('should be able to call "partition", "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') | ||
.orFilter('author', conditions_2.FilterConditions.contains('Doyle')) | ||
.orFilter('genre', conditions_2.FilterConditions.equalsTo('horror')) | ||
.partition([2019, 'John']) | ||
.where(conditions_2.WhereConditions.beginsWith('harry')) | ||
.cursor('DUMMY_CURSOR_1234') | ||
.limit(10) | ||
.sortOrder(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('partition'); | ||
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('orFilter'); | ||
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('cursor'); | ||
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('limit'); | ||
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('sortOrder'); | ||
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 "partition", "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') | ||
.andFilter('author', conditions_2.FilterConditions.contains('Doyle')) | ||
.andFilter('genre', conditions_2.FilterConditions.equalsTo('horror')) | ||
.partition([2019, 'John']) | ||
.where(conditions_2.WhereConditions.beginsWith('harry')) | ||
.cursor('DUMMY_CURSOR_1234') | ||
.limit(10) | ||
.sortOrder(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('partition'); | ||
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('andFilter'); | ||
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('cursor'); | ||
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('limit'); | ||
expect(queryBuilderInstanceWithOrFilter).toHaveProperty('sortOrder'); | ||
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])) | ||
.sortOrder(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])) | ||
.sortOrder(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' | ||
})); | ||
}); | ||
}); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.APIError = exports.getErrorMessage = exports.getErrorMessageFromCode = void 0; | ||
exports.getErrorMessageFromCode = (code, message) => { | ||
const getErrorMessageFromCode = (code, message) => { | ||
return message !== null && message !== void 0 ? message : code; | ||
}; | ||
exports.getErrorMessage = (statusCode) => { | ||
exports.getErrorMessageFromCode = getErrorMessageFromCode; | ||
const getErrorMessage = (statusCode) => { | ||
switch (statusCode) { | ||
@@ -25,2 +26,3 @@ case 400: | ||
}; | ||
exports.getErrorMessage = getErrorMessage; | ||
class APIError extends Error { | ||
@@ -31,6 +33,6 @@ constructor(message) { | ||
static forStatus(status) { | ||
return new APIError(exports.getErrorMessage(status)); | ||
return new APIError((0, exports.getErrorMessage)(status)); | ||
} | ||
static forErrorCode(code, message) { | ||
return new APIError(exports.getErrorMessageFromCode(code, message)); | ||
return new APIError((0, exports.getErrorMessageFromCode)(code, message)); | ||
} | ||
@@ -37,0 +39,0 @@ static forUnexpected(message) { |
import { FetchMethod } from './index'; | ||
import { ListOptions } from './queries'; | ||
import { StorageAdapter } from './storage-adapter'; | ||
import { CustomEntityListOptions, ListOptions, CustomEntityInput } 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; | ||
@@ -19,5 +19,16 @@ private apiClient; | ||
get(key: string): Promise<any>; | ||
getSecret(key: string): Promise<any>; | ||
list(options: ListOptions): Promise<ListResults>; | ||
listCustomEntities(options: CustomEntityListOptions): Promise<ListResults>; | ||
set(key: string, value: any): Promise<void>; | ||
setSecret(key: string, value: any): Promise<void>; | ||
delete(key: string): 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 getParsedIndex; | ||
upsertCustomEntities(schemas: CustomEntityInput[]): Promise<void>; | ||
private getInternal; | ||
private getEntityInternal; | ||
private buildRequest; | ||
@@ -24,0 +35,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) { | ||
@@ -38,10 +38,11 @@ if (errors && errors.length > 0) { | ||
async get(key) { | ||
const requestBody = queries_1.getQuery(this.doGetAppContextAri(), key); | ||
const { appStoredEntity: { value } } = await this.query(requestBody); | ||
return value !== null && value !== void 0 ? value : undefined; | ||
return this.getInternal(key, false); | ||
} | ||
async getSecret(key) { | ||
return this.getInternal(key, true); | ||
} | ||
async list(options) { | ||
const requestBody = process.env.IS_CLEANUP_FUNCTION === 'true' | ||
? queries_1.listQueryForCleanup(this.doGetAppContextAri(), options) | ||
: 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); | ||
@@ -58,10 +59,67 @@ const edges = process.env.IS_CLEANUP_FUNCTION === 'true' | ||
} | ||
async listCustomEntities(options) { | ||
const requestBody = gql_queries_1.CustomEntityQueries.listQuery(this.doGetAppContextAri(), options); | ||
const response = await this.query(requestBody); | ||
const edges = response.appStoredCustomEntities.edges; | ||
const nextCursor = edges.length > 0 ? edges[edges.length - 1].cursor : undefined; | ||
const results = edges.map(({ node }) => node); | ||
return { | ||
results, | ||
nextCursor | ||
}; | ||
} | ||
async set(key, value) { | ||
const requestBody = queries_1.setQuery(this.doGetAppContextAri(), key, value); | ||
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 = gql_queries_1.UntypedQueries.set(this.doGetAppContextAri(), key, value, true); | ||
await this.mutation(requestBody, 'appStorage', 'setAppStoredEntity'); | ||
} | ||
async delete(key) { | ||
const requestBody = queries_1.deleteQuery(this.doGetAppContextAri(), key); | ||
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 = 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'); | ||
} | ||
getParsedIndex(indexes) { | ||
return indexes | ||
? { | ||
indexes: indexes.map((index) => { | ||
return Object.assign(Object.assign({ name: index.name }, (index.partition ? { partition: index.partition } : {})), { range: [index.range] }); | ||
}) | ||
} | ||
: {}; | ||
} | ||
async upsertCustomEntities(schemas) { | ||
const convertedSchemas = schemas.map((schema) => { | ||
const modifiedSchema = Object.assign({ name: schema.name, attributes: schema.attributes }, this.getParsedIndex(schema.indexes)); | ||
return modifiedSchema; | ||
}); | ||
const requestBody = gql_queries_1.CustomEntityQueries.createSchema(convertedSchemas); | ||
await this.mutation(requestBody, 'customSchema', 'createCustomSchemas'); | ||
} | ||
async getInternal(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) { | ||
@@ -80,5 +138,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); | ||
@@ -85,0 +143,0 @@ if (!success) { |
import { RequestInit, Response } from 'node-fetch'; | ||
import { EntityStorageBuilder } from './entity-storage'; | ||
import { GlobalStorage } from './global-storage'; | ||
@@ -10,8 +11,15 @@ import { DefaultQueryBuilder } from './query-api'; | ||
delete: (key: string) => Promise<void>; | ||
getSecret: (key: string) => Promise<any>; | ||
setSecret: (key: string, value: any) => Promise<void>; | ||
deleteSecret: (key: string) => Promise<void>; | ||
query: () => DefaultQueryBuilder; | ||
entity: (entityName: string) => EntityStorageBuilder; | ||
upsertCustomEntities: (schemas: import("./query-interfaces").CustomEntityInput[]) => Promise<void>; | ||
}; | ||
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, CustomEntityInput } from './query-interfaces'; | ||
export { APIError } from './errors'; | ||
//# sourceMappingURL=index.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
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"); | ||
exports.getStorageInstanceWithQuery = (adapter) => { | ||
const getStorageInstanceWithQuery = (adapter) => { | ||
return { | ||
@@ -10,5 +11,11 @@ get: adapter.get.bind(adapter), | ||
delete: adapter.delete.bind(adapter), | ||
query: () => new query_api_1.DefaultQueryBuilder(adapter) | ||
getSecret: adapter.getSecret.bind(adapter), | ||
setSecret: adapter.setSecret.bind(adapter), | ||
deleteSecret: adapter.deleteSecret.bind(adapter), | ||
query: () => new query_api_1.DefaultQueryBuilder(adapter), | ||
entity: (entityName) => new entity_storage_1.EntityStorageBuilder(entityName, adapter), | ||
upsertCustomEntities: adapter.upsertCustomEntities.bind(adapter) | ||
}; | ||
}; | ||
exports.getStorageInstanceWithQuery = getStorageInstanceWithQuery; | ||
var global_storage_1 = require("./global-storage"); | ||
@@ -18,3 +25,6 @@ Object.defineProperty(exports, "GlobalStorage", { enumerable: true, get: function () { return global_storage_1.GlobalStorage; } }); | ||
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'; | ||
@@ -8,3 +8,3 @@ export declare class DefaultQueryBuilder implements QueryBuilder { | ||
constructor(globalStorage: Pick<GlobalStorage, 'list'>, queryOptions?: ListOptions); | ||
where(field: 'key', { condition, value }: Condition): QueryBuilder; | ||
where(field: 'key', where: Condition): QueryBuilder; | ||
cursor(cursor: string): QueryBuilder; | ||
@@ -11,0 +11,0 @@ limit(limit: number): QueryBuilder; |
@@ -9,9 +9,5 @@ "use strict"; | ||
} | ||
where(field, { condition, value }) { | ||
where(field, where) { | ||
return new DefaultQueryBuilder(this.globalStorage, Object.assign(Object.assign({}, this.queryOptions), { where: [ | ||
{ | ||
field, | ||
condition, | ||
value | ||
} | ||
Object.assign({ field }, where) | ||
] })); | ||
@@ -18,0 +14,0 @@ } |
@@ -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, CustomEntityPartitionValue, CustomEntityInput } from './query-interfaces'; | ||
export interface StorageAdapter { | ||
@@ -5,11 +7,20 @@ get(key: string): Promise<any>; | ||
delete(key: string): Promise<void>; | ||
getSecret(key: string): Promise<any>; | ||
setSecret(key: string, value: any): Promise<void>; | ||
deleteSecret(key: string): Promise<void>; | ||
upsertCustomEntities(schemas: CustomEntityInput[]): Promise<void>; | ||
} | ||
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(entityKey: string): EntityStorageBuilderType; | ||
} | ||
export declare type SharedStorageAdapter = StorageAdapter & EntityStorageAdapter; | ||
export interface QueryApi { | ||
query(): QueryBuilder; | ||
} | ||
export declare type Value = string; | ||
export interface Predicate { | ||
condition: 'STARTS_WITH'; | ||
value: Value; | ||
} | ||
export declare type Predicate = StartsWith | NotEqualTo | In; | ||
export declare type Condition = Predicate; | ||
@@ -23,2 +34,16 @@ export interface QueryBuilder { | ||
} | ||
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 { | ||
index(indexName: string): CustomEntityQueryBuilder; | ||
partition(partition: CustomEntityPartitionValue[]): CustomEntityQueryBuilder; | ||
where(condition: WherePredicate): CustomEntityQueryBuilder; | ||
sortOrder(sort: SortOrder): CustomEntityQueryBuilder; | ||
filters(property: string, condition: FilterPredicate): CustomEntityQueryBuilder; | ||
filterOperator(operator: FilterOperator): CustomEntityQueryBuilder; | ||
cursor(cursor: string): CustomEntityQueryBuilder; | ||
limit(limit: number): CustomEntityQueryBuilder; | ||
getMany(): Promise<ListResult>; | ||
getOne(): Promise<Result | undefined>; | ||
} | ||
export interface Result { | ||
@@ -25,0 +50,0 @@ key: string; |
{ | ||
"name": "@forge/storage", | ||
"version": "0.0.0-experimental-4e6084f", | ||
"version": "0.0.0-experimental-6d39f4e", | ||
"description": "Forge Storage methods", | ||
@@ -19,5 +19,5 @@ "author": "Atlassian", | ||
"@types/node": "^12.12.63", | ||
"node-fetch": "^2.6.1", | ||
"@types/node-fetch": "^2.5.7" | ||
"@types/node-fetch": "^2.5.7", | ||
"node-fetch": "2.6.7" | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
128295
50
2698
1