@reldens/storage 0.81.0 → 0.82.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.
package/CLAUDE.md CHANGED
@@ -105,12 +105,18 @@ npx reldens-storage-prisma --host=<host> --database=<db> --user=<user> --passwor
105
105
  - Automatic schema synchronization
106
106
 
107
107
  **Prisma Driver** (`lib/prisma/`):
108
- - `prisma-driver.js`: Driver implementation
108
+ - `prisma-driver.js`: Driver implementation with enhanced validation
109
109
  - `prisma-data-server.js`: Data server using Prisma Client
110
110
  - `prisma-schema-generator.js`: Schema generation and introspection
111
+ - `prisma-metadata-loader.js`: Loads field metadata including defaults
112
+ - `prisma-type-caster.js`: Type casting and normalization
113
+ - `prisma-relation-resolver.js`: Relation mapping and transformations
111
114
  - Features:
112
- - Schema-first approach
113
- - Type-safe queries
115
+ - Schema-first approach with auto-introspection
116
+ - Type-safe queries with Prisma Client
117
+ - Custom `ensureRequiredFields()` validation for better error messages
118
+ - Database default value support (skips validation for fields with defaults)
119
+ - VARCHAR foreign key support using relation connect syntax
114
120
  - Introspection via `prisma db pull`
115
121
  - Binary targets configuration
116
122
  - Data proxy support
@@ -237,6 +243,122 @@ All generated entity relations follow the `related_*` prefix pattern:
237
243
 
238
244
  This pattern is consistent across all ORM drivers and is defined in `entities-config.js`.
239
245
 
246
+ ## Prisma Driver Validation System
247
+
248
+ ### ensureRequiredFields() Method
249
+
250
+ The Prisma driver includes custom validation that differs from ObjectionJS and provides better error messages:
251
+
252
+ **Location:** `lib/prisma/prisma-driver.js` lines 201-223
253
+
254
+ **Purpose:** Validates that all required fields are present before sending data to Prisma Client
255
+
256
+ **Key Behavior:**
257
+ ```javascript
258
+ ensureRequiredFields(data) {
259
+ let missingFields = [];
260
+ for(let field of this.requiredFields){
261
+ if(sc.hasOwn(data, field)){
262
+ continue; // Field is present
263
+ }
264
+ if(sc.hasOwn(this.foreignKeyMappings, field)){
265
+ let relationName = this.foreignKeyMappings[field];
266
+ if(sc.hasOwn(data, relationName)){
267
+ continue; // FK mapped to relation (connect syntax)
268
+ }
269
+ }
270
+ if(sc.hasOwn(this.fieldDefaults, field)){
271
+ continue; // Field has database default - skip validation
272
+ }
273
+ missingFields.push(field);
274
+ }
275
+ if(0 < missingFields.length){
276
+ Logger.warning('Missing required fields for '+this.tableName()+': '+missingFields.join(', '));
277
+ }
278
+ return data;
279
+ }
280
+ ```
281
+
282
+ **Important:** This validation runs BEFORE Prisma Client, allowing it to:
283
+ 1. Provide clear error messages about missing fields
284
+ 2. Allow database defaults to work (doesn't validate fields with defaults)
285
+ 3. Support foreign key relation syntax (checks both FK field and relation)
286
+
287
+ ### Database Default Values
288
+
289
+ **How It Works:**
290
+ - Metadata loader extracts default values from Prisma schema (`@default()` directive)
291
+ - Stored in `this.fieldDefaults` map during driver initialization
292
+ - Validation skips required fields that have defaults
293
+ - Prisma/database applies default when field is missing
294
+
295
+ **Example:**
296
+ ```javascript
297
+ // Prisma schema
298
+ model scores_detail {
299
+ kill_time DateTime @default(now()) @db.DateTime(0)
300
+ }
301
+
302
+ // Admin panel sends data without kill_time
303
+ {
304
+ player_id: 1001,
305
+ obtained_score: 150
306
+ // kill_time missing but has default
307
+ }
308
+
309
+ // Validation skips kill_time (has default)
310
+ // Prisma creates record, database applies DEFAULT CURRENT_TIMESTAMP
311
+ ```
312
+
313
+ ### Comparison with ObjectionJS
314
+
315
+ **ObjectionJS Driver:**
316
+ ```javascript
317
+ create(params) {
318
+ return this.queryBuilder().insert(params);
319
+ }
320
+ ```
321
+ - No validation
322
+ - Passes data directly to Knex
323
+ - Database handles missing fields and defaults
324
+ - Less informative error messages
325
+
326
+ **Prisma Driver:**
327
+ ```javascript
328
+ async create(params) {
329
+ let preparedData = this.prepareDataWithRelations(params, true);
330
+ this.ensureRequiredFields(preparedData); // Custom validation
331
+ try {
332
+ return this.typeCaster.normalizeReturnData(await this.model.create({data: preparedData}));
333
+ ```
334
+ - Custom validation before Prisma
335
+ - Better error messages
336
+ - Supports database defaults
337
+ - Type-safe queries
338
+
339
+ **Key Difference:** Prisma validates first, so it must be aware of database defaults to allow them to work.
340
+
341
+ ### Foreign Key Handling
342
+
343
+ Both drivers handle foreign keys, but with different syntax:
344
+
345
+ **ObjectionJS:**
346
+ ```javascript
347
+ // Direct FK field
348
+ {player_id: 1001}
349
+ ```
350
+
351
+ **Prisma:**
352
+ ```javascript
353
+ // Relation connect syntax
354
+ {players: {connect: {id: 1001}}}
355
+
356
+ // Also supports VARCHAR FKs
357
+ {related_table: {connect: {custom_id: "ABC123"}}}
358
+ ```
359
+
360
+ The `prepareDataWithRelations()` method (lines 156-199) automatically converts FK fields to relation syntax.
361
+
240
362
  ## Important Notes
241
363
 
242
364
  ### Entity Management
@@ -7,6 +7,7 @@
7
7
  */
8
8
 
9
9
  const { EntitiesGenerator } = require('../lib/entities-generator');
10
+ const { FileHandler } = require('@reldens/server-utils');
10
11
  const { Logger, sc } = require('@reldens/utils');
11
12
 
12
13
  class StorageEntitiesGenerator
@@ -19,6 +20,7 @@ class StorageEntitiesGenerator
19
20
  this.config = {};
20
21
  this.projectPath = process.cwd();
21
22
  this.isOverride = false;
23
+ this.prismaClientPath = '';
22
24
  this.parseArguments();
23
25
  }
