@aurios/mizzle 1.1.2 → 1.1.3

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 (116) hide show
  1. package/.turbo/turbo-build.log +37 -0
  2. package/LICENSE +21 -0
  3. package/README.md +57 -57
  4. package/dist/chunk-AQVECMXP.js +1 -0
  5. package/dist/chunk-DU7UPWBW.js +1 -0
  6. package/dist/chunk-GPYZK4WY.js +1 -0
  7. package/dist/chunk-NPPZW6VT.js +1 -0
  8. package/dist/chunk-TOYV2M4M.js +1 -0
  9. package/dist/chunk-UM3YF5EC.js +1 -0
  10. package/dist/columns.d.ts +1 -0
  11. package/dist/columns.js +1 -0
  12. package/dist/db-zHIHBm1E.d.ts +815 -0
  13. package/dist/db.d.ts +3 -0
  14. package/dist/db.js +1 -0
  15. package/dist/diff.d.ts +18 -0
  16. package/dist/diff.js +1 -0
  17. package/dist/index.d.ts +42 -0
  18. package/dist/index.js +1 -0
  19. package/dist/introspection.d.ts +7 -0
  20. package/dist/introspection.js +1 -0
  21. package/dist/operators-BVreW0ky.d.ts +719 -0
  22. package/dist/snapshot.d.ts +24 -0
  23. package/dist/snapshot.js +1 -0
  24. package/dist/table.d.ts +1 -0
  25. package/dist/table.js +1 -0
  26. package/dist/transaction-RE7LXTGV.js +1 -0
  27. package/package.json +82 -66
  28. package/src/builders/base.ts +53 -56
  29. package/src/builders/batch-get.ts +63 -58
  30. package/src/builders/batch-write.ts +81 -78
  31. package/src/builders/delete.ts +46 -53
  32. package/src/builders/insert.ts +158 -150
  33. package/src/builders/query-promise.ts +26 -35
  34. package/src/builders/relational-builder.ts +214 -191
  35. package/src/builders/select.ts +250 -237
  36. package/src/builders/transaction.ts +170 -152
  37. package/src/builders/update.ts +197 -192
  38. package/src/columns/binary-set.ts +29 -38
  39. package/src/columns/binary.ts +25 -35
  40. package/src/columns/boolean.ts +25 -30
  41. package/src/columns/date.ts +57 -64
  42. package/src/columns/index.ts +15 -15
  43. package/src/columns/json.ts +39 -48
  44. package/src/columns/list.ts +26 -36
  45. package/src/columns/map.ts +26 -34
  46. package/src/columns/number-set.ts +29 -38
  47. package/src/columns/number.ts +33 -40
  48. package/src/columns/string-set.ts +38 -47
  49. package/src/columns/string.ts +37 -49
  50. package/src/columns/uuid.ts +26 -33
  51. package/src/core/client.ts +9 -9
  52. package/src/core/column-builder.ts +194 -220
  53. package/src/core/column.ts +127 -135
  54. package/src/core/diff.ts +40 -34
  55. package/src/core/errors.ts +20 -17
  56. package/src/core/introspection.ts +62 -58
  57. package/src/core/operations.ts +17 -23
  58. package/src/core/parser.ts +82 -89
  59. package/src/core/relations.ts +164 -154
  60. package/src/core/retry.ts +52 -52
  61. package/src/core/snapshot.ts +131 -130
  62. package/src/core/strategies.ts +222 -218
  63. package/src/core/table.ts +189 -202
  64. package/src/core/validation.ts +52 -52
  65. package/src/db.ts +211 -209
  66. package/src/expressions/actions.ts +26 -26
  67. package/src/expressions/builder.ts +62 -54
  68. package/src/expressions/operators.ts +48 -48
  69. package/src/expressions/update-builder.ts +78 -76
  70. package/src/index.ts +1 -1
  71. package/src/indexes.ts +8 -8
  72. package/test/batch-resilience.test.ts +138 -0
  73. package/test/builders/delete.test.ts +100 -0
  74. package/test/builders/insert.test.ts +216 -0
  75. package/test/builders/relational-types.test.ts +55 -0
  76. package/test/builders/relational.integration.test.ts +291 -0
  77. package/test/builders/relational.test.ts +66 -0
  78. package/test/builders/select.test.ts +411 -0
  79. package/test/builders/transaction-errors.test.ts +46 -0
  80. package/test/builders/transaction-execution.test.ts +99 -0
  81. package/test/builders/transaction-proxy.test.ts +41 -0
  82. package/test/builders/update-expression.test.ts +106 -0
  83. package/test/builders/update.test.ts +179 -0
  84. package/test/core/diff.test.ts +152 -0
  85. package/test/core/expressions.test.ts +64 -0
  86. package/test/core/introspection.test.ts +47 -0
  87. package/test/core/parser.test.ts +69 -0
  88. package/test/core/snapshot-gen.test.ts +155 -0
  89. package/test/core/snapshot.test.ts +52 -0
  90. package/test/date-column.test.ts +159 -0
  91. package/test/fluent-writes.integration.test.ts +148 -0
  92. package/test/integration-retry.test.ts +77 -0
  93. package/test/integration.test.ts +105 -0
  94. package/test/item-size-error.test.ts +16 -0
  95. package/test/item-size-validation.test.ts +82 -0
  96. package/test/item-size.test.ts +47 -0
  97. package/test/iterator-pagination.integration.test.ts +132 -0
  98. package/test/jsdoc-builders.test.ts +55 -0
  99. package/test/jsdoc-schema.test.ts +107 -0
  100. package/test/json-column.test.ts +51 -0
  101. package/test/metadata.test.ts +54 -0
  102. package/test/mizzle-package.test.ts +20 -0
  103. package/test/relational-centralized.test.ts +83 -0
  104. package/test/relational-definition.test.ts +75 -0
  105. package/test/relational-init.test.ts +30 -0
  106. package/test/relational-proxy.test.ts +52 -0
  107. package/test/relations.test.ts +45 -0
  108. package/test/resilience-config.test.ts +34 -0
  109. package/test/retry-handler.test.ts +63 -0
  110. package/test/transaction.integration.test.ts +153 -0
  111. package/test/unified-select.integration.test.ts +153 -0
  112. package/test/unified-update.integration.test.ts +139 -0
  113. package/test/update.integration.test.ts +132 -0
  114. package/tsconfig.json +12 -8
  115. package/tsup.config.ts +11 -11
  116. package/vitest.config.ts +8 -0
