@prisma-next/migration-tools 0.5.0-dev.9 → 0.5.0

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 (130) hide show
  1. package/README.md +34 -22
  2. package/dist/{constants-BRi0X7B_.mjs → constants-DWV9_o2Z.mjs} +2 -2
  3. package/dist/{constants-BRi0X7B_.mjs.map → constants-DWV9_o2Z.mjs.map} +1 -1
  4. package/dist/errors-EPL_9p9f.mjs +297 -0
  5. package/dist/errors-EPL_9p9f.mjs.map +1 -0
  6. package/dist/exports/aggregate.d.mts +614 -0
  7. package/dist/exports/aggregate.d.mts.map +1 -0
  8. package/dist/exports/aggregate.mjs +611 -0
  9. package/dist/exports/aggregate.mjs.map +1 -0
  10. package/dist/exports/constants.d.mts.map +1 -1
  11. package/dist/exports/constants.mjs +2 -3
  12. package/dist/exports/errors.d.mts +68 -0
  13. package/dist/exports/errors.d.mts.map +1 -0
  14. package/dist/exports/errors.mjs +2 -0
  15. package/dist/exports/graph.d.mts +2 -0
  16. package/dist/exports/graph.mjs +1 -0
  17. package/dist/exports/hash.d.mts +52 -0
  18. package/dist/exports/hash.d.mts.map +1 -0
  19. package/dist/exports/hash.mjs +2 -0
  20. package/dist/exports/invariants.d.mts +34 -0
  21. package/dist/exports/invariants.d.mts.map +1 -0
  22. package/dist/exports/invariants.mjs +2 -0
  23. package/dist/exports/io.d.mts +66 -6
  24. package/dist/exports/io.d.mts.map +1 -1
  25. package/dist/exports/io.mjs +2 -3
  26. package/dist/exports/metadata.d.mts +2 -0
  27. package/dist/exports/metadata.mjs +1 -0
  28. package/dist/exports/migration-graph.d.mts +2 -0
  29. package/dist/exports/migration-graph.mjs +2 -0
  30. package/dist/exports/migration-ts.d.mts.map +1 -1
  31. package/dist/exports/migration-ts.mjs +2 -4
  32. package/dist/exports/migration-ts.mjs.map +1 -1
  33. package/dist/exports/migration.d.mts +15 -14
  34. package/dist/exports/migration.d.mts.map +1 -1
  35. package/dist/exports/migration.mjs +70 -43
  36. package/dist/exports/migration.mjs.map +1 -1
  37. package/dist/exports/package.d.mts +3 -0
  38. package/dist/exports/package.mjs +1 -0
  39. package/dist/exports/refs.d.mts.map +1 -1
  40. package/dist/exports/refs.mjs +3 -4
  41. package/dist/exports/refs.mjs.map +1 -1
  42. package/dist/exports/spaces.d.mts +550 -0
  43. package/dist/exports/spaces.d.mts.map +1 -0
  44. package/dist/exports/spaces.mjs +223 -0
  45. package/dist/exports/spaces.mjs.map +1 -0
  46. package/dist/graph-HMWAldoR.d.mts +28 -0
  47. package/dist/graph-HMWAldoR.d.mts.map +1 -0
  48. package/dist/hash-By50zM_E.mjs +74 -0
  49. package/dist/hash-By50zM_E.mjs.map +1 -0
  50. package/dist/invariants-Duc8f9NM.mjs +52 -0
  51. package/dist/invariants-Duc8f9NM.mjs.map +1 -0
  52. package/dist/io-D13dLvUh.mjs +239 -0
  53. package/dist/io-D13dLvUh.mjs.map +1 -0
  54. package/dist/metadata-CFvm3ayn.d.mts +2 -0
  55. package/dist/migration-graph-DGNnKDY5.mjs +523 -0
  56. package/dist/migration-graph-DGNnKDY5.mjs.map +1 -0
  57. package/dist/migration-graph-DulOITvG.d.mts +124 -0
  58. package/dist/migration-graph-DulOITvG.d.mts.map +1 -0
  59. package/dist/op-schema-D5qkXfEf.mjs +13 -0
  60. package/dist/op-schema-D5qkXfEf.mjs.map +1 -0
  61. package/dist/package-BjiZ7KDy.d.mts +21 -0
  62. package/dist/package-BjiZ7KDy.d.mts.map +1 -0
  63. package/dist/read-contract-space-contract-C3-1eyaI.mjs +298 -0
  64. package/dist/read-contract-space-contract-C3-1eyaI.mjs.map +1 -0
  65. package/package.json +44 -19
  66. package/src/aggregate/loader.ts +409 -0
  67. package/src/aggregate/marker-types.ts +16 -0
  68. package/src/aggregate/planner-types.ts +171 -0
  69. package/src/aggregate/planner.ts +158 -0
  70. package/src/aggregate/project-schema-to-space.ts +64 -0
  71. package/src/aggregate/strategies/graph-walk.ts +118 -0
  72. package/src/aggregate/strategies/synth.ts +122 -0
  73. package/src/aggregate/types.ts +89 -0
  74. package/src/aggregate/verifier.ts +230 -0
  75. package/src/assert-descriptor-self-consistency.ts +70 -0
  76. package/src/compute-extension-space-apply-path.ts +152 -0
  77. package/src/concatenate-space-apply-inputs.ts +90 -0
  78. package/src/detect-space-contract-drift.ts +91 -0
  79. package/src/emit-contract-space-artefacts.ts +70 -0
  80. package/src/errors.ts +251 -17
  81. package/src/exports/aggregate.ts +42 -0
  82. package/src/exports/errors.ts +8 -0
  83. package/src/exports/graph.ts +1 -0
  84. package/src/exports/hash.ts +2 -0
  85. package/src/exports/invariants.ts +1 -0
  86. package/src/exports/io.ts +3 -1
  87. package/src/exports/metadata.ts +1 -0
  88. package/src/exports/{dag.ts → migration-graph.ts} +3 -2
  89. package/src/exports/migration.ts +0 -1
  90. package/src/exports/package.ts +2 -0
  91. package/src/exports/spaces.ts +49 -0
  92. package/src/gather-disk-contract-space-state.ts +62 -0
  93. package/src/graph-ops.ts +57 -30
  94. package/src/graph.ts +25 -0
  95. package/src/hash.ts +91 -0
  96. package/src/invariants.ts +56 -0
  97. package/src/io.ts +163 -40
  98. package/src/metadata.ts +1 -0
  99. package/src/migration-base.ts +97 -56
  100. package/src/migration-graph.ts +676 -0
  101. package/src/op-schema.ts +11 -0
  102. package/src/package.ts +21 -0
  103. package/src/plan-all-spaces.ts +76 -0
  104. package/src/read-contract-space-contract.ts +44 -0
  105. package/src/read-contract-space-head-ref.ts +63 -0
  106. package/src/space-layout.ts +48 -0
  107. package/src/verify-contract-spaces.ts +272 -0
  108. package/dist/attestation-BnzTb0Qp.mjs +0 -65
  109. package/dist/attestation-BnzTb0Qp.mjs.map +0 -1
  110. package/dist/errors-BmiSgz1j.mjs +0 -160
  111. package/dist/errors-BmiSgz1j.mjs.map +0 -1
  112. package/dist/exports/attestation.d.mts +0 -37
  113. package/dist/exports/attestation.d.mts.map +0 -1
  114. package/dist/exports/attestation.mjs +0 -4
  115. package/dist/exports/dag.d.mts +0 -51
  116. package/dist/exports/dag.d.mts.map +0 -1
  117. package/dist/exports/dag.mjs +0 -386
  118. package/dist/exports/dag.mjs.map +0 -1
  119. package/dist/exports/types.d.mts +0 -35
  120. package/dist/exports/types.d.mts.map +0 -1
  121. package/dist/exports/types.mjs +0 -3
  122. package/dist/io-Cd6GLyjK.mjs +0 -153
  123. package/dist/io-Cd6GLyjK.mjs.map +0 -1
  124. package/dist/types-DyGXcWWp.d.mts +0 -71
  125. package/dist/types-DyGXcWWp.d.mts.map +0 -1
  126. package/src/attestation.ts +0 -81
  127. package/src/dag.ts +0 -426
  128. package/src/exports/attestation.ts +0 -2
  129. package/src/exports/types.ts +0 -10
  130. package/src/types.ts +0 -66
