Something went wrong. Try again.
🔥 🔥 🔥 A Free & Self-hostable Airtable Alternative nocodb.com
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293import { type BoolType, SSLUsage } from 'nocodb-sdk'import { ClientType } from '~/lib/enums'
// todo: move to noco-sdkexport enum NcProjectType { DB = 'database',}
interface ProjectCreateForm { title: string dataSource: { client: ClientType connection: DefaultConnection | SQLiteConnection | SnowflakeConnection | DatabricksConnection searchPath?: string[] } inflection: { inflectionColumn?: string inflectionTable?: string } sslUse?: SSLUsage extraParameters: { key: string; value: string }[] is_private?: BoolType is_schema_readonly?: BoolType is_data_readonly?: BoolType fk_integration_id?: string}
interface DefaultConnection { host: string database: string user: string password: string port: number | string ssl?: Record<CertTypes, string> | 'no-verify' | 'true' // MSSQL (tedious) driver options — encrypt / trustServerCertificate / instanceName. // Only populated for SQL Server connections; ignored by other dialects. options?: Record<string, any>}
interface SQLiteConnection { client: ClientType.SQLITE database: string connection: { filename?: string } useNullAsDefault?: boolean}
interface SnowflakeConnection { account: string username: string password: string warehouse: string database: string schema: string}
interface DatabricksConnection { token: string host: string path: string database: string schema: string}
const defaultHost = 'localhost'
export { getTestDatabaseName } from 'nocodb-sdk'
export const clientTypes = [ { text: 'MySql', value: ClientType.MYSQL, }, { text: 'PostgreSQL', value: ClientType.PG, }, { text: 'SQLite', value: ClientType.SQLITE, }, { text: 'SQL Server', value: ClientType.MSSQL, }, { text: 'Oracle', value: ClientType.ORACLE, }, { text: 'Snowflake', value: ClientType.SNOWFLAKE, }, { text: 'Databricks', value: ClientType.DATABRICKS, },]
export const clientTypesMap = clientTypes.reduce((acc, curr) => { acc[curr.value] = curr return acc}, {} as Record<string, (typeof clientTypes)[0]>)
const homeDir = ''
type ConnectionClientType = | Exclude<ClientType, ClientType.SQLITE | ClientType.SNOWFLAKE | ClientType.DATABRICKS> | 'tidb' | 'yugabyte' | 'citusdb' | 'cockroachdb' | 'greenplum'
const sampleConnectionData: { [key in ConnectionClientType]: DefaultConnection } & { [ClientType.SQLITE]: SQLiteConnection } & { [ClientType.SNOWFLAKE]: SnowflakeConnection} & { [ClientType.DATABRICKS]: DatabricksConnection } = { [ClientType.PG]: { host: defaultHost, port: '5432', user: 'postgres', password: 'password', database: '_test', }, [ClientType.MYSQL]: { host: defaultHost, port: '3306', user: 'root', password: 'password', database: '_test', }, [ClientType.VITESS]: { host: defaultHost, port: '15306', user: 'root', password: 'password', database: '_test', }, [ClientType.MSSQL]: { host: defaultHost, port: '1433', user: 'sa', password: 'Password123!', database: 'master', // Permissive defaults for local/self-hosted SQL Server; Azure SQL needs // encrypt: true. Full TLS/auth controls land in Phase 6. options: { encrypt: false, trustServerCertificate: true, }, }, [ClientType.ORACLE]: { host: defaultHost, port: '1521', user: 'system', password: 'Password123!', database: 'FREEPDB1', }, [ClientType.SQLITE]: { client: ClientType.SQLITE, database: homeDir, connection: { filename: homeDir, }, useNullAsDefault: true, }, [ClientType.SNOWFLAKE]: { account: 'LOCATOR.REGION', username: 'USERNAME', password: 'PASSWORD', warehouse: 'COMPUTE_WH', database: 'DATABASE', schema: 'PUBLIC', }, [ClientType.DATABRICKS]: { token: 'dapiPLACEHOLDER', host: 'PLACEHOLDER.cloud.databricks.com', path: '/sql/1.0/warehouses/PLACEHOLDER', database: 'database', schema: 'default', }, tidb: { host: defaultHost, port: '4000', user: 'root', password: '', database: '_test', }, yugabyte: { host: defaultHost, port: '5432', user: 'postgres', password: '', database: '_test', }, citusdb: { host: defaultHost, port: '5432', user: 'postgres', password: '', database: '_test', }, cockroachdb: { host: defaultHost, port: '5432', user: 'postgres', password: '', database: '_test', }, greenplum: { host: defaultHost, port: '5432', user: 'postgres', password: '', database: '_test', },}
export const getDefaultConnectionConfig = (client: ClientType): ProjectCreateForm['dataSource'] => { return { client, connection: sampleConnectionData[client], searchPath: client === ClientType.PG ? ['public'] : client === ClientType.MSSQL ? ['dbo'] : undefined, }}
enum CertTypes { ca = 'ca', cert = 'cert', key = 'key',}
const errorHandlers = [ { messages: ['unable to get local issuer certificate', 'self signed certificate in certificate chain'], codes: ['UNABLE_TO_GET_ISSUER_CERT_LOCALLY', 'SELF_SIGNED_CERT_IN_CHAIN'], action: { connection: { ssl: { rejectUnauthorized: false, }, }, }, }, { messages: ['SSL is required'], codes: ['28000'], // PostgreSQL error code for invalid authorization specification action: { connection: { ssl: true, }, }, }, { messages: ['The server does not support SSL connections'], codes: ['08P01'], // PostgreSQL error code for protocol violation action: { connection: { ssl: false, }, }, },]
function generateConfigFix(e: any) { for (const handler of errorHandlers) { const errorMessage = e?.response?.data?.msg const errorCode = e?.response?.data?.sql_code
if (!errorMessage && !errorCode) return
const messageMatches = errorMessage && handler.messages.some((msg) => errorMessage?.toLowerCase()?.includes?.(msg?.toLowerCase())) const codeMatches = errorCode && handler.codes.includes(errorCode)
if (messageMatches || codeMatches) { return handler.action } }}
export { generateConfigFix, SSLUsage, CertTypes, ProjectCreateForm, DefaultConnection, SQLiteConnection, SnowflakeConnection, DatabricksConnection,}