Skip to content

Commit 74e1a5e

Browse files
rtolsmaclaude
andcommitted
fix: Generate valid code for column names that are not TS identifiers
Columns like "invalid-name" produced interface properties, object literal keys, and args property accesses that were not valid TypeScript, so the generated file failed to parse. Property names are now emitted as quoted string keys and argument access falls back to element access (args["invalid-name"]) whenever the mapped name is not a valid identifier, via new propertyKey/ propertyAccess helpers shared by all four drivers. Verified with a schema containing a hyphenated column used in both a SELECT row and an INSERT parameter; output compiles under tsc --strict. Output for schemas with well-formed names is unchanged (all examples regenerate byte-for-byte identical). Fixes #70. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GFyrFwpJC2eivaBRyNBJqv
1 parent 903881e commit 74e1a5e

6 files changed

Lines changed: 53 additions & 79 deletions

File tree

‎src/app.ts‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import {
2828
Query,
2929
} from "./gen/plugin/codegen_pb";
3030

31-
import { argName, colName } from "./drivers/utlis";
31+
import { argName, colName, propertyKey } from "./drivers/utlis";
3232
import {
3333
CustomTypeFn,
3434
CustomTypeRegistry,
@@ -268,7 +268,7 @@ function argsDecl(
268268
params.map((param, i) =>
269269
factory.createPropertySignature(
270270
undefined,
271-
factory.createIdentifier(argName(i, param.column)),
271+
propertyKey(argName(i, param.column)),
272272
undefined,
273273
driver.columnType(param.column)
274274
)
@@ -289,7 +289,7 @@ function rowDecl(
289289
columns.map((column, i) =>
290290
factory.createPropertySignature(
291291
undefined,
292-
factory.createIdentifier(colName(i, column)),
292+
propertyKey(colName(i, column)),
293293
undefined,
294294
driver.columnType(column)
295295
)

‎src/drivers/better-sqlite3.ts‎

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99

1010
import { Parameter, Column, Query } from "../gen/plugin/codegen_pb";
1111
import { CustomTypeFn } from "../customTypes";
12-
import { argName } from "./utlis";
12+
import { argName, propertyAccess } from "./utlis";
1313

1414
function funcParamsDecl(iface: string | undefined, params: Parameter[]) {
1515
let funcParams = [
@@ -200,10 +200,7 @@ export class Driver {
200200
),
201201
undefined,
202202
params.map((param, i) =>
203-
factory.createPropertyAccessExpression(
204-
factory.createIdentifier("args"),
205-
factory.createIdentifier(argName(i, param.column))
206-
)
203+
propertyAccess("args", argName(i, param.column))
207204
)
208205
)
209206
)
@@ -286,10 +283,7 @@ export class Driver {
286283
),
287284
undefined,
288285
params.map((param, i) =>
289-
factory.createPropertyAccessExpression(
290-
factory.createIdentifier("args"),
291-
factory.createIdentifier(argName(i, param.column))
292-
)
286+
propertyAccess("args", argName(i, param.column))
293287
)
294288
)
295289
)
@@ -401,10 +395,7 @@ export class Driver {
401395
),
402396
undefined,
403397
params.map((param, i) =>
404-
factory.createPropertyAccessExpression(
405-
factory.createIdentifier("args"),
406-
factory.createIdentifier(argName(i, param.column))
407-
)
398+
propertyAccess("args", argName(i, param.column))
408399
)
409400
)
410401
)

‎src/drivers/mysql2.ts‎

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { SyntaxKind, NodeFlags, TypeNode, factory } from "typescript";
44

55
import { Parameter, Column, Query } from "../gen/plugin/codegen_pb";
66
import { CustomTypeFn } from "../customTypes";
7-
import { argName, colName } from "./utlis";
7+
import { argName, colName, propertyAccess, propertyKey } from "./utlis";
88

99
export interface Mysql2Options {
1010
support_big_numbers?: boolean;
@@ -334,10 +334,7 @@ export class Driver {
334334
factory.createIdentifier("values"),
335335
factory.createArrayLiteralExpression(
336336
params.map((param, i) =>
337-
factory.createPropertyAccessExpression(
338-
factory.createIdentifier("args"),
339-
factory.createIdentifier(argName(i, param.column))
340-
)
337+
propertyAccess("args", argName(i, param.column))
341338
),
342339
false
343340
)
@@ -424,12 +421,7 @@ export class Driver {
424421
factory.createIdentifier("values"),
425422
factory.createArrayLiteralExpression(
426423
params.map((param, i) =>
427-
factory.createPropertyAccessExpression(
428-
factory.createIdentifier("args"),
429-
factory.createIdentifier(
430-
argName(i, param.column)
431-
)
432-
)
424+
propertyAccess("args", argName(i, param.column))
433425
),
434426
false
435427
)
@@ -483,7 +475,7 @@ export class Driver {
483475
factory.createObjectLiteralExpression(
484476
columns.map((col, i) =>
485477
factory.createPropertyAssignment(
486-
factory.createIdentifier(colName(i, col)),
478+
propertyKey(colName(i, col)),
487479
factory.createElementAccessExpression(
488480
factory.createIdentifier("row"),
489481
factory.createNumericLiteral(`${i}`)
@@ -576,12 +568,7 @@ export class Driver {
576568
factory.createIdentifier("values"),
577569
factory.createArrayLiteralExpression(
578570
params.map((param, i) =>
579-
factory.createPropertyAccessExpression(
580-
factory.createIdentifier("args"),
581-
factory.createIdentifier(
582-
argName(i, param.column)
583-
)
584-
)
571+
propertyAccess("args", argName(i, param.column))
585572
),
586573
false
587574
)
@@ -647,7 +634,7 @@ export class Driver {
647634
factory.createObjectLiteralExpression(
648635
columns.map((col, i) =>
649636
factory.createPropertyAssignment(
650-
factory.createIdentifier(colName(i, col)),
637+
propertyKey(colName(i, col)),
651638
factory.createElementAccessExpression(
652639
factory.createIdentifier("row"),
653640
factory.createNumericLiteral(`${i}`)
@@ -723,12 +710,7 @@ export class Driver {
723710
factory.createIdentifier("values"),
724711
factory.createArrayLiteralExpression(
725712
params.map((param, i) =>
726-
factory.createPropertyAccessExpression(
727-
factory.createIdentifier("args"),
728-
factory.createIdentifier(
729-
argName(i, param.column)
730-
)
731-
)
713+
propertyAccess("args", argName(i, param.column))
732714
),
733715
false
734716
)

‎src/drivers/pg.ts‎

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99

1010
import { Parameter, Column, Query } from "../gen/plugin/codegen_pb";
1111
import { CustomTypeFn } from "../customTypes";
12-
import { argName, colName } from "./utlis";
12+
import { argName, colName, propertyAccess, propertyKey } from "./utlis";
1313

1414
function funcParamsDecl(iface: string | undefined, params: Parameter[]) {
1515
let funcParams = [
@@ -482,10 +482,7 @@ export class Driver {
482482
factory.createIdentifier("values"),
483483
factory.createArrayLiteralExpression(
484484
params.map((param, i) =>
485-
factory.createPropertyAccessExpression(
486-
factory.createIdentifier("args"),
487-
factory.createIdentifier(argName(i, param.column))
488-
)
485+
propertyAccess("args", argName(i, param.column))
489486
),
490487
false
491488
)
@@ -563,12 +560,7 @@ export class Driver {
563560
factory.createIdentifier("values"),
564561
factory.createArrayLiteralExpression(
565562
params.map((param, i) =>
566-
factory.createPropertyAccessExpression(
567-
factory.createIdentifier("args"),
568-
factory.createIdentifier(
569-
argName(i, param.column)
570-
)
571-
)
563+
propertyAccess("args", argName(i, param.column))
572564
),
573565
false
574566
)
@@ -640,7 +632,7 @@ export class Driver {
640632
factory.createObjectLiteralExpression(
641633
columns.map((col, i) =>
642634
factory.createPropertyAssignment(
643-
factory.createIdentifier(colName(i, col)),
635+
propertyKey(colName(i, col)),
644636
factory.createElementAccessExpression(
645637
factory.createIdentifier("row"),
646638
factory.createNumericLiteral(`${i}`)
@@ -711,12 +703,7 @@ export class Driver {
711703
factory.createIdentifier("values"),
712704
factory.createArrayLiteralExpression(
713705
params.map((param, i) =>
714-
factory.createPropertyAccessExpression(
715-
factory.createIdentifier("args"),
716-
factory.createIdentifier(
717-
argName(i, param.column)
718-
)
719-
)
706+
propertyAccess("args", argName(i, param.column))
720707
),
721708
false
722709
)
@@ -773,7 +760,7 @@ export class Driver {
773760
factory.createObjectLiteralExpression(
774761
columns.map((col, i) =>
775762
factory.createPropertyAssignment(
776-
factory.createIdentifier(colName(i, col)),
763+
propertyKey(colName(i, col)),
777764
factory.createElementAccessExpression(
778765
factory.createIdentifier("row"),
779766
factory.createNumericLiteral(`${i}`)

‎src/drivers/postgres.ts‎

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88

99
import { Parameter, Column } from "../gen/plugin/codegen_pb";
1010
import { CustomTypeFn } from "../customTypes";
11-
import { argName, colName } from "./utlis";
11+
import { argName, colName, propertyAccess, propertyKey } from "./utlis";
1212
import { log } from "../logger";
1313

1414
function funcParamsDecl(iface: string | undefined, params: Parameter[]) {
@@ -363,10 +363,7 @@ export class Driver {
363363
factory.createIdentifier(queryName),
364364
factory.createArrayLiteralExpression(
365365
params.map((param, i) =>
366-
factory.createPropertyAccessExpression(
367-
factory.createIdentifier("args"),
368-
factory.createIdentifier(argName(i, param.column))
369-
)
366+
propertyAccess("args", argName(i, param.column))
370367
),
371368
false
372369
),
@@ -425,12 +422,7 @@ export class Driver {
425422
factory.createIdentifier(queryName),
426423
factory.createArrayLiteralExpression(
427424
params.map((param, i) =>
428-
factory.createPropertyAccessExpression(
429-
factory.createIdentifier("args"),
430-
factory.createIdentifier(
431-
argName(i, param.column)
432-
)
433-
)
425+
propertyAccess("args", argName(i, param.column))
434426
),
435427
false
436428
),
@@ -461,7 +453,7 @@ export class Driver {
461453
factory.createObjectLiteralExpression(
462454
columns.map((col, i) =>
463455
factory.createPropertyAssignment(
464-
factory.createIdentifier(colName(i, col)),
456+
propertyKey(colName(i, col)),
465457
factory.createElementAccessExpression(
466458
factory.createIdentifier("row"),
467459
factory.createNumericLiteral(`${i}`)
@@ -531,12 +523,7 @@ export class Driver {
531523
factory.createIdentifier(queryName),
532524
factory.createArrayLiteralExpression(
533525
params.map((param, i) =>
534-
factory.createPropertyAccessExpression(
535-
factory.createIdentifier("args"),
536-
factory.createIdentifier(
537-
argName(i, param.column)
538-
)
539-
)
526+
propertyAccess("args", argName(i, param.column))
540527
),
541528
false
542529
),
@@ -605,7 +592,7 @@ export class Driver {
605592
factory.createObjectLiteralExpression(
606593
columns.map((col, i) =>
607594
factory.createPropertyAssignment(
608-
factory.createIdentifier(colName(i, col)),
595+
propertyKey(colName(i, col)),
609596
factory.createElementAccessExpression(
610597
factory.createIdentifier("row"),
611598
factory.createNumericLiteral(`${i}`)

‎src/drivers/utlis.ts‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { Expression, PropertyName, factory } from "typescript";
2+
13
import { Column } from "../gen/plugin/codegen_pb";
24

35
// https://stackoverflow.com/questions/40710628/how-to-convert-snake-case-to-camelcase
@@ -22,3 +24,28 @@ export function argName(index: number, column?: Column): string {
2224
export function colName(index: number, column?: Column): string {
2325
return fieldName("col", index, column);
2426
}
27+
28+
const validIdentifier = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
29+
30+
// Property name for an interface or object literal: a plain identifier when
31+
// possible, otherwise a quoted string ("invalid-name": ...)
32+
export function propertyKey(name: string): PropertyName {
33+
if (validIdentifier.test(name)) {
34+
return factory.createIdentifier(name);
35+
}
36+
return factory.createStringLiteral(name);
37+
}
38+
39+
// target.name when name is a valid identifier, otherwise target["name"]
40+
export function propertyAccess(target: string, name: string): Expression {
41+
if (validIdentifier.test(name)) {
42+
return factory.createPropertyAccessExpression(
43+
factory.createIdentifier(target),
44+
factory.createIdentifier(name)
45+
);
46+
}
47+
return factory.createElementAccessExpression(
48+
factory.createIdentifier(target),
49+
factory.createStringLiteral(name)
50+
);
51+
}

0 commit comments

Comments
 (0)