@@ -0,0 +1,614 @@
1
+ import { n as OnDiskMigrationPackage } from "../package-BjiZ7KDy.mjs";
2
+ import { n as MigrationGraph } from "../graph-HMWAldoR.mjs";
3
+ import { t as PathDecision } from "../migration-graph-DulOITvG.mjs";
4
+ import { ControlFamilyInstance, MigrationOperationPolicy, MigrationPlan, MigrationPlanOperation, MigrationPlannerConflict, TargetMigrationsCapability } from "@prisma-next/framework-components/control";
5
+ import { Result } from "@prisma-next/utils/result";
6
+ import { Contract } from "@prisma-next/contract/types";
7
+ import { TargetBoundComponentDescriptor } from "@prisma-next/framework-components/components";
8
+
9
+ //#region src/aggregate/types.d.ts
10
+ /**
11
+ * Hydrated migration graph for a single contract space.
12
+ *
13
+ * `graph` is the structural shortest-path graph (forward / reverse chain,
14
+ * deterministic tie-break order) reconstructed from a set of on-disk
15
+ * migration packages. `packagesByMigrationHash` is the lookup table the
16
+ * graph-walk strategy uses to resolve a path's edge sequence back to the
17
+ * concrete `OnDiskMigrationPackage` (and therefore the operation list) for
18
+ * apply.
19
+ *
20
+ * Eagerly hydrated by the loader. Once a `ContractSpaceAggregate` exists,
21
+ * downstream consumers do **not** touch the filesystem to walk graphs or
22
+ * resolve packages — the aggregate is the boundary.
23
+ */
24
+ interface HydratedMigrationGraph {
25
+ readonly graph: MigrationGraph;
26
+ readonly packagesByMigrationHash: ReadonlyMap<string, OnDiskMigrationPackage>;
27
+ }
28
+ /**
29
+ * One contract space — app or extension — as a member of a
30
+ * {@link ContractSpaceAggregate}. Every member has the same shape.
31
+ *
32
+ * - `spaceId`: `'app'` for the application, otherwise the extension's
33
+ * id (validated against `[a-z][a-z0-9_-]{0,63}`).
34
+ * - `contract`: the validated contract value for this member. For the
35
+ * app, the user's authored contract; for an extension, the on-disk
36
+ * `migrations/<spaceId>/contract.json`. Both have already passed the
37
+ * family's `validateContract` at the loader boundary.
38
+ * - `headRef.hash`: the storage hash this member is targeting. For the
39
+ * app, equals `contract.storage.storageHash`. For extensions, the
40
+ * on-disk `refs/head.json.hash`.
41
+ * - `headRef.invariants`: alphabetically sorted, deduplicated invariant
42
+ * ids declared on the head ref. Empty for the app member (the app's
43
+ * plan is synthesised from the contract IR, no invariants required).
44
+ * - `migrations`: the hydrated migration graph for this space. Possibly
45
+ * empty (an extension whose on-disk head ref points at the
46
+ * empty-contract sentinel and ships no migrations yet, or the app
47
+ * when the user hasn't authored any).
48
+ */
49
+ interface ContractSpaceMember {
50
+ readonly spaceId: string;
51
+ readonly contract: Contract;
52
+ readonly headRef: {
53
+ readonly hash: string;
54
+ readonly invariants: readonly string[];
55
+ };
56
+ readonly migrations: HydratedMigrationGraph;
57
+ }
58
+ /**
59
+ * Typed value carrying the user's app contract plus every loaded
60
+ * extension contract space, fully hydrated and internally consistent.
61
+ *
62
+ * Produced once per CLI invocation by `loadContractSpaceAggregate`.
63
+ * Every downstream component (planner, verifier, runner adapter)
64
+ * consumes this value rather than rebuilding state from disk.
65
+ *
66
+ * Invariants the loader enforces at construction:
67
+ *
68
+ * 1. `targetId` is consistent across every member (`contract.target`
69
+ * matches `aggregate.targetId`). The aggregate's `targetId` is the
70
+ * `Config.adapter.targetId` value the loader was told to use.
71
+ * 2. `aggregate.extensions` is sorted alphabetically by `spaceId`.
72
+ * Mirrors {@link import('../concatenate-space-apply-inputs').concatenateSpaceApplyInputs}'s
73
+ * extension ordering convention so downstream apply order matches
74
+ * today's behaviour byte-for-byte.
75
+ * 3. No two members claim the same storage element (table / type / etc.).
76
+ * 4. For each extension member: `member.headRef.hash` is reachable from
77
+ * the empty-contract sentinel in `member.migrations.graph` (or the
78
+ * graph is empty and `member.headRef.hash === EMPTY_CONTRACT_HASH`).
79
+ * 5. For the app member: `member.headRef.hash` equals
80
+ * `member.contract.storage.storageHash`. The app's `migrations`
81
+ * is hydrated from the user's authored `migrations/` (or empty if
82
+ * none).
83
+ *
84
+ * The aggregate is **type-uniform** post-construction: app/extension
85
+ * distinguishability survives only at the caller-policy layer
86
+ * (`ignoreGraphFor: new Set([appSpaceId])`), not on member shape.
87
+ */
88
+ interface ContractSpaceAggregate {
89
+ readonly targetId: string;
90
+ readonly app: ContractSpaceMember;
91
+ readonly extensions: readonly ContractSpaceMember[];
92
+ }
93
+ //#endregion
94
+ //#region src/aggregate/loader.d.ts
95
+ /**
96
+ * Hash function used by drift detection. Defaults to a canonical-JSON +
97
+ * SHA-256 pipeline that mirrors the framework's contract-hash convention,
98
+ * but the loader accepts a callback so SQL-family callers can pass their
99
+ * `coreHash` / `storageHash` derivation through unchanged.
100
+ *
101
+ * The contract value passed in is the framework-neutral `unknown` form;
102
+ * callers that have already validated typed contracts can simply hand
103
+ * the validated value back through.
104
+ */
105
+ type AggregateContractHasher = (contract: unknown) => string;
106
+ /**
107
+ * Single declared extension entry the loader needs from `Config.extensionPacks`.
108
+ *
109
+ * Only the subset of fields the loader operates on:
110
+ *
111
+ * - `id` — the space id (also the directory name under `migrations/`).
112
+ * - `targetId` — the configured `Config.adapter.targetId` value the
113
+ * declaring extension declared. The loader rejects mismatches against
114
+ * the aggregate's `targetId` with `targetMismatch`.
115
+ * - `contractSpace` — present iff the descriptor declares a contract
116
+ * space (extensions can ship without one and remain runtime-only /
117
+ * codec-only). Drift detection compares the descriptor's
118
+ * `contractJson` hash against the on-disk on-disk head hash; the loader
119
+ * rejects drift fatally.
120
+ *
121
+ * Typed structurally so the migration-tools layer stays framework-neutral.
122
+ */
123
+ interface DeclaredExtensionEntry {
124
+ readonly id: string;
125
+ readonly targetId: string;
126
+ readonly contractSpace?: {
127
+ readonly contractJson: unknown;
128
+ };
129
+ }
130
+ /**
131
+ * Inputs for {@link loadContractSpaceAggregate}.
132
+ *
133
+ * The loader is the **sole** descriptor-import boundary in the M2.5
134
+ * pipeline: callers gather the descriptor data (already-validated app
135
+ * contract, declared extension entries) and pass it through. Once the
136
+ * loader returns, no descriptor module is imported again for this
137
+ * aggregate's lifetime.
138
+ */
139
+ interface LoadAggregateInput {
140
+ readonly targetId: string;
141
+ readonly migrationsDir: string;
142
+ readonly appContract: Contract;
143
+ readonly declaredExtensions: ReadonlyArray<DeclaredExtensionEntry>;
144
+ readonly validateContract: (contractJson: unknown) => Contract;
145
+ readonly hashContract: AggregateContractHasher;
146
+ /**
147
+ * Hydrated migration graph for the **app member**.
148
+ *
149
+ * The framework-neutral migration-tools layer doesn't know how to read
150
+ * the user's authored `migrations/` directory (the app member's
151
+ * migration-package layout is family-aware: ops.json shape, manifest
152
+ * keys, etc.). Callers — the SQL family today — read the user's
153
+ * `migrations/` and hand the resulting `OnDiskMigrationPackage[]` through.
154
+ *
155
+ * Passing `[]` is valid (greenfield project, no authored migrations).
156
+ * Equivalent to `migrations/` not existing or being empty.
157
+ */
158
+ readonly appMigrationPackages: ReadonlyArray<OnDiskMigrationPackage>;
159
+ }
160
+ /**
161
+ * Discriminated failure variants the loader emits.
162
+ *
163
+ * Every variant short-circuits at first hit; the loader does not keep
164
+ * collecting after the first violation in any phase except for layout
165
+ * (where every layout offence is bundled into one `layoutViolation`).
166
+ */
167
+ type LoadAggregateError = {
168
+ readonly kind: 'layoutViolation';
169
+ readonly violations: readonly LayoutViolation[];
170
+ } | {
171
+ readonly kind: 'integrityFailure';
172
+ readonly spaceId: string;
173
+ readonly detail: string;
174
+ } | {
175
+ readonly kind: 'validationFailure';
176
+ readonly spaceId: string;
177
+ readonly detail: string;
178
+ } | {
179
+ readonly kind: 'driftViolation';
180
+ readonly spaceId: string;
181
+ readonly priorHeadHash: string;
182
+ readonly liveHash: string;
183
+ } | {
184
+ readonly kind: 'disjointnessViolation';
185
+ readonly element: string;
186
+ readonly claimedBy: readonly string[];
187
+ } | {
188
+ readonly kind: 'targetMismatch';
189
+ readonly spaceId: string;
190
+ readonly expected: string;
191
+ readonly actual: string;
192
+ };
193
+ /**
194
+ * Single layout violation; bundled into a `layoutViolation` error so
195
+ * users see every layout offence at once rather than fixing them one
196
+ * at a time across re-runs.
197
+ *
198
+ * - `declaredButUnmigrated`: extension declared in `extensionPacks` with
199
+ * a `contractSpace` but no contract-space dir on disk. Remediation:
200
+ * `prisma-next migrate`.
201
+ * - `orphanSpaceDir`: contract-space dir under `migrations/` for an extension
202
+ * not in `extensionPacks`. Remediation: remove the directory, or
203
+ * re-add the extension to `extensionPacks`.
204
+ */
205
+ type LayoutViolation = {
206
+ readonly kind: 'declaredButUnmigrated';
207
+ readonly spaceId: string;
208
+ } | {
209
+ readonly kind: 'orphanSpaceDir';
210
+ readonly spaceId: string;
211
+ };
212
+ type LoadAggregateOutput = Result<{
213
+ readonly aggregate: ContractSpaceAggregate;
214
+ }, LoadAggregateError>;
215
+ /**
216
+ * Hydrate a {@link ContractSpaceAggregate} from on-disk state and
217
+ * caller-provided descriptor data.
218
+ *
219
+ * This is the **only** descriptor-import boundary in the post-M2.5
220
+ * pipeline: callers read `extensionPacks` from `Config`, validate the
221
+ * app contract, and pass everything through. The loader composes
222
+ * existing migration-tools primitives — layout precheck (via
223
+ * {@link listContractSpaceDirectories}), integrity checks (via
224
+ * {@link readMigrationsDir} / {@link readContractSpaceHeadRef} /
225
+ * {@link readContractSpaceContract} / `validateContract`), drift detection
226
+ * (via {@link detectSpaceContractDrift}), and disjointness — into a
227
+ * single typed value.
228
+ *
229
+ * Failure semantics: every failure variant in {@link LoadAggregateError}
230
+ * short-circuits the load. Drift is fatal (M2.5 spec § Loader, step 5).
231
+ */
232
+ declare function loadContractSpaceAggregate(input: LoadAggregateInput): Promise<LoadAggregateOutput>;
233
+ //#endregion
234
+ //#region src/aggregate/marker-types.d.ts
235
+ /**
236
+ * Structural shape the aggregate planner / verifier accept for marker
237
+ * rows. Mirrors `family.readAllMarkers(...)` outputs across SQL and
238
+ * Mongo families: a `(storageHash, invariants)` pair plus an optional
239
+ * `profileHash` the verifier uses to align the marker with the
240
+ * destination contract's profile envelope.
241
+ *
242
+ * Typed structurally so `migration-tools` stays framework-neutral; SQL
243
+ * and Mongo families pass their typed `ContractMarkerRecord` through
244
+ * unchanged.
245
+ */
246
+ interface ContractMarkerRecordLike {
247
+ readonly storageHash: string;
248
+ readonly invariants: readonly string[];
249
+ readonly profileHash?: string;
250
+ }
251
+ //#endregion
252
+ //#region src/aggregate/planner-types.d.ts
253
+ /**
254
+ * Caller-provided policy for {@link planAggregate}. Today this carries
255
+ * just one knob:
256
+ *
257
+ * - `ignoreGraphFor`: `Set<spaceId>`. For listed members, the planner
258
+ * forces the **synth** strategy (synthesise a plan from the contract
259
+ * IR via `familyInstance.createPlanner(...).plan(...)`) regardless of
260
+ * whether a graph is available. The CLI's daily-driver `db init` /
261
+ * `db update` pipelines pass `new Set([aggregate.app.spaceId])` to
262
+ * keep today's app-space behaviour: the user's authored
263
+ * `migrations/` directory is **not** walked for the app member, the
264
+ * plan is synthesised on the fly. Extension members are walked.
265
+ *
266
+ * Listing a member here whose `headRef.invariants` is non-empty is
267
+ * a `policyConflict` — synth cannot satisfy authored invariants.
268
+ */
269
+ interface CallerPolicy {
270
+ readonly ignoreGraphFor: ReadonlySet<string>;
271
+ }
272
+ /**
273
+ * Snapshot of the live database state the planner needs to drive
274
+ * strategy selection.
275
+ *
276
+ * - `markersBySpaceId`: per-space marker rows. Absent entry = no
277
+ * marker yet (greenfield space). The planner treats the marker's
278
+ * `storageHash` as the graph-walk's `from` node, falling back to
279
+ * {@link import('../constants').EMPTY_CONTRACT_HASH} when absent.
280
+ * - `schemaIntrospection`: the family's full live schema IR. Fed into
281
+ * the synth strategy after per-space pre-projection via
282
+ * {@link import('./project-schema-to-space').projectSchemaToSpace}.
283
+ *
284
+ * Callers (CLI commands) gather this via the family's
285
+ * `readAllMarkers` + `introspect` calls before invoking the planner.
286
+ * The planner itself does not touch the database.
287
+ */
288
+ interface AggregateCurrentDBState {
289
+ readonly markersBySpaceId: ReadonlyMap<string, ContractMarkerRecordLike | null>;
290
+ readonly schemaIntrospection: unknown;
291
+ }
292
+ /**
293
+ * Inputs to {@link planAggregate}.
294
+ *
295
+ * The planner is target-agnostic but family-aware: per-member synth
296
+ * delegates to the family's `createPlanner(familyInstance).plan(...)`,
297
+ * which is why `familyInstance`, `migrations` (the
298
+ * `TargetMigrationsCapability`), and `frameworkComponents` are all
299
+ * threaded through. (`frameworkComponents` is passed verbatim into
300
+ * `planner.plan(...)` per ADR 212; the planner does not interpret it.)
301
+ *
302
+ * The aggregate planner does **not** receive a `targetId` separately —
303
+ * it reads `aggregate.targetId` and stamps it onto every emitted
304
+ * `MigrationPlan` from construction. No placeholder, no patch step.
305
+ */
306
+ interface AggregatePlannerInput<TFamilyId extends string, TTargetId extends string> {
307
+ readonly aggregate: ContractSpaceAggregate;
308
+ readonly currentDBState: AggregateCurrentDBState;
309
+ readonly familyInstance: ControlFamilyInstance<TFamilyId, unknown>;
310
+ readonly migrations: TargetMigrationsCapability<TFamilyId, TTargetId, ControlFamilyInstance<TFamilyId, unknown>>;
311
+ readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>>;
312
+ readonly callerPolicy: CallerPolicy;
313
+ readonly operationPolicy: MigrationOperationPolicy;
314
+ }
315
+ /**
316
+ * Per-member output of the aggregate planner. The runner ingests this
317
+ * shape directly via a thin `toRunnerInput` adapter at the CLI.
318
+ *
319
+ * - `plan`: ready-to-execute `MigrationPlan` with `targetId` already
320
+ * set from `aggregate.targetId`.
321
+ * - `displayOps`: same operation list, surfaced separately so plan-mode
322
+ * output can render without touching the runner-bound `plan`.
323
+ * - `destinationContract`: the typed contract value the runner uses
324
+ * for post-apply verification. For the app member, the user's
325
+ * contract; for extension members, the on-disk `contract.json`.
326
+ * - `strategy`: which strategy produced this plan (`'graph-walk'` or
327
+ * `'synth'`). Surfaced for diagnostics; not consumed by the runner.
328
+ */
329
+ /**
330
+ * Per-edge metadata for the chain assembled by the graph-walk
331
+ * strategy. Lets `migration apply` surface a per-migration `applied[]`
332
+ * entry (preserving the single-space `migrationsApplied` count
333
+ * semantics) without re-walking the graph.
334
+ *
335
+ * `synth`-produced plans leave this absent — synthesised plans don't
336
+ * have authored edges to surface.
337
+ */
338
+ interface AggregateMigrationEdgeRef {
339
+ readonly migrationHash: string;
340
+ readonly dirName: string;
341
+ readonly from: string;
342
+ readonly to: string;
343
+ readonly operationCount: number;
344
+ }
345
+ interface AggregatePerSpacePlan {
346
+ readonly plan: MigrationPlan;
347
+ readonly displayOps: readonly MigrationPlanOperation[];
348
+ readonly destinationContract: Contract;
349
+ readonly strategy: 'graph-walk' | 'synth';
350
+ /**
351
+ * Per-edge breakdown of the chain. Populated by the graph-walk
352
+ * strategy; absent for synth-produced plans.
353
+ */
354
+ readonly migrationEdges?: readonly AggregateMigrationEdgeRef[];
355
+ /**
356
+ * Path decision data the strategy used to select the chain
357
+ * (alternative count, tie-break reasons, required/satisfied
358
+ * invariants, per-edge invariants). Populated by the graph-walk
359
+ * strategy; absent for synth-produced plans.
360
+ *
361
+ * `migration apply` surfaces this for the app member as
362
+ * `MigrationApplySuccess.pathDecision` (back-compat with single-
363
+ * space callers).
364
+ */
365
+ readonly pathDecision?: PathDecision;
366
+ }
367
+ interface AggregatePlannerSuccess {
368
+ readonly perSpace: ReadonlyMap<string, AggregatePerSpacePlan>;
369
+ /**
370
+ * `applyOrder` is the order the runner must walk per-space inputs.
371
+ * Mirrors the existing `concatenateSpaceApplyInputs` convention:
372
+ * extensions alphabetically by `spaceId`, then the app. Tests assert
373
+ * on `MultiSpaceRunnerFailure.failingSpace`, which is positional in
374
+ * the runner's input array — preserving the literal ordering keeps
375
+ * `failingSpace` attribution byte-for-byte.
376
+ */
377
+ readonly applyOrder: readonly string[];
378
+ }
379
+ /**
380
+ * Discriminated failure variants for {@link planAggregate}. Each
381
+ * variant short-circuits the plan; per-member errors carry the
382
+ * `spaceId` so the CLI can surface a precise envelope.
383
+ */
384
+ type AggregatePlannerError = {
385
+ readonly kind: 'extensionPathUnreachable';
386
+ readonly spaceId: string;
387
+ readonly target: string;
388
+ } | {
389
+ readonly kind: 'extensionPathUnsatisfiable';
390
+ readonly spaceId: string;
391
+ readonly missingInvariants: readonly string[];
392
+ } | {
393
+ readonly kind: 'appSynthFailure';
394
+ readonly spaceId: string;
395
+ readonly conflicts: readonly MigrationPlannerConflict[];
396
+ } | {
397
+ readonly kind: 'policyConflict';
398
+ readonly spaceId: string;
399
+ readonly detail: string;
400
+ };
401
+ type AggregatePlannerOutput = Result<AggregatePlannerSuccess, AggregatePlannerError>;
402
+ //#endregion
403
+ //#region src/aggregate/planner.d.ts
404
+ /**
405
+ * Plan a migration across every member of a {@link ContractSpaceAggregate}.
406
+ *
407
+ * Strategy selection per member, in order; first match wins:
408
+ *
409
+ * 1. If `callerPolicy.ignoreGraphFor.has(member.spaceId)`:
410
+ * - If `member.headRef.invariants` is empty → synth.
411
+ * - Else → `policyConflict` (synth cannot satisfy authored invariants).
412
+ * 2. Else if `member.migrations.graph` is non-empty AND graph-walk
413
+ * succeeds → graph-walk.
414
+ * 3. Else if `member.headRef.invariants` is empty → synth.
415
+ * 4. Else → graph-walk failure → `extensionPathUnreachable` /
416
+ * `extensionPathUnsatisfiable`.
417
+ *
418
+ * Output `applyOrder` is `[...aggregate.extensions.map(spaceId), aggregate.app.spaceId]`
419
+ * — extensions alphabetical, then app — matching today's
420
+ * `concatenateSpaceApplyInputs` ordering. This preserves
421
+ * `MultiSpaceRunnerFailure.failingSpace` attribution byte-for-byte.
422
+ *
423
+ * Every emitted `MigrationPlan` has `targetId = aggregate.targetId`.
424
+ * No placeholder cast; no patch step.
425
+ */
426
+ declare function planAggregate<TFamilyId extends string, TTargetId extends string>(input: AggregatePlannerInput<TFamilyId, TTargetId>): Promise<AggregatePlannerOutput>;
427
+ //#endregion
428
+ //#region src/aggregate/project-schema-to-space.d.ts
429
+ /**
430
+ * Project the introspected live schema to the slice claimed by a single
431
+ * contract-space member.
432
+ *
433
+ * Returns the same `schema` value with every top-level table claimed by
434
+ * **other** members of the aggregate removed. Tables not claimed by any
435
+ * member flow through unchanged — the planner / verifier sees them as
436
+ * orphans (extras in strict mode).
437
+ *
438
+ * Used by:
439
+ *
440
+ * - The aggregate planner's **synth strategy**: when synthesising a
441
+ * plan against a member's contract, the live schema must be projected
442
+ * to that member's slice so the planner doesn't treat tables claimed
443
+ * by other members as "extras" and emit destructive ops to drop
444
+ * them.
445
+ * - The aggregate verifier's **schemaCheck**: projects per member so the
446
+ * single-contract `verifySqlSchema` only sees the slice claimed by
447
+ * the member it is checking. Closes the F23 architectural concern
448
+ * (multi-member deployments where each member's tables look like
449
+ * extras to every other member's verify pass).
450
+ *
451
+ * **Duck-typing semantics**: the helper operates on `unknown` for the
452
+ * schema and falls through structurally if the shape doesn't match.
453
+ * Every family today exposes `storage.tables: Record<string, ...>` and
454
+ * the introspected schema mirrors the same shape; a future family with
455
+ * a different storage shape gets the schema returned unchanged rather
456
+ * than blowing up the aggregate planner.
457
+ */
458
+ declare function projectSchemaToSpace(schema: unknown, member: ContractSpaceMember, otherMembers: ReadonlyArray<ContractSpaceMember>): unknown;
459
+ //#endregion
460
+ //#region src/aggregate/strategies/graph-walk.d.ts
461
+ /**
462
+ * Outcome variants for the graph-walk strategy. Mirrors
463
+ * {@link import('../../compute-extension-space-apply-path').ExtensionSpaceApplyPathOutcome}
464
+ * but operates against the **already-hydrated** `member.migrations.graph`
465
+ * instead of re-reading from disk. The aggregate planner converts
466
+ * these into {@link import('../planner-types').AggregatePlannerError}
467
+ * variants.
468
+ */
469
+ type GraphWalkOutcome = {
470
+ readonly kind: 'ok';
471
+ readonly result: AggregatePerSpacePlan;
472
+ } | {
473
+ readonly kind: 'unreachable';
474
+ } | {
475
+ readonly kind: 'unsatisfiable';
476
+ readonly missing: readonly string[];
477
+ };
478
+ interface GraphWalkStrategyInputs {
479
+ readonly aggregateTargetId: string;
480
+ readonly member: ContractSpaceMember;
481
+ readonly currentMarker: ContractMarkerRecordLike | null;
482
+ /**
483
+ * Optional ref name to decorate the resulting `PathDecision`. Used by
484
+ * `migration apply` to surface the user-supplied `--ref <name>` in
485
+ * structured-progress events and invariant-path error envelopes. The
486
+ * strategy itself does not interpret it.
487
+ */
488
+ readonly refName?: string;
489
+ }
490
+ /**
491
+ * Walk a member's hydrated migration graph from the live marker to
492
+ * `member.headRef.hash`, covering every required invariant.
493
+ *
494
+ * Pure synchronous function — no I/O. The aggregate's loader has
495
+ * already integrity-checked every package and reconstructed the graph;
496
+ * this strategy just looks up ops by `migrationHash` and assembles a
497
+ * `MigrationPlan` with `targetId` set from the aggregate (no
498
+ * placeholder cast).
499
+ *
500
+ * Required invariants are computed as `headRef.invariants \ marker.invariants`
501
+ * — the marker already declares some invariants satisfied; the path
502
+ * only needs to provide the remainder. Mirrors today's
503
+ * `computeExtensionSpaceApplyPath` semantics.
504
+ */
505
+ declare function graphWalkStrategy(input: GraphWalkStrategyInputs): GraphWalkOutcome;
506
+ //#endregion
507
+ //#region src/aggregate/verifier.d.ts
508
+ /**
509
+ * Caller policy for the aggregate verifier. Today's only knob is
510
+ * `mode`: `strict` treats orphan elements (live tables not claimed by
511
+ * any aggregate member) as errors; `lenient` treats them as
512
+ * informational. Maps directly to `db verify --strict`.
513
+ */
514
+ interface AggregateVerifierInput<TSchemaResult> {
515
+ readonly aggregate: ContractSpaceAggregate;
516
+ readonly markersBySpaceId: ReadonlyMap<string, ContractMarkerRecordLike | null>;
517
+ readonly schemaIntrospection: unknown;
518
+ readonly mode: 'strict' | 'lenient';
519
+ /**
520
+ * Caller-supplied per-space schema verifier. The CLI wires this to
521
+ * the family's `verifySqlSchema` (SQL) / equivalent (other
522
+ * families). The aggregate verifier projects the schema to the
523
+ * member's slice via {@link projectSchemaToSpace} before invoking
524
+ * the callback, so single-contract semantics are preserved.
525
+ *
526
+ * Typed structurally with a generic `TSchemaResult` so the
527
+ * migration-tools layer doesn't depend on the SQL family's
528
+ * `VerifySqlSchemaResult`. CLI callers pass the family's type
529
+ * through unchanged.
530
+ */
531
+ readonly verifySchemaForMember: (projectedSchema: unknown, member: ContractSpaceMember, mode: 'strict' | 'lenient') => TSchemaResult;
532
+ }
533
+ /**
534
+ * Marker-check result per member. Mirrors the four cases the
535
+ * `verifyContractSpaces` primitive surfaces today, plus an `'absent'`
536
+ * case for greenfield spaces (no marker row written yet — `db init`
537
+ * not run).
538
+ */
539
+ type MarkerCheckResult = {
540
+ readonly kind: 'ok';
541
+ } | {
542
+ readonly kind: 'absent';
543
+ } | {
544
+ readonly kind: 'hashMismatch';
545
+ readonly markerHash: string;
546
+ readonly expected: string;
547
+ } | {
548
+ readonly kind: 'missingInvariants';
549
+ readonly missing: readonly string[];
550
+ };
551
+ interface MarkerCheckSection {
552
+ readonly perSpace: ReadonlyMap<string, MarkerCheckResult>;
553
+ readonly orphanMarkers: readonly {
554
+ readonly spaceId: string;
555
+ readonly row: ContractMarkerRecordLike;
556
+ }[];
557
+ }
558
+ /**
559
+ * A live storage element (today: a top-level table) not claimed by any
560
+ * member of the aggregate. The aggregate verifier always reports these;
561
+ * the caller decides what to do — `db verify --strict` treats them as
562
+ * errors, the lenient default treats them as informational.
563
+ *
564
+ * Today only `kind: 'table'` exists. The discriminated shape leaves
565
+ * room for orphan columns / indexes / sequences in the future without
566
+ * breaking the type contract.
567
+ */
568
+ type OrphanElement = {
569
+ readonly kind: 'table';
570
+ readonly name: string;
571
+ };
572
+ interface SchemaCheckSection<TSchemaResult> {
573
+ readonly perSpace: ReadonlyMap<string, TSchemaResult>;
574
+ /**
575
+ * Live elements present in the introspected schema that are not
576
+ * claimed by **any** aggregate member. Sorted alphabetically by name.
577
+ */
578
+ readonly orphanElements: readonly OrphanElement[];
579
+ }
580
+ interface AggregateVerifierSuccess<TSchemaResult> {
581
+ readonly markerCheck: MarkerCheckSection;
582
+ readonly schemaCheck: SchemaCheckSection<TSchemaResult>;
583
+ }
584
+ type AggregateVerifierError = {
585
+ readonly kind: 'introspectionFailure';
586
+ readonly detail: string;
587
+ };
588
+ type AggregateVerifierOutput<TSchemaResult> = Result<AggregateVerifierSuccess<TSchemaResult>, AggregateVerifierError>;
589
+ /**
590
+ * Verify a {@link ContractSpaceAggregate} against the live database
591
+ * state. Bundles two checks:
592
+ *
593
+ * - `markerCheck` per member: compare the live marker row against the
594
+ * member's `headRef.hash` + `headRef.invariants`. Absence is a
595
+ * distinct kind, not an error (callers — `db verify` strict vs
596
+ * `db init` precondition — choose how to interpret it).
597
+ * - `schemaCheck` per member: project the live schema to the slice
598
+ * the member claims via {@link projectSchemaToSpace}, then delegate
599
+ * to the caller-supplied `verifySchemaForMember`. The pre-projection
600
+ * means the family's single-contract verifier no longer sees other
601
+ * members' tables as `extras`, so a multi-member deployment never
602
+ * surfaces cross-member tables as orphaned schema elements.
603
+ *
604
+ * `markerCheck.orphanMarkers` lists every marker row whose `space` is
605
+ * not a member of the aggregate. `db verify` callers reject orphans;
606
+ * future tooling may not.
607
+ *
608
+ * Pure synchronous function; no I/O. The caller (CLI) gathers
609
+ * `markersBySpaceId` and `schemaIntrospection` ahead of the call.
610
+ */
611
+ declare function verifyAggregate<TSchemaResult>(input: AggregateVerifierInput<TSchemaResult>): AggregateVerifierOutput<TSchemaResult>;
612
+ //#endregion
613
+ export { type AggregateContractHasher, type AggregateCurrentDBState, type AggregatePerSpacePlan, type AggregatePlannerError, type AggregatePlannerInput, type AggregatePlannerOutput, type AggregatePlannerSuccess, type AggregateVerifierError, type AggregateVerifierInput, type AggregateVerifierOutput, type AggregateVerifierSuccess, type CallerPolicy, type ContractMarkerRecordLike, type ContractSpaceAggregate, type ContractSpaceMember, type DeclaredExtensionEntry, type GraphWalkOutcome, type GraphWalkStrategyInputs, type HydratedMigrationGraph, type LayoutViolation, type LoadAggregateError, type LoadAggregateInput, type LoadAggregateOutput, type MarkerCheckResult, type MarkerCheckSection, type OrphanElement, type SchemaCheckSection, graphWalkStrategy, loadContractSpaceAggregate, planAggregate, projectSchemaToSpace, verifyAggregate };
614
+ //# sourceMappingURL=aggregate.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aggregate.d.mts","names":[],"sources":["../../src/aggregate/types.ts","../../src/aggregate/loader.ts","../../src/aggregate/marker-types.ts","../../src/aggregate/planner-types.ts","../../src/aggregate/planner.ts","../../src/aggregate/project-schema-to-space.ts","../../src/aggregate/strategies/graph-walk.ts","../../src/aggregate/verifier.ts"],"mappings":";;;;;;;;;;;;;;;AAkBA;;;;;;;;UAAiB,sBAAA;EAAA,SACN,KAAA,EAAO,cAAA;EAAA,SACP,uBAAA,EAAyB,WAAA,SAAoB,sBAAA;AAAA;;;;AAwBxD;;;;;;;;;;;;;;AAwCA;;;;UAxCiB,mBAAA;EAAA,SACN,OAAA;EAAA,SACA,QAAA,EAAU,QAAA;EAAA,SACV,OAAA;IAAA,SACE,IAAA;IAAA,SACA,UAAA;EAAA;EAAA,SAEF,UAAA,EAAY,sBAAA;AAAA;;AC5BvB;;;;;AAmBA;;;;;;;;;;AAiBA;;;;;;;;;;;;;;UDyBiB,sBAAA;EAAA,SACN,QAAA;EAAA,SACA,GAAA,EAAK,mBAAA;EAAA,SACL,UAAA,WAAqB,mBAAA;AAAA;;;;;;;;AArEhC;;;;;KCKY,uBAAA,IAA2B,QAAA;;;;;;;;;;ADqBvC;;;;;;;;UCFiB,sBAAA;EAAA,SACN,EAAA;EAAA,SACA,QAAA;EAAA,SACA,aAAA;IAAA,SACE,YAAA;EAAA;AAAA;;;;;;;;;;UAaI,kBAAA;EAAA,SACN,QAAA;EAAA,SACA,aAAA;EAAA,SACA,WAAA,EAAa,QAAA;EAAA,SACb,kBAAA,EAAoB,aAAA,CAAc,sBAAA;EAAA,SAClC,gBAAA,GAAmB,YAAA,cAA0B,QAAA;EAAA,SAC7C,YAAA,EAAc,uBAAA;EA1Cc;;AAmBvC;;;;;;;;;;EAnBuC,SAuD5B,oBAAA,EAAsB,aAAA,CAAc,sBAAA;AAAA;;;;;;;;KAUnC,kBAAA;EAAA,SACG,IAAA;EAAA,SAAkC,UAAA,WAAqB,eAAA;AAAA;EAAA,SACvD,IAAA;EAAA,SAAmC,OAAA;EAAA,SAA0B,MAAA;AAAA;EAAA,SAC7D,IAAA;EAAA,SAAoC,OAAA;EAAA,SAA0B,MAAA;AAAA;EAAA,SAE9D,IAAA;EAAA,SACA,OAAA;EAAA,SACA,aAAA;EAAA,SACA,QAAA;AAAA;EAAA,SAGA,IAAA;EAAA,SACA,OAAA;EAAA,SACA,SAAA;AAAA;EAAA,SAGA,IAAA;EAAA,SACA,OAAA;EAAA,SACA,QAAA;EAAA,SACA,MAAA;AAAA;;;;;;;;;;;;;KAeH,eAAA;EAAA,SACG,IAAA;EAAA,SAAwC,OAAA;AAAA;EAAA,SACxC,IAAA;EAAA,SAAiC,OAAA;AAAA;AAAA,KAEpC,mBAAA,GAAsB,MAAA;EAAA,SACrB,SAAA,EAAW,sBAAA;AAAA,GACtB,kBAAA;;;;;;;;;AAFF;;;;;;;;;iBA8BsB,0BAAA,CACpB,KAAA,EAAO,kBAAA,GACN,OAAA,CAAQ,mBAAA;;;;;;;;;;;;AD5IX;;UEPiB,wBAAA;EAAA,SACN,WAAA;EAAA,SACA,UAAA;EAAA,SACA,WAAA;AAAA;;;;;AFIX;;;;;;;;;;;;;;UGaiB,YAAA;EAAA,SACN,cAAA,EAAgB,WAAA;AAAA;;;;;;;;;;;;;AHoD3B;;;;UGjCiB,uBAAA;EAAA,SACN,gBAAA,EAAkB,WAAA,SAAoB,wBAAA;EAAA,SACtC,mBAAA;AAAA;;;;;;;AF9BX;;;;;AAmBA;;;UE4BiB,qBAAA;EAAA,SACN,SAAA,EAAW,sBAAA;EAAA,SACX,cAAA,EAAgB,uBAAA;EAAA,SAChB,cAAA,EAAgB,qBAAA,CAAsB,SAAA;EAAA,SACtC,UAAA,EAAY,0BAAA,CACnB,SAAA,EACA,SAAA,EACA,qBAAA,CAAsB,SAAA;EAAA,SAEf,mBAAA,EAAqB,aAAA,CAAc,8BAAA,CAA+B,SAAA,EAAW,SAAA;EAAA,SAC7E,YAAA,EAAc,YAAA;EAAA,SACd,eAAA,EAAiB,wBAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;UA0BX,yBAAA;EAAA,SACN,aAAA;EAAA,SACA,OAAA;EAAA,SACA,IAAA;EAAA,SACA,EAAA;EAAA,SACA,cAAA;AAAA;AAAA,UAGM,qBAAA;EAAA,SACN,IAAA,EAAM,aAAA;EAAA,SACN,UAAA,WAAqB,sBAAA;EAAA,SACrB,mBAAA,EAAqB,QAAA;EAAA,SACrB,QAAA;EF7BuC;;;;EAAA,SEkCvC,cAAA,YAA0B,yBAAA;EF/BtB;;;;;;;;;;EAAA,SE0CJ,YAAA,GAAe,YAAA;AAAA;AAAA,UAGT,uBAAA;EAAA,SACN,QAAA,EAAU,WAAA,SAAoB,qBAAA;EFjBd;;;;;;;;EAAA,SE0BhB,UAAA;AAAA;;;;;;KAQC,qBAAA;EAAA,SACG,IAAA;EAAA,SAA2C,OAAA;EAAA,SAA0B,MAAA;AAAA;EAAA,SAErE,IAAA;EAAA,SACA,OAAA;EAAA,SACA,iBAAA;AAAA;EAAA,SAGA,IAAA;EAAA,SACA,OAAA;EAAA,SACA,SAAA,WAAoB,wBAAA;AAAA;EAAA,SAEpB,IAAA;EAAA,SAAiC,OAAA;EAAA,SAA0B,MAAA;AAAA;AAAA,KAE9D,sBAAA,GAAyB,MAAA,CAAO,uBAAA,EAAyB,qBAAA;;;;;;;;;;AHxJrE;;;;;;;;;;;;;;;iBIyBsB,aAAA,oDAAA,CACpB,KAAA,EAAO,qBAAA,CAAsB,SAAA,EAAW,SAAA,IACvC,OAAA,CAAQ,sBAAA;;;;;;;;;;;AJ3BX;;;;;;;;;;;;;;;AA0BA;;;;;;iBKbgB,oBAAA,CACd,MAAA,WACA,MAAA,EAAQ,mBAAA,EACR,YAAA,EAAc,aAAA,CAAc,mBAAA;;;;;;;;;ALhB9B;;KMDY,gBAAA;EAAA,SACG,IAAA;EAAA,SAAqB,MAAA,EAAQ,qBAAA;AAAA;EAAA,SAC7B,IAAA;AAAA;EAAA,SACA,IAAA;EAAA,SAAgC,OAAA;AAAA;AAAA,UAE9B,uBAAA;EAAA,SACN,iBAAA;EAAA,SACA,MAAA,EAAQ,mBAAA;EAAA,SACR,aAAA,EAAe,wBAAA;ENmBT;;;;;;EAAA,SMZN,OAAA;AAAA;;;;;;;ANoDX;;;;;;;;;iBMlCgB,iBAAA,CAAkB,KAAA,EAAO,uBAAA,GAA0B,gBAAA;;;;;;;;;UCtClD,sBAAA;EAAA,SACN,SAAA,EAAW,sBAAA;EAAA,SACX,gBAAA,EAAkB,WAAA,SAAoB,wBAAA;EAAA,SACtC,mBAAA;EAAA,SACA,IAAA;EPIyB;;;;;;;;;;AAwBpC;;EAxBoC,SOSzB,qBAAA,GACP,eAAA,WACA,MAAA,EAAQ,mBAAA,EACR,IAAA,2BACG,aAAA;AAAA;;;;;;;KASK,iBAAA;EAAA,SACG,IAAA;AAAA;EAAA,SACA,IAAA;AAAA;EAAA,SAEA,IAAA;EAAA,SACA,UAAA;EAAA,SACA,QAAA;AAAA;EAAA,SAEA,IAAA;EAAA,SAAoC,OAAA;AAAA;AAAA,UAElC,kBAAA;EAAA,SACN,QAAA,EAAU,WAAA,SAAoB,iBAAA;EAAA,SAC9B,aAAA;IAAA,SACE,OAAA;IAAA,SACA,GAAA,EAAK,wBAAA;EAAA;AAAA;;;;;ANdlB;;;;;;KM4BY,aAAA;EAAA,SAA2B,IAAA;EAAA,SAAwB,IAAA;AAAA;AAAA,UAE9C,kBAAA;EAAA,SACN,QAAA,EAAU,WAAA,SAAoB,aAAA;;;;;WAK9B,cAAA,WAAyB,aAAA;AAAA;AAAA,UAGnB,wBAAA;EAAA,SACN,WAAA,EAAa,kBAAA;EAAA,SACb,WAAA,EAAa,kBAAA,CAAmB,aAAA;AAAA;AAAA,KAG/B,sBAAA;EAAA,SACD,IAAA;EAAA,SACA,MAAA;AAAA;AAAA,KAGC,uBAAA,kBAAyC,MAAA,CACnD,wBAAA,CAAyB,aAAA,GACzB,sBAAA;;;;;;;;;;;;;ANLF;;;;;;;;;;iBM8BgB,eAAA,eAAA,CACd,KAAA,EAAO,sBAAA,CAAuB,aAAA,IAC7B,uBAAA,CAAwB,aAAA"}