@abloatai/ablo 0.25.0 → 0.27.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.
- package/AGENTS.md +5 -3
- package/CHANGELOG.md +34 -0
- package/README.md +104 -88
- package/dist/BaseSyncedStore.d.ts +140 -266
- package/dist/BaseSyncedStore.js +338 -739
- package/dist/Database.d.ts +62 -77
- package/dist/Database.js +106 -127
- package/dist/{ObjectPool.d.ts → InstanceCache.d.ts} +10 -13
- package/dist/{ObjectPool.js → InstanceCache.js} +91 -83
- package/dist/LazyReferenceCollection.d.ts +11 -15
- package/dist/LazyReferenceCollection.js +16 -15
- package/dist/Model.d.ts +37 -52
- package/dist/Model.js +52 -69
- package/dist/ModelRegistry.d.ts +46 -25
- package/dist/ModelRegistry.js +32 -30
- package/dist/NetworkMonitor.d.ts +5 -6
- package/dist/NetworkMonitor.js +6 -7
- package/dist/SyncClient.d.ts +119 -109
- package/dist/SyncClient.js +303 -224
- package/dist/SyncEngineContext.d.ts +1 -3
- package/dist/SyncEngineContext.js +1 -2
- package/dist/adapters/alwaysOnline.d.ts +6 -8
- package/dist/adapters/alwaysOnline.js +6 -8
- package/dist/adapters/inMemoryStorage.d.ts +9 -9
- package/dist/adapters/inMemoryStorage.js +9 -9
- package/dist/agent/Agent.d.ts +39 -31
- package/dist/agent/Agent.js +35 -23
- package/dist/agent/index.d.ts +4 -4
- package/dist/agent/index.js +5 -5
- package/dist/agent/session.d.ts +47 -44
- package/dist/agent/session.js +37 -48
- package/dist/agent/types.d.ts +26 -31
- package/dist/agent/types.js +6 -7
- package/dist/ai-sdk/coordinatedTool.d.ts +108 -0
- package/dist/ai-sdk/{coordinated-tool.js → coordinatedTool.js} +44 -38
- package/dist/ai-sdk/coordinationContext.d.ts +46 -0
- package/dist/ai-sdk/{coordination-context.js → coordinationContext.js} +30 -31
- package/dist/ai-sdk/index.d.ts +25 -22
- package/dist/ai-sdk/index.js +25 -22
- package/dist/ai-sdk/wrap.d.ts +7 -8
- package/dist/ai-sdk/wrap.js +2 -2
- package/dist/auth/credentialPolicy.d.ts +74 -71
- package/dist/auth/credentialPolicy.js +51 -56
- package/dist/auth/credentialSource.d.ts +7 -18
- package/dist/auth/credentialSource.js +10 -18
- package/dist/auth/index.d.ts +59 -58
- package/dist/auth/index.js +34 -40
- package/dist/auth/schemas.d.ts +5 -4
- package/dist/auth/schemas.js +5 -4
- package/dist/batching/index.d.ts +19 -21
- package/dist/batching/index.js +14 -17
- package/dist/cli.cjs +483 -369
- package/dist/client/Ablo.d.ts +107 -836
- package/dist/client/Ablo.js +174 -833
- package/dist/client/ApiClient.d.ts +44 -20
- package/dist/client/ApiClient.js +193 -44
- package/dist/client/auth.d.ts +51 -60
- package/dist/client/auth.js +137 -110
- package/dist/client/claimHeartbeatLoop.d.ts +50 -0
- package/dist/client/claimHeartbeatLoop.js +88 -0
- package/dist/client/consoleLogger.d.ts +35 -0
- package/dist/client/consoleLogger.js +44 -0
- package/dist/client/createInternalComponents.d.ts +14 -17
- package/dist/client/createInternalComponents.js +26 -31
- package/dist/client/createModelProxy.d.ts +130 -120
- package/dist/client/createModelProxy.js +158 -124
- package/dist/client/credentialEndpoint.d.ts +61 -0
- package/dist/client/credentialEndpoint.js +86 -0
- package/dist/client/functionalUpdate.d.ts +29 -27
- package/dist/client/functionalUpdate.js +21 -21
- package/dist/client/hostedEndpoints.d.ts +21 -0
- package/dist/client/hostedEndpoints.js +21 -0
- package/dist/client/httpClient.d.ts +58 -54
- package/dist/client/httpClient.js +29 -31
- package/dist/client/identity.d.ts +15 -20
- package/dist/client/identity.js +49 -59
- package/dist/client/modelRegistration.d.ts +10 -0
- package/dist/client/modelRegistration.js +301 -0
- package/dist/client/options.d.ts +373 -0
- package/dist/client/options.js +6 -0
- package/dist/client/registerDataSource.d.ts +9 -9
- package/dist/client/registerDataSource.js +15 -16
- package/dist/client/resourceTypes.d.ts +333 -0
- package/dist/client/resourceTypes.js +7 -0
- package/dist/client/schemaConfig.d.ts +44 -0
- package/dist/client/schemaConfig.js +176 -0
- package/dist/client/sessionMint.d.ts +17 -13
- package/dist/client/sessionMint.js +26 -31
- package/dist/client/validateAbloOptions.d.ts +12 -14
- package/dist/client/validateAbloOptions.js +9 -10
- package/dist/client/writeOptionsSchema.d.ts +18 -16
- package/dist/client/writeOptionsSchema.js +23 -20
- package/dist/client/wsMutationExecutor.d.ts +28 -0
- package/dist/client/wsMutationExecutor.js +71 -0
- package/dist/context.d.ts +6 -4
- package/dist/context.js +6 -7
- package/dist/coordination/index.d.ts +13 -4
- package/dist/coordination/index.js +29 -4
- package/dist/coordination/schema.d.ts +176 -128
- package/dist/coordination/schema.js +197 -133
- package/dist/coordination/trace.d.ts +9 -11
- package/dist/coordination/trace.js +13 -15
- package/dist/core/DatabaseManager.d.ts +5 -8
- package/dist/core/DatabaseManager.js +38 -40
- package/dist/core/QueryProcessor.d.ts +7 -9
- package/dist/core/QueryProcessor.js +27 -34
- package/dist/core/QueryView.d.ts +17 -5
- package/dist/core/QueryView.js +6 -7
- package/dist/core/StoreManager.d.ts +14 -16
- package/dist/core/StoreManager.js +26 -25
- package/dist/core/ViewRegistry.d.ts +5 -5
- package/dist/core/ViewRegistry.js +4 -4
- package/dist/core/index.d.ts +18 -13
- package/dist/core/index.js +32 -26
- package/dist/core/openIDBWithTimeout.d.ts +38 -36
- package/dist/core/openIDBWithTimeout.js +57 -54
- package/dist/core/queryUtils.d.ts +45 -0
- package/dist/core/queryUtils.js +69 -0
- package/dist/core/storeContract.d.ts +145 -0
- package/dist/core/storeContract.js +12 -0
- package/dist/environment.d.ts +28 -0
- package/dist/environment.js +21 -0
- package/dist/errorCodes.d.ts +118 -101
- package/dist/errorCodes.js +277 -260
- package/dist/errors.d.ts +170 -165
- package/dist/errors.js +161 -151
- package/dist/index.d.ts +30 -27
- package/dist/index.js +90 -82
- package/dist/interfaces/index.d.ts +108 -133
- package/dist/interfaces/index.js +5 -4
- package/dist/keys/index.d.ts +27 -29
- package/dist/keys/index.js +59 -49
- package/dist/mutators/RecordingTransaction.d.ts +16 -16
- package/dist/mutators/RecordingTransaction.js +31 -37
- package/dist/mutators/Transaction.d.ts +18 -26
- package/dist/mutators/Transaction.js +14 -20
- package/dist/mutators/UndoManager.d.ts +122 -131
- package/dist/mutators/UndoManager.js +149 -155
- package/dist/mutators/defineMutators.d.ts +24 -37
- package/dist/mutators/defineMutators.js +14 -20
- package/dist/mutators/inverseOp.d.ts +12 -15
- package/dist/mutators/inverseOp.js +12 -15
- package/dist/mutators/mutateActions.d.ts +10 -9
- package/dist/mutators/mutateActions.js +1 -1
- package/dist/mutators/readerActions.d.ts +9 -8
- package/dist/mutators/readerActions.js +2 -2
- package/dist/mutators/undoApply.d.ts +31 -27
- package/dist/mutators/undoApply.js +26 -24
- package/dist/policy/index.d.ts +5 -3
- package/dist/policy/index.js +5 -3
- package/dist/policy/types.d.ts +105 -101
- package/dist/policy/types.js +67 -66
- package/dist/query/client.d.ts +32 -16
- package/dist/query/client.js +103 -72
- package/dist/query/types.d.ts +37 -60
- package/dist/query/types.js +13 -33
- package/dist/react/AbloProvider.d.ts +7 -11
- package/dist/react/AbloProvider.js +24 -17
- package/dist/react/context.d.ts +27 -146
- package/dist/react/context.js +9 -10
- package/dist/react/index.d.ts +41 -42
- package/dist/react/index.js +37 -38
- package/dist/react/internalContext.d.ts +17 -19
- package/dist/react/useAblo.d.ts +23 -22
- package/dist/react/useAblo.js +17 -15
- package/dist/react/useCurrentUserId.d.ts +8 -7
- package/dist/react/useCurrentUserId.js +8 -7
- package/dist/react/useErrorListener.d.ts +7 -7
- package/dist/react/useErrorListener.js +11 -12
- package/dist/react/useMutationFailureListener.d.ts +8 -8
- package/dist/react/useMutationFailureListener.js +9 -9
- package/dist/react/useMutators.d.ts +11 -11
- package/dist/react/useMutators.js +10 -4
- package/dist/react/useReactive.js +2 -3
- package/dist/react/useSyncStatus.d.ts +4 -6
- package/dist/react/useUndoScope.d.ts +7 -9
- package/dist/react/useUndoScope.js +3 -3
- package/dist/schema/coordination.d.ts +21 -25
- package/dist/schema/coordination.js +21 -25
- package/dist/schema/ddl.d.ts +43 -39
- package/dist/schema/ddl.js +75 -68
- package/dist/schema/ddlLock.d.ts +35 -0
- package/dist/schema/ddlLock.js +46 -0
- package/dist/schema/diff.d.ts +99 -61
- package/dist/schema/diff.js +43 -34
- package/dist/schema/field.d.ts +37 -42
- package/dist/schema/field.js +36 -49
- package/dist/schema/generate.d.ts +12 -12
- package/dist/schema/generate.js +12 -12
- package/dist/schema/index.d.ts +5 -4
- package/dist/schema/index.js +29 -21
- package/dist/schema/model.d.ts +121 -146
- package/dist/schema/model.js +24 -35
- package/dist/schema/openapi.d.ts +10 -9
- package/dist/schema/openapi.js +7 -1
- package/dist/schema/queries.d.ts +30 -32
- package/dist/schema/queries.js +24 -25
- package/dist/schema/relation.d.ts +89 -99
- package/dist/schema/relation.js +13 -13
- package/dist/schema/residency.d.ts +38 -0
- package/dist/schema/residency.js +30 -0
- package/dist/schema/roles.d.ts +45 -27
- package/dist/schema/roles.js +52 -21
- package/dist/schema/schema.d.ts +36 -45
- package/dist/schema/schema.js +42 -39
- package/dist/schema/select.d.ts +13 -13
- package/dist/schema/select.js +13 -13
- package/dist/schema/serialize.d.ts +36 -39
- package/dist/schema/serialize.js +27 -31
- package/dist/schema/sugar.d.ts +17 -32
- package/dist/schema/sugar.js +14 -29
- package/dist/schema/{sync-delta-row.d.ts → syncDeltaRow.d.ts} +27 -50
- package/dist/schema/syncDeltaRow.js +89 -0
- package/dist/schema/tenancy.d.ts +44 -46
- package/dist/schema/tenancy.js +46 -48
- package/dist/server/adapter.d.ts +58 -58
- package/dist/server/adapter.js +13 -14
- package/dist/server/commit.d.ts +60 -64
- package/dist/server/index.d.ts +9 -10
- package/dist/server/index.js +1 -1
- package/dist/server/readConfig.d.ts +70 -0
- package/dist/server/readConfig.js +8 -0
- package/dist/server/storageMode.d.ts +23 -0
- package/dist/server/storageMode.js +17 -0
- package/dist/source/adapter.d.ts +31 -26
- package/dist/source/adapter.js +10 -10
- package/dist/source/adapters/drizzle.d.ts +28 -23
- package/dist/source/adapters/drizzle.js +34 -28
- package/dist/source/adapters/kysely.d.ts +27 -25
- package/dist/source/adapters/kysely.js +28 -26
- package/dist/source/adapters/memory.d.ts +8 -7
- package/dist/source/adapters/memory.js +10 -9
- package/dist/source/adapters/prisma.d.ts +13 -12
- package/dist/source/adapters/prisma.js +27 -29
- package/dist/source/conformance.d.ts +18 -11
- package/dist/source/conformance.js +27 -19
- package/dist/source/connector.d.ts +31 -32
- package/dist/source/connector.js +30 -28
- package/dist/source/connectorProtocol.d.ts +160 -0
- package/dist/source/connectorProtocol.js +162 -0
- package/dist/source/contract.d.ts +26 -27
- package/dist/source/contract.js +28 -29
- package/dist/source/factory.d.ts +94 -0
- package/dist/source/factory.js +268 -0
- package/dist/source/index.d.ts +10 -462
- package/dist/source/index.js +17 -421
- package/dist/source/migrations.d.ts +9 -9
- package/dist/source/migrations.js +9 -9
- package/dist/source/next.d.ts +10 -11
- package/dist/source/next.js +7 -8
- package/dist/source/pushQueue.d.ts +70 -48
- package/dist/source/pushQueue.js +36 -29
- package/dist/source/signing.d.ts +88 -0
- package/dist/source/signing.js +159 -0
- package/dist/source/types.d.ts +351 -0
- package/dist/source/types.js +43 -0
- package/dist/stores/ObjectStore.d.ts +11 -12
- package/dist/stores/ObjectStore.js +34 -35
- package/dist/stores/ObjectStoreContract.d.ts +12 -15
- package/dist/stores/SyncActionStore.d.ts +8 -12
- package/dist/stores/SyncActionStore.js +77 -46
- package/dist/surface.d.ts +28 -21
- package/dist/surface.js +28 -20
- package/dist/sync/{BootstrapHelper.d.ts → BootstrapFetcher.d.ts} +37 -45
- package/dist/sync/{BootstrapHelper.js → BootstrapFetcher.js} +101 -80
- package/dist/sync/ConnectionManager.d.ts +47 -50
- package/dist/sync/ConnectionManager.js +74 -70
- package/dist/sync/NetworkProbe.d.ts +27 -31
- package/dist/sync/NetworkProbe.js +67 -72
- package/dist/sync/{HydrationCoordinator.d.ts → OnDemandLoader.d.ts} +49 -36
- package/dist/sync/{HydrationCoordinator.js → OnDemandLoader.js} +79 -54
- package/dist/sync/{AreaOfInterestManager.d.ts → SubscriptionManager.d.ts} +45 -59
- package/dist/sync/{AreaOfInterestManager.js → SubscriptionManager.js} +44 -52
- package/dist/sync/SyncWebSocket.d.ts +175 -250
- package/dist/sync/SyncWebSocket.js +431 -769
- package/dist/sync/awaitClaimGrant.d.ts +18 -18
- package/dist/sync/awaitClaimGrant.js +38 -30
- package/dist/sync/bootstrapApply.d.ts +70 -0
- package/dist/sync/bootstrapApply.js +73 -0
- package/dist/sync/commitFrames.d.ts +44 -0
- package/dist/sync/commitFrames.js +94 -0
- package/dist/sync/createClaimStream.d.ts +23 -22
- package/dist/sync/createClaimStream.js +108 -25
- package/dist/sync/createPresenceStream.d.ts +19 -18
- package/dist/sync/createPresenceStream.js +25 -26
- package/dist/sync/createSnapshot.d.ts +13 -17
- package/dist/sync/createSnapshot.js +20 -26
- package/dist/sync/credentialLifecycle.d.ts +175 -0
- package/dist/sync/credentialLifecycle.js +322 -0
- package/dist/sync/deltaPipeline.d.ts +113 -0
- package/dist/sync/deltaPipeline.js +261 -0
- package/dist/sync/groupChange.d.ts +113 -0
- package/dist/sync/groupChange.js +242 -0
- package/dist/sync/heartbeat.d.ts +63 -0
- package/dist/sync/heartbeat.js +91 -0
- package/dist/sync/participants.d.ts +27 -27
- package/dist/sync/schemas.d.ts +3 -2
- package/dist/sync/schemas.js +14 -10
- package/dist/sync/syncCursor.d.ts +40 -0
- package/dist/sync/syncCursor.js +55 -0
- package/dist/sync/syncPlan.d.ts +54 -0
- package/dist/sync/syncPlan.js +50 -0
- package/dist/sync/syncPosition.d.ts +54 -49
- package/dist/sync/syncPosition.js +57 -52
- package/dist/sync/wsFrameHandlers.d.ts +116 -0
- package/dist/sync/wsFrameHandlers.js +374 -0
- package/dist/testing/fixtures/bootstrap.d.ts +21 -17
- package/dist/testing/fixtures/bootstrap.js +12 -6
- package/dist/testing/fixtures/deltas.d.ts +31 -34
- package/dist/testing/fixtures/deltas.js +30 -33
- package/dist/testing/fixtures/models.d.ts +11 -10
- package/dist/testing/fixtures/models.js +12 -10
- package/dist/testing/helpers/{react-wrapper.d.ts → reactWrapper.d.ts} +13 -10
- package/dist/testing/helpers/{react-wrapper.js → reactWrapper.js} +15 -12
- package/dist/testing/helpers/{sync-engine-harness.d.ts → syncEngineHarness.d.ts} +17 -18
- package/dist/testing/helpers/{sync-engine-harness.js → syncEngineHarness.js} +14 -11
- package/dist/testing/helpers/wait.d.ts +13 -8
- package/dist/testing/helpers/wait.js +13 -8
- package/dist/testing/index.d.ts +4 -4
- package/dist/testing/index.js +3 -3
- package/dist/testing/mocks/MockMutationExecutor.d.ts +18 -17
- package/dist/testing/mocks/MockMutationExecutor.js +15 -14
- package/dist/testing/mocks/MockNetworkMonitor.d.ts +8 -8
- package/dist/testing/mocks/MockNetworkMonitor.js +8 -8
- package/dist/testing/mocks/MockSyncContext.d.ts +21 -34
- package/dist/testing/mocks/MockSyncContext.js +16 -45
- package/dist/testing/mocks/MockSyncStore.d.ts +14 -14
- package/dist/testing/mocks/MockSyncStore.js +11 -11
- package/dist/testing/mocks/MockWebSocket.d.ts +28 -24
- package/dist/testing/mocks/MockWebSocket.js +22 -21
- package/dist/transactions/TransactionQueue.d.ts +190 -221
- package/dist/transactions/TransactionQueue.js +424 -822
- package/dist/transactions/TransactionStore.d.ts +20 -0
- package/dist/transactions/TransactionStore.js +53 -0
- package/dist/transactions/UnconfirmedWrites.d.ts +82 -0
- package/dist/transactions/UnconfirmedWrites.js +104 -0
- package/dist/transactions/coalesceRules.d.ts +58 -0
- package/dist/transactions/coalesceRules.js +140 -0
- package/dist/transactions/commitPayload.d.ts +130 -0
- package/dist/transactions/commitPayload.js +143 -0
- package/dist/transactions/deltaConfirmation.d.ts +58 -0
- package/dist/transactions/deltaConfirmation.js +215 -0
- package/dist/transactions/optimisticApply.d.ts +49 -0
- package/dist/transactions/optimisticApply.js +65 -0
- package/dist/transactions/replayValidation.d.ts +99 -0
- package/dist/transactions/replayValidation.js +111 -0
- package/dist/types/global.d.ts +46 -41
- package/dist/types/global.js +20 -19
- package/dist/types/index.d.ts +74 -80
- package/dist/types/index.js +22 -27
- package/dist/types/modelData.d.ts +10 -0
- package/dist/types/modelData.js +9 -0
- package/dist/types/participant.d.ts +20 -0
- package/dist/types/participant.js +10 -0
- package/dist/types/streams.d.ts +216 -209
- package/dist/types/streams.js +7 -7
- package/dist/utils/asyncIterator.d.ts +25 -32
- package/dist/utils/asyncIterator.js +25 -32
- package/dist/utils/duration.d.ts +12 -15
- package/dist/utils/duration.js +12 -15
- package/dist/utils/mobxSetup.d.ts +53 -0
- package/dist/utils/{mobx-setup.js → mobxSetup.js} +44 -100
- package/dist/webhooks/events.d.ts +21 -16
- package/dist/webhooks/events.js +10 -8
- package/dist/webhooks/index.d.ts +5 -7
- package/dist/webhooks/index.js +5 -7
- package/dist/{schema/sync-delta-wire.d.ts → wire/delta.d.ts} +58 -41
- package/dist/wire/delta.js +114 -0
- package/dist/wire/errorEnvelope.d.ts +35 -27
- package/dist/wire/errorEnvelope.js +38 -32
- package/dist/wire/frames.d.ts +150 -67
- package/dist/wire/frames.js +48 -1
- package/dist/wire/index.d.ts +18 -13
- package/dist/wire/index.js +36 -13
- package/dist/wire/listEnvelope.d.ts +16 -23
- package/dist/wire/listEnvelope.js +7 -6
- package/dist/wire/protocol.d.ts +38 -0
- package/dist/wire/protocol.js +38 -0
- package/dist/wire/protocolVersion.d.ts +60 -0
- package/dist/wire/protocolVersion.js +67 -0
- package/docs/api-keys.md +4 -3
- package/docs/coordination.md +59 -0
- package/docs/examples/existing-python-backend.md +3 -3
- package/docs/identity.md +4 -4
- package/docs/integration-guide.md +1 -1
- package/docs/react.md +1 -1
- package/docs/sessions.md +5 -7
- package/package.json +24 -21
- package/dist/ai-sdk/coordinated-tool.d.ts +0 -101
- package/dist/ai-sdk/coordination-context.d.ts +0 -52
- package/dist/client/index.d.ts +0 -36
- package/dist/client/index.js +0 -33
- package/dist/config/index.d.ts +0 -10
- package/dist/config/index.js +0 -12
- package/dist/core/query-utils.d.ts +0 -34
- package/dist/core/query-utils.js +0 -59
- package/dist/interfaces/headless.d.ts +0 -95
- package/dist/interfaces/headless.js +0 -41
- package/dist/query/index.d.ts +0 -6
- package/dist/query/index.js +0 -5
- package/dist/realtime/index.d.ts +0 -10
- package/dist/realtime/index.js +0 -9
- package/dist/schema/plane.d.ts +0 -23
- package/dist/schema/plane.js +0 -19
- package/dist/schema/sync-delta-row.js +0 -103
- package/dist/schema/sync-delta-wire.js +0 -102
- package/dist/server/next.d.ts +0 -51
- package/dist/server/next.js +0 -47
- package/dist/server/read-config.d.ts +0 -67
- package/dist/server/read-config.js +0 -8
- package/dist/server/storage-mode.d.ts +0 -1
- package/dist/server/storage-mode.js +0 -18
- package/dist/source/connector-protocol.d.ts +0 -159
- package/dist/source/connector-protocol.js +0 -161
- package/dist/sync/OfflineFlush.d.ts +0 -9
- package/dist/sync/OfflineFlush.js +0 -22
- package/dist/sync/OfflineTransactionStore.d.ts +0 -37
- package/dist/sync/OfflineTransactionStore.js +0 -263
- package/dist/transactions/OptimisticEchoTracker.d.ts +0 -82
- package/dist/transactions/OptimisticEchoTracker.js +0 -104
- package/dist/transactions/index.d.ts +0 -16
- package/dist/transactions/index.js +0 -7
- package/dist/transactions/mutation-error-handler.d.ts +0 -5
- package/dist/transactions/mutation-error-handler.js +0 -39
- package/dist/utils/mobx-setup.d.ts +0 -42
package/dist/schema/diff.d.ts
CHANGED
|
@@ -1,61 +1,74 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Computes the migration plan that turns one schema into another. Given two
|
|
3
|
+
* serialized schemas — the one currently active and the one being pushed — it
|
|
4
|
+
* produces an ordered list of {@link MigrationStep}s describing how to evolve the
|
|
5
|
+
* database, and a {@link MigrationClassification} that separates the risky parts
|
|
6
|
+
* into warnings (they run, but may lose or risk data on a non-empty table) and
|
|
7
|
+
* unexecutable steps (they fail on a non-empty table unless a backfill or default
|
|
8
|
+
* is supplied). This module only plans: it has no database dependency and emits no
|
|
9
|
+
* SQL, so it can be unit-tested exhaustively and reused by the command-line tools.
|
|
10
|
+
* Turning a step into SQL and running it happens in the host implementation, which
|
|
11
|
+
* owns the column-type mapping and row-security rules.
|
|
3
12
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* (
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
13
|
+
* A few design choices worth knowing about:
|
|
14
|
+
* - Renames are supplied as data through {@link RenameHints}, not guessed. Without
|
|
15
|
+
* a hint, a removed field plus an added field reads as a drop followed by an add,
|
|
16
|
+
* which is the safe (lossy) default; a hint tells the planner they are the same
|
|
17
|
+
* field under a new name.
|
|
18
|
+
* - Destructive changes fall into two tiers — warnings versus unexecutable — and a
|
|
19
|
+
* type change carries its own sub-tier ({@link CastSafety}: safe, risky, or not
|
|
20
|
+
* castable) that decides between an in-place `ALTER COLUMN … TYPE` and a lossy
|
|
21
|
+
* drop-and-recreate.
|
|
22
|
+
* - A single {@link FieldChanges} value records which facets of a column changed
|
|
23
|
+
* (type, nullability, enum values, index) so one `alter_field` step covers them
|
|
24
|
+
* all instead of several separate steps.
|
|
11
25
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* - **Prisma migration engine**: a two-tier destructive classification
|
|
17
|
-
* (warning vs unexecutable) and a type-change sub-tier
|
|
18
|
-
* (safe / risky / not-castable) that decides in-place `ALTER TYPE` vs a
|
|
19
|
-
* lossy drop-and-recreate.
|
|
20
|
-
* - **Atlas**: a single `alter_field` step carrying *which* facets changed
|
|
21
|
-
* (type / nullability / enum / index) instead of N discrete alter steps.
|
|
22
|
-
*
|
|
23
|
-
* Step ordering is the expand→contract sequence (add before drop, widen before
|
|
24
|
-
* narrow): create models → rename → add columns (always nullable) → alter →
|
|
25
|
-
* drop columns → drop models. NOT NULL is never set on add — it is an
|
|
26
|
-
* `alter_field` nullability change that a backfill must precede.
|
|
26
|
+
* Steps come back in expand-then-contract order — add before drop, widen before
|
|
27
|
+
* narrow: create models, rename, add columns (always nullable), alter, drop columns,
|
|
28
|
+
* drop models. A newly added column is never created `NOT NULL`; making a column
|
|
29
|
+
* required is a separate nullability change that a backfill must run before.
|
|
27
30
|
*/
|
|
28
31
|
import type { FieldMeta } from './field.js';
|
|
29
32
|
import type { SchemaJSON } from './serialize.js';
|
|
30
33
|
export type FieldType = FieldMeta['type'];
|
|
31
34
|
/** Whether a Postgres `ALTER COLUMN … TYPE` can preserve the existing data. */
|
|
32
35
|
export type CastSafety = 'safe' | 'risky' | 'notCastable';
|
|
36
|
+
/** Records a column's type change and how safely Postgres can carry it out. */
|
|
33
37
|
export interface FieldTypeChange {
|
|
34
38
|
readonly from: FieldType;
|
|
35
39
|
readonly to: FieldType;
|
|
36
|
-
/**
|
|
37
|
-
* `
|
|
40
|
+
/** How the type change is carried out: `safe` runs a plain `ALTER COLUMN … TYPE`;
|
|
41
|
+
* `risky` runs one with a `USING` cast that may fail on some rows; `notCastable`
|
|
42
|
+
* drops and recreates the column, losing its data. */
|
|
38
43
|
readonly cast: CastSafety;
|
|
39
44
|
}
|
|
40
|
-
/**
|
|
45
|
+
/** Records a change to whether a field is optional. Going from optional to required
|
|
46
|
+
* (`true → false`) is the dangerous direction: it fails if any existing row holds
|
|
47
|
+
* a null. */
|
|
41
48
|
export interface NullabilityChange {
|
|
42
49
|
readonly fromOptional: boolean;
|
|
43
50
|
readonly toOptional: boolean;
|
|
44
51
|
}
|
|
52
|
+
/** Records which allowed values an enum field gained and lost. Removing a value is
|
|
53
|
+
* the risky part — existing rows still holding it violate the new constraint. */
|
|
45
54
|
export interface EnumValuesChange {
|
|
46
55
|
readonly added: readonly string[];
|
|
47
56
|
readonly removed: readonly string[];
|
|
48
57
|
}
|
|
58
|
+
/** Records a change to whether a field is indexed (`from` was, `to` will be). */
|
|
49
59
|
export interface IndexChange {
|
|
50
60
|
readonly from: boolean;
|
|
51
61
|
readonly to: boolean;
|
|
52
62
|
}
|
|
53
|
-
/**
|
|
63
|
+
/** Records a change to the physical database column name backing a field whose
|
|
64
|
+
* logical name stayed the same. */
|
|
54
65
|
export interface FieldColumnChange {
|
|
55
66
|
readonly from: string;
|
|
56
67
|
readonly to: string;
|
|
57
68
|
}
|
|
58
|
-
/** The facets of a single column that changed
|
|
69
|
+
/** The set of facets of a single column that changed. Each optional member is
|
|
70
|
+
* present only when that facet actually changed, so one `alter_field` step can
|
|
71
|
+
* describe several simultaneous changes to the same column. */
|
|
59
72
|
export interface FieldChanges {
|
|
60
73
|
readonly column?: FieldColumnChange;
|
|
61
74
|
readonly type?: FieldTypeChange;
|
|
@@ -63,6 +76,9 @@ export interface FieldChanges {
|
|
|
63
76
|
readonly enumValues?: EnumValuesChange;
|
|
64
77
|
readonly indexed?: IndexChange;
|
|
65
78
|
}
|
|
79
|
+
/** One step in a migration plan. The `kind` tag names the operation and the
|
|
80
|
+
* remaining fields carry its target and payload. {@link diffSchema} emits these in
|
|
81
|
+
* expand-then-contract order, and the host implementation lowers each to SQL. */
|
|
66
82
|
export type MigrationStep = {
|
|
67
83
|
readonly kind: 'create_model';
|
|
68
84
|
readonly model: string;
|
|
@@ -96,10 +112,11 @@ export type MigrationStep = {
|
|
|
96
112
|
readonly changes: FieldChanges;
|
|
97
113
|
};
|
|
98
114
|
/**
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
* model
|
|
115
|
+
* Tells {@link diffSchema} which removed-and-added pairs are really renames. Supply
|
|
116
|
+
* these as data because the planner cannot safely guess: without a hint, a field
|
|
117
|
+
* that disappears and a field that appears read as a drop followed by an add, which
|
|
118
|
+
* loses the column's data. Each field rename names its model by the model's key in
|
|
119
|
+
* the new schema, after any model rename has been applied.
|
|
103
120
|
*/
|
|
104
121
|
export interface RenameHints {
|
|
105
122
|
readonly models?: readonly {
|
|
@@ -112,6 +129,9 @@ export interface RenameHints {
|
|
|
112
129
|
readonly to: string;
|
|
113
130
|
}[];
|
|
114
131
|
}
|
|
132
|
+
/** Reports how safely a field's type can change from `from` to `to`. The same type
|
|
133
|
+
* in and out is always safe; anything else is looked up in the cast-safety matrix
|
|
134
|
+
* and defaults to `notCastable` when no entry exists. */
|
|
115
135
|
export declare function classifyCast(from: FieldType, to: FieldType): CastSafety;
|
|
116
136
|
/**
|
|
117
137
|
* Diff two serialized schemas into an ordered, expand→contract migration plan.
|
|
@@ -120,56 +140,73 @@ export declare function classifyCast(from: FieldType, to: FieldType): CastSafety
|
|
|
120
140
|
* drop+add.
|
|
121
141
|
*/
|
|
122
142
|
export declare function diffSchema(prev: SchemaJSON | null, next: SchemaJSON, hints?: RenameHints): MigrationStep[];
|
|
143
|
+
/**
|
|
144
|
+
* Why a migration step is flagged as a warning — a change that runs but may lose or
|
|
145
|
+
* risk data on a non-empty table. Each code corresponds to one destructive step
|
|
146
|
+
* kind that {@link classifyMigration} recognizes.
|
|
147
|
+
*/
|
|
123
148
|
export type WarningCode = 'drop_model' | 'drop_field' | 'risky_cast' | 'lossy_recreate' | 'enum_value_removed'
|
|
124
|
-
/** A model
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
* artifact that sandbox readers were served via the registry's sandbox→production
|
|
128
|
-
* fallback. The data plane is untouched — the loss is visibility. */
|
|
149
|
+
/** A model stops being served to readers even though no table is dropped. This is
|
|
150
|
+
* raised when a push is accepted, not by {@link classifyMigration}, and the loss
|
|
151
|
+
* is visibility, not data — the underlying rows are left untouched. */
|
|
129
152
|
| 'remove_model';
|
|
153
|
+
/** Why a migration step is unexecutable — it fails on a non-empty table unless a
|
|
154
|
+
* default or backfill is supplied. Both cases introduce a requirement that existing
|
|
155
|
+
* rows might not satisfy. */
|
|
130
156
|
export type BlockerCode = 'required_field_added' | 'made_required';
|
|
157
|
+
/**
|
|
158
|
+
* One flagged change in a classified migration plan. {@link code} says what kind of
|
|
159
|
+
* risk it is, {@link model} and the optional {@link field} say where, and
|
|
160
|
+
* {@link detail} is a human-readable explanation suitable for showing to a
|
|
161
|
+
* developer.
|
|
162
|
+
*/
|
|
131
163
|
export interface MigrationSignal {
|
|
132
164
|
readonly code: WarningCode | BlockerCode;
|
|
133
165
|
readonly model: string;
|
|
134
166
|
readonly field?: string;
|
|
135
167
|
readonly detail: string;
|
|
136
168
|
/**
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
169
|
+
* Extra context for a removal signal: the previously active schema this push was
|
|
170
|
+
* compared against. Tools use it to show which baseline made the push look
|
|
171
|
+
* incompatible — its version and when it was pushed — so the warning is not a
|
|
172
|
+
* mystery.
|
|
141
173
|
*/
|
|
142
174
|
readonly shadowed?: {
|
|
143
175
|
readonly environment: string;
|
|
144
176
|
readonly version: number;
|
|
145
|
-
/** ISO timestamp the
|
|
177
|
+
/** ISO 8601 timestamp when the compared-against schema was pushed, or null. */
|
|
146
178
|
readonly pushedAt: string | null;
|
|
147
|
-
/** Who pushed
|
|
179
|
+
/** Who pushed the compared-against schema, or null. */
|
|
148
180
|
readonly pushedBy: string | null;
|
|
149
181
|
};
|
|
150
182
|
}
|
|
183
|
+
/** The result of classifying a migration plan: its flagged changes split by
|
|
184
|
+
* severity. Produced by {@link classifyMigration} and read by
|
|
185
|
+
* {@link isAutoApplicable} and {@link unresolvedBlockers}. */
|
|
151
186
|
export interface MigrationClassification {
|
|
152
|
-
/**
|
|
187
|
+
/** Changes that run but may lose or risk data on a non-empty table. */
|
|
153
188
|
readonly warnings: readonly MigrationSignal[];
|
|
154
|
-
/**
|
|
189
|
+
/** Changes that fail on a non-empty table unless a default or backfill is supplied. */
|
|
155
190
|
readonly unexecutable: readonly MigrationSignal[];
|
|
156
191
|
}
|
|
157
192
|
/**
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
* exists
|
|
162
|
-
*
|
|
193
|
+
* Sorts a plan's steps into {@link MigrationClassification.warnings} and
|
|
194
|
+
* {@link MigrationClassification.unexecutable}. Because a step carries no per-field
|
|
195
|
+
* default, adding a required field is treated conservatively as unexecutable — the
|
|
196
|
+
* classifier cannot prove a default exists, so a backfill or default must resolve
|
|
197
|
+
* it. The classification is derived from the schema alone; whoever runs the plan can
|
|
198
|
+
* still downgrade a flagged step to a no-op once it finds the target table is empty.
|
|
163
199
|
*/
|
|
164
200
|
export declare function classifyMigration(steps: readonly MigrationStep[]): MigrationClassification;
|
|
165
|
-
/**
|
|
201
|
+
/** Whether a plan is safe to apply automatically — true when it has no unexecutable
|
|
202
|
+
* steps. Warnings do not block auto-apply; only unexecutable steps do. */
|
|
166
203
|
export declare function isAutoApplicable(classification: MigrationClassification): boolean;
|
|
167
204
|
/**
|
|
168
|
-
* A constant value to
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
* expression
|
|
172
|
-
*
|
|
205
|
+
* A constant value to write into existing rows so an otherwise-unexecutable step can
|
|
206
|
+
* run: a required field added to a non-empty table, or a field made required while
|
|
207
|
+
* some rows hold null. This is intentionally a single constant, not an SQL
|
|
208
|
+
* expression — it covers the common "new column defaults to X" case; anything more
|
|
209
|
+
* elaborate is out of scope.
|
|
173
210
|
*/
|
|
174
211
|
export interface BackfillValue {
|
|
175
212
|
readonly model: string;
|
|
@@ -177,11 +214,12 @@ export interface BackfillValue {
|
|
|
177
214
|
readonly value: string | number | boolean;
|
|
178
215
|
}
|
|
179
216
|
/**
|
|
180
|
-
*
|
|
181
|
-
* blockers
|
|
182
|
-
* data-loss
|
|
217
|
+
* Reports whether a supplied backfill resolves this blocker. Only the two
|
|
218
|
+
* row-dependent blockers — `required_field_added` and `made_required` — can be
|
|
219
|
+
* resolved with a backfill; a data-loss warning cannot, and must be accepted
|
|
220
|
+
* explicitly instead.
|
|
183
221
|
*/
|
|
184
222
|
export declare function isBlockerResolved(signal: MigrationSignal, backfills: readonly BackfillValue[]): boolean;
|
|
185
|
-
/** The unexecutable signals
|
|
186
|
-
*
|
|
223
|
+
/** The unexecutable signals that the supplied backfills do not cover. An empty
|
|
224
|
+
* result means no blocker remains, though any warnings are still gated separately. */
|
|
187
225
|
export declare function unresolvedBlockers(classification: MigrationClassification, backfills: readonly BackfillValue[]): readonly MigrationSignal[];
|
package/dist/schema/diff.js
CHANGED
|
@@ -1,29 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Computes the migration plan that turns one schema into another. Given two
|
|
3
|
+
* serialized schemas — the one currently active and the one being pushed — it
|
|
4
|
+
* produces an ordered list of {@link MigrationStep}s describing how to evolve the
|
|
5
|
+
* database, and a {@link MigrationClassification} that separates the risky parts
|
|
6
|
+
* into warnings (they run, but may lose or risk data on a non-empty table) and
|
|
7
|
+
* unexecutable steps (they fail on a non-empty table unless a backfill or default
|
|
8
|
+
* is supplied). This module only plans: it has no database dependency and emits no
|
|
9
|
+
* SQL, so it can be unit-tested exhaustively and reused by the command-line tools.
|
|
10
|
+
* Turning a step into SQL and running it happens in the host implementation, which
|
|
11
|
+
* owns the column-type mapping and row-security rules.
|
|
3
12
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* (
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
13
|
+
* A few design choices worth knowing about:
|
|
14
|
+
* - Renames are supplied as data through {@link RenameHints}, not guessed. Without
|
|
15
|
+
* a hint, a removed field plus an added field reads as a drop followed by an add,
|
|
16
|
+
* which is the safe (lossy) default; a hint tells the planner they are the same
|
|
17
|
+
* field under a new name.
|
|
18
|
+
* - Destructive changes fall into two tiers — warnings versus unexecutable — and a
|
|
19
|
+
* type change carries its own sub-tier ({@link CastSafety}: safe, risky, or not
|
|
20
|
+
* castable) that decides between an in-place `ALTER COLUMN … TYPE` and a lossy
|
|
21
|
+
* drop-and-recreate.
|
|
22
|
+
* - A single {@link FieldChanges} value records which facets of a column changed
|
|
23
|
+
* (type, nullability, enum values, index) so one `alter_field` step covers them
|
|
24
|
+
* all instead of several separate steps.
|
|
11
25
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* - **Prisma migration engine**: a two-tier destructive classification
|
|
17
|
-
* (warning vs unexecutable) and a type-change sub-tier
|
|
18
|
-
* (safe / risky / not-castable) that decides in-place `ALTER TYPE` vs a
|
|
19
|
-
* lossy drop-and-recreate.
|
|
20
|
-
* - **Atlas**: a single `alter_field` step carrying *which* facets changed
|
|
21
|
-
* (type / nullability / enum / index) instead of N discrete alter steps.
|
|
22
|
-
*
|
|
23
|
-
* Step ordering is the expand→contract sequence (add before drop, widen before
|
|
24
|
-
* narrow): create models → rename → add columns (always nullable) → alter →
|
|
25
|
-
* drop columns → drop models. NOT NULL is never set on add — it is an
|
|
26
|
-
* `alter_field` nullability change that a backfill must precede.
|
|
26
|
+
* Steps come back in expand-then-contract order — add before drop, widen before
|
|
27
|
+
* narrow: create models, rename, add columns (always nullable), alter, drop columns,
|
|
28
|
+
* drop models. A newly added column is never created `NOT NULL`; making a column
|
|
29
|
+
* required is a separate nullability change that a backfill must run before.
|
|
27
30
|
*/
|
|
28
31
|
// ── Cast safety matrix ────────────────────────────────────────────────────────
|
|
29
32
|
// Keyed `${from}->${to}` over the 6 sync field types. Targets that map to TEXT
|
|
@@ -50,6 +53,9 @@ const CAST = {
|
|
|
50
53
|
'string->json': 'risky', 'enum->json': 'risky', 'number->json': 'notCastable',
|
|
51
54
|
'boolean->json': 'notCastable', 'date->json': 'notCastable',
|
|
52
55
|
};
|
|
56
|
+
/** Reports how safely a field's type can change from `from` to `to`. The same type
|
|
57
|
+
* in and out is always safe; anything else is looked up in the cast-safety matrix
|
|
58
|
+
* and defaults to `notCastable` when no entry exists. */
|
|
53
59
|
export function classifyCast(from, to) {
|
|
54
60
|
if (from === to)
|
|
55
61
|
return 'safe';
|
|
@@ -197,11 +203,12 @@ export function diffSchema(prev, next, hints = {}) {
|
|
|
197
203
|
return [...creates, ...renames, ...fieldSteps, ...drops];
|
|
198
204
|
}
|
|
199
205
|
/**
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
* exists
|
|
204
|
-
*
|
|
206
|
+
* Sorts a plan's steps into {@link MigrationClassification.warnings} and
|
|
207
|
+
* {@link MigrationClassification.unexecutable}. Because a step carries no per-field
|
|
208
|
+
* default, adding a required field is treated conservatively as unexecutable — the
|
|
209
|
+
* classifier cannot prove a default exists, so a backfill or default must resolve
|
|
210
|
+
* it. The classification is derived from the schema alone; whoever runs the plan can
|
|
211
|
+
* still downgrade a flagged step to a no-op once it finds the target table is empty.
|
|
205
212
|
*/
|
|
206
213
|
export function classifyMigration(steps) {
|
|
207
214
|
const warnings = [];
|
|
@@ -259,22 +266,24 @@ export function classifyMigration(steps) {
|
|
|
259
266
|
}
|
|
260
267
|
return { warnings, unexecutable };
|
|
261
268
|
}
|
|
262
|
-
/**
|
|
269
|
+
/** Whether a plan is safe to apply automatically — true when it has no unexecutable
|
|
270
|
+
* steps. Warnings do not block auto-apply; only unexecutable steps do. */
|
|
263
271
|
export function isAutoApplicable(classification) {
|
|
264
272
|
return classification.unexecutable.length === 0;
|
|
265
273
|
}
|
|
266
274
|
/**
|
|
267
|
-
*
|
|
268
|
-
* blockers
|
|
269
|
-
* data-loss
|
|
275
|
+
* Reports whether a supplied backfill resolves this blocker. Only the two
|
|
276
|
+
* row-dependent blockers — `required_field_added` and `made_required` — can be
|
|
277
|
+
* resolved with a backfill; a data-loss warning cannot, and must be accepted
|
|
278
|
+
* explicitly instead.
|
|
270
279
|
*/
|
|
271
280
|
export function isBlockerResolved(signal, backfills) {
|
|
272
281
|
if (signal.code !== 'required_field_added' && signal.code !== 'made_required')
|
|
273
282
|
return false;
|
|
274
283
|
return backfills.some((b) => b.model === signal.model && b.field === signal.field);
|
|
275
284
|
}
|
|
276
|
-
/** The unexecutable signals
|
|
277
|
-
*
|
|
285
|
+
/** The unexecutable signals that the supplied backfills do not cover. An empty
|
|
286
|
+
* result means no blocker remains, though any warnings are still gated separately. */
|
|
278
287
|
export function unresolvedBlockers(classification, backfills) {
|
|
279
288
|
return classification.unexecutable.filter((s) => !isBlockerResolved(s, backfills));
|
|
280
289
|
}
|
package/dist/schema/field.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* survives `.optional()`, `.nullable()`, and `.default()`
|
|
2
|
+
* Field builders for schema definitions. Each helper — {@link field}.string(),
|
|
3
|
+
* .number(), .enum(), and so on — returns an ordinary Zod schema with a little
|
|
4
|
+
* sync-engine metadata attached (its type tag and whether it is indexed) plus a
|
|
5
|
+
* couple of chainable methods. The metadata is tucked into the schema's description
|
|
6
|
+
* as a JSON string so it survives `.optional()`, `.nullable()`, and `.default()`
|
|
7
|
+
* chaining, and {@link resolveFieldMeta} reads it back out as a {@link FieldMeta}.
|
|
7
8
|
*
|
|
8
9
|
* Usage:
|
|
9
10
|
* import { field } from '@abloatai/ablo/schema';
|
|
@@ -23,9 +24,11 @@
|
|
|
23
24
|
* });
|
|
24
25
|
*/
|
|
25
26
|
import { z } from 'zod';
|
|
26
|
-
/**
|
|
27
|
+
/** The sync-engine metadata describing one field, available at runtime through a
|
|
28
|
+
* model's `fields` map. The {@link field} builders attach it, and the migration
|
|
29
|
+
* planner, type generator, and OpenAPI generator all read it. */
|
|
27
30
|
export interface FieldMeta {
|
|
28
|
-
/** Sync-engine type tag
|
|
31
|
+
/** Sync-engine type tag, which maps to storage and serialization hints. */
|
|
29
32
|
type: 'string' | 'number' | 'boolean' | 'date' | 'enum' | 'json';
|
|
30
33
|
/** Whether the field was marked optional via `.optional()` or `.nullable()`. */
|
|
31
34
|
isOptional: boolean;
|
|
@@ -48,53 +51,44 @@ export interface FieldMeta {
|
|
|
48
51
|
*/
|
|
49
52
|
export declare function getFieldMeta(schema: z.ZodType): FieldMeta | null;
|
|
50
53
|
/**
|
|
51
|
-
*
|
|
52
|
-
* `
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* the sync-engine type tag. Used by `resolveFieldMeta` and by
|
|
57
|
-
* `model()` / `query()` at definition time.
|
|
58
|
-
*
|
|
59
|
-
* Kept as an internal helper rather than exported directly — the
|
|
60
|
-
* public API is `resolveFieldMeta`, which combines this fallback
|
|
61
|
-
* with the `getFieldMeta` fast path.
|
|
54
|
+
* Infers a {@link FieldMeta} from a plain Zod schema that carries no field-builder
|
|
55
|
+
* metadata — for example a bare `z.string()`. It unwraps `.optional()`,
|
|
56
|
+
* `.nullable()`, and `.default()` to reach the inner type, then maps that Zod type
|
|
57
|
+
* to a sync-engine type tag. Most callers should use {@link resolveFieldMeta}
|
|
58
|
+
* instead, which tries the attached metadata first and falls back to this.
|
|
62
59
|
*/
|
|
63
60
|
export declare function inferFieldMetaFromZod(schema: z.ZodType): FieldMeta;
|
|
64
61
|
/**
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* me its sync-engine type tag and optionality." Both `model()` and
|
|
71
|
-
* `query()` use it to populate their `fields` / `inputFields` maps at
|
|
72
|
-
* definition time, and the schema serializer reads those maps at
|
|
73
|
-
* serialization time.
|
|
62
|
+
* Resolves a {@link FieldMeta} for any Zod schema, whether it was built with a
|
|
63
|
+
* {@link field} builder (which attaches metadata) or with plain Zod (which needs
|
|
64
|
+
* inference). This is the single entry point for "given a Zod field, tell me its
|
|
65
|
+
* sync-engine type tag and whether it is optional"; the model and query builders use
|
|
66
|
+
* it to populate their field maps, and the serializer reads those maps.
|
|
74
67
|
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
* the existing behavior that was previously duplicated in
|
|
78
|
-
* `model.ts:inferMetaFromZod`.
|
|
68
|
+
* It always returns a value and never returns null. A Zod type it does not recognize
|
|
69
|
+
* falls through to the `string` tag by design.
|
|
79
70
|
*/
|
|
80
71
|
export declare function resolveFieldMeta(schema: z.ZodType): FieldMeta;
|
|
72
|
+
/** A Zod schema returned by a {@link field} builder — the underlying Zod type plus
|
|
73
|
+
* two chainable methods: `indexed()` marks the field for a database index, and
|
|
74
|
+
* `from(column)` overrides the physical column name it maps to. */
|
|
81
75
|
export type FieldBuilder<T extends z.ZodType> = T & {
|
|
82
76
|
indexed(): FieldBuilder<T>;
|
|
83
77
|
from(column: string): FieldBuilder<T>;
|
|
84
78
|
};
|
|
85
79
|
export declare const field: {
|
|
86
|
-
/**
|
|
80
|
+
/** Defines a text field. */
|
|
87
81
|
readonly string: () => FieldBuilder<z.ZodString>;
|
|
88
|
-
/**
|
|
82
|
+
/** Defines a numeric field. */
|
|
89
83
|
readonly number: () => FieldBuilder<z.ZodNumber>;
|
|
90
|
-
/**
|
|
84
|
+
/** Defines a true/false field. */
|
|
91
85
|
readonly boolean: () => FieldBuilder<z.ZodBoolean>;
|
|
92
|
-
/**
|
|
86
|
+
/** Defines a timestamp field, represented as a JavaScript `Date`. */
|
|
93
87
|
readonly date: () => FieldBuilder<z.ZodDate>;
|
|
94
|
-
/**
|
|
88
|
+
/** Defines a field constrained to a fixed set of string values. */
|
|
95
89
|
readonly enum: <const T extends readonly [string, ...string[]]>(values: T) => FieldBuilder<z.ZodEnum<{ [k_1 in T[number]]: k_1; } extends infer T_1 ? { [k in keyof T_1]: T_1[k]; } : never>>;
|
|
96
90
|
/**
|
|
97
|
-
* JSON field
|
|
91
|
+
* Defines a JSON field, with three call shapes:
|
|
98
92
|
*
|
|
99
93
|
* ```ts
|
|
100
94
|
* field.json() // unknown JSON blob
|
|
@@ -102,9 +96,9 @@ export declare const field: {
|
|
|
102
96
|
* field.json({ icon: z.string().default('default') }) // typed sub-properties with defaults
|
|
103
97
|
* ```
|
|
104
98
|
*
|
|
105
|
-
* The third form is
|
|
106
|
-
*
|
|
107
|
-
*
|
|
99
|
+
* The third form is especially handy for metadata fields. It wraps the plain
|
|
100
|
+
* object in `z.object()` automatically, and the model runtime adds a
|
|
101
|
+
* `${field}Json` getter that parses the JSON string on read, applies the Zod
|
|
108
102
|
* defaults, and caches the result.
|
|
109
103
|
*
|
|
110
104
|
* Example:
|
|
@@ -124,8 +118,9 @@ export declare const field: {
|
|
|
124
118
|
* ```
|
|
125
119
|
*/
|
|
126
120
|
readonly json: <T extends z.ZodType = z.ZodUnknown>(schemaOrShape?: T | z.ZodRawShape) => FieldBuilder<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
|
|
127
|
-
/**
|
|
121
|
+
/** Defines an indexed text field — shorthand for `field.string().indexed()`. */
|
|
128
122
|
readonly id: () => FieldBuilder<z.ZodString>;
|
|
129
123
|
};
|
|
130
|
-
/**
|
|
124
|
+
/** Marks a Zod schema as indexed so lookups on it use a database index. This is the
|
|
125
|
+
* standalone-function form of the `.indexed()` chain method. */
|
|
131
126
|
export declare function indexed<T extends z.ZodType>(schema: T): T;
|