package/src/core/retry.ts CHANGED
@@ -1,71 +1,71 @@
1
1
  export interface RetryConfig {
2
- /**
3
- * Maximum number of attempts (including the initial one).
4
- * @default 3
5
- */
6
- maxAttempts: number;
7
- /**
8
- * Base delay in milliseconds for exponential backoff.
9
- * @default 100
10
- */
11
- baseDelay: number;
2
+ /**
3
+ * Maximum number of attempts (including the initial one).
4
+ * @default 3
5
+ */
6
+ maxAttempts: number;
7
+ /**
8
+ * Base delay in milliseconds for exponential backoff.
9
+ * @default 100
10
+ */
11
+ baseDelay: number;
12
12
  }
13
13
 
14
14
  const RETRYABLE_ERRORS = new Set([
15
- "ProvisionedThroughputExceededException",
16
- "RequestLimitExceeded",
17
- "InternalServerError",
18
- "ServiceUnavailable",
19
- "ThrottlingException",
15
+ "ProvisionedThroughputExceededException",
16
+ "RequestLimitExceeded",
17
+ "InternalServerError",
18
+ "ServiceUnavailable",
19
+ "ThrottlingException",
20
20
  ]);
21
21
 
22
22
  const RETRYABLE_STATUS_CODES = new Set([500, 503]);
23
23
 
