diff --git a/resources/buildConfigDefinitions.js b/resources/buildConfigDefinitions.js index f4813975f4..0b7dcdac3d 100644 --- a/resources/buildConfigDefinitions.js +++ b/resources/buildConfigDefinitions.js @@ -155,6 +155,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') { @@ -372,12 +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 }; diff --git a/spec/buildConfigDefinitions.spec.js b/spec/buildConfigDefinitions.spec.js new file mode 100644 index 0000000000..f0a8055860 --- /dev/null +++ b/spec/buildConfigDefinitions.spec.js @@ -0,0 +1,153 @@ +const t = require('@babel/types'); +const { mapperFor } = require('../resources/buildConfigDefinitions'); + +describe('buildConfigDefinitions', () => { + describe('mapperFor', () => { + 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'); + }); + }); +}); diff --git a/src/Options/Definitions.js b/src/Options/Definitions.js index 1ae9512823..013d2c80ec 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',