@happyvertical/smrt-cli 0.51.31 → 0.51.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/dist/{ApiKey-BZmbOTnL-Cv3Wygmt.js → ApiKey-BZmbOTnL-B5lc6Wx3.js} +2 -2
  2. package/dist/ApiKeyCollection-Bfb_nw81-DC5iJ1mb.js +2 -0
  3. package/dist/AuditLogCollection-B1YonCAP-Bk3462Oa.js +2 -0
  4. package/dist/{NostrIdentity-n70E0vck-vTE-rc6q.js → NostrIdentity-n70E0vck-usXX4s_K.js} +3 -3
  5. package/dist/NostrIdentityCollection-Ca74dkaL-EMjWAg-m.js +2 -0
  6. package/dist/{OidcIdentity-K8V4u0CR-wPYvpzJB.js → OidcIdentity-K8V4u0CR-BVLWjf-i.js} +2 -2
  7. package/dist/OidcIdentityCollection-gnrLoF08-BBZE53OW.js +2 -0
  8. package/dist/ProfileAssetCollection-CmbeSgDi-HoBqJG3G.js +2 -0
  9. package/dist/{ProfileCollection-DTT4KNpQ-DmsRHTBt.js → ProfileCollection-DTT4KNpQ-CBSNj-47.js} +25 -25
  10. package/dist/ProfileMetadataCollection-DxX_BJKV-CmmrJM8N.js +2 -0
  11. package/dist/{ProfileMetafieldCollection-CMKhVi2I-m8oSrJ89.js → ProfileMetafieldCollection-CMKhVi2I-fJIfcATW.js} +1 -1
  12. package/dist/{ProfileRelationshipCollection-DUVgaIqf-BAg4tA8Y.js → ProfileRelationshipCollection-DUVgaIqf-CuZEerRb.js} +1 -1
  13. package/dist/{ProfileRelationshipTermCollection-DtA9OM23-DSGT-cfT.js → ProfileRelationshipTermCollection-DtA9OM23-BUs2ORAN.js} +1 -1
  14. package/dist/{ProfileRelationshipType-BRiRka6t-DPudoJjG.js → ProfileRelationshipType-BRiRka6t-DFa-_Qqp.js} +1 -1
  15. package/dist/{ProfileRelationshipTypeCollection-BdXwd7Kf-D__rQBOn.js → ProfileRelationshipTypeCollection-BdXwd7Kf-CcvbhUWo.js} +1 -1
  16. package/dist/cli-generator.d.ts +243 -0
  17. package/dist/cli-generator.d.ts.map +1 -0
  18. package/dist/commands/config-export.d.ts +9 -0
  19. package/dist/commands/config-export.d.ts.map +1 -0
  20. package/dist/commands/db-command-utils.d.ts +24 -0
  21. package/dist/commands/db-command-utils.d.ts.map +1 -0
  22. package/dist/commands/db-diff.d.ts +8 -0
  23. package/dist/commands/db-diff.d.ts.map +1 -0
  24. package/dist/commands/db-drop-framework-base-tables.d.ts +28 -0
  25. package/dist/commands/db-drop-framework-base-tables.d.ts.map +1 -0
  26. package/dist/commands/db-generate.d.ts +9 -0
  27. package/dist/commands/db-generate.d.ts.map +1 -0
  28. package/dist/commands/db-history.d.ts +8 -0
  29. package/dist/commands/db-history.d.ts.map +1 -0
  30. package/dist/commands/db-materialize-tenant-hierarchy.d.ts +12 -0
  31. package/dist/commands/db-materialize-tenant-hierarchy.d.ts.map +1 -0
  32. package/dist/commands/db-migrate-actions.d.ts +338 -0
  33. package/dist/commands/db-migrate-actions.d.ts.map +1 -0
  34. package/dist/commands/db-migrate-agent-schedule-slugs.d.ts +3 -0
  35. package/dist/commands/db-migrate-agent-schedule-slugs.d.ts.map +1 -0
  36. package/dist/commands/db-migrate-int8.d.ts +11 -0
  37. package/dist/commands/db-migrate-int8.d.ts.map +1 -0
  38. package/dist/commands/db-migrate-ledger-accounts.d.ts +8 -0
  39. package/dist/commands/db-migrate-ledger-accounts.d.ts.map +1 -0
  40. package/dist/commands/db-migrate-null-equal-indexes.d.ts +3 -0
  41. package/dist/commands/db-migrate-null-equal-indexes.d.ts.map +1 -0
  42. package/dist/commands/db-migrate-uuid.d.ts +171 -0
  43. package/dist/commands/db-migrate-uuid.d.ts.map +1 -0
  44. package/dist/commands/db-orphans.d.ts +39 -0
  45. package/dist/commands/db-orphans.d.ts.map +1 -0
  46. package/dist/commands/db-parity.d.ts +70 -0
  47. package/dist/commands/db-parity.d.ts.map +1 -0
  48. package/dist/commands/db-permissions.d.ts +19 -0
  49. package/dist/commands/db-permissions.d.ts.map +1 -0
  50. package/dist/commands/db-prune.d.ts +70 -0
  51. package/dist/commands/db-prune.d.ts.map +1 -0
  52. package/dist/commands/db-rollback.d.ts +44 -0
  53. package/dist/commands/db-rollback.d.ts.map +1 -0
  54. package/dist/commands/db-status.d.ts +91 -0
  55. package/dist/commands/db-status.d.ts.map +1 -0
  56. package/dist/commands/dev-knowledge.d.ts +10 -0
  57. package/dist/commands/dev-knowledge.d.ts.map +1 -0
  58. package/dist/commands/dev-runtime.d.ts +14 -0
  59. package/dist/commands/dev-runtime.d.ts.map +1 -0
  60. package/dist/commands/dispatch.d.ts +11 -0
  61. package/dist/commands/dispatch.d.ts.map +1 -0
  62. package/dist/commands/docs-claude.d.ts +44 -0
  63. package/dist/commands/docs-claude.d.ts.map +1 -0
  64. package/dist/commands/export.d.ts +31 -0
  65. package/dist/commands/export.d.ts.map +1 -0
  66. package/dist/commands/generate.d.ts +12 -0
  67. package/dist/commands/generate.d.ts.map +1 -0
  68. package/dist/commands/git.d.ts +41 -0
  69. package/dist/commands/git.d.ts.map +1 -0
  70. package/dist/commands/gnode.d.ts +11 -0
  71. package/dist/commands/gnode.d.ts.map +1 -0
  72. package/dist/commands/index.d.ts +23 -0
  73. package/dist/commands/index.d.ts.map +1 -0
  74. package/dist/commands/init.d.ts +11 -0
  75. package/dist/commands/init.d.ts.map +1 -0
  76. package/dist/commands/json-validator.d.ts +155 -0
  77. package/dist/commands/json-validator.d.ts.map +1 -0
  78. package/dist/commands/migration-failure-analysis.d.ts +12 -0
  79. package/dist/commands/migration-failure-analysis.d.ts.map +1 -0
  80. package/dist/commands/playground.d.ts +8 -0
  81. package/dist/commands/playground.d.ts.map +1 -0
  82. package/dist/commands/postgres-timestamp-migration.d.ts +11 -0
  83. package/dist/commands/postgres-timestamp-migration.d.ts.map +1 -0
  84. package/dist/commands/runtime-check-command.d.ts +5 -0
  85. package/dist/commands/runtime-check-command.d.ts.map +1 -0
  86. package/dist/commands/schema-contract.d.ts +83 -0
  87. package/dist/commands/schema-contract.d.ts.map +1 -0
  88. package/dist/commands/sti-upgrade.d.ts +51 -0
  89. package/dist/commands/sti-upgrade.d.ts.map +1 -0
  90. package/dist/commands/utilities.d.ts +134 -0
  91. package/dist/commands/utilities.d.ts.map +1 -0
  92. package/dist/commands/validation-types.d.ts +119 -0
  93. package/dist/commands/validation-types.d.ts.map +1 -0
  94. package/dist/commands/workbench.d.ts +8 -0
  95. package/dist/commands/workbench.d.ts.map +1 -0
  96. package/dist/{commands-Dh9aoJhm.js → commands-DjkVEXmb.js} +2 -2
  97. package/dist/config.d.ts +70 -0
  98. package/dist/config.d.ts.map +1 -0
  99. package/dist/discovery/index.d.ts +6 -0
  100. package/dist/discovery/index.d.ts.map +1 -0
  101. package/dist/discovery/manifest-discovery.d.ts +67 -0
  102. package/dist/discovery/manifest-discovery.d.ts.map +1 -0
  103. package/dist/discovery/manifest-identity.d.ts +10 -0
  104. package/dist/discovery/manifest-identity.d.ts.map +1 -0
  105. package/dist/{dist-C2jQ7IGl.js → dist-CYBGFt2p.js} +4 -4
  106. package/dist/{dist-B6_K9o7Y.js → dist-DD9wiC0-.js} +25 -25
  107. package/dist/{dist-Cv14Wf2P.js → dist-DJ_WTzB9.js} +2 -2
  108. package/dist/{dist-Be-ArZYl.js → dist-iN1z9gzn.js} +3 -3
  109. package/dist/index.d.ts +9 -1
  110. package/dist/index.d.ts.map +1 -0
  111. package/dist/index.js +9 -9
  112. package/dist/loaders/class-loader.d.ts +53 -0
  113. package/dist/loaders/class-loader.d.ts.map +1 -0
  114. package/dist/loaders/git-loader.d.ts +36 -0
  115. package/dist/loaders/git-loader.d.ts.map +1 -0
  116. package/dist/loaders/index.d.ts +9 -0
  117. package/dist/loaders/index.d.ts.map +1 -0
  118. package/dist/loaders/local-loader.d.ts +23 -0
  119. package/dist/loaders/local-loader.d.ts.map +1 -0
  120. package/dist/loaders/npm-loader.d.ts +40 -0
  121. package/dist/loaders/npm-loader.d.ts.map +1 -0
  122. package/dist/loaders/template-loader.d.ts +62 -0
  123. package/dist/loaders/template-loader.d.ts.map +1 -0
  124. package/dist/{oidcProvisioningPrimitives-0-3n3D6f-CDDRCBIe.js → oidcProvisioningPrimitives-0-3n3D6f-CJHDoAXn.js} +4 -4
  125. package/dist/resolveIdentity-BrJDCjYi-1VmNML6W.js +2 -0
  126. package/dist/runtime-check.d.ts +19 -0
  127. package/dist/runtime-check.d.ts.map +1 -0
  128. package/dist/utils/generator.d.ts +48 -0
  129. package/dist/utils/generator.d.ts.map +1 -0
  130. package/dist/utils/index.d.ts +5 -0
  131. package/dist/utils/index.d.ts.map +1 -0
  132. package/package.json +10 -12
  133. package/dist/ApiKeyCollection-Bfb_nw81-CtvdoVgy.js +0 -2
  134. package/dist/AuditLogCollection-B1YonCAP-DqsjkPEt.js +0 -2
  135. package/dist/NostrIdentityCollection-Ca74dkaL-CN7lM1Z-.js +0 -2
  136. package/dist/OidcIdentityCollection-gnrLoF08-aTRP5F16.js +0 -2
  137. package/dist/ProfileAssetCollection-CmbeSgDi-6917iH0C.js +0 -2
  138. package/dist/ProfileMetadataCollection-DxX_BJKV-DNfvqy24.js +0 -2
  139. package/dist/resolveIdentity-BrJDCjYi-Ub2HbiBO.js +0 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-history.d.ts","sourceRoot":"","sources":["../../src/commands/db-history.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AA2DtD,eAAO,MAAM,gBAAgB,EAAE,UAgV9B,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { CLICommand } from '../cli-generator.js';
