Change guessType to retain value types if they are known (#22349)

* Improve env variable casting for already typed variables configured through .[c]js files

* Revert back to using dedicated toX functions and extended toBoolean to handle boolean type values

* Some additions to test and removed some redundant code in toBoolean

* Fix test case name

* Add changeset

* Change changeset
This commit is contained in:
Hannes Küttner
2024-05-02 11:42:35 +02:00
committed by GitHub
parent 8e10388487
commit 97bf47e67c
5 changed files with 32 additions and 7 deletions

View File

@@ -0,0 +1,5 @@
---
'@directus/env': patch
---
Fixed behavior of config variable casting to retain types of known value types

View File

@@ -87,7 +87,7 @@ describe('Casting', () => {
expect(cast('value')).toBe(123);
});
test('Uses toBoolean for number types', () => {
test('Uses toBoolean for boolean types', () => {
vi.mocked(getCastFlag).mockReturnValue('boolean');
vi.mocked(toBoolean).mockReturnValue(false);

View File

@@ -9,6 +9,10 @@ describe('boolean', () => {
test('Returns boolean if value is literal "false"', () => {
expect(guessType('true')).toBe('boolean');
});
test('Returns boolean if value is of type boolean', () => {
expect(guessType(true)).toBe('boolean');
});
});
describe('number', () => {
@@ -27,12 +31,24 @@ describe('number', () => {
test('Returns json for numbers bigger than the max safe integer', () => {
expect(guessType('9007199254740992')).toBe('json');
});
test('Returns json for numbers smaller than the min safe integer', () => {
expect(guessType('-9007199254740992')).toBe('json');
});
test('Returns number for values of type number', () => {
expect(guessType(12345)).toBe('number');
});
});
describe('array', () => {
test('Returns array for strings containing a comma', () => {
expect(guessType('a,b,c')).toBe('array');
});
test('Returns array for values that are actual arrays', () => {
expect(guessType(['a', 'b', 'c'])).toBe('array');
});
});
describe('json', () => {

View File

@@ -1,20 +1,22 @@
import type { EnvType } from '../types/env-type.js';
export const guessType = (value: unknown): EnvType => {
if (value === 'true' || value === 'false') {
if (typeof value === 'boolean' || value === 'true' || value === 'false') {
return 'boolean';
}
if (
String(value).startsWith('0') === false &&
isNaN(Number(value)) === false &&
String(value).length > 0 &&
Number(value) <= Number.MAX_SAFE_INTEGER
typeof value === 'number' ||
(!String(value).startsWith('0') &&
!isNaN(Number(value)) &&
String(value).length > 0 &&
Number(value) >= Number.MIN_SAFE_INTEGER &&
Number(value) <= Number.MAX_SAFE_INTEGER)
) {
return 'number';
}
if (String(value).includes(',')) {
if (Array.isArray(value) || String(value).includes(',')) {
return 'array';
}

View File

@@ -11,6 +11,8 @@ test.each([
[123, false],
[{}, false],
[['{}'], false],
[true, true],
[false, false],
])('toBoolean(%s) -> %s', (value, expected) => {
expect(toBoolean(value)).toBe(expected);
});