24
24
  export class RetryHandler {
25
- constructor(private config: RetryConfig) {}
25
+ constructor(private config: RetryConfig) {}
26
26
 
27
- async execute<T>(operation: () => Promise<T>): Promise<T> {
28
- let lastError: unknown;
29
-
30
- for (let attempt = 1; attempt <= this.config.maxAttempts; attempt++) {
31
- try {
32
- return await operation();
33
- } catch (error) {
34
- lastError = error;
35
-
36
- if (attempt >= this.config.maxAttempts || !this.isRetryable(error)) {
37
- throw error;
38
- }
39
-
40
- await this.delay(attempt - 1);
41
- }
27
+ async execute<T>(operation: () => Promise<T>): Promise<T> {
28
+ let lastError: unknown;
29
+
30
+ for (let attempt = 1; attempt <= this.config.maxAttempts; attempt++) {
31
+ try {
32
+ return await operation();
33
+ } catch (error) {
34
+ lastError = error;
35
+
36
+ if (attempt >= this.config.maxAttempts || !this.isRetryable(error)) {
37
+ throw error;
42
38
  }
43
-
44
- throw lastError;
39
+
40
+ await this.delay(attempt - 1);
41
+ }
45
42
  }
46
43
 
47
- private isRetryable(error: unknown): boolean {
48
- if (!error || typeof error !== 'object') return false;
49
-
50
- const err = error as { name?: string; $metadata?: { httpStatusCode?: number } };
51
- if (err.name && RETRYABLE_ERRORS.has(err.name)) {
52
- return true;
53
- }
44
+ throw lastError;
45
+ }
54
46
 
55
- if (err.$metadata?.httpStatusCode && RETRYABLE_STATUS_CODES.has(err.$metadata.httpStatusCode)) {
56
- return true;
57
- }
47
+ private isRetryable(error: unknown): boolean {
48
+ if (!error || typeof error !== "object") return false;
58
49
 
59
- // AWS SDK v3 specific error structure sometimes wraps things
60
- return false;
50
+ const err = error as { name?: string; $metadata?: { httpStatusCode?: number } };
51
+ if (err.name && RETRYABLE_ERRORS.has(err.name)) {
52
+ return true;
61
53
  }
62
54
 
63
- private async delay(retryCount: number): Promise<void> {
64
- const base = this.config.baseDelay * Math.pow(2, retryCount);
65
- const jitter = Math.random() * base; // Full jitter or equal jitter? Standard is random between 0 and base.
66
- // Cap at some reasonable max if needed, but for now standard exponential + jitter
67
- const delayTime = base + jitter;
68
-
69
- return new Promise(resolve => setTimeout(resolve, delayTime));
55
+ if (err.$metadata?.httpStatusCode && RETRYABLE_STATUS_CODES.has(err.$metadata.httpStatusCode)) {
56
+ return true;
70
57
  }
58
+
59
+ // AWS SDK v3 specific error structure sometimes wraps things
60
+ return false;
61
+ }
62
+
63
+ private async delay(retryCount: number): Promise<void> {
64
+ const base = this.config.baseDelay * Math.pow(2, retryCount);
65
+ const jitter = Math.random() * base; // Full jitter or equal jitter? Standard is random between 0 and base.
66
+ // Cap at some reasonable max if needed, but for now standard exponential + jitter
67
+ const delayTime = base + jitter;
68
+
69
+ return new Promise((resolve) => setTimeout(resolve, delayTime));
70
+ }
71
71
  }
@@ -2,21 +2,21 @@ import { join } from "path";
2
2
  import { writeFile, readFile, mkdir, readdir } from "fs/promises";
3
3
  import { existsSync } from "fs";
4
4
  import { PhysicalTable, Entity } from "./table";
5
- import { TABLE_SYMBOLS, ENTITY_SYMBOLS } from "@mizzle/shared";
5
+ import { TABLE_SYMBOLS, ENTITY_SYMBOLS } from "@repo/shared";
6
6
  import { Column } from "./column";
7
7
  import type {
8
- AttributeDefinition,
9
- KeySchemaElement,
10
- GlobalSecondaryIndex,
11
- LocalSecondaryIndex,
8
+ AttributeDefinition,
9
+ KeySchemaElement,
10
+ GlobalSecondaryIndex,
11
+ LocalSecondaryIndex,
12
12
  } from "@aws-sdk/client-dynamodb";
13
13
 
14
14
  export interface TableSnapshot {
15
- TableName: string;
16
- AttributeDefinitions: AttributeDefinition[];
17
- KeySchema: KeySchemaElement[];
18
- GlobalSecondaryIndexes?: GlobalSecondaryIndex[];
19
- LocalSecondaryIndexes?: LocalSecondaryIndex[];
15
+ TableName: string;
16
+ AttributeDefinitions: AttributeDefinition[];
17
+ KeySchema: KeySchemaElement[];
18
+ GlobalSecondaryIndexes?: GlobalSecondaryIndex[];
19
+ LocalSecondaryIndexes?: LocalSecondaryIndex[];
20
20
  }
21
21
 
22
22
  export interface MizzleSnapshot {
@@ -25,8 +25,8 @@ export interface MizzleSnapshot {
25
25
  }
26
26
 
27
27
  export interface SchemaCurrent {
28
- tables: PhysicalTable[];
29
- entities: Entity[];
28
+ tables: PhysicalTable[];
29
+ entities: Entity[];
30
30
  }
31
31
 
32
32
  const SNAPSHOT_FILENAME = "snapshot.json";
@@ -49,144 +49,145 @@ export async function loadSnapshot(dir: string): Promise<MizzleSnapshot | null>
49
49
  }
50
50
 
51
51
  export function generateSnapshot(schema: SchemaCurrent): MizzleSnapshot {
52
- const tables: Record<string, TableSnapshot> = {};
53
-
54
- for (const table of schema.tables) {
55
- const associatedEntities = schema.entities.filter(e => e[ENTITY_SYMBOLS.PHYSICAL_TABLE] === table);
56
- const tableSnapshot = physicalTableToSnapshot(table, associatedEntities);
57
- tables[tableSnapshot.TableName] = tableSnapshot;
58
- }
59
-
60
- return {
61
- version: "1",
62
- tables
63
- };
52
+ const tables: Record<string, TableSnapshot> = {};
53
+
54
+ for (const table of schema.tables) {
55
+ const associatedEntities = schema.entities.filter(
56
+ (e) => e[ENTITY_SYMBOLS.PHYSICAL_TABLE] === table,
57
+ );
58
+ const tableSnapshot = physicalTableToSnapshot(table, associatedEntities);
59
+ tables[tableSnapshot.TableName] = tableSnapshot;
60
+ }
61
+
62
+ return {
63
+ version: "1",
64
+ tables,
65
+ };
64
66
  }
65
67
 
66
68
  export async function getNextMigrationVersion(migrationsDir: string): Promise<string> {
67
- if (!existsSync(migrationsDir)) return "0000";
68
-
69
- const files = await readdir(migrationsDir);
70
- let maxVersion = -1;
71
-
72
- for (const file of files) {
73
- if (!file.endsWith(".ts")) continue;
74
- const match = file.match(/^(\d{4})_/);
75
- if (match) {
76
- const version = parseInt(match[1]!, 10);
77
- if (version > maxVersion) maxVersion = version;
78
- }
69
+ if (!existsSync(migrationsDir)) return "0000";
70
+
71
+ const files = await readdir(migrationsDir);
72
+ let maxVersion = -1;
73
+
74
+ for (const file of files) {
75
+ if (!file.endsWith(".ts")) continue;
76
+ const match = file.match(/^(\d{4})_/);
77
+ if (match) {
78
+ const version = parseInt(match[1]!, 10);
79
+ if (version > maxVersion) maxVersion = version;
79
80
  }
80
-
81
- if (maxVersion === -1) return "0000";
82
- return (maxVersion + 1).toString().padStart(4, "0");
81
+ }
82
+
83
+ if (maxVersion === -1) return "0000";
84
+ return (maxVersion + 1).toString().padStart(4, "0");
83
85
  }
84
86
 
85
87
  function physicalTableToSnapshot(table: PhysicalTable, entities: Entity[]): TableSnapshot {
86
- const tableName = table[TABLE_SYMBOLS.TABLE_NAME];
87
- const attributeDefinitionsMap = new Map<string, string>(); // Name -> Type
88
+ const tableName = table[TABLE_SYMBOLS.TABLE_NAME];
89
+ const attributeDefinitionsMap = new Map<string, string>(); // Name -> Type
88
90
 
89
- // PK
90
- const pk = table[TABLE_SYMBOLS.PARTITION_KEY] as Column;
91
- attributeDefinitionsMap.set(pk.name, pk.getDynamoType());
91
+ // PK
92
+ const pk = table[TABLE_SYMBOLS.PARTITION_KEY] as Column;
93
+ attributeDefinitionsMap.set(pk.name, pk.getDynamoType());
92
94
 
93
- // SK
94
- const sk = table[TABLE_SYMBOLS.SORT_KEY] as Column | undefined;
95
- if (sk) {
96
- attributeDefinitionsMap.set(sk.name, sk.getDynamoType());
97
- }
95
+ // SK
96
+ const sk = table[TABLE_SYMBOLS.SORT_KEY] as Column | undefined;
97
+ if (sk) {
98
+ attributeDefinitionsMap.set(sk.name, sk.getDynamoType());
99
+ }
98
100
 
99
- const keySchema: KeySchemaElement[] = [
100
- { AttributeName: pk.name, KeyType: "HASH" }
101
- ];
102
- if (sk) {
103
- keySchema.push({ AttributeName: sk.name, KeyType: "RANGE" });
104
- }
101
+ const keySchema: KeySchemaElement[] = [{ AttributeName: pk.name, KeyType: "HASH" }];
102
+ if (sk) {
103
+ keySchema.push({ AttributeName: sk.name, KeyType: "RANGE" });
104
+ }
105
105
 
106
- const gsis: GlobalSecondaryIndex[] = [];
107
- const lsis: LocalSecondaryIndex[] = [];
108
-
109
- const indexes = table[TABLE_SYMBOLS.INDEXES] || {};
110
- for (const [indexName, indexBuilder] of Object.entries(indexes)) {
111
- const type = (indexBuilder as { type: string }).type;
112
- const config = (indexBuilder as { config: { pk?: string; sk?: string } }).config;
113
-
114
- if (type === 'gsi') {
115
- if (config.pk) {
116
- const pkType = resolveColumnType(config.pk, table, entities);
117
- attributeDefinitionsMap.set(config.pk, pkType);
118
- }
119
- if (config.sk) {
120
- const skType = resolveColumnType(config.sk, table, entities);
121
- attributeDefinitionsMap.set(config.sk, skType);
122
- }
123
-
124
- const gsiDef: GlobalSecondaryIndex = {
125
- IndexName: indexName,
126
- KeySchema: [
127
- { AttributeName: config.pk!, KeyType: "HASH" }
128
- ],
129
- Projection: { ProjectionType: "ALL" }
130
- };
131
- if (config.sk) {
132
- gsiDef.KeySchema!.push({ AttributeName: config.sk, KeyType: "RANGE" });
133
- }
134
- gsis.push(gsiDef);
135
-
136
- } else if (type === 'lsi') {
137
- if (config.sk) {
138
- const skType = resolveColumnType(config.sk, table, entities);
139
- attributeDefinitionsMap.set(config.sk, skType);
140
- }
141
-
142
- const lsiDef: LocalSecondaryIndex = {
143
- IndexName: indexName,
144
- KeySchema: [
145
- { AttributeName: pk.name, KeyType: "HASH" },
146
- { AttributeName: config.sk!, KeyType: "RANGE" }
147
- ],
148
- Projection: { ProjectionType: "ALL" }
149
- };
150
- lsis.push(lsiDef);
151
- }
106
+ const gsis: GlobalSecondaryIndex[] = [];
107
+ const lsis: LocalSecondaryIndex[] = [];
108
+
109
+ const indexes = table[TABLE_SYMBOLS.INDEXES] || {};
110
+ for (const [indexName, indexBuilder] of Object.entries(indexes)) {
111
+ const type = (indexBuilder as { type: string }).type;
112
+ const config = (indexBuilder as { config: { pk?: string; sk?: string } }).config;
113
+
114
+ if (type === "gsi") {
115
+ if (config.pk) {
116
+ const pkType = resolveColumnType(config.pk, table, entities);
117
+ attributeDefinitionsMap.set(config.pk, pkType);
118
+ }
119
+ if (config.sk) {
120
+ const skType = resolveColumnType(config.sk, table, entities);
121
+ attributeDefinitionsMap.set(config.sk, skType);
122
+ }
123
+
124
+ const gsiDef: GlobalSecondaryIndex = {
125
+ IndexName: indexName,
126
+ KeySchema: [{ AttributeName: config.pk!, KeyType: "HASH" }],
127
+ Projection: { ProjectionType: "ALL" },
128
+ };
129
+ if (config.sk) {
130
+ gsiDef.KeySchema!.push({ AttributeName: config.sk, KeyType: "RANGE" });
131
+ }
132
+ gsis.push(gsiDef);
133
+ } else if (type === "lsi") {
134
+ if (config.sk) {
135
+ const skType = resolveColumnType(config.sk, table, entities);
136
+ attributeDefinitionsMap.set(config.sk, skType);
137
+ }
138
+
139
+ const lsiDef: LocalSecondaryIndex = {
140
+ IndexName: indexName,
141
+ KeySchema: [
142
+ { AttributeName: pk.name, KeyType: "HASH" },
143
+ { AttributeName: config.sk!, KeyType: "RANGE" },
144
+ ],
145
+ Projection: { ProjectionType: "ALL" },
146
+ };
147
+ lsis.push(lsiDef);
152
148
  }
149
+ }
153
150
 
154
- const attributeDefinitions = Array.from(attributeDefinitionsMap.entries()).map(([name, type]) => ({
155
- AttributeName: name,
156
- AttributeType: type as "S" | "N" | "B"
157
- })).sort((a, b) => a.AttributeName.localeCompare(b.AttributeName));
151
+ const attributeDefinitions = Array.from(attributeDefinitionsMap.entries())
152
+ .map(([name, type]) => ({
153
+ AttributeName: name,
154
+ AttributeType: type as "S" | "N" | "B",
155
+ }))
156
+ .sort((a, b) => a.AttributeName.localeCompare(b.AttributeName));
158
157
 
159
- gsis.sort((a, b) => (a.IndexName || "").localeCompare(b.IndexName || ""));
160
- lsis.sort((a, b) => (a.IndexName || "").localeCompare(b.IndexName || ""));
158
+ gsis.sort((a, b) => (a.IndexName || "").localeCompare(b.IndexName || ""));
159
+ lsis.sort((a, b) => (a.IndexName || "").localeCompare(b.IndexName || ""));
161
160
 
162
- const result: TableSnapshot = {
163
- TableName: tableName as string,
164
- AttributeDefinitions: attributeDefinitions,
165
- KeySchema: keySchema,
166
- };
161
+ const result: TableSnapshot = {
162
+ TableName: tableName as string,
163
+ AttributeDefinitions: attributeDefinitions,
164
+ KeySchema: keySchema,
165
+ };
167
166
 
168
- if (gsis.length > 0) result.GlobalSecondaryIndexes = gsis;
169
- if (lsis.length > 0) result.LocalSecondaryIndexes = lsis;
167
+ if (gsis.length > 0) result.GlobalSecondaryIndexes = gsis;
168
+ if (lsis.length > 0) result.LocalSecondaryIndexes = lsis;
170
169
 
171
- return result;
170
+ return result;
172
171
  }
173
172
 
174
173
  function resolveColumnType(columnName: string, table: PhysicalTable, entities: Entity[]): string {
175
- const pk = table[TABLE_SYMBOLS.PARTITION_KEY] as Column;
176
- if (pk.name === columnName) return pk.getDynamoType();
177
-
178
- const sk = table[TABLE_SYMBOLS.SORT_KEY] as Column | undefined;
179
- if (sk && sk.name === columnName) return sk.getDynamoType();
180
-
181
- for (const entity of entities) {
182
- const columns = entity[ENTITY_SYMBOLS.COLUMNS] as Record<string, Column> | undefined;
183
- if (columns) {
184
- const col = columns[columnName];
185
- if (col) {
186
- return col.getDynamoType();
187
- }
188
- }
174
+ const pk = table[TABLE_SYMBOLS.PARTITION_KEY] as Column;
175
+ if (pk.name === columnName) return pk.getDynamoType();
176
+
177
+ const sk = table[TABLE_SYMBOLS.SORT_KEY] as Column | undefined;
178
+ if (sk && sk.name === columnName) return sk.getDynamoType();
179
+
180
+ for (const entity of entities) {
181
+ const columns = entity[ENTITY_SYMBOLS.COLUMNS] as Record<string, Column> | undefined;
182
+ if (columns) {
183
+ const col = columns[columnName];
184
+ if (col) {
185
+ return col.getDynamoType();
186
+ }
189
187
  }
188
+ }
190
189
 
191
- throw new Error(`Could not resolve type for column '${columnName}' in table '${table[TABLE_SYMBOLS.TABLE_NAME]}'. Ensure it is defined in an Entity.`);
190
+ throw new Error(
191
+ `Could not resolve type for column '${columnName}' in table '${table[TABLE_SYMBOLS.TABLE_NAME]}'. Ensure it is defined in an Entity.`,
192
+ );
192
193
  }