feat: new importer (#214)

This commit is contained in:
Carl-Gerhard Lindesvärd
2025-11-05 09:49:36 +01:00
committed by GitHub
parent b51bc8f3f6
commit 212254d31a
80 changed files with 4884 additions and 842 deletions

View File

@@ -0,0 +1,48 @@
import { describe, expect, it } from 'vitest';
import { toDots } from './object';
describe('toDots', () => {
it('should convert an object to a dot object', () => {
const obj = {
a: 1,
b: 2,
array: ['1', '2', '3'],
arrayWithObjects: [{ a: 1 }, { b: 2 }, { c: 3 }],
objectWithArrays: { a: [1, 2, 3] },
null: null,
undefined: undefined,
empty: '',
jsonString: '{"a": 1, "b": 2}',
};
expect(toDots(obj)).toEqual({
a: '1',
b: '2',
'array.0': '1',
'array.1': '2',
'array.2': '3',
'arrayWithObjects.0.a': '1',
'arrayWithObjects.1.b': '2',
'arrayWithObjects.2.c': '3',
'objectWithArrays.a.0': '1',
'objectWithArrays.a.1': '2',
'objectWithArrays.a.2': '3',
'jsonString.a': '1',
'jsonString.b': '2',
});
});
it('should handle malformed JSON strings gracefully', () => {
const obj = {
validJson: '{"key":"value"}',
malformedJson: '{"key":"unterminated string',
startsWithBrace: '{not json at all',
startsWithBracket: '[also not json',
regularString: 'normal string',
};
expect(toDots(obj)).toEqual({
'validJson.key': 'value',
regularString: 'normal string',
});
});
});

View File

@@ -1,5 +1,18 @@
import { anyPass, assocPath, isEmpty, isNil, reject } from 'ramda';
function isValidJsonString(value: string): boolean {
return (
(value.startsWith('{') && value.endsWith('}')) ||
(value.startsWith('[') && value.endsWith(']'))
);
}
function isMalformedJsonString(value: string): boolean {
return (
(value.startsWith('{') && !value.endsWith('}')) ||
(value.startsWith('[') && !value.endsWith(']'))
);
}
export function toDots(
obj: Record<string, unknown>,
path = '',
@@ -19,10 +32,28 @@ export function toDots(
};
}
if (value === undefined || value === null) {
if (value === undefined || value === null || value === '') {
return acc;
}
if (typeof value === 'string' && isMalformedJsonString(value)) {
// Skip it
return acc;
}
// Fix nested json strings - but catch parse errors for malformed JSON
if (typeof value === 'string' && isValidJsonString(value)) {
try {
return {
...acc,
...toDots(JSON.parse(value), `${path}${key}.`),
};
} catch {
// Skip it
return acc;
}
}
const cleanedValue =
typeof value === 'string'
? removeInvalidSurrogates(value).trim()