@vibesdotdev/storage 0.0.1
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/README.md +75 -0
- package/SPEC.md +60 -0
- package/dist/adapters/index.d.ts +14 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +15 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/bridge/index.d.ts +3 -0
- package/dist/bridge/index.d.ts.map +1 -0
- package/dist/bridge/index.js +2 -0
- package/dist/bridge/index.js.map +1 -0
- package/dist/bridge/storage-kind-bridge.d.ts +27 -0
- package/dist/bridge/storage-kind-bridge.d.ts.map +1 -0
- package/dist/bridge/storage-kind-bridge.js +110 -0
- package/dist/bridge/storage-kind-bridge.js.map +1 -0
- package/dist/bridge/types.d.ts +45 -0
- package/dist/bridge/types.d.ts.map +1 -0
- package/dist/bridge/types.js +8 -0
- package/dist/bridge/types.js.map +1 -0
- package/dist/cli/commands/list/storage.list.cli-command.descriptor.d.ts +4 -0
- package/dist/cli/commands/list/storage.list.cli-command.descriptor.d.ts.map +1 -0
- package/dist/cli/commands/list/storage.list.cli-command.descriptor.js +18 -0
- package/dist/cli/commands/list/storage.list.cli-command.descriptor.js.map +1 -0
- package/dist/cli/commands/list/storage.list.cli-command.impl.d.ts +11 -0
- package/dist/cli/commands/list/storage.list.cli-command.impl.d.ts.map +1 -0
- package/dist/cli/commands/list/storage.list.cli-command.impl.js +48 -0
- package/dist/cli/commands/list/storage.list.cli-command.impl.js.map +1 -0
- package/dist/cli/commands/sync/pull/storage.sync.pull.cli-command.descriptor.d.ts +4 -0
- package/dist/cli/commands/sync/pull/storage.sync.pull.cli-command.descriptor.d.ts.map +1 -0
- package/dist/cli/commands/sync/pull/storage.sync.pull.cli-command.descriptor.js +26 -0
- package/dist/cli/commands/sync/pull/storage.sync.pull.cli-command.descriptor.js.map +1 -0
- package/dist/cli/commands/sync/pull/storage.sync.pull.cli-command.impl.d.ts +13 -0
- package/dist/cli/commands/sync/pull/storage.sync.pull.cli-command.impl.d.ts.map +1 -0
- package/dist/cli/commands/sync/pull/storage.sync.pull.cli-command.impl.js +136 -0
- package/dist/cli/commands/sync/pull/storage.sync.pull.cli-command.impl.js.map +1 -0
- package/dist/cli/commands/sync/push/storage.sync.push.cli-command.descriptor.d.ts +4 -0
- package/dist/cli/commands/sync/push/storage.sync.push.cli-command.descriptor.d.ts.map +1 -0
- package/dist/cli/commands/sync/push/storage.sync.push.cli-command.descriptor.js +26 -0
- package/dist/cli/commands/sync/push/storage.sync.push.cli-command.descriptor.js.map +1 -0
- package/dist/cli/commands/sync/push/storage.sync.push.cli-command.impl.d.ts +13 -0
- package/dist/cli/commands/sync/push/storage.sync.push.cli-command.impl.d.ts.map +1 -0
- package/dist/cli/commands/sync/push/storage.sync.push.cli-command.impl.js +165 -0
- package/dist/cli/commands/sync/push/storage.sync.push.cli-command.impl.js.map +1 -0
- package/dist/cli/commands/sync/resolve/storage.sync.resolve.cli-command.descriptor.d.ts +4 -0
- package/dist/cli/commands/sync/resolve/storage.sync.resolve.cli-command.descriptor.d.ts.map +1 -0
- package/dist/cli/commands/sync/resolve/storage.sync.resolve.cli-command.descriptor.js +20 -0
- package/dist/cli/commands/sync/resolve/storage.sync.resolve.cli-command.descriptor.js.map +1 -0
- package/dist/cli/commands/sync/resolve/storage.sync.resolve.cli-command.impl.d.ts +12 -0
- package/dist/cli/commands/sync/resolve/storage.sync.resolve.cli-command.impl.d.ts.map +1 -0
- package/dist/cli/commands/sync/resolve/storage.sync.resolve.cli-command.impl.js +95 -0
- package/dist/cli/commands/sync/resolve/storage.sync.resolve.cli-command.impl.js.map +1 -0
- package/dist/cli/commands/sync/status/storage.sync.status.cli-command.descriptor.d.ts +4 -0
- package/dist/cli/commands/sync/status/storage.sync.status.cli-command.descriptor.d.ts.map +1 -0
- package/dist/cli/commands/sync/status/storage.sync.status.cli-command.descriptor.js +15 -0
- package/dist/cli/commands/sync/status/storage.sync.status.cli-command.descriptor.js.map +1 -0
- package/dist/cli/commands/sync/status/storage.sync.status.cli-command.impl.d.ts +13 -0
- package/dist/cli/commands/sync/status/storage.sync.status.cli-command.impl.d.ts.map +1 -0
- package/dist/cli/commands/sync/status/storage.sync.status.cli-command.impl.js +150 -0
- package/dist/cli/commands/sync/status/storage.sync.status.cli-command.impl.js.map +1 -0
- package/dist/cli/context.consumer.d.ts +26 -0
- package/dist/cli/context.consumer.d.ts.map +1 -0
- package/dist/cli/context.consumer.js +164 -0
- package/dist/cli/context.consumer.js.map +1 -0
- package/dist/cli/storage.cli-group.descriptor.d.ts +4 -0
- package/dist/cli/storage.cli-group.descriptor.d.ts.map +1 -0
- package/dist/cli/storage.cli-group.descriptor.js +11 -0
- package/dist/cli/storage.cli-group.descriptor.js.map +1 -0
- package/dist/cli/storage.sync.cli-group.descriptor.d.ts +4 -0
- package/dist/cli/storage.sync.cli-group.descriptor.d.ts.map +1 -0
- package/dist/cli/storage.sync.cli-group.descriptor.js +12 -0
- package/dist/cli/storage.sync.cli-group.descriptor.js.map +1 -0
- package/dist/cli/types.d.ts +26 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.js +11 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/client/index.d.ts +10 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +10 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/list-browsable-adapters.d.ts +31 -0
- package/dist/client/list-browsable-adapters.d.ts.map +1 -0
- package/dist/client/list-browsable-adapters.js +40 -0
- package/dist/client/list-browsable-adapters.js.map +1 -0
- package/dist/daemon/commands/sync.d.ts +23 -0
- package/dist/daemon/commands/sync.d.ts.map +1 -0
- package/dist/daemon/commands/sync.js +169 -0
- package/dist/daemon/commands/sync.js.map +1 -0
- package/dist/docs/adapters.docs.descriptor.d.ts +4 -0
- package/dist/docs/adapters.docs.descriptor.d.ts.map +1 -0
- package/dist/docs/adapters.docs.descriptor.js +223 -0
- package/dist/docs/adapters.docs.descriptor.js.map +1 -0
- package/dist/docs/manifests.docs.descriptor.d.ts +4 -0
- package/dist/docs/manifests.docs.descriptor.d.ts.map +1 -0
- package/dist/docs/manifests.docs.descriptor.js +316 -0
- package/dist/docs/manifests.docs.descriptor.js.map +1 -0
- package/dist/docs/records.docs.descriptor.d.ts +4 -0
- package/dist/docs/records.docs.descriptor.d.ts.map +1 -0
- package/dist/docs/records.docs.descriptor.js +269 -0
- package/dist/docs/records.docs.descriptor.js.map +1 -0
- package/dist/docs/sync.docs.descriptor.d.ts +4 -0
- package/dist/docs/sync.docs.descriptor.d.ts.map +1 -0
- package/dist/docs/sync.docs.descriptor.js +279 -0
- package/dist/docs/sync.docs.descriptor.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/adapter.d.ts +382 -0
- package/dist/interfaces/adapter.d.ts.map +1 -0
- package/dist/interfaces/adapter.js +11 -0
- package/dist/interfaces/adapter.js.map +1 -0
- package/dist/interfaces/document-store.d.ts +62 -0
- package/dist/interfaces/document-store.d.ts.map +1 -0
- package/dist/interfaces/document-store.js +8 -0
- package/dist/interfaces/document-store.js.map +1 -0
- package/dist/interfaces/index.d.ts +17 -0
- package/dist/interfaces/index.d.ts.map +1 -0
- package/dist/interfaces/index.js +24 -0
- package/dist/interfaces/index.js.map +1 -0
- package/dist/interfaces/key-value.d.ts +95 -0
- package/dist/interfaces/key-value.d.ts.map +1 -0
- package/dist/interfaces/key-value.js +8 -0
- package/dist/interfaces/key-value.js.map +1 -0
- package/dist/interfaces/query-builder.d.ts +31 -0
- package/dist/interfaces/query-builder.d.ts.map +1 -0
- package/dist/interfaces/query-builder.js +11 -0
- package/dist/interfaces/query-builder.js.map +1 -0
- package/dist/interfaces/record/index.d.ts +7 -0
- package/dist/interfaces/record/index.d.ts.map +1 -0
- package/dist/interfaces/record/index.js +7 -0
- package/dist/interfaces/record/index.js.map +1 -0
- package/dist/interfaces/record/interface.d.ts +593 -0
- package/dist/interfaces/record/interface.d.ts.map +1 -0
- package/dist/interfaces/record/interface.js +49 -0
- package/dist/interfaces/record/interface.js.map +1 -0
- package/dist/interfaces/repository.d.ts +262 -0
- package/dist/interfaces/repository.d.ts.map +1 -0
- package/dist/interfaces/repository.js +8 -0
- package/dist/interfaces/repository.js.map +1 -0
- package/dist/interfaces/schema/index.d.ts +8 -0
- package/dist/interfaces/schema/index.d.ts.map +1 -0
- package/dist/interfaces/schema/index.js +10 -0
- package/dist/interfaces/schema/index.js.map +1 -0
- package/dist/interfaces/schema/schema-interface.d.ts +516 -0
- package/dist/interfaces/schema/schema-interface.d.ts.map +1 -0
- package/dist/interfaces/schema/schema-interface.js +31 -0
- package/dist/interfaces/schema/schema-interface.js.map +1 -0
- package/dist/interfaces/schema/table-interface.d.ts +250 -0
- package/dist/interfaces/schema/table-interface.d.ts.map +1 -0
- package/dist/interfaces/schema/table-interface.js +31 -0
- package/dist/interfaces/schema/table-interface.js.map +1 -0
- package/dist/interfaces/storage-consumer-fs.d.ts +40 -0
- package/dist/interfaces/storage-consumer-fs.d.ts.map +1 -0
- package/dist/interfaces/storage-consumer-fs.js +42 -0
- package/dist/interfaces/storage-consumer-fs.js.map +1 -0
- package/dist/manifest/base.d.ts +187 -0
- package/dist/manifest/base.d.ts.map +1 -0
- package/dist/manifest/base.js +516 -0
- package/dist/manifest/base.js.map +1 -0
- package/dist/manifest/cloud-sync.consumer.d.ts +7 -0
- package/dist/manifest/cloud-sync.consumer.d.ts.map +1 -0
- package/dist/manifest/cloud-sync.consumer.js +82 -0
- package/dist/manifest/cloud-sync.consumer.js.map +1 -0
- package/dist/manifest/index.d.ts +7 -0
- package/dist/manifest/index.d.ts.map +1 -0
- package/dist/manifest/index.js +7 -0
- package/dist/manifest/index.js.map +1 -0
- package/dist/manifest/source-policy.d.ts +8 -0
- package/dist/manifest/source-policy.d.ts.map +1 -0
- package/dist/manifest/source-policy.js +62 -0
- package/dist/manifest/source-policy.js.map +1 -0
- package/dist/paths.d.ts +6 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +152 -0
- package/dist/paths.js.map +1 -0
- package/dist/policy/context.d.ts +9 -0
- package/dist/policy/context.d.ts.map +1 -0
- package/dist/policy/context.js +29 -0
- package/dist/policy/context.js.map +1 -0
- package/dist/policy/index.d.ts +4 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/index.js +4 -0
- package/dist/policy/index.js.map +1 -0
- package/dist/policy/overrides.d.ts +40 -0
- package/dist/policy/overrides.d.ts.map +1 -0
- package/dist/policy/overrides.js +37 -0
- package/dist/policy/overrides.js.map +1 -0
- package/dist/policy/persistence.d.ts +38 -0
- package/dist/policy/persistence.d.ts.map +1 -0
- package/dist/policy/persistence.js +65 -0
- package/dist/policy/persistence.js.map +1 -0
- package/dist/policy/types.d.ts +21 -0
- package/dist/policy/types.d.ts.map +1 -0
- package/dist/policy/types.js +7 -0
- package/dist/policy/types.js.map +1 -0
- package/dist/record/base.d.ts +186 -0
- package/dist/record/base.d.ts.map +1 -0
- package/dist/record/base.js +1437 -0
- package/dist/record/base.js.map +1 -0
- package/dist/record/events.d.ts +71 -0
- package/dist/record/events.d.ts.map +1 -0
- package/dist/record/events.js +52 -0
- package/dist/record/events.js.map +1 -0
- package/dist/record/extensions.d.ts +51 -0
- package/dist/record/extensions.d.ts.map +1 -0
- package/dist/record/extensions.js +222 -0
- package/dist/record/extensions.js.map +1 -0
- package/dist/record/index.d.ts +7 -0
- package/dist/record/index.d.ts.map +1 -0
- package/dist/record/index.js +7 -0
- package/dist/record/index.js.map +1 -0
- package/dist/resolver/storage-backed-resolver.d.ts +23 -0
- package/dist/resolver/storage-backed-resolver.d.ts.map +1 -0
- package/dist/resolver/storage-backed-resolver.js +187 -0
- package/dist/resolver/storage-backed-resolver.js.map +1 -0
- package/dist/schemas/adapter-descriptor.d.ts +108 -0
- package/dist/schemas/adapter-descriptor.d.ts.map +1 -0
- package/dist/schemas/adapter-descriptor.js +101 -0
- package/dist/schemas/adapter-descriptor.js.map +1 -0
- package/dist/schemas/index.d.ts +14 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +12 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/manifest-descriptor.d.ts +110 -0
- package/dist/schemas/manifest-descriptor.d.ts.map +1 -0
- package/dist/schemas/manifest-descriptor.js +114 -0
- package/dist/schemas/manifest-descriptor.js.map +1 -0
- package/dist/schemas/record/descriptor.d.ts +570 -0
- package/dist/schemas/record/descriptor.d.ts.map +1 -0
- package/dist/schemas/record/descriptor.js +389 -0
- package/dist/schemas/record/descriptor.js.map +1 -0
- package/dist/schemas/record/index.d.ts +8 -0
- package/dist/schemas/record/index.d.ts.map +1 -0
- package/dist/schemas/record/index.js +7 -0
- package/dist/schemas/record/index.js.map +1 -0
- package/dist/schemas/record/relation.d.ts +36 -0
- package/dist/schemas/record/relation.d.ts.map +1 -0
- package/dist/schemas/record/relation.js +37 -0
- package/dist/schemas/record/relation.js.map +1 -0
- package/dist/schemas/schema/descriptor.d.ts +231 -0
- package/dist/schemas/schema/descriptor.d.ts.map +1 -0
- package/dist/schemas/schema/descriptor.js +205 -0
- package/dist/schemas/schema/descriptor.js.map +1 -0
- package/dist/schemas/schema/index.d.ts +7 -0
- package/dist/schemas/schema/index.d.ts.map +1 -0
- package/dist/schemas/schema/index.js +7 -0
- package/dist/schemas/schema/index.js.map +1 -0
- package/dist/schemas/sync-bridge-descriptor.d.ts +124 -0
- package/dist/schemas/sync-bridge-descriptor.d.ts.map +1 -0
- package/dist/schemas/sync-bridge-descriptor.js +67 -0
- package/dist/schemas/sync-bridge-descriptor.js.map +1 -0
- package/dist/server/manifest-route.d.ts +92 -0
- package/dist/server/manifest-route.d.ts.map +1 -0
- package/dist/server/manifest-route.js +226 -0
- package/dist/server/manifest-route.js.map +1 -0
- package/dist/storage-policy.context.descriptor.d.ts +16 -0
- package/dist/storage-policy.context.descriptor.d.ts.map +1 -0
- package/dist/storage-policy.context.descriptor.js +16 -0
- package/dist/storage-policy.context.descriptor.js.map +1 -0
- package/dist/storage-policy.context.server.d.ts +14 -0
- package/dist/storage-policy.context.server.d.ts.map +1 -0
- package/dist/storage-policy.context.server.js +27 -0
- package/dist/storage-policy.context.server.js.map +1 -0
- package/dist/storage.plugin.d.ts +38 -0
- package/dist/storage.plugin.d.ts.map +1 -0
- package/dist/storage.plugin.js +204 -0
- package/dist/storage.plugin.js.map +1 -0
- package/dist/sync/cloud-pull.d.ts +15 -0
- package/dist/sync/cloud-pull.d.ts.map +1 -0
- package/dist/sync/cloud-pull.js +130 -0
- package/dist/sync/cloud-pull.js.map +1 -0
- package/dist/sync/cloud-record-crud-config.d.ts +19 -0
- package/dist/sync/cloud-record-crud-config.d.ts.map +1 -0
- package/dist/sync/cloud-record-crud-config.js +22 -0
- package/dist/sync/cloud-record-crud-config.js.map +1 -0
- package/dist/sync/record-sync-bridge.d.ts +5 -0
- package/dist/sync/record-sync-bridge.d.ts.map +1 -0
- package/dist/sync/record-sync-bridge.js +121 -0
- package/dist/sync/record-sync-bridge.js.map +1 -0
- package/dist/sync/resolve-sync-target.d.ts +23 -0
- package/dist/sync/resolve-sync-target.d.ts.map +1 -0
- package/dist/sync/resolve-sync-target.js +45 -0
- package/dist/sync/resolve-sync-target.js.map +1 -0
- package/dist/sync/schemas/cloud-pull.d.ts +25 -0
- package/dist/sync/schemas/cloud-pull.d.ts.map +1 -0
- package/dist/sync/schemas/cloud-pull.js +7 -0
- package/dist/sync/schemas/cloud-pull.js.map +1 -0
- package/dist/sync/schemas/index.d.ts +9 -0
- package/dist/sync/schemas/index.d.ts.map +1 -0
- package/dist/sync/schemas/index.js +9 -0
- package/dist/sync/schemas/index.js.map +1 -0
- package/dist/sync/schemas/sync-helpers.d.ts +17 -0
- package/dist/sync/schemas/sync-helpers.d.ts.map +1 -0
- package/dist/sync/schemas/sync-helpers.js +7 -0
- package/dist/sync/schemas/sync-helpers.js.map +1 -0
- package/dist/sync/schemas/sync-state.d.ts +65 -0
- package/dist/sync/schemas/sync-state.d.ts.map +1 -0
- package/dist/sync/schemas/sync-state.js +32 -0
- package/dist/sync/schemas/sync-state.js.map +1 -0
- package/dist/sync/sync-bridge.d.ts +80 -0
- package/dist/sync/sync-bridge.d.ts.map +1 -0
- package/dist/sync/sync-bridge.js +617 -0
- package/dist/sync/sync-bridge.js.map +1 -0
- package/dist/sync/sync-manifest.d.ts +20 -0
- package/dist/sync/sync-manifest.d.ts.map +1 -0
- package/dist/sync/sync-manifest.js +140 -0
- package/dist/sync/sync-manifest.js.map +1 -0
- package/dist/sync/sync-state.consumer.d.ts +23 -0
- package/dist/sync/sync-state.consumer.d.ts.map +1 -0
- package/dist/sync/sync-state.consumer.js +111 -0
- package/dist/sync/sync-state.consumer.js.map +1 -0
- package/dist/transform/index.d.ts +75 -0
- package/dist/transform/index.d.ts.map +1 -0
- package/dist/transform/index.js +81 -0
- package/dist/transform/index.js.map +1 -0
- package/dist/transform/transform-descriptor.d.ts +51 -0
- package/dist/transform/transform-descriptor.d.ts.map +1 -0
- package/dist/transform/transform-descriptor.js +30 -0
- package/dist/transform/transform-descriptor.js.map +1 -0
- package/dist/tui/storage-explorer.descriptor.d.ts +14 -0
- package/dist/tui/storage-explorer.descriptor.d.ts.map +1 -0
- package/dist/tui/storage-explorer.descriptor.js +29 -0
- package/dist/tui/storage-explorer.descriptor.js.map +1 -0
- package/dist/tui/storage-explorer.impl.consumer.d.ts +11 -0
- package/dist/tui/storage-explorer.impl.consumer.d.ts.map +1 -0
- package/dist/tui/storage-explorer.impl.consumer.js +13 -0
- package/dist/tui/storage-explorer.impl.consumer.js.map +1 -0
- package/dist/tui/storage-open.descriptor.d.ts +14 -0
- package/dist/tui/storage-open.descriptor.d.ts.map +1 -0
- package/dist/tui/storage-open.descriptor.js +28 -0
- package/dist/tui/storage-open.descriptor.js.map +1 -0
- package/dist/tui/storage-open.impl.consumer.d.ts +11 -0
- package/dist/tui/storage-open.impl.consumer.d.ts.map +1 -0
- package/dist/tui/storage-open.impl.consumer.js +13 -0
- package/dist/tui/storage-open.impl.consumer.js.map +1 -0
- package/dist/utils/error-context.d.ts +2 -0
- package/dist/utils/error-context.d.ts.map +1 -0
- package/dist/utils/error-context.js +17 -0
- package/dist/utils/error-context.js.map +1 -0
- package/package.json +241 -0
- package/src/adapters/index.ts +13 -0
- package/src/bridge/index.ts +2 -0
- package/src/bridge/storage-kind-bridge.ts +131 -0
- package/src/bridge/types.ts +46 -0
- package/src/cli/commands/list/storage.list.cli-command.descriptor.ts +20 -0
- package/src/cli/commands/list/storage.list.cli-command.impl.ts +72 -0
- package/src/cli/commands/sync/pull/storage.sync.pull.cli-command.descriptor.ts +28 -0
- package/src/cli/commands/sync/pull/storage.sync.pull.cli-command.impl.ts +171 -0
- package/src/cli/commands/sync/push/storage.sync.push.cli-command.descriptor.ts +28 -0
- package/src/cli/commands/sync/push/storage.sync.push.cli-command.impl.ts +213 -0
- package/src/cli/commands/sync/resolve/storage.sync.resolve.cli-command.descriptor.ts +22 -0
- package/src/cli/commands/sync/resolve/storage.sync.resolve.cli-command.impl.ts +129 -0
- package/src/cli/commands/sync/status/storage.sync.status.cli-command.descriptor.ts +17 -0
- package/src/cli/commands/sync/status/storage.sync.status.cli-command.impl.ts +192 -0
- package/src/cli/context.consumer.ts +195 -0
- package/src/cli/storage.cli-group.descriptor.ts +13 -0
- package/src/cli/storage.sync.cli-group.descriptor.ts +14 -0
- package/src/cli/types.ts +25 -0
- package/src/client/index.ts +10 -0
- package/src/client/list-browsable-adapters.ts +42 -0
- package/src/daemon/commands/sync.ts +225 -0
- package/src/docs/adapters.docs.descriptor.ts +225 -0
- package/src/docs/manifests.docs.descriptor.ts +318 -0
- package/src/docs/records.docs.descriptor.ts +271 -0
- package/src/docs/sync.docs.descriptor.ts +281 -0
- package/src/index.ts +109 -0
- package/src/interfaces/adapter.ts +451 -0
- package/src/interfaces/document-store.ts +74 -0
- package/src/interfaces/index.ts +117 -0
- package/src/interfaces/key-value.ts +112 -0
- package/src/interfaces/query-builder.ts +31 -0
- package/src/interfaces/record/index.ts +58 -0
- package/src/interfaces/record/interface.ts +723 -0
- package/src/interfaces/repository.ts +300 -0
- package/src/interfaces/schema/index.ts +37 -0
- package/src/interfaces/schema/schema-interface.ts +586 -0
- package/src/interfaces/schema/table-interface.ts +314 -0
- package/src/interfaces/storage-consumer-fs.ts +66 -0
- package/src/manifest/base.ts +594 -0
- package/src/manifest/cloud-sync.consumer.ts +120 -0
- package/src/manifest/index.ts +7 -0
- package/src/manifest/source-policy.ts +74 -0
- package/src/paths.ts +171 -0
- package/src/policy/context.ts +30 -0
- package/src/policy/index.ts +20 -0
- package/src/policy/overrides.ts +46 -0
- package/src/policy/persistence.ts +117 -0
- package/src/policy/types.ts +28 -0
- package/src/record/base.ts +1872 -0
- package/src/record/events.ts +56 -0
- package/src/record/extensions.ts +308 -0
- package/src/record/index.ts +7 -0
- package/src/resolver/storage-backed-resolver.ts +255 -0
- package/src/schemas/adapter-descriptor.ts +128 -0
- package/src/schemas/index.ts +104 -0
- package/src/schemas/manifest-descriptor.ts +143 -0
- package/src/schemas/record/descriptor.ts +621 -0
- package/src/schemas/record/index.ts +60 -0
- package/src/schemas/record/relation.ts +49 -0
- package/src/schemas/schema/descriptor.ts +278 -0
- package/src/schemas/schema/index.ts +14 -0
- package/src/schemas/sync-bridge-descriptor.ts +143 -0
- package/src/server/manifest-route.ts +319 -0
- package/src/storage-policy.context.descriptor.ts +17 -0
- package/src/storage-policy.context.server.ts +34 -0
- package/src/storage.plugin.ts +264 -0
- package/src/sync/cloud-pull.ts +202 -0
- package/src/sync/cloud-record-crud-config.ts +41 -0
- package/src/sync/record-sync-bridge.ts +183 -0
- package/src/sync/resolve-sync-target.ts +57 -0
- package/src/sync/schemas/cloud-pull.ts +26 -0
- package/src/sync/schemas/index.ts +18 -0
- package/src/sync/schemas/sync-helpers.ts +18 -0
- package/src/sync/schemas/sync-state.ts +41 -0
- package/src/sync/sync-bridge.ts +763 -0
- package/src/sync/sync-manifest.ts +212 -0
- package/src/sync/sync-state.consumer.ts +144 -0
- package/src/transform/index.ts +130 -0
- package/src/transform/transform-descriptor.ts +53 -0
- package/src/tui/storage-explorer.descriptor.ts +32 -0
- package/src/tui/storage-explorer.impl.consumer.ts +14 -0
- package/src/tui/storage-open.descriptor.ts +31 -0
- package/src/tui/storage-open.impl.consumer.ts +14 -0
- package/src/utils/error-context.ts +19 -0
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic Storage Manifest Route Handler
|
|
3
|
+
*
|
|
4
|
+
* SvelteKit-friendly handler that serves the canonical HTTP surface
|
|
5
|
+
* for `storage/manifest` descriptors via `/api/storage/[id]`.
|
|
6
|
+
*
|
|
7
|
+
* The owning app mounts a single `[id]/+server.ts` that calls
|
|
8
|
+
* `createManifestRouteHandler({ appId, loaders })`. The handler:
|
|
9
|
+
*
|
|
10
|
+
* 1. Looks up the descriptor at `params.id` via the runtime
|
|
11
|
+
* (`runtime.query('storage/manifest').withId(params.id)`).
|
|
12
|
+
* 2. Verifies the descriptor declares the running app as its owner
|
|
13
|
+
* via `adapterConfig['storage.cloud-api'].ownerApp === appId`.
|
|
14
|
+
* Cross-app callers get a 403, which keeps the contract clean
|
|
15
|
+
* and prevents accidental data leaks from a borrower app being
|
|
16
|
+
* asked to serve data it doesn't own.
|
|
17
|
+
* 3. Dispatches to a per-descriptor loader the app provides — one
|
|
18
|
+
* function per descriptor for `load` / `save` / `delete`.
|
|
19
|
+
* Loaders are the bridge between the owning app's local data
|
|
20
|
+
* surface (D1 table, libsql, file, etc.) and the manifest's
|
|
21
|
+
* wire shape that other apps consume via the `storage.cloud-api`
|
|
22
|
+
* adapter.
|
|
23
|
+
*
|
|
24
|
+
* Loaders are registered explicitly per descriptor (not auto-discovered)
|
|
25
|
+
* so the owning app stays in control of validation, authorization, and
|
|
26
|
+
* the local data path. A descriptor without a loader returns 404.
|
|
27
|
+
*
|
|
28
|
+
* Framework-agnostic by design: the handler accepts a structural
|
|
29
|
+
* `ManifestRouteEvent` matching SvelteKit's `RequestEvent` shape but
|
|
30
|
+
* doesn't import `@sveltejs/kit`. Apps re-export the produced GET/PUT/
|
|
31
|
+
* DELETE/HEAD from a `+server.ts` file.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
import { getLogger } from '@vibesdotdev/logging';
|
|
35
|
+
import type { StorageManifestDescriptor } from '../schemas/manifest-descriptor.ts';
|
|
36
|
+
|
|
37
|
+
const logger = getLogger('storage.manifest-route');
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Structural type matching SvelteKit's `RequestEvent`. Keeps this
|
|
41
|
+
* module framework-agnostic. `locals` stays `unknown` because each
|
|
42
|
+
* app types its own `App.Locals` interface without an index signature —
|
|
43
|
+
* loaders cast it as needed.
|
|
44
|
+
*/
|
|
45
|
+
export interface ManifestRouteEvent {
|
|
46
|
+
params: Partial<Record<string, string>>;
|
|
47
|
+
request: Request;
|
|
48
|
+
url: URL;
|
|
49
|
+
locals: unknown;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export type ManifestOperation = 'read' | 'write' | 'delete';
|
|
53
|
+
|
|
54
|
+
export interface ManifestLoader<T = unknown> {
|
|
55
|
+
/** Load the full manifest payload (typically a `Record<id, descriptor>`). */
|
|
56
|
+
load: (event: ManifestRouteEvent) => Promise<T | null>;
|
|
57
|
+
/** Optional write path; omit to make the descriptor read-only over HTTP. */
|
|
58
|
+
save?: (event: ManifestRouteEvent, data: T) => Promise<void>;
|
|
59
|
+
/** Optional delete path; omit to make the descriptor non-deletable over HTTP. */
|
|
60
|
+
delete?: (event: ManifestRouteEvent) => Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Optional per-request authorization. Return `false` to send 403.
|
|
63
|
+
* Default: allow all (the SvelteKit auth hooks have already gated
|
|
64
|
+
* unauthenticated traffic before this handler runs).
|
|
65
|
+
*/
|
|
66
|
+
authorize?: (event: ManifestRouteEvent, op: ManifestOperation) => boolean | Promise<boolean>;
|
|
67
|
+
/** Optional zod schema for validating PUT bodies before the loader sees them. */
|
|
68
|
+
validate?: (data: unknown) => unknown;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface ManifestRouteOptions {
|
|
72
|
+
/** This app's id; must match `descriptor.adapterConfig['storage.cloud-api'].ownerApp`. */
|
|
73
|
+
appId: string;
|
|
74
|
+
/** Map of descriptor id → loader. Missing entries return 404. */
|
|
75
|
+
loaders: Record<string, ManifestLoader>;
|
|
76
|
+
/**
|
|
77
|
+
* Resolver for the runtime descriptor lookup. Defaults to
|
|
78
|
+
* `(id) => getVibesRuntime().query('storage/manifest').withId(id).firstDescriptor()`.
|
|
79
|
+
* Override for tests.
|
|
80
|
+
*/
|
|
81
|
+
resolveDescriptor?: (id: string) => Promise<StorageManifestDescriptor | null>;
|
|
82
|
+
/**
|
|
83
|
+
* Returns the expected `Authorization: Bearer <token>` for internal
|
|
84
|
+
* cross-app calls. When the inbound request's bearer matches, loader
|
|
85
|
+
* `authorize` hooks are bypassed and `event.locals.user` is augmented
|
|
86
|
+
* with `{ id: 'system', isSuperuser: true, internal: true }` so loaders see
|
|
87
|
+
* a system-admin actor. Lets one cloud worker fetch the manifests it
|
|
88
|
+
* doesn't own from the owning worker's `[id]/+server.ts` without
|
|
89
|
+
* forwarding the end-user's session cookie cross-origin.
|
|
90
|
+
*/
|
|
91
|
+
internalServiceToken?: () => string | null | undefined;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
interface InternalLocals {
|
|
95
|
+
user: { id: string; email: string; isSuperuser: true; internal: true };
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function tryAuthorizeInternal(
|
|
99
|
+
event: ManifestRouteEvent,
|
|
100
|
+
opts: ManifestRouteOptions
|
|
101
|
+
): boolean {
|
|
102
|
+
const expected = opts.internalServiceToken?.()?.trim();
|
|
103
|
+
if (!expected) return false;
|
|
104
|
+
const header = event.request.headers.get('authorization');
|
|
105
|
+
if (!header || !header.toLowerCase().startsWith('bearer ')) return false;
|
|
106
|
+
const presented = header.slice(7).trim();
|
|
107
|
+
if (!presented || presented !== expected) return false;
|
|
108
|
+
const augmented: InternalLocals = {
|
|
109
|
+
user: { id: 'system', email: 'system@vibes.internal', isSuperuser: true, internal: true }
|
|
110
|
+
};
|
|
111
|
+
(event as { locals: unknown }).locals = augmented;
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export type ManifestRouteHandlers = {
|
|
116
|
+
GET: (event: ManifestRouteEvent) => Promise<Response>;
|
|
117
|
+
PUT: (event: ManifestRouteEvent) => Promise<Response>;
|
|
118
|
+
DELETE: (event: ManifestRouteEvent) => Promise<Response>;
|
|
119
|
+
HEAD: (event: ManifestRouteEvent) => Promise<Response>;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
function jsonResponse(status: number, body: unknown): Response {
|
|
123
|
+
return new Response(JSON.stringify(body), {
|
|
124
|
+
status,
|
|
125
|
+
headers: { 'content-type': 'application/json' }
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async function defaultResolveDescriptor(id: string): Promise<StorageManifestDescriptor | null> {
|
|
130
|
+
const { getVibesRuntime } = await import('@vibesdotdev/runtime');
|
|
131
|
+
const runtime = getVibesRuntime();
|
|
132
|
+
const scoped = runtime.query('storage/manifest').withId(id) as {
|
|
133
|
+
firstDescriptor?: () => StorageManifestDescriptor | null;
|
|
134
|
+
};
|
|
135
|
+
if (typeof scoped.firstDescriptor !== 'function') return null;
|
|
136
|
+
return scoped.firstDescriptor() ?? null;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function getOwnerApp(descriptor: StorageManifestDescriptor): string | null {
|
|
140
|
+
const raw = descriptor.adapterConfig?.['storage.cloud-api'];
|
|
141
|
+
if (!raw || typeof raw !== 'object') return null;
|
|
142
|
+
const value = (raw as Record<string, unknown>).ownerApp;
|
|
143
|
+
return typeof value === 'string' && value.length > 0 ? value : null;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async function resolveAndGate(
|
|
147
|
+
event: ManifestRouteEvent,
|
|
148
|
+
opts: ManifestRouteOptions
|
|
149
|
+
): Promise<
|
|
150
|
+
| { ok: true; descriptor: StorageManifestDescriptor; loader: ManifestLoader }
|
|
151
|
+
| { ok: false; response: Response }
|
|
152
|
+
> {
|
|
153
|
+
const id = event.params.id;
|
|
154
|
+
if (!id) return { ok: false, response: jsonResponse(400, { error: 'Missing descriptor id' }) };
|
|
155
|
+
|
|
156
|
+
const resolveDescriptor = opts.resolveDescriptor ?? defaultResolveDescriptor;
|
|
157
|
+
const descriptor = await resolveDescriptor(id);
|
|
158
|
+
if (!descriptor) {
|
|
159
|
+
return { ok: false, response: jsonResponse(404, { error: `Unknown storage descriptor: ${id}` }) };
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const owner = getOwnerApp(descriptor);
|
|
163
|
+
if (!owner) {
|
|
164
|
+
return {
|
|
165
|
+
ok: false,
|
|
166
|
+
response: jsonResponse(403, {
|
|
167
|
+
error: `Descriptor '${id}' does not declare ownerApp. Cross-app HTTP access requires adapterConfig['storage.cloud-api'].ownerApp.`
|
|
168
|
+
})
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
if (owner !== opts.appId) {
|
|
172
|
+
return {
|
|
173
|
+
ok: false,
|
|
174
|
+
response: jsonResponse(403, {
|
|
175
|
+
error: `Descriptor '${id}' is owned by '${owner}', not '${opts.appId}'. Request the owning app's origin.`
|
|
176
|
+
})
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const loader = opts.loaders[id];
|
|
181
|
+
if (!loader) {
|
|
182
|
+
return {
|
|
183
|
+
ok: false,
|
|
184
|
+
response: jsonResponse(404, {
|
|
185
|
+
error: `App '${opts.appId}' owns descriptor '${id}' but has not registered a loader for it.`
|
|
186
|
+
})
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return { ok: true, descriptor, loader };
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export function createManifestRouteHandler(opts: ManifestRouteOptions): ManifestRouteHandlers {
|
|
194
|
+
if (!opts.appId) throw new Error('createManifestRouteHandler: appId is required');
|
|
195
|
+
|
|
196
|
+
const authorize = async (
|
|
197
|
+
event: ManifestRouteEvent,
|
|
198
|
+
loader: ManifestLoader,
|
|
199
|
+
op: ManifestOperation,
|
|
200
|
+
internal: boolean
|
|
201
|
+
): Promise<boolean> => {
|
|
202
|
+
if (internal) return true;
|
|
203
|
+
if (!loader.authorize) return true;
|
|
204
|
+
try {
|
|
205
|
+
return await loader.authorize(event, op);
|
|
206
|
+
} catch (error) {
|
|
207
|
+
logger.warn(`authorize threw for ${event.params.id}`, {
|
|
208
|
+
error: error instanceof Error ? error.message : String(error)
|
|
209
|
+
});
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
const GET = async (event: ManifestRouteEvent): Promise<Response> => {
|
|
215
|
+
const gated = await resolveAndGate(event, opts);
|
|
216
|
+
if (!gated.ok) return gated.response;
|
|
217
|
+
|
|
218
|
+
const internal = tryAuthorizeInternal(event, opts);
|
|
219
|
+
if (!(await authorize(event, gated.loader, 'read', internal))) {
|
|
220
|
+
return jsonResponse(403, { error: 'Forbidden' });
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
try {
|
|
224
|
+
const value = await gated.loader.load(event);
|
|
225
|
+
// `{ value }` matches the wire shape consumed by the cloud-api
|
|
226
|
+
// adapter's fetch client (see `cloud-api.fetch-client.ts:131`,
|
|
227
|
+
// `data.value` lookup). Keeping this in lockstep with the adapter
|
|
228
|
+
// means borrower apps get descriptor records back without bespoke
|
|
229
|
+
// translation per app.
|
|
230
|
+
return jsonResponse(200, { value });
|
|
231
|
+
} catch (error) {
|
|
232
|
+
logger.error(`load failed for ${event.params.id}`, {
|
|
233
|
+
error: error instanceof Error ? error.message : String(error)
|
|
234
|
+
});
|
|
235
|
+
return jsonResponse(500, { error: 'Failed to load manifest data' });
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
const HEAD = async (event: ManifestRouteEvent): Promise<Response> => {
|
|
240
|
+
const gated = await resolveAndGate(event, opts);
|
|
241
|
+
if (!gated.ok) {
|
|
242
|
+
return new Response(null, { status: gated.response.status });
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const internal = tryAuthorizeInternal(event, opts);
|
|
246
|
+
if (!(await authorize(event, gated.loader, 'read', internal))) {
|
|
247
|
+
return new Response(null, { status: 403 });
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
try {
|
|
251
|
+
const data = await gated.loader.load(event);
|
|
252
|
+
return new Response(null, { status: data == null ? 404 : 200 });
|
|
253
|
+
} catch {
|
|
254
|
+
return new Response(null, { status: 500 });
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
const PUT = async (event: ManifestRouteEvent): Promise<Response> => {
|
|
259
|
+
const gated = await resolveAndGate(event, opts);
|
|
260
|
+
if (!gated.ok) return gated.response;
|
|
261
|
+
|
|
262
|
+
if (!gated.loader.save) {
|
|
263
|
+
return jsonResponse(405, { error: 'Descriptor is read-only over HTTP' });
|
|
264
|
+
}
|
|
265
|
+
const internal = tryAuthorizeInternal(event, opts);
|
|
266
|
+
if (!(await authorize(event, gated.loader, 'write', internal))) {
|
|
267
|
+
return jsonResponse(403, { error: 'Forbidden' });
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
let body: unknown;
|
|
271
|
+
try {
|
|
272
|
+
body = await event.request.json();
|
|
273
|
+
} catch {
|
|
274
|
+
return jsonResponse(400, { error: 'Body must be valid JSON' });
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Cloud-api fetch client wraps the payload as `{ value: data }`
|
|
278
|
+
// (see `cloud-api.fetch-client.ts:144`). Unwrap once on the server
|
|
279
|
+
// so loaders see the raw manifest record.
|
|
280
|
+
const unwrappedBody =
|
|
281
|
+
body && typeof body === 'object' && 'value' in (body as Record<string, unknown>)
|
|
282
|
+
? (body as Record<string, unknown>).value
|
|
283
|
+
: body;
|
|
284
|
+
|
|
285
|
+
try {
|
|
286
|
+
const validated = gated.loader.validate ? gated.loader.validate(unwrappedBody) : unwrappedBody;
|
|
287
|
+
await gated.loader.save(event, validated);
|
|
288
|
+
return jsonResponse(200, { ok: true });
|
|
289
|
+
} catch (error) {
|
|
290
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
291
|
+
logger.error(`save failed for ${event.params.id}`, { error: message });
|
|
292
|
+
return jsonResponse(500, { error: 'Failed to save manifest data', detail: message });
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
const DELETE = async (event: ManifestRouteEvent): Promise<Response> => {
|
|
297
|
+
const gated = await resolveAndGate(event, opts);
|
|
298
|
+
if (!gated.ok) return gated.response;
|
|
299
|
+
|
|
300
|
+
if (!gated.loader.delete) {
|
|
301
|
+
return jsonResponse(405, { error: 'Descriptor is not deletable over HTTP' });
|
|
302
|
+
}
|
|
303
|
+
const internal = tryAuthorizeInternal(event, opts);
|
|
304
|
+
if (!(await authorize(event, gated.loader, 'delete', internal))) {
|
|
305
|
+
return jsonResponse(403, { error: 'Forbidden' });
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
try {
|
|
309
|
+
await gated.loader.delete(event);
|
|
310
|
+
return jsonResponse(200, { ok: true });
|
|
311
|
+
} catch (error) {
|
|
312
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
313
|
+
logger.error(`delete failed for ${event.params.id}`, { error: message });
|
|
314
|
+
return jsonResponse(500, { error: 'Failed to delete manifest data', detail: message });
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
return { GET, PUT, DELETE, HEAD };
|
|
319
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createRuntimeAsset } from "@vibesdotdev/runtime/factory/asset";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Storage Policy Context Descriptor
|
|
5
|
+
*
|
|
6
|
+
* Registers the storage/policy context kind with the runtime.
|
|
7
|
+
* This context provides storage policy resolution and overrides.
|
|
8
|
+
*/
|
|
9
|
+
export default createRuntimeAsset({
|
|
10
|
+
id: "storage/policy",
|
|
11
|
+
kind: "context",
|
|
12
|
+
name: "Storage Policy Context",
|
|
13
|
+
description:
|
|
14
|
+
"Provides storage policy resolution and runtime overrides for storage adapters",
|
|
15
|
+
tags: ["storage", "policy", "context"],
|
|
16
|
+
enabled: true,
|
|
17
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { StoragePolicyContext, StoragePolicy, StoragePolicyOverride } from './policy/types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Load Storage Policy Context
|
|
5
|
+
*
|
|
6
|
+
* Provides the default storage policy context for consumer environments.
|
|
7
|
+
* The runtime resolves the active adapter through scope-based selection;
|
|
8
|
+
* this context provides the fallback policy when no manifest-specific
|
|
9
|
+
* policy is registered.
|
|
10
|
+
*
|
|
11
|
+
* Apps can register a custom policy context through the runtime's context
|
|
12
|
+
* kind to override these defaults (e.g. cloud apps using API adapters).
|
|
13
|
+
*/
|
|
14
|
+
export async function loadStoragePolicyContext(): Promise<StoragePolicyContext> {
|
|
15
|
+
return {
|
|
16
|
+
resolveStoragePolicy: async (
|
|
17
|
+
namespace: string,
|
|
18
|
+
options?: Record<string, unknown>
|
|
19
|
+
): Promise<StoragePolicy> => {
|
|
20
|
+
return {
|
|
21
|
+
mode: 'persistent',
|
|
22
|
+
adapter: 'localdb',
|
|
23
|
+
namespace,
|
|
24
|
+
...options
|
|
25
|
+
};
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
resolveStoragePolicyOverrides: async (
|
|
29
|
+
_context: Record<string, unknown>
|
|
30
|
+
): Promise<StoragePolicyOverride> => {
|
|
31
|
+
return {};
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage Plugin
|
|
3
|
+
*
|
|
4
|
+
* Registers storage/adapter, storage/manifest, and storage/record kinds with the runtime.
|
|
5
|
+
* This is the entry point for the storage module's runtime integration.
|
|
6
|
+
*
|
|
7
|
+
* Also registers storage-owned TUI surfaces during activation:
|
|
8
|
+
* - `storage.explorer` (tui/app) — interactive storage browser
|
|
9
|
+
* - `storage.open` (tui/command) — opens the explorer via `/storage`
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { createRuntimePlugin, loader } from '@vibesdotdev/runtime';
|
|
13
|
+
import { createRuntimeImplementation } from '@vibesdotdev/runtime/factory/implementation';
|
|
14
|
+
import type { RuntimeImplementationWrapper } from '@vibesdotdev/runtime';
|
|
15
|
+
import storagePolicyContextDescriptor from './storage-policy.context.descriptor';
|
|
16
|
+
import { loadStoragePolicyContext } from './storage-policy.context.server';
|
|
17
|
+
// CLI
|
|
18
|
+
import storageGroup from './cli/storage.cli-group.descriptor.ts';
|
|
19
|
+
import storageSyncGroup from './cli/storage.sync.cli-group.descriptor.ts';
|
|
20
|
+
import storageList from './cli/commands/list/storage.list.cli-command.descriptor.ts';
|
|
21
|
+
import storageSyncPull from './cli/commands/sync/pull/storage.sync.pull.cli-command.descriptor.ts';
|
|
22
|
+
import storageSyncPush from './cli/commands/sync/push/storage.sync.push.cli-command.descriptor.ts';
|
|
23
|
+
import storageSyncResolve from './cli/commands/sync/resolve/storage.sync.resolve.cli-command.descriptor.ts';
|
|
24
|
+
import storageSyncStatus from './cli/commands/sync/status/storage.sync.status.cli-command.descriptor.ts';
|
|
25
|
+
|
|
26
|
+
// TUI
|
|
27
|
+
import storageExplorerDescriptor from './tui/storage-explorer.descriptor';
|
|
28
|
+
import storageOpenDescriptor from './tui/storage-open.descriptor';
|
|
29
|
+
|
|
30
|
+
// Docs
|
|
31
|
+
import adaptersDescriptor from './docs/adapters.docs.descriptor';
|
|
32
|
+
import recordsDescriptor from './docs/records.docs.descriptor';
|
|
33
|
+
import syncDescriptor from './docs/sync.docs.descriptor';
|
|
34
|
+
import manifestsDescriptor from './docs/manifests.docs.descriptor';
|
|
35
|
+
|
|
36
|
+
import type { StorageRecordInterface } from './interfaces/record';
|
|
37
|
+
import {
|
|
38
|
+
StorageAdapterDescriptorSchema,
|
|
39
|
+
type StorageAdapterDescriptor
|
|
40
|
+
} from './schemas/adapter-descriptor';
|
|
41
|
+
import { StorageManifestDescriptorSchema } from './schemas/manifest-descriptor';
|
|
42
|
+
import { StorageRecordDescriptorSchema, type StorageRecordDescriptor } from './schemas/record';
|
|
43
|
+
import { SyncBridgeDescriptorSchema } from './schemas/sync-bridge-descriptor';
|
|
44
|
+
import { StorageTransformDescriptorSchema } from './transform/transform-descriptor';
|
|
45
|
+
import { StorageManifest } from './manifest/base';
|
|
46
|
+
import { storageRecordEvents } from './record/events';
|
|
47
|
+
|
|
48
|
+
const storageRecordDefaultImplementation:
|
|
49
|
+
| (new (
|
|
50
|
+
descriptor: StorageRecordDescriptor,
|
|
51
|
+
context: { runtime: unknown; readonly [contextId: string]: unknown }
|
|
52
|
+
) => StorageRecordInterface<Record<string, unknown>>)
|
|
53
|
+
| undefined = (() => {
|
|
54
|
+
if (typeof globalThis !== 'undefined' && 'window' in globalThis) return undefined;
|
|
55
|
+
try {
|
|
56
|
+
const runtimeRequire = (
|
|
57
|
+
import.meta as ImportMeta & {
|
|
58
|
+
require?: (id: string) => {
|
|
59
|
+
StorageRecord: new (
|
|
60
|
+
descriptor: StorageRecordDescriptor,
|
|
61
|
+
context: { runtime: unknown; readonly [contextId: string]: unknown }
|
|
62
|
+
) => StorageRecordInterface<Record<string, unknown>>;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
).require;
|
|
66
|
+
if (typeof runtimeRequire !== 'function') return undefined;
|
|
67
|
+
return runtimeRequire('./record/base.ts').StorageRecord;
|
|
68
|
+
} catch {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
})();
|
|
72
|
+
|
|
73
|
+
// Kind definitions - types are inferred to work with AnyKindDefinition
|
|
74
|
+
const storageAdapterKind = {
|
|
75
|
+
id: 'storage/adapter',
|
|
76
|
+
descriptorSchema: StorageAdapterDescriptorSchema,
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Resolution strategy: Find adapter matching hardware target.
|
|
80
|
+
* Prefers persistent adapters over memory when available.
|
|
81
|
+
*
|
|
82
|
+
* No defaultImplementation — adapter packages register their own descriptor + loader
|
|
83
|
+
* via their plugin (e.g. `storageAdapterMemoryPlugin`). Consumers must register at
|
|
84
|
+
* least one adapter plugin matching their scope.
|
|
85
|
+
*/
|
|
86
|
+
resolve: (candidates: StorageAdapterDescriptor[], scope: { hardware: string }) => {
|
|
87
|
+
// Filter to candidates matching hardware
|
|
88
|
+
const matching = candidates.filter(
|
|
89
|
+
(d) => !d.hardware || d.hardware.length === 0 || d.hardware.includes(scope.hardware)
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
if (matching.length === 0) return undefined;
|
|
93
|
+
|
|
94
|
+
// Prefer persistent adapters
|
|
95
|
+
const persistent = matching.filter((d) => d.persistent);
|
|
96
|
+
if (persistent.length > 0) return persistent[0];
|
|
97
|
+
|
|
98
|
+
// Fall back to any matching
|
|
99
|
+
return matching[0];
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const storageManifestKind = {
|
|
104
|
+
id: 'storage/manifest',
|
|
105
|
+
descriptorSchema: StorageManifestDescriptorSchema,
|
|
106
|
+
contexts: ['runtime/workspace-path'],
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Default implementation: StorageManifest
|
|
110
|
+
*
|
|
111
|
+
* Base class providing document operations (load, save, exists, delete).
|
|
112
|
+
* Modules can extend this for custom methods.
|
|
113
|
+
* Constructor signature: (descriptor, context) - context provides runtime access.
|
|
114
|
+
*/
|
|
115
|
+
defaultImplementation: StorageManifest
|
|
116
|
+
|
|
117
|
+
// No custom resolve - manifests are looked up by ID, not scope-based
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const storageRecordKind = {
|
|
121
|
+
id: 'storage/record',
|
|
122
|
+
descriptorSchema: StorageRecordDescriptorSchema,
|
|
123
|
+
contexts: ['runtime/workspace-path', 'storage/policy'],
|
|
124
|
+
...(storageRecordDefaultImplementation
|
|
125
|
+
? { defaultImplementation: storageRecordDefaultImplementation }
|
|
126
|
+
: {})
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const storageSyncBridgeKind = {
|
|
130
|
+
id: 'storage/sync-bridge',
|
|
131
|
+
descriptorSchema: SyncBridgeDescriptorSchema
|
|
132
|
+
|
|
133
|
+
// No defaultImplementation — SyncBridge is server/CLI only.
|
|
134
|
+
// Implementations are registered by the bun loader during discovery.
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
const storageTransformKind = {
|
|
138
|
+
id: 'storage/transform',
|
|
139
|
+
descriptorSchema: StorageTransformDescriptorSchema
|
|
140
|
+
|
|
141
|
+
// No defaultImplementation — transforms are plugin-registered per
|
|
142
|
+
// manifest. The wire shape is `{ fromRow, toRow? }` (see
|
|
143
|
+
// `./transform/transform-descriptor.ts`). Consumers resolve via
|
|
144
|
+
// `resolveStorageTransform(runtime, id)`.
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
function loadTuiImplementation<T>(kind: string, id: string, load: () => Promise<{ default: T }>) {
|
|
148
|
+
return async () => {
|
|
149
|
+
const mod = await load();
|
|
150
|
+
return createRuntimeImplementation({
|
|
151
|
+
kind,
|
|
152
|
+
id,
|
|
153
|
+
implementation: mod.default
|
|
154
|
+
});
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Storage plugin - registers storage kinds with the runtime.
|
|
160
|
+
*
|
|
161
|
+
* Kinds registered:
|
|
162
|
+
* - `storage/adapter` - Storage backends. Adapter implementations live in sibling
|
|
163
|
+
* packages (`storage-adapter-{memory,json,localdb,cloud-api,drizzle}`) and register
|
|
164
|
+
* themselves via their own plugins. The storage core does not import them.
|
|
165
|
+
* - `storage/manifest` - Storable data type definitions
|
|
166
|
+
* - `storage/record` - Single-table CRUD operations with relations
|
|
167
|
+
* - `storage/sync-bridge` - Declarative runtime kind ↔ cloud CRUD sync
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* ```ts
|
|
171
|
+
* import { getVibesRuntime } from '@vibesdotdev/runtime/factory/plugin';
|
|
172
|
+
* import storagePlugin from './storage.plugin';
|
|
173
|
+
*
|
|
174
|
+
* const runtime = getVibesRuntime();
|
|
175
|
+
* await runtime.registerPlugin(storagePlugin);
|
|
176
|
+
*
|
|
177
|
+
* // Now you can query storage adapters
|
|
178
|
+
* const adapter = await runtime.query('storage/adapter')
|
|
179
|
+
* .forHardware('consumer')
|
|
180
|
+
* .resolve();
|
|
181
|
+
* ```
|
|
182
|
+
*/
|
|
183
|
+
export default createRuntimePlugin({
|
|
184
|
+
id: 'storage',
|
|
185
|
+
name: 'Storage Module',
|
|
186
|
+
description: 'Interface-driven storage providers for document and repository-style storage',
|
|
187
|
+
dependencies: ['context'],
|
|
188
|
+
kinds: [
|
|
189
|
+
storageAdapterKind,
|
|
190
|
+
storageManifestKind,
|
|
191
|
+
storageRecordKind,
|
|
192
|
+
storageSyncBridgeKind,
|
|
193
|
+
storageTransformKind
|
|
194
|
+
],
|
|
195
|
+
|
|
196
|
+
descriptors: [
|
|
197
|
+
storageGroup,
|
|
198
|
+
storageSyncGroup,
|
|
199
|
+
storageList,
|
|
200
|
+
storageSyncPull,
|
|
201
|
+
storageSyncPush,
|
|
202
|
+
storageSyncResolve,
|
|
203
|
+
storageSyncStatus,
|
|
204
|
+
...storageRecordEvents,
|
|
205
|
+
adaptersDescriptor,
|
|
206
|
+
recordsDescriptor,
|
|
207
|
+
syncDescriptor,
|
|
208
|
+
manifestsDescriptor
|
|
209
|
+
],
|
|
210
|
+
|
|
211
|
+
loaders: [
|
|
212
|
+
loader('storage.list', () => import('./cli/commands/list/storage.list.cli-command.impl.js')),
|
|
213
|
+
loader('storage.sync.push', () =>
|
|
214
|
+
import('./cli/commands/sync/push/storage.sync.push.cli-command.impl.js')
|
|
215
|
+
),
|
|
216
|
+
loader('storage.sync.pull', () =>
|
|
217
|
+
import('./cli/commands/sync/pull/storage.sync.pull.cli-command.impl.js')
|
|
218
|
+
),
|
|
219
|
+
loader('storage.sync.status', () =>
|
|
220
|
+
import('./cli/commands/sync/status/storage.sync.status.cli-command.impl.js')
|
|
221
|
+
),
|
|
222
|
+
loader('storage.sync.resolve', () =>
|
|
223
|
+
import('./cli/commands/sync/resolve/storage.sync.resolve.cli-command.impl.js')
|
|
224
|
+
)
|
|
225
|
+
],
|
|
226
|
+
|
|
227
|
+
onRegister: async (runtime) => {
|
|
228
|
+
// Register storage-owned TUI surfaces only when the tui/* kinds are
|
|
229
|
+
// available. The standard bootstrap (see apps/cli-bin defaults.ts)
|
|
230
|
+
// loads tui before storage. Keeping this conditional lets minimal
|
|
231
|
+
// test setups register storage without spinning up the TUI stack.
|
|
232
|
+
if (runtime.hasKind('tui/app')) {
|
|
233
|
+
runtime.registerDescriptor('tui/app', storageExplorerDescriptor);
|
|
234
|
+
runtime.registerLoader(
|
|
235
|
+
'tui/app',
|
|
236
|
+
storageExplorerDescriptor.id,
|
|
237
|
+
loadTuiImplementation('tui/app', storageExplorerDescriptor.id, () =>
|
|
238
|
+
import('./tui/storage-explorer.impl.consumer')
|
|
239
|
+
)
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
if (runtime.hasKind('tui/command')) {
|
|
243
|
+
runtime.registerDescriptor('tui/command', storageOpenDescriptor);
|
|
244
|
+
runtime.registerLoader(
|
|
245
|
+
'tui/command',
|
|
246
|
+
storageOpenDescriptor.id,
|
|
247
|
+
loadTuiImplementation('tui/command', storageOpenDescriptor.id, () =>
|
|
248
|
+
import('./tui/storage-open.impl.consumer')
|
|
249
|
+
)
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
// Register storage policy context
|
|
253
|
+
runtime.registerDescriptor('context', storagePolicyContextDescriptor);
|
|
254
|
+
runtime.registerLoader('context', storagePolicyContextDescriptor.id, async () =>
|
|
255
|
+
createRuntimeImplementation({
|
|
256
|
+
kind: 'context',
|
|
257
|
+
id: storagePolicyContextDescriptor.id,
|
|
258
|
+
implementation: {
|
|
259
|
+
provide: async () => loadStoragePolicyContext()
|
|
260
|
+
}
|
|
261
|
+
})
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
});
|