24
26
 
@@ -38,11 +40,15 @@ class StorageEntitiesGenerator
38
40
  continue;
39
41
  }
40
42
  let key = arg.substring(2, equalIndex);
41
- let value = arg.substring(equalIndex + 1);
43
+ let value = arg.substring(equalIndex+1);
42
44
  if('path' === key){
43
45
  this.projectPath = value;
44
46
  continue;
45
47
  }
48
+ if('prismaClientPath' === key){
49
+ this.prismaClientPath = value;
50
+ continue;
51
+ }
46
52
  if('pass' === key){
47
53
  this.config['password'] = value;
48
54
  continue;
@@ -69,6 +75,9 @@ class StorageEntitiesGenerator
69
75
  if('mikro-orm' === connectionData.driver && !this.config.client){
70
76
  connectionData.client = 'mysql';
71
77
  }
78
+ if('prisma' === connectionData.driver && !this.config.client){
79
+ connectionData.client = 'mysql';
80
+ }
72
81
  return connectionData;
73
82
  }
74
83
 
@@ -84,16 +93,54 @@ class StorageEntitiesGenerator
84
93
  validateRequiredArgs(connectionData)
85
94
  {
86
95
  if(!connectionData.user || !connectionData.database){
87
- Logger.error('Required parameters missing.');
88
- Logger.error('Usage: npx reldens-storage generateEntities --user=[db-username] --pass=[db-password] --host=[db-host] --database=[db-name] --driver=[driver-map-key] --client=[db-client] --path=[project-path] --override');
89
- Logger.error('');
90
- Logger.error('Optional flags:');
91
- Logger.error(' --override Regenerate all files even if they exist');
96
+ Logger.error(
97
+ 'Required parameters missing.',
98
+ 'Usage: npx reldens-storage generateEntities --user=[db-username]'
99
+ +' --pass=[db-password]'
100
+ +' --host=[db-host]'
101
+ +' --database=[db-name]'
102
+ +' --driver=[driver-map-key]'
103
+ +' --client=[db-client]'
104
+ +' --prismaClientPath=[path-to-prisma-client]'
105
+ +' --path=[project-path] --override',
106
+ 'Optional flags:',
107
+ ' --override Regenerate all files even if they exist'
108
+ );
92
109
  return false;
93
110
  }
94
111
  return true;
95
112
  }
