@fougere/core 0.5.0-alpha.1 → 0.7.0-alpha.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/README.md +1 -1
- package/dist/boot/Emissions.d.ts +14 -91
- package/dist/boot/Emissions.d.ts.map +1 -1
- package/dist/boot/Emissions.js +21 -118
- package/dist/boot/Emissions.js.map +1 -1
- package/dist/boot/ambient-port.d.ts +3 -24
- package/dist/boot/ambient-port.d.ts.map +1 -1
- package/dist/boot/ambient.als.d.ts.map +1 -1
- package/dist/boot/ambient.als.js +7 -12
- package/dist/boot/ambient.als.js.map +1 -1
- package/dist/boot/ambient.queue.d.ts +2 -5
- package/dist/boot/ambient.queue.d.ts.map +1 -1
- package/dist/boot/ambient.queue.js.map +1 -1
- package/dist/boot/apply.d.ts +1 -13
- package/dist/boot/apply.d.ts.map +1 -1
- package/dist/boot/apply.js +3 -15
- package/dist/boot/apply.js.map +1 -1
- package/dist/boot/auth.d.ts +6 -16
- package/dist/boot/auth.d.ts.map +1 -1
- package/dist/boot/boot.d.ts +5 -18
- package/dist/boot/boot.d.ts.map +1 -1
- package/dist/boot/boot.js +4 -11
- package/dist/boot/boot.js.map +1 -1
- package/dist/boot/bootstrap.d.ts.map +1 -1
- package/dist/boot/bootstrap.js +106 -163
- package/dist/boot/bootstrap.js.map +1 -1
- package/dist/boot/card.d.ts +5 -0
- package/dist/boot/card.d.ts.map +1 -0
- package/dist/boot/card.js +71 -0
- package/dist/boot/card.js.map +1 -0
- package/dist/boot/frame.d.ts +8 -32
- package/dist/boot/frame.d.ts.map +1 -1
- package/dist/boot/frame.js +23 -57
- package/dist/boot/frame.js.map +1 -1
- package/dist/boot/hosted.d.ts +3 -19
- package/dist/boot/hosted.d.ts.map +1 -1
- package/dist/boot/hosted.js +12 -17
- package/dist/boot/hosted.js.map +1 -1
- package/dist/boot/ownership.d.ts +5 -36
- package/dist/boot/ownership.d.ts.map +1 -1
- package/dist/boot/ownership.js +9 -49
- package/dist/boot/ownership.js.map +1 -1
- package/dist/boot/ports.d.ts +2 -15
- package/dist/boot/ports.d.ts.map +1 -1
- package/dist/boot/ports.js +1 -14
- package/dist/boot/ports.js.map +1 -1
- package/dist/boot/remote.d.ts +5 -38
- package/dist/boot/remote.d.ts.map +1 -1
- package/dist/boot/remote.js +8 -41
- package/dist/boot/remote.js.map +1 -1
- package/dist/boot/runner.d.ts +11 -0
- package/dist/boot/runner.d.ts.map +1 -0
- package/dist/boot/runner.js +13 -0
- package/dist/boot/runner.js.map +1 -0
- package/dist/boot/seed.d.ts +5 -32
- package/dist/boot/seed.d.ts.map +1 -1
- package/dist/boot/seed.js +10 -41
- package/dist/boot/seed.js.map +1 -1
- package/dist/boot/statement-drift.d.ts +4 -22
- package/dist/boot/statement-drift.d.ts.map +1 -1
- package/dist/boot/statement-drift.js +4 -9
- package/dist/boot/statement-drift.js.map +1 -1
- package/dist/boot/together.d.ts +8 -12
- package/dist/boot/together.d.ts.map +1 -1
- package/dist/boot/together.js +28 -65
- package/dist/boot/together.js.map +1 -1
- package/dist/boot/types.d.ts +36 -180
- package/dist/boot/types.d.ts.map +1 -1
- package/dist/builtin/config.d.ts +7 -0
- package/dist/builtin/config.d.ts.map +1 -0
- package/dist/builtin/config.js +15 -0
- package/dist/builtin/config.js.map +1 -0
- package/dist/{builtins → builtin}/logger.d.ts +4 -25
- package/dist/builtin/logger.d.ts.map +1 -0
- package/dist/{builtins → builtin}/logger.js +5 -32
- package/dist/builtin/logger.js.map +1 -0
- package/dist/config-loader.d.ts +9 -67
- package/dist/config-loader.d.ts.map +1 -1
- package/dist/config-loader.js +5 -18
- package/dist/config-loader.js.map +1 -1
- package/dist/contract.d.ts +13 -31
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +10 -26
- package/dist/contract.js.map +1 -1
- package/dist/crypto/encoding.d.ts +2 -15
- package/dist/crypto/encoding.d.ts.map +1 -1
- package/dist/crypto/encoding.js +2 -15
- package/dist/crypto/encoding.js.map +1 -1
- package/dist/crypto/node.d.ts.map +1 -1
- package/dist/crypto/node.js +1 -7
- package/dist/crypto/node.js.map +1 -1
- package/dist/crypto/port.d.ts +2 -18
- package/dist/crypto/port.d.ts.map +1 -1
- package/dist/crypto/port.js +1 -17
- package/dist/crypto/port.js.map +1 -1
- package/dist/crypto/webcrypto.d.ts.map +1 -1
- package/dist/crypto/webcrypto.js +1 -12
- package/dist/crypto/webcrypto.js.map +1 -1
- package/dist/declare.d.ts +41 -0
- package/dist/declare.d.ts.map +1 -0
- package/dist/{scan/declare.js → declare.js} +6 -31
- package/dist/declare.js.map +1 -0
- package/dist/define.d.ts +2 -3
- package/dist/define.d.ts.map +1 -1
- package/dist/define.js +2 -3
- package/dist/define.js.map +1 -1
- package/dist/descriptor/Fronds.d.ts +19 -0
- package/dist/descriptor/Fronds.d.ts.map +1 -0
- package/dist/descriptor/Fronds.js +40 -0
- package/dist/descriptor/Fronds.js.map +1 -0
- package/dist/descriptor/frond.d.ts +135 -0
- package/dist/descriptor/frond.d.ts.map +1 -0
- package/dist/{scan → descriptor}/frond.js.map +1 -1
- package/dist/dispatch/ArgumentResolver.d.ts +6 -3
- package/dist/dispatch/ArgumentResolver.d.ts.map +1 -1
- package/dist/dispatch/ArgumentResolver.js +48 -3
- package/dist/dispatch/ArgumentResolver.js.map +1 -1
- package/dist/dispatch/DispatchEvent.d.ts +2 -2
- package/dist/dispatch/DispatchEvent.d.ts.map +1 -1
- package/dist/dispatch/DispatchLifecycle.d.ts +1 -7
- package/dist/dispatch/DispatchLifecycle.d.ts.map +1 -1
- package/dist/dispatch/DispatchLifecycle.js +1 -7
- package/dist/dispatch/DispatchLifecycle.js.map +1 -1
- package/dist/dispatch/DispatchPort.d.ts +1 -1
- package/dist/dispatch/DispatchPort.d.ts.map +1 -1
- package/dist/dispatch/Dispatcher.d.ts +1 -1
- package/dist/dispatch/Dispatcher.d.ts.map +1 -1
- package/dist/dispatch/Dispatcher.js +2 -2
- package/dist/dispatch/Dispatcher.js.map +1 -1
- package/dist/{boot → dispatch}/HandlerFacade.d.ts +25 -38
- package/dist/dispatch/HandlerFacade.d.ts.map +1 -0
- package/dist/{boot → dispatch}/HandlerFacade.js +65 -74
- package/dist/dispatch/HandlerFacade.js.map +1 -0
- package/dist/dispatch/LocalRoutePolicy.d.ts +1 -1
- package/dist/dispatch/LocalRoutePolicy.d.ts.map +1 -1
- package/dist/dispatch/LocalRoutePolicy.js +4 -4
- package/dist/dispatch/LocalRoutePolicy.js.map +1 -1
- package/dist/dispatch/OperationRoute.d.ts +2 -2
- package/dist/dispatch/OperationRoute.d.ts.map +1 -1
- package/dist/dispatch/OutputView.d.ts +3 -2
- package/dist/dispatch/OutputView.d.ts.map +1 -1
- package/dist/dispatch/OutputView.js +19 -1
- package/dist/dispatch/OutputView.js.map +1 -1
- package/dist/dispatch/Route.d.ts +2 -3
- package/dist/dispatch/Route.d.ts.map +1 -1
- package/dist/dispatch/RoutePolicy.d.ts +1 -1
- package/dist/dispatch/RoutePolicy.d.ts.map +1 -1
- package/dist/dispatch/RouteRegistry.d.ts +1 -1
- package/dist/dispatch/RouteRegistry.d.ts.map +1 -1
- package/dist/dispatch/RouteRegistry.js +2 -2
- package/dist/dispatch/RouteRegistry.js.map +1 -1
- package/dist/dispatch/RouteResolver.d.ts +2 -4
- package/dist/dispatch/RouteResolver.d.ts.map +1 -1
- package/dist/dispatch/StorageGuard.d.ts +9 -8
- package/dist/dispatch/StorageGuard.d.ts.map +1 -1
- package/dist/dispatch/StorageGuard.js +66 -23
- package/dist/dispatch/StorageGuard.js.map +1 -1
- package/dist/dispatch/presenterArguments.d.ts +7 -0
- package/dist/dispatch/presenterArguments.d.ts.map +1 -0
- package/dist/dispatch/presenterArguments.js +12 -0
- package/dist/dispatch/presenterArguments.js.map +1 -0
- package/dist/dispatch/remoteRoutes.d.ts +7 -0
- package/dist/dispatch/remoteRoutes.d.ts.map +1 -0
- package/dist/dispatch/{RemoteRouteResolver.js → remoteRoutes.js} +6 -10
- package/dist/dispatch/remoteRoutes.js.map +1 -0
- package/dist/dispatch/routeNotFound.d.ts +9 -0
- package/dist/dispatch/routeNotFound.d.ts.map +1 -0
- package/dist/dispatch/routeNotFound.js +21 -0
- package/dist/dispatch/routeNotFound.js.map +1 -0
- package/dist/dispatch/validateInput.d.ts +5 -0
- package/dist/dispatch/validateInput.d.ts.map +1 -0
- package/dist/dispatch/validateInput.js +20 -0
- package/dist/dispatch/validateInput.js.map +1 -0
- package/dist/effective-operation.d.ts +6 -3
- package/dist/effective-operation.d.ts.map +1 -1
- package/dist/effective-operation.js +49 -27
- package/dist/effective-operation.js.map +1 -1
- package/dist/emit.d.ts +4 -42
- package/dist/emit.d.ts.map +1 -1
- package/dist/emit.js +3 -39
- package/dist/emit.js.map +1 -1
- package/dist/entry/facade.d.ts +8 -0
- package/dist/entry/facade.d.ts.map +1 -0
- package/dist/entry/facade.js +28 -0
- package/dist/entry/facade.js.map +1 -0
- package/dist/entry/transport.d.ts +5 -0
- package/dist/entry/transport.d.ts.map +1 -0
- package/dist/entry/transport.js +11 -0
- package/dist/entry/transport.js.map +1 -0
- package/dist/frond-config.d.ts +8 -71
- package/dist/frond-config.d.ts.map +1 -1
- package/dist/frond-config.js +1 -9
- package/dist/frond-config.js.map +1 -1
- package/dist/graph.d.ts +1 -1
- package/dist/graph.d.ts.map +1 -1
- package/dist/identity-keys.d.ts +2 -5
- package/dist/identity-keys.d.ts.map +1 -1
- package/dist/identity-keys.js +3 -16
- package/dist/identity-keys.js.map +1 -1
- package/dist/identity.d.ts +4 -30
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +11 -73
- package/dist/identity.js.map +1 -1
- package/dist/imports.d.ts +2 -8
- package/dist/imports.d.ts.map +1 -1
- package/dist/imports.js +1 -7
- package/dist/imports.js.map +1 -1
- package/dist/index.d.ts +28 -30
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -22
- package/dist/index.js.map +1 -1
- package/dist/loader.d.ts +1 -8
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +1 -8
- package/dist/loader.js.map +1 -1
- package/dist/node.d.ts +2 -11
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +2 -11
- package/dist/node.js.map +1 -1
- package/dist/prefab/collector.d.ts +1 -22
- package/dist/prefab/collector.d.ts.map +1 -1
- package/dist/prefab/collector.js +1 -22
- package/dist/prefab/collector.js.map +1 -1
- package/dist/prefab/crud.d.ts +19 -35
- package/dist/prefab/crud.d.ts.map +1 -1
- package/dist/prefab/crud.js +39 -66
- package/dist/prefab/crud.js.map +1 -1
- package/dist/prefab/mirror.d.ts +5 -27
- package/dist/prefab/mirror.d.ts.map +1 -1
- package/dist/prefab/mirror.js +6 -24
- package/dist/prefab/mirror.js.map +1 -1
- package/dist/prefab/prefab.d.ts +1 -7
- package/dist/prefab/prefab.d.ts.map +1 -1
- package/dist/prefab/prefab.js +1 -7
- package/dist/prefab/prefab.js.map +1 -1
- package/dist/prefab/presenter.d.ts +2 -36
- package/dist/prefab/presenter.d.ts.map +1 -1
- package/dist/prefab/presenter.js +2 -36
- package/dist/prefab/presenter.js.map +1 -1
- package/dist/prefab/repository.d.ts +12 -80
- package/dist/prefab/repository.d.ts.map +1 -1
- package/dist/prefab/repository.js +22 -35
- package/dist/prefab/repository.js.map +1 -1
- package/dist/scan/adapters.d.ts +3 -0
- package/dist/scan/adapters.d.ts.map +1 -0
- package/dist/scan/adapters.js +25 -0
- package/dist/scan/adapters.js.map +1 -0
- package/dist/scan/bundling.d.ts +1 -12
- package/dist/scan/bundling.d.ts.map +1 -1
- package/dist/scan/bundling.js +1 -12
- package/dist/scan/bundling.js.map +1 -1
- package/dist/scan/conventions.d.ts +6 -40
- package/dist/scan/conventions.d.ts.map +1 -1
- package/dist/scan/conventions.js +5 -34
- package/dist/scan/conventions.js.map +1 -1
- package/dist/scan/emit.d.ts +2 -6
- package/dist/scan/emit.d.ts.map +1 -1
- package/dist/scan/emit.js +5 -39
- package/dist/scan/emit.js.map +1 -1
- package/dist/scan/handler-parser.d.ts +9 -76
- package/dist/scan/handler-parser.d.ts.map +1 -1
- package/dist/scan/handler-parser.js +28 -85
- package/dist/scan/handler-parser.js.map +1 -1
- package/dist/scan/result.d.ts +28 -0
- package/dist/scan/result.d.ts.map +1 -0
- package/dist/scan/result.js +2 -0
- package/dist/scan/result.js.map +1 -0
- package/dist/scan/scanner.d.ts +3 -28
- package/dist/scan/scanner.d.ts.map +1 -1
- package/dist/scan/scanner.js +36 -135
- package/dist/scan/scanner.js.map +1 -1
- package/dist/scan/statement.d.ts +1 -1
- package/dist/scan/statement.d.ts.map +1 -1
- package/dist/scan/statement.js +4 -30
- package/dist/scan/statement.js.map +1 -1
- package/dist/source.d.ts +41 -0
- package/dist/source.d.ts.map +1 -0
- package/dist/source.js +10 -0
- package/dist/source.js.map +1 -0
- package/dist/storage.d.ts +92 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +50 -0
- package/dist/storage.js.map +1 -0
- package/dist/store.d.ts +18 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +146 -0
- package/dist/store.js.map +1 -0
- package/dist/verify.d.ts +6 -39
- package/dist/verify.d.ts.map +1 -1
- package/dist/verify.js +19 -39
- package/dist/verify.js.map +1 -1
- package/dist/wire/CallLog.d.ts +32 -0
- package/dist/wire/CallLog.d.ts.map +1 -0
- package/dist/{contract → wire}/CallLog.js.map +1 -1
- package/dist/wire/Invocation.d.ts +32 -0
- package/dist/wire/Invocation.d.ts.map +1 -0
- package/dist/wire/Invocation.js +66 -0
- package/dist/wire/Invocation.js.map +1 -0
- package/dist/wire/RouteAddress.d.ts +24 -0
- package/dist/wire/RouteAddress.d.ts.map +1 -0
- package/dist/{contract → wire}/RouteAddress.js +7 -0
- package/dist/wire/RouteAddress.js.map +1 -0
- package/dist/wire/binding.d.ts +36 -0
- package/dist/wire/binding.d.ts.map +1 -0
- package/dist/{boot → wire}/binding.js +5 -62
- package/dist/wire/binding.js.map +1 -0
- package/dist/wire/call.d.ts +25 -172
- package/dist/wire/call.d.ts.map +1 -1
- package/dist/wire/call.js +15 -166
- package/dist/wire/call.js.map +1 -1
- package/dist/wire/drift.d.ts +3 -28
- package/dist/wire/drift.d.ts.map +1 -1
- package/dist/wire/drift.js +4 -23
- package/dist/wire/drift.js.map +1 -1
- package/dist/wire/errors.d.ts +4 -24
- package/dist/wire/errors.d.ts.map +1 -1
- package/dist/wire/errors.js +4 -24
- package/dist/wire/errors.js.map +1 -1
- package/dist/wire/http-error.d.ts +2 -13
- package/dist/wire/http-error.d.ts.map +1 -1
- package/dist/wire/http-error.js +5 -19
- package/dist/wire/http-error.js.map +1 -1
- package/dist/wire/loggerMiddleware.d.ts +2 -8
- package/dist/wire/loggerMiddleware.d.ts.map +1 -1
- package/dist/wire/loggerMiddleware.js +1 -7
- package/dist/wire/loggerMiddleware.js.map +1 -1
- package/dist/wire/middleware.d.ts +3 -7
- package/dist/wire/middleware.d.ts.map +1 -1
- package/dist/wire/middleware.js +1 -5
- package/dist/wire/middleware.js.map +1 -1
- package/dist/wire/operation.d.ts +12 -74
- package/dist/wire/operation.d.ts.map +1 -1
- package/dist/wire/operation.js +4 -66
- package/dist/wire/operation.js.map +1 -1
- package/dist/wire/signature.d.ts +37 -0
- package/dist/wire/signature.d.ts.map +1 -0
- package/dist/wire/signature.js +2 -0
- package/dist/wire/signature.js.map +1 -0
- package/package.json +3 -3
- package/src/boot/Emissions.ts +22 -119
- package/src/boot/ambient-port.ts +3 -24
- package/src/boot/ambient.als.ts +7 -12
- package/src/boot/ambient.queue.ts +2 -5
- package/src/boot/apply.ts +3 -15
- package/src/boot/auth.ts +6 -16
- package/src/boot/boot.ts +8 -23
- package/src/boot/bootstrap.ts +117 -173
- package/src/boot/card.ts +84 -0
- package/src/boot/frame.ts +31 -65
- package/src/boot/hosted.ts +15 -40
- package/src/boot/ownership.ts +14 -49
- package/src/boot/ports.ts +2 -15
- package/src/boot/remote.ts +11 -58
- package/src/boot/runner.ts +17 -0
- package/src/boot/seed.ts +11 -42
- package/src/boot/statement-drift.ts +10 -28
- package/src/boot/together.ts +38 -72
- package/src/boot/types.ts +36 -180
- package/src/{builtins → builtin}/config.ts +1 -7
- package/src/{builtins → builtin}/logger.ts +6 -39
- package/src/config-loader.ts +12 -71
- package/src/contract.ts +15 -39
- package/src/crypto/encoding.ts +2 -15
- package/src/crypto/node.ts +1 -7
- package/src/crypto/port.ts +2 -18
- package/src/crypto/webcrypto.ts +1 -12
- package/src/{scan/declare.ts → declare.ts} +11 -42
- package/src/define.ts +2 -3
- package/src/descriptor/Fronds.ts +47 -0
- package/src/descriptor/frond.ts +145 -0
- package/src/dispatch/ArgumentResolver.ts +54 -8
- package/src/dispatch/DispatchEvent.ts +2 -2
- package/src/dispatch/DispatchLifecycle.ts +1 -7
- package/src/dispatch/DispatchPort.ts +1 -1
- package/src/dispatch/Dispatcher.ts +3 -3
- package/src/dispatch/HandlerFacade.ts +231 -0
- package/src/dispatch/LocalRoutePolicy.ts +4 -4
- package/src/dispatch/OperationRoute.ts +2 -2
- package/src/dispatch/OutputView.ts +24 -2
- package/src/dispatch/Route.ts +2 -4
- package/src/dispatch/RoutePolicy.ts +1 -1
- package/src/dispatch/RouteRegistry.ts +2 -2
- package/src/dispatch/RouteResolver.ts +2 -4
- package/src/dispatch/StorageGuard.ts +75 -23
- package/src/dispatch/presenterArguments.ts +25 -0
- package/src/dispatch/{RemoteRouteResolver.ts → remoteRoutes.ts} +7 -9
- package/src/dispatch/routeNotFound.ts +33 -0
- package/src/dispatch/validateInput.ts +28 -0
- package/src/effective-operation.ts +60 -37
- package/src/emit.ts +5 -63
- package/src/entry/facade.ts +44 -0
- package/src/entry/transport.ts +16 -0
- package/src/frond-config.ts +8 -71
- package/src/graph.ts +1 -1
- package/src/identity-keys.ts +3 -16
- package/src/identity.ts +12 -80
- package/src/imports.ts +3 -32
- package/src/index.ts +28 -33
- package/src/loader.ts +2 -16
- package/src/node.ts +2 -11
- package/src/prefab/collector.ts +1 -22
- package/src/prefab/crud.ts +51 -90
- package/src/prefab/mirror.ts +9 -49
- package/src/prefab/prefab.ts +2 -21
- package/src/prefab/presenter.ts +2 -36
- package/src/prefab/repository.ts +32 -108
- package/src/scan/adapters.ts +32 -0
- package/src/scan/bundling.ts +1 -12
- package/src/scan/conventions.ts +6 -40
- package/src/scan/emit.ts +7 -43
- package/src/scan/handler-parser.ts +41 -163
- package/src/scan/result.ts +29 -0
- package/src/scan/scanner.ts +40 -138
- package/src/scan/statement.ts +6 -31
- package/src/source.ts +44 -0
- package/src/storage.ts +141 -0
- package/src/store.ts +152 -0
- package/src/verify.ts +19 -60
- package/src/wire/CallLog.ts +30 -0
- package/src/{contract → wire}/Invocation.ts +24 -17
- package/src/{contract → wire}/RouteAddress.ts +10 -0
- package/src/wire/binding.ts +102 -0
- package/src/wire/call.ts +30 -261
- package/src/wire/drift.ts +5 -30
- package/src/wire/errors.ts +4 -24
- package/src/wire/http-error.ts +5 -19
- package/src/wire/loggerMiddleware.ts +2 -8
- package/src/wire/middleware.ts +3 -7
- package/src/wire/operation.ts +13 -110
- package/src/wire/signature.ts +38 -0
- package/dist/boot/HandlerFacade.d.ts.map +0 -1
- package/dist/boot/HandlerFacade.js.map +0 -1
- package/dist/boot/binding.d.ts +0 -60
- package/dist/boot/binding.d.ts.map +0 -1
- package/dist/boot/binding.js.map +0 -1
- package/dist/builtins/config.d.ts +0 -13
- package/dist/builtins/config.d.ts.map +0 -1
- package/dist/builtins/config.js +0 -21
- package/dist/builtins/config.js.map +0 -1
- package/dist/builtins/logger.d.ts.map +0 -1
- package/dist/builtins/logger.js.map +0 -1
- package/dist/contract/Call.d.ts +0 -10
- package/dist/contract/Call.d.ts.map +0 -1
- package/dist/contract/Call.js +0 -15
- package/dist/contract/Call.js.map +0 -1
- package/dist/contract/CallLog.d.ts +0 -57
- package/dist/contract/CallLog.d.ts.map +0 -1
- package/dist/contract/Invocation.d.ts +0 -27
- package/dist/contract/Invocation.d.ts.map +0 -1
- package/dist/contract/Invocation.js +0 -59
- package/dist/contract/Invocation.js.map +0 -1
- package/dist/contract/RouteAddress.d.ts +0 -17
- package/dist/contract/RouteAddress.d.ts.map +0 -1
- package/dist/contract/RouteAddress.js.map +0 -1
- package/dist/dispatch/InputValidator.d.ts +0 -7
- package/dist/dispatch/InputValidator.d.ts.map +0 -1
- package/dist/dispatch/InputValidator.js +0 -22
- package/dist/dispatch/InputValidator.js.map +0 -1
- package/dist/dispatch/OperationExecutor.d.ts +0 -25
- package/dist/dispatch/OperationExecutor.d.ts.map +0 -1
- package/dist/dispatch/OperationExecutor.js +0 -32
- package/dist/dispatch/OperationExecutor.js.map +0 -1
- package/dist/dispatch/OutputProjector.d.ts +0 -12
- package/dist/dispatch/OutputProjector.d.ts.map +0 -1
- package/dist/dispatch/OutputProjector.js +0 -30
- package/dist/dispatch/OutputProjector.js.map +0 -1
- package/dist/dispatch/PresenterArgumentResolver.d.ts +0 -12
- package/dist/dispatch/PresenterArgumentResolver.d.ts.map +0 -1
- package/dist/dispatch/PresenterArgumentResolver.js +0 -20
- package/dist/dispatch/PresenterArgumentResolver.js.map +0 -1
- package/dist/dispatch/RemoteRouteResolver.d.ts +0 -13
- package/dist/dispatch/RemoteRouteResolver.d.ts.map +0 -1
- package/dist/dispatch/RemoteRouteResolver.js.map +0 -1
- package/dist/dispatch/RouteNotFoundError.d.ts +0 -10
- package/dist/dispatch/RouteNotFoundError.d.ts.map +0 -1
- package/dist/dispatch/RouteNotFoundError.js +0 -24
- package/dist/dispatch/RouteNotFoundError.js.map +0 -1
- package/dist/entry/DynamicFacade.d.ts +0 -10
- package/dist/entry/DynamicFacade.d.ts.map +0 -1
- package/dist/entry/DynamicFacade.js +0 -27
- package/dist/entry/DynamicFacade.js.map +0 -1
- package/dist/entry/FacadeEntry.d.ts +0 -11
- package/dist/entry/FacadeEntry.d.ts.map +0 -1
- package/dist/entry/FacadeEntry.js +0 -26
- package/dist/entry/FacadeEntry.js.map +0 -1
- package/dist/entry/TransportEntry.d.ts +0 -13
- package/dist/entry/TransportEntry.d.ts.map +0 -1
- package/dist/entry/TransportEntry.js +0 -24
- package/dist/entry/TransportEntry.js.map +0 -1
- package/dist/orm.d.ts +0 -207
- package/dist/orm.d.ts.map +0 -1
- package/dist/orm.js +0 -66
- package/dist/orm.js.map +0 -1
- package/dist/scan/Fronds.d.ts +0 -45
- package/dist/scan/Fronds.d.ts.map +0 -1
- package/dist/scan/Fronds.js +0 -66
- package/dist/scan/Fronds.js.map +0 -1
- package/dist/scan/declare.d.ts +0 -71
- package/dist/scan/declare.d.ts.map +0 -1
- package/dist/scan/declare.js.map +0 -1
- package/dist/scan/frond.d.ts +0 -224
- package/dist/scan/frond.d.ts.map +0 -1
- package/src/boot/HandlerFacade.ts +0 -242
- package/src/boot/binding.ts +0 -182
- package/src/contract/Call.ts +0 -18
- package/src/contract/CallLog.ts +0 -55
- package/src/dispatch/InputValidator.ts +0 -28
- package/src/dispatch/OperationExecutor.ts +0 -60
- package/src/dispatch/OutputProjector.ts +0 -32
- package/src/dispatch/PresenterArgumentResolver.ts +0 -25
- package/src/dispatch/RouteNotFoundError.ts +0 -29
- package/src/entry/DynamicFacade.ts +0 -28
- package/src/entry/FacadeEntry.ts +0 -32
- package/src/entry/TransportEntry.ts +0 -30
- package/src/orm.ts +0 -252
- package/src/scan/Fronds.ts +0 -73
- package/src/scan/frond.ts +0 -235
- /package/dist/{scan → descriptor}/frond.js +0 -0
- /package/dist/{contract → wire}/CallLog.js +0 -0
|
@@ -1,242 +0,0 @@
|
|
|
1
|
-
import { lowerFirst, type Fields } from '@fougere/schema';
|
|
2
|
-
import type { Container } from '@fougere/container';
|
|
3
|
-
import type { AppMiddleware } from '../wire/middleware.js';
|
|
4
|
-
import type { CollectorResolver } from './binding.js';
|
|
5
|
-
import { collectorKeyOf } from '../prefab/collector.js';
|
|
6
|
-
import { presenterKeyOf } from '../prefab/presenter.js';
|
|
7
|
-
import { repositoryKeyOf } from '../prefab/repository.js';
|
|
8
|
-
import { targetOf } from '../prefab/prefab.js';
|
|
9
|
-
import type { OperationContract, OperationsMap } from '../wire/operation.js';
|
|
10
|
-
import type { EffectiveOperation, EffectiveOperationsMap } from '../effective-operation.js';
|
|
11
|
-
import type { InvocationContext } from '../contract/Invocation.js';
|
|
12
|
-
import type { Emissions } from './Emissions.js';
|
|
13
|
-
import type { Logger } from '../builtins/logger.js';
|
|
14
|
-
import type { EntityEntry, HandlerEntry, PresenterEntry } from '../scan/frond.js';
|
|
15
|
-
import { InputValidator } from '../dispatch/InputValidator.js';
|
|
16
|
-
import { ArgumentResolver } from '../dispatch/ArgumentResolver.js';
|
|
17
|
-
import { OperationExecutor } from '../dispatch/OperationExecutor.js';
|
|
18
|
-
import { OutputProjector } from '../dispatch/OutputProjector.js';
|
|
19
|
-
import { OutputView } from '../dispatch/OutputView.js';
|
|
20
|
-
import { PresenterExecutor } from '../dispatch/PresenterExecutor.js';
|
|
21
|
-
import { PresenterArgumentResolver } from '../dispatch/PresenterArgumentResolver.js';
|
|
22
|
-
|
|
23
|
-
/** What this door is about: a handler, the entity behind it when there is one, and where it resolves. */
|
|
24
|
-
export interface Doorway {
|
|
25
|
-
handler: HandlerEntry;
|
|
26
|
-
/** Handlers in the owning frond, used to realize a resolved implementation override. */
|
|
27
|
-
handlers: readonly HandlerEntry[];
|
|
28
|
-
/** The canonical operation table resolved before boot performs any side effect. */
|
|
29
|
-
operations: EffectiveOperationsMap;
|
|
30
|
-
/** The subject — absent is ordinary: a health check owns no row. */
|
|
31
|
-
entity: EntityEntry | undefined;
|
|
32
|
-
/** The scope the handler and its collectors resolve in — a surface gets its own. */
|
|
33
|
-
scope: Container;
|
|
34
|
-
/** The container key this door answers under. */
|
|
35
|
-
key: string;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** What the frond and the boot supply to every door alike. */
|
|
39
|
-
export interface Wiring {
|
|
40
|
-
/** The frond this door belongs to — travels on every OperationContext. */
|
|
41
|
-
frond: string;
|
|
42
|
-
/** The frond's own scope — where presenters live, whatever sub-scope the door uses. */
|
|
43
|
-
frondScope: Container;
|
|
44
|
-
log: Logger;
|
|
45
|
-
/** Entity names this frond has a collector for. */
|
|
46
|
-
collectors: Set<string>;
|
|
47
|
-
presenters: Map<string, PresenterEntry>;
|
|
48
|
-
/** The middlewares that apply to an address, read at call time and never at boot. */
|
|
49
|
-
middlewaresFor: (address: string) => AppMiddleware[];
|
|
50
|
-
emissions: Emissions;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/** Adapts one handler door to executable operations. */
|
|
54
|
-
export class HandlerFacade {
|
|
55
|
-
/** Rich operation facts shared with check, explain and adapters. */
|
|
56
|
-
readonly effectiveOperations: EffectiveOperationsMap;
|
|
57
|
-
/** Contracts served by this door. */
|
|
58
|
-
readonly contracts: OperationsMap;
|
|
59
|
-
|
|
60
|
-
/** The callable surface: op name → the function a caller reaches. */
|
|
61
|
-
readonly ops: Record<string, Function> = {};
|
|
62
|
-
|
|
63
|
-
private readonly cachedViews = new Map<string, OutputView>();
|
|
64
|
-
private instance: any;
|
|
65
|
-
private readonly implementationKeys = new Map<string, string>();
|
|
66
|
-
private readonly implementationInstances = new Map<string, any>();
|
|
67
|
-
private readonly inputValidator = new InputValidator();
|
|
68
|
-
private readonly argumentResolver = new ArgumentResolver(
|
|
69
|
-
(typeName) => this.collectorResolver(typeName),
|
|
70
|
-
);
|
|
71
|
-
private readonly presenterArguments: PresenterArgumentResolver;
|
|
72
|
-
|
|
73
|
-
constructor(private readonly door: Doorway, private readonly wiring: Wiring) {
|
|
74
|
-
const { handler, entity } = door;
|
|
75
|
-
this.presenterArguments = new PresenterArgumentResolver(
|
|
76
|
-
this.argumentResolver,
|
|
77
|
-
wiring.collectors,
|
|
78
|
-
);
|
|
79
|
-
this.refuseCrudWithoutRepository(handler);
|
|
80
|
-
|
|
81
|
-
door.scope.register(this.handlerKey, handler.ctor, { deps: this.depsOf(handler) });
|
|
82
|
-
|
|
83
|
-
this.effectiveOperations = door.operations;
|
|
84
|
-
this.contracts = new Map(
|
|
85
|
-
[...door.operations].map(([name, operation]) => [name, operation as OperationContract] as const),
|
|
86
|
-
);
|
|
87
|
-
handler.operations = this.contracts;
|
|
88
|
-
|
|
89
|
-
// Register model-selected implementations in the same execution scope.
|
|
90
|
-
for (const [name, operation] of door.operations) {
|
|
91
|
-
if (this.isBaseImplementation(operation)) continue;
|
|
92
|
-
const implementation = this.implementationHandler(name);
|
|
93
|
-
this.refuseCrudWithoutRepository(implementation);
|
|
94
|
-
const key = `${this.handlerKey}:implementation:${operation.implementation.className}`;
|
|
95
|
-
if (!this.implementationKeys.has(operation.implementation.className)) {
|
|
96
|
-
door.scope.register(key, implementation.ctor, { deps: this.depsOf(implementation) });
|
|
97
|
-
this.implementationKeys.set(operation.implementation.className, key);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Emissions use the same contracts and execution path as direct calls.
|
|
102
|
-
wiring.emissions.note(this.contracts, door.key);
|
|
103
|
-
// Only declared operations become callable façade members.
|
|
104
|
-
for (const op of this.contracts.keys()) this.ops[op] = this.wrap(op);
|
|
105
|
-
|
|
106
|
-
if (this.inheritsCrud(handler) && !entity) {
|
|
107
|
-
// An installed Crud subject may be absent from the local scan.
|
|
108
|
-
wiring.log.debug(`${handler.ctor.name} extends Crud() and no scanned entity is named `
|
|
109
|
-
+ `'${this.subjectOf(handler)}' — installed entity, or a missing one: no ORM will be injected`);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/** Storage follows the Crud subject, which may differ from the door address. */
|
|
114
|
-
private subjectOf(handler: HandlerEntry): string {
|
|
115
|
-
const target = targetOf(handler.ctor);
|
|
116
|
-
return target?.name ? lowerFirst(target.name) : handler.address;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
private inheritsCrud(handler: HandlerEntry): boolean {
|
|
120
|
-
const proto = handler.ctor.prototype;
|
|
121
|
-
return typeof proto?.list === 'function' && typeof proto?.findById === 'function';
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
private get handlerKey(): string {
|
|
125
|
-
return `_handler:${this.door.key}`;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
private depsOf(handler: HandlerEntry): string[] {
|
|
129
|
-
const { deps } = handler;
|
|
130
|
-
if (deps.length > 0) return deps;
|
|
131
|
-
return this.inheritsCrud(handler) ? [repositoryKeyOf(this.subjectOf(handler))] : [];
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/** A custom Crud constructor must explicitly receive its repository. */
|
|
135
|
-
private refuseCrudWithoutRepository(handler: HandlerEntry): void {
|
|
136
|
-
const repoTypeName = repositoryKeyOf(this.subjectOf(handler));
|
|
137
|
-
if (!this.inheritsCrud(handler) || handler.deps.length === 0 || handler.deps.includes(repoTypeName)) return;
|
|
138
|
-
throw new Error(
|
|
139
|
-
`${handler.ctor.name} extends Crud() and declares a constructor, so its storage is no ` +
|
|
140
|
-
`longer injected for it — but it does not take any.\n` +
|
|
141
|
-
` Add it and hand it to super():\n` +
|
|
142
|
-
` constructor(repo: ${repoTypeName}, …) { super(repo); }`,
|
|
143
|
-
);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/** Resolve and cache the output view declared for one operation. */
|
|
147
|
-
private viewOf(op: string): OutputView {
|
|
148
|
-
const known = this.cachedViews.get(op);
|
|
149
|
-
if (known) return known;
|
|
150
|
-
|
|
151
|
-
const operation = this.effectiveOperations.get(op);
|
|
152
|
-
const schema = operation?.output as { getFields?: () => Fields } | undefined;
|
|
153
|
-
const resolved = new OutputView(
|
|
154
|
-
typeof schema?.getFields === 'function' ? schema.getFields() : {},
|
|
155
|
-
operation?.outputClosed ?? false,
|
|
156
|
-
);
|
|
157
|
-
this.cachedViews.set(op, resolved);
|
|
158
|
-
return resolved;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
private collectorResolver = (typeName: string): CollectorResolver | undefined => {
|
|
162
|
-
try { return this.door.scope.resolve(collectorKeyOf(typeName)) as CollectorResolver; }
|
|
163
|
-
catch { return undefined; }
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
/** The handler itself, resolved on first call — never at boot. */
|
|
167
|
-
private resolvedHandler(): any {
|
|
168
|
-
if (!this.instance) this.instance = this.door.scope.resolve(this.handlerKey);
|
|
169
|
-
return this.instance;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
private isBaseImplementation(operation: EffectiveOperation): boolean {
|
|
173
|
-
return operation.implementation.className === this.door.handler.ctor.name
|
|
174
|
-
&& operation.implementation.address === this.door.handler.address
|
|
175
|
-
&& operation.implementation.filePath === this.door.handler.filePath;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/** The exact handler entry the pure model selected; no name-only retry or fallback. */
|
|
179
|
-
private implementationHandler(operationName: string): HandlerEntry {
|
|
180
|
-
const operation = this.effectiveOperations.get(operationName)!;
|
|
181
|
-
const matches = this.door.handlers.filter((handler) =>
|
|
182
|
-
handler.ctor.name === operation.implementation.className
|
|
183
|
-
&& handler.address === operation.implementation.address
|
|
184
|
-
&& handler.filePath === operation.implementation.filePath);
|
|
185
|
-
if (matches.length !== 1) {
|
|
186
|
-
throw new Error(
|
|
187
|
-
`EffectiveOperation '${operation.id}' names ${operation.implementation.className}.`
|
|
188
|
-
+ `${operation.implementation.method}, but boot found ${matches.length} matching handlers.`,
|
|
189
|
-
);
|
|
190
|
-
}
|
|
191
|
-
return matches[0]!;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
private resolvedImplementation(operationName: string): { instance: any; method: string } {
|
|
195
|
-
const operation = this.effectiveOperations.get(operationName)!;
|
|
196
|
-
if (this.isBaseImplementation(operation)) {
|
|
197
|
-
return { instance: this.resolvedHandler(), method: operation.implementation.method };
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
const className = operation.implementation.className;
|
|
201
|
-
const key = this.implementationKeys.get(className);
|
|
202
|
-
if (!key) throw new Error(`No registered implementation for EffectiveOperation '${operation.id}'.`);
|
|
203
|
-
let instance = this.implementationInstances.get(key);
|
|
204
|
-
if (!instance) {
|
|
205
|
-
instance = this.door.scope.resolve(key);
|
|
206
|
-
this.implementationInstances.set(key, instance);
|
|
207
|
-
}
|
|
208
|
-
return { instance, method: operation.implementation.method };
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
private wrap(op: string): (invocation?: InvocationContext) => Promise<unknown> {
|
|
212
|
-
const address = this.door.handler.address;
|
|
213
|
-
const contract = this.contracts.get(op);
|
|
214
|
-
const view = this.viewOf(op);
|
|
215
|
-
const presenter = this.wiring.presenters.get(address);
|
|
216
|
-
const executor = new OperationExecutor({
|
|
217
|
-
entity: address,
|
|
218
|
-
frond: this.wiring.frond,
|
|
219
|
-
operation: op,
|
|
220
|
-
contract,
|
|
221
|
-
middlewares: () => this.wiring.middlewaresFor(address),
|
|
222
|
-
validator: this.inputValidator,
|
|
223
|
-
arguments: this.argumentResolver,
|
|
224
|
-
invoke: async (args) => {
|
|
225
|
-
const implementation = this.resolvedImplementation(op);
|
|
226
|
-
return implementation.instance[implementation.method](...args);
|
|
227
|
-
},
|
|
228
|
-
projector: new OutputProjector(view),
|
|
229
|
-
...(view.closed || !presenter ? {} : {
|
|
230
|
-
present: async (result: unknown, effective: InvocationContext) =>
|
|
231
|
-
new PresenterExecutor(
|
|
232
|
-
this.wiring.frondScope.resolve(presenterKeyOf(address)),
|
|
233
|
-
presenter.fields,
|
|
234
|
-
address,
|
|
235
|
-
op,
|
|
236
|
-
).present(result, await this.presenterArguments.resolve(presenter, effective)),
|
|
237
|
-
}),
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
return (invocation) => executor.execute(invocation);
|
|
241
|
-
}
|
|
242
|
-
}
|
package/src/boot/binding.ts
DELETED
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Where each parameter of an operation gets its value — decided once at boot from the
|
|
3
|
-
* parsed signature, replayed per call by `resolveArgs`.
|
|
4
|
-
*
|
|
5
|
-
* The branches are ORDERED and each states why it sits where it does; the list used to
|
|
6
|
-
* be repeated here too, and it had already lost `Fact` — the one whose position is
|
|
7
|
-
* load-bearing, since the fall-through would otherwise hand it the caller's body.
|
|
8
|
-
*/
|
|
9
|
-
import type { ParsedParam } from '../scan/handler-parser.js';
|
|
10
|
-
import type { InvocationContext } from '../contract/Invocation.js';
|
|
11
|
-
import { lowerFirst } from '@fougere/schema';
|
|
12
|
-
|
|
13
|
-
// ── Types ─────────────────────────────────────
|
|
14
|
-
|
|
15
|
-
type ParamSource =
|
|
16
|
-
| { kind: 'collector'; typeName: string }
|
|
17
|
-
/**
|
|
18
|
-
* `Fact<PostPublished>` — something that happened, not something a caller typed.
|
|
19
|
-
*
|
|
20
|
-
* It resolves from the body exactly like `body` does, and that is deliberate: an
|
|
21
|
-
* emission and a direct call ARE the same call, so a subscriber cannot tell them apart
|
|
22
|
-
* and does not need to. The branch exists so the PLAN says what this parameter is —
|
|
23
|
-
* that sentence is what makes the subscriber index readable without reparsing types.
|
|
24
|
-
*/
|
|
25
|
-
| { kind: 'fact'; factName: string }
|
|
26
|
-
| { kind: 'param'; name: string; coerce?: 'number' | 'boolean' }
|
|
27
|
-
| { kind: 'body' }
|
|
28
|
-
| { kind: 'context' }
|
|
29
|
-
/** The whole query bag, for an op whose argument IS the options (list). */
|
|
30
|
-
| { kind: 'query' };
|
|
31
|
-
|
|
32
|
-
interface ParamBinding {
|
|
33
|
-
name: string;
|
|
34
|
-
source: ParamSource;
|
|
35
|
-
optional: boolean;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export type BindingPlan = ParamBinding[];
|
|
39
|
-
|
|
40
|
-
// ── Primitives ────────────────────────────────
|
|
41
|
-
|
|
42
|
-
const PRIMITIVES = new Set(['string', 'number', 'boolean']);
|
|
43
|
-
|
|
44
|
-
function coercionFor(typeName: string): 'number' | 'boolean' | undefined {
|
|
45
|
-
if (typeName === 'number') return 'number';
|
|
46
|
-
if (typeName === 'boolean') return 'boolean';
|
|
47
|
-
return undefined;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// ── Compute ───────────────────────────────────
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Build a BindingPlan from parsed method params.
|
|
54
|
-
*
|
|
55
|
-
* @param params - Parsed parameter list from AST
|
|
56
|
-
* @param collectorTypeNames - Registration keys of the types a Collector answers for
|
|
57
|
-
*/
|
|
58
|
-
export function computeBindingPlan(
|
|
59
|
-
params: ParsedParam[],
|
|
60
|
-
collectorTypeNames: Set<string>,
|
|
61
|
-
): BindingPlan {
|
|
62
|
-
return params.map((param) => {
|
|
63
|
-
const typeName = param.type.name;
|
|
64
|
-
// `lowerFirst`, never `toLowerCase()`: the collector set is keyed the way the
|
|
65
|
-
// scan spells it, and the two agree on one word only — `AuthorUser` looked up as
|
|
66
|
-
// `authoruser` missed `authorUser` and fell through to branch 4, the request body.
|
|
67
|
-
const typeKey = lowerFirst(typeName);
|
|
68
|
-
|
|
69
|
-
// 0. Fact — `Fact<X>` names itself, so nothing has to be known in advance. It comes
|
|
70
|
-
// FIRST because branch 4 would otherwise hand it the caller's body under the name
|
|
71
|
-
// of something that happened.
|
|
72
|
-
const factOf = param.type.name === 'Fact' ? param.type.generics?.[0]?.name : undefined;
|
|
73
|
-
if (factOf) {
|
|
74
|
-
return {
|
|
75
|
-
name: param.name,
|
|
76
|
-
source: { kind: 'fact' as const, factName: lowerFirst(factOf) },
|
|
77
|
-
optional: param.optional ?? false,
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// 1. Collector — param type matches a type some collector answers for
|
|
82
|
-
if (collectorTypeNames.has(typeKey)) {
|
|
83
|
-
return {
|
|
84
|
-
name: param.name,
|
|
85
|
-
source: { kind: 'collector' as const, typeName: typeKey },
|
|
86
|
-
optional: param.optional ?? false,
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// 2. InvocationContext — inject the full context
|
|
91
|
-
if (typeName === 'InvocationContext') {
|
|
92
|
-
return {
|
|
93
|
-
name: param.name,
|
|
94
|
-
source: { kind: 'context' as const },
|
|
95
|
-
optional: param.optional ?? false,
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// 3. Primitives — matched by name from params > query
|
|
100
|
-
if (PRIMITIVES.has(typeName)) {
|
|
101
|
-
return {
|
|
102
|
-
name: param.name,
|
|
103
|
-
source: {
|
|
104
|
-
kind: 'param' as const,
|
|
105
|
-
name: param.name,
|
|
106
|
-
coerce: coercionFor(typeName),
|
|
107
|
-
},
|
|
108
|
-
optional: param.optional ?? false,
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// 4. Everything else — body
|
|
113
|
-
return {
|
|
114
|
-
name: param.name,
|
|
115
|
-
source: { kind: 'body' as const },
|
|
116
|
-
optional: param.optional ?? false,
|
|
117
|
-
};
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// ── Resolve ───────────────────────────────────
|
|
122
|
-
|
|
123
|
-
export interface CollectorResolver {
|
|
124
|
-
collect(ctx: InvocationContext): Promise<unknown>;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Resolve handler arguments from a BindingPlan + InvocationContext.
|
|
129
|
-
*/
|
|
130
|
-
export async function resolveArgs(
|
|
131
|
-
plan: BindingPlan,
|
|
132
|
-
ctx: InvocationContext,
|
|
133
|
-
resolveCollector?: (typeName: string) => CollectorResolver | undefined,
|
|
134
|
-
): Promise<unknown[]> {
|
|
135
|
-
const args: unknown[] = [];
|
|
136
|
-
|
|
137
|
-
for (const binding of plan) {
|
|
138
|
-
switch (binding.source.kind) {
|
|
139
|
-
case 'collector': {
|
|
140
|
-
const collector = resolveCollector?.(binding.source.typeName);
|
|
141
|
-
args.push(collector ? await collector.collect(ctx) : undefined);
|
|
142
|
-
break;
|
|
143
|
-
}
|
|
144
|
-
case 'context': {
|
|
145
|
-
args.push(ctx);
|
|
146
|
-
break;
|
|
147
|
-
}
|
|
148
|
-
case 'param': {
|
|
149
|
-
// `null` is a value, not a miss. Nullish coalescing used to make an explicit
|
|
150
|
-
// nullable path/GraphQL argument fall through to query (or become undefined),
|
|
151
|
-
// collapsing `T | null` into `T | undefined`. Only undefined means absent.
|
|
152
|
-
const fromParams = ctx.params[binding.source.name];
|
|
153
|
-
let val: unknown = fromParams === undefined
|
|
154
|
-
? ctx.query[binding.source.name]
|
|
155
|
-
: fromParams;
|
|
156
|
-
if (val != null && binding.source.coerce === 'number') val = Number(val);
|
|
157
|
-
if (val != null && binding.source.coerce === 'boolean') val = val === 'true' || val === '1' || val === true;
|
|
158
|
-
args.push(val);
|
|
159
|
-
break;
|
|
160
|
-
}
|
|
161
|
-
case 'fact': {
|
|
162
|
-
// A fact IS the payload — the whole of what happened, never a piece of it.
|
|
163
|
-
// Identical to `body` today, and deliberately not sharing its branch: the two
|
|
164
|
-
// agree by coincidence, not by rule, and the day `body` learns to look up a
|
|
165
|
-
// value by parameter name a subscriber would receive ONE FIELD of the fact it
|
|
166
|
-
// subscribed to. Splitting it costs nothing and removes that trap.
|
|
167
|
-
args.push(ctx.body);
|
|
168
|
-
break;
|
|
169
|
-
}
|
|
170
|
-
case 'body': {
|
|
171
|
-
args.push(ctx.body);
|
|
172
|
-
break;
|
|
173
|
-
}
|
|
174
|
-
case 'query': {
|
|
175
|
-
args.push(ctx.query);
|
|
176
|
-
break;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return args;
|
|
182
|
-
}
|
package/src/contract/Call.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { Invocation, type InvocationInput } from './Invocation.js';
|
|
2
|
-
import type { RouteAddress } from './RouteAddress.js';
|
|
3
|
-
|
|
4
|
-
/** One normalized request: where it goes and what the caller supplied. */
|
|
5
|
-
export class Call {
|
|
6
|
-
readonly address: RouteAddress;
|
|
7
|
-
readonly invocation: Invocation;
|
|
8
|
-
|
|
9
|
-
constructor(address: RouteAddress, invocation?: InvocationInput) {
|
|
10
|
-
this.address = address;
|
|
11
|
-
this.invocation = Invocation.from(invocation);
|
|
12
|
-
Object.freeze(this);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
withInvocation(invocation: Invocation): Call {
|
|
16
|
-
return new Call(this.address, invocation);
|
|
17
|
-
}
|
|
18
|
-
}
|
package/src/contract/CallLog.ts
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import type { DispatchEvent } from '../dispatch/DispatchEvent.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* What crosses the door: the address, the route it took, and the verdict.
|
|
5
|
-
*
|
|
6
|
-
* It lives here rather than beside its producer for the reason `TopologyReport` does: it
|
|
7
|
-
* crosses a process boundary, so a reader that never installed `@fougere/calls` — the CLI
|
|
8
|
-
* — needs its shape, and putting it there is what produces a hand-copied duplicate.
|
|
9
|
-
*
|
|
10
|
-
* Never the body. Same rule the topology report states — a remote destination is named,
|
|
11
|
-
* not disclosed — and it holds here for the same reason: this answer leaves the process.
|
|
12
|
-
*/
|
|
13
|
-
export interface CallRecord {
|
|
14
|
-
/** Monotonic, and the whole cursor protocol: a reader asks for what is above its own. */
|
|
15
|
-
seq: number;
|
|
16
|
-
frond?: string;
|
|
17
|
-
entity: string;
|
|
18
|
-
operation: string;
|
|
19
|
-
surface?: string;
|
|
20
|
-
/** Known at `resolved`, so absent on a call that never found a route. */
|
|
21
|
-
route?: NonNullable<DispatchEvent['routeKind']>;
|
|
22
|
-
/**
|
|
23
|
-
* The traceparent the invocation carried, when one did.
|
|
24
|
-
*
|
|
25
|
-
* One panel reads one process, so this is what lets two of them be sewn: the process
|
|
26
|
-
* that sent and the process that executed share it, and the gap between their two
|
|
27
|
-
* durations IS the cost of the wire rather than a deduction.
|
|
28
|
-
*/
|
|
29
|
-
trace?: string;
|
|
30
|
-
/**
|
|
31
|
-
* The peer that established this call, when one did.
|
|
32
|
-
*
|
|
33
|
-
* A hosted frond serves several consumers, so its own ring mixes them: this is what
|
|
34
|
-
* separates them. Absent on a call nobody signed — a loopback dev boot has no identity.
|
|
35
|
-
*/
|
|
36
|
-
caller?: string;
|
|
37
|
-
startedAt: number;
|
|
38
|
-
/** Known at `settled`. */
|
|
39
|
-
ms?: number;
|
|
40
|
-
verdict: 'running' | 'ok' | 'failed';
|
|
41
|
-
refusal?: { code?: string; message: string };
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* One page of the ring.
|
|
46
|
-
*
|
|
47
|
-
* `dropped` is what the ring could not keep — an absence is named rather than left to
|
|
48
|
-
* look like a quiet period.
|
|
49
|
-
*/
|
|
50
|
-
export interface CallPage {
|
|
51
|
-
calls: CallRecord[];
|
|
52
|
-
cursor: number;
|
|
53
|
-
inFlight: number;
|
|
54
|
-
dropped: number;
|
|
55
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { RowJudge, type SchemaView } from '@fougere/schema';
|
|
2
|
-
import type { InvocationContext } from '../contract/Invocation.js';
|
|
3
|
-
import { ErrorCode, FougereError } from '../wire/errors.js';
|
|
4
|
-
|
|
5
|
-
/** Validates and decodes the input body declared by one operation contract. */
|
|
6
|
-
export class InputValidator {
|
|
7
|
-
validate(
|
|
8
|
-
schema: SchemaView | undefined,
|
|
9
|
-
invocation: InvocationContext,
|
|
10
|
-
entity: string,
|
|
11
|
-
operation: string,
|
|
12
|
-
): InvocationContext {
|
|
13
|
-
if (!schema || invocation.body === undefined || invocation.body === null) return invocation;
|
|
14
|
-
|
|
15
|
-
const result = RowJudge.of(schema.getFields(), { patch: schema.getOpts().patch })
|
|
16
|
-
.check(invocation.body);
|
|
17
|
-
if (!result.success) {
|
|
18
|
-
throw new FougereError({
|
|
19
|
-
code: ErrorCode.VALIDATION_FAILED,
|
|
20
|
-
message: result.errors.map((error) => `${error.path}: ${error.message}`).join(', '),
|
|
21
|
-
details: result.errors,
|
|
22
|
-
entity,
|
|
23
|
-
operation,
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
return { ...invocation, body: result.data };
|
|
27
|
-
}
|
|
28
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import type { InvocationContext } from '../contract/Invocation.js';
|
|
2
|
-
import { canonicalInvocation } from '../contract/Invocation.js';
|
|
3
|
-
import type { OperationContract } from '../wire/operation.js';
|
|
4
|
-
import {
|
|
5
|
-
runMiddlewares,
|
|
6
|
-
type AppMiddleware,
|
|
7
|
-
type OperationContext,
|
|
8
|
-
} from '../wire/middleware.js';
|
|
9
|
-
import type { ArgumentResolver } from './ArgumentResolver.js';
|
|
10
|
-
import type { InputValidator } from './InputValidator.js';
|
|
11
|
-
import type { OutputProjector } from './OutputProjector.js';
|
|
12
|
-
|
|
13
|
-
export interface OperationExecution {
|
|
14
|
-
entity: string;
|
|
15
|
-
frond: string;
|
|
16
|
-
operation: string;
|
|
17
|
-
contract: OperationContract | undefined;
|
|
18
|
-
middlewares: () => AppMiddleware[];
|
|
19
|
-
validator: InputValidator;
|
|
20
|
-
arguments: ArgumentResolver;
|
|
21
|
-
invoke: (args: unknown[]) => unknown | Promise<unknown>;
|
|
22
|
-
projector: OutputProjector;
|
|
23
|
-
present?: (result: unknown, invocation: InvocationContext) => Promise<unknown>;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/** Executes one operation through the same ordered boundary steps on every route. */
|
|
27
|
-
export class OperationExecutor {
|
|
28
|
-
constructor(private readonly execution: OperationExecution) {}
|
|
29
|
-
|
|
30
|
-
async execute(input?: Partial<InvocationContext>): Promise<unknown> {
|
|
31
|
-
const invocation = canonicalInvocation(input);
|
|
32
|
-
const context: OperationContext = {
|
|
33
|
-
entity: this.execution.entity,
|
|
34
|
-
frond: this.execution.frond,
|
|
35
|
-
operation: this.execution.operation,
|
|
36
|
-
args: [],
|
|
37
|
-
state: invocation.state,
|
|
38
|
-
invocation,
|
|
39
|
-
};
|
|
40
|
-
return runMiddlewares(this.execution.middlewares(), context, async () => {
|
|
41
|
-
const effective = this.execution.validator.validate(
|
|
42
|
-
this.execution.contract?.input,
|
|
43
|
-
invocation,
|
|
44
|
-
context.entity,
|
|
45
|
-
context.operation,
|
|
46
|
-
);
|
|
47
|
-
context.invocation = effective;
|
|
48
|
-
|
|
49
|
-
const args = this.execution.contract?.binding
|
|
50
|
-
? await this.execution.arguments.resolve(this.execution.contract.binding, effective)
|
|
51
|
-
: [];
|
|
52
|
-
const projected = this.execution.projector.project(
|
|
53
|
-
await this.execution.invoke(args),
|
|
54
|
-
);
|
|
55
|
-
return this.execution.present
|
|
56
|
-
? this.execution.present(projected, effective)
|
|
57
|
-
: projected;
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { Visibility } from '@fougere/schema';
|
|
2
|
-
import { preserveArrayProperties } from './ArrayResult.js';
|
|
3
|
-
import type { OutputView } from './OutputView.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Projects one operation result onto the fields its audience may read.
|
|
7
|
-
*
|
|
8
|
-
* One of the two exits a judge watches; `StorageGuard` is the other.
|
|
9
|
-
*/
|
|
10
|
-
export class OutputProjector {
|
|
11
|
-
constructor(private readonly view: OutputView) {}
|
|
12
|
-
|
|
13
|
-
project(result: unknown): unknown {
|
|
14
|
-
if (result === null || result === undefined) return result;
|
|
15
|
-
|
|
16
|
-
if (Array.isArray(result)) {
|
|
17
|
-
return preserveArrayProperties(result, result.map((item) => this.project(item)));
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
if (typeof result !== 'object') return result;
|
|
21
|
-
|
|
22
|
-
const record = result as Record<string, unknown>;
|
|
23
|
-
const scoped = this.view.closed
|
|
24
|
-
? Object.fromEntries(
|
|
25
|
-
Object.keys(this.view.fields)
|
|
26
|
-
.filter((key) => key in record)
|
|
27
|
-
.map((key) => [key, record[key]]),
|
|
28
|
-
)
|
|
29
|
-
: record;
|
|
30
|
-
return Visibility.of(this.view.fields).encode(scoped);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { computeBindingPlan } from '../boot/binding.js';
|
|
2
|
-
import type { InvocationContext } from '../contract/Invocation.js';
|
|
3
|
-
import type { PresenterEntry } from '../scan/frond.js';
|
|
4
|
-
import type { ArgumentResolver } from './ArgumentResolver.js';
|
|
5
|
-
import type { PresenterArgs } from './PresenterExecutor.js';
|
|
6
|
-
|
|
7
|
-
/** Resolves the invocation-dependent arguments of every computed presenter field. */
|
|
8
|
-
export class PresenterArgumentResolver {
|
|
9
|
-
constructor(
|
|
10
|
-
private readonly argumentsResolver: ArgumentResolver,
|
|
11
|
-
private readonly collectorTypes: Set<string>,
|
|
12
|
-
) {}
|
|
13
|
-
|
|
14
|
-
async resolve(meta: PresenterEntry, invocation: InvocationContext): Promise<PresenterArgs> {
|
|
15
|
-
const argumentsByField: PresenterArgs = {};
|
|
16
|
-
for (const field of meta.fieldMeta) {
|
|
17
|
-
if (!field.params?.length) continue;
|
|
18
|
-
argumentsByField[field.name] = await this.argumentsResolver.resolve(
|
|
19
|
-
computeBindingPlan(field.params, this.collectorTypes),
|
|
20
|
-
invocation,
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
return argumentsByField;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import type { Call } from '../contract/Call.js';
|
|
2
|
-
import { ErrorCode, FougereError } from '../wire/errors.js';
|
|
3
|
-
import type { Route } from './Route.js';
|
|
4
|
-
import type { RoutePolicy } from './RoutePolicy.js';
|
|
5
|
-
|
|
6
|
-
/** Describes an unresolved route from the destinations visible to one dispatcher. */
|
|
7
|
-
export class RouteNotFoundError extends FougereError {
|
|
8
|
-
readonly servedOperations: readonly string[];
|
|
9
|
-
|
|
10
|
-
constructor(call: Call, routes: readonly Route[], policy?: RoutePolicy) {
|
|
11
|
-
const served = routes
|
|
12
|
-
.filter((route) => !policy || policy.accepts(route))
|
|
13
|
-
.filter((route) => route.address.entity === call.address.entity)
|
|
14
|
-
.filter((route) => route.kind === 'system'
|
|
15
|
-
|| route.address.surface === call.address.surface)
|
|
16
|
-
.map((route) => route.address.operation);
|
|
17
|
-
const operation = call.address.operation;
|
|
18
|
-
const entity = call.address.entity;
|
|
19
|
-
const message = entity === 'rpc'
|
|
20
|
-
? `Unknown rpc operation '${operation}'. `
|
|
21
|
-
+ (served.length ? `It serves ${served.join(', ')}.` : 'It serves nothing.')
|
|
22
|
-
: served.length
|
|
23
|
-
? `Unknown operation '${operation}' on '${entity}'. It serves ${served.join(', ')}.`
|
|
24
|
-
: `No route serves '${call.address}'`;
|
|
25
|
-
|
|
26
|
-
super({ code: ErrorCode.NOT_FOUND, message, entity, operation });
|
|
27
|
-
this.servedOperations = served;
|
|
28
|
-
}
|
|
29
|
-
}
|