From dab15c1301be8ac56793a0d6a7e30f5e83a1bdad Mon Sep 17 00:00:00 2001 From: Daniel Date: Sun, 5 Jul 2026 00:38:29 +1000 Subject: [PATCH] fix: NumberOrBoolean config option (cluster) value not coerced from env/CLI --- resources/buildConfigDefinitions.js | 2 +- spec/CLI.spec.js | 12 ++++++++++-- spec/buildConfigDefinitions.spec.js | 9 +++++---- src/Options/Definitions.js | 2 +- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/resources/buildConfigDefinitions.js b/resources/buildConfigDefinitions.js index 1a3cbb4b55..d752735cb8 100644 --- a/resources/buildConfigDefinitions.js +++ b/resources/buildConfigDefinitions.js @@ -177,7 +177,7 @@ function mapperFor(elt, t) { return wrap(t.identifier('moduleOrObjectParser')); } if (type == 'NumberOrBoolean') { - return wrap(t.identifier('numberOrBooleanParser')); + return t.callExpression(wrap(t.identifier('numberOrBoolParser')), [t.stringLiteral(elt.name)]); } if (type == 'NumberOrString') { return t.callExpression(wrap(t.identifier('numberOrStringParser')), [t.stringLiteral(elt.name)]); diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index 39061b8083..ccddf5420d 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -178,7 +178,7 @@ describe('definitions', () => { if (typeof definition.required !== 'undefined') { expect(typeof definition.required).toBe('boolean'); } - if (typeof definition.action !== 'undefined') { + if ('action' in definition) { expect(typeof definition.action).toBe('function'); } } @@ -189,6 +189,14 @@ describe('definitions', () => { definitions.facebookAppIds.action(); }).toThrow(); }); + + it('should coerce the NumberOrBoolean cluster option value', () => { + const action = definitions.cluster.action; + expect(typeof action).toBe('function'); + expect(action('2')).toBe(2); + expect(action('true')).toBe(true); + expect(action('false')).toBe(false); + }); }); describe('LiveQuery definitions', () => { @@ -203,7 +211,7 @@ describe('LiveQuery definitions', () => { if (typeof definition.required !== 'undefined') { expect(typeof definition.required).toBe('boolean'); } - if (typeof definition.action !== 'undefined') { + if ('action' in definition) { expect(typeof definition.action).toBe('function'); } } diff --git a/spec/buildConfigDefinitions.spec.js b/spec/buildConfigDefinitions.spec.js index bc15793a04..3d5fc625a4 100644 --- a/spec/buildConfigDefinitions.spec.js +++ b/spec/buildConfigDefinitions.spec.js @@ -81,9 +81,10 @@ describe('buildConfigDefinitions', () => { expect(result.property.name).toBe('moduleOrObjectParser'); }); - it('should return numberOrBooleanParser for NumberOrBoolean GenericTypeAnnotation', () => { + it('should return numberOrBoolParser call expression for NumberOrBoolean GenericTypeAnnotation', () => { const mockElement = { type: 'GenericTypeAnnotation', + name: 'cluster', typeAnnotation: { id: { name: 'NumberOrBoolean', @@ -93,9 +94,9 @@ describe('buildConfigDefinitions', () => { const result = mapperFor(mockElement, t); - expect(t.isMemberExpression(result)).toBe(true); - expect(result.object.name).toBe('parsers'); - expect(result.property.name).toBe('numberOrBooleanParser'); + expect(t.isCallExpression(result)).toBe(true); + expect(result.callee.property.name).toBe('numberOrBoolParser'); + expect(result.arguments[0].value).toBe('cluster'); }); it('should return numberOrStringParser call expression for NumberOrString GenericTypeAnnotation', () => { diff --git a/src/Options/Definitions.js b/src/Options/Definitions.js index 5b2e6e497a..f5230e7f1b 100644 --- a/src/Options/Definitions.js +++ b/src/Options/Definitions.js @@ -139,7 +139,7 @@ module.exports.ParseServerOptions = { cluster: { env: 'PARSE_SERVER_CLUSTER', help: 'Run with cluster, optionally set the number of processes default to os.cpus().length', - action: parsers.numberOrBooleanParser, + action: parsers.numberOrBoolParser('cluster'), }, collectionPrefix: { env: 'PARSE_SERVER_COLLECTION_PREFIX',