Skip to content

Commit d84e2ca

Browse files
committed
feat(schema): add mapObjects option
1 parent 1120a06 commit d84e2ca

File tree

3 files changed

+80
-16
lines changed

3 files changed

+80
-16
lines changed

.changeset/honest-dolls-punch.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@dreamkit/schema": patch
3+
---
4+
5+
Add `mapObjects` option

packages/schema/src/types/ObjectType.ts

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,11 @@ type ObjectTypeCreatorOptions = ObjectTypeIteratorOptions & {
127127
pathName: string;
128128
},
129129
) => boolean;
130+
mapObjects?: boolean;
130131
map?: (
131132
data: ObjectTypeIteratorItem & {
132133
pathName: string;
134+
nextValue: () => any;
133135
},
134136
) => any;
135137
output?: Record<string, any>;
@@ -246,21 +248,29 @@ export class ObjectType<
246248
get pathName() {
247249
return pathName || (pathName = item.path.join("."));
248250
},
251+
nextValue: item.objectType
252+
? () =>
253+
item.objectType!.createWith({
254+
...options,
255+
data: item.value,
256+
output: undefined,
257+
parentPath: item.path,
258+
})
259+
: () => item.value,
249260
};
250261
if (options.filter && !options.filter(subItem)) continue;
262+
251263
if (
264+
!options.mapObjects &&
252265
item.objectType &&
253266
(!!item.value ||
254267
(!item.type.options.nullable && !item.type.options.optional))
255268
) {
256-
output[item.name] = item.objectType.createWith({
257-
...options,
258-
data: item.value,
259-
output: undefined,
260-
parentPath: item.path,
261-
});
269+
output[item.name] = subItem.nextValue();
262270
} else {
263-
const newValue = options.map ? options.map(subItem) : item.value;
271+
const newValue = options.map
272+
? options.map(subItem)
273+
: subItem.nextValue();
264274
if (newValue !== undefined) output[item.name] = newValue;
265275
}
266276
}
@@ -277,22 +287,28 @@ export class ObjectType<
277287
get pathName() {
278288
return pathName || (pathName = item.path.join("."));
279289
},
290+
nextValue: item.objectType
291+
? () =>
292+
item.objectType!.createWithAsync({
293+
...options,
294+
data: item.value,
295+
output: undefined,
296+
parentPath: item.path,
297+
})
298+
: () => item.value,
280299
};
281300
if (options.filter && !options.filter(subItem)) continue;
282-
283301
if (
302+
!options.mapObjects &&
284303
item.objectType &&
285304
(!!item.value ||
286305
(!item.type.options.nullable && !item.type.options.optional))
287306
) {
288-
output[item.name] = await item.objectType.createWithAsync({
289-
...options,
290-
data: item.value,
291-
output: undefined,
292-
parentPath: item.path,
293-
});
307+
output[item.name] = await subItem.nextValue();
294308
} else {
295-
const newValue = options.map ? await options.map(subItem) : item.value;
309+
const newValue = options.map
310+
? await options.map(subItem)
311+
: await subItem.nextValue();
296312
if (newValue !== undefined) output[item.name] = newValue;
297313
}
298314
}

packages/schema/test/types/ObjectType.test.ts

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1-
import { InferType, NumberType, StringType, s } from "../../src/index.js";
1+
import {
2+
InferType,
3+
NumberType,
4+
StringType,
5+
ObjectType,
6+
s,
7+
} from "../../src/index.js";
28
import "./../override.js";
9+
import { kindOf } from "@dreamkit/kind";
310
import { describe, expect, expectTypeOf, it } from "vitest";
411

512
describe("object.type", () => {
@@ -185,6 +192,42 @@ describe("object.createWith", () => {
185192
},
186193
});
187194
});
195+
it("with mapObjects", () => {
196+
const $ = s.object({
197+
a: s.string(),
198+
b: s
199+
.object({
200+
c: s.bool(),
201+
})
202+
.flags({ internal: true }),
203+
d: s.object({
204+
e: s.bool(),
205+
}),
206+
});
207+
208+
const o = $.createWith({
209+
mapObjects: true,
210+
map: ({ type, pathName, nextValue }) => {
211+
if (kindOf(type, ObjectType)) {
212+
return (type.flagsValue as any).internal
213+
? JSON.stringify(nextValue())
214+
: nextValue();
215+
} else {
216+
return pathName;
217+
}
218+
},
219+
});
220+
221+
expect(o).toEqual({
222+
a: "a",
223+
b: JSON.stringify({
224+
c: "b.c",
225+
}),
226+
d: {
227+
e: "d.e",
228+
},
229+
});
230+
});
188231
});
189232

190233
describe("object.partial", () => {

0 commit comments

Comments
 (0)