Skip to content

Commit a3a5b33

Browse files
committed
fix(datastore.ts): ensure entities with id based keys are correcly loaded from cache
All entities which have id based keys now return those ids and their paths as numbers. If you rely on the id being a string you will need to update your code. BREAKING CHANGE: Entity keys return ids as Number fix #243
1 parent 873d4e9 commit a3a5b33

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

__tests__/integration/cache.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const gstore = new Gstore({
2727
gstore.connect(ds);
2828

2929
const uniqueId = (): string => chance.string({ pool: 'abcdefghijklmnopqrstuvwxyz0123456789' });
30+
const uniqueNumericId = (): number => Number(`4${chance.string({ numeric: true, length: 15 })}`);
3031

3132
const cleanUp = (cb: any): void => {
3233
((ds.delete(allKeys) as unknown) as Promise<any>).then(cb);
@@ -101,8 +102,8 @@ describe('Integration Tests (Cache)', () => {
101102
});
102103

103104
test('should load already cached entities with correct datastore entity keys', async () => {
104-
const id1 = uniqueId();
105-
const id2 = uniqueId();
105+
const id1 = uniqueNumericId();
106+
const id2 = uniqueNumericId();
106107

107108
const user1 = new MyModel({ email: '[email protected]' }, id1);
108109
const user2 = new MyModel({ email: '[email protected]' }, id2);
@@ -115,12 +116,14 @@ describe('Integration Tests (Cache)', () => {
115116

116117
responseMultiple0.entities.forEach((entry) => {
117118
expect(ds.isKey(entry?.entityKey)).to.equal(true);
119+
expect(typeof entry?.entityKey.id).to.equal('number');
118120
});
119121

120122
const responseMultiple1 = await MyModel.list({ format: 'ENTITY', order: { property: 'email', descending: false } });
121123

122124
responseMultiple1.entities.forEach((entry) => {
123125
expect(ds.isKey(entry?.entityKey)).to.equal(true);
126+
expect(typeof entry?.entityKey.id).to.equal('number');
124127
});
125128
});
126129

src/serializers/datastore.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,25 @@ const fromDatastore = <F extends 'JSON' | 'ENTITY' = 'JSON', R = F extends 'ENTI
6060
options: { format?: F; readAll?: boolean; showKey?: boolean } = {},
6161
): R => {
6262
const getEntityKey = (): EntityKey => {
63-
const keyData = entityData[Model.gstore.ds.KEY as any];
64-
return Model.gstore.ds.isKey(keyData) ? (keyData as EntityKey) : Model.gstore.ds.key({ ...keyData });
63+
let keyData = entityData[Model.gstore.ds.KEY as any];
64+
// datastore can return id as a string however we need to ensure that the path
65+
// is correctly a number in order to return the correct entity key
66+
if (keyData.id && typeof keyData.id !== 'number') {
67+
const path = [...keyData.path];
68+
const id = Number(path.pop());
69+
// if id is still not a number then we ignore since it is either really a string or another non-number type
70+
if (!isNaN(id)) {
71+
keyData = {
72+
...keyData,
73+
id,
74+
path: [...path, Number(id)],
75+
};
76+
}
77+
}
78+
if (Model.gstore.ds.isKey(keyData)) {
79+
return keyData;
80+
}
81+
return Model.gstore.ds.key(keyData);
6582
};
6683

6784
const convertToJson = (): GenericObject => {

0 commit comments

Comments
 (0)