@ftschopp/dynatable-core 1.2.1 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## @ftschopp/dynatable-core [1.2.2](https://github.com/ftschopp/dynatable/compare/@ftschopp/dynatable-core@1.2.1...@ftschopp/dynatable-core@1.2.2) (2026-04-15)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * add filter type scan entity ([dddff15](https://github.com/ftschopp/dynatable/commit/dddff15228f84fd11b0c6d2daa6f5cc8d77c641d))
7
+
1
8
  ## @ftschopp/dynatable-core [1.2.1](https://github.com/ftschopp/dynatable/compare/@ftschopp/dynatable-core@1.2.0...@ftschopp/dynatable-core@1.2.1) (2026-04-15)
2
9
 
3
10
 
@@ -1 +1 @@
1
- {"version":3,"file":"create-entity-api.d.ts","sourceRoot":"","sources":["../../src/entity/create-entity-api.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AActF,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAKtD;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,GAAI,KAAK,SAAS,eAAe,EAC3D,WAAW,MAAM,EACjB,WAAW,MAAM,EACjB,OAAO,KAAK,EACZ,QAAQ,cAAc,EACtB,UAAS,gBAAqB,KAC7B,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC,KAAK,CAAC,CA8KtE,CAAC"}
1
+ {"version":3,"file":"create-entity-api.d.ts","sourceRoot":"","sources":["../../src/entity/create-entity-api.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AActF,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAMtD;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,GAAI,KAAK,SAAS,eAAe,EAC3D,WAAW,MAAM,EACjB,WAAW,MAAM,EACjB,OAAO,KAAK,EACZ,QAAQ,cAAc,EACtB,UAAS,gBAAqB,KAC7B,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC,KAAK,CAAC,CAqLtE,CAAC"}
@@ -54,7 +54,13 @@ const createEntityAPI = (tableName, modelName, model, client, options = {}) => {
54
54
  return (0, builders_1.createQueryBuilder)(tableName, client, model, logger);
55
55
  },
56
56
  scan() {
57
- const builder = (0, builders_1.createScanBuilder)(tableName, client, [], [], undefined, false, undefined, undefined, undefined, logger);
57
+ // Auto-filter by entity type so scan only returns items for this entity
58
+ const typeFilter = {
59
+ expression: '#_type = :_type',
60
+ names: { '#_type': '_type' },
61
+ values: { ':_type': modelName },
62
+ };
63
+ const builder = (0, builders_1.createScanBuilder)(tableName, client, [typeFilter], [], undefined, false, undefined, undefined, undefined, logger);
58
64
  return (0, with_middleware_1.withMiddleware)(builder, (0, factories_1.createCleanKeysMiddleware)(cleanInternalKeys));
59
65
  },
60
66
  update(key) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ftschopp/dynatable-core",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "description": "Core library for DynamoDB single table design",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -18,6 +18,7 @@ import { EntityAPI, EntityAPIOptions } from './types';
18
18
  import { withMiddleware } from './middleware/with-middleware';
19
19
  import { createCleanKeysMiddleware } from './middleware/factories';
20
20
  import { validateKeyFields } from './validation/key-validation';
21
+ import { Condition } from '@/builders/shared/types';
21
22
 
22
23
  /**
23
24
  * Creates an entity API instance with validation, key resolution, and builder creation.
@@ -90,10 +91,17 @@ export const createEntityAPI = <Model extends ModelDefinition>(
90
91
  },
91
92
 
92
93
  scan() {
94
+ // Auto-filter by entity type so scan only returns items for this entity
95
+ const typeFilter: Condition = {
96
+ expression: '#_type = :_type',
97
+ names: { '#_type': '_type' },
98
+ values: { ':_type': modelName },
99
+ };
100
+
93
101
  const builder = createScanBuilder<InferModel<Model>>(
94
102
  tableName,
95
103
  client,
96
- [],
104
+ [typeFilter],
97
105
  [],
98
106
  undefined,
99
107
  false,
@@ -726,7 +726,9 @@ describe('Should test dbParams function builder', () => {
726
726
  const params = await table.entities.User.scan().dbParams();
727
727
 
728
728
  expect(params.TableName).toBe('InstagramClone');
729
- expect(params.FilterExpression).toBeUndefined();
729
+ expect(params.FilterExpression).toBe('#_type = :_type');
730
+ expect(params.ExpressionAttributeNames).toMatchObject({ '#_type': '_type' });
731
+ expect(params.ExpressionAttributeValues).toMatchObject({ ':_type': 'User' });
730
732
  });
731
733
 
732
734
  test('SCAN Users with filter', async () => {
@@ -736,10 +738,12 @@ describe('Should test dbParams function builder', () => {
736
738
 
737
739
  expect(params.TableName).toBe('InstagramClone');
738
740
  expect(params.FilterExpression).toMatch(/#followerCount > :followerCount_\d+/);
739
- expect(params.ExpressionAttributeNames).toEqual({
741
+ expect(params.ExpressionAttributeNames).toMatchObject({
740
742
  '#followerCount': 'followerCount',
743
+ '#_type': '_type',
741
744
  });
742
745
  expect(Object.values(params.ExpressionAttributeValues || {})).toContain(100);
746
+ expect(Object.values(params.ExpressionAttributeValues || {})).toContain('User');
743
747
  });
744
748
 
745
749
  test('SCAN Users with multiple filters', async () => {
@@ -751,9 +755,10 @@ describe('Should test dbParams function builder', () => {
751
755
  expect(params.FilterExpression).toMatch(
752
756
  /\(#followerCount > :followerCount_\d+\) AND \(#followingCount > :followingCount_\d+\)/
753
757
  );
754
- expect(params.ExpressionAttributeNames).toEqual({
758
+ expect(params.ExpressionAttributeNames).toMatchObject({
755
759
  '#followerCount': 'followerCount',
756
760
  '#followingCount': 'followingCount',
761
+ '#_type': '_type',
757
762
  });
758
763
  });
759
764
 
@@ -763,6 +768,8 @@ describe('Should test dbParams function builder', () => {
763
768
  .dbParams();
764
769
 
765
770
  expect(params.ProjectionExpression).toBe('username, photoId, likesCount');
771
+ expect(params.FilterExpression).toBe('#_type = :_type');
772
+ expect(params.ExpressionAttributeValues).toMatchObject({ ':_type': 'Photo' });
766
773
  });
767
774
 
768
775
  test('SCAN Photos with limit', async () => {
@@ -773,6 +780,8 @@ describe('Should test dbParams function builder', () => {
773
780
 
774
781
  expect(params.Limit).toBe(10);
775
782
  expect(params.FilterExpression).toMatch(/#likesCount > :likesCount_\d+/);
783
+ expect(params.FilterExpression).toMatch(/#_type = :_type/);
784
+ expect(params.ExpressionAttributeValues).toMatchObject({ ':_type': 'Photo' });
776
785
  });
777
786
 
778
787
  test('SCAN with IN operator', async () => {
@@ -781,9 +790,11 @@ describe('Should test dbParams function builder', () => {
781
790
  .dbParams();
782
791
 
783
792
  expect(params.FilterExpression).toContain('IN');
793
+ expect(params.FilterExpression).toMatch(/#_type = :_type/);
784
794
  expect(Object.values(params.ExpressionAttributeValues || {})).toContain('alice');
785
795
  expect(Object.values(params.ExpressionAttributeValues || {})).toContain('bob');
786
796
  expect(Object.values(params.ExpressionAttributeValues || {})).toContain('charlie');
797
+ expect(Object.values(params.ExpressionAttributeValues || {})).toContain('User');
787
798
  });
788
799
 
789
800
  test('SCAN with size operator', async () => {
@@ -792,7 +803,9 @@ describe('Should test dbParams function builder', () => {
792
803
  .dbParams();
793
804
 
794
805
  expect(params.FilterExpression).toMatch(/size\(#name\) > :name_size_\d+/);
806
+ expect(params.FilterExpression).toMatch(/#_type = :_type/);
795
807
  expect(Object.values(params.ExpressionAttributeValues || {})).toContain(5);
808
+ expect(Object.values(params.ExpressionAttributeValues || {})).toContain('User');
796
809
  });
797
810
 
798
811
  test('SCAN Comments with complex filter', async () => {
@@ -804,6 +817,8 @@ describe('Should test dbParams function builder', () => {
804
817
 
805
818
  expect(params.FilterExpression).toMatch(/attribute_exists\(#content\)/);
806
819
  expect(params.FilterExpression).toMatch(/size\(#content\) > :content_size_\d+/);
820
+ expect(params.FilterExpression).toMatch(/#_type = :_type/);
821
+ expect(params.ExpressionAttributeValues).toMatchObject({ ':_type': 'Comment' });
807
822
  expect(params.ProjectionExpression).toBe('photoId, commentId, content');
808
823
  expect(params.Limit).toBe(50);
809
824
  });