typemold 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/LICENSE +43 -0
  2. package/README.md +235 -0
  3. package/dist/cjs/decorators.js +284 -0
  4. package/dist/cjs/index.js +74 -0
  5. package/dist/cjs/mapper.js +153 -0
  6. package/dist/cjs/nestjs/index.js +12 -0
  7. package/dist/cjs/nestjs/mapper.module.js +103 -0
  8. package/dist/cjs/nestjs/mapper.service.js +161 -0
  9. package/dist/cjs/registry.js +179 -0
  10. package/dist/cjs/types.js +17 -0
  11. package/dist/cjs/utils.js +136 -0
  12. package/dist/esm/decorators.js +274 -0
  13. package/dist/esm/index.js +51 -0
  14. package/dist/esm/mapper.js +149 -0
  15. package/dist/esm/nestjs/index.js +6 -0
  16. package/dist/esm/nestjs/mapper.module.js +100 -0
  17. package/dist/esm/nestjs/mapper.service.js +125 -0
  18. package/dist/esm/registry.js +175 -0
  19. package/dist/esm/types.js +14 -0
  20. package/dist/esm/utils.js +127 -0
  21. package/dist/types/decorators.d.ts +206 -0
  22. package/dist/types/decorators.d.ts.map +1 -0
  23. package/dist/types/index.d.ts +46 -0
  24. package/dist/types/index.d.ts.map +1 -0
  25. package/dist/types/mapper.d.ts +93 -0
  26. package/dist/types/mapper.d.ts.map +1 -0
  27. package/dist/types/nestjs/index.d.ts +7 -0
  28. package/dist/types/nestjs/index.d.ts.map +1 -0
  29. package/dist/types/nestjs/mapper.module.d.ts +89 -0
  30. package/dist/types/nestjs/mapper.module.d.ts.map +1 -0
  31. package/dist/types/nestjs/mapper.service.d.ts +80 -0
  32. package/dist/types/nestjs/mapper.service.d.ts.map +1 -0
  33. package/dist/types/registry.d.ts +60 -0
  34. package/dist/types/registry.d.ts.map +1 -0
  35. package/dist/types/types.d.ts +120 -0
  36. package/dist/types/types.d.ts.map +1 -0
  37. package/dist/types/utils.d.ts +30 -0
  38. package/dist/types/utils.d.ts.map +1 -0
  39. package/package.json +92 -0
