From 996205bc9ab508380cb639c6ac3b5108c1399478 Mon Sep 17 00:00:00 2001 From: Giacomo117 Date: Fri, 7 Nov 2025 19:51:22 +0000 Subject: [PATCH 1/7] fix: Add objectParser action for ParseServerOptions in Definitions.js --- resources/buildConfigDefinitions.js | 2 ++ src/Options/Definitions.js | 1 + 2 files changed, 3 insertions(+) diff --git a/resources/buildConfigDefinitions.js b/resources/buildConfigDefinitions.js index 5b9084f863..da9db8d480 100644 --- a/resources/buildConfigDefinitions.js +++ b/resources/buildConfigDefinitions.js @@ -153,6 +153,8 @@ function mapperFor(elt, t) { return wrap(t.identifier('objectParser')); } else if (t.isBooleanTypeAnnotation(elt)) { return wrap(t.identifier('booleanParser')); + } else if (t.isObjectTypeAnnotation(elt)) { + return wrap(t.identifier('objectParser')); } else if (t.isGenericTypeAnnotation(elt)) { const type = elt.typeAnnotation.id.name; if (type == 'Adapter') { diff --git a/src/Options/Definitions.js b/src/Options/Definitions.js index d5674eaf29..61f7391ecd 100644 --- a/src/Options/Definitions.js +++ b/src/Options/Definitions.js @@ -111,6 +111,7 @@ module.exports.ParseServerOptions = { env: 'PARSE_SERVER_AUTH_PROVIDERS', help: 'Configuration for your authentication providers, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#oauth-and-3rd-party-authentication', + action: parsers.objectParser, }, cacheAdapter: { env: 'PARSE_SERVER_CACHE_ADAPTER', From 69875a25699315fc05bb5d4aff918e87a18eba47 Mon Sep 17 00:00:00 2001 From: Giacomo117 Date: Wed, 12 Nov 2025 13:32:47 +0000 Subject: [PATCH 2/7] test: Add unit tests for mapperFor function in buildConfigDefinitions --- spec/buildConfigDefinitions.spec.js | 187 ++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 spec/buildConfigDefinitions.spec.js diff --git a/spec/buildConfigDefinitions.spec.js b/spec/buildConfigDefinitions.spec.js new file mode 100644 index 0000000000..6165c7136f --- /dev/null +++ b/spec/buildConfigDefinitions.spec.js @@ -0,0 +1,187 @@ +const t = require('@babel/types'); + +describe('buildConfigDefinitions', () => { + describe('mapperFor', () => { + // Recreate the mapperFor function for testing + function mapperFor(elt, t) { + const p = t.identifier('parsers'); + const wrap = identifier => t.memberExpression(p, identifier); + + if (t.isNumberTypeAnnotation(elt)) { + return t.callExpression(wrap(t.identifier('numberParser')), [t.stringLiteral(elt.name)]); + } else if (t.isArrayTypeAnnotation(elt)) { + return wrap(t.identifier('arrayParser')); + } else if (t.isAnyTypeAnnotation(elt)) { + return wrap(t.identifier('objectParser')); + } else if (t.isBooleanTypeAnnotation(elt)) { + return wrap(t.identifier('booleanParser')); + } else if (t.isObjectTypeAnnotation(elt)) { + return wrap(t.identifier('objectParser')); + } else if (t.isGenericTypeAnnotation(elt)) { + const type = elt.typeAnnotation.id.name; + if (type == 'Adapter') { + return wrap(t.identifier('moduleOrObjectParser')); + } + if (type == 'NumberOrBoolean') { + return wrap(t.identifier('numberOrBooleanParser')); + } + if (type == 'NumberOrString') { + return t.callExpression(wrap(t.identifier('numberOrStringParser')), [ + t.stringLiteral(elt.name), + ]); + } + if (type === 'StringOrStringArray') { + return wrap(t.identifier('arrayParser')); + } + return wrap(t.identifier('objectParser')); + } + } + + it('should return objectParser for ObjectTypeAnnotation', () => { + const mockElement = { + type: 'ObjectTypeAnnotation', + }; + + const result = mapperFor(mockElement, t); + + expect(t.isMemberExpression(result)).toBe(true); + expect(result.object.name).toBe('parsers'); + expect(result.property.name).toBe('objectParser'); + }); + + it('should return objectParser for AnyTypeAnnotation', () => { + const mockElement = { + type: 'AnyTypeAnnotation', + }; + + const result = mapperFor(mockElement, t); + + expect(t.isMemberExpression(result)).toBe(true); + expect(result.object.name).toBe('parsers'); + expect(result.property.name).toBe('objectParser'); + }); + + it('should return arrayParser for ArrayTypeAnnotation', () => { + const mockElement = { + type: 'ArrayTypeAnnotation', + }; + + const result = mapperFor(mockElement, t); + + expect(t.isMemberExpression(result)).toBe(true); + expect(result.object.name).toBe('parsers'); + expect(result.property.name).toBe('arrayParser'); + }); + + it('should return booleanParser for BooleanTypeAnnotation', () => { + const mockElement = { + type: 'BooleanTypeAnnotation', + }; + + const result = mapperFor(mockElement, t); + + expect(t.isMemberExpression(result)).toBe(true); + expect(result.object.name).toBe('parsers'); + expect(result.property.name).toBe('booleanParser'); + }); + + it('should return numberParser call expression for NumberTypeAnnotation', () => { + const mockElement = { + type: 'NumberTypeAnnotation', + name: 'testNumber', + }; + + const result = mapperFor(mockElement, t); + + expect(t.isCallExpression(result)).toBe(true); + expect(result.callee.property.name).toBe('numberParser'); + expect(result.arguments[0].value).toBe('testNumber'); + }); + + it('should return moduleOrObjectParser for Adapter GenericTypeAnnotation', () => { + const mockElement = { + type: 'GenericTypeAnnotation', + typeAnnotation: { + id: { + name: 'Adapter', + }, + }, + }; + + const result = mapperFor(mockElement, t); + + expect(t.isMemberExpression(result)).toBe(true); + expect(result.object.name).toBe('parsers'); + expect(result.property.name).toBe('moduleOrObjectParser'); + }); + + it('should return numberOrBooleanParser for NumberOrBoolean GenericTypeAnnotation', () => { + const mockElement = { + type: 'GenericTypeAnnotation', + typeAnnotation: { + id: { + name: 'NumberOrBoolean', + }, + }, + }; + + const result = mapperFor(mockElement, t); + + expect(t.isMemberExpression(result)).toBe(true); + expect(result.object.name).toBe('parsers'); + expect(result.property.name).toBe('numberOrBooleanParser'); + }); + + it('should return numberOrStringParser call expression for NumberOrString GenericTypeAnnotation', () => { + const mockElement = { + type: 'GenericTypeAnnotation', + name: 'testString', + typeAnnotation: { + id: { + name: 'NumberOrString', + }, + }, + }; + + const result = mapperFor(mockElement, t); + + expect(t.isCallExpression(result)).toBe(true); + expect(result.callee.property.name).toBe('numberOrStringParser'); + expect(result.arguments[0].value).toBe('testString'); + }); + + it('should return arrayParser for StringOrStringArray GenericTypeAnnotation', () => { + const mockElement = { + type: 'GenericTypeAnnotation', + typeAnnotation: { + id: { + name: 'StringOrStringArray', + }, + }, + }; + + const result = mapperFor(mockElement, t); + + expect(t.isMemberExpression(result)).toBe(true); + expect(result.object.name).toBe('parsers'); + expect(result.property.name).toBe('arrayParser'); + }); + + it('should return objectParser for unknown GenericTypeAnnotation', () => { + const mockElement = { + type: 'GenericTypeAnnotation', + typeAnnotation: { + id: { + name: 'UnknownType', + }, + }, + }; + + const result = mapperFor(mockElement, t); + + expect(t.isMemberExpression(result)).toBe(true); + expect(result.object.name).toBe('parsers'); + expect(result.property.name).toBe('objectParser'); + }); + }); +}); From 8224a93f96dc963d0df5c7c6cf3bcf2c8a107de3 Mon Sep 17 00:00:00 2001 From: Giacomo117 Date: Wed, 12 Nov 2025 13:45:13 +0000 Subject: [PATCH 3/7] feat: Export mapperFor function for testing purposes --- resources/buildConfigDefinitions.js | 3 +++ spec/buildConfigDefinitions.spec.js | 36 +---------------------------- 2 files changed, 4 insertions(+), 35 deletions(-) diff --git a/resources/buildConfigDefinitions.js b/resources/buildConfigDefinitions.js index 1f11b1639c..a10b0b8696 100644 --- a/resources/buildConfigDefinitions.js +++ b/resources/buildConfigDefinitions.js @@ -383,3 +383,6 @@ const res = babel.transformFileSync('./src/Options/index.js', { }); require('fs').writeFileSync('./src/Options/Definitions.js', res.code + '\n'); require('fs').writeFileSync('./src/Options/docs.js', docs); + +// Export mapperFor for testing +module.exports = { mapperFor }; diff --git a/spec/buildConfigDefinitions.spec.js b/spec/buildConfigDefinitions.spec.js index 6165c7136f..f0a8055860 100644 --- a/spec/buildConfigDefinitions.spec.js +++ b/spec/buildConfigDefinitions.spec.js @@ -1,42 +1,8 @@ const t = require('@babel/types'); +const { mapperFor } = require('../resources/buildConfigDefinitions'); describe('buildConfigDefinitions', () => { describe('mapperFor', () => { - // Recreate the mapperFor function for testing - function mapperFor(elt, t) { - const p = t.identifier('parsers'); - const wrap = identifier => t.memberExpression(p, identifier); - - if (t.isNumberTypeAnnotation(elt)) { - return t.callExpression(wrap(t.identifier('numberParser')), [t.stringLiteral(elt.name)]); - } else if (t.isArrayTypeAnnotation(elt)) { - return wrap(t.identifier('arrayParser')); - } else if (t.isAnyTypeAnnotation(elt)) { - return wrap(t.identifier('objectParser')); - } else if (t.isBooleanTypeAnnotation(elt)) { - return wrap(t.identifier('booleanParser')); - } else if (t.isObjectTypeAnnotation(elt)) { - return wrap(t.identifier('objectParser')); - } else if (t.isGenericTypeAnnotation(elt)) { - const type = elt.typeAnnotation.id.name; - if (type == 'Adapter') { - return wrap(t.identifier('moduleOrObjectParser')); - } - if (type == 'NumberOrBoolean') { - return wrap(t.identifier('numberOrBooleanParser')); - } - if (type == 'NumberOrString') { - return t.callExpression(wrap(t.identifier('numberOrStringParser')), [ - t.stringLiteral(elt.name), - ]); - } - if (type === 'StringOrStringArray') { - return wrap(t.identifier('arrayParser')); - } - return wrap(t.identifier('objectParser')); - } - } - it('should return objectParser for ObjectTypeAnnotation', () => { const mockElement = { type: 'ObjectTypeAnnotation', From 55e2001c5fcaa9ec1c40fad378ea3e07c28f5400 Mon Sep 17 00:00:00 2001 From: Giacomo117 Date: Wed, 19 Nov 2025 14:27:44 +0000 Subject: [PATCH 4/7] fix: Run transformation only when executed directly to prevent issues during tests --- resources/buildConfigDefinitions.js | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/resources/buildConfigDefinitions.js b/resources/buildConfigDefinitions.js index a10b0b8696..0b7dcdac3d 100644 --- a/resources/buildConfigDefinitions.js +++ b/resources/buildConfigDefinitions.js @@ -374,15 +374,18 @@ This code has been generated by resources/buildConfigDefinitions.js Do not edit manually, but update Options/index.js `; -const babel = require('@babel/core'); -const res = babel.transformFileSync('./src/Options/index.js', { - plugins: [plugin, '@babel/transform-flow-strip-types'], - babelrc: false, - auxiliaryCommentBefore, - sourceMaps: false, -}); -require('fs').writeFileSync('./src/Options/Definitions.js', res.code + '\n'); -require('fs').writeFileSync('./src/Options/docs.js', docs); +// Only run the transformation when executed directly, not when imported by tests +if (require.main === module) { + const babel = require('@babel/core'); + const res = babel.transformFileSync('./src/Options/index.js', { + plugins: [plugin, '@babel/transform-flow-strip-types'], + babelrc: false, + auxiliaryCommentBefore, + sourceMaps: false, + }); + require('fs').writeFileSync('./src/Options/Definitions.js', res.code + '\n'); + require('fs').writeFileSync('./src/Options/docs.js', docs); +} // Export mapperFor for testing module.exports = { mapperFor }; From cca3608fcdee0dde7604abdcc1c00fe18f781fb7 Mon Sep 17 00:00:00 2001 From: Giacomo117 Date: Wed, 19 Nov 2025 15:00:42 +0000 Subject: [PATCH 5/7] fix: Simplify GenericTypeAnnotation structure in mapperFor function and tests --- resources/buildConfigDefinitions.js | 2 +- spec/buildConfigDefinitions.spec.js | 30 ++++++++++------------------- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/resources/buildConfigDefinitions.js b/resources/buildConfigDefinitions.js index 0b7dcdac3d..bb059996d7 100644 --- a/resources/buildConfigDefinitions.js +++ b/resources/buildConfigDefinitions.js @@ -158,7 +158,7 @@ function mapperFor(elt, t) { } else if (t.isObjectTypeAnnotation(elt)) { return wrap(t.identifier('objectParser')); } else if (t.isGenericTypeAnnotation(elt)) { - const type = elt.typeAnnotation.id.name; + const type = elt.id.name; if (type == 'Adapter') { return wrap(t.identifier('moduleOrObjectParser')); } diff --git a/spec/buildConfigDefinitions.spec.js b/spec/buildConfigDefinitions.spec.js index f0a8055860..ab46b466c9 100644 --- a/spec/buildConfigDefinitions.spec.js +++ b/spec/buildConfigDefinitions.spec.js @@ -67,10 +67,8 @@ describe('buildConfigDefinitions', () => { it('should return moduleOrObjectParser for Adapter GenericTypeAnnotation', () => { const mockElement = { type: 'GenericTypeAnnotation', - typeAnnotation: { - id: { - name: 'Adapter', - }, + id: { + name: 'Adapter', }, }; @@ -84,10 +82,8 @@ describe('buildConfigDefinitions', () => { it('should return numberOrBooleanParser for NumberOrBoolean GenericTypeAnnotation', () => { const mockElement = { type: 'GenericTypeAnnotation', - typeAnnotation: { - id: { - name: 'NumberOrBoolean', - }, + id: { + name: 'NumberOrBoolean', }, }; @@ -102,10 +98,8 @@ describe('buildConfigDefinitions', () => { const mockElement = { type: 'GenericTypeAnnotation', name: 'testString', - typeAnnotation: { - id: { - name: 'NumberOrString', - }, + id: { + name: 'NumberOrString', }, }; @@ -119,10 +113,8 @@ describe('buildConfigDefinitions', () => { it('should return arrayParser for StringOrStringArray GenericTypeAnnotation', () => { const mockElement = { type: 'GenericTypeAnnotation', - typeAnnotation: { - id: { - name: 'StringOrStringArray', - }, + id: { + name: 'StringOrStringArray', }, }; @@ -136,10 +128,8 @@ describe('buildConfigDefinitions', () => { it('should return objectParser for unknown GenericTypeAnnotation', () => { const mockElement = { type: 'GenericTypeAnnotation', - typeAnnotation: { - id: { - name: 'UnknownType', - }, + id: { + name: 'UnknownType', }, }; From b35f5d53aa34539763da2110daba93b8bf1c4d24 Mon Sep 17 00:00:00 2001 From: Giacomo117 Date: Wed, 19 Nov 2025 15:19:33 +0000 Subject: [PATCH 6/7] fix: Correctly retrieve type name from GenericTypeAnnotation in mapperFor function --- resources/buildConfigDefinitions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/buildConfigDefinitions.js b/resources/buildConfigDefinitions.js index bb059996d7..0b7dcdac3d 100644 --- a/resources/buildConfigDefinitions.js +++ b/resources/buildConfigDefinitions.js @@ -158,7 +158,7 @@ function mapperFor(elt, t) { } else if (t.isObjectTypeAnnotation(elt)) { return wrap(t.identifier('objectParser')); } else if (t.isGenericTypeAnnotation(elt)) { - const type = elt.id.name; + const type = elt.typeAnnotation.id.name; if (type == 'Adapter') { return wrap(t.identifier('moduleOrObjectParser')); } From 8ea3f4cf0db859a8b5cc02bb96c94fb9e4b3b1c3 Mon Sep 17 00:00:00 2001 From: Giacomo117 Date: Wed, 19 Nov 2025 15:33:27 +0000 Subject: [PATCH 7/7] fix: Update GenericTypeAnnotation structure to use typeAnnotation for id --- spec/buildConfigDefinitions.spec.js | 30 +++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/spec/buildConfigDefinitions.spec.js b/spec/buildConfigDefinitions.spec.js index ab46b466c9..f0a8055860 100644 --- a/spec/buildConfigDefinitions.spec.js +++ b/spec/buildConfigDefinitions.spec.js @@ -67,8 +67,10 @@ describe('buildConfigDefinitions', () => { it('should return moduleOrObjectParser for Adapter GenericTypeAnnotation', () => { const mockElement = { type: 'GenericTypeAnnotation', - id: { - name: 'Adapter', + typeAnnotation: { + id: { + name: 'Adapter', + }, }, }; @@ -82,8 +84,10 @@ describe('buildConfigDefinitions', () => { it('should return numberOrBooleanParser for NumberOrBoolean GenericTypeAnnotation', () => { const mockElement = { type: 'GenericTypeAnnotation', - id: { - name: 'NumberOrBoolean', + typeAnnotation: { + id: { + name: 'NumberOrBoolean', + }, }, }; @@ -98,8 +102,10 @@ describe('buildConfigDefinitions', () => { const mockElement = { type: 'GenericTypeAnnotation', name: 'testString', - id: { - name: 'NumberOrString', + typeAnnotation: { + id: { + name: 'NumberOrString', + }, }, }; @@ -113,8 +119,10 @@ describe('buildConfigDefinitions', () => { it('should return arrayParser for StringOrStringArray GenericTypeAnnotation', () => { const mockElement = { type: 'GenericTypeAnnotation', - id: { - name: 'StringOrStringArray', + typeAnnotation: { + id: { + name: 'StringOrStringArray', + }, }, }; @@ -128,8 +136,10 @@ describe('buildConfigDefinitions', () => { it('should return objectParser for unknown GenericTypeAnnotation', () => { const mockElement = { type: 'GenericTypeAnnotation', - id: { - name: 'UnknownType', + typeAnnotation: { + id: { + name: 'UnknownType', + }, }, };