@bairock/lenz 0.0.6 → 0.0.8

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.
package/README.md CHANGED
@@ -6,10 +6,12 @@ GraphQL-based ORM for MongoDB (Prisma style)
6
6
 
7
7
  - ✅ **GraphQL SDL Schema** - Define models using GraphQL syntax
8
8
  - ✅ **TypeScript First** - Full type safety and autocompletion
9
- - ✅ **MongoDB Native** - Leverage all MongoDB features
9
+ - ✅ **MongoDB Native** - Leverage all MongoDB features including aggregation
10
10
  - ✅ **Prisma Style** - Familiar configuration and client generation
11
11
  - ✅ **Auto-generated Client** - Generate TypeScript client from GraphQL schema
12
12
  - ✅ **Relations Support** - One-to-One, One-to-Many, Many-to-Many
13
+ - ✅ **Smart Loading Strategies** - Automatic choice between populate (separate queries) and lookup (server-side joins)
14
+ - ✅ **Automatic Indexing** - Intelligent index creation for foreign key fields
13
15
  - ✅ **Transactions** - ACID transactions with MongoDB
14
16
 
15
17
  ## Quick Start
@@ -41,8 +43,15 @@ type User @model {
41
43
  id: ID! @id
42
44
  email: String! @unique
43
45
  name: String!
46
+
47
+ # One-to-many relationship (auto-selects lookup strategy)
44
48
  posts: [Post!]! @relation(field: "postIds")
45
- postIds: [ID!]!
49
+ postIds: [ID!]! # Array automatically indexed
50
+
51
+ # One-to-one relationship (auto-selects populate strategy)
52
+ profile: Profile @relation(field: "profileId")
53
+ profileId: ID # Sparse index automatically created
54
+
46
55
  createdAt: DateTime! @createdAt
47
56
  updatedAt: DateTime! @updatedAt
48
57
  }
@@ -51,8 +60,28 @@ type Post @model {
51
60
  id: ID! @id
52
61
  title: String!
53
62
  content: String
63
+
64
+ # Many-to-one relationship (auto-selects populate strategy)
54
65
  author: User! @relation(field: "authorId")
55
- authorId: ID!
66
+ authorId: ID! # Foreign key index automatically created
67
+
68
+ # Many-to-many relationship with ID arrays (auto-selects lookup strategy)
69
+ categories: [Category!]! @relation(field: "categoryIds")
70
+ categoryIds: [ID!]! # Multikey index automatically created
71
+ }
72
+
73
+ type Profile @model {
74
+ id: ID! @id
75
+ bio: String
76
+ user: User @relation(field: "userId", strategy: "populate")
77
+ userId: ID
78
+ }
79
+
80
+ type Category @model {
81
+ id: ID! @id
82
+ name: String! @unique
83
+ posts: [Post!]! @relation(field: "postIds", strategy: "lookup", index: false)
84
+ postIds: [ID!]! # No auto-index (index: false)
56
85
  }
