Skip to content

Commit f41f893

Browse files
committed
feat: Add common name generators
1 parent 49fcf4c commit f41f893

File tree

3 files changed

+100
-0
lines changed

3 files changed

+100
-0
lines changed

packages/utils/src/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ import unwrapErrorHandler from './unwrapErrorHandler';
7070
import utcToLocal from './utcToLocal';
7171
import validationDataMerge from './validationDataMerge';
7272
import withIdRefPrefix from './withIdRefPrefix';
73+
import getOptionMatchingSimpleDiscriminator from './getOptionMatchingSimpleDiscriminator';
74+
import getChangedFields from './getChangedFields';
75+
import { bracketNameGenerator, dotNotationNameGenerator } from './nameGenerators';
7376

7477
export * from './types';
7578
export * from './enums';
@@ -153,6 +156,8 @@ export {
153156
utcToLocal,
154157
validationDataMerge,
155158
withIdRefPrefix,
159+
bracketNameGenerator,
160+
dotNotationNameGenerator,
156161
};
157162

158163
export type { ComponentUpdateStrategy } from './shouldRender';
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { NameGeneratorFunction, FieldPathList } from './types';
2+
3+
/**
4+
* Generates bracketed names
5+
* Example: root[tasks][0][title]
6+
*/
7+
export const bracketNameGenerator: NameGeneratorFunction = (path: FieldPathList, idPrefix: string): string => {
8+
if (!path || path.length === 0) {
9+
return idPrefix;
10+
}
11+
12+
return path.reduce<string>((acc, pathUnit, index) => {
13+
if (index === 0) {
14+
return `${idPrefix}[${String(pathUnit)}]`;
15+
}
16+
return `${acc}[${String(pathUnit)}]`;
17+
}, '');
18+
};
19+
20+
/**
21+
* Generates dot-notation names
22+
* Example: root.tasks.0.title
23+
*/
24+
export const dotNotationNameGenerator: NameGeneratorFunction = (path: FieldPathList, idPrefix: string): string => {
25+
if (!path || path.length === 0) {
26+
return idPrefix;
27+
}
28+
29+
return `${idPrefix}.${path.map(String).join('.')}`;
30+
};
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { bracketNameGenerator, dotNotationNameGenerator } from '../src';
2+
3+
describe('bracketNameGenerator()', () => {
4+
test('returns "root" for empty path', () => {
5+
expect(bracketNameGenerator([], 'root')).toBe('root');
6+
});
7+
8+
test('generates name for single string segment', () => {
9+
expect(bracketNameGenerator(['firstName'], 'root')).toBe('root[firstName]');
10+
});
11+
12+
test('generates name for single number segment (array index)', () => {
13+
expect(bracketNameGenerator([0], 'root')).toBe('root[0]');
14+
});
15+
16+
test('generates name for nested object path', () => {
17+
expect(bracketNameGenerator(['user', 'address', 'city'], 'root')).toBe('root[user][address][city]');
18+
});
19+
20+
test('generates name for array with object properties', () => {
21+
expect(bracketNameGenerator(['tasks', 0, 'title'], 'root')).toBe('root[tasks][0][title]');
22+
});
23+
24+
test('generates name for nested arrays', () => {
25+
expect(bracketNameGenerator(['matrix', 0, 1], 'root')).toBe('root[matrix][0][1]');
26+
});
27+
28+
test('generates name for complex nested structure', () => {
29+
expect(bracketNameGenerator(['users', 0, 'addresses', 1, 'street'], 'root')).toBe(
30+
'root[users][0][addresses][1][street]',
31+
);
32+
});
33+
});
34+
35+
describe('dotNotationNameGenerator()', () => {
36+
test('returns "root" for empty path', () => {
37+
expect(dotNotationNameGenerator([], 'root')).toBe('root');
38+
});
39+
40+
test('generates name for single string segment', () => {
41+
expect(dotNotationNameGenerator(['firstName'], 'root')).toBe('root.firstName');
42+
});
43+
44+
test('generates name for single number segment (array index)', () => {
45+
expect(dotNotationNameGenerator([0], 'root')).toBe('root.0');
46+
});
47+
48+
test('generates name for nested object path', () => {
49+
expect(dotNotationNameGenerator(['user', 'address', 'city'], 'root')).toBe('root.user.address.city');
50+
});
51+
52+
test('generates name for array with object properties', () => {
53+
expect(dotNotationNameGenerator(['tasks', 0, 'title'], 'root')).toBe('root.tasks.0.title');
54+
});
55+
56+
test('generates name for nested arrays', () => {
57+
expect(dotNotationNameGenerator(['matrix', 0, 1], 'root')).toBe('root.matrix.0.1');
58+
});
59+
60+
test('generates name for complex nested structure', () => {
61+
expect(dotNotationNameGenerator(['users', 0, 'addresses', 1, 'street'], 'root')).toBe(
62+
'root.users.0.addresses.1.street',
63+
);
64+
});
65+
});

0 commit comments

Comments
 (0)