pocketbase-zod-schema 0.7.2 → 1.0.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 (67) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +198 -25
  3. package/dist/cli/index.cjs +3740 -1233
  4. package/dist/cli/index.cjs.map +1 -1
  5. package/dist/cli/index.js +3737 -1232
  6. package/dist/cli/index.js.map +1 -1
  7. package/dist/cli/migrate.cjs +3815 -1201
  8. package/dist/cli/migrate.cjs.map +1 -1
  9. package/dist/cli/migrate.js +3811 -1199
  10. package/dist/cli/migrate.js.map +1 -1
  11. package/dist/cli/utils/index.cjs +52 -13
  12. package/dist/cli/utils/index.cjs.map +1 -1
  13. package/dist/cli/utils/index.d.cts +46 -1
  14. package/dist/cli/utils/index.d.ts +46 -1
  15. package/dist/cli/utils/index.js +51 -13
  16. package/dist/cli/utils/index.js.map +1 -1
  17. package/dist/migration/analyzer.cjs +123 -42
  18. package/dist/migration/analyzer.cjs.map +1 -1
  19. package/dist/migration/analyzer.js +123 -42
  20. package/dist/migration/analyzer.js.map +1 -1
  21. package/dist/migration/diff.cjs +13 -0
  22. package/dist/migration/diff.cjs.map +1 -1
  23. package/dist/migration/diff.js +13 -0
  24. package/dist/migration/diff.js.map +1 -1
  25. package/dist/migration/engine.cjs +3263 -0
  26. package/dist/migration/engine.cjs.map +1 -0
  27. package/dist/migration/engine.d.cts +105 -0
  28. package/dist/migration/engine.d.ts +105 -0
  29. package/dist/migration/engine.js +3173 -0
  30. package/dist/migration/engine.js.map +1 -0
  31. package/dist/migration/generator.cjs +40 -18
  32. package/dist/migration/generator.cjs.map +1 -1
  33. package/dist/migration/generator.d.cts +45 -2
  34. package/dist/migration/generator.d.ts +45 -2
  35. package/dist/migration/generator.js +39 -19
  36. package/dist/migration/generator.js.map +1 -1
  37. package/dist/migration/index.cjs +3479 -1145
  38. package/dist/migration/index.cjs.map +1 -1
  39. package/dist/migration/index.d.cts +21 -4
  40. package/dist/migration/index.d.ts +21 -4
  41. package/dist/migration/index.js +3433 -1142
  42. package/dist/migration/index.js.map +1 -1
  43. package/dist/migration/snapshot.cjs +2200 -804
  44. package/dist/migration/snapshot.cjs.map +1 -1
  45. package/dist/migration/snapshot.d.cts +24 -66
  46. package/dist/migration/snapshot.d.ts +24 -66
  47. package/dist/migration/snapshot.js +2198 -801
  48. package/dist/migration/snapshot.js.map +1 -1
  49. package/dist/migration/utils/index.cjs +51 -9
  50. package/dist/migration/utils/index.cjs.map +1 -1
  51. package/dist/migration/utils/index.d.cts +1 -1
  52. package/dist/migration/utils/index.d.ts +1 -1
  53. package/dist/migration/utils/index.js +50 -10
  54. package/dist/migration/utils/index.js.map +1 -1
  55. package/dist/server.cjs +3837 -1248
  56. package/dist/server.cjs.map +1 -1
  57. package/dist/server.d.cts +6 -4
  58. package/dist/server.d.ts +6 -4
  59. package/dist/server.js +3791 -1245
  60. package/dist/server.js.map +1 -1
  61. package/dist/{type-mapper-Bu9qjCdd.d.cts → type-mapper-BSPTj8t5.d.cts} +23 -1
  62. package/dist/{type-mapper-JBaVuKE2.d.ts → type-mapper-D31WYDee.d.ts} +23 -1
  63. package/dist/types-B_MLb1Ob.d.ts +475 -0
  64. package/dist/types-upZBVMfb.d.cts +475 -0
  65. package/dist/verify-BF72n2df.d.ts +402 -0
  66. package/dist/verify-DTzYpiXX.d.cts +402 -0
  67. package/package.json +7 -1
