Kysely and StudioCMS SDK
此内容尚不支持你的语言。
The following packages are built-in to StudioCMS and provide the core database functionality used by StudioCMS. They are intended to be used internally by StudioCMS, but users can also use them directly in their projects for more advanced use cases.
These packages are primarily intended for internal use by StudioCMS. While you can use them directly in your projects, be aware that they may change without notice as StudioCMS evolves.
Introduction to Kysely
Section titled “Introduction to Kysely”Kysely^ is a type-safe SQL query builder for TypeScript. It provides a powerful and flexible way to interact with databases while ensuring type safety and reducing runtime errors. Kysely supports various SQL databases, including PostgreSQL, MySQL, SQLite, and more. It allows developers to construct SQL queries using a fluent API, making it easier to read and maintain database interactions in TypeScript applications.
Currently StudioCMS only supports libSQL(SQLite), MySQL, and PostgreSQL databases via Kysely. In the future, support for other database dialects can be added as needed or requested.
Want to have another database dialect supported? Check out the Kysely Dialects documentation^ and open an issue on the StudioCMS GitHub repository^.
The Kysely Client package
Section titled “The Kysely Client package”@withstudiocms/kysely
A type-safe database client and migration system for StudioCMS, built on top of Kysely^. Provides a unified interface for working with libSQL, MySQL, and PostgreSQL databases with runtime schema management and migrations.
Features
Section titled “Features”- Type-Safe Database Operations - Full TypeScript support with Kysely’s type-safe query builder
- Multi-Database Support - Works with libSQL (SQLite), MySQL, and PostgreSQL
- Runtime Schema Management - Dynamic schema creation and validation
- Error Handling - Custom error types for better debugging
- TypeScript-Based Migrations - File-based migrations with automatic tracking
- Schema Introspection - Inspect and validate database schemas at runtime
- Effect-ts Integration - Functional programming patterns with Effect-ts
Code Example
Section titled “Code Example”Basic client setup
Section titled “Basic client setup”import { const getDBClientLive: <Schema>(dialect: Dialect) => KyselyDBClientLive<Schema>
Factory that creates a live database client configured for the specified SQL dialect.
This exported helper forwards the provided dialect to an underlying makeDBClientLive
implementation and returns the resulting database client instance typed to the supplied
schema generic.
getDBClientLive, type type StudioCMSDatabaseSchema = { readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}const StudioCMSDatabaseSchema: Struct<{ StudioCMSUsersTable: Table<{ id: typeof String$; url: NullishOr<typeof String$>; name: typeof String$; email: NullishOr<typeof String$>; avatar: NullishOr<typeof String$>; username: typeof String$; password: NullishOr<typeof String$>; updatedAt: Schema<ColumnType<Date, string, string>, ColumnType<string, string, string>, never> & ColumnTypes<typeof DateFromString, typeof String$, typeof String$>; createdAt: Schema<ColumnType<Date, string | undefined, never>, ColumnType<string, string | undefined, never>, never> & ColumnTypes<...>; emailVerified: transform<typeof Number$, typeof Boolean$>; notifications: NullishOr<typeof String$>; }>; ... 13 more ...; StudioCMSDynamicConfigSettings: Table<{ id: typeof String$; data: Schema<ColumnType<...>, ColumnType<...>, never> & ColumnTypes<...>; }>;}>
Complete StudioCMS Database Schema Definition
Type representing the StudioCMS Database Schema.
StudioCMSDatabaseSchema } from '@withstudiocms/kysely';import { const libsqlDriver: Effect.Effect<LibsqlDialect, ConfigError, never>
Effect that builds and returns a LibsqlDialect configured from environment-backed configuration.
This generator reads the following configuration keys:
STUDIOCMS_LIBSQL_URL (required, redacted) — connection URL for the libsql instance.
STUDIOCMS_LIBSQL_AUTH_TOKEN (required, redacted) — authentication token for the libsql instance.
STUDIOCMS_LIBSQL_SYNC_INTERVAL (optional) — synchronization interval in milliseconds. If not set, no interval is configured.
STUDIOCMS_LIBSQL_SYNC_URL (optional, redacted) — optional sync URL. If not set, no sync URL is configured.
Secrets (URL, auth token, sync URL) are obtained via the redacted config helpers and passed to the dialect via Redacted.value to preserve redaction semantics.
The returned Effect yields a fully constructed LibsqlDialect instance:
- url: string (from STUDIOCMS_LIBSQL_URL)
- authToken: string (from STUDIOCMS_LIBSQL_AUTH_TOKEN)
- syncInterval?: number (from STUDIOCMS_LIBSQL_SYNC_INTERVAL, or undefined)
- syncUrl?: string (from STUDIOCMS_LIBSQL_SYNC_URL, or undefined)
libsqlDriver } from '@withstudiocms/kysely/drivers/libsql';import { import ConfigProvider
ConfigProvider, import Effect
Effect } from 'studiocms/effect';
export const const getDbClient: Effect.Effect<DBClientInterface<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>, ConfigError, never>
getDbClient = import Effect
Effect.const gen: <YieldWrap<Effect.Effect<LibsqlDialect, ConfigError, never>> | YieldWrap<Effect.Effect<DBClientInterface<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>, never, never>>, DBClientInterface<...>>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
Provides a way to write effectful code using generator functions, simplifying
control flow and error handling.
When to Use
Effect.gen allows you to write code that looks and behaves like synchronous
code, but it can handle asynchronous tasks, errors, and complex control flow
(like loops and conditions). It helps make asynchronous code more readable
and easier to manage.
The generator functions work similarly to async/await but with more
explicit control over the execution of effects. You can yield* values from
effects and return the final result at the end.
Example
import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = ( total: number, discountRate: number): Effect.Effect<number, Error> => discountRate === 0 ? Effect.fail(new Error("Discount rate cannot be zero")) : Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () { const transactionAmount = yield* fetchTransactionAmount const discountRate = yield* fetchDiscountRate const discountedAmount = yield* applyDiscount( transactionAmount, discountRate ) const finalAmount = addServiceCharge(discountedAmount) return `Final amount to charge: ${finalAmount}`})
gen(function* () { // Setup the LibSQL driver with a database URL from config const const dialect: LibsqlDialect
dialect = yield* const libsqlDriver: Effect.Effect<LibsqlDialect, ConfigError, never>
Effect that builds and returns a LibsqlDialect configured from environment-backed configuration.
This generator reads the following configuration keys:
STUDIOCMS_LIBSQL_URL (required, redacted) — connection URL for the libsql instance.
STUDIOCMS_LIBSQL_AUTH_TOKEN (required, redacted) — authentication token for the libsql instance.
STUDIOCMS_LIBSQL_SYNC_INTERVAL (optional) — synchronization interval in milliseconds. If not set, no interval is configured.
STUDIOCMS_LIBSQL_SYNC_URL (optional, redacted) — optional sync URL. If not set, no sync URL is configured.
Secrets (URL, auth token, sync URL) are obtained via the redacted config helpers and passed to the dialect via Redacted.value to preserve redaction semantics.
The returned Effect yields a fully constructed LibsqlDialect instance:
- url: string (from STUDIOCMS_LIBSQL_URL)
- authToken: string (from STUDIOCMS_LIBSQL_AUTH_TOKEN)
- syncInterval?: number (from STUDIOCMS_LIBSQL_SYNC_INTERVAL, or undefined)
- syncUrl?: string (from STUDIOCMS_LIBSQL_SYNC_URL, or undefined)
libsqlDriver.Pipeable.pipe<Effect.Effect<LibsqlDialect, ConfigError, never>, Effect.Effect<LibsqlDialect, ConfigError, never>>(this: Effect.Effect<LibsqlDialect, ConfigError, never>, ab: (_: Effect.Effect<LibsqlDialect, ConfigError, never>) => Effect.Effect<LibsqlDialect, ConfigError, never>): Effect.Effect<LibsqlDialect, ConfigError, never> (+21 overloads)
pipe( import Effect
Effect.const withConfigProvider: (provider: ConfigProvider.ConfigProvider) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R> (+1 overload)
Executes an effect using a specific configuration provider.
Details
This function lets you run an effect with a specified configuration provider.
The custom provider will override the default configuration provider for the
duration of the effect's execution.
When to Use
This is particularly useful when you need to use a different set of
configuration values or sources for specific parts of your application.
Example
import { Config, ConfigProvider, Effect } from "effect"
const customProvider: ConfigProvider.ConfigProvider = ConfigProvider.fromMap( new Map([["custom-key", "custom-value"]]))
const program = Effect.withConfigProvider(customProvider)( Effect.gen(function*() { const value = yield* Config.string("custom-key") console.log(`Config value: ${value}`) }))
Effect.runPromise(program)// Output:// Config value: custom-value
withConfigProvider( import ConfigProvider
ConfigProvider.const fromJson: (json: unknown) => ConfigProvider.ConfigProvider
Constructs a new ConfigProvider from a JSON object.
fromJson({ type CMS_LIBSQL_URL: string
CMS_LIBSQL_URL: 'file:./test.db', }) ) );
// Return the Kysely DB client with Effect helpers return yield* getDBClientLive<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>(dialect: Dialect): KyselyDBClientLive<...>
Factory that creates a live database client configured for the specified SQL dialect.
This exported helper forwards the provided dialect to an underlying makeDBClientLive
implementation and returns the resulting database client instance typed to the supplied
schema generic.
getDBClientLive<type StudioCMSDatabaseSchema = { readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}
Complete StudioCMS Database Schema Definition
Type representing the StudioCMS Database Schema.
StudioCMSDatabaseSchema>(const dialect: LibsqlDialect
dialect);});Get users example
Section titled “Get users example”import { import Schema
Schema } from 'studiocms/effect';import { const StudioCMSUsersTable: Table<{ id: typeof Schema.String; url: Schema.NullishOr<typeof Schema.String>; name: typeof Schema.String; email: Schema.NullishOr<typeof Schema.String>; avatar: Schema.NullishOr<typeof Schema.String>; username: typeof Schema.String; password: Schema.NullishOr<typeof Schema.String>; updatedAt: Schema.Schema<ColumnType<Date, string, string>, ColumnType<string, string, string>, never> & ColumnTypes<typeof Schema.DateFromString, typeof Schema.String, typeof Schema.String>; createdAt: Schema.Schema<ColumnType<...>, ColumnType<...>, never> & ColumnTypes<...>; emailVerified: Schema.transform<typeof Schema.Number, typeof Schema.Boolean>; notifications: Schema.NullishOr<typeof Schema.String>;}>
StudioCMS Users Table Definition
StudioCMSUsersTable } from '@withstudiocms/kysely';
export const const getUsers: Effect.Effect<void, ConfigError | DBCallbackFailure | DatabaseError, never>
getUsers = import Effect
Effect.const gen: <YieldWrap<Effect.Effect<DBClientInterface<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>, ConfigError, never>> | YieldWrap<...>, void>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
Provides a way to write effectful code using generator functions, simplifying
control flow and error handling.
When to Use
Effect.gen allows you to write code that looks and behaves like synchronous
code, but it can handle asynchronous tasks, errors, and complex control flow
(like loops and conditions). It helps make asynchronous code more readable
and easier to manage.
The generator functions work similarly to async/await but with more
explicit control over the execution of effects. You can yield* values from
effects and return the final result at the end.
Example
import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = ( total: number, discountRate: number): Effect.Effect<number, Error> => discountRate === 0 ? Effect.fail(new Error("Discount rate cannot be zero")) : Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () { const transactionAmount = yield* fetchTransactionAmount const discountRate = yield* fetchDiscountRate const discountedAmount = yield* applyDiscount( transactionAmount, discountRate ) const finalAmount = addServiceCharge(discountedAmount) return `Final amount to charge: ${finalAmount}`})
gen(function* () { const { const withDecoder: <OEncoded, OType>({ decoder, callbackFn, }: { decoder: Schema.Schema<OType, OEncoded, never>; callbackFn: DBCallbackFn<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; }; }, undefined, OEncoded>;}) => () => Effect.Effect<...>
Creates a function that decodes output data after executing a database operation.
withDecoder } = yield* const getDbClient: Effect.Effect<DBClientInterface<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>, ConfigError, never>
getDbClient;
const const getUsers: () => Effect.Effect<readonly { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: Date; readonly createdAt: Date; readonly emailVerified: boolean; readonly notifications: string | null | undefined;}[], DBCallbackFailure | DatabaseError, never>
getUsers = const withDecoder: <readonly { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: string; readonly createdAt: string; readonly emailVerified: number; readonly notifications: string | null | undefined;}[], readonly { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; ... 5 more ...; readonly notifications: string | ... 1 more ... | undefined;}[]>({ decoder, callbackFn, }: { ...;}) => () => Effect.Effect<...>
Creates a function that decodes output data after executing a database operation.
withDecoder({ decoder: Schema.Schema<readonly { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: Date; readonly createdAt: Date; readonly emailVerified: boolean; readonly notifications: string | null | undefined;}[], readonly { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; ... 5 more ...; readonly notifications: string | ... 1 more ... | undefined;}[], never>
decoder: import Schema
Schema.Array<Schema.Struct<{ readonly id: Schema.Schema<string, string, never>; readonly url: Schema.Schema<string | null | undefined, string | null | undefined, never>; readonly name: Schema.Schema<string, string, never>; readonly email: Schema.Schema<string | null | undefined, string | null | undefined, never>; readonly avatar: Schema.Schema<string | null | undefined, string | null | undefined, never>; readonly username: Schema.Schema<string, string, never>; readonly password: Schema.Schema<string | null | undefined, string | ... 1 more ... | undefined, never>; readonly updatedAt: Schema.Schema<...>; readonly createdAt: Schema.Schema<...>; readonly emailVerified: Schema.Schema<...>; readonly notifications: Schema.Schema<...>;}>>(value: Schema.Struct<...>): Schema.Array$<...>export Array
Array(const StudioCMSUsersTable: Table<{ id: typeof Schema.String; url: Schema.NullishOr<typeof Schema.String>; name: typeof Schema.String; email: Schema.NullishOr<typeof Schema.String>; avatar: Schema.NullishOr<typeof Schema.String>; username: typeof Schema.String; password: Schema.NullishOr<typeof Schema.String>; updatedAt: Schema.Schema<ColumnType<Date, string, string>, ColumnType<string, string, string>, never> & ColumnTypes<typeof Schema.DateFromString, typeof Schema.String, typeof Schema.String>; createdAt: Schema.Schema<ColumnType<...>, ColumnType<...>, never> & ColumnTypes<...>; emailVerified: Schema.transform<typeof Schema.Number, typeof Schema.Boolean>; notifications: Schema.NullishOr<typeof Schema.String>;}>
StudioCMS Users Table Definition
StudioCMSUsersTable.type Select: Schema.Struct<{ readonly id: Schema.Schema<string, string, never>; readonly url: Schema.Schema<string | null | undefined, string | null | undefined, never>; readonly name: Schema.Schema<string, string, never>; readonly email: Schema.Schema<string | null | undefined, string | null | undefined, never>; readonly avatar: Schema.Schema<string | null | undefined, string | null | undefined, never>; readonly username: Schema.Schema<string, string, never>; readonly password: Schema.Schema<string | null | undefined, string | ... 1 more ... | undefined, never>; readonly updatedAt: Schema.Schema<...>; readonly createdAt: Schema.Schema<...>; readonly emailVerified: Schema.Schema<...>; readonly notifications: Schema.Schema<...>;}>
- A mapping of column names to the types returned by SELECT queries.
Typically these types represent the actual stored or computed values.
Select), callbackFn: DBCallbackFn<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}, undefined, readonly { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; ... 5 more ...; readonly notifications: string | ... 1 more ... | undefined;}[]>
callbackFn: (db: DBCallback<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>
db) => db: <{ id: string; url: string | null | undefined; name: string; email: string | null | undefined; avatar: string | null | undefined; username: string; password: string | null | undefined; updatedAt: string; createdAt: string; emailVerified: number; notifications: string | null | undefined;}[]>(fn: (db: Kysely<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>) => Promise<...>) => Effect.Effect<out A, out E = never, out R = never>.AsEffect<...>
db((client: Kysely<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>
client) => client: Kysely<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>
client.QueryCreator<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; }; }>.selectFrom<"StudioCMSUsersTable">(from: "StudioCMSUsersTable"): SelectQueryBuilder<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}, "StudioCMSUsersTable", {}>
Creates a select query builder for the given table or tables.
The tables passed to this method are built as the query's from clause.
Examples
Create a select query for one table:
db.selectFrom('person').selectAll()
The generated SQL (PostgreSQL):
select * from "person"
Create a select query for one table with an alias:
const persons = await db.selectFrom('person as p') .select(['p.id', 'first_name']) .execute()
console.log(persons[0].id)
The generated SQL (PostgreSQL):
select "p"."id", "first_name" from "person" as "p"
Create a select query from a subquery:
const persons = await db.selectFrom( (eb) => eb.selectFrom('person').select('person.id as identifier').as('p') ) .select('p.identifier') .execute()
console.log(persons[0].identifier)
The generated SQL (PostgreSQL):
select "p"."identifier",from ( select "person"."id" as "identifier" from "person") as p
Create a select query from raw sql:
import { sql } from 'kysely'
const items = await db .selectFrom(sql<{ one: number }>`(select 1 as one)`.as('q')) .select('q.one') .execute()
console.log(items[0].one)
The generated SQL (PostgreSQL):
select "q"."one",from ( select 1 as one) as q
When you use the sql tag you need to also provide the result type of the
raw snippet / query so that Kysely can figure out what columns are
available for the rest of the query.
The selectFrom method also accepts an array for multiple tables. All
the above examples can also be used in an array.
import { sql } from 'kysely'
const items = await db.selectFrom([ 'person as p', db.selectFrom('pet').select('pet.species').as('a'), sql<{ one: number }>`(select 1 as one)`.as('q') ]) .select(['p.id', 'a.species', 'q.one']) .execute()
The generated SQL (PostgreSQL):
select "p".id, "a"."species", "q"."one"from "person" as "p", (select "pet"."species" from "pet") as a, (select 1 as one) as "q"
selectFrom('StudioCMSUsersTable').SelectQueryBuilder<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; }; }, "StudioCMSUsersTable", {}>.selectAll(): SelectQueryBuilder<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}, "StudioCMSUsersTable", { ...;}> (+2 overloads)
Adds a select * or select table.* clause to the query.
Examples
The selectAll method generates SELECT *:
const persons = await db .selectFrom('person') .selectAll() .execute()
The generated SQL (PostgreSQL):
select * from "person"
Select all columns of a table:
const persons = await db .selectFrom('person') .selectAll('person') .execute()
The generated SQL (PostgreSQL):
select "person".* from "person"
Select all columns of multiple tables:
const personsPets = await db .selectFrom(['person', 'pet']) .selectAll(['person', 'pet']) .execute()
The generated SQL (PostgreSQL):
select "person".*, "pet".* from "person", "pet"
selectAll().SelectQueryBuilder<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; }; }, "StudioCMSUsersTable", { ...; }>.execute(): Promise<{ id: string; url: string | null | undefined; name: string; email: string | null | undefined; avatar: string | null | undefined; username: string; password: string | null | undefined; updatedAt: string; createdAt: string; emailVerified: number; notifications: string | null | undefined;}[]>
Executes the query and returns an array of rows.
Also see the
executeTakeFirst
and
executeTakeFirstOrThrow
methods.
execute()), });
const const users: readonly { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: Date; readonly createdAt: Date; readonly emailVerified: boolean; readonly notifications: string | null | undefined;}[]
users = yield* const getUsers: () => Effect.Effect<readonly { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: Date; readonly createdAt: Date; readonly emailVerified: boolean; readonly notifications: string | null | undefined;}[], DBCallbackFailure | DatabaseError, never>
getUsers(); var console: Console
The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
- A
Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
- A global
console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.
Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.
Example using the global console:
console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err);
myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err
console.Console.log(message?: any, ...optionalParams: any[]): void
Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).
const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout
See util.format() for more information.
log('Users:', const users: readonly { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: Date; readonly createdAt: Date; readonly emailVerified: boolean; readonly notifications: string | null | undefined;}[]
users); /* type of 'users' is: const users: readonly { readonly url: string | null | undefined; readonly id: string; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: Date; readonly createdAt: Date; readonly emailVerified: boolean; readonly notifications: string | null | undefined; }[] */});Insert new user example (withEncoder)
Section titled “Insert new user example (withEncoder)”import { import Schema
Schema } from 'studiocms/effect';import { const StudioCMSUsersTable: Table<{ id: typeof Schema.String; url: Schema.NullishOr<typeof Schema.String>; name: typeof Schema.String; email: Schema.NullishOr<typeof Schema.String>; avatar: Schema.NullishOr<typeof Schema.String>; username: typeof Schema.String; password: Schema.NullishOr<typeof Schema.String>; updatedAt: Schema.Schema<ColumnType<Date, string, string>, ColumnType<string, string, string>, never> & ColumnTypes<typeof Schema.DateFromString, typeof Schema.String, typeof Schema.String>; createdAt: Schema.Schema<ColumnType<...>, ColumnType<...>, never> & ColumnTypes<...>; emailVerified: Schema.transform<typeof Schema.Number, typeof Schema.Boolean>; notifications: Schema.NullishOr<typeof Schema.String>;}>
StudioCMS Users Table Definition
StudioCMSUsersTable } from '@withstudiocms/kysely';
export const const insertUser: Effect.Effect<void, ConfigError | DBCallbackFailure | DatabaseError, never>
insertUser = import Effect
Effect.const gen: <YieldWrap<Effect.Effect<DBClientInterface<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>, ConfigError, never>> | YieldWrap<...>, void>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
Provides a way to write effectful code using generator functions, simplifying
control flow and error handling.
When to Use
Effect.gen allows you to write code that looks and behaves like synchronous
code, but it can handle asynchronous tasks, errors, and complex control flow
(like loops and conditions). It helps make asynchronous code more readable
and easier to manage.
The generator functions work similarly to async/await but with more
explicit control over the execution of effects. You can yield* values from
effects and return the final result at the end.
Example
import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = ( total: number, discountRate: number): Effect.Effect<number, Error> => discountRate === 0 ? Effect.fail(new Error("Discount rate cannot be zero")) : Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () { const transactionAmount = yield* fetchTransactionAmount const discountRate = yield* fetchDiscountRate const discountedAmount = yield* applyDiscount( transactionAmount, discountRate ) const finalAmount = addServiceCharge(discountedAmount) return `Final amount to charge: ${finalAmount}`})
gen(function* () { const { const withEncoder: <IEncoded, IType, O, CIType = OmitNever<{ [K in keyof IType as HasNullOrUndefined<IType[K]> extends true ? K : never]?: IType[K] extends object ? IType[K] extends any[] ? IType[K] : OmitNever<{ [K in keyof IType[K] as HasNullOrUndefined<IType[K][K]> extends true ? K : never]?: IType[K][K] extends object ? IType[K][K] extends any[] ? IType[K][K] : OmitNever<{ [K in keyof IType[K][K] as HasNullOrUndefined<IType[K][K][K]> extends true ? K : never]?: IType[K][K][K] extends object ? IType[K][K][K] extends any[] ? IType[K][K][K] : OmitNever<...> : IType[K][K][K]; } & { [K in keyof IType[K][K] as HasNullOrUndefined<...> extends true ? never : K]: IType[K][K][K] extends object ? IType[K][K][K] extends any[] ? IType[K][K][K] : OmitNever<...> : IType[K][K][K]; }> : IType[K][K]; } & { [K in keyof IType[K] as HasNullOrUndefined<...> extends true ? never : K]: IType[K][K] extends object ? IType[K][K] extends any[] ? IType[K][K] : OmitNever<...> : IType[K][K]; }> : IType[K]; } & { [K in keyof IType as HasNullOrUndefined<...> extends true ? never : K]: IType[K] extends object ? IType[K] extends any[] ? IType[K] : OmitNever<...> : IType[K]; }>>({ callbackFn, encoder, }: { ...;}) => (input: CIType) => Effect.Effect<...>
Creates a function that encodes input data before executing a database operation.
withEncoder } = yield* const getDbClient: Effect.Effect<DBClientInterface<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>, ConfigError, never>
getDbClient;
const const insertUser: (input: OmitNever<{ readonly url?: string | null | undefined; readonly email?: string | null | undefined; readonly avatar?: string | null | undefined; readonly password?: string | null | undefined; readonly createdAt?: string | undefined; readonly notifications?: string | null | undefined;} & { readonly id: string; readonly name: string; readonly username: string; readonly updatedAt: string; readonly emailVerified: boolean;}>) => Effect.Effect<InsertResult, DBCallbackFailure | DatabaseError, never>
insertUser = const withEncoder: <{ readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: string; readonly createdAt: string | undefined; readonly emailVerified: number; readonly notifications: string | null | undefined;}, { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; ... 5 more ...; readonly notifications: string | ... 1 more ... | undefined;}, InsertResult, OmitNever<...>>({ callbackFn, encoder, }: { ...;}) => (input: OmitNever<...>) => Effect.Effect<...>
Creates a function that encodes input data before executing a database operation.
withEncoder({ encoder: Schema.Schema<{ readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: string; readonly createdAt: string | undefined; readonly emailVerified: boolean; readonly notifications: string | null | undefined;}, { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; ... 5 more ...; readonly notifications: string | ... 1 more ... | undefined;}, never>
encoder: const StudioCMSUsersTable: Table<{ id: typeof Schema.String; url: Schema.NullishOr<typeof Schema.String>; name: typeof Schema.String; email: Schema.NullishOr<typeof Schema.String>; avatar: Schema.NullishOr<typeof Schema.String>; username: typeof Schema.String; password: Schema.NullishOr<typeof Schema.String>; updatedAt: Schema.Schema<ColumnType<Date, string, string>, ColumnType<string, string, string>, never> & ColumnTypes<typeof Schema.DateFromString, typeof Schema.String, typeof Schema.String>; createdAt: Schema.Schema<ColumnType<...>, ColumnType<...>, never> & ColumnTypes<...>; emailVerified: Schema.transform<typeof Schema.Number, typeof Schema.Boolean>; notifications: Schema.NullishOr<typeof Schema.String>;}>
StudioCMS Users Table Definition
StudioCMSUsersTable.type Insert: Schema.Struct<{ readonly id: Schema.Schema<string, string, never>; readonly url: Schema.Schema<string | null | undefined, string | null | undefined, never>; readonly name: Schema.Schema<string, string, never>; readonly email: Schema.Schema<string | null | undefined, string | null | undefined, never>; readonly avatar: Schema.Schema<string | null | undefined, string | null | undefined, never>; readonly username: Schema.Schema<string, string, never>; readonly password: Schema.Schema<string | null | undefined, string | ... 1 more ... | undefined, never>; readonly updatedAt: Schema.Schema<...>; readonly createdAt: Schema.Schema<...>; readonly emailVerified: Schema.Schema<...>; readonly notifications: Schema.Schema<...>;}>
- A mapping of column names to the types accepted by INSERT operations.
Insert types may allow undefined/optional values for columns with defaults
or auto-generated values.
Insert, callbackFn: DBCallbackFn<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}, { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; ... 5 more ...; readonly notifications: string | ... 1 more ... | undefined;}, InsertResult>
callbackFn: (db: DBCallback<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>
db, newUser: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; ... 5 more ...; readonly notifications: string | ... 1 more ... | undefined;}
newUser) => db: <InsertResult>(fn: (db: Kysely<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>) => Promise<...>) => Effect.Effect<out A, out E = never, out R = never>.AsEffect<...>
db((client: Kysely<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>
client) => client: Kysely<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>
client.QueryCreator<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; }; }>.insertInto<"StudioCMSUsersTable">(table: "StudioCMSUsersTable"): InsertQueryBuilder<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}, "StudioCMSUsersTable", InsertResult>
Creates an insert query.
The return value of this query is an instance of
InsertResult
.
InsertResult
has the
InsertResult.insertId
insertId
field that holds the auto incremented id of
the inserted row if the db returned one.
See the
InsertQueryBuilder.values
values
method for more info and examples. Also see
the
ReturningInterface.returning returning
method for a way to return columns
on supported databases like PostgreSQL.
Examples
const result = await db .insertInto('person') .values({ first_name: 'Jennifer', last_name: 'Aniston' }) .executeTakeFirst()
console.log(result.insertId)
Some databases like PostgreSQL support the returning method:
const { id } = await db .insertInto('person') .values({ first_name: 'Jennifer', last_name: 'Aniston' }) .returning('id') .executeTakeFirstOrThrow()
insertInto('StudioCMSUsersTable').InsertQueryBuilder<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; }; }, "StudioCMSUsersTable", InsertResult>.values(insert: InsertExpression<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}, "StudioCMSUsersTable">): InsertQueryBuilder<...>
Sets the values to insert for an
Kysely.insertInto insert
query.
This method takes an object whose keys are column names and values are
values to insert. In addition to the column's type, the values can be
raw
sql
snippets or select queries.
You must provide all fields you haven't explicitly marked as nullable
or optional using
Generated
or
ColumnType
.
The return value of an insert query is an instance of
InsertResult
. The
InsertResult.insertId
insertId
field holds the auto incremented primary
key if the database returned one.
On PostgreSQL and some other dialects, you need to call returning to get
something out of the query.
Also see the
expression
method for inserting the result of a select
query or any other expression.
Examples
Insert a single row:
const result = await db .insertInto('person') .values({ first_name: 'Jennifer', last_name: 'Aniston', age: 40 }) .executeTakeFirst()
// `insertId` is only available on dialects that// automatically return the id of the inserted row// such as MySQL and SQLite. On PostgreSQL, for example,// you need to add a `returning` clause to the query to// get anything out. See the "returning data" example.console.log(result.insertId)
The generated SQL (MySQL):
insert into `person` (`first_name`, `last_name`, `age`) values (?, ?, ?)
On dialects that support it (for example PostgreSQL) you can insert multiple
rows by providing an array. Note that the return value is once again very
dialect-specific. Some databases may only return the id of the last inserted
row and some return nothing at all unless you call returning.
await db .insertInto('person') .values([{ first_name: 'Jennifer', last_name: 'Aniston', age: 40, }, { first_name: 'Arnold', last_name: 'Schwarzenegger', age: 70, }]) .execute()
The generated SQL (PostgreSQL):
insert into "person" ("first_name", "last_name", "age") values (($1, $2, $3), ($4, $5, $6))
On supported dialects like PostgreSQL you need to chain returning to the query to get
the inserted row's columns (or any other expression) as the return value. returning
works just like select. Refer to select method's examples and documentation for
more info.
const result = await db .insertInto('person') .values({ first_name: 'Jennifer', last_name: 'Aniston', age: 40, }) .returning(['id', 'first_name as name']) .executeTakeFirstOrThrow()
The generated SQL (PostgreSQL):
insert into "person" ("first_name", "last_name", "age") values ($1, $2, $3) returning "id", "first_name" as "name"
In addition to primitives, the values can also be arbitrary expressions.
You can build the expressions by using a callback and calling the methods
on the expression builder passed to it:
import { sql } from 'kysely'
const ani = "Ani"const ston = "ston"
const result = await db .insertInto('person') .values(({ ref, selectFrom, fn }) => ({ first_name: 'Jennifer', last_name: sql<string>`concat(${ani}, ${ston})`, middle_name: ref('first_name'), age: selectFrom('person') .select(fn.avg<number>('age').as('avg_age')), })) .executeTakeFirst()
The generated SQL (PostgreSQL):
insert into "person" ( "first_name", "last_name", "middle_name", "age")values ( $1, concat($2, $3), "first_name", (select avg("age") as "avg_age" from "person"))
You can also use the callback version of subqueries or raw expressions:
await db.with('jennifer', (db) => db .selectFrom('person') .where('first_name', '=', 'Jennifer') .select(['id', 'first_name', 'gender']) .limit(1)).insertInto('pet').values((eb) => ({ owner_id: eb.selectFrom('jennifer').select('id'), name: eb.selectFrom('jennifer').select('first_name'), species: 'cat',})).execute()
The generated SQL (PostgreSQL):
with "jennifer" as ( select "id", "first_name", "gender" from "person" where "first_name" = $1 limit $2)insert into "pet" ("owner_id", "name", "species")values ( (select "id" from "jennifer"), (select "first_name" from "jennifer"), $3)
values(newUser: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; ... 5 more ...; readonly notifications: string | ... 1 more ... | undefined;}
newUser).InsertQueryBuilder<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; }; }, "StudioCMSUsersTable", InsertResult>.executeTakeFirst(): Promise<InsertResult>
Executes the query and returns the first result or undefined if
the query returned no result.
executeTakeFirst()), });
const const newUser: InsertResult
newUser = yield* const insertUser: (input: OmitNever<{ readonly url?: string | null | undefined; readonly email?: string | null | undefined; readonly avatar?: string | null | undefined; readonly password?: string | null | undefined; readonly createdAt?: string | undefined; readonly notifications?: string | null | undefined;} & { readonly id: string; readonly name: string; readonly username: string; readonly updatedAt: string; readonly emailVerified: boolean;}>) => Effect.Effect<InsertResult, DBCallbackFailure | DatabaseError, never>
insertUser({ username: string
username: 'new_user', email?: string | null | undefined
email: 'new_user@example.com', password?: string | null | undefined
password: null, avatar?: string | null | undefined
avatar: null, emailVerified: boolean
emailVerified: false, name: string
name: 'user', notifications?: string | null | undefined
notifications: '', url?: string | null | undefined
url: null, id: string
id: var crypto: webcrypto.Crypto
crypto.webcrypto.Crypto.randomUUID(): UUID
Generates a random
https://www.rfc-editor.org/rfc/rfc4122.txt RFC 4122
version 4 UUID.
The UUID is generated using a cryptographic pseudorandom number generator.
randomUUID(), updatedAt: string
updatedAt: new var Date: DateConstructornew () => Date (+3 overloads)
Date().Date.toISOString(): string
Returns a date as a string value in ISO format.
toISOString(), }); var console: Console
The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
- A
Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
- A global
console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.
Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.
Example using the global console:
console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err);
myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err
console.Console.log(message?: any, ...optionalParams: any[]): void
Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).
const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout
See util.format() for more information.
log('Inserted new user:', const newUser: InsertResult
newUser); // withEncoder returns a 'InsertResult' /* type of 'newUser' is: const newUser: InsertResult */});Insert new user example (withCodec)
Section titled “Insert new user example (withCodec)”import { import Schema
Schema } from 'studiocms/effect';import { const StudioCMSUsersTable: Table<{ id: typeof Schema.String; url: Schema.NullishOr<typeof Schema.String>; name: typeof Schema.String; email: Schema.NullishOr<typeof Schema.String>; avatar: Schema.NullishOr<typeof Schema.String>; username: typeof Schema.String; password: Schema.NullishOr<typeof Schema.String>; updatedAt: Schema.Schema<ColumnType<Date, string, string>, ColumnType<string, string, string>, never> & ColumnTypes<typeof Schema.DateFromString, typeof Schema.String, typeof Schema.String>; createdAt: Schema.Schema<ColumnType<...>, ColumnType<...>, never> & ColumnTypes<...>; emailVerified: Schema.transform<typeof Schema.Number, typeof Schema.Boolean>; notifications: Schema.NullishOr<typeof Schema.String>;}>
StudioCMS Users Table Definition
StudioCMSUsersTable } from '@withstudiocms/kysely';
export const const insertUser: Effect.Effect<void, ConfigError | DBCallbackFailure | DatabaseError, never>
insertUser = import Effect
Effect.const gen: <YieldWrap<Effect.Effect<DBClientInterface<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>, ConfigError, never>> | YieldWrap<...>, void>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
Provides a way to write effectful code using generator functions, simplifying
control flow and error handling.
When to Use
Effect.gen allows you to write code that looks and behaves like synchronous
code, but it can handle asynchronous tasks, errors, and complex control flow
(like loops and conditions). It helps make asynchronous code more readable
and easier to manage.
The generator functions work similarly to async/await but with more
explicit control over the execution of effects. You can yield* values from
effects and return the final result at the end.
Example
import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = ( total: number, discountRate: number): Effect.Effect<number, Error> => discountRate === 0 ? Effect.fail(new Error("Discount rate cannot be zero")) : Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () { const transactionAmount = yield* fetchTransactionAmount const discountRate = yield* fetchDiscountRate const discountedAmount = yield* applyDiscount( transactionAmount, discountRate ) const finalAmount = addServiceCharge(discountedAmount) return `Final amount to charge: ${finalAmount}`})
gen(function* () { const { const withCodec: <IEncoded, IType, OEncoded, OType, CIType = OmitNever<{ [K in keyof IType as HasNullOrUndefined<IType[K]> extends true ? K : never]?: IType[K] extends object ? IType[K] extends any[] ? IType[K] : OmitNever<{ [K in keyof IType[K] as HasNullOrUndefined<IType[K][K]> extends true ? K : never]?: IType[K][K] extends object ? IType[K][K] extends any[] ? IType[K][K] : OmitNever<{ [K in keyof IType[K][K] as HasNullOrUndefined<IType[K][K][K]> extends true ? K : never]?: IType[K][K][K] extends object ? IType[K][K][K] extends any[] ? IType[K][K][K] : OmitNever<...> : IType[K][K][K]; } & { [K in keyof IType[K][K] as HasNullOrUndefined<...> extends true ? never : K]: IType[K][K][K] extends object ? IType[K][K][K] extends any[] ? IType[K][K][K] : OmitNever<...> : IType[K][K][K]; }> : IType[K][K]; } & { [K in keyof IType[K] as HasNullOrUndefined<...> extends true ? never : K]: IType[K][K] extends object ? IType[K][K] extends any[] ? IType[K][K] : OmitNever<...> : IType[K][K]; }> : IType[K]; } & { [K in keyof IType as HasNullOrUndefined<...> extends true ? never : K]: IType[K] extends object ? IType[K] extends any[] ? IType[K] : OmitNever<...> : IType[K]; }>>({ encoder, decoder, callbackFn, }: { ...;}) => (input: CIType) => Effect.Effect<...>
Creates a function that both encodes input data and decodes output data around a database operation.
withCodec } = yield* const getDbClient: Effect.Effect<DBClientInterface<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>, ConfigError, never>
getDbClient;
const const insertNewUser: (input: OmitNever<{ readonly url?: string | null | undefined; readonly email?: string | null | undefined; readonly avatar?: string | null | undefined; readonly password?: string | null | undefined; readonly createdAt?: string | undefined; readonly notifications?: string | null | undefined;} & { readonly id: string; readonly name: string; readonly username: string; readonly updatedAt: string; readonly emailVerified: boolean;}>) => Effect.Effect<{ readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; ... 6 more ...; readonly notifications: string | ... 1 more ... | undefined;}, DBCallbackFailure | DatabaseError, never>
insertNewUser = const withCodec: <{ readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: string; readonly createdAt: string | undefined; readonly emailVerified: number; readonly notifications: string | null | undefined;}, { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; ... 5 more ...; readonly notifications: string | ... 1 more ... | undefined;}, { ...;}, { ...;}, OmitNever<...>>({ encoder, decoder, callbackFn, }: { ...;}) => (input: OmitNever<...>) => Effect.Effect<...>
Creates a function that both encodes input data and decodes output data around a database operation.
withCodec({ encoder: Schema.Schema<{ readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: string; readonly createdAt: string | undefined; readonly emailVerified: boolean; readonly notifications: string | null | undefined;}, { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; ... 5 more ...; readonly notifications: string | ... 1 more ... | undefined;}, never>
encoder: const StudioCMSUsersTable: Table<{ id: typeof Schema.String; url: Schema.NullishOr<typeof Schema.String>; name: typeof Schema.String; email: Schema.NullishOr<typeof Schema.String>; avatar: Schema.NullishOr<typeof Schema.String>; username: typeof Schema.String; password: Schema.NullishOr<typeof Schema.String>; updatedAt: Schema.Schema<ColumnType<Date, string, string>, ColumnType<string, string, string>, never> & ColumnTypes<typeof Schema.DateFromString, typeof Schema.String, typeof Schema.String>; createdAt: Schema.Schema<ColumnType<...>, ColumnType<...>, never> & ColumnTypes<...>; emailVerified: Schema.transform<typeof Schema.Number, typeof Schema.Boolean>; notifications: Schema.NullishOr<typeof Schema.String>;}>
StudioCMS Users Table Definition
StudioCMSUsersTable.type Insert: Schema.Struct<{ readonly id: Schema.Schema<string, string, never>; readonly url: Schema.Schema<string | null | undefined, string | null | undefined, never>; readonly name: Schema.Schema<string, string, never>; readonly email: Schema.Schema<string | null | undefined, string | null | undefined, never>; readonly avatar: Schema.Schema<string | null | undefined, string | null | undefined, never>; readonly username: Schema.Schema<string, string, never>; readonly password: Schema.Schema<string | null | undefined, string | ... 1 more ... | undefined, never>; readonly updatedAt: Schema.Schema<...>; readonly createdAt: Schema.Schema<...>; readonly emailVerified: Schema.Schema<...>; readonly notifications: Schema.Schema<...>;}>
- A mapping of column names to the types accepted by INSERT operations.
Insert types may allow undefined/optional values for columns with defaults
or auto-generated values.
Insert, decoder: Schema.Schema<{ readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: Date; readonly createdAt: Date; readonly emailVerified: boolean; readonly notifications: string | null | undefined;}, { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; ... 5 more ...; readonly notifications: string | ... 1 more ... | undefined;}, never>
decoder: const StudioCMSUsersTable: Table<{ id: typeof Schema.String; url: Schema.NullishOr<typeof Schema.String>; name: typeof Schema.String; email: Schema.NullishOr<typeof Schema.String>; avatar: Schema.NullishOr<typeof Schema.String>; username: typeof Schema.String; password: Schema.NullishOr<typeof Schema.String>; updatedAt: Schema.Schema<ColumnType<Date, string, string>, ColumnType<string, string, string>, never> & ColumnTypes<typeof Schema.DateFromString, typeof Schema.String, typeof Schema.String>; createdAt: Schema.Schema<ColumnType<...>, ColumnType<...>, never> & ColumnTypes<...>; emailVerified: Schema.transform<typeof Schema.Number, typeof Schema.Boolean>; notifications: Schema.NullishOr<typeof Schema.String>;}>
StudioCMS Users Table Definition
StudioCMSUsersTable.type Select: Schema.Struct<{ readonly id: Schema.Schema<string, string, never>; readonly url: Schema.Schema<string | null | undefined, string | null | undefined, never>; readonly name: Schema.Schema<string, string, never>; readonly email: Schema.Schema<string | null | undefined, string | null | undefined, never>; readonly avatar: Schema.Schema<string | null | undefined, string | null | undefined, never>; readonly username: Schema.Schema<string, string, never>; readonly password: Schema.Schema<string | null | undefined, string | ... 1 more ... | undefined, never>; readonly updatedAt: Schema.Schema<...>; readonly createdAt: Schema.Schema<...>; readonly emailVerified: Schema.Schema<...>; readonly notifications: Schema.Schema<...>;}>
- A mapping of column names to the types returned by SELECT queries.
Typically these types represent the actual stored or computed values.
Select, callbackFn: DBCallbackFn<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}, { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; ... 5 more ...; readonly notifications: string | ... 1 more ... | undefined;}, { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; ... 5 more ...; readonly notifications: string | ... 1 more ... | undefined;}>
callbackFn: (db: DBCallback<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>
db, newUser: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; ... 5 more ...; readonly notifications: string | ... 1 more ... | undefined;}
newUser) => db: <{ id: string; url: string | null | undefined; name: string; email: string | null | undefined; avatar: string | null | undefined; username: string; password: string | null | undefined; updatedAt: string; createdAt: string; emailVerified: number; notifications: string | null | undefined;}>(fn: (db: Kysely<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>) => Promise<...>) => Effect.Effect<out A, out E = never, out R = never>.AsEffect<...>
db((client: Kysely<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>
client) => client: Kysely<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>
client .QueryCreator<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; }; }>.insertInto<"StudioCMSUsersTable">(table: "StudioCMSUsersTable"): InsertQueryBuilder<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}, "StudioCMSUsersTable", InsertResult>
Creates an insert query.
The return value of this query is an instance of
InsertResult
.
InsertResult
has the
InsertResult.insertId
insertId
field that holds the auto incremented id of
the inserted row if the db returned one.
See the
InsertQueryBuilder.values
values
method for more info and examples. Also see
the
ReturningInterface.returning returning
method for a way to return columns
on supported databases like PostgreSQL.
Examples
const result = await db .insertInto('person') .values({ first_name: 'Jennifer', last_name: 'Aniston' }) .executeTakeFirst()
console.log(result.insertId)
Some databases like PostgreSQL support the returning method:
const { id } = await db .insertInto('person') .values({ first_name: 'Jennifer', last_name: 'Aniston' }) .returning('id') .executeTakeFirstOrThrow()
insertInto('StudioCMSUsersTable') .InsertQueryBuilder<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; }; }, "StudioCMSUsersTable", InsertResult>.values(insert: InsertExpression<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}, "StudioCMSUsersTable">): InsertQueryBuilder<...>
Sets the values to insert for an
Kysely.insertInto insert
query.
This method takes an object whose keys are column names and values are
values to insert. In addition to the column's type, the values can be
raw
sql
snippets or select queries.
You must provide all fields you haven't explicitly marked as nullable
or optional using
Generated
or
ColumnType
.
The return value of an insert query is an instance of
InsertResult
. The
InsertResult.insertId
insertId
field holds the auto incremented primary
key if the database returned one.
On PostgreSQL and some other dialects, you need to call returning to get
something out of the query.
Also see the
expression
method for inserting the result of a select
query or any other expression.
Examples
Insert a single row:
const result = await db .insertInto('person') .values({ first_name: 'Jennifer', last_name: 'Aniston', age: 40 }) .executeTakeFirst()
// `insertId` is only available on dialects that// automatically return the id of the inserted row// such as MySQL and SQLite. On PostgreSQL, for example,// you need to add a `returning` clause to the query to// get anything out. See the "returning data" example.console.log(result.insertId)
The generated SQL (MySQL):
insert into `person` (`first_name`, `last_name`, `age`) values (?, ?, ?)
On dialects that support it (for example PostgreSQL) you can insert multiple
rows by providing an array. Note that the return value is once again very
dialect-specific. Some databases may only return the id of the last inserted
row and some return nothing at all unless you call returning.
await db .insertInto('person') .values([{ first_name: 'Jennifer', last_name: 'Aniston', age: 40, }, { first_name: 'Arnold', last_name: 'Schwarzenegger', age: 70, }]) .execute()
The generated SQL (PostgreSQL):
insert into "person" ("first_name", "last_name", "age") values (($1, $2, $3), ($4, $5, $6))
On supported dialects like PostgreSQL you need to chain returning to the query to get
the inserted row's columns (or any other expression) as the return value. returning
works just like select. Refer to select method's examples and documentation for
more info.
const result = await db .insertInto('person') .values({ first_name: 'Jennifer', last_name: 'Aniston', age: 40, }) .returning(['id', 'first_name as name']) .executeTakeFirstOrThrow()
The generated SQL (PostgreSQL):
insert into "person" ("first_name", "last_name", "age") values ($1, $2, $3) returning "id", "first_name" as "name"
In addition to primitives, the values can also be arbitrary expressions.
You can build the expressions by using a callback and calling the methods
on the expression builder passed to it:
import { sql } from 'kysely'
const ani = "Ani"const ston = "ston"
const result = await db .insertInto('person') .values(({ ref, selectFrom, fn }) => ({ first_name: 'Jennifer', last_name: sql<string>`concat(${ani}, ${ston})`, middle_name: ref('first_name'), age: selectFrom('person') .select(fn.avg<number>('age').as('avg_age')), })) .executeTakeFirst()
The generated SQL (PostgreSQL):
insert into "person" ( "first_name", "last_name", "middle_name", "age")values ( $1, concat($2, $3), "first_name", (select avg("age") as "avg_age" from "person"))
You can also use the callback version of subqueries or raw expressions:
await db.with('jennifer', (db) => db .selectFrom('person') .where('first_name', '=', 'Jennifer') .select(['id', 'first_name', 'gender']) .limit(1)).insertInto('pet').values((eb) => ({ owner_id: eb.selectFrom('jennifer').select('id'), name: eb.selectFrom('jennifer').select('first_name'), species: 'cat',})).execute()
The generated SQL (PostgreSQL):
with "jennifer" as ( select "id", "first_name", "gender" from "person" where "first_name" = $1 limit $2)insert into "pet" ("owner_id", "name", "species")values ( (select "id" from "jennifer"), (select "first_name" from "jennifer"), $3)
values(newUser: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; ... 5 more ...; readonly notifications: string | ... 1 more ... | undefined;}
newUser) .InsertQueryBuilder<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; }; }, "StudioCMSUsersTable", InsertResult>.returningAll(): InsertQueryBuilder<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}, "StudioCMSUsersTable", { ...;}>
Adds a returning * to an insert/update/delete/merge query on databases
that support returning such as PostgreSQL.
Also see the
returning
method.
returningAll() .InsertQueryBuilder<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; }; }, "StudioCMSUsersTable", { ...; }>.executeTakeFirstOrThrow(errorConstructor?: NoResultErrorConstructor | ((node: QueryNode) => Error)): Promise<{ id: string; url: string | null | undefined; name: string; email: string | null | undefined; avatar: string | null | undefined; username: string; password: string | null | undefined; updatedAt: string; createdAt: string; emailVerified: number; notifications: string | null | undefined;}>
Executes the query and returns the first result or throws if
the query returned no result.
By default an instance of
NoResultError
is thrown, but you can
provide a custom error class, or callback as the only argument to throw a different
error.
executeTakeFirstOrThrow() ), });
const const insertedUser: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: Date; readonly createdAt: Date; readonly emailVerified: boolean; readonly notifications: string | null | undefined;}
insertedUser = yield* const insertNewUser: (input: OmitNever<{ readonly url?: string | null | undefined; readonly email?: string | null | undefined; readonly avatar?: string | null | undefined; readonly password?: string | null | undefined; readonly createdAt?: string | undefined; readonly notifications?: string | null | undefined;} & { readonly id: string; readonly name: string; readonly username: string; readonly updatedAt: string; readonly emailVerified: boolean;}>) => Effect.Effect<{ readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; ... 6 more ...; readonly notifications: string | ... 1 more ... | undefined;}, DBCallbackFailure | DatabaseError, never>
insertNewUser({ username: string
username: 'codec_user', email?: string | null | undefined
email: 'codec_user@example.com', password?: string | null | undefined
password: null, avatar?: string | null | undefined
avatar: null, emailVerified: boolean
emailVerified: false, name: string
name: 'user', notifications?: string | null | undefined
notifications: '', url?: string | null | undefined
url: null, id: string
id: var crypto: webcrypto.Crypto
crypto.webcrypto.Crypto.randomUUID(): UUID
Generates a random
https://www.rfc-editor.org/rfc/rfc4122.txt RFC 4122
version 4 UUID.
The UUID is generated using a cryptographic pseudorandom number generator.
randomUUID(), updatedAt: string
updatedAt: new var Date: DateConstructornew () => Date (+3 overloads)
Date().Date.toISOString(): string
Returns a date as a string value in ISO format.
toISOString(), }); var console: Console
The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
- A
Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
- A global
console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.
Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.
Example using the global console:
console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err);
myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err
console.Console.log(message?: any, ...optionalParams: any[]): void
Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).
const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout
See util.format() for more information.
log('Inserted user with codec:', const insertedUser: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: Date; readonly createdAt: Date; readonly emailVerified: boolean; readonly notifications: string | null | undefined;}
insertedUser); // withCodec returns decoded results /* type of 'insertedUser' is: const user: { readonly url: string | null | undefined; readonly id: string; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: Date; readonly createdAt: Date; readonly emailVerified: boolean; readonly notifications: string | null | undefined; } */});Get user by ID example
Section titled “Get user by ID example”import { import Schema
Schema } from 'studiocms/effect';import { const StudioCMSUsersTable: Table<{ id: typeof Schema.String; url: Schema.NullishOr<typeof Schema.String>; name: typeof Schema.String; email: Schema.NullishOr<typeof Schema.String>; avatar: Schema.NullishOr<typeof Schema.String>; username: typeof Schema.String; password: Schema.NullishOr<typeof Schema.String>; updatedAt: Schema.Schema<ColumnType<Date, string, string>, ColumnType<string, string, string>, never> & ColumnTypes<typeof Schema.DateFromString, typeof Schema.String, typeof Schema.String>; createdAt: Schema.Schema<ColumnType<...>, ColumnType<...>, never> & ColumnTypes<...>; emailVerified: Schema.transform<typeof Schema.Number, typeof Schema.Boolean>; notifications: Schema.NullishOr<typeof Schema.String>;}>
StudioCMS Users Table Definition
StudioCMSUsersTable } from '@withstudiocms/kysely';
export const const insertUser: Effect.Effect<void, ConfigError | DBCallbackFailure | DatabaseError, never>
insertUser = import Effect
Effect.const gen: <YieldWrap<Effect.Effect<DBClientInterface<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>, ConfigError, never>> | YieldWrap<...>, void>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
Provides a way to write effectful code using generator functions, simplifying
control flow and error handling.
When to Use
Effect.gen allows you to write code that looks and behaves like synchronous
code, but it can handle asynchronous tasks, errors, and complex control flow
(like loops and conditions). It helps make asynchronous code more readable
and easier to manage.
The generator functions work similarly to async/await but with more
explicit control over the execution of effects. You can yield* values from
effects and return the final result at the end.
Example
import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = ( total: number, discountRate: number): Effect.Effect<number, Error> => discountRate === 0 ? Effect.fail(new Error("Discount rate cannot be zero")) : Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () { const transactionAmount = yield* fetchTransactionAmount const discountRate = yield* fetchDiscountRate const discountedAmount = yield* applyDiscount( transactionAmount, discountRate ) const finalAmount = addServiceCharge(discountedAmount) return `Final amount to charge: ${finalAmount}`})
gen(function* () { const { const withCodec: <IEncoded, IType, OEncoded, OType, CIType = OmitNever<{ [K in keyof IType as HasNullOrUndefined<IType[K]> extends true ? K : never]?: IType[K] extends object ? IType[K] extends any[] ? IType[K] : OmitNever<{ [K in keyof IType[K] as HasNullOrUndefined<IType[K][K]> extends true ? K : never]?: IType[K][K] extends object ? IType[K][K] extends any[] ? IType[K][K] : OmitNever<{ [K in keyof IType[K][K] as HasNullOrUndefined<IType[K][K][K]> extends true ? K : never]?: IType[K][K][K] extends object ? IType[K][K][K] extends any[] ? IType[K][K][K] : OmitNever<...> : IType[K][K][K]; } & { [K in keyof IType[K][K] as HasNullOrUndefined<...> extends true ? never : K]: IType[K][K][K] extends object ? IType[K][K][K] extends any[] ? IType[K][K][K] : OmitNever<...> : IType[K][K][K]; }> : IType[K][K]; } & { [K in keyof IType[K] as HasNullOrUndefined<...> extends true ? never : K]: IType[K][K] extends object ? IType[K][K] extends any[] ? IType[K][K] : OmitNever<...> : IType[K][K]; }> : IType[K]; } & { [K in keyof IType as HasNullOrUndefined<...> extends true ? never : K]: IType[K] extends object ? IType[K] extends any[] ? IType[K] : OmitNever<...> : IType[K]; }>>({ encoder, decoder, callbackFn, }: { ...;}) => (input: CIType) => Effect.Effect<...>
Creates a function that both encodes input data and decodes output data around a database operation.
withCodec } = yield* const getDbClient: Effect.Effect<DBClientInterface<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>, ConfigError, never>
getDbClient;
const const getUserById: (input: string) => Effect.Effect<{ readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: Date; readonly createdAt: Date; readonly emailVerified: boolean; readonly notifications: string | null | undefined;} | undefined, DBCallbackFailure | DatabaseError, never>
getUserById = const withCodec: <string, string, { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: string; readonly createdAt: string; readonly emailVerified: number; readonly notifications: string | null | undefined;} | undefined, { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | ... 1 more ... | undefined; ... 5 more ...; readonly notifications: string | ... 1 more ... | undefined;} | undefined, string>({ encoder, decoder, callbackFn, }: { ...;}) => (input: string) => Effect.Effect<...>
Creates a function that both encodes input data and decodes output data around a database operation.
withCodec({ encoder: Schema.Schema<string, string, never>
encoder: import Schema
Schema.class Stringexport String
String, decoder: Schema.Schema<{ readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: Date; readonly createdAt: Date; readonly emailVerified: boolean; readonly notifications: string | null | undefined;} | undefined, { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | ... 1 more ... | undefined; ... 5 more ...; readonly notifications: string | ... 1 more ... | undefined;} | undefined, never>
decoder: import Schema
Schema.const UndefinedOr: <Schema.Struct<{ readonly id: Schema.Schema<string, string, never>; readonly url: Schema.Schema<string | null | undefined, string | null | undefined, never>; readonly name: Schema.Schema<string, string, never>; readonly email: Schema.Schema<string | null | undefined, string | null | undefined, never>; readonly avatar: Schema.Schema<string | null | undefined, string | null | undefined, never>; readonly username: Schema.Schema<string, string, never>; readonly password: Schema.Schema<string | null | undefined, string | ... 1 more ... | undefined, never>; readonly updatedAt: Schema.Schema<...>; readonly createdAt: Schema.Schema<...>; readonly emailVerified: Schema.Schema<...>; readonly notifications: Schema.Schema<...>;}>>(self: Schema.Struct<...>) => Schema.UndefinedOr<...>
UndefinedOr(const StudioCMSUsersTable: Table<{ id: typeof Schema.String; url: Schema.NullishOr<typeof Schema.String>; name: typeof Schema.String; email: Schema.NullishOr<typeof Schema.String>; avatar: Schema.NullishOr<typeof Schema.String>; username: typeof Schema.String; password: Schema.NullishOr<typeof Schema.String>; updatedAt: Schema.Schema<ColumnType<Date, string, string>, ColumnType<string, string, string>, never> & ColumnTypes<typeof Schema.DateFromString, typeof Schema.String, typeof Schema.String>; createdAt: Schema.Schema<ColumnType<...>, ColumnType<...>, never> & ColumnTypes<...>; emailVerified: Schema.transform<typeof Schema.Number, typeof Schema.Boolean>; notifications: Schema.NullishOr<typeof Schema.String>;}>
StudioCMS Users Table Definition
StudioCMSUsersTable.type Select: Schema.Struct<{ readonly id: Schema.Schema<string, string, never>; readonly url: Schema.Schema<string | null | undefined, string | null | undefined, never>; readonly name: Schema.Schema<string, string, never>; readonly email: Schema.Schema<string | null | undefined, string | null | undefined, never>; readonly avatar: Schema.Schema<string | null | undefined, string | null | undefined, never>; readonly username: Schema.Schema<string, string, never>; readonly password: Schema.Schema<string | null | undefined, string | ... 1 more ... | undefined, never>; readonly updatedAt: Schema.Schema<...>; readonly createdAt: Schema.Schema<...>; readonly emailVerified: Schema.Schema<...>; readonly notifications: Schema.Schema<...>;}>
- A mapping of column names to the types returned by SELECT queries.
Typically these types represent the actual stored or computed values.
Select), callbackFn: DBCallbackFn<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}, string, { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | ... 1 more ... | undefined; ... 5 more ...; readonly notifications: string | ... 1 more ... | undefined;} | undefined>
callbackFn: (db: DBCallback<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>
db, id: string
id) => db: <{ id: string; url: string | null | undefined; name: string; email: string | null | undefined; avatar: string | null | undefined; username: string; password: string | null | undefined; updatedAt: string; createdAt: string; emailVerified: number; notifications: string | null | undefined;} | undefined>(fn: (db: Kysely<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>) => Promise<...>) => Effect.Effect<out A, out E = never, out R = never>.AsEffect<...>
db((client: Kysely<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>
client) => client: Kysely<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}>
client.QueryCreator<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; }; }>.selectFrom<"StudioCMSUsersTable">(from: "StudioCMSUsersTable"): SelectQueryBuilder<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}, "StudioCMSUsersTable", {}>
Creates a select query builder for the given table or tables.
The tables passed to this method are built as the query's from clause.
Examples
Create a select query for one table:
db.selectFrom('person').selectAll()
The generated SQL (PostgreSQL):
select * from "person"
Create a select query for one table with an alias:
const persons = await db.selectFrom('person as p') .select(['p.id', 'first_name']) .execute()
console.log(persons[0].id)
The generated SQL (PostgreSQL):
select "p"."id", "first_name" from "person" as "p"
Create a select query from a subquery:
const persons = await db.selectFrom( (eb) => eb.selectFrom('person').select('person.id as identifier').as('p') ) .select('p.identifier') .execute()
console.log(persons[0].identifier)
The generated SQL (PostgreSQL):
select "p"."identifier",from ( select "person"."id" as "identifier" from "person") as p
Create a select query from raw sql:
import { sql } from 'kysely'
const items = await db .selectFrom(sql<{ one: number }>`(select 1 as one)`.as('q')) .select('q.one') .execute()
console.log(items[0].one)
The generated SQL (PostgreSQL):
select "q"."one",from ( select 1 as one) as q
When you use the sql tag you need to also provide the result type of the
raw snippet / query so that Kysely can figure out what columns are
available for the rest of the query.
The selectFrom method also accepts an array for multiple tables. All
the above examples can also be used in an array.
import { sql } from 'kysely'
const items = await db.selectFrom([ 'person as p', db.selectFrom('pet').select('pet.species').as('a'), sql<{ one: number }>`(select 1 as one)`.as('q') ]) .select(['p.id', 'a.species', 'q.one']) .execute()
The generated SQL (PostgreSQL):
select "p".id, "a"."species", "q"."one"from "person" as "p", (select "pet"."species" from "pet") as a, (select 1 as one) as "q"
selectFrom('StudioCMSUsersTable').SelectQueryBuilder<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; }; }, "StudioCMSUsersTable", {}>.selectAll(): SelectQueryBuilder<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}, "StudioCMSUsersTable", { ...;}> (+2 overloads)
Adds a select * or select table.* clause to the query.
Examples
The selectAll method generates SELECT *:
const persons = await db .selectFrom('person') .selectAll() .execute()
The generated SQL (PostgreSQL):
select * from "person"
Select all columns of a table:
const persons = await db .selectFrom('person') .selectAll('person') .execute()
The generated SQL (PostgreSQL):
select "person".* from "person"
Select all columns of multiple tables:
const personsPets = await db .selectFrom(['person', 'pet']) .selectAll(['person', 'pet']) .execute()
The generated SQL (PostgreSQL):
select "person".*, "pet".* from "person", "pet"
selectAll().SelectQueryBuilder<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; }; }, "StudioCMSUsersTable", { ...; }>.where<"id", string>(lhs: "id", op: ComparisonOperatorExpression, rhs: string): SelectQueryBuilder<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; };}, "StudioCMSUsersTable", { ...;}> (+1 overload)
Adds a where expression to the query.
Calling this method multiple times will combine the expressions using and.
Also see
whereRef
Examples
where method calls are combined with AND:
const person = await db .selectFrom('person') .selectAll() .where('first_name', '=', 'Jennifer') .where('age', '>', 40) .executeTakeFirst()
The generated SQL (PostgreSQL):
select * from "person" where "first_name" = $1 and "age" > $2
Operator can be any supported operator or if the typings don't support it
you can always use:
import { sql } from 'kysely'
sql`your operator`
Find multiple items using a list of identifiers:
const persons = await db .selectFrom('person') .selectAll() .where('id', 'in', [1, 2, 3]) .execute()
The generated SQL (PostgreSQL):
select * from "person" where "id" in ($1, $2, $3)
You can use the and function to create a simple equality
filter using an object
const persons = await db .selectFrom('person') .selectAll() .where((eb) => eb.and({ first_name: 'Jennifer', last_name: eb.ref('first_name') })) .execute()
The generated SQL (PostgreSQL):
select *from "person"where ( "first_name" = $1 and "last_name" = "first_name")
To combine conditions using OR, you can use the expression builder.
There are two ways to create OR expressions. Both are shown in this
example:
const persons = await db .selectFrom('person') .selectAll() // 1. Using the `or` method on the expression builder: .where((eb) => eb.or([ eb('first_name', '=', 'Jennifer'), eb('first_name', '=', 'Sylvester') ])) // 2. Chaining expressions using the `or` method on the // created expressions: .where((eb) => eb('last_name', '=', 'Aniston').or('last_name', '=', 'Stallone') ) .execute()
The generated SQL (PostgreSQL):
select *from "person"where ( ("first_name" = $1 or "first_name" = $2) and ("last_name" = $3 or "last_name" = $4))
You can add expressions conditionally like this:
import { Expression, SqlBool } from 'kysely'
const firstName: string | undefined = 'Jennifer'const lastName: string | undefined = 'Aniston'const under18 = trueconst over60 = true
let query = db .selectFrom('person') .selectAll()
if (firstName) { // The query builder is immutable. Remember to reassign // the result back to the query variable. query = query.where('first_name', '=', firstName)}
if (lastName) { query = query.where('last_name', '=', lastName)}
if (under18 || over60) { // Conditional OR expressions can be added like this. query = query.where((eb) => { const ors: Expression<SqlBool>[] = []
if (under18) { ors.push(eb('age', '<', 18)) }
if (over60) { ors.push(eb('age', '>', 60)) }
return eb.or(ors) })}
const persons = await query.execute()
Both the first and third argument can also be arbitrary expressions like
subqueries. An expression can defined by passing a function and calling
the methods of the
ExpressionBuilder
passed to the callback:
const persons = await db .selectFrom('person') .selectAll() .where( (qb) => qb.selectFrom('pet') .select('pet.name') .whereRef('pet.owner_id', '=', 'person.id') .limit(1), '=', 'Fluffy' ) .execute()
The generated SQL (PostgreSQL):
select *from "person"where ( select "pet"."name" from "pet" where "pet"."owner_id" = "person"."id" limit $1) = $2
A where in query can be built by using the in operator and an array
of values. The values in the array can also be expressions:
const persons = await db .selectFrom('person') .selectAll() .where('person.id', 'in', [100, 200, 300]) .execute()
The generated SQL (PostgreSQL):
select * from "person" where "id" in ($1, $2, $3)
For complex where expressions you can pass in a single callback and
use the ExpressionBuilder to build your expression:
const firstName = 'Jennifer'const maxAge = 60
const persons = await db .selectFrom('person') .selectAll('person') .where(({ eb, or, and, not, exists, selectFrom }) => and([ or([ eb('first_name', '=', firstName), eb('age', '<', maxAge) ]), not(exists( selectFrom('pet') .select('pet.id') .whereRef('pet.owner_id', '=', 'person.id') )) ])) .execute()
The generated SQL (PostgreSQL):
select "person".*from "person"where ( ( "first_name" = $1 or "age" < $2 ) and not exists ( select "pet"."id" from "pet" where "pet"."owner_id" = "person"."id" ))
If everything else fails, you can always use the
sql
tag
as any of the arguments, including the operator:
import { sql } from 'kysely'
const persons = await db .selectFrom('person') .selectAll() .where( sql<string>`coalesce(first_name, last_name)`, 'like', '%' + name + '%', ) .execute()
The generated SQL (PostgreSQL):
select * from "person"where coalesce(first_name, last_name) like $1
In all examples above the columns were known at compile time
(except for the raw
sql
expressions). By default kysely only
allows you to refer to columns that exist in the database and
can be referred to in the current query and context.
Sometimes you may want to refer to columns that come from the user
input and thus are not available at compile time.
You have two options, the
sql
tag or db.dynamic. The example below
uses both:
import { sql } from 'kysely'const { ref } = db.dynamic
const columnFromUserInput: string = 'id'
const persons = await db .selectFrom('person') .selectAll() .where(ref(columnFromUserInput), '=', 1) .where(sql.id(columnFromUserInput), '=', 2) .execute()
where('id', '=', id: string
id).SelectQueryBuilder<{ readonly StudioCMSUsersTable: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: ColumnType<string, string, string>; readonly createdAt: ColumnType<string, string | undefined, never>; readonly emailVerified: number; readonly notifications: string | null | undefined; }; ... 13 more ...; readonly StudioCMSDynamicConfigSettings: { readonly id: string; readonly data: ColumnType<...>; }; }, "StudioCMSUsersTable", { ...; }>.executeTakeFirst(): Promise<{ id: string; url: string | null | undefined; name: string; email: string | null | undefined; avatar: string | null | undefined; username: string; password: string | null | undefined; updatedAt: string; createdAt: string; emailVerified: number; notifications: string | null | undefined;} | undefined>
Executes the query and returns the first result or undefined if
the query returned no result.
executeTakeFirst() ), });
const const user: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: Date; readonly createdAt: Date; readonly emailVerified: boolean; readonly notifications: string | null | undefined;} | undefined
user = yield* const getUserById: (input: string) => Effect.Effect<{ readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: Date; readonly createdAt: Date; readonly emailVerified: boolean; readonly notifications: string | null | undefined;} | undefined, DBCallbackFailure | DatabaseError, never>
getUserById('some-user-id'); var console: Console
The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
- A
Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
- A global
console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.
Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.
Example using the global console:
console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err);
myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err
console.Console.log(message?: any, ...optionalParams: any[]): void
Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).
const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout
See util.format() for more information.
log('User by ID:', const user: { readonly id: string; readonly url: string | null | undefined; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: Date; readonly createdAt: Date; readonly emailVerified: boolean; readonly notifications: string | null | undefined;} | undefined
user); /* type of 'user' is: const user: { readonly url: string | null | undefined; readonly id: string; readonly name: string; readonly email: string | null | undefined; readonly avatar: string | null | undefined; readonly username: string; readonly password: string | null | undefined; readonly updatedAt: Date; readonly createdAt: Date; readonly emailVerified: boolean; readonly notifications: string | null | undefined; } | undefined */});The SDK package
Section titled “The SDK package”@withstudiocms/sdk
A comprehensive Software Development Kit for StudioCMS, providing a unified API for interacting with the CMS core functionality. Built with TypeScript and Effect-ts for type-safety and functional programming patterns, with Kysely DB (@withstudiocms/kysely) for dynamic database storage.
Features
Section titled “Features”- Authentication Module - User authentication and session management
- Configuration Management - Type-safe configuration handling with validation
- Database Operations - CRUD operations with Effect-ts error handling
- Plugin System - Utilities for plugin development and integration
- Caching Layer - Built-in caching with query memoization and invalidation
- Middleware Utilities - Request handling and middleware composition
- Diff Tracking - Track changes and modifications
- REST API Helpers - Utilities for building REST endpoints
- Notification Settings - User notification preference management
- Token Bucket - Rate limiting and token management
Further Reading
Section titled “Further Reading”For a code example of how to use the StudioCMS SDK manually in your project, check how it’s implemented in StudioCMS on GitHub^
Interested in the live SDK already available in StudioCMS? Check out The SDK documentation to learn how to use it in your StudioCMS project!