镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Commit 9d028a2

Browse files
committed
fix(database): honor model scopes during schema drift audits
1 parent 0e5a865 commit 9d028a2

3 files changed

Lines changed: 37 additions & 5 deletions

File tree

‎storage/framework/core/database/src/schema-drift.ts‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { Model } from '@stacksjs/types'
22
import fs from 'node:fs'
3+
import { config, overridesReady } from '@stacksjs/config'
34
import { path } from '@stacksjs/path'
45

56
/**
@@ -48,21 +49,26 @@ export interface SchemaDriftReport {
4849
* subdirectories, and one unreadable model must not cost every other model its
4950
* audit. Mirrors the loader in relation-columns.ts.
5051
*/
51-
async function loadModelsFrom(dir: string): Promise<Model[]> {
52+
export async function loadSchemaAuditModels(dir: string, include?: readonly string[]): Promise<Model[]> {
5253
const out: Model[] = []
54+
const selected = include === undefined ? undefined : new Set(include.map(name => name.trim().toLowerCase()))
5355
if (!fs.existsSync(dir))
5456
return out
5557

5658
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
5759
const fullPath = path.join(dir, entry.name)
5860

5961
if (entry.isDirectory()) {
60-
out.push(...(await loadModelsFrom(fullPath)))
62+
out.push(...(await loadSchemaAuditModels(fullPath, include)))
6163
continue
6264
}
6365

6466
if (!entry.name.endsWith('.ts') || entry.name.startsWith('_') || entry.name.startsWith('index'))
6567
continue
68+
// Match migration generation's file-based model names before importing.
69+
// Models owned by another runtime have no tables in this database.
70+
if (selected && !selected.has(entry.name.slice(0, -3).toLowerCase()))
71+
continue
6672

6773
try {
6874
const imported = (await import(fullPath)).default as Model
@@ -99,7 +105,8 @@ export async function auditSchemaDrift(): Promise<SchemaDriftReport> {
99105
}
100106

101107
try {
102-
const models = await loadModelsFrom(path.appPath('Models'))
108+
await overridesReady
109+
const models = await loadSchemaAuditModels(path.appPath('Models'), config.database?.models?.include)
103110
if (models.length === 0)
104111
return empty
105112

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { expect, test } from 'bun:test'
2+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'
3+
import { tmpdir } from 'node:os'
4+
import { join } from 'node:path'
5+
import { loadSchemaAuditModels } from '../src/schema-drift'
6+
7+
test('schema audits import only models selected for this database, including nested definitions', async () => {
8+
const root = mkdtempSync(join(tmpdir(), 'stacks-schema-audit-scope-'))
9+
const marker = Symbol.for(root)
10+
try {
11+
mkdirSync(join(root, 'Mail'))
12+
writeFileSync(join(root, 'User.ts'), "export default { name: 'User', table: 'users' }\n")
13+
writeFileSync(join(root, 'Mail/Subscriber.ts'), "export default { name: 'Subscriber', table: 'subscribers' }\n")
14+
writeFileSync(join(root, 'LocalHistory.ts'), `Reflect.set(globalThis, Symbol.for(${JSON.stringify(root)}), true)\nexport default { name: 'LocalHistory', table: 'local_history' }\n`)
15+
expect((await loadSchemaAuditModels(root, [' user ', 'SUBSCRIBER'])).map(model => model.table).sort()).toEqual(['subscribers', 'users'])
16+
expect(Reflect.get(globalThis, marker)).toBeUndefined()
17+
expect(await loadSchemaAuditModels(root, [])).toEqual([])
18+
expect((await loadSchemaAuditModels(root)).map(model => model.table).sort()).toEqual(['local_history', 'subscribers', 'users'])
19+
expect(Reflect.get(globalThis, marker)).toBe(true)
20+
}
21+
finally {
22+
Reflect.deleteProperty(globalThis, marker)
23+
rmSync(root, { recursive: true })
24+
}
25+
})

‎storage/framework/defaults/ai/skills/stacks-native/CATALOG.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ Browser runtime bindings are documented separately in `stacks-auto-imports`.
3535
| `@stacksjs/composables` | [`stacks-composables`](../stacks-composables/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/composables/src/index.ts) | 18 |
3636
| `@stacksjs/config` | [`stacks-config`](../stacks-config/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/config/src/index.ts) | 16 |
3737
| `@stacksjs/cron` | [`stacks-cron`](../stacks-cron/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/cron/src/index.ts) | 6 |
38-
| `@stacksjs/database` | [`stacks-database`](../stacks-database/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/index.ts) | 142 |
38+
| `@stacksjs/database` | [`stacks-database`](../stacks-database/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/index.ts) | 143 |
3939
| `@stacksjs/datetime` | [`stacks-datetime`](../stacks-datetime/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/datetime/src/index.ts) | 22 |
4040
| `@stacksjs/defaults` | [`stacks-build`](../stacks-build/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/defaults/package.json) | 3 |
4141
| `@stacksjs/deploy` | [`stacks-deploy`](../stacks-deploy/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/deploy/package.json) | 1 |
@@ -357,7 +357,7 @@ Declared runtime exports: `Database`, `EntityQueryBuilder`, `__flushAfterCommitN
357357

358358
Local source modules: [src/affected-rows.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/affected-rows.ts), [src/auth-tables.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/auth-tables.ts), [src/custom/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/custom/index.ts), [src/database.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/database.ts), [src/datetime-columns.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/datetime-columns.ts), [src/ddl-constraints.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/ddl-constraints.ts), [src/defaults.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/defaults.ts), [src/dialect.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/dialect.ts), [src/driver-config.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/driver-config.ts), [src/drivers/dynamodb.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/drivers/dynamodb.ts), [src/drivers/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/drivers/index.ts), [src/ensure-database.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/ensure-database.ts), [src/erd.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/erd.ts), [src/fk-audit.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/fk-audit.ts), [src/framework-renames.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/framework-renames.ts), [src/framework-route-admission.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/framework-route-admission.ts), [src/hand-written-migrations.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/hand-written-migrations.ts), [src/ignored-migrations.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/ignored-migrations.ts), [src/index-shape.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/index-shape.ts), [src/managed-columns.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/managed-columns.ts), [src/migration-dialect.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/migration-dialect.ts), [src/migration-ledger.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/migration-ledger.ts), [src/migration-names.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/migration-names.ts), [src/migration-path.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/migration-path.ts), [src/migrations.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/migrations.ts), [src/model-sources.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/model-sources.ts), [src/notification-tables.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/notification-tables.ts), [src/package-migrations.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/package-migrations.ts), [src/package-models.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/package-models.ts), [src/query-logger.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/query-logger.ts), [src/rbac-tables.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/rbac-tables.ts), [src/relation-columns.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/relation-columns.ts), [src/replicas.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/replicas.ts), [src/row-lease.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/row-lease.ts), [src/row-lock.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/row-lock.ts), [src/safe-migrations.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/safe-migrations.ts), [src/schema-align.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/schema-align.ts), [src/schema-drift.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/schema-drift.ts), [src/seeder.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/seeder.ts), [src/shadowed-models.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/shadowed-models.ts), [src/sql-helpers.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/sql-helpers.ts), [src/table-exists.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/table-exists.ts), [src/trait-tables.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/trait-tables.ts), [src/transaction-context.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/transaction-context.ts), [src/transaction-options.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/transaction-options.ts), [src/types.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/types.ts), [src/unique-audit.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/unique-audit.ts), [src/utc-defaults.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/utc-defaults.ts), [src/utils.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/utils.ts), [src/uuid-columns.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/uuid-columns.ts), [src/vschema.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/vschema.ts).
359359

360-
Evidence directory: [142 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
360+
Evidence directory: [143 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
361361

362362
### @stacksjs/datetime
363363

0 commit comments

Comments
 (0)