96
113
 
114
+ loadPrismaClient(connectionData)
115
+ {
116
+ let prismaClientPath = this.prismaClientPath;
117
+ if(!prismaClientPath){
118
+ prismaClientPath = FileHandler.joinPaths(this.projectPath, 'prisma', 'client');
119
+ }
120
+ if(!FileHandler.exists(prismaClientPath)){
121
+ Logger.critical('PrismaClient path does not exist: '+prismaClientPath);
122
+ Logger.info('Please run "npx prisma generate" first or provide --prismaClientPath argument.');
123
+ return null;
124
+ }
125
+ Logger.info('Loading PrismaClient from: '+prismaClientPath);
126
+ let prismaModule = require(prismaClientPath);
127
+ if(!prismaModule.PrismaClient){
128
+ Logger.critical('PrismaClient class not found at: '+prismaClientPath);
129
+ return null;
130
+ }
131
+ let connectionString = connectionData.client+'://'
132
+ +connectionData.user
133
+ +(connectionData.password ? ':'+connectionData.password : '')
134
+ +'@'+connectionData.host
135
+ +':'+connectionData.port
136
+ +'/'+connectionData.database;
137
+ Logger.info('Creating PrismaClient with connection to: '+connectionData.database);
138
+ return new prismaModule.PrismaClient({
139
+ datasources: {db: {url: connectionString}},
140
+ log: ['error']
141
+ });
142
+ }
143
+
97
144
  async run()
98
145
  {
99
146
  if(!this.validateCommand()){
@@ -103,11 +150,19 @@ class StorageEntitiesGenerator
103
150
  if(!this.validateRequiredArgs(connectionData)){
104
151
  return false;
105
152
  }
106
- let generator = new EntitiesGenerator({
153
+ let generatorProps = {
107
154
  connectionData,
108
155
  projectPath: this.projectPath,
109
156
  isOverride: this.isOverride
110
- });
157
+ };
158
+ if('prisma' === connectionData.driver){
159
+ let prismaClient = this.loadPrismaClient(connectionData);
160
+ if(!prismaClient){
161
+ return false;
162
+ }
163
+ generatorProps.prismaClient = prismaClient;
164
+ }
165
+ let generator = new EntitiesGenerator(generatorProps);
111
166
  let success = await generator.generate();
112
167
  if(!success){
113
168
  Logger.error('Entity generation failed.');
@@ -208,7 +208,7 @@ class EntitiesGenerator
208
208
  }
209
209
  this.processModelForRelations(model.name, model, models);
210
210
  }
211
- Logger.info('Extracted relations metadata for ' + Object.keys(this.prismaRelationsMetadata).length + ' models.');
211
+ Logger.info('Extracted relations metadata for '+Object.keys(this.prismaRelationsMetadata).length+' models.');
212
212
  }
213
213
 
214
214
  processObjectModels(models)
@@ -225,7 +225,7 @@ class EntitiesGenerator
225
225
  }
226
226
  this.processModelForRelations(modelName, model, models);
227
227
  }
228
- Logger.info('Extracted relations metadata for ' + Object.keys(this.prismaRelationsMetadata).length + ' models.');
228
+ Logger.info('Extracted relations metadata for '+Object.keys(this.prismaRelationsMetadata).length+' models.');
229
229
  }
230
230
 
231
231
  processModelForRelations(modelName, model, allModels)
@@ -470,7 +470,8 @@ class EntitiesGenerator
470
470
  database: sc.get(this.connectionData, 'database', ''),
471
471
  host: sc.get(this.connectionData, 'host', 'localhost'),
472
472
  port: sc.get(this.connectionData, 'port', 3306)
473
- }
473
+ },
474
+ projectRoot: this.projectPath
474
475
  };
