diff --git a/index.js b/index.js index 3a02da13..aa16c319 100644 --- a/index.js +++ b/index.js @@ -10,8 +10,7 @@ const Location = require('./lib/location') const validate = require('./lib/schema-validator') const mergeSchemas = require('./lib/merge-schemas') -let largeArraySize = 2e4 -let largeArrayMechanism = 'default' +const DEFAULT_LARGE_ARRAY_SIZE = 2e4 const NAMED_FRAGMENT_REF = /^#[a-z_][-\w._]*$/i @@ -190,9 +189,14 @@ function build (schema, options) { } } + // on the context, not the module: a build without these options must not inherit them + // from the build before it + context.largeArrayMechanism = 'default' + context.largeArraySize = DEFAULT_LARGE_ARRAY_SIZE + if (options.largeArrayMechanism) { if (validLargeArrayMechanisms.has(options.largeArrayMechanism)) { - largeArrayMechanism = options.largeArrayMechanism + context.largeArrayMechanism = options.largeArrayMechanism } else { throw new Error(`Unsupported large array mechanism ${options.largeArrayMechanism}`) } @@ -203,11 +207,11 @@ function build (schema, options) { let parsedNumber if (largeArraySizeType === 'string' && Number.isFinite((parsedNumber = Number.parseInt(options.largeArraySize, 10)))) { - largeArraySize = parsedNumber + context.largeArraySize = parsedNumber } else if (largeArraySizeType === 'number' && Number.isInteger(options.largeArraySize)) { - largeArraySize = options.largeArraySize + context.largeArraySize = options.largeArraySize } else if (largeArraySizeType === 'bigint') { - largeArraySize = Number(options.largeArraySize) + context.largeArraySize = Number(options.largeArraySize) } else { throw new Error(`Unsupported large array size. Expected integer-like, got ${typeof options.largeArraySize} with value ${options.largeArraySize}`) } @@ -713,8 +717,8 @@ function buildArray (context, location, input) { ` } - if (largeArrayMechanism === 'json-stringify') { - functionCode += `if (arrayLength >= ${largeArraySize}) return JSON.stringify(obj)\n` + if (context.largeArrayMechanism === 'json-stringify') { + functionCode += `if (arrayLength >= ${context.largeArraySize}) return JSON.stringify(obj)\n` } functionCode += ` @@ -798,8 +802,8 @@ function buildArray (context, location, input) { ` } - if (largeArrayMechanism === 'json-stringify') { - inlinedCode += `if (arrayLength_${objVar} >= ${largeArraySize}) json += JSON.stringify(${objVar})\n else {` + if (context.largeArrayMechanism === 'json-stringify') { + inlinedCode += `if (arrayLength_${objVar} >= ${context.largeArraySize}) json += JSON.stringify(${objVar})\n else {` } inlinedCode += ` @@ -856,7 +860,7 @@ function buildArray (context, location, input) { json += JSON_STR_END_ARRAY ` - if (largeArrayMechanism === 'json-stringify') { + if (context.largeArrayMechanism === 'json-stringify') { inlinedCode += '}' } diff --git a/test/array.test.js b/test/array.test.js index 3dbeeb55..47920e47 100644 --- a/test/array.test.js +++ b/test/array.test.js @@ -686,3 +686,20 @@ buildTest({ largeArraySize: '10000', largeArrayMechanism: 'default' }) + +test('large array options do not leak into the next build', (t) => { + t.plan(2) + + const schema = { + type: 'array', + items: { type: 'string', format: 'date' } + } + const dates = [new Date(0), new Date(0), new Date(0)] + + const withOptions = build(schema, { largeArrayMechanism: 'json-stringify', largeArraySize: 3 }) + t.assert.equal(withOptions(dates), JSON.stringify(dates)) + + // the options above were kept on the module and read by this build too + const withoutOptions = build(schema) + t.assert.equal(withoutOptions(dates), '["1970-01-01","1970-01-01","1970-01-01"]') +})