57
86
  ```
58
87
 
@@ -72,12 +101,13 @@ import { LenzClient } from '../generated/lenz/client';
72
101
  async function main() {
73
102
  const lenz = new LenzClient({
74
103
  url: process.env.MONGODB_URI,
75
- database: 'myapp'
104
+ database: 'myapp',
105
+ log: ['query', 'info'] // Enable query logging
76
106
  });
77
107
 
78
108
  await lenz.$connect();
79
109
 
80
- // Create a user
110
+ // Create a user with posts (populate strategy for posts)
81
111
  const user = await lenz.user.create({
82
112
  data: {
83
113
  email: 'alice@example.com',
@@ -89,19 +119,95 @@ async function main() {
89
119
  }
90
120
  },
91
121
  include: {
92
- posts: true
122
+ posts: true, // Uses populate strategy (separate queries)
123
+ profile: true // Uses populate strategy (one-to-one)
124
+ }
125
+ });
126
+
127
+ // Query with include - automatic strategy selection
128
+ const authorWithBooks = await lenz.author.findUnique({
129
+ where: { id: 'some-author-id' },
130
+ include: {
131
+ books: true // Uses lookup strategy (one-to-many, single query)
93
132
  }
94
133
  });
95
134
 
96
- // Query users
97
- const users = await lenz.user.findMany({
135
+ // Manual array synchronization for lookup strategy
136
+ // When creating a book, add its ID to author.bookIds
137
+ const newBook = await lenz.book.create({
138
+ data: {
139
+ title: 'New Book',
140
+ authorId: 'author-id'
141
+ }
142
+ });
143
+
144
+ // Manually update the author's bookIds array
145
+ await lenz.author.update({
146
+ where: { id: 'author-id' },
147
+ data: {
148
+ bookIds: {
149
+ push: newBook.id // Add new book ID to array
150
+ }
151
+ }
152
+ });
153
+
154
+ // Complex query with filtering and sorting
155
+ const posts = await lenz.post.findMany({
98
156
  where: {
99
- email: {
100
- contains: 'example'
157
+ title: { contains: 'tutorial' },
158
+ categories: {
159
+ some: { name: { equals: 'Programming' } }
101
160
  }
161
+ },
162
+ orderBy: { createdAt: 'desc' },
163
+ take: 10,
164
+ include: {
165
+ author: true, // populate strategy
166
+ categories: true // many-to-many lookup strategy (server-side join with $lookup)
102
167
  }
103
168
  });
104
169
 
170
+ // Transaction example (requires replica set)
171
+ await lenz.$transaction(async (tx) => {
172
+ const updatedUser = await lenz.user.update({
173
+ where: { id: user.id },
174
+ data: { name: 'Alice Updated' }
175
+ });
176
+
177
+ await lenz.post.create({
178
+ data: {
179
+ title: 'Transaction Post',
180
+ authorId: user.id
181
+ }
182
+ });
183
+ });
184
+
185
+ // Advanced many-to-many lookup with filtering
186
+ // Uses MongoDB aggregation pipeline for server-side joins
187
+ const postsWithTechCategories = await lenz.post.findMany({
188
+ where: {
189
+ categories: {
190
+ some: {
191
+ name: { equals: 'Technology' }
192
+ }
193
+ }
194
+ },
195
+ include: {
196
+ categories: {
197
+ where: {
198
+ name: { equals: 'Technology' }
199
+ }
200
+ }
201
+ },
202
+ orderBy: { createdAt: 'desc' },
203
+ take: 5
204
+ });
205
+
206
+ // Note: For lookup strategy, array synchronization is manual
207
+ // When creating relationships, update both arrays:
208
+ // await lenz.post.update({ where: { id: postId }, data: { categoryIds: { push: categoryId } } });
209
+ // await lenz.category.update({ where: { id: categoryId }, data: { postIds: { push: postId } } });
210
+
105
211
  await lenz.$disconnect();
106
212
  }
107
213
  ```
@@ -143,13 +249,35 @@ Lenz extends GraphQL with custom directives:
143
249
  - `@unique` - Creates a unique index
144
250
  - `@index` - Creates a regular index
145
251
  - `@default(value: "...")` - Sets default value
146
- - `@relation(field: "...")` - Defines relation field (foreign key must be in the same model)
252
+ - `@relation(field: "...", strategy: "populate|lookup", index: true|false)` - Defines relation with loading strategy and index control
147
253
  - `@createdAt` - Auto-sets creation timestamp
148
254
  - `@updatedAt` - Auto-updates timestamp
255
+ - `@embedded` - Marks a type as embedded document
256
+ - `@hide` - Excludes field from query results by default
149
257
 
150
258
  ## Relations
151
259
 