475
476
  if('prisma' === driverKey && this.prismaClient){
476
477
  serverConfig.prismaClient = this.prismaClient;
@@ -100,7 +100,7 @@ class ModelsGeneration extends BaseGenerator
100
100
  generateModelRelations(tableName, tableData, relationMetadata, driverKey)
101
101
  {
102
102
  if('prisma' === driverKey){
103
- return this.generatePrismaRelations(relationMetadata);
103
+ return this.generatePrismaRelations(tableName, tableData, relationMetadata);
104
104
  }
105
105
  if('objection-js' === driverKey){
106
106
  return this.generateObjectionJsRelations(tableName, tableData);
@@ -108,20 +108,173 @@ class ModelsGeneration extends BaseGenerator
108
108
  return '';
109
109
  }
110
110
 
111
- generatePrismaRelations(relationMetadata)
111
+ generatePrismaRelations(tableName, tableData, relationMetadata)
112
112
  {
113
113
  if(!relationMetadata || 0 === Object.keys(relationMetadata).length){
114
114
  return '';
115
115
  }
116
116
  let relationTypesArray = [];
117
- for(let relationName of Object.keys(relationMetadata)){
118
- let relation = relationMetadata[relationName];
119
- relationTypesArray.push(' '+relationName+': \''+relation.type+'\'');
117
+ let relationMappingsArray = [];
118
+ let forwardMappings = this.buildPrismaForwardMappings(tableData, relationMetadata);
119
+ let reverseMappings = this.buildPrismaReverseMappings(tableName, relationMetadata);
120
+ let allMappings = Object.assign({}, forwardMappings, reverseMappings);
121
+ for(let prismaRelationName of Object.keys(relationMetadata)){
122
+ let relation = relationMetadata[prismaRelationName];
123
+ relationTypesArray.push(' '+prismaRelationName+': \''+relation.type+'\'');
124
+ }
125
+ for(let reldensKey of Object.keys(allMappings)){
126
+ let prismaName = allMappings[reldensKey];
127
+ relationMappingsArray.push(' \''+reldensKey+'\': \''+prismaName+'\'');
128
+ }
129
+ let result = '';
130
+ if(0 < relationTypesArray.length){
131
+ result += '\n\n static get relationTypes()\n {\n return {\n';
132
+ result += relationTypesArray.join(',\n');
133
+ result += '\n };\n }';
134
+ }
135
+ if(0 < relationMappingsArray.length){
136
+ result += '\n\n static get relationMappings()\n {\n return {\n';
137
+ result += relationMappingsArray.join(',\n');
138
+ result += '\n };\n }';
139
+ }
140
+ return result;
141
+ }
142
+
143
+ buildPrismaForwardMappings(tableData, relationMetadata)
144
+ {
145
+ let mappings = {};
146
+ let referenceCounts = this.countReferencesPerTable(tableData);
147
+ for(let columnName of Object.keys(tableData.columns)){
148
+ let column = tableData.columns[columnName];
149
+ if(!sc.hasOwn(column, 'referencedTable')){
150
+ continue;
151
+ }
152
+ let reldensKey = this.generateForwardRelationKey(
153
+ column.referencedTable,
154
+ columnName,
155
+ referenceCounts
156
+ );
157
+ let prismaName = this.findPrismaRelationForFk(columnName, column.referencedTable, relationMetadata);
158
+ if(!prismaName){
159
+ continue;
160
+ }
161
+ mappings[reldensKey] = prismaName;
120
162
  }
121
- if(0 === relationTypesArray.length){
122
- return '';
163
+ return mappings;
164
+ }
165
+
166
+ findPrismaRelationForFk(columnName, referencedTable, relationMetadata)
167
+ {
168
+ let lowerColumn = columnName.toLowerCase();
169
+ let lowerTable = referencedTable.toLowerCase();
170
+ for(let prismaName of Object.keys(relationMetadata)){
171
+ let relation = relationMetadata[prismaName];
172
+ if(relation.model.toLowerCase() !== lowerTable){
173
+ continue;
174
+ }
175
+ if(relation.isList){
176
+ continue;
177
+ }
178
+ let lowerPrisma = prismaName.toLowerCase();
179
+ if(lowerPrisma.includes(lowerColumn.replace('_id', ''))){
180
+ return prismaName;
181
+ }
182
+ if(lowerPrisma.includes(lowerColumn)){
183
+ return prismaName;
184
+ }
185
+ }
186
+ for(let prismaName of Object.keys(relationMetadata)){
187
+ let relation = relationMetadata[prismaName];
188
+ if(relation.model.toLowerCase() !== lowerTable){
189
+ continue;
190
+ }
191
+ if(relation.isList){
192
+ continue;
193
+ }
194
+ return prismaName;
195
+ }
196
+ return null;
197
+ }
198
+
199
+ buildPrismaReverseMappings(tableName, relationMetadata)
200
+ {
201
+ let mappings = {};
202
+ let reverseRelations = {};
203
+ for(let prismaName of Object.keys(relationMetadata)){
204
+ let relation = relationMetadata[prismaName];
205
+ if(this.isForwardRelation(relation)){
206
+ continue;
207
+ }
208
+ let relatedTable = relation.model.toLowerCase();
209
+ if(!reverseRelations[relatedTable]){
210
+ reverseRelations[relatedTable] = [];
211
+ }
212
+ reverseRelations[relatedTable].push({prismaName, relation});
213
+ }
214
+ for(let relatedTable of Object.keys(reverseRelations)){
215
+ let relations = reverseRelations[relatedTable];
216
+ let referenceCount = relations.length;
217
+ for(let relInfo of relations){
218
+ let reldensKey = this.generatePrismaReverseRelationKey(
219
+ relatedTable,
220
+ relInfo.prismaName,
221
+ tableName,
222
+ referenceCount
223
+ );
224
+ mappings[reldensKey] = relInfo.prismaName;
225
+ }
226
+ }
227
+ return mappings;
228
+ }
229
+
230
+ isForwardRelation(relation)
231
+ {
232
+ return sc.hasOwn(relation, 'foreignKeys')
233
+ && sc.isArray(relation.foreignKeys)
234
+ && 0 < relation.foreignKeys.length;
235
+ }
236
+
237
+ generatePrismaReverseRelationKey(relatedTable, prismaName, tableName, referenceCount)
238
+ {
239
+ if(1 === referenceCount){
240
+ return 'related_'+relatedTable;
241
+ }
242
+ let columnHint = this.extractColumnHintFromPrismaName(prismaName, relatedTable, tableName);
243
+ if(columnHint){
244
+ return 'related_'+relatedTable+'_'+columnHint;
245
+ }
246
+ return 'related_'+relatedTable;
247
+ }
248
+
249
+ extractColumnHintFromPrismaName(prismaName, relatedTable, tableName)
250
+ {
251
+ let lowerName = prismaName.toLowerCase();
252
+ let lowerTable = tableName.toLowerCase();
253
+ let lowerRelated = relatedTable.toLowerCase();
254
+ let toSuffix = 'to'+lowerTable;
255
+ if(!lowerName.endsWith(toSuffix)){
256
+ toSuffix = 'to'+lowerRelated;
257
+ if(!lowerName.endsWith(toSuffix)){
258
+ return null;
259
+ }
260
+ }
261
+ let withoutSuffix = prismaName.slice(0, -toSuffix.length);
262
+ let lowerWithout = withoutSuffix.toLowerCase();
263
+ let prefixes = [
264
+ lowerRelated+'_'+lowerRelated+'_',
265
+ lowerRelated+'_',
266
+ lowerTable+'_'
267
+ ];
268
+ for(let prefix of prefixes){
269
+ if(lowerWithout.startsWith(prefix)){
270
+ withoutSuffix = withoutSuffix.slice(prefix.length);
271
+ lowerWithout = withoutSuffix.toLowerCase();
272
+ }
273
+ }
274
+ if(withoutSuffix.endsWith('_id')){
275
+ withoutSuffix = withoutSuffix.slice(0, -3);
123
276
  }
124
- return '\n\n static get relationTypes()\n {\n return {\n '+relationTypesArray.join(',\n ')+'\n };\n }';
277
+ return withoutSuffix.toLowerCase();
125
278
  }
126
279
 
127
280
  generateObjectionJsRelations(tableName, tableData)
@@ -8,6 +8,7 @@ const { BaseDataServer } = require('../base-data-server');
8
8
  const { PrismaDriver } = require('./prisma-driver');
9
9
  const { MySQLTablesProvider } = require('../mysql-tables-provider');
10
10
  const { PrismaClient } = require('@prisma/client');
11
+ const { FileHandler } = require('@reldens/server-utils');
11
12
  const { Logger, sc } = require('@reldens/utils');
12
13
 
13
14
  class PrismaDataServer extends BaseDataServer
@@ -17,6 +18,8 @@ class PrismaDataServer extends BaseDataServer
17
18
  {
18
19
  super(props);
19
20
  this.prisma = sc.get(props, 'prismaClient', false);
21
+ this.projectRoot = sc.get(props, 'projectRoot', false);
22
+ this.allRelationMappings = {};
20
23
  }
21
24
 
22
25
  async connect()
@@ -25,12 +28,16 @@ class PrismaDataServer extends BaseDataServer
25
28
  return this.initialized;
26
29
  }
27
30
  try {
28
- if(!this.prisma){
31
+ if(!this.prisma && this.defaultClientIsGenerated()){
29
32
  this.prisma = new PrismaClient({
30
33
  datasources: {db: {url: this.connectString}},
31
34
  log: this.debug ? ['query', 'info', 'warn', 'error'] : ['error']
32
35
  });
33
36
  }
37
+ if(!this.prisma){
38
+ Logger.error('Prisma client could not be initialized.');
39
+ return false;
40
+ }
34
41
  await this.prisma.$connect();
35
42
  let dbTest = await this.prisma.$queryRaw`SELECT DATABASE() as current_db`;
36
43
  Logger.info('Connected to database: ' + dbTest[0].current_db);
@@ -42,6 +49,20 @@ class PrismaDataServer extends BaseDataServer
42
49
  return false;
43
50
  }
44
51
 
52
+ defaultClientIsGenerated()
53
+ {
54
+ let existsFromProjectRoot = false;
55
+ if(this.projectRoot){
56
+ existsFromProjectRoot = FileHandler.exists(FileHandler.joinPaths(
57
+ this.projectRoot, 'node_modules', '@prisma', 'client', 'index.js'
58
+ ));
59
+ }
60
+ let existsFromRelativePath = FileHandler.exists(FileHandler.joinPaths(
61
+ __dirname, '..', '..', '..', '@prisma', 'client', 'index.js'
62
+ ));
63
+ return existsFromProjectRoot || existsFromRelativePath;
64
+ }
65
+
45
66
  generateEntities()
46
67
  {
47
68
  if(!this.initialized){
@@ -52,6 +73,7 @@ class PrismaDataServer extends BaseDataServer
52
73
  Logger.warning('Empty raw entities array, none entities generated.');
53
74
  return {};
54
75
  }
76
+ this.collectAllRelationMappings();
55
77
  this.entities = {};
56
78
  for(let i of Object.keys(this.rawEntities)){
57
79
  let rawEntity = this.rawEntities[i];
@@ -68,13 +90,25 @@ class PrismaDataServer extends BaseDataServer
68
90
  config: this.config,
69
91
  prisma: this.prisma,
70
92
  model: prismaModel,
71
- server: this
93
+ server: this,
94
+ allRelationMappings: this.allRelationMappings
72
95
  });
73
96
  }
74
97
  this.entityManager.setEntities(this.entities);
75
98
  return this.entities;
76
99
  }
77
100
 
101
+ collectAllRelationMappings()
102
+ {
103
+ for(let i of Object.keys(this.rawEntities)){
104
+ let rawEntity = this.rawEntities[i];
105
+ let tableName = rawEntity.tableName;
106
+ if(rawEntity.relationMappings){
107
+ this.allRelationMappings[tableName] = rawEntity.relationMappings;
108
+ }
109
+ }
110
+ }
111
+
78
112
  name()
79
113
  {
80
114
  return this.name || 'Prisma Data Server Driver';
@@ -103,7 +137,7 @@ class PrismaDataServer extends BaseDataServer
103
137
  //Logger.error('Statement results length is zero.', results);
104
138
  return false;
105
139
  }
106
- return 1 === results.length ? results[0] : results;
140
+ return 1 === results.length ? [...results].shift() : results;
107
141
  } catch(error) {
108
142
  Logger.error('Raw query failed: '+error.message);
109
143
  return false;
@@ -126,7 +160,7 @@ class PrismaDataServer extends BaseDataServer
126
160
  || trimmedStatement.startsWith('ALTER')
127
161
  || trimmedStatement.startsWith('DROP')
128
162
  ){
129
- return { affectedRows: result };
163
+ return {affectedRows: result};
130
164
  }
131
165
  return result;
132
166
  }