bde148f286
* wip * some extra fixes * stuff kinda works? * need to figure out mocks * need to figure out mocks * fix db listener * gqlgen fix * minor gqlgen watch adjustment * lint fixes * delete old codegen file * converting migrations to ESM * getModuleDIrectory * vitest sort of works * added back ts-vitest * resolve gql double load * fixing test timeout configs * TSC lint fix * fix automate tests * moar debugging * debugging * more debugging * codegen update * server works * yargs migrated * chore(server): getting rid of global mocks for Server ESM (#5046) * got rid of email mock * got rid of comment mocks * got rid of multi region mocks * got rid of stripe mock * admin override mock updated * removed final mock * fixing import.meta.resolve calls * another import.meta.resolve fix * added requested test * nyc ESM fix * removed unneeded deps + linting * yarn lock forgot to commit * tryna fix flakyness * email capture util fix * sendEmail fix * fix TSX check * sender transporter fix + CR comments * merge main fix * test fixx * circleci fix * gqlgen bigint fix * error formatter fix * more error formatting improvements * esmloader added to Dockerfile * more dockerfile fixes * bg jobs fix
118 lines
3.8 KiB
TypeScript
118 lines
3.8 KiB
TypeScript
/* eslint-disable no-restricted-imports */
|
|
/* istanbul ignore file */
|
|
import { packageRoot } from './bootstrap.js'
|
|
import fs from 'fs'
|
|
import path from 'path'
|
|
import {
|
|
isTestEnv,
|
|
ignoreMissingMigrations,
|
|
postgresMaxConnections,
|
|
isDevOrTestEnv,
|
|
postgresConnectionAcquireTimeoutMillis,
|
|
postgresConnectionCreateTimeoutMillis,
|
|
knexAsyncStackTracesEnabled
|
|
} from '@/modules/shared/helpers/envHelper'
|
|
import { dbLogger as logger } from '@/observability/logging'
|
|
import { Knex } from 'knex'
|
|
import {
|
|
createKnexConfig,
|
|
configureKnexClient,
|
|
KnexConfigArgs,
|
|
RegionServerConfig
|
|
} from '@speckle/shared/environment/db'
|
|
|
|
function walk(dir: string) {
|
|
let results: string[] = []
|
|
const list = fs.readdirSync(dir)
|
|
list.forEach(function (file) {
|
|
const fullFile = path.join(dir, file)
|
|
const stat = fs.statSync(fullFile)
|
|
if (stat && stat.isDirectory()) {
|
|
if (file === 'migrations') results.push(fullFile)
|
|
else results = results.concat(walk(fullFile))
|
|
}
|
|
})
|
|
return results
|
|
}
|
|
|
|
// Always read migrations from /dist, otherwise we risk the same migration being applied twice
|
|
// once with the .ts extension and the 2nd time with the .js one
|
|
// The only exception is when running tests in the test DB, cause the stakes are way lower there and we always
|
|
// run them through ts-node anyway, so it doesn't make sense forcing the app to be built
|
|
const migrationModulesDir = path.resolve(
|
|
packageRoot,
|
|
isTestEnv() ? './modules' : './dist/modules'
|
|
)
|
|
const migrationDirsExist = fs.existsSync(migrationModulesDir)
|
|
if (!migrationDirsExist && !ignoreMissingMigrations()) {
|
|
throw new Error('App must be built into /dist, to enable work with migrations')
|
|
}
|
|
|
|
const migrationDirs = migrationDirsExist ? walk(migrationModulesDir) : []
|
|
|
|
// this is for readability, many users struggle to set the postgres connection uri
|
|
// in the env variables. This way its a bit easier to understand, also backward compatible.
|
|
const env = process.env
|
|
let connectionUri
|
|
if (env.POSTGRES_USER && env.POSTGRES_PASSWORD) {
|
|
connectionUri = `postgres://${encodeURIComponent(
|
|
env.POSTGRES_USER
|
|
)}:${encodeURIComponent(env.POSTGRES_PASSWORD)}@${
|
|
env.POSTGRES_URL
|
|
}/${encodeURIComponent(env.POSTGRES_DB as string)}`
|
|
} else {
|
|
connectionUri = env.POSTGRES_URL
|
|
}
|
|
|
|
// NOTE: fixes time pagination, breaks graphql DateTime parsing :/
|
|
// The pg driver (& knex?) parses dates for us and it breaks precision. This
|
|
// disables any date parsing and we guarantee values are returned as strings.
|
|
// const types = require('pg').types
|
|
// const TIMESTAMPTZ_OID = 1184
|
|
// const TIMESTAMP_OID = 1114
|
|
// types.setTypeParser(TIMESTAMPTZ_OID, (val) => val)
|
|
// types.setTypeParser(TIMESTAMP_OID, (val) => val)
|
|
|
|
// Another NOTE:
|
|
// this is why the new datetime columns are created like this
|
|
// table.specificType('createdAt', 'TIMESTAMPTZ(3)').defaultTo(knex.fn.now())
|
|
|
|
const configArgs: KnexConfigArgs = {
|
|
migrationDirs,
|
|
isTestEnv: isTestEnv(),
|
|
isDevOrTestEnv: isDevOrTestEnv(),
|
|
applicationName: 'speckle_server',
|
|
logger,
|
|
maxConnections: postgresMaxConnections(),
|
|
connectionAcquireTimeoutMillis: postgresConnectionAcquireTimeoutMillis(),
|
|
connectionCreateTimeoutMillis: postgresConnectionCreateTimeoutMillis(),
|
|
asyncStackTraces: knexAsyncStackTracesEnabled()
|
|
}
|
|
|
|
const config: Record<string, Knex.Config> = {
|
|
test: {
|
|
...createKnexConfig({
|
|
connectionString: connectionUri || 'postgres://127.0.0.1/speckle2_test',
|
|
...configArgs
|
|
})
|
|
},
|
|
development: {
|
|
...createKnexConfig({
|
|
connectionString: connectionUri || 'postgres://127.0.0.1/speckle2_dev',
|
|
...configArgs
|
|
})
|
|
},
|
|
production: {
|
|
...createKnexConfig({
|
|
connectionString: connectionUri,
|
|
...configArgs
|
|
})
|
|
}
|
|
}
|
|
|
|
export const configureClient = (config: Pick<RegionServerConfig, 'postgres'>) => {
|
|
return configureKnexClient(config, configArgs)
|
|
}
|
|
|
|
export default config
|