Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit 44e6fbe

Browse files
author
pavelsvagr
committed
🐛 Add disableFields support for not defined serializers.
1 parent b738e0d commit 44e6fbe

2 files changed

Lines changed: 128 additions & 4 deletions

File tree

src/serializers.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,56 @@ const serializers: Dictionary<SerializerFn> = {
5757
const sliceByPrefix = (prefix: string, paths?: string[]) =>
5858
(paths || []).filter((field) => field.startsWith(prefix)).map((field) => field.slice(prefix.length));
5959

60+
const groupPrefixes = (paths: string[] = []): Map<string, string[] | null> => {
61+
const prefixes = new Map<string, string[] | null>();
62+
63+
paths.forEach((path) => {
64+
const keys = path.split(/\.(.+)/);
65+
let value;
66+
let prefix;
67+
68+
if (keys.length > 1) {
69+
prefix = keys[0];
70+
value = path.slice(prefix.length + 1); // +1 for dot
71+
} else {
72+
prefix = path;
73+
value = null;
74+
}
75+
76+
if (prefix !== null && prefixes.has(prefix)) {
77+
if (prefixes.get(prefix) !== null) prefixes.get(prefix).push(value);
78+
} else {
79+
if (value === null) prefixes.set(prefix, null);
80+
else prefixes.set(prefix, [value]);
81+
}
82+
});
83+
return prefixes;
84+
};
85+
6086
const disablePaths = (paths?: string[]) => {
87+
const notDisabled = new Map<string, boolean>(paths?.map((path) => [path, true]) || []);
88+
6189
forEach(serializers, (value, key) => {
6290
const affectedFields = sliceByPrefix(`${key}.`, paths);
6391

6492
if (affectedFields.length === 0) return;
93+
affectedFields.forEach((path) => notDisabled.delete(`${key}.${path}`));
94+
6595
const newSerializer: SerializerFn = (obj: Dictionary<any>) => {
6696
return omit(value(obj), affectedFields);
6797
};
6898
serializers[key] = newSerializer;
6999
});
100+
101+
if (!notDisabled.size) return;
102+
103+
const prefixGroups = groupPrefixes(Array.from(notDisabled.keys()));
104+
105+
prefixGroups.forEach((fields, prefix) => {
106+
serializers[prefix] = (obj: Dictionary<any>) => {
107+
return fields === null ? {} : omit(obj, fields);
108+
};
109+
});
70110
};
71111

72112
const enablePaths = (paths?: string[]) => {

src/tests/serializers.test.ts

Lines changed: 88 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,92 @@ test('Disable custom path', () => {
147147
expect(loggerWrites).toBeCalled();
148148
});
149149

150+
test('Disable path without default serializer', () => {
151+
const loggerWrites = jest.fn();
152+
const data = {
153+
customData: 'Some server data',
154+
test: 'test',
155+
};
156+
157+
const logger = loggerFactory({
158+
disableFields: ['data.customData'],
159+
streams: [
160+
{
161+
stream: new Writable({
162+
write: (chunk, encoding, next) => {
163+
const json = JSON.parse(chunk);
164+
expect(json.data).toEqual(pick(data, 'test'));
165+
loggerWrites();
166+
next();
167+
},
168+
}),
169+
},
170+
],
171+
});
172+
173+
logger.info({ data });
174+
expect(loggerWrites).toBeCalled();
175+
});
176+
177+
test('Disable field without default serializer', () => {
178+
const loggerWrites = jest.fn();
179+
const data = {
180+
customData: {
181+
test: 'Some server data',
182+
},
183+
test: 'test',
184+
};
185+
186+
const logger = loggerFactory({
187+
disableFields: ['data'],
188+
streams: [
189+
{
190+
stream: new Writable({
191+
write: (chunk, encoding, next) => {
192+
const json = JSON.parse(chunk);
193+
expect(json.data).toEqual({});
194+
loggerWrites();
195+
next();
196+
},
197+
}),
198+
},
199+
],
200+
});
201+
202+
logger.info({ data });
203+
expect(loggerWrites).toBeCalled();
204+
});
205+
206+
test('Disable fields without default serializer from 1 object', () => {
207+
const loggerWrites = jest.fn();
208+
const data = {
209+
customData: {
210+
test: 'Some server data',
211+
},
212+
customData2: 'Some another data',
213+
test: 'test',
214+
};
215+
216+
const logger = loggerFactory({
217+
disableFields: ['data.customData', 'data.customData2'],
218+
streams: [
219+
{
220+
stream: new Writable({
221+
write: (chunk, encoding, next) => {
222+
const json = JSON.parse(chunk);
223+
expect(json.data).toEqual(pick(data, 'test'));
224+
loggerWrites();
225+
next();
226+
},
227+
}),
228+
},
229+
],
230+
});
231+
232+
logger.info({ data });
233+
expect(loggerWrites).toBeCalled();
234+
});
235+
150236
test('Enable custom path', () => {
151237
const loggerWrites = jest.fn();
152238
const req = {
@@ -184,10 +270,8 @@ test('Some express headers are enabled by default', () => {
184270
write: (chunk, encoding, next) => {
185271
const json = JSON.parse(chunk);
186272
const validHeaders = ['x-deviceid', 'authorization', 'user-agent'];
187-
validHeaders.forEach(header =>
188-
expect(json.req.headers[header]).toBeDefined()
189-
);
190-
Object.keys(json.req.headers).forEach(header =>
273+
validHeaders.forEach((header) => expect(json.req.headers[header]).toBeDefined());
274+
Object.keys(json.req.headers).forEach((header) =>
191275
expect(validHeaders.includes(header)).toBe(true)
192276
);
193277
loggerWrites();

0 commit comments

Comments
 (0)