@@ -0,0 +1,475 @@
1
+ import { a as SchemaSnapshot } from './types-CnzfX6JH.cjs';
2
+
3
+ /**
4
+ * `_migrations` table awareness
5
+ *
6
+ * PocketBase records every migration it has run in an internal `_migrations`
7
+ * table (`file` TEXT PRIMARY KEY, `applied` INTEGER). Replay that assumes
8
+ * every file on disk is applied reconstructs a state the database may never
9
+ * have been in: a file added but not yet run, or a file deleted from disk
10
+ * after it ran, both produce silent drift.
11
+ *
12
+ * This module reads that table so replay can start from an actual checkpoint,
13
+ * and so `status --verify` can name the difference between disk and database.
14
+ *
15
+ * The read is done with Node's built-in `node:sqlite` (Node >= 22.5), fetched
16
+ * through `process.getBuiltinModule` so neither the ESM nor the CJS bundle
17
+ * carries a hard dependency on it. `pb_data/data.db` is opened **read-only**;
18
+ * a running PocketBase instance is never disturbed.
19
+ */
20
+ /** PocketBase's internal table of applied migrations */
21
+ declare const APPLIED_MIGRATIONS_TABLE = "_migrations";
22
+ /** PocketBase's SQLite database file inside a pb_data directory */
23
+ declare const POCKETBASE_DATABASE_FILENAME = "data.db";
24
+ interface AppliedMigration {
25
+ /** Filename as PocketBase recorded it, e.g. "1712345678_created_Posts.js" */
26
+ file: string;
27
+ /** Unix seconds from `_migrations.applied`, when the column has a value */
28
+ applied?: number;
29
+ }
30
+ interface AppliedMigrationsSource {
31
+ /** Where the list came from — a database path, or a caller-supplied label */
32
+ origin: string;
33
+ /** Every row, in application order */
34
+ entries: AppliedMigration[];
35
+ /**
36
+ * Entries PocketBase's own Go core migrations contributed (`*.go`). They
37
+ * never correspond to a file in a pb_migrations directory, so they are
38
+ * kept separate from `entries` rather than reported as missing.
39
+ */
40
+ coreEntries: AppliedMigration[];
41
+ }
42
+ /**
43
+ * Raised when an applied-migrations list was requested but could not be read.
44
+ * Callers that treat the list as optional should catch this and fall back to
45
+ * "assume everything on disk is applied".
46
+ */
47
+ declare class AppliedMigrationsError extends Error {
48
+ readonly source?: string;
49
+ readonly originalError?: Error;
50
+ constructor(message: string, source?: string, originalError?: Error);
51
+ }
52
+ /**
53
+ * Builds a source from an explicit list of filenames (paths are reduced to
54
+ * their basename, so a caller can pass either).
55
+ */
56
+ declare function appliedMigrationsFromList(files: string[], origin?: string): AppliedMigrationsSource;
57
+ /**
58
+ * The pb_data directory PocketBase uses alongside a pb_migrations directory.
59
+ * Both live under the PocketBase working directory, so pb_data is a sibling.
60
+ */
61
+ declare function defaultDataDirectory(migrationsPath: string): string;
62
+ /**
63
+ * Resolves a user-supplied pb_data path (directory or database file) to the
64
+ * SQLite file to open. Returns null when nothing usable exists.
65
+ */
66
+ declare function resolveDatabasePath(dataPathOrFile: string): string | null;
67
+ /**
68
+ * Reads `_migrations` out of a PocketBase SQLite database.
69
+ *
70
+ * @param dataPathOrFile - A pb_data directory or a data.db file
71
+ * @throws AppliedMigrationsError when the runtime, file, or table is unusable
72
+ */
73
+ declare function readAppliedMigrations(dataPathOrFile: string): AppliedMigrationsSource;
74
+ /**
75
+ * Best-effort read: returns null instead of throwing when there is simply no
76
+ * database to read (the common case for a checkout that has never run
77
+ * PocketBase). Genuine failures — an unreadable file, a missing table, a
78
+ * runtime without node:sqlite — still throw, because silently assuming
79
+ * "everything is applied" is the drift this module exists to catch.
80
+ */
81
+ declare function readAppliedMigrationsIfPresent(dataPathOrFile: string): AppliedMigrationsSource | null;
82
+
83
+ /**
84
+ * Replay planning — which migration files reconstruct the current state
85
+ *
86
+ * Without knowledge of PocketBase's `_migrations` table, replay assumes every
87
+ * file on disk has been applied. That is right for the common case and wrong
88
+ * in exactly the situations that matter: a migration written but not yet run,
89
+ * or a file removed from disk after it ran. Both produce a reconstructed state
90
+ * the database was never in, and therefore a wrong diff.
91
+ *
92
+ * Given an applied-migrations list (see `applied-migrations.ts`), this module
93
+ * turns a pb_migrations directory into a plan:
94
+ *
95
+ * - `filesToReplay` — the applied prefix, starting at the newest *applied*
96
+ * snapshot, which is the checkpoint replay should start from
97
+ * - `pending` — on disk, never applied
98
+ * - `missing` — applied, no longer on disk
99
+ * - `outOfOrder` — pending files whose timestamp sits behind an already
100
+ * applied one, so they will be applied out of authoring order
101
+ */
102
+
103
+ /**
104
+ * Extracts the timestamp prefix from a migration filename.
105
+ * Migration files are named `[timestamp]_[description].js`.
106
+ *
107
+ * @param filename - Migration filename (basename, not a path)
108
+ * @returns Timestamp as a number, or null when the name is not prefixed
109
+ */
110
+ declare function extractTimestampFromFilename(filename: string): number | null;
111
+ /** A migration file discovered on disk */
112
+ interface DiscoveredMigration {
113
+ /** Absolute path */
114
+ path: string;
115
+ /** Basename, which is what `_migrations.file` stores */
116
+ name: string;
117
+ timestamp: number;
118
+ /** PocketBase's own `*_collections_snapshot.js` files */
119
+ isSnapshot: boolean;
120
+ }
121
+ interface MigrationPlan {
122
+ /** The snapshot the replay starts from, when the directory has one */
123
+ snapshotFile: string | null;
124
+ /** Absolute paths to execute, in timestamp order */
125
+ filesToReplay: string[];
126
+ /** Basenames present on disk but absent from `_migrations` */
127
+ pending: string[];
128
+ /** Basenames recorded in `_migrations` with no file on disk */
129
+ missing: string[];
130
+ /**
131
+ * Basenames from `pending` whose timestamp precedes an already-applied
132
+ * migration. PocketBase will still run them, but after migrations authored
133
+ * later — so the state they produce depends on apply order.
134
+ */
135
+ outOfOrder: string[];
136
+ /** False when no applied list was supplied: every file is assumed applied */
137
+ appliedKnown: boolean;
138
+ /** Where the applied list came from, when there was one */
139
+ appliedOrigin?: string;
140
+ /** Number of JS migrations recorded as applied */
141
+ appliedCount: number;
142
+ /** True when disk and `_migrations` agree exactly */
143
+ inSync: boolean;
144
+ }
145
+ interface PlanOptions {
146
+ /**
147
+ * The applied-migrations list. A plain array of filenames is accepted as a
148
+ * shorthand. Omit (or pass null) to assume every file on disk is applied.
149
+ */
150
+ applied?: AppliedMigrationsSource | string[] | null;
151
+ }
152
+ /**
153
+ * Lists every timestamped `.js` migration in a directory, in timestamp order.
154
+ * Returns an empty list when the directory does not exist.
155
+ */
156
+ declare function discoverMigrations(migrationsPath: string): DiscoveredMigration[];
157
+ /**
158
+ * Builds the replay plan for a migrations directory.
159
+ *
160
+ * Without an applied list this reproduces the directory's default replay
161
+ * window — newest snapshot plus everything after it — so the plan is a
162
+ * drop-in for the previous file selection.
163
+ */
164
+ declare function planMigrationReplay(migrationsPath: string, options?: PlanOptions): MigrationPlan;
165
+
166
+ /**
167
+ * Runtime field constructors matching the PocketBase JSVM globals
168
+ *
169
+ * In the PocketBase JSVM, migrations construct fields via `new Field({...})`
170
+ * or typed constructors like `new TextField({...})`. Instances are plain
171
+ * mutable objects; migrations freely assign properties after construction
172
+ * (e.g. `field.max = 500`).
173
+ *
174
+ * The constructors deliberately add no default properties beyond `type`:
175
+ * the resulting state must match what the migration file literally declares,
176
+ * the same data the literal declares, materialized as a real object.
177
+ */
178
+ /**
179
+ * Generic field constructor: `new Field({type: "number", ...})`.
180
+ * PocketBase's own generated migrations use this form with an explicit type.
181
+ */
182
+ declare class Field {
183
+ [key: string]: any;
184
+ constructor(data?: Record<string, any>);
185
+ }
186
+ declare const TextField: new (data?: Record<string, any>) => Field;
187
+ declare const EmailField: new (data?: Record<string, any>) => Field;
188
+ declare const URLField: new (data?: Record<string, any>) => Field;
189
+ declare const NumberField: new (data?: Record<string, any>) => Field;
190
+ declare const BoolField: new (data?: Record<string, any>) => Field;
191
+ declare const DateField: new (data?: Record<string, any>) => Field;
192
+ declare const SelectField: new (data?: Record<string, any>) => Field;
193
+ declare const RelationField: new (data?: Record<string, any>) => Field;
194
+ declare const FileField: new (data?: Record<string, any>) => Field;
195
+ declare const JSONField: new (data?: Record<string, any>) => Field;
196
+ declare const EditorField: new (data?: Record<string, any>) => Field;
197
+ declare const GeoPointField: new (data?: Record<string, any>) => Field;
198
+ declare const AutodateField: new (data?: Record<string, any>) => Field;
199
+ declare const PasswordField: new (data?: Record<string, any>) => Field;
200
+ declare const FIELD_CONSTRUCTORS: Record<string, new (data?: Record<string, any>) => Field>;
201
+
202
+ /**
203
+ * FieldsList — runtime equivalent of a PocketBase collection's `fields`
204
+ *
205
+ * Mirrors the methods the JSVM exposes on `collection.fields`:
206
+ * add / addAt / removeById / removeByName / getById / getByName, plus
207
+ * read-side iteration. Field entries are live objects — mutations through
208
+ * getByName() are visible when the collection is saved, exactly like the
209
+ * generator's `const f = collection.fields.getByName("x"); f.max = 500;`
210
+ * output expects.
211
+ */
212
+
213
+ declare class FieldsList {
214
+ private items;
215
+ constructor(fields?: any[]);
216
+ get length(): number;
217
+ /**
218
+ * Appends fields; a field whose id matches an existing entry replaces it
219
+ * in place (position preserved), matching PocketBase upsert semantics.
220
+ */
221
+ add(...fields: any[]): void;
222
+ /**
223
+ * Inserts fields at a position. A field with an already-present id is
224
+ * moved: the old entry is removed first, then the field is inserted at
225
+ * the requested position.
226
+ */
227
+ addAt(position: number, ...fields: any[]): void;
228
+ removeById(id: string): void;
229
+ removeByName(name: string): void;
230
+ getById(id: string): Field | undefined;
231
+ getByName(name: string): Field | undefined;
232
+ at(index: number): Field | undefined;
233
+ find(predicate: (field: Field, index: number) => boolean): Field | undefined;
234
+ filter(predicate: (field: Field, index: number) => boolean): Field[];
235
+ map<T>(mapper: (field: Field, index: number) => T): T[];
236
+ forEach(callback: (field: Field, index: number) => void): void;
237
+ [Symbol.iterator](): Iterator<Field>;
238
+ /** Replaces the whole list (used by unmarshal({fields: [...]}, collection)) */
239
+ replaceAll(fields: any[]): void;
240
+ /** Plain objects, in order */
241
+ serialize(): Record<string, any>[];
242
+ private indexOfId;
243
+ }
244
+
245
+ /**
246
+ * Runtime Collection class matching the PocketBase JSVM global
247
+ *
248
+ * `new Collection({...})` in a migration produces one of these. All data
249
+ * properties are copied verbatim (auth options, templates, etc. survive a
250
+ * snapshot import round-trip); `fields` becomes a live FieldsList and
251
+ * `indexes` a real array so `push`/`findIndex`/`splice` work natively.
252
+ *
253
+ * No rule properties are defaulted: the serialized collection must contain
254
+ * exactly what the migration declared, so engine output stays byte-parity
255
+ * with static analysis of the same literals.
256
+ */
257
+
258
+ declare function generateRuntimeCollectionId(): string;
259
+ declare class Collection {
260
+ [key: string]: any;
261
+ id: string;
262
+ name: string;
263
+ type: string;
264
+ system: boolean;
265
+ fields: FieldsList;
266
+ indexes: string[];
267
+ constructor(data?: RawCollection);
268
+ /** PocketBase-shaped plain object (what a snapshot array entry looks like) */
269
+ serialize(): RawCollection;
270
+ }
271
+
272
+ /**
273
+ * Record simulation — an in-memory row store per collection
274
+ *
275
+ * Schema reconstruction never needs this: a migration that seeds or rewrites
276
+ * data does not change the shape of a collection. It matters for the other
277
+ * job the engine can do — running a hand-written data migration before it
278
+ * touches production and seeing what it actually does.
279
+ *
280
+ * Enabled with `records: "simulate"`. Left off, `Record` and the data-layer
281
+ * `app.*` methods stay the inert stubs they have always been, so schema-only
282
+ * replay is unchanged.
283
+ *
284
+ * The store lives on `CollectionStore`, which means it inherits the runner's
285
+ * transaction semantics for free: a migration that throws halfway through a
286
+ * data rewrite leaves neither schema nor records behind.
287
+ */
288
+
289
+ /** PocketBase record ids are 15 lowercase alphanumeric characters */
290
+ declare function generateRecordId(): string;
291
+ /**
292
+ * The `Record` global a migration sees. Mirrors `core.Record`'s JSVM surface:
293
+ * `get`/`set` plus the typed getters, `load`, `publicExport`, `originalCopy`.
294
+ *
295
+ * Arbitrary property access (`record.title`) is deliberately *not* supported —
296
+ * `core.Record` is a Go struct and does not support it either, so a migration
297
+ * that relies on it would fail in PocketBase.
298
+ */
299
+ declare class RecordModel {
300
+ private data;
301
+ private original;
302
+ private readonly owner;
303
+ /** Set by setPassword(); PocketBase stores a hash, the simulation the value */
304
+ private password?;
305
+ constructor(collection: Collection, data?: Record<string, unknown>);
306
+ get id(): string;
307
+ set id(value: string);
308
+ collection(): Collection;
309
+ /** PocketBase names a collection's table after the collection */
310
+ tableName(): string;
311
+ get(key: string): unknown;
312
+ set(key: string, value: unknown): void;
313
+ getString(key: string): string;
314
+ getBool(key: string): boolean;
315
+ getInt(key: string): number;
316
+ getFloat(key: string): number;
317
+ getDateTime(key: string): string;
318
+ getStringSlice(key: string): string[];
319
+ /** Bulk assignment, as `record.load({...})` does in the JSVM */
320
+ load(data: Record<string, unknown>): void;
321
+ setPassword(password: string): void;
322
+ validatePassword(password: string): boolean;
323
+ /** The record as it was last read from (or written to) the store */
324
+ originalCopy(): RecordModel;
325
+ /**
326
+ * Deep, independent copy. `owner` rebinds the copy to another Collection
327
+ * instance (what a transaction clone needs); everything the getters cannot
328
+ * reach — the pre-modification `original` and the password `setPassword()`
329
+ * stored — is carried over, so a copy behaves like the record it came from.
330
+ */
331
+ clone(owner?: Collection): RecordModel;
332
+ /** Plain object, the shape `publicExport()` returns in the JSVM */
333
+ publicExport(): Record<string, unknown>;
334
+ /** Every stored value, including system columns */
335
+ export(): Record<string, unknown>;
336
+ /** Called by the store once a save has committed */
337
+ markPersisted(): void;
338
+ /** Fields the record carries that the collection does not declare */
339
+ undeclaredFields(): string[];
340
+ }
341
+ /**
342
+ * Rows, keyed by collection id then record id. Insertion order is preserved
343
+ * so unsorted queries come back the way they went in.
344
+ */
345
+ declare class RecordStore {
346
+ private byCollection;
347
+ save(record: RecordModel): RecordModel;
348
+ delete(record: RecordModel): boolean;
349
+ deleteById(collectionId: string, recordId: string): boolean;
350
+ getById(collectionId: string, recordId: string): RecordModel | undefined;
351
+ list(collectionId: string): RecordModel[];
352
+ count(collectionId: string): number;
353
+ /** Drops every row of a collection (what deleting the collection does) */
354
+ dropCollection(collectionId: string): void;
355
+ /** Every collection id that currently holds at least one record */
356
+ collectionIds(): string[];
357
+ /**
358
+ * Deep copy. Records are rebound to the collections in `collections` so a
359
+ * cloned record's `collection()` points at the cloned schema, not the one
360
+ * the transaction started from.
361
+ */
362
+ clone(resolveCollection: (id: string) => Collection | undefined): RecordStore;
363
+ /** Commit: adopt another store's rows */
364
+ replaceWith(other: RecordStore): void;
365
+ private rowsFor;
366
+ }
367
+
368
+ /**
369
+ * CollectionStore — the in-memory database state migrations execute against
370
+ *
371
+ * Keyed by collection id (migrations reference collections by id, name, or
372
+ * the `_pb_users_auth_` alias; renames must not orphan entries). Cloning
373
+ * serializes to plain objects and rebuilds, giving transaction semantics:
374
+ * the runner clones, applies a migration to the clone, and commits with
375
+ * replaceWith() only on success.
376
+ */
377
+
378
+ declare class CollectionStore {
379
+ private byId;
380
+ /**
381
+ * Rows, when record simulation is enabled. Always present so clone/commit
382
+ * carry data through the same transaction as the schema; empty and
383
+ * effectively free when only schema is being replayed.
384
+ */
385
+ readonly records: RecordStore;
386
+ list(): Collection[];
387
+ getById(id: string): Collection | undefined;
388
+ getByNameOrId(nameOrId: string): Collection | undefined;
389
+ upsert(collection: Collection): void;
390
+ removeById(id: string): boolean;
391
+ /** Deep, independent copy (rebuilds Collection/FieldsList instances) */
392
+ clone(): CollectionStore;
393
+ /** Commit: adopt another store's state */
394
+ replaceWith(other: CollectionStore): void;
395
+ serialize(): RawCollection[];
396
+ /** Convert to the internal schema model used by diff/compare */
397
+ toSnapshot(): SchemaSnapshot;
398
+ }
399
+
400
+ /**
401
+ * Execution engine types
402
+ *
403
+ * The engine executes PocketBase JS migration files in a sandboxed context
404
+ * that emulates the PocketBase JSVM (goja) API surface, instead of statically
405
+ * parsing them. These types describe its configuration and results.
406
+ */
407
+
408
+ /**
409
+ * A PocketBase-shaped plain collection object, as found in migration files
410
+ * and snapshot arrays (the JSON shape PocketBase itself serializes).
411
+ */
412
+ type RawCollection = Record<string, any>;
413
+ /**
414
+ * How the engine treats PocketBase APIs it does not simulate
415
+ * ($os, $dbx, Record, data-layer app methods, ...):
416
+ * - "lenient": record a warning and return an inert no-op value
417
+ * - "strict": throw immediately
418
+ */
419
+ type EngineStrictness = "strict" | "lenient";
420
+ /**
421
+ * Whether record CRUD and `$dbx`/`app.db()` queries execute against an
422
+ * in-memory row store:
423
+ * - "stub" (default): `Record` and the data-layer `app.*` methods stay inert,
424
+ * which is all schema reconstruction needs
425
+ * - "simulate": rows are tracked per collection, so a hand-written data
426
+ * migration can be executed and inspected before it runs for real
427
+ */
428
+ type EngineRecordMode = "stub" | "simulate";
429
+ interface EngineWarning {
430
+ /** Migration file the warning originated from, when known */
431
+ file?: string;
432
+ kind: "unsupported-api" | "console" | "noop";
433
+ /** The API that was stubbed, e.g. "$os.getenv" or "app.findRecordById" */
434
+ api?: string;
435
+ message: string;
436
+ }
437
+ interface EngineOptions {
438
+ /** Defaults to "lenient" */
439
+ strictness?: EngineStrictness;
440
+ /** Defaults to "stub" */
441
+ records?: EngineRecordMode;
442
+ /** Invoked for every warning as it happens (warnings are also collected) */
443
+ onWarning?: (warning: EngineWarning) => void;
444
+ /** Per-file evaluation/execution timeout in milliseconds. Defaults to 5000. */
445
+ timeoutMs?: number;
446
+ }
447
+ /** Which of a migration's two closures was executed */
448
+ type MigrationDirection = "up" | "down";
449
+ interface MigrationExecutionResult {
450
+ file?: string;
451
+ /** Which closure ran. Defaults to "up" for state reconstruction. */
452
+ direction: MigrationDirection;
453
+ /**
454
+ * False when the file registered no closure for this direction — no
455
+ * migrate() call at all, or a migrate(up) with no down.
456
+ */
457
+ applied: boolean;
458
+ warnings: EngineWarning[];
459
+ }
460
+ interface ReplayResult {
461
+ /** Final state converted to the internal schema model */
462
+ snapshot: SchemaSnapshot;
463
+ /** The raw store, for further execution or inspection */
464
+ store: CollectionStore;
465
+ warnings: EngineWarning[];
466
+ filesExecuted: string[];
467
+ /**
468
+ * How the file list was chosen — including anything on disk that is not
469
+ * applied, and anything applied that is no longer on disk. Null when the
470
+ * caller supplied the file list directly.
471
+ */
472
+ plan: MigrationPlan | null;
473
+ }
474
+
475
+ export { APPLIED_MIGRATIONS_TABLE as A, BoolField as B, CollectionStore as C, type DiscoveredMigration as D, type EngineOptions as E, FIELD_CONSTRUCTORS as F, Field as G, FileField as H, GeoPointField as I, JSONField as J, PasswordField as K, RelationField as L, type MigrationDirection as M, NumberField as N, FieldsList as O, POCKETBASE_DATABASE_FILENAME as P, generateRecordId as Q, RecordModel as R, SelectField as S, TextField as T, URLField as U, AppliedMigrationsError as a, RecordStore as b, appliedMigrationsFromList as c, defaultDataDirectory as d, discoverMigrations as e, extractTimestampFromFilename as f, readAppliedMigrationsIfPresent as g, resolveDatabasePath as h, type AppliedMigration as i, type AppliedMigrationsSource as j, type EngineRecordMode as k, type EngineStrictness as l, type EngineWarning as m, type MigrationExecutionResult as n, type MigrationPlan as o, planMigrationReplay as p, type PlanOptions as q, readAppliedMigrations as r, type ReplayResult as s, Collection as t, type RawCollection as u, generateRuntimeCollectionId as v, AutodateField as w, DateField as x, EditorField as y, EmailField as z };