在 #3791 里验证启动横幅有没有被我的改动搞坏时发现的。不是回归 —— 在干净的 main 上同样复现,按 Prime Directive #10 单独记账。
现象
OS_DATABASE_URL="postgres://u:p@127.0.0.1:59437/nope" \
OS_ALLOW_DRIVER_CONNECT_FAILURE=1 npx os serve
启动横幅:
Driver: SqlDriver(pg) → (unknown)
driver 类型认出来了(SqlDriver(pg) 是对的),但连接地址丢了。横幅存在的意义正是"让开发者一眼看到自己连的是哪个库",这一半失效了 —— 而它恰好在数据库连不上、最需要确认地址的时候失效。
根因
packages/cli/src/commands/serve.ts 的 describeRegisteredDriver 只认三种 connection 形状:
const conn = cfg.connection;
let url = '';
if (typeof conn === 'string') {
url = conn;
} else if (conn && typeof conn === 'object') {
url = conn.filename
?? (conn.host ? `${conn.host}${conn.port ? `:${conn.port}` : ''}${conn.database ? `/${conn.database}` : ''}` : '');
}
// …
return { label, url: url || '(unknown)' };
字符串 ✓、{ filename }(SQLite)✓、{ host, port, database } ✓ —— 但没有 { connectionString }。
而 packages/services/service-datasource/src/default-datasource-driver-factory.ts:83-86 正是产出这个形状的地方:
const url = (cfg.url as string | undefined) ?? (cfg.connectionString as string | undefined);
if (url) {
return spec.secret ? { connectionString: url, password: spec.secret } : { connectionString: url };
}
所以任何以 DSN 声明的 pg datasource(config.url / config.connectionString),经由 DatasourceConnectionService → defaultDatasourceDriverFactory 建起来的 driver,横幅都读不出地址。用离散字段(host/port/database)声明的则正常。
顺带一提,#3791 之后 SqlDriver 交给 knex 的那份配置也会是 { connectionString, connectionTimeoutMillis } —— 但 driver.config 仍保持作者传入的原形状(有测试钉住),所以横幅读的那一份没变,#3791 没有让这个问题变严重。不过它确实说明这个形状会越来越常见。
建议处置
describeRegisteredDriver 补上 connectionString / uri 分支,并对 DSN 做凭据脱敏 —— 现在 typeof conn === 'string' 那条分支是原样打印整个 URL 的,包含密码:
Driver: SqlDriver(pg) → postgres://admin:hunter2@db.example.com:5432/app
这在共享终端 / CI 日志 / 截图里是个小的凭据泄露面。修 (unknown) 的时候顺手把两种形状统一走一个"取 host/port/database、丢弃 user:password"的格式化函数,比只补一个分支更值。
优先级不高(纯展示),但两处都很小。
关联
在 #3791 里验证启动横幅有没有被我的改动搞坏时发现的。不是回归 —— 在干净的
main上同样复现,按 Prime Directive #10 单独记账。现象
OS_DATABASE_URL="postgres://u:p@127.0.0.1:59437/nope" \ OS_ALLOW_DRIVER_CONNECT_FAILURE=1 npx os serve启动横幅:
driver 类型认出来了(
SqlDriver(pg)是对的),但连接地址丢了。横幅存在的意义正是"让开发者一眼看到自己连的是哪个库",这一半失效了 —— 而它恰好在数据库连不上、最需要确认地址的时候失效。根因
packages/cli/src/commands/serve.ts的describeRegisteredDriver只认三种connection形状:字符串 ✓、
{ filename }(SQLite)✓、{ host, port, database }✓ —— 但没有{ connectionString }。而
packages/services/service-datasource/src/default-datasource-driver-factory.ts:83-86正是产出这个形状的地方:所以任何以 DSN 声明的 pg datasource(
config.url/config.connectionString),经由DatasourceConnectionService→defaultDatasourceDriverFactory建起来的 driver,横幅都读不出地址。用离散字段(host/port/database)声明的则正常。顺带一提,#3791 之后
SqlDriver交给 knex 的那份配置也会是{ connectionString, connectionTimeoutMillis }—— 但driver.config仍保持作者传入的原形状(有测试钉住),所以横幅读的那一份没变,#3791 没有让这个问题变严重。不过它确实说明这个形状会越来越常见。建议处置
describeRegisteredDriver补上connectionString/uri分支,并对 DSN 做凭据脱敏 —— 现在typeof conn === 'string'那条分支是原样打印整个 URL 的,包含密码:这在共享终端 / CI 日志 / 截图里是个小的凭据泄露面。修
(unknown)的时候顺手把两种形状统一走一个"取 host/port/database、丢弃 user:password"的格式化函数,比只补一个分支更值。优先级不高(纯展示),但两处都很小。
关联