Overview
The CamelCasePlugin converts snake_case identifiers in the database into camelCase in the JavaScript side. This allows you to use JavaScript naming conventions in your code while maintaining SQL naming conventions in the database.
Installation
import { Kysely, CamelCasePlugin } from 'kysely'
const db = new Kysely<Database>({
dialect,
plugins: [new CamelCasePlugin()]
})
Usage Example
Assuming you have a table called person_table with columns first_name and last_name in the database:
import * as Sqlite from 'better-sqlite3'
import { CamelCasePlugin, Kysely, SqliteDialect } from 'kysely'
interface CamelCasedDatabase {
userMetadata: {
firstName: string
lastName: string
}
}
const db = new Kysely<CamelCasedDatabase>({
dialect: new SqliteDialect({
database: new Sqlite(':memory:'),
}),
plugins: [new CamelCasePlugin()],
})
const person = await db.selectFrom('userMetadata')
.where('firstName', '=', 'Arnold')
.select(['firstName', 'lastName'])
.executeTakeFirst()
if (person) {
console.log(person.firstName)
}
Generated SQL (SQLite):
select "first_name", "last_name" from "user_metadata" where "first_name" = ?
Everything must be defined in camelCase in the TypeScript code: table names, columns, schemas, everything. When using the CamelCasePlugin, Kysely works as if the database was defined in camelCase.
Constructor Options
interface CamelCasePluginOptions {
upperCase?: boolean
underscoreBeforeDigits?: boolean
underscoreBetweenUppercaseLetters?: boolean
maintainNestedObjectKeys?: boolean
}
upperCase
Type: boolean
Default: false
If true, camelCase is transformed into upper case SNAKE_CASE.
Example:
new CamelCasePlugin({ upperCase: true })
// fooBar => FOO_BAR
// FOO_BAR => fooBar
underscoreBeforeDigits
Type: boolean
Default: false
If true, an underscore is added before each digit when converting camelCase to snake_case.
Example:
new CamelCasePlugin({ underscoreBeforeDigits: true })
// foo12Bar => foo_12_bar
// foo_12_bar => foo12Bar
underscoreBetweenUppercaseLetters
Type: boolean
Default: false
If true, an underscore is added between consecutive upper case letters when converting from camelCase to snake_case.
Example:
new CamelCasePlugin({ underscoreBetweenUppercaseLetters: true })
// fooBAR => foo_b_a_r
// foo_b_a_r => fooBAR
maintainNestedObjectKeys
Type: boolean
Default: false
If true, nested object’s keys will not be converted to camelCase.
Example:
new CamelCasePlugin({ maintainNestedObjectKeys: true })
// Nested objects in results keep their original keys
Methods
transformQuery(args: PluginTransformQueryArgs): RootOperationNode
Transforms all identifiers in the query from camelCase to snake_case before execution.
Source: ~/workspace/source/src/plugin/camel-case/camel-case-plugin.ts:135
async transformResult(
args: PluginTransformResultArgs
): Promise<QueryResult<UnknownRow>>
Transforms all keys in the result rows from snake_case to camelCase after execution.
Source: ~/workspace/source/src/plugin/camel-case/camel-case-plugin.ts:139
Custom Conversion Logic
You can override the plugin’s conversion methods for custom behavior:
class MyCamelCasePlugin extends CamelCasePlugin {
protected override snakeCase(str: string): string {
// Custom snake_case conversion logic
return str
}
protected override camelCase(str: string): string {
// Custom camelCase conversion logic
return str
}
}
snakeCase
protected snakeCase(str: string): string
Converts a camelCase string to snake_case. Override this method to customize the conversion.
Source: ~/workspace/source/src/plugin/camel-case/camel-case-plugin.ts:167
camelCase
protected camelCase(str: string): string
Converts a snake_case string to camelCase. Override this method to customize the conversion.
Source: ~/workspace/source/src/plugin/camel-case/camel-case-plugin.ts:171
How It Works
- Query Transformation: When a query is built, the plugin uses a
SnakeCaseTransformer to convert all identifier names from camelCase to snake_case
- Result Transformation: After query execution, the plugin recursively processes all result rows, converting keys from snake_case to camelCase
- Nested Objects: By default, nested objects and arrays are also processed recursively (unless
maintainNestedObjectKeys is true)
See Also