Turbine

The turbine-orm/cli module

turbine-orm/cli holds the config behind the turbine CLI: the TurbineCliConfig type and the functions that find, load and resolve it. Most projects import only the type:

// turbine.config.ts
import type { TurbineCliConfig } from 'turbine-orm/cli';
 
const config: TurbineCliConfig = {
  url: process.env.DATABASE_URL,
  out: './generated/turbine',
  schema: 'public',
  migrationsDir: './turbine/migrations',
  seedFile: './turbine/seed.ts',
  schemaFile: './turbine/schema.ts',
};
 
export default config;

The module exports no commands and opens no connection, so importing it has no side effects.

TurbineCliConfig#

FieldDefaultMeaning
urlnoneConnection string.
out'./generated/turbine'Output directory for the generated client.
schema'public'The Postgres namespace to introspect, not a file path.
include[]Tables to include. Empty means all.
exclude[]Tables to exclude.
migrationsDir'./turbine/migrations'SQL migration directory.
seedFilesee resolveSeedFileSeed file path.
seednoneAlias for seedFile, which wins when both are set.
schemaFile'./turbine/schema.ts'The defineSchema file that push applies and whose tags generate reads. A named file that is missing fails both; a missing default is skipped.
columnTypesnone{ 'table.column': 'TypeScript type' }. See Typing columns.
relationNamesnone{ table: { derivedName: newName } }. See Renaming derived relations.
importExtension'auto'Imports in the generated index.ts: 'js', 'ts', 'none', or 'auto' (from your tsconfig, else 'js').
keepColumnNamesfalseUse raw column names as field names instead of camelCase.
legacyToManyUniquesfalseType a child with a unique foreign key as hasMany instead of hasOne.
adapternoneA DatabaseAdapter such as cockroachdb. The CLI does not read it.
  • The module's TurbineConfig export is an alias of TurbineCliConfig, not the runtime TurbineConfig from the package root.
  • A schema that looks like a file path (a / or \, or a .ts, .mts, .cts, .js, .mjs, .cjs or .json ending) would match no tables, so turbine generate refuses it. The check is the exported looksLikeSchemaFilePath(value).

Finding and loading the config#

import { findConfigFile, loadConfig, loadConfigResult } from 'turbine-orm/cli';
 
const { config, loadError } = await loadConfigResult();
if (loadError) {
  console.error(`Failed to load ${loadError.filename}:`, loadError.error);
}

Candidates are turbine.config.ts, turbine.config.mts, turbine.config.js and turbine.config.mjs, in that order. The first that imports successfully wins.

FunctionReturns
findConfigFile(cwd?)The first candidate that exists, or null. Imports nothing.
loadConfig(cwd?)The config, or {}. Load errors are swallowed.
loadConfigResult(cwd?){ config, loadError? }. A file that throws is skipped for the next candidate, and the first failure is reported as loadError: { filename, error }.

unwrapModuleDefault(mod) and unwrapConfigModule(mod) unwrap a module's default export. In a "type": "commonjs" project, importing turbine.config.ts through tsx can wrap the default twice ({ default: { default: config } }), which would otherwise read every field as undefined.

resolveConfig(fileConfig, overrides)#

Merges a loaded config with flag overrides and the environment into a fully defaulted ResolvedConfig.

import { loadConfig, resolveConfig } from 'turbine-orm/cli';
 
const resolved = resolveConfig(await loadConfig(), { url: argv.url, out: argv.out });
  • A flag beats the config file, which beats the default.
  • url alone reads the environment: --url, then DATABASE_URL, then the file's url. A shell DATABASE_URL therefore overrides the config file.
  • An empty or whitespace-only value counts as unset.
  • CliOverrides covers url, out, schema, schemaFile, include, exclude, importExtension, keepColumnNames and legacyToManyUniques. Everything else comes from the file.

resolveSeedFile(config, cwd?)#

Returns the seed file's absolute path, or null.

import { resolveSeedFile } from 'turbine-orm/cli';
 
const seed = resolveSeedFile({ seedFile: './turbine/seed.ts' });

An explicit seedFile (or seed) wins even when the file does not exist yet, so a typo surfaces as a missing file. Otherwise the first that exists of seed.ts, seed.js, seed.sql, turbine/seed.ts, turbine/seed.js, turbine/seed.sql.

configTemplate(connectionString?, schema?)#

Returns the turbine.config.ts source that turbine init writes, with schema defaulting to 'public'. A connection string without a password is inlined. One with a password, or none, gives url: process.env.DATABASE_URL. DEFAULT_INIT_SEED_FILE is the seed path the template uses.

See also#

  • CLI: every command and flag.
  • Seeding: writing the seed file.
  • Schema: the schemaFile that push applies.