152
- Lenz requires explicit foreign key fields for all relation types:
260
+ Lenz implements MongoDB-native relations with explicit foreign key fields and intelligent loading strategies. Each relation type has an optimal default strategy for loading related data (see [Relation Loading Strategies](#relation-loading-strategies) for details).
261
+
262
+ **Key principles:**
263
+ - Foreign keys must be in the **source model** (the model containing `@relation`)
264
+ - Arrays are automatically initialized for required array fields
265
+ - Indexes are automatically created for foreign key fields (configurable)
266
+ - Loading strategy is automatically selected based on relation type
267
+
268
+ ### Automatic Array Initialization
269
+
270
+ Required array fields (like `bookIds: [ID!]!`) are automatically initialized with empty arrays `[]` when creating documents. This prevents MongoDB `$in needs an array` errors when querying relations.
271
+
272
+ ```typescript
273
+ // When creating a document, required arrays are automatically set to []
274
+ const author = await lenz.author.create({
275
+ data: {
276
+ name: 'John Doe',
277
+ // bookIds is automatically set to [] even if not provided
278
+ }
279
+ });
280
+ ```
153
281
 
154
282
  ### One-to-Many / Many-to-One
155
283
  A bidirectional relationship where one side has an array and the other has a single reference:
@@ -157,52 +285,203 @@ A bidirectional relationship where one side has an array and the other has a sin
157
285
  ```graphql
158
286
  type Author @model {
159
287
  id: ID! @id
160
- books: [Book!]! @relation(field: "bookIds") # one-to-many side
161
- bookIds: [ID!]! # array of Book IDs in Author document
288
+ books: [Book!]! @relation(field: "bookIds") # one-to-many side, auto: lookup strategy
289
+ bookIds: [ID!]! # array automatically indexed (multikey index)
162
290
  }
163
291
 
164
292
  type Book @model {
165
293
  id: ID! @id
166
- author: Author! @relation(field: "authorId") # many-to-one side
167
- authorId: ID! # single Author ID in Book document
294
+ author: Author! @relation(field: "authorId") # many-to-one side, auto: populate strategy
295
+ authorId: ID! # single ID automatically indexed (sparse index)
168
296
  }
169
297
  ```
170
298
 
171
- - **Author → Book (one-to-many):** Foreign key `bookIds` is an array of IDs in the Author document
172
- - **Book → Author (many-to-one):** Foreign key `authorId` is a single ID in the Book document
299
+ - **Author → Book (one-to-many):** Uses `lookup` strategy by default (server-side join). Requires manual synchronization of `bookIds` array.
300
+ - **Book → Author (many-to-one):** Uses `populate` strategy by default (separate query). Foreign key `authorId` has automatic sparse index.
301
+ - **Indexes:** Multikey index on `bookIds`, sparse index on `authorId` (created automatically).
173
302
 
174
303
  ### One-to-One (foreign key single ID in source model)
304
+
175
305
  ```graphql
176
306
  type User @model {
177
307
  id: ID! @id
178
- profile: Profile @relation(field: "profileId")
179
- profileId: ID
308
+ profile: Profile @relation(field: "profileId") # auto: populate strategy
309
+ profileId: ID # optional, sparse index
180
310
  }
181
311
 
182
312
  type Profile @model {
183
313
  id: ID! @id
184
- user: User @relation(field: "userId")
185
- userId: ID
314
+ user: User @relation(field: "userId", strategy: "populate") # explicit populate
315
+ userId: ID # optional, sparse index
186
316
  }
187
317
  ```
188
318
 
319
+ - **Strategy:** Uses `populate` by default (separate queries for each side)
320
+ - **Indexes:** Sparse indexes on `profileId` and `userId` (optional fields)
321
+ - **Optional:** Both sides can be optional (nullable IDs)
322
+ - **Bidirectional:** Each side maintains its own foreign key
323
+
189
324
  ### Many-to-Many (ID arrays on both sides)
325
+
190
326
  ```graphql
191
327
  type Post @model {
192
328
  id: ID! @id
193
- categories: [Category!]! @relation(field: "categoryIds")
194
- categoryIds: [ID!]!
329
+ categories: [Category!]! @relation(field: "categoryIds") # auto: lookup strategy (default for arrays)
330
+ categoryIds: [ID!]! # multikey index
195
331
  }
196
332
 
197
333
  type Category @model {
198
334
  id: ID! @id
199
- posts: [Post!]! @relation(field: "postIds")
200
- postIds: [ID!]!
335
+ posts: [Post!]! @relation(field: "postIds", strategy: "lookup", index: false)
336
+ postIds: [ID!]! # no auto-index (index: false)
201
337
  }
202
338
  ```
203
339
 
340
+ - **Strategy:** Uses `lookup` by default when foreign key arrays are specified (server-side joins with MongoDB's `$lookup` aggregation), `populate` for join collections
341
+ - **Indexes:** Multikey indexes on both array fields (configurable with `index: false`)
342
+ - **Bidirectional:** Both sides maintain arrays of IDs
343
+ - **Manual sync:** You must manually synchronize both arrays when creating/updating relations (for `lookup` strategy)
344
+
345
+ **Example - Manual synchronization for many-to-many lookup strategy:**
346
+
347
+ ```typescript
348
+ // Create a post and category
349
+ const post = await lenz.post.create({
350
+ data: {
351
+ title: 'My Post',
352
+ categoryIds: [] // Initialize empty array
353
+ }
354
+ });
355
+
356
+ const category = await lenz.category.create({
357
+ data: {
358
+ name: 'Technology',
359
+ postIds: [] // Initialize empty array
360
+ }
361
+ });
362
+
363
+ // Add category to post
364
+ await lenz.post.update({
365
+ where: { id: post.id },
366
+ data: {
367
+ categoryIds: {
368
+ push: category.id // Add category ID to post's array
369
+ }
370
+ }
371
+ });
372
+
373
+ // Add post to category (bidirectional sync)
374
+ await lenz.category.update({
375
+ where: { id: category.id },
376
+ data: {
377
+ postIds: {
378
+ push: post.id // Add post ID to category's array
379
+ }
380
+ }
381
+ });
382
+ ```
383
+
204
384
  **Important:** Foreign keys must always be in the **source model** (the model containing the `@relation` directive). Classic one-to-many patterns with foreign keys in target models will cause validation errors.
205
385
 
386
+ ## Relation Loading Strategies
387
+
388
+ Lenz automatically chooses the optimal strategy for loading related data, balancing performance and simplicity. You can also explicitly override the strategy.
389
+
390
+ ### Populate Strategy (Default for oneToOne, manyToOne)
391
+
392
+ Uses separate queries - first fetches the main document, then queries related collections. Best for simple relationships and sharded environments.
393
+
394
+ ```graphql
395
+ type User @model {
396
+ profile: Profile @relation(field: "profileId", strategy: "populate")
397
+ profileId: ID
398
+ }
399
+ ```
400
+
401
+ ### Lookup Strategy (Default for oneToMany)
402
+
403
+ Uses MongoDB's `$lookup` aggregation operator for server-side joins. Best for high-read scenarios with bidirectional relationships.
404
+
405
+ ```graphql
406
+ type Author @model {
407
+ books: [Book!]! @relation(field: "bookIds", strategy: "lookup")
408
+ bookIds: [ID!]!
409
+ }
410
+ ```
411
+
412
+ **Note:** When using `lookup` strategy, you must manually synchronize ID arrays (e.g., `bookIds`) when creating/updating/deleting related documents.
413
+
414
+ **Include options support:** Lookup strategy now supports `where`, `orderBy`, `take`, and `skip` options for filtering, sorting, and paginating related documents.
415
+
416
+ Example:
417
+ ```typescript
418
+ const author = await lenz.author.findUnique({
419
+ where: { id: 'author-id' },
420
+ include: {
421
+ books: {
422
+ where: { published: true },
423
+ orderBy: { createdAt: 'desc' },
424
+ take: 5
425
+ }
426
+ }
427
+ });
428
+ ```
429
+
430
+ ### Automatic Strategy Selection
431
+
432
+ | Relation Type | Default Strategy | Reason |
433
+ |--------------|------------------|--------|
434
+ | `oneToOne` | `populate` | Simple relationships, no arrays |
435
+ | `manyToOne` | `populate` | Single reference, no arrays |
436
+ | `oneToMany` | `lookup` | Array of IDs in source document (e.g., Author.bookIds) |
437
+ | `manyToMany` | `lookup` (if foreign key array specified) or `populate` (if join collection) | Foreign key arrays use server-side joins, join collections use separate queries |
438
+
439
+ **Note:** The lookup strategy now supports include options (where, orderBy, take, skip) for both array foreign keys and single foreign key relations. However, nested includes are not yet supported for lookup strategy but are fully supported for populate strategy.
440
+
441
+ **Many-to-Many Lookup Strategy:**
442
+
443
+ When a many-to-many relationship uses foreign key arrays (either single-sided or both sides), Lenz automatically uses the `lookup` strategy with MongoDB's `$lookup` aggregation operator. This performs server-side joins for optimal read performance. For example, `post.categoryIds` array referencing categories.
444
+
445
+ ```graphql
446
+ type Post @model {
447
+ categories: [Category!]! @relation(field: "categoryIds", strategy: "lookup")
448
+ categoryIds: [ID!]! # multikey index automatically created
449
+ }
450
+
451
+ type Category @model {
452
+ posts: [Post!]! @relation(field: "postIds", strategy: "lookup", index: false)
453
+ postIds: [ID!]! # no auto-index (index: false)
454
+ }
455
+ ```
456
+
457
+ **Many-to-Many Populate Strategy:**
458
+
459
+ When a many-to-many relationship uses a join collection (no foreign key arrays), Lenz uses the `populate` strategy with separate queries.
460
+
461
+ ```graphql
462
+ type Post @model {
463
+ categories: [Category!]! @relation # no field parameter → join collection
464
+ }
465
+
466
+ type Category @model {
467
+ posts: [Post!]! @relation
468
+ }
469
+ ```
470
+
471
+ ### Automatic Indexing
472
+
473
+ Lenz automatically creates indexes for foreign key fields when `index: true` (default). You can disable this:
474
+
475
+ ```graphql
476
+ type Author @model {
477
+ books: [Book!]! @relation(field: "bookIds", index: false)
478
+ bookIds: [ID!]!
479
+ }
480
+ ```
481
+
482
+ - For arrays (oneToMany): Creates multikey indexes
483
+ - For single IDs (oneToOne, manyToOne): Creates sparse indexes
484
+
206
485
  ## Supported Field Types
207
486
 
208
487
  - `String`
@@ -215,6 +494,78 @@ type Category @model {
215
494
  - `Json` (any JSON value)
216
495
  - `ObjectId` (MongoDB ObjectId as string)
217
496
 
497
+ ## Best Practices with MongoDB
498
+
499
+ ### 1. Schema Design
500
+ - **Embed documents** when data is accessed together frequently (use `@embedded` directive)
501
+ - **Reference documents** when data is large or accessed independently
502
+ - **Use arrays judiciously** - large arrays can impact performance
503
+ - **Denormalize carefully** - duplicate data for read performance, but maintain consistency
504
+
505
+ ### 2. Index Strategy
506
+ - **Auto-index foreign keys** - Lenz does this by default with `index: true`
507
+ - **Add compound indexes** for frequently queried field combinations
508
+ - **Use sparse indexes** for optional fields (auto-created for optional relations)
509
+ - **Monitor index usage** with `$indexStats`
510
+
511
+ ### 3. Performance Optimization
512
+ - **Use `lookup` strategy** for high-read bidirectional relationships
513
+ - **Use `populate` strategy** for simple relationships and sharded clusters
514
+ - **Batch operations** with `createMany`, `updateMany` instead of individual calls
515
+ - **Project only needed fields** with `select` option
516
+
517
+ ### 4. Query Patterns
518
+ - **Filter early** - push filters to database with `where` clauses
519
+ - **Avoid large skip/limit** - use cursor-based pagination (`cursor` option)
520
+ - **Use transactions** for multi-document consistency (requires replica set)
521
+ - **Monitor slow queries** with MongoDB profiler
522
+
523
+ ### 5. Data Consistency
524
+ - **Manual array sync** - when using `lookup` strategy, maintain ID arrays
525
+ - **Use default values** for required fields to avoid validation errors
526
+ - **Handle race conditions** with optimistic concurrency or transactions
527
+ - **Implement soft deletes** with `deletedAt` field instead of hard deletes
528
+
529
+ ### 6. Many-to-Many Performance Optimization
530
+ - **Array size limits:** Keep array sizes reasonable (<1000 elements). Large arrays increase `$lookup` complexity and memory usage.
531
+ - **Batch synchronization:** When updating multiple relationships, batch array operations to reduce database round trips.
532
+ - **Index management:** Regularly monitor and optimize multikey indexes for array fields.
533
+ - **Alternative approaches:** For extremely large many-to-many relationships, consider:
534
+ - **Denormalization:** Embed frequently accessed data
535
+ - **Hybrid approach:** Use `lookup` for recent/active relationships, `populate` for historical
536
+ - **Materialized views:** Pre-compute relationships for read-heavy scenarios
537
+
538
+ ### 7. When to Use Each Strategy
539
+
540
+ #### Use **Populate** when:
541
+ - Simple one-to-one or many-to-one relationships
542
+ - Working with sharded clusters (`$lookup` doesn't work across shards)
543
+ - Relationships are rarely accessed
544
+ - You prefer automatic data consistency
545
+ - Many-to-many relationships with join collections (no foreign key arrays)
546
+ - Small datasets where separate queries are acceptable
547
+
548
+ #### Use **Lookup** when:
549
+ - High-read scenarios with one-to-many or many-to-many relationships
550
+ - Need server-side joins for complex filtering/sorting
551
+ - Willing to manually maintain ID arrays
552
+ - Maximum read performance is critical
553
+ - Many-to-many relationships with foreign key arrays (both sides)
554
+ - Medium to large datasets where join performance matters
555
+
556
+ #### Special Considerations for Many-to-Many Lookup:
557
+ - **Array size:** Large arrays (>1000 IDs) can impact `$lookup` performance. Consider denormalization or hybrid approaches.
558
+ - **Indexing:** Multikey indexes are essential for array fields. Monitor index size and performance.
559
+ - **Consistency:** Manual array synchronization requires careful application logic to maintain data integrity.
560
+ - **Sharding:** `$lookup` doesn't work across shards. For sharded clusters, use `populate` strategy or ensure related documents are on the same shard.
561
+
562
+ ### 8. Production Readiness
563
+ - **Enable replica set** for transaction support
564
+ - **Set up proper connection pooling** in `lenz.config.ts`
565
+ - **Implement retry logic** for transient failures
566
+ - **Use environment-specific configurations**
567
+ - **Monitor connection health** with regular `ping` commands
568
+
218
569
  ## CLI Commands
219
570
 
220
571
  ```bash
@@ -31,6 +31,7 @@ export declare class CodeGenerator {
31
31
  private generateModelDelegate;
32
32
  private generateRelationInclusionCode;
33
33
  private toCamelCase;
34
+ private toCollectionName;
34
35
  }
35
36
  export interface GeneratedFiles {
36
37
  [filePath: string]: string;
@@ -1 +1 @@
1
- {"version":3,"file":"CodeGenerator.d.ts","sourceRoot":"","sources":["../../src/engine/CodeGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAG3E,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAUb;IAEF,OAAO,CAAC,6BAA6B;IAyBrC,OAAO,CAAC,wBAAwB;IAyBhC,OAAO,CAAC,sBAAsB;IA8B9B,OAAO,CAAC,mBAAmB;IAO3B,OAAO,CAAC,wBAAwB;IA4IhC,OAAO,CAAC,oBAAoB;IAM5B,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,cAAc;IAmClD,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,cAAc;IAwLtB,OAAO,CAAC,mBAAmB;IAY3B,OAAO,CAAC,aAAa;IAiKrB,OAAO,CAAC,iBAAiB;IA+BzB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,aAAa;IAiBrB,OAAO,CAAC,yBAAyB;IA4LjC,OAAO,CAAC,oBAAoB;IAU5B,OAAO,CAAC,oBAAoB;IA2N5B,OAAO,CAAC,wBAAwB;IAiEhC,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,kBAAkB;IAU1B,OAAO,CAAC,qBAAqB;IA6a7B,OAAO,CAAC,6BAA6B;IA8DrC,OAAO,CAAC,WAAW;CAGpB;AAED,MAAM,WAAW,cAAc;IAC7B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;CAC5B"}
1
+ {"version":3,"file":"CodeGenerator.d.ts","sourceRoot":"","sources":["../../src/engine/CodeGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAG3E,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAUb;IAEF,OAAO,CAAC,6BAA6B;IAyBrC,OAAO,CAAC,wBAAwB;IAyBhC,OAAO,CAAC,sBAAsB;IA8B9B,OAAO,CAAC,mBAAmB;IAO3B,OAAO,CAAC,wBAAwB;IA4IhC,OAAO,CAAC,oBAAoB;IAM5B,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,cAAc;IAmClD,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,cAAc;IAwLtB,OAAO,CAAC,mBAAmB;IAY3B,OAAO,CAAC,aAAa;IAiKrB,OAAO,CAAC,iBAAiB;IA+BzB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,aAAa;IAiBrB,OAAO,CAAC,yBAAyB;IA4LjC,OAAO,CAAC,oBAAoB;IAU5B,OAAO,CAAC,oBAAoB;IA0Q5B,OAAO,CAAC,wBAAwB;IAiEhC,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,kBAAkB;IAU1B,OAAO,CAAC,qBAAqB;IAqb7B,OAAO,CAAC,6BAA6B;IAuOrC,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,gBAAgB;CAGzB;AAED,MAAM,WAAW,cAAc;IAC7B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;CAC5B"}