فهرست منبع

fix(core): Correctly handle negative "skip"/"take" in list query options

Michael Bromley 5 سال پیش
والد
کامیت
04a4c39e7c

+ 57 - 0
packages/core/e2e/list-query-builder.e2e-spec.ts

@@ -36,6 +36,63 @@ describe('ListQueryBuilder', () => {
         return items.map((x: any) => x.label).sort();
     }
 
+    describe('pagination', () => {
+        it('take', async () => {
+            const { testEntities } = await adminClient.query(GET_LIST, {
+                options: {
+                    take: 2,
+                },
+            });
+
+            expect(testEntities.totalItems).toBe(5);
+            expect(getItemLabels(testEntities.items)).toEqual(['A', 'B']);
+        });
+
+        it('skip', async () => {
+            const { testEntities } = await adminClient.query(GET_LIST, {
+                options: {
+                    skip: 2,
+                },
+            });
+
+            expect(testEntities.totalItems).toBe(5);
+            expect(getItemLabels(testEntities.items)).toEqual(['C', 'D', 'E']);
+        });
+
+        it('skip negative is ignored', async () => {
+            const { testEntities } = await adminClient.query(GET_LIST, {
+                options: {
+                    skip: -1,
+                },
+            });
+
+            expect(testEntities.totalItems).toBe(5);
+            expect(testEntities.items.length).toBe(5);
+        });
+
+        it('take zero is ignored', async () => {
+            const { testEntities } = await adminClient.query(GET_LIST, {
+                options: {
+                    take: 0,
+                },
+            });
+
+            expect(testEntities.totalItems).toBe(5);
+            expect(testEntities.items.length).toBe(5);
+        });
+
+        it('take negative is ignored', async () => {
+            const { testEntities } = await adminClient.query(GET_LIST, {
+                options: {
+                    take: -1,
+                },
+            });
+
+            expect(testEntities.totalItems).toBe(5);
+            expect(testEntities.items.length).toBe(5);
+        });
+    });
+
     describe('string filtering', () => {
         it('eq', async () => {
             const { testEntities } = await adminClient.query(GET_LIST, {

+ 2 - 2
packages/core/src/service/helpers/list-query-builder/list-query-builder.ts

@@ -45,9 +45,9 @@ export class ListQueryBuilder implements OnApplicationBootstrap {
         options: ListQueryOptions<T> = {},
         extendedOptions: ExtendedListQueryOptions<T> = {},
     ): SelectQueryBuilder<T> {
-        const skip = options.skip;
         const rawConnection = this.connection.rawConnection;
-        let take = options.take;
+        const skip = Math.max(options.skip ?? 0, 0);
+        let take = Math.max(options.take ?? 0, 0);
         if (options.skip !== undefined && options.take === undefined) {
             take = Number.MAX_SAFE_INTEGER;
         }