Repository: typedorm/typedorm (ts)

Issue:
Wrong level nesting with expressions using Logical operators
Generated expression are getting wrong level of nesting where it should be flat

i.e 
```Typescript
AND : {
x: '11',
y: '22',
z: '33
}
```

should have been transformed into 
(x = 11) AND (y=22) AND (z=33)

instead it is currently being transformed as 
((x = 11) AND (y = 22)) AND (z=33)

Pull request:
fix(core): wrong expression nesting with filter expressions
# Changes

- fixes expression evaluation order issue

closes #75 

Patch:
diff --git a/packages/core/src/classes/expression/base-expression-input.ts b/packages/core/src/classes/expression/base-expression-input.ts
index a559ce5..340a6ef 100644
--- a/packages/core/src/classes/expression/base-expression-input.ts
+++ b/packages/core/src/classes/expression/base-expression-input.ts
@@ -167,9 +167,38 @@ export abstract class BaseExpressionInput {
     inputs: T[],
     strategy: MERGE_STRATEGY
   ) {
-    inputs.forEach(input => {
-      this.merge(input, strategy);
+    // check if base expression has any value
+    if (this.expression) {
+      this.expression = `(${this.expression})`;
+      this.appendToExpression(strategy);
+    }
+
+    inputs.forEach((input, index) => {
+      this.appendToExpression(`(${input.expression})`);
+
+      if (index !== inputs.length - 1) {
+        this.appendToExpression(strategy);
+      }
+
+      Object.keys(input.names).forEach(nameKey => {
+        if (this.names[nameKey]) {
+          throw new Error(
+            `Failed to merge expression attribute names, there are multiple attributes names with key "${nameKey}"`
+          );
+        }
+      });
+      Object.keys(input.values).forEach(valueKey => {
+        if (this.names[valueKey]) {
+          throw new Error(
+            `Failed to merge expression attribute values, there are multiple attributes values with key "${valueKey}"`
+          );
+        }
+      });
+
+      this.names = {...this.names, ...input.names};
+      this.values = {...this.values, ...input.values};
     });
+
     return this;
   }
 


Test patch:
diff --git a/packages/core/src/classes/expression/__test__/base-expression-input.spec.ts b/packages/core/src/classes/expression/__test__/base-expression-input.spec.ts
index 43a6bbf..13900b8 100644
--- a/packages/core/src/classes/expression/__test__/base-expression-input.spec.ts
+++ b/packages/core/src/classes/expression/__test__/base-expression-input.spec.ts
@@ -185,7 +185,7 @@ test('merges conditions when merging condition is empty', () => {
  * @group mergeMany
  */
 
-test('merges many conditions', () => {
+test('merges many conditions with AND operator', () => {
   const merged = new TestCondition()
     .lessThan('age', 12)
     .mergeMany(
@@ -210,7 +210,36 @@ test('merges many conditions', () => {
       ':TC_status': 'active',
     },
     expression:
-      '(((#TC_age < :TC_age) AND (#TC_name = :TC_name)) AND (#TC_status = :TC_status)) AND (#TC_score > :TC_score)',
+      '(#TC_age < :TC_age) AND (#TC_name = :TC_name) AND (#TC_status = :TC_status) AND (#TC_score > :TC_score)',
+  });
+});
+
+test('merges many conditions with OR operator', () => {
+  const merged = new TestCondition()
+    .lessThan('age', 12)
+    .mergeMany(
+      [
+        new TestCondition().equals('name', 'sid'),
+        new TestCondition().equals('status', 'active'),
+        new TestCondition().greaterThan('score', 120),
+      ],
+      MERGE_STRATEGY.OR
+    );
+  expect(merged).toEqual({
+    _names: {
+      '#TC_age': 'age',
+      '#TC_name': 'name',
+      '#TC_score': 'score',
+      '#TC_status': 'status',
+    },
+    _values: {
+      ':TC_age': 12,
+      ':TC_name': 'sid',
+      ':TC_score': 120,
+      ':TC_status': 'active',
+    },
+    expression:
+      '(#TC_age < :TC_age) OR (#TC_name = :TC_name) OR (#TC_status = :TC_status) OR (#TC_score > :TC_score)',
   });
 });
 
diff --git a/packages/core/src/classes/manager/__test__/entity-manager.spec.ts b/packages/core/src/classes/manager/__test__/entity-manager.spec.ts
index 9872fe7..4caf8f1 100644
--- a/packages/core/src/classes/manager/__test__/entity-manager.spec.ts
+++ b/packages/core/src/classes/manager/__test__/entity-manager.spec.ts
@@ -665,7 +665,7 @@ test('finds items matching given query params and options', async () => {
     KeyConditionExpression:
       '(#KY_CE_PK = :KY_CE_PK) AND (begins_with(#KY_CE_SK, :KY_CE_SK))',
     FilterExpression:
-      '((#FE_age BETWEEN :FE_age_start AND :FE_age_end) AND (#FE_name = :FE_name)) AND (attribute_exists(#FE_status))',
+      '(#FE_age BETWEEN :FE_age_start AND :FE_age_end) AND (#FE_name = :FE_name) AND (attribute_exists(#FE_status))',
     Limit: 10,
     ScanIndexForward: true,
     TableName: 'test-table',