2
+ /**
3
+ * `smrt db:materialize-tenant-hierarchy` (smrt#3036).
4
+ *
5
+ * Backfills `tenants.hierarchy_path` / `hierarchy_level` from each row's
6
+ * `parent_tenant_id` chain. `Tenant.save()` in `@happyvertical/smrt-users`
7
+ * now maintains both; this repairs rows written before it did, which left `inheritsToDescendants` and the declared ancestor-read
8
+ * policy failing closed. Idempotent; refuses (writing nothing) when any
9
+ * tenant's parent chain is broken.
10
+ */
11
+ export declare const dbMaterializeTenantHierarchyCommand: CLICommand;
12
+ //# sourceMappingURL=db-materialize-tenant-hierarchy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-materialize-tenant-hierarchy.d.ts","sourceRoot":"","sources":["../../src/commands/db-materialize-tenant-hierarchy.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAYtD;;;;;;;;GAQG;AACH,eAAO,MAAM,mCAAmC,EAAE,UAgGjD,CAAC"}
@@ -0,0 +1,338 @@
1
+ /**
2
+ * Which column property an `alter_column` change repairs (mirrors
3
+ * `ColumnAlteration` in @happyvertical/smrt-core).
4
+ */
5
+ export type ColumnAlterationLike = 'set_not_null' | 'drop_not_null' | 'set_default' | 'drop_default';
6
+ /**
7
+ * Report-only detail attached to a change the differ surfaces but does not
8
+ * execute (mirrors `SchemaChangeAdvisory` in @happyvertical/smrt-core).
9
+ */
10
+ export interface SchemaChangeAdvisoryLike {
11
+ severity: 'warning' | 'info';
12
+ message: string;
13
+ suggestedSql?: string[];
14
+ }
15
+ /** Mirrors core's `ForeignKeyAction` (see `@happyvertical/smrt-core/schema`). */
16
+ export type ForeignKeyActionLike = 'CASCADE' | 'SET NULL' | 'RESTRICT' | 'NO ACTION';
17
+ /**
18
+ * Local mirror of core's `ForeignKeyDefinition` — just enough shape for
19
+ * dependency analysis (#2748) and for rebuilding the `ADD CONSTRAINT`
20
+ * statements after an orphan-FK disposition repairs the blocking rows.
21
+ */
22
+ export interface ForeignKeyDefinitionLike {
23
+ column: string;
24
+ referencesTable: string;
25
+ referencesColumn: string;
26
+ onDelete?: ForeignKeyActionLike;
27
+ onUpdate?: ForeignKeyActionLike;
28
+ }
29
+ export interface MigrationAction {
30
+ type: 'add_column' | 'drop_column' | 'alter_column' | 'add_foreign_key' | 'drop_foreign_key' | 'add_index' | 'drop_index' | 'type_mismatch' | 'type_upgrade';
31
+ tableName: string;
32
+ className: string;
33
+ column?: {
34
+ name: string;
35
+ type: string;
36
+ notNull?: boolean;
37
+ defaultValue?: unknown;
38
+ unique?: boolean;
39
+ };
40
+ index?: {
41
+ name: string;
42
+ columns: string[];
43
+ unique?: boolean;
44
+ };
45
+ /**
46
+ * Set on `drop_index` actions — the index name being dropped. We track
47
+ * this separately from `index` because the differ does not (and cannot,
48
+ * for the orphan-drop case) always know the original column list of a
49
+ * DB-side index that's being removed.
50
+ */
51
+ indexName?: string;
52
+ /**
53
+ * Set on `drop_column` / `alter_column` actions — the live column name.
54
+ * `column` is only populated when the differ had a manifest definition.
55
+ */
56
+ columnName?: string;
57
+ /** Set on `alter_column` actions (#2369). */
58
+ alteration?: ColumnAlterationLike;
59
+ /**
60
+ * Ordering phase carried through from `SchemaChange.phase` (#2608).
61
+ * `pre_foreign_key` marks the pre-R11 `text` -> `uuid` convergence, which
62
+ * must run before every `CREATE TABLE` (an acyclic new child keeps its
63
+ * foreign key inline) and before every foreign-key statement in the batch.
64
+ */
65
+ phase?: 'pre_foreign_key';
66
+ mismatch?: {
67
+ column: string;
68
+ expected: string;
69
+ actual: string;
70
+ };
71
+ sql?: string;
72
+ sqlStatements?: string[];
73
+ advisory?: SchemaChangeAdvisoryLike;
74
+ /** Set on `add_foreign_key` / `drop_foreign_key` actions (#2748). */
75
+ foreignKey?: ForeignKeyDefinitionLike;
76
+ /** See `SchemaChangeLike.orphanBlocked` (#2748). */
77
+ orphanBlocked?: boolean;
78
+ /** See `SchemaChangeLike.orphanNullable` (#2748). */
79
+ orphanNullable?: boolean;
80
+ /** See `SchemaChangeLike.engineUnsupported` (#2748). */
81
+ engineUnsupported?: boolean;
82
+ }
83
+ /**
84
+ * A change the differ reports but does not execute: orphan columns/indexes
85
+ * and relaxations not opted into (#2369). Surfaced by db:migrate/db:diff/
86
+ * db:status; never turned into a tracker migration.
87
+ */
88
+ export interface SchemaAdvisory {
89
+ type: 'orphan_column' | 'orphan_index' | 'alter_column' | 'type_upgrade' | 'rename_data_pending';
90
+ tableName: string;
91
+ className: string;
92
+ name: string;
93
+ alteration?: ColumnAlterationLike;
94
+ actual?: string;
95
+ advisory: SchemaChangeAdvisoryLike;
96
+ }
97
+ export interface SchemaChangeLike {
98
+ type: 'add_table' | 'drop_table' | 'add_column' | 'drop_column' | 'alter_column' | 'orphan_column' | 'add_foreign_key' | 'drop_foreign_key' | 'add_index' | 'drop_index' | 'orphan_index' | 'type_mismatch' | 'type_upgrade' | 'rename_data_pending';
99
+ table: string;
100
+ name?: string;
101
+ column?: {
102
+ type: string;
103
+ notNull?: boolean;
104
+ defaultValue?: unknown;
105
+ unique?: boolean;
106
+ };
107
+ index?: {
108
+ name: string;
109
+ columns: string[];
110
+ unique?: boolean;
111
+ };
112
+ mismatch?: {
113
+ expected: string;
114
+ actual: string;
115
+ };
116
+ alteration?: ColumnAlterationLike;
117
+ /** See `MigrationAction.phase` (#2608). */
118
+ phase?: 'pre_foreign_key';
119
+ advisory?: SchemaChangeAdvisoryLike;
120
+ sql?: string;
121
+ sqlStatements?: string[];
122
+ /** Set on `add_foreign_key` / `drop_foreign_key` changes (#2748). */
123
+ foreignKey?: ForeignKeyDefinitionLike;
124
+ /**
125
+ * True on an advisory-only `add_foreign_key` change specifically blocked
126
+ * by live orphan child rows (#2748), as opposed to any other manual-repair
127
+ * reason. Mirrors core's `SchemaChange.orphanBlocked`.
128
+ */
129
+ orphanBlocked?: boolean;
130
+ /**
131
+ * Present alongside `orphanBlocked: true`: whether the child column
132
+ * allows NULL. Mirrors core's `SchemaChange.orphanNullable`.
133
+ */
134
+ orphanNullable?: boolean;
135
+ /**
136
+ * True on an advisory-only `add_foreign_key` change blocked because this
137
+ * engine cannot express the constraint at all (SQLite/DuckDB), as opposed
138
+ * to a data or type problem with the column itself. Mirrors core's
139
+ * `SchemaChange.engineUnsupported`.
140
+ */
141
+ engineUnsupported?: boolean;
142
+ }
143
+ /** True when a change carries an advisory and no executable statement. */
144
+ export declare function isAdvisoryOnlyChangeLike(change: {
145
+ advisory?: SchemaChangeAdvisoryLike;
146
+ sql?: string;
147
+ sqlStatements?: string[];
148
+ }): boolean;
149
+ export type TypeUpgradeExecutionKind = 'executable' | 'manual' | 'noop';
150
+ export type FailedMigrationClassification = 'unresolved' | 'superseded' | 'other';
151
+ export interface FailedMigrationLike {
152
+ name: string;
153
+ error_message?: string | null;
154
+ }
155
+ export interface FailedMigrationSummaryItem {
156
+ name: string;
157
+ classification: FailedMigrationClassification;
158
+ recommendation: string;
159
+ errorMessage: string | null;
160
+ }
161
+ export interface FailedMigrationBuckets {
162
+ unresolved: FailedMigrationSummaryItem[];
163
+ superseded: FailedMigrationSummaryItem[];
164
+ other: FailedMigrationSummaryItem[];
165
+ }
166
+ export interface DbMigrateFailureState {
167
+ manualInterventionCount?: number;
168
+ tableErrorCount?: number;
169
+ migrationErrorCount?: number;
170
+ stiErrorCount?: number;
171
+ dryRun?: boolean;
172
+ }
173
+ export declare function classifyTypeUpgradeSql(sql?: string): TypeUpgradeExecutionKind;
174
+ export declare function getSyntheticMigrationNameForAction(action: MigrationAction): string | null;
175
+ export declare function getSyntheticMigrationNameForChange(change: SchemaChangeLike): string | null;
176
+ /**
177
+ * Return every tracker name that can represent the current schema change.
178
+ *
179
+ * New type upgrades use a fingerprinted id, but releases before #2111 wrote
180
+ * failures under the bare table-and-column id. Keep that old id as a
181
+ * classification alias only: execution always uses the fingerprinted id, so
182
+ * no applied migration record is rewritten or reused for a new conversion.
183
+ */
184
+ export declare function getSyntheticMigrationNamesForChange(change: SchemaChangeLike): string[];
185
+ export declare function shouldFailDbMigrate(state: DbMigrateFailureState): boolean;
186
+ export declare function shouldApplySchemaMigrations(state: {
187
+ dryRun?: boolean;
188
+ }): boolean;
189
+ export declare function classifyFailedMigration(migrationName: string, unresolvedSyntheticMigrationNames: Set<string>): FailedMigrationClassification;
190
+ export declare function getUnresolvedGeneratedMigrationNames(changes: SchemaChangeLike[]): Set<string>;
191
+ export declare const getUnresolvedAdditiveMigrationNames: typeof getUnresolvedGeneratedMigrationNames;
192
+ export declare function getFailedMigrationRecommendation(classification: FailedMigrationClassification, liveSchemaCompared?: boolean): string;
193
+ export declare function summarizeFailedMigrations(failedMigrations: FailedMigrationLike[], unresolvedSyntheticMigrationNames: Set<string> | null): FailedMigrationBuckets;
194
+ export declare function partitionSchemaChanges(changes: SchemaChangeLike[], getClassForTable: (tableName: string) => string): {
195
+ migrations: MigrationAction[];
196
+ manualInterventions: MigrationAction[];
197
+ /**
198
+ * Report-only findings (#2369): orphan columns/indexes and relaxations the
199
+ * operator has not opted into. Printed, never executed, and they never
200
+ * fail db:migrate on their own.
201
+ */
202
+ advisories: SchemaAdvisory[];
203
+ };
204
+ /**
205
+ * Print report-only schema findings (#2369) in a stable order: warnings
206
+ * first (an orphan NOT NULL column that breaks inserts, a stale unique
207
+ * constraint, a relaxation not opted into), then info, then orphan tables
208
+ * (verbose only — shared databases legitimately hold tables from other
209
+ * apps). Shared by db:migrate and db:diff so both commands report the same
210
+ * findings the same way.
211
+ */
212
+ export declare function printSchemaAdvisories(advisories: SchemaAdvisory[], options?: {
213
+ orphanTables?: string[];
214
+ verbose?: boolean;
215
+ log?: (line: string) => void;
216
+ }): void;
217
+ /**
218
+ * Every column a manual intervention blocks, keyed `table.column`, with the
219
+ * human-readable reason (the action's advisory message, or a description of
220
+ * the type mismatch) a dependent change is withheld for. `advisories`
221
+ * includes only report-only `type_upgrade` findings (the #2608 refused
222
+ * uuid convergence) — that shape is a genuine, permanent column-state block
223
+ * that names a column just as concretely as a manual intervention does, so
224
+ * omitting it let `--apply-unblocked` apply an index/alter/drop against a
225
+ * column whose type convergence is itself blocked (review finding, #2748).
226
+ *
227
+ * `alter_column` advisories are deliberately excluded even though the type
228
+ * exists on `SchemaAdvisory`: an advisory-only `alter_column` is produced
229
+ * only by an un-opted-into relaxation (`drop_default`/`drop_not_null` when
230
+ * `--relax-columns` was not passed) — it says the live column is *stricter*
231
+ * than the manifest, not that the column's state blocks anything, and it
232
+ * reappears on every run regardless of `--apply-unblocked`. Treating it as
233
+ * a blocked column reproduced the exact defect this function's
234
+ * `engineUnsupported` exclusion fixed for `add_foreign_key`: permanently
235
+ * withholding unrelated executable DDL on that column (review finding,
236
+ * #2748, second pass). A genuinely blocked `alter_column` (e.g. NOT NULL
237
+ * required with live NULLs and no default) carries executable-looking SQL
238
+ * as a comment and already reaches `manualInterventions` instead, where it
239
+ * is covered by the loop above via `columnName`.
240
+ */
241
+ export declare function computeBlockedColumns(manualInterventions: MigrationAction[], advisories?: SchemaAdvisory[]): Map<string, string>;
242
+ /**
243
+ * `table.column` keys whose only manual-intervention block is an
244
+ * orphan-blocked `add_foreign_key` on that same (child) column — a
245
+ * row-data condition (existing rows don't match a parent), not a
246
+ * column-state one. An un-opted-into `--relax-columns` relaxation on that
247
+ * column (`DROP NOT NULL`/`DROP DEFAULT`) is not unsafe against orphan
248
+ * rows; it is in fact the exact remediation that makes a NOT-NULL-child
249
+ * orphan block eventually resolvable by `--null-orphans` on a later run.
250
+ * Gating that `alter_column` on the orphan block made `--apply-unblocked
251
+ * --relax-columns` withhold it forever — the relaxation never applies, the
252
+ * live column never becomes nullable, the orphan block never clears, in a
253
+ * stable non-converging loop (review finding, #2748). Every other
254
+ * dependent shape on that column (an index, an unrelated foreign key, a
255
+ * `drop_column`) still correctly stays gated by the orphan block; this set
256
+ * narrows the exclusion to `alter_column` alone at the call site.
257
+ */
258
+ export declare function computeOrphanOnlyBlockedColumns(manualInterventions: MigrationAction[]): Set<string>;
259
+ /** One migration withheld under `--apply-unblocked` and why. */
260
+ export interface WithheldMigration {
261
+ action: MigrationAction;
262
+ /** `table.column` of the blocked change this one depends on. */
263
+ dependsOn: string;
264
+ reason: string;
265
+ }
266
+ /**
267
+ * Partition executable migrations (the differ's "safe DDL" bucket) into
268
+ * those independent of every blocked column and those that depend on one
269
+ * (#2748's dependency rule): an index or foreign key on a column whose type
270
+ * upgrade is blocked, or a foreign key whose orphan rows block it, stays
271
+ * withheld; everything else is applied. Pure and order-preserving so a
272
+ * dry-run preview and a real apply partition identically.
273
+ *
274
+ * A `drop_index` carries no column list of its own (a DB-side index being
275
+ * removed; see `MigrationAction.indexName`'s doc comment), so it is never
276
+ * itself a dependency target — EXCEPT when it is the drop half of the
277
+ * #1165 shape-drift recreate pair (`drop_index` then `add_index` for the
278
+ * SAME name, in that order, in the same batch). Withholding the `add_index`
279
+ * half alone while letting its paired `drop_index` proceed would remove the
280
+ * existing index/uniqueness enforcement with no replacement — reachable and
281
+ * unsafe (review, #2748) — so a `drop_index` withholds together with any
282
+ * `add_index` of the same name that this partition withheld.
283
+ */
284
+ export declare function partitionUnblockedMigrations(migrations: MigrationAction[], blockedColumns: Map<string, string>, orphanOnlyBlockedColumns?: Set<string>): {
285
+ applied: MigrationAction[];
286
+ withheld: WithheldMigration[];
287
+ };
288
+ /**
289
+ * Drop any pending post-apply report entry whose `action` reference was
290
+ * withheld by `partitionUnblockedMigrations()` (review finding, #2748): a
291
+ * `--null-orphans` combined null+add-FK migration can itself depend on a
292
+ * separately blocked *parent* column and get withheld under
293
+ * `--apply-unblocked` even though it already resolved out of
294
+ * `manualInterventions`. Without this filter, the post-apply report printed
295
+ * a `✓ ... resolved` line for a disposition that never executed — the same
296
+ * relationship the `🔒 Withheld` listing (from `withheld`) already names.
297
+ * Matches by object identity, not by table/column, since the caller pushed
298
+ * the exact `MigrationAction` reference into both `migrations` and the
299
+ * pending entry.
300
+ */
301
+ export declare function filterUnresolvedOrphanDispositions<T extends {
302
+ action: MigrationAction;
303
+ }>(pending: T[], withheld: WithheldMigration[]): T[];
304
+ /** One orphan-blocked FK the child column allows nulling out. */
305
+ export interface OrphanDispositionPlanItem {
306
+ action: MigrationAction;
307
+ tableName: string;
308
+ column: string;
309
+ /** `SELECT ... orphan_key ...` probe the differ generated (read-only). */
310
+ detectorSql: string;
311
+ /** Executable `UPDATE ... SET <column> = NULL WHERE ...` statement. */
312
+ repairSql: string;
313
+ }
314
+ /**
315
+ * Split `manualInterventions` into orphan-blocked `add_foreign_key` actions
316
+ * whose child column is nullable (an opt-in `--null-orphans` disposition can
317
+ * null the references and proceed) and every other manual intervention,
318
+ * including orphan-blocked FKs on a NOT NULL child column, which keep the
319
+ * existing "Manual repair required" refusal (#2748) unconditionally — a
320
+ * caller must never delete rows to make room for one of these.
321
+ *
322
+ * Reuses the differ's own rendered `advisory.suggestedSql` (detector at
323
+ * index 0, repair at index 1) rather than re-deriving the orphan probe's
324
+ * uuid-cast options, so the disposition always runs exactly the SQL the
325
+ * differ already decided on.
326
+ */
327
+ export declare function planOrphanDispositions(manualInterventions: MigrationAction[]): {
328
+ nullable: OrphanDispositionPlanItem[];
329
+ notNullable: MigrationAction[];
330
+ };
331
+ /**
332
+ * Wrap an orphan-probe `SELECT` (the differ's `renderForeignKeyOrphanDetector`
333
+ * output, a bare `SELECT ... orphan_key ...` with no `LIMIT`) as a
334
+ * `COUNT(*)` so `--null-orphans` can report before/after counts without
335
+ * re-deriving the probe's own uuid-cast options.
336
+ */
337
+ export declare function orphanCountSql(detectorSql: string): string;
338
+ //# sourceMappingURL=db-migrate-actions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-migrate-actions.d.ts","sourceRoot":"","sources":["../../src/commands/db-migrate-actions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { CLICommand } from '../cli-generator.js';
2
+ export declare const dbMigrateAgentScheduleSlugsCommand: CLICommand;
3
+ //# sourceMappingURL=db-migrate-agent-schedule-slugs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-migrate-agent-schedule-slugs.d.ts","sourceRoot":"","sources":["../../src/commands/db-migrate-agent-schedule-slugs.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAWtD,eAAO,MAAM,kCAAkC,EAAE,UA6EhD,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * db:migrate-int8 Command
3
+ *
4
+ * Explicitly widens legacy PostgreSQL/DuckDB int4 columns created before
5
+ * #2373. This is deliberately separate from `db:migrate`: PostgreSQL rewrites
6
+ * each table, so an operator must review the row-count preflight and schedule
7
+ * a maintenance window before opting in.
8
+ */
9
+ import type { CLICommand } from '../cli-generator.js';
10
+ export declare const dbMigrateInt8Command: CLICommand;
11
+ //# sourceMappingURL=db-migrate-int8.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-migrate-int8.d.ts","sourceRoot":"","sources":["../../src/commands/db-migrate-int8.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAiBtD,eAAO,MAAM,oBAAoB,EAAE,UA0IlC,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { CLICommand } from '../cli-generator.js';
2
+ /**
3
+ * Move ledger accounts out of the `accounts` table they shared with
4
+ * smrt-messages before #3098. Run between two `db:migrate` passes; see the
5
+ * smrt-ledgers README.
6
+ */
7
+ export declare const dbMigrateLedgerAccountsCommand: CLICommand;
8
+ //# sourceMappingURL=db-migrate-ledger-accounts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-migrate-ledger-accounts.d.ts","sourceRoot":"","sources":["../../src/commands/db-migrate-ledger-accounts.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAYtD;;;;GAIG;AACH,eAAO,MAAM,8BAA8B,EAAE,UAkF5C,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { CLICommand } from '../cli-generator.js';
2
+ export declare const dbMigrateNullEqualIndexesCommand: CLICommand;
3
+ //# sourceMappingURL=db-migrate-null-equal-indexes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-migrate-null-equal-indexes.d.ts","sourceRoot":"","sources":["../../src/commands/db-migrate-null-equal-indexes.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAQtD,eAAO,MAAM,gCAAgC,EAAE,UA8E9C,CAAC"}
@@ -0,0 +1,171 @@
1
+ /**
2
+ * db:migrate-uuid Command
3
+ *
4
+ * relationships-v2 (0.27.0) data migration helper.
5
+ *
6
+ * The 0.27.0 release makes `@foreignKey()` / `@crossPackageRef()` (and primary
7
+ * `id`) columns native `uuid` on PostgreSQL. The structural migration
8
+ * (`smrt db:migrate`) is *additive* — it cannot rename or change a column's
9
+ * type in place — so two pieces of per-project DATA migration remain:
10
+ *
11
+ * 1. **R3 column renames** (e.g. `tags.parent_slug → parent_id`,
12
+ * `facts.parent_id → previous_fact_id`, `assets.parent_id →
13
+ * source_asset_id`). The new column is added empty and the old column is
14
+ * left orphaned. Use `--rename "old:new[,old2:new2]"` (optionally with
15
+ * `--table <name>`) to copy old → new (only where new is still empty) and
16
+ * drop the old column.
17
+ *
18
+ * 2. **TEXT → native uuid conversion**. Most existing `id`/FK columns already
19
+ * hold UUID-shaped strings in TEXT columns and can be promoted to native
20
+ * `uuid`. Conversion is gated on TWO independent checks, BOTH of which must
21
+ * pass for a column to be converted:
22
+ *
23
+ * (a) **Schema-declared UUID** — the column is one the SMRT manifest
24
+ * declares as a `UUID` type (primary `id`, `@foreignKey()` /
25
+ * `@crossPackageRef()` columns). The declared types come from
26
+ * `ObjectRegistry.getAllSchemasAsDefinitions()` — the SAME source
27
+ * `smrt db:migrate` / `db:diff` use. Columns the schema intentionally
28
+ * keeps TEXT (`external_id`, `message_id`, provider/oauth ids, …) are
29
+ * NEVER converted even when their current data happens to be
30
+ * uuid-shaped, because a future non-uuid insert must still succeed.
31
+ * Tables not present in the manifest (non-SMRT tables in the `public`
32
+ * schema) drop out automatically.
33
+ *
34
+ * (b) **Data-shape** — every non-empty value is already UUID-shaped.
35
+ * A declared-UUID column that still holds genuine non-uuid values
36
+ * (legacy unhyphenated ids, partially-migrated data, …) is SKIPPED and
37
+ * reported so the operator can clean it before re-running.
38
+ *
39
+ * **Fail-closed:** if the manifest/registry can't be loaded or declares no
40
+ * UUID columns, NOTHING is converted (the operator is told to run from the
41
+ * project root). There is deliberately no name-regex fallback — over-
42
+ * converting a TEXT column the schema tolerates as TEXT (the differ treats
43
+ * uuid/text as equivalent, so it would never self-repair) is irreversible
44
+ * prod-data damage.
45
+ *
46
+ * When BOTH the rename backfills and the uuid conversion run in one invocation
47
+ * they share a SINGLE transaction (one `BEGIN`, one `COMMIT`, one `ROLLBACK` on
48
+ * any failure) so a conversion failure can never leave a half-applied migration
49
+ * with the old columns already dropped. Postgres DDL is transactional, so this
50
+ * holds. With `--skip-convert` the rename phase commits on its own. Both steps
51
+ * are idempotent — re-running is a no-op once the renames are done and the
52
+ * columns are already `uuid`.
53
+ *
54
+ * PostgreSQL only: SQLite and DuckDB store SMRT uuid columns as TEXT (SQLite)
55
+ * or accept uuid strings transparently, so no `ALTER COLUMN TYPE uuid` step is
56
+ * needed there. On a non-Postgres database this command performs the rename
57
+ * backfills (if requested) and then reports that the uuid conversion is a no-op.
58
+ *
59
+ * Run AFTER `smrt db:migrate`.
60
+ *
61
+ * Usage:
62
+ * smrt db:migrate-uuid --dry-run
63
+ * smrt db:migrate-uuid
64
+ * smrt db:migrate-uuid --rename "parent_id:source_asset_id" --table assets
65
+ * smrt db:migrate-uuid --rename "parent_slug:parent_id" --table tags --skip-convert
66
+ */
67
+ import type { CLICommand } from '../cli-generator.js';
68
+ /**
69
+ * Build the set of schema-declared UUID columns from a manifest's
70
+ * `getAllSchemasAsDefinitions()` output.
71
+ *
72
+ * Only columns whose declared `type === 'UUID'` are included. The returned set
73
+ * uses `${table}|${column}` keys for O(1) membership tests. Pure and
74
+ * DB-independent so the gating semantics can be unit-tested without a database.
75
+ */
76
+ export declare function buildDeclaredUuidColumnSet(schemaDefinitions: Record<string, {
77
+ columns?: Record<string, {
78
+ type?: string;
79
+ }>;
80
+ }>): Set<string>;
81
+ /** A live TEXT column scheduled for `ALTER COLUMN … TYPE uuid`. */
82
+ interface ConvertCandidate {
83
+ table: string;
84
+ column: string;
85
+ hasDefault: boolean;
86
+ }
87
+ /**
88
+ * A live TEXT `id`/FK column discovered in the database, annotated with how
89
+ * many of its non-empty values are NOT UUID-shaped.
90
+ */
91
+ export interface LiveTextColumn {
92
+ table: string;
93
+ column: string;
94
+ hasDefault: boolean;
95
+ /** Count of non-empty values that are not UUID-shaped. */
96
+ nonUuid: number;
97
+ /**
98
+ * Count of normalized-value groups with more than one distinct TEXT row
99
+ * mapping to the same uuid (e.g. one hyphenated, one bare-hex row for the
100
+ * same value) — a many-to-one collision the widened shape probe admits.
101
+ * Optional/defaults to 0 so existing call sites need not set it.
102
+ */
103
+ duplicateNormalized?: number;
104
+ }
105
+ /**
106
+ * The outcome of classifying live TEXT columns against the declared-UUID set.
107
+ */
108
+ export interface ConversionPlan {
109
+ convert: ConvertCandidate[];
110
+ /**
111
+ * Declared-UUID columns whose data still has non-uuid values, and/or two or
112
+ * more TEXT rows that normalize to the same uuid (a post-normalization
113
+ * collision — `duplicateNormalized` is present only when > 0).
114
+ */
115
+ skipDirtyData: Array<{
116
+ table: string;
117
+ column: string;
118
+ nonUuid: number;
119
+ duplicateNormalized?: number;
120
+ }>;
121
+ /** Live TEXT columns the schema does NOT declare as UUID (left as TEXT). */
122
+ skipNotDeclared: Array<{
123
+ table: string;
124
+ column: string;
125
+ }>;
126
+ /**
127
+ * Otherwise-convertible columns blocked because a foreign-key partner
128
+ * (transitively) will not convert. Populated by
129
+ * `propagateBlockedForeignKeyPartners`; absent/empty before that step runs.
130
+ */
131
+ skipBlockedPartner?: Array<{
132
+ table: string;
133
+ column: string;
134
+ reason: string;
135
+ }>;
136
+ }
137
+ /** A single-column foreign key edge between two candidate columns. */
138
+ export interface ForeignKeyEdge {
139
+ name: string;
140
+ childTable: string;
141
+ childColumn: string;
142
+ parentTable: string;
143
+ parentColumn: string;
144
+ }
145
+ export declare function propagateBlockedForeignKeyPartners(plan: ConversionPlan, edges: ForeignKeyEdge[]): ConversionPlan;
146
+ /**
147
+ * Decide which live TEXT columns to convert to native `uuid`.
148
+ *
149
+ * A column is converted ONLY if BOTH gates pass:
150
+ * 1. it is in the schema-declared-UUID set, AND
151
+ * 2. all of its non-empty values are already UUID-shaped.
152
+ *
153
+ * Declared-UUID columns with dirty data are reported in `skipDirtyData`;
154
+ * undeclared columns (schema-intentional TEXT, or non-SMRT tables) are reported
155
+ * in `skipNotDeclared`. Pure so the gating can be unit-tested without a DB.
156
+ */
157
+ export declare function planUuidConversions(liveColumns: LiveTextColumn[], declaredUuid: Set<string>): ConversionPlan;
158
+ interface RenameSpec {
159
+ table: string;
160
+ from: string;
161
+ to: string;
162
+ }
163
+ /**
164
+ * Parse `--rename "old:new,old2:new2"` plus the optional default `--table`
165
+ * into structured rename specs. A pair may carry its own table via
166
+ * `table.old:new`; otherwise it falls back to `--table`.
167
+ */
168
+ export declare function parseRenameSpecs(renameArg: string | undefined, defaultTable: string | undefined): RenameSpec[];
169
+ export declare const dbMigrateUuidCommand: CLICommand;
170
+ export {};
171
+ //# sourceMappingURL=db-migrate-uuid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-migrate-uuid.d.ts","sourceRoot":"","sources":["../../src/commands/db-migrate-uuid.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiEG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAqCtD;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,iBAAiB,EAAE,MAAM,CACvB,MAAM,EACN;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAChD,GACA,GAAG,CAAC,MAAM,CAAC,CAWb;AAYD,mEAAmE;AACnE,UAAU,gBAAgB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;IACpB,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B;;;;OAIG;IACH,aAAa,EAAE,KAAK,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,mBAAmB,CAAC,EAAE,MAAM,CAAC;KAC9B,CAAC,CAAC;IACH,4EAA4E;IAC5E,eAAe,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1D;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/E;AAED,sEAAsE;AACtE,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AA+BD,wBAAgB,kCAAkC,CAChD,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE,cAAc,EAAE,GACtB,cAAc,CA6EhB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,cAAc,EAAE,EAC7B,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,GACxB,cAAc,CAgChB;AAED,UAAU,UAAU;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,YAAY,EAAE,MAAM,GAAG,SAAS,GAC/B,UAAU,EAAE,CA2Bd;AAED,eAAO,MAAM,oBAAoB,EAAE,UA4JlC,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * db:orphans Command (#2753)
3
+ *
4
+ * Read-only per-foreign-key orphan count report. `db:migrate`'s orphan probe
5
+ * already gates `ADD CONSTRAINT` with a `LIMIT 1` existence check and prints a
6
+ * suggested repair; this command runs the identical probe as `COUNT(*)` for
7
+ * every manifest-declared foreign key, so planning a repair no longer starts
8
+ * with hand-writing the same SQL against the live database.
9
+ *
10
+ * Strictly diagnostic: it never repairs anything, and the orphan counts
11
+ * themselves never affect the exit code — a database full of orphans still
12
+ * exits 0. It exits non-zero only on a configuration or runtime error (no
13
+ * database configured, or the report itself could not run), the same
14
+ * contract every other `db:*` command uses. The existing "no foreign-key
15
+ * orphan repair, by design" boundary stays exactly where it is. Use `--json`
16
+ * for scripting.
17
+ */
18
+ import { type ForeignKeyOrphanCount, type ForeignKeyOrphanCountReport, type ForeignKeyOrphanSkipped } from '@happyvertical/smrt-core';
19
+ import type { CLICommand } from '../cli-generator.js';
20
+ /** Render one count row as a compact, script-friendly line. */
21
+ export declare function formatOrphanCountLine(count: ForeignKeyOrphanCount): string;
22
+ /**
23
+ * Scrub connection-string credentials from each skipped relationship's
24
+ * `reason`. A `probe_failed` reason is the database driver's error text,
25
+ * which can echo the DSN, so both the JSON and human outputs render this
26
+ * redacted copy.
27
+ */
28
+ export declare function redactOrphanReport(report: ForeignKeyOrphanCountReport): ForeignKeyOrphanCountReport;
29
+ /** Render the full report as console lines. */
30
+ export declare function formatOrphanReport(report: ForeignKeyOrphanCountReport, options?: {
31
+ verbose?: boolean;
32
+ }): string[];
33
+ /** One-line summary used by `db:status`. */
34
+ export declare function summarizeOrphanReport(report: ForeignKeyOrphanCountReport): string;
35
+ /** Foreign keys with at least one orphan row, for `db:status`'s summary. */
36
+ export declare function affectedOrphanCounts(report: ForeignKeyOrphanCountReport): ForeignKeyOrphanCount[];
37
+ export type { ForeignKeyOrphanCount, ForeignKeyOrphanCountReport, ForeignKeyOrphanSkipped, };
38
+ export declare const dbOrphansCommand: CLICommand;
39
+ //# sourceMappingURL=db-orphans.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-orphans.d.ts","sourceRoot":"","sources":["../../src/commands/db-orphans.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,EAChC,KAAK,uBAAuB,EAE7B,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAatD,+DAA+D;AAC/D,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,qBAAqB,GAAG,MAAM,CAM1E;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,2BAA2B,GAClC,2BAA2B,CAQ7B;AAED,+CAA+C;AAC/C,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,2BAA2B,EACnC,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAClC,MAAM,EAAE,CAgDV;AAED,4CAA4C;AAC5C,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,2BAA2B,GAClC,MAAM,CAGR;AAED,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,2BAA2B,GAClC,qBAAqB,EAAE,CAEzB;AAED,YAAY,EACV,qBAAqB,EACrB,2BAA2B,EAC3B,uBAAuB,GACxB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,UA0F9B,CAAC"}