Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion yarn-project/foundation/src/config/config.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { jest } from '@jest/globals';

import { type ConfigMappingsType, getConfigFromMappings, numberConfigHelper } from './index.js';
import { type ConfigMappingsType, bigintConfigHelper, getConfigFromMappings, numberConfigHelper } from './index.js';

describe('Config', () => {
describe('getConfigFromMappings', () => {
Expand Down Expand Up @@ -131,4 +131,37 @@ describe('Config', () => {
});
});
});

describe('bigintConfigHelper', () => {
it('parses plain integer strings', () => {
const { parseEnv } = bigintConfigHelper();
expect(parseEnv!('123')).toBe(123n);
expect(parseEnv!('0')).toBe(0n);
expect(parseEnv!('200000000000000000000000')).toBe(200000000000000000000000n);
});

it('parses scientific notation', () => {
const { parseEnv } = bigintConfigHelper();
expect(parseEnv!('1e+23')).toBe(100000000000000000000000n);
expect(parseEnv!('2E+23')).toBe(200000000000000000000000n);
expect(parseEnv!('1e23')).toBe(100000000000000000000000n);
expect(parseEnv!('5e18')).toBe(5000000000000000000n);
});

it('parses scientific notation with decimal mantissa', () => {
const { parseEnv } = bigintConfigHelper();
expect(parseEnv!('1.5e10')).toBe(15000000000n);
expect(parseEnv!('2.5e5')).toBe(250000n);
});

it('returns default value for empty string', () => {
const { parseEnv } = bigintConfigHelper(42n);
expect(parseEnv!('')).toBe(42n);
});

it('throws for non-integer scientific notation results', () => {
const { parseEnv } = bigintConfigHelper();
expect(() => parseEnv!('1e-3')).toThrow();
});
});
});
15 changes: 15 additions & 0 deletions yarn-project/foundation/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,21 @@ export function bigintConfigHelper(defaultVal?: bigint): Pick<ConfigMapping, 'pa
if (val === '') {
return defaultVal;
}
// Handle scientific notation (e.g. "1e+23", "2E23") which BigInt() doesn't accept directly.
// We parse it losslessly using bigint arithmetic instead of going through float64.
if (/[eE]/.test(val)) {
const match = val.match(/^(-?\d+(?:\.(\d+))?)[eE]([+-]?\d+)$/);
if (!match) {
throw new Error(`Cannot convert '${val}' to a BigInt`);
}
const digits = match[1].replace('.', '');
const decimalPlaces = match[2]?.length ?? 0;
const exponent = parseInt(match[3], 10) - decimalPlaces;
if (exponent < 0) {
throw new Error(`Cannot convert '${val}' to a BigInt: result is not an integer`);
}
return BigInt(digits) * 10n ** BigInt(exponent);
}
return BigInt(val);
},
defaultValue: defaultVal,
Expand Down
Loading