package/LICENSE ADDED
@@ -0,0 +1,43 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Chetan Prakash Joshi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ MIT License
24
+
25
+ Copyright (c) 2026 Chetan Joshi
26
+
27
+ Permission is hereby granted, free of charge, to any person obtaining a copy
28
+ of this software and associated documentation files (the "Software"), to deal
29
+ in the Software without restriction, including without limitation the rights
30
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
31
+ copies of the Software, and to permit persons to whom the Software is
32
+ furnished to do so, subject to the following conditions:
33
+
34
+ The above copyright notice and this permission notice shall be included in all
35
+ copies or substantial portions of the Software.
36
+
37
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
38
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
39
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
40
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
41
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
42
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
43
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,235 @@
1
+ # typemold
2
+
3
+ A **lightweight**, **high-performance** object mapper for NestJS with runtime field projection.
4
+
5
+ [![npm version](https://badge.fury.io/js/%40sevirial%2Fnest-mapper.svg)](https://www.npmjs.com/package/typemold)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## Features
9
+
10
+ - ⚡ **High Performance** - Compiled mappers cached after first use (no runtime reflection)
11
+ - 🎯 **Runtime Field Projection** - Pick/omit fields without creating multiple DTOs
12
+ - 📦 **Lightweight** - < 5KB bundle, zero production dependencies
13
+ - 🏷️ **Field Groups** - Define reusable field sets with decorators
14
+ - 🔧 **NestJS Integration** - Full module support with DI
15
+ - ✅ **TypeScript First** - Full strict mode support
16
+ - 🔄 **Hybrid Validation** - Optional class-validator integration
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install typemold
22
+
23
+ # Peer dependency (already in NestJS projects)
24
+ npm install reflect-metadata
25
+ ```
26
+
27
+ ## Quick Start
28
+
29
+ ### 1. Define Your DTO
30
+
31
+ ```typescript
32
+ import { AutoMap, MapFrom, FieldGroup } from "typemold";
33
+
34
+ class UserDto {
35
+ @AutoMap()
36
+ username: string;
37
+
38
+ @MapFrom("profile.avatar")
39
+ avatarUrl: string;
40
+
41
+ @MapFrom((src) => src.age >= 18)
42
+ isAdult: boolean;
43
+
44
+ @AutoMap()
45
+ email: string;
46
+ }
47
+ ```
48
+
49
+ ### 2. Map Objects
50
+
51
+ ```typescript
52
+ import { Mapper } from "typemold";
53
+
54
+ // Basic mapping
55
+ const userDto = Mapper.map(userEntity, UserDto);
56
+
57
+ // Array mapping
58
+ const userDtos = Mapper.mapArray(users, UserDto);
59
+ ```
60
+
61
+ ## Runtime Field Projection ⭐
62
+
63
+ **The killer feature** - reuse a single DTO across multiple endpoints:
64
+
65
+ ```typescript
66
+ // Full user profile
67
+ Mapper.map(user, UserDto);
68
+ // Result: { username, avatarUrl, isAdult, email }
69
+
70
+ // Only username and avatar (shorthand)
71
+ Mapper.pick(user, UserDto, ["username", "avatarUrl"]);
72
+ // Result: { username, avatarUrl }
73
+
74
+ // Exclude sensitive fields
75
+ Mapper.omit(user, UserDto, ["email"]);
76
+ // Result: { username, avatarUrl, isAdult }
77
+
78
+ // Using options object
79
+ Mapper.map(user, UserDto, { pick: ["username", "avatarUrl"] });
80
+ Mapper.map(user, UserDto, { omit: ["email"] });
81
+ ```
82
+
83
+ ## Field Groups
84
+
85
+ Define reusable field sets:
86
+
87
+ ```typescript
88
+ class UserDto {
89
+ @FieldGroup("minimal", "public")
90
+ @AutoMap()
91
+ username: string;
92
+
93
+ @FieldGroup("minimal", "public")
94
+ @MapFrom("profile.avatar")
95
+ avatar: string;
96
+
97
+ @FieldGroup("public", "full")
98
+ @AutoMap()
99
+ bio: string;
100
+
101
+ @FieldGroup("full")
102
+ @AutoMap()
103
+ email: string;
104
+ }
105
+
106
+ // Use field groups
107
+ Mapper.group(user, UserDto, "minimal"); // { username, avatar }
108
+ Mapper.group(user, UserDto, "public"); // { username, avatar, bio }
109
+ Mapper.group(user, UserDto, "full"); // { bio, email }
110
+
111
+ // Or via options
112
+ Mapper.map(user, UserDto, { group: "minimal" });
113
+ ```
114
+
115
+ ## Decorators
116
+
117
+ | Decorator | Description | Example |
118
+ | ------------------------- | ---------------------------- | ------------------------------------------------ |
119
+ | `@AutoMap()` | Maps property with same name | `@AutoMap() name: string` |
120
+ | `@MapFrom(path)` | Maps from nested path | `@MapFrom('profile.avatar') avatar: string` |
121
+ | `@MapFrom(fn)` | Custom transform | `@MapFrom(src => src.age > 18) isAdult: boolean` |
122
+ | `@FieldGroup(...groups)` | Assigns to field groups | `@FieldGroup('minimal', 'public')` |
123
+ | `@Ignore()` | Skips property | `@Ignore() internalId: string` |
124
+ | `@NestedType(() => Type)` | Nested object mapping | `@NestedType(() => AddressDto)` |
125
+
126
+ ## NestJS Integration
127
+
128
+ ### Basic Setup
129
+
130
+ ```typescript
131
+ import { Module } from "@nestjs/common";
132
+ import { MapperModule } from "typemold";
133
+
134
+ @Module({
135
+ imports: [MapperModule.forRoot()], // Global by default
136
+ })
137
+ export class AppModule {}
138
+ ```
139
+
140
+ ### With Validation
141
+
142
+ ```typescript
143
+ @Module({
144
+ imports: [
145
+ MapperModule.forRoot({
146
+ enableValidation: true, // Uses class-validator if installed
147
+ }),
148
+ ],
149
+ })
150
+ export class AppModule {}
151
+ ```
152
+
153
+ ### Async Configuration
154
+
155
+ ```typescript
156
+ @Module({
157
+ imports: [
158
+ MapperModule.forRootAsync({
159
+ imports: [ConfigModule],
160
+ useFactory: (config: ConfigService) => ({
161
+ enableValidation: config.get("ENABLE_VALIDATION"),
162
+ }),
163
+ inject: [ConfigService],
164
+ }),
165
+ ],
166
+ })
167
+ export class AppModule {}
168
+ ```
169
+
170
+ ### Using MapperService
171
+
172
+ ```typescript
173
+ import { Injectable } from "@nestjs/common";
174
+ import { MapperService } from "typemold";
175
+
176
+ @Injectable()
177
+ export class UserService {
178
+ constructor(private readonly mapper: MapperService) {}
179
+
180
+ async getUser(id: string): Promise<UserDto> {
181
+ const user = await this.userRepo.findOne(id);
182
+ return this.mapper.map(user, UserDto);
183
+ }
184
+
185
+ async getUserMinimal(id: string): Promise<Partial<UserDto>> {
186
+ const user = await this.userRepo.findOne(id);
187
+ return this.mapper.group(user, UserDto, "minimal");
188
+ }
189
+
190
+ async getPostAuthor(
191
+ postId: string
192
+ ): Promise<Pick<UserDto, "username" | "avatar">> {
193
+ const user = await this.getPostUser(postId);
194
+ return this.mapper.pick(user, UserDto, ["username", "avatar"]);
195
+ }
196
+ }
197
+ ```
198
+
199
+ ## Performance
200
+
201
+ Thanks to compiled & cached mappers, performance is near-identical to hand-written mapping code:
202
+
203
+ | Operation | typemold | @automapper/nestjs | Manual |
204
+ | ------------ | --------------------- | ------------------ | -------- |
205
+ | Single map | ~0.002ms | ~0.05ms | ~0.001ms |
206
+ | Array (1000) | ~1.5ms | ~40ms | ~1ms |
207
+ | Memory | O(1) cache | O(n) profiles | None |
208
+
209
+ ## API Reference
210
+
211
+ ### Mapper (Static)
212
+
213
+ ```typescript
214
+ Mapper.map(source, TargetDto, options?)
215
+ Mapper.mapArray(sources, TargetDto, options?)
216
+ Mapper.pick(source, TargetDto, ['field1', 'field2'])
217
+ Mapper.omit(source, TargetDto, ['field1'])
218
+ Mapper.group(source, TargetDto, 'groupName')
219
+ Mapper.createMapper(TargetDto, options?) // Returns reusable function
220
+ ```
221
+
222
+ ### MapOptions
223
+
224
+ ```typescript
225
+ interface MapOptions<T> {
226
+ pick?: (keyof T)[]; // Include only these fields
227
+ omit?: (keyof T)[]; // Exclude these fields
228
+ group?: string; // Use predefined field group
229
+ extras?: Record<string, unknown>; // Extra context for transforms
230
+ }
231
+ ```
232
+
233
+ ## License
234
+
235
+ MIT © [Sevirial](https://sevirial.com)
@@ -0,0 +1,284 @@
1
+ "use strict";
2
+ /**
3
+ * @sevirial/nest-mapper - Decorators
4
+ * Property decorators for defining mapping configurations
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.Groups = void 0;
8
+ exports.MapFrom = MapFrom;
9
+ exports.createMapping = createMapping;
10
+ exports.AutoMap = AutoMap;
11
+ exports.FieldGroup = FieldGroup;
12
+ exports.createFieldGroups = createFieldGroups;
13
+ exports.Ignore = Ignore;
14
+ exports.NestedType = NestedType;
15
+ require("reflect-metadata");
16
+ const types_1 = require("./types");
17
+ /**
18
+ * Maps a property from a source path or using a transform function.
19
+ *
20
+ * @example
21
+ * // Direct property mapping
22
+ * class UserDto {
23
+ * @MapFrom('firstName')
24
+ * name: string;
25
+ * }
26
+ *
27
+ * @example
28
+ * // Nested path mapping
29
+ * class UserDto {
30
+ * @MapFrom('profile.avatar')
31
+ * avatarUrl: string;
32
+ * }
33
+ *
34
+ * @example
35
+ * // Transform function with typed source
36
+ * class UserDto {
37
+ * @MapFrom<User>((src) => src.age >= 18) // ← IntelliSense for src!
38
+ * isAdult: boolean;
39
+ * }
40
+ */
41
+ function MapFrom(sourcePathOrTransform) {
42
+ return (target, propertyKey) => {
43
+ const key = String(propertyKey);
44
+ const existingMappings = Reflect.getMetadata(types_1.METADATA_KEYS.PROPERTY_MAPPINGS, target.constructor) || new Map();
45
+ const existingConfig = existingMappings.get(key) || createDefaultConfig(key);
46
+ if (typeof sourcePathOrTransform === "function") {
47
+ existingConfig.source = sourcePathOrTransform;
48
+ existingConfig.isTransform = true;
49
+ }
50
+ else {
51
+ existingConfig.source = sourcePathOrTransform;
52
+ existingConfig.isTransform = false;
53
+ }
54
+ existingMappings.set(key, existingConfig);
55
+ Reflect.defineMetadata(types_1.METADATA_KEYS.PROPERTY_MAPPINGS, existingMappings, target.constructor);
56
+ };
57
+ }
58
+ /**
59
+ * Creates a type-safe mapping configuration with full IntelliSense support.
60
+ * Use this builder pattern when you need autocomplete for source paths.
61
+ *
62
+ * @example
63
+ * interface User {
64
+ * username: string;
65
+ * profile: { avatar: string; bio: string };
66
+ * }
67
+ *
68
+ * // Option 1: Define mappings with full autocomplete
69
+ * const toUserDto = createMapping<User, UserDto>({
70
+ * avatar: 'profile.avatar', // ✨ Autocomplete for paths!
71
+ * bio: src => src.profile.bio, // ✨ Autocomplete for transforms!
72
+ * });
73
+ *
74
+ * // Usage
75
+ * const dto = toUserDto(userEntity);
76
+ *
77
+ * @example
78
+ * // Option 2: Use with Mapper
79
+ * const dto = Mapper.mapWith(user, toUserDto);
80
+ */
81
+ function createMapping(mappings) {
82
+ return (source) => {
83
+ const result = {};
84
+ for (const [targetKey, sourcePathOrFn] of Object.entries(mappings)) {
85
+ if (typeof sourcePathOrFn === "function") {
86
+ result[targetKey] = sourcePathOrFn(source);
87
+ }
88
+ else {
89
+ result[targetKey] = getNestedValueTyped(source, sourcePathOrFn);
90
+ }
91
+ }
92
+ return result;
93
+ };
94
+ }
95
+ /**
96
+ * Helper to get nested value with type safety
97
+ */
98
+ function getNestedValueTyped(obj, path) {
99
+ if (obj == null)
100
+ return undefined;
101
+ const segments = path.split(".");
102
+ let current = obj;
103
+ for (const segment of segments) {
104
+ if (current == null || typeof current !== "object")
105
+ return undefined;
106
+ current = current[segment];
107
+ }
108
+ return current;
109
+ }
110
+ /**
111
+ * Automatically maps a property with the same name from source.
112
+ *
113
+ * @example
114
+ * class UserDto {
115
+ * @AutoMap()
116
+ * username: string; // Maps from source.username
117
+ * }
118
+ */
119
+ function AutoMap() {
120
+ return (target, propertyKey) => {
121
+ const key = String(propertyKey);
122
+ const existingMappings = Reflect.getMetadata(types_1.METADATA_KEYS.PROPERTY_MAPPINGS, target.constructor) || new Map();
123
+ const existingConfig = existingMappings.get(key) || createDefaultConfig(key);
124
+ existingConfig.source = key; // Same name mapping
125
+ existingConfig.isTransform = false;
126
+ existingMappings.set(key, existingConfig);
127
+ Reflect.defineMetadata(types_1.METADATA_KEYS.PROPERTY_MAPPINGS, existingMappings, target.constructor);
128
+ Reflect.defineMetadata(types_1.METADATA_KEYS.AUTO_MAP, true, target.constructor, key);
129
+ };
130
+ }
131
+ /**
132
+ * Assigns a property to one or more field groups for runtime projection.
133
+ *
134
+ * @example
135
+ * // Basic usage with strings
136
+ * class UserDto {
137
+ * @FieldGroup('minimal', 'public')
138
+ * @AutoMap()
139
+ * username: string;
140
+ * }
141
+ *
142
+ * @example
143
+ * // Type-safe usage with const object (recommended for autocomplete!)
144
+ * const Groups = createFieldGroups('minimal', 'public', 'full');
145
+ *
146
+ * class UserDto {
147
+ * @FieldGroup(Groups.minimal, Groups.public) // ✨ Autocomplete!
148
+ * @AutoMap()
149
+ * username: string;
150
+ * }
151
+ */
152
+ function FieldGroup(...groups) {
153
+ return (target, propertyKey) => {
154
+ const key = String(propertyKey);
155
+ const existingMappings = Reflect.getMetadata(types_1.METADATA_KEYS.PROPERTY_MAPPINGS, target.constructor) || new Map();
156
+ const existingConfig = existingMappings.get(key) || createDefaultConfig(key);
157
+ existingConfig.groups = [...new Set([...existingConfig.groups, ...groups])];
158
+ existingMappings.set(key, existingConfig);
159
+ Reflect.defineMetadata(types_1.METADATA_KEYS.PROPERTY_MAPPINGS, existingMappings, target.constructor);
160
+ // Also store in field groups map for quick lookup
161
+ const fieldGroups = Reflect.getMetadata(types_1.METADATA_KEYS.FIELD_GROUPS, target.constructor) || new Map();
162
+ for (const group of groups) {
163
+ const groupSet = fieldGroups.get(group) || new Set();
164
+ groupSet.add(key);
165
+ fieldGroups.set(group, groupSet);
166
+ }
167
+ Reflect.defineMetadata(types_1.METADATA_KEYS.FIELD_GROUPS, fieldGroups, target.constructor);
168
+ };
169
+ }
170
+ /**
171
+ * Creates a type-safe field groups object with autocomplete support.
172
+ * Use this to define your groups once and get IntelliSense everywhere!
173
+ *
174
+ * @example
175
+ * // Define groups once
176
+ * export const UserGroups = createFieldGroups('minimal', 'public', 'full');
177
+ *
178
+ * class UserDto {
179
+ * @FieldGroup(UserGroups.minimal, UserGroups.public) // ✨ Autocomplete!
180
+ * @AutoMap()
181
+ * username: string;
182
+ *
183
+ * @FieldGroup(UserGroups.full)
184
+ * @AutoMap()
185
+ * email: string;
186
+ * }
187
+ *
188
+ * // Usage with type-safety
189
+ * Mapper.map(user, UserDto, { group: UserGroups.minimal }); // ✨ Autocomplete!
190
+ */
191
+ function createFieldGroups(...groups) {
192
+ const result = {};
193
+ for (const group of groups) {
194
+ result[group] = group;
195
+ }
196
+ return Object.freeze(result);
197
+ }
198
+ /**
199
+ * Built-in field groups with autocomplete - use these directly!
200
+ * No need to define your own groups for common use cases.
201
+ *
202
+ * @example
203
+ * class UserDto {
204
+ * @FieldGroup(Groups.MINIMAL, Groups.PUBLIC) // ✨ Autocomplete!
205
+ * @AutoMap()
206
+ * username: string;
207
+ *
208
+ * @FieldGroup(Groups.DETAILED)
209
+ * @AutoMap()
210
+ * email: string;
211
+ * }
212
+ *
213
+ * // Usage
214
+ * Mapper.map(user, UserDto, { group: Groups.MINIMAL }); // ✨ Autocomplete!
215
+ */
216
+ exports.Groups = Object.freeze({
217
+ /** Minimal fields - just the essentials (e.g., id, name) */
218
+ MINIMAL: "minimal",
219
+ /** Summary fields - brief overview */
220
+ SUMMARY: "summary",
221
+ /** Public fields - safe to expose publicly */
222
+ PUBLIC: "public",
223
+ /** Private fields - internal use only */
224
+ PRIVATE: "private",
225
+ /** Detailed fields - comprehensive info */
226
+ DETAILED: "detailed",
227
+ /** Full fields - everything */
228
+ FULL: "full",
229
+ /** List view fields - for table/list displays */
230
+ LIST: "list",
231
+ /** Detail view fields - for detail pages */
232
+ DETAIL: "detail",
233
+ /** Admin fields - administrative data */
234
+ ADMIN: "admin",
235
+ /** API response fields */
236
+ API: "api",
237
+ });
238
+ /**
239
+ * Ignores a property during mapping.
240
+ *
241
+ * @example
242
+ * class UserDto {
243
+ * @Ignore()
244
+ * internalId: string; // Will not be mapped
245
+ * }
246
+ */
247
+ function Ignore() {
248
+ return (target, propertyKey) => {
249
+ const key = String(propertyKey);
250
+ const existingMappings = Reflect.getMetadata(types_1.METADATA_KEYS.PROPERTY_MAPPINGS, target.constructor) || new Map();
251
+ const existingConfig = existingMappings.get(key) || createDefaultConfig(key);
252
+ existingConfig.ignore = true;
253
+ existingMappings.set(key, existingConfig);
254
+ Reflect.defineMetadata(types_1.METADATA_KEYS.PROPERTY_MAPPINGS, existingMappings, target.constructor);
255
+ Reflect.defineMetadata(types_1.METADATA_KEYS.IGNORE, true, target.constructor, key);
256
+ };
257
+ }
258
+ /**
259
+ * Specifies the type for nested object mapping.
260
+ *
261
+ * @example
262
+ * class UserDto {
263
+ * @NestedType(() => AddressDto)
264
+ * @MapFrom('address')
265
+ * address: AddressDto;
266
+ * }
267
+ */
268
+ function NestedType(typeFactory) {
269
+ return (target, propertyKey) => {
270
+ Reflect.defineMetadata(types_1.METADATA_KEYS.NESTED_TYPE, typeFactory, target.constructor, String(propertyKey));
271
+ };
272
+ }
273
+ /**
274
+ * Creates a default property mapping config
275
+ */
276
+ function createDefaultConfig(targetKey) {
277
+ return {
278
+ targetKey,
279
+ source: targetKey,
280
+ isTransform: false,
281
+ groups: [],
282
+ ignore: false,
283
+ };
284
+ }
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ /**
3
+ * typemold
4
+ * A lightweight, high-performance object mapper for TypeScript and Node.js
5
+ *
6
+ * @author Chetan Joshi
7
+ * @license MIT
8
+ *
9
+ * @example
10
+ * // Basic mapping
11
+ * import { Mapper, MapFrom, AutoMap } from 'typemold';
12
+ *
13
+ * class UserDto {
14
+ * @AutoMap()
15
+ * username: string;
16
+ *
17
+ * @MapFrom('profile.avatar')
18
+ * avatar: string;
19
+ *
20
+ * @MapFrom((src) => src.age >= 18)
21
+ * isAdult: boolean;
22
+ * }
23
+ *
24
+ * const userDto = Mapper.map(userEntity, UserDto);
25
+ *
26
+ * @example
27
+ * // Runtime field projection
28
+ * const minimal = Mapper.map(user, UserDto, { pick: ['username', 'avatar'] });
29
+ * const safe = Mapper.map(user, UserDto, { omit: ['email', 'password'] });
30
+ * const public = Mapper.map(user, UserDto, { group: 'public' });
31
+ *
32
+ * @example
33
+ * // NestJS integration (optional)
34
+ * import { MapperModule, MapperService } from 'typemold';
35
+ *
36
+ * @Module({
37
+ * imports: [MapperModule.forRoot()],
38
+ * })
39
+ * export class AppModule {}
40
+ */
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.MAPPER_OPTIONS = exports.MapperService = exports.MapperModule = exports.isClassInstance = exports.isPlainObject = exports.omitKeys = exports.pickKeys = exports.getNestedValue = exports.MapperFactory = exports.MappingRegistry = exports.METADATA_KEYS = exports.NestedType = exports.Ignore = exports.Groups = exports.createFieldGroups = exports.FieldGroup = exports.AutoMap = exports.createMapping = exports.MapFrom = exports.Mapper = void 0;
43
+ // Core Mapper
44
+ var mapper_1 = require("./mapper");
45
+ Object.defineProperty(exports, "Mapper", { enumerable: true, get: function () { return mapper_1.Mapper; } });
46
+ // Decorators
47
+ var decorators_1 = require("./decorators");
48
+ Object.defineProperty(exports, "MapFrom", { enumerable: true, get: function () { return decorators_1.MapFrom; } });
49
+ Object.defineProperty(exports, "createMapping", { enumerable: true, get: function () { return decorators_1.createMapping; } });
50
+ Object.defineProperty(exports, "AutoMap", { enumerable: true, get: function () { return decorators_1.AutoMap; } });
51
+ Object.defineProperty(exports, "FieldGroup", { enumerable: true, get: function () { return decorators_1.FieldGroup; } });
52
+ Object.defineProperty(exports, "createFieldGroups", { enumerable: true, get: function () { return decorators_1.createFieldGroups; } });
53
+ Object.defineProperty(exports, "Groups", { enumerable: true, get: function () { return decorators_1.Groups; } });
54
+ Object.defineProperty(exports, "Ignore", { enumerable: true, get: function () { return decorators_1.Ignore; } });
55
+ Object.defineProperty(exports, "NestedType", { enumerable: true, get: function () { return decorators_1.NestedType; } });
56
+ // Types
57
+ var types_1 = require("./types");
58
+ Object.defineProperty(exports, "METADATA_KEYS", { enumerable: true, get: function () { return types_1.METADATA_KEYS; } });
59
+ // Registry (for advanced usage)
60
+ var registry_1 = require("./registry");
61
+ Object.defineProperty(exports, "MappingRegistry", { enumerable: true, get: function () { return registry_1.MappingRegistry; } });
62
+ Object.defineProperty(exports, "MapperFactory", { enumerable: true, get: function () { return registry_1.MapperFactory; } });
63
+ // Utilities
64
+ var utils_1 = require("./utils");
65
+ Object.defineProperty(exports, "getNestedValue", { enumerable: true, get: function () { return utils_1.getNestedValue; } });
66
+ Object.defineProperty(exports, "pickKeys", { enumerable: true, get: function () { return utils_1.pickKeys; } });
67
+ Object.defineProperty(exports, "omitKeys", { enumerable: true, get: function () { return utils_1.omitKeys; } });
68
+ Object.defineProperty(exports, "isPlainObject", { enumerable: true, get: function () { return utils_1.isPlainObject; } });
69
+ Object.defineProperty(exports, "isClassInstance", { enumerable: true, get: function () { return utils_1.isClassInstance; } });
70
+ // NestJS Integration
71
+ var nestjs_1 = require("./nestjs");
72
+ Object.defineProperty(exports, "MapperModule", { enumerable: true, get: function () { return nestjs_1.MapperModule; } });
73
+ Object.defineProperty(exports, "MapperService", { enumerable: true, get: function () { return nestjs_1.MapperService; } });
74
+ Object.defineProperty(exports, "MAPPER_OPTIONS", { enumerable: true, get: function () { return nestjs_1.MAPPER_OPTIONS; } });