@fougere/core 0.2.0-alpha.2 → 0.3.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 +2 -1
- package/dist/boot/AppLifecycle.d.ts +18 -0
- package/dist/boot/AppLifecycle.d.ts.map +1 -0
- package/dist/boot/AppLifecycle.js +42 -0
- package/dist/boot/AppLifecycle.js.map +1 -0
- package/dist/boot/Emissions.d.ts +126 -0
- package/dist/boot/Emissions.d.ts.map +1 -0
- package/dist/boot/Emissions.js +233 -0
- package/dist/boot/Emissions.js.map +1 -0
- package/dist/boot/HandlerFacade.d.ts +72 -0
- package/dist/boot/HandlerFacade.d.ts.map +1 -0
- package/dist/boot/HandlerFacade.js +174 -0
- package/dist/boot/HandlerFacade.js.map +1 -0
- package/dist/boot/Lifecycle.d.ts +4 -0
- package/dist/boot/Lifecycle.d.ts.map +1 -0
- package/dist/boot/Lifecycle.js +3 -0
- package/dist/boot/Lifecycle.js.map +1 -0
- package/dist/boot/ambient-port.d.ts +38 -0
- package/dist/boot/ambient-port.d.ts.map +1 -0
- package/dist/boot/ambient-port.js +2 -0
- package/dist/boot/ambient-port.js.map +1 -0
- package/dist/boot/ambient.als.d.ts +3 -0
- package/dist/boot/ambient.als.d.ts.map +1 -0
- package/dist/boot/ambient.als.js +34 -0
- package/dist/boot/ambient.als.js.map +1 -0
- package/dist/boot/ambient.queue.d.ts +10 -0
- package/dist/boot/ambient.queue.d.ts.map +1 -0
- package/dist/boot/ambient.queue.js +60 -0
- package/dist/boot/ambient.queue.js.map +1 -0
- package/dist/boot/apply.d.ts +22 -0
- package/dist/boot/apply.d.ts.map +1 -0
- package/dist/boot/apply.js +48 -0
- package/dist/boot/apply.js.map +1 -0
- package/dist/boot/auth.d.ts +53 -0
- package/dist/boot/auth.d.ts.map +1 -0
- package/dist/boot/auth.js +2 -0
- package/dist/boot/auth.js.map +1 -0
- package/dist/{binding.d.ts → boot/binding.d.ts} +14 -17
- package/dist/boot/binding.d.ts.map +1 -0
- package/dist/{binding.js → boot/binding.js} +19 -10
- package/dist/boot/binding.js.map +1 -0
- package/dist/{boot.d.ts → boot/boot.d.ts} +25 -5
- package/dist/boot/boot.d.ts.map +1 -0
- package/dist/boot/boot.js +70 -0
- package/dist/boot/boot.js.map +1 -0
- package/dist/boot/bootstrap.d.ts.map +1 -0
- package/dist/boot/bootstrap.js +721 -0
- package/dist/boot/bootstrap.js.map +1 -0
- package/dist/boot/egress.d.ts +8 -0
- package/dist/boot/egress.d.ts.map +1 -0
- package/dist/boot/egress.js +11 -0
- package/dist/boot/egress.js.map +1 -0
- package/dist/boot/frame.d.ts +44 -0
- package/dist/boot/frame.d.ts.map +1 -0
- package/dist/boot/frame.js +181 -0
- package/dist/boot/frame.js.map +1 -0
- package/dist/boot/ownership.d.ts +42 -0
- package/dist/boot/ownership.d.ts.map +1 -0
- package/dist/boot/ownership.js +127 -0
- package/dist/boot/ownership.js.map +1 -0
- package/dist/boot/ports.d.ts +17 -0
- package/dist/boot/ports.d.ts.map +1 -0
- package/dist/boot/ports.js +57 -0
- package/dist/boot/ports.js.map +1 -0
- package/dist/{remote.d.ts → boot/remote.d.ts} +11 -3
- package/dist/boot/remote.d.ts.map +1 -0
- package/dist/{remote.js → boot/remote.js} +24 -26
- package/dist/boot/remote.js.map +1 -0
- package/dist/{seed.d.ts → boot/seed.d.ts} +13 -1
- package/dist/boot/seed.d.ts.map +1 -0
- package/dist/{seed.js → boot/seed.js} +24 -3
- package/dist/boot/seed.js.map +1 -0
- package/dist/boot/together.d.ts +26 -0
- package/dist/boot/together.d.ts.map +1 -0
- package/dist/boot/together.js +163 -0
- package/dist/boot/together.js.map +1 -0
- package/dist/boot/types.d.ts +260 -0
- package/dist/boot/types.d.ts.map +1 -0
- package/dist/boot/types.js.map +1 -0
- package/dist/builtins/config.d.ts +9 -0
- package/dist/builtins/config.d.ts.map +1 -1
- package/dist/builtins/config.js +16 -1
- package/dist/builtins/config.js.map +1 -1
- package/dist/builtins/logger.d.ts +37 -4
- package/dist/builtins/logger.d.ts.map +1 -1
- package/dist/builtins/logger.js +66 -7
- package/dist/builtins/logger.js.map +1 -1
- package/dist/config-loader.d.ts +39 -35
- package/dist/config-loader.d.ts.map +1 -1
- package/dist/config-loader.js +15 -54
- package/dist/config-loader.js.map +1 -1
- package/dist/contract/Call.d.ts +10 -0
- package/dist/contract/Call.d.ts.map +1 -0
- package/dist/contract/Call.js +15 -0
- package/dist/contract/Call.js.map +1 -0
- package/dist/contract/Invocation.d.ts +27 -0
- package/dist/contract/Invocation.d.ts.map +1 -0
- package/dist/contract/Invocation.js +59 -0
- package/dist/contract/Invocation.js.map +1 -0
- package/dist/contract/RouteAddress.d.ts +17 -0
- package/dist/contract/RouteAddress.d.ts.map +1 -0
- package/dist/contract/RouteAddress.js +38 -0
- package/dist/contract/RouteAddress.js.map +1 -0
- package/dist/contract.d.ts +25 -19
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +25 -10
- package/dist/contract.js.map +1 -1
- package/dist/crypto/encoding.d.ts +25 -0
- package/dist/crypto/encoding.d.ts.map +1 -0
- package/dist/crypto/encoding.js +58 -0
- package/dist/crypto/encoding.js.map +1 -0
- package/dist/crypto/node.d.ts +4 -0
- package/dist/crypto/node.d.ts.map +1 -0
- package/dist/crypto/node.js +25 -0
- package/dist/crypto/node.js.map +1 -0
- package/dist/crypto/port.d.ts +42 -0
- package/dist/crypto/port.d.ts.map +1 -0
- package/dist/crypto/port.js +19 -0
- package/dist/crypto/port.js.map +1 -0
- package/dist/crypto/webcrypto.d.ts +4 -0
- package/dist/crypto/webcrypto.d.ts.map +1 -0
- package/dist/crypto/webcrypto.js +34 -0
- package/dist/crypto/webcrypto.js.map +1 -0
- package/dist/dispatch/ArgumentResolver.d.ts +10 -0
- package/dist/dispatch/ArgumentResolver.d.ts.map +1 -0
- package/dist/dispatch/ArgumentResolver.js +12 -0
- package/dist/dispatch/ArgumentResolver.js.map +1 -0
- package/dist/dispatch/ArrayResult.d.ts +3 -0
- package/dist/dispatch/ArrayResult.d.ts.map +1 -0
- package/dist/dispatch/ArrayResult.js +11 -0
- package/dist/dispatch/ArrayResult.js.map +1 -0
- package/dist/dispatch/DispatchEvent.d.ts +18 -0
- package/dist/dispatch/DispatchEvent.d.ts.map +1 -0
- package/dist/dispatch/DispatchEvent.js +30 -0
- package/dist/dispatch/DispatchEvent.js.map +1 -0
- package/dist/dispatch/DispatchLifecycle.d.ts +9 -0
- package/dist/dispatch/DispatchLifecycle.d.ts.map +1 -0
- package/dist/dispatch/DispatchLifecycle.js +25 -0
- package/dist/dispatch/DispatchLifecycle.js.map +1 -0
- package/dist/dispatch/DispatchPort.d.ts +6 -0
- package/dist/dispatch/DispatchPort.d.ts.map +1 -0
- package/dist/dispatch/DispatchPort.js +2 -0
- package/dist/dispatch/DispatchPort.js.map +1 -0
- package/dist/dispatch/Dispatcher.d.ts +16 -0
- package/dist/dispatch/Dispatcher.d.ts.map +1 -0
- package/dist/dispatch/Dispatcher.js +44 -0
- package/dist/dispatch/Dispatcher.js.map +1 -0
- package/dist/dispatch/InFlight.d.ts +12 -0
- package/dist/dispatch/InFlight.d.ts.map +1 -0
- package/dist/dispatch/InFlight.js +46 -0
- package/dist/dispatch/InFlight.js.map +1 -0
- package/dist/dispatch/InputValidator.d.ts +7 -0
- package/dist/dispatch/InputValidator.d.ts.map +1 -0
- package/dist/dispatch/InputValidator.js +21 -0
- package/dist/dispatch/InputValidator.js.map +1 -0
- package/dist/dispatch/LocalRoutePolicy.d.ts +11 -0
- package/dist/dispatch/LocalRoutePolicy.d.ts.map +1 -0
- package/dist/dispatch/LocalRoutePolicy.js +32 -0
- package/dist/dispatch/LocalRoutePolicy.js.map +1 -0
- package/dist/dispatch/OperationExecutor.d.ts +25 -0
- package/dist/dispatch/OperationExecutor.d.ts.map +1 -0
- package/dist/dispatch/OperationExecutor.js +32 -0
- package/dist/dispatch/OperationExecutor.js.map +1 -0
- package/dist/dispatch/OperationRoute.d.ts +13 -0
- package/dist/dispatch/OperationRoute.d.ts.map +1 -0
- package/dist/dispatch/OperationRoute.js +15 -0
- package/dist/dispatch/OperationRoute.js.map +1 -0
- package/dist/dispatch/OutputProjector.d.ts +12 -0
- package/dist/dispatch/OutputProjector.d.ts.map +1 -0
- package/dist/dispatch/OutputProjector.js +30 -0
- package/dist/dispatch/OutputProjector.js.map +1 -0
- package/dist/dispatch/OutputView.d.ts +8 -0
- package/dist/dispatch/OutputView.d.ts.map +1 -0
- package/dist/dispatch/OutputView.js +10 -0
- package/dist/dispatch/OutputView.js.map +1 -0
- package/dist/dispatch/PresenterArgumentResolver.d.ts +12 -0
- package/dist/dispatch/PresenterArgumentResolver.d.ts.map +1 -0
- package/dist/dispatch/PresenterArgumentResolver.js +20 -0
- package/dist/dispatch/PresenterArgumentResolver.js.map +1 -0
- package/dist/dispatch/PresenterExecutor.d.ts +11 -0
- package/dist/dispatch/PresenterExecutor.d.ts.map +1 -0
- package/dist/dispatch/PresenterExecutor.js +56 -0
- package/dist/dispatch/PresenterExecutor.js.map +1 -0
- package/dist/dispatch/RemoteRouteResolver.d.ts +13 -0
- package/dist/dispatch/RemoteRouteResolver.d.ts.map +1 -0
- package/dist/dispatch/RemoteRouteResolver.js +18 -0
- package/dist/dispatch/RemoteRouteResolver.js.map +1 -0
- package/dist/dispatch/Route.d.ts +10 -0
- package/dist/dispatch/Route.d.ts.map +1 -0
- package/dist/dispatch/Route.js +2 -0
- package/dist/dispatch/Route.js.map +1 -0
- package/dist/dispatch/RouteNotFoundError.d.ts +10 -0
- package/dist/dispatch/RouteNotFoundError.d.ts.map +1 -0
- package/dist/dispatch/RouteNotFoundError.js +24 -0
- package/dist/dispatch/RouteNotFoundError.js.map +1 -0
- package/dist/dispatch/RoutePolicy.d.ts +8 -0
- package/dist/dispatch/RoutePolicy.d.ts.map +1 -0
- package/dist/dispatch/RoutePolicy.js +2 -0
- package/dist/dispatch/RoutePolicy.js.map +1 -0
- package/dist/dispatch/RouteRegistry.d.ts +18 -0
- package/dist/dispatch/RouteRegistry.d.ts.map +1 -0
- package/dist/dispatch/RouteRegistry.js +62 -0
- package/dist/dispatch/RouteRegistry.js.map +1 -0
- package/dist/dispatch/RouteResolver.d.ts +7 -0
- package/dist/dispatch/RouteResolver.d.ts.map +1 -0
- package/dist/dispatch/RouteResolver.js +2 -0
- package/dist/dispatch/RouteResolver.js.map +1 -0
- package/dist/dispatch/StorageGuard.d.ts +15 -0
- package/dist/dispatch/StorageGuard.d.ts.map +1 -0
- package/dist/dispatch/StorageGuard.js +63 -0
- package/dist/dispatch/StorageGuard.js.map +1 -0
- package/dist/effective-operation.d.ts +90 -0
- package/dist/effective-operation.d.ts.map +1 -0
- package/dist/effective-operation.js +450 -0
- package/dist/effective-operation.js.map +1 -0
- package/dist/emit.js +2 -2
- package/dist/emit.js.map +1 -1
- package/dist/entry/DynamicFacade.d.ts +10 -0
- package/dist/entry/DynamicFacade.d.ts.map +1 -0
- package/dist/entry/DynamicFacade.js +27 -0
- package/dist/entry/DynamicFacade.js.map +1 -0
- package/dist/entry/FacadeEntry.d.ts +11 -0
- package/dist/entry/FacadeEntry.d.ts.map +1 -0
- package/dist/entry/FacadeEntry.js +26 -0
- package/dist/entry/FacadeEntry.js.map +1 -0
- package/dist/entry/TransportEntry.d.ts +13 -0
- package/dist/entry/TransportEntry.d.ts.map +1 -0
- package/dist/entry/TransportEntry.js +24 -0
- package/dist/entry/TransportEntry.js.map +1 -0
- package/dist/frond-config.d.ts +24 -7
- package/dist/frond-config.d.ts.map +1 -1
- 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/graph.js +3 -2
- package/dist/graph.js.map +1 -1
- package/dist/identity-keys.d.ts +14 -0
- package/dist/identity-keys.d.ts.map +1 -0
- package/dist/identity-keys.js +37 -0
- package/dist/identity-keys.js.map +1 -0
- package/dist/identity.d.ts +58 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +182 -0
- package/dist/identity.js.map +1 -0
- package/dist/imports.d.ts +1 -1
- package/dist/imports.d.ts.map +1 -1
- package/dist/imports.js +7 -3
- package/dist/imports.js.map +1 -1
- package/dist/index.d.ts +57 -38
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +38 -32
- package/dist/index.js.map +1 -1
- package/dist/loader.d.ts +16 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +25 -0
- package/dist/loader.js.map +1 -0
- package/dist/node.d.ts +21 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +24 -0
- package/dist/node.js.map +1 -0
- package/dist/orm.d.ts +69 -8
- package/dist/orm.d.ts.map +1 -1
- package/dist/orm.js +35 -2
- package/dist/orm.js.map +1 -1
- package/dist/prefab/collector.d.ts +29 -0
- package/dist/prefab/collector.d.ts.map +1 -0
- package/dist/prefab/collector.js +34 -0
- package/dist/prefab/collector.js.map +1 -0
- package/dist/{crud.d.ts → prefab/crud.d.ts} +7 -8
- package/dist/prefab/crud.d.ts.map +1 -0
- package/dist/{crud.js → prefab/crud.js} +39 -5
- package/dist/prefab/crud.js.map +1 -0
- package/dist/prefab/mirror.d.ts +52 -0
- package/dist/prefab/mirror.d.ts.map +1 -0
- package/dist/prefab/mirror.js +66 -0
- package/dist/prefab/mirror.js.map +1 -0
- package/dist/prefab/prefab.d.ts +15 -0
- package/dist/prefab/prefab.d.ts.map +1 -0
- package/dist/prefab/prefab.js +19 -0
- package/dist/prefab/prefab.js.map +1 -0
- package/dist/{presenter.d.ts → prefab/presenter.d.ts} +6 -17
- package/dist/prefab/presenter.d.ts.map +1 -0
- package/dist/{presenter.js → prefab/presenter.js} +5 -23
- package/dist/prefab/presenter.js.map +1 -0
- package/dist/prefab/repository.d.ts +104 -0
- package/dist/prefab/repository.d.ts.map +1 -0
- package/dist/prefab/repository.js +62 -0
- package/dist/prefab/repository.js.map +1 -0
- package/dist/scan/Fronds.d.ts +45 -0
- package/dist/scan/Fronds.d.ts.map +1 -0
- package/dist/scan/Fronds.js +66 -0
- package/dist/scan/Fronds.js.map +1 -0
- package/dist/scan/conventions.d.ts +74 -0
- package/dist/scan/conventions.d.ts.map +1 -0
- package/dist/scan/conventions.js +82 -0
- package/dist/scan/conventions.js.map +1 -0
- package/dist/scan/emit.d.ts +14 -0
- package/dist/scan/emit.d.ts.map +1 -0
- package/dist/scan/emit.js +211 -0
- package/dist/scan/emit.js.map +1 -0
- package/dist/scan/frond.d.ts +224 -0
- package/dist/scan/frond.d.ts.map +1 -0
- package/dist/scan/frond.js +2 -0
- package/dist/scan/frond.js.map +1 -0
- package/dist/{handler-parser.d.ts → scan/handler-parser.d.ts} +18 -9
- package/dist/scan/handler-parser.d.ts.map +1 -0
- package/dist/scan/handler-parser.js +625 -0
- package/dist/scan/handler-parser.js.map +1 -0
- package/dist/scan/scan-cache.d.ts +16 -0
- package/dist/scan/scan-cache.d.ts.map +1 -0
- package/dist/{scan-cache.js → scan/scan-cache.js} +27 -20
- package/dist/scan/scan-cache.js.map +1 -0
- package/dist/scan/scanner.d.ts +20 -0
- package/dist/scan/scanner.d.ts.map +1 -0
- package/dist/{scanner.js → scan/scanner.js} +185 -167
- package/dist/scan/scanner.js.map +1 -0
- package/dist/verify.d.ts +16 -3
- package/dist/verify.d.ts.map +1 -1
- package/dist/verify.js +21 -18
- package/dist/verify.js.map +1 -1
- package/dist/{call.d.ts → wire/call.d.ts} +70 -1
- package/dist/wire/call.d.ts.map +1 -0
- package/dist/{call.js → wire/call.js} +48 -75
- package/dist/wire/call.js.map +1 -0
- package/dist/{middleware.d.ts → wire/errors.d.ts} +18 -19
- package/dist/wire/errors.d.ts.map +1 -0
- package/dist/{middleware.js → wire/errors.js} +26 -14
- package/dist/wire/errors.js.map +1 -0
- package/dist/{errors.d.ts → wire/http-error.d.ts} +5 -6
- package/dist/wire/http-error.d.ts.map +1 -0
- package/dist/{errors.js → wire/http-error.js} +7 -6
- package/dist/wire/http-error.js.map +1 -0
- package/dist/wire/invocation.d.ts +4 -0
- package/dist/wire/invocation.d.ts.map +1 -0
- package/dist/wire/invocation.js +3 -0
- package/dist/wire/invocation.js.map +1 -0
- package/dist/{middleware/logger.d.ts → wire/loggerMiddleware.d.ts} +3 -3
- package/dist/wire/loggerMiddleware.d.ts.map +1 -0
- package/dist/{middleware/logger.js → wire/loggerMiddleware.js} +2 -2
- package/dist/wire/loggerMiddleware.js.map +1 -0
- package/dist/wire/middleware.d.ts +29 -0
- package/dist/wire/middleware.d.ts.map +1 -0
- package/dist/wire/middleware.js +20 -0
- package/dist/wire/middleware.js.map +1 -0
- package/dist/{operation.d.ts → wire/operation.d.ts} +39 -10
- package/dist/wire/operation.d.ts.map +1 -0
- package/dist/wire/operation.js +167 -0
- package/dist/wire/operation.js.map +1 -0
- package/package.json +24 -7
- package/dist/binding.d.ts.map +0 -1
- package/dist/binding.js.map +0 -1
- package/dist/boot.d.ts.map +0 -1
- package/dist/boot.js +0 -53
- package/dist/boot.js.map +0 -1
- package/dist/bootstrap.d.ts.map +0 -1
- package/dist/bootstrap.js +0 -879
- package/dist/bootstrap.js.map +0 -1
- package/dist/call.d.ts.map +0 -1
- package/dist/call.js.map +0 -1
- package/dist/collector.d.ts +0 -28
- package/dist/collector.d.ts.map +0 -1
- package/dist/collector.js +0 -32
- package/dist/collector.js.map +0 -1
- package/dist/crud.d.ts.map +0 -1
- package/dist/crud.js.map +0 -1
- package/dist/egress.d.ts +0 -52
- package/dist/egress.d.ts.map +0 -1
- package/dist/egress.js +0 -186
- package/dist/egress.js.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js.map +0 -1
- package/dist/handler-parser.d.ts.map +0 -1
- package/dist/handler-parser.js +0 -505
- package/dist/handler-parser.js.map +0 -1
- package/dist/invocation.d.ts +0 -20
- package/dist/invocation.d.ts.map +0 -1
- package/dist/invocation.js +0 -15
- package/dist/invocation.js.map +0 -1
- package/dist/middleware/error-handler.d.ts +0 -15
- package/dist/middleware/error-handler.d.ts.map +0 -1
- package/dist/middleware/error-handler.js +0 -29
- package/dist/middleware/error-handler.js.map +0 -1
- package/dist/middleware/logger.d.ts.map +0 -1
- package/dist/middleware/logger.js.map +0 -1
- package/dist/middleware.d.ts.map +0 -1
- package/dist/middleware.js.map +0 -1
- package/dist/mirror.d.ts +0 -93
- package/dist/mirror.d.ts.map +0 -1
- package/dist/mirror.js +0 -96
- package/dist/mirror.js.map +0 -1
- package/dist/operation.d.ts.map +0 -1
- package/dist/operation.js +0 -95
- package/dist/operation.js.map +0 -1
- package/dist/presenter.d.ts.map +0 -1
- package/dist/presenter.js.map +0 -1
- package/dist/remote.d.ts.map +0 -1
- package/dist/remote.js.map +0 -1
- package/dist/repository.d.ts +0 -55
- package/dist/repository.d.ts.map +0 -1
- package/dist/repository.js +0 -26
- package/dist/repository.js.map +0 -1
- package/dist/scan-cache.d.ts +0 -10
- package/dist/scan-cache.d.ts.map +0 -1
- package/dist/scan-cache.js.map +0 -1
- package/dist/scanner.d.ts +0 -34
- package/dist/scanner.d.ts.map +0 -1
- package/dist/scanner.js.map +0 -1
- package/dist/seed.d.ts.map +0 -1
- package/dist/seed.js.map +0 -1
- package/dist/types.d.ts +0 -421
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- /package/dist/{bootstrap.d.ts → boot/bootstrap.d.ts} +0 -0
- /package/dist/{types.js → boot/types.js} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DynamicFacade.js","sourceRoot":"","sources":["../../src/entry/DynamicFacade.ts"],"names":[],"mappings":"AAEA,yFAAyF;AACzF,MAAM,OAAO,aAAa;IAGK;IAFpB,UAAU,CAA4B;IAE/C,YAA6B,SAAsC;QAAtC,cAAS,GAAT,SAAS,CAA6B;QACjE,IAAI,CAAC,UAAU,GAAG,IAAI,KAAK,CAAC,EAAE,EAAE;YAC9B,GAAG,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;YACrF,GAAG,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;YAClD,wBAAwB,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;gBACrE,CAAC,CAAC;oBACE,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;oBAC3B,QAAQ,EAAE,KAAK;oBACf,UAAU,EAAE,IAAI;oBAChB,YAAY,EAAE,IAAI;iBACnB;gBACH,CAAC,CAAC,SAAS;SACd,CAAC,CAAC;IACL,CAAC;IAEO,eAAe,CAAC,IAAqB;QAC3C,OAAO,OAAO,IAAI,KAAK,QAAQ;eAC1B,IAAI,KAAK,MAAM;eACf,IAAI,KAAK,QAAQ;eACjB,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC9C,CAAC;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { DispatchPort } from '../dispatch/DispatchPort.js';
|
|
2
|
+
/** Object-shaped entry that turns facade method calls into canonical dispatches. */
|
|
3
|
+
export declare class FacadeEntry {
|
|
4
|
+
private readonly dispatcher;
|
|
5
|
+
private readonly entity;
|
|
6
|
+
private readonly surface?;
|
|
7
|
+
readonly operations: Record<string, Function>;
|
|
8
|
+
constructor(dispatcher: DispatchPort, entity: string, operationNames?: Iterable<string>, surface?: string | undefined);
|
|
9
|
+
private operation;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=FacadeEntry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FacadeEntry.d.ts","sourceRoot":"","sources":["../../src/entry/FacadeEntry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAGhE,oFAAoF;AACpF,qBAAa,WAAW;IAIpB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAEvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IAN3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;gBAG3B,UAAU,EAAE,YAAY,EACxB,MAAM,EAAE,MAAM,EAC/B,cAAc,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,EAChB,OAAO,CAAC,EAAE,MAAM,YAAA;IAOnC,OAAO,CAAC,SAAS;CAUlB"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Call } from '../contract/Call.js';
|
|
2
|
+
import { RouteAddress } from '../contract/RouteAddress.js';
|
|
3
|
+
import { DynamicFacade } from './DynamicFacade.js';
|
|
4
|
+
/** Object-shaped entry that turns facade method calls into canonical dispatches. */
|
|
5
|
+
export class FacadeEntry {
|
|
6
|
+
dispatcher;
|
|
7
|
+
entity;
|
|
8
|
+
surface;
|
|
9
|
+
operations;
|
|
10
|
+
constructor(dispatcher, entity, operationNames, surface) {
|
|
11
|
+
this.dispatcher = dispatcher;
|
|
12
|
+
this.entity = entity;
|
|
13
|
+
this.surface = surface;
|
|
14
|
+
this.operations = operationNames
|
|
15
|
+
? Object.fromEntries([...operationNames].map((name) => [name, this.operation(name)]))
|
|
16
|
+
: new DynamicFacade((name) => this.operation(name)).operations;
|
|
17
|
+
}
|
|
18
|
+
operation(name) {
|
|
19
|
+
return (invocation) => this.dispatcher.dispatch(new Call(new RouteAddress({
|
|
20
|
+
entity: this.entity,
|
|
21
|
+
operation: name,
|
|
22
|
+
...(this.surface !== undefined ? { surface: this.surface } : {}),
|
|
23
|
+
}), invocation));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=FacadeEntry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FacadeEntry.js","sourceRoot":"","sources":["../../src/entry/FacadeEntry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAE3C,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAE3D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,oFAAoF;AACpF,MAAM,OAAO,WAAW;IAIH;IACA;IAEA;IANV,UAAU,CAA2B;IAE9C,YACmB,UAAwB,EACxB,MAAc,EAC/B,cAAiC,EAChB,OAAgB;QAHhB,eAAU,GAAV,UAAU,CAAc;QACxB,WAAM,GAAN,MAAM,CAAQ;QAEd,YAAO,GAAP,OAAO,CAAS;QAEjC,IAAI,CAAC,UAAU,GAAG,cAAc;YAC9B,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACrF,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC;IACnE,CAAC;IAEO,SAAS,CAAC,IAAY;QAC5B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,IAAI,CACtD,IAAI,YAAY,CAAC;YACf,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,SAAS,EAAE,IAAI;YACf,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACjE,CAAC,EACF,UAAU,CACX,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { DispatchPort } from '../dispatch/DispatchPort.js';
|
|
2
|
+
import type { FrondCall, Transport } from '../wire/call.js';
|
|
3
|
+
import type { InvocationContext } from '../contract/Invocation.js';
|
|
4
|
+
/** Object entry for the historical transport contract. */
|
|
5
|
+
export declare class TransportEntry {
|
|
6
|
+
private readonly dispatcher;
|
|
7
|
+
private readonly surface?;
|
|
8
|
+
constructor(dispatcher: DispatchPort, surface?: string | undefined);
|
|
9
|
+
receive(legacy: FrondCall, invocation: InvocationContext): Promise<unknown>;
|
|
10
|
+
}
|
|
11
|
+
/** Adapt the historical transport signature to the canonical dispatch port. */
|
|
12
|
+
export declare function createTransportEntry(dispatcher: DispatchPort, surface?: string): Transport;
|
|
13
|
+
//# sourceMappingURL=TransportEntry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TransportEntry.d.ts","sourceRoot":"","sources":["../../src/entry/TransportEntry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,0DAA0D;AAC1D,qBAAa,cAAc;IAEvB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;gBADR,UAAU,EAAE,YAAY,EACxB,OAAO,CAAC,EAAE,MAAM,YAAA;IAGnC,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;CAU5E;AAED,+EAA+E;AAC/E,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAG1F"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Call } from '../contract/Call.js';
|
|
2
|
+
import { RouteAddress } from '../contract/RouteAddress.js';
|
|
3
|
+
/** Object entry for the historical transport contract. */
|
|
4
|
+
export class TransportEntry {
|
|
5
|
+
dispatcher;
|
|
6
|
+
surface;
|
|
7
|
+
constructor(dispatcher, surface) {
|
|
8
|
+
this.dispatcher = dispatcher;
|
|
9
|
+
this.surface = surface;
|
|
10
|
+
}
|
|
11
|
+
receive(legacy, invocation) {
|
|
12
|
+
return this.dispatcher.dispatch(new Call(new RouteAddress({
|
|
13
|
+
entity: legacy.entity,
|
|
14
|
+
operation: legacy.op,
|
|
15
|
+
...(this.surface !== undefined ? { surface: this.surface } : {}),
|
|
16
|
+
}), invocation));
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/** Adapt the historical transport signature to the canonical dispatch port. */
|
|
20
|
+
export function createTransportEntry(dispatcher, surface) {
|
|
21
|
+
const entry = new TransportEntry(dispatcher, surface);
|
|
22
|
+
return entry.receive.bind(entry);
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=TransportEntry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TransportEntry.js","sourceRoot":"","sources":["../../src/entry/TransportEntry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAK3D,0DAA0D;AAC1D,MAAM,OAAO,cAAc;IAEN;IACA;IAFnB,YACmB,UAAwB,EACxB,OAAgB;QADhB,eAAU,GAAV,UAAU,CAAc;QACxB,YAAO,GAAP,OAAO,CAAS;IAChC,CAAC;IAEJ,OAAO,CAAC,MAAiB,EAAE,UAA6B;QACtD,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,IAAI,CACtC,IAAI,YAAY,CAAC;YACf,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,SAAS,EAAE,MAAM,CAAC,EAAE;YACpB,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACjE,CAAC,EACF,UAAU,CACX,CAAC,CAAC;IACL,CAAC;CACF;AAED,+EAA+E;AAC/E,MAAM,UAAU,oBAAoB,CAAC,UAAwB,EAAE,OAAgB;IAC7E,MAAM,KAAK,GAAG,IAAI,cAAc,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACtD,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACnC,CAAC"}
|
package/dist/frond-config.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import type { SchemaView } from '@fougere/schema';
|
|
2
|
-
import type { BindingPlan } from './binding.js';
|
|
1
|
+
import type { EntityConstructor, SchemaView } from '@fougere/schema';
|
|
2
|
+
import type { BindingPlan } from './boot/binding.js';
|
|
3
3
|
/**
|
|
4
4
|
* Per-operation override. Config takes precedence over conventions (isReadOp, facade lookup).
|
|
5
5
|
*
|
|
6
6
|
* Two families of keys, and they act at different depths:
|
|
7
7
|
*
|
|
8
|
-
* - **
|
|
9
|
-
*
|
|
8
|
+
* - **Resolution** (`kind`, `handler`, `method`) — intent and implementation, resolved
|
|
9
|
+
* once into core's `EffectiveOperation`; every local or remote door consumes it.
|
|
10
|
+
* - **Projection** (`graphql`) — protocol vocabulary, read only by that adapter.
|
|
10
11
|
* - **Contract** (`input`, `output`, `binding`) — what the op IS. Read by the façade,
|
|
11
12
|
* and this is the third producer of an {@link OperationContract}: a prefab DECLARES its
|
|
12
13
|
* ops (`Crud.__ops`), the scan DERIVES them from source, config STATES them outright.
|
|
@@ -16,20 +17,34 @@ import type { BindingPlan } from './binding.js';
|
|
|
16
17
|
* answers that nothing else does:
|
|
17
18
|
* - a method inherited from an **installed** base class — the scan resolves nothing there
|
|
18
19
|
* (workspace-only heritage) and says nothing, so the op silently misses the façade;
|
|
19
|
-
* -
|
|
20
|
+
* - an operation inherited from a declaration unavailable to the project's type checker.
|
|
20
21
|
*
|
|
21
22
|
* Config wins over both other producers — it is the most explicit statement, made by
|
|
22
23
|
* whoever assembles the app. Precedence: CLI > frond config > fougere config > scan >
|
|
23
24
|
* conventions.
|
|
24
25
|
*/
|
|
25
26
|
export interface OperationOverride {
|
|
26
|
-
/**
|
|
27
|
+
/**
|
|
28
|
+
* Force operation kind, over the naming convention (`isReadOp`).
|
|
29
|
+
*
|
|
30
|
+
* The convention reads the NAME, which is a weak signal — an app naming its reads in
|
|
31
|
+
* domain terms (`ofBook`, `roots`, `bySlug`) matches no prefix and every one of them is
|
|
32
|
+
* published as a mutation and a POST. This is the only place that fixes it.
|
|
33
|
+
*/
|
|
27
34
|
kind?: 'query' | 'command';
|
|
35
|
+
/**
|
|
36
|
+
* The GraphQL root field this op answers to. Defaults to the method name.
|
|
37
|
+
*
|
|
38
|
+
* A GraphQL root is flat, so two handlers naming a method `ofBook` claim one field and
|
|
39
|
+
* the build is refused, naming both. Nothing is renamed for you: the root vocabulary is
|
|
40
|
+
* the app's, and a derived name would move the day a distant frond gained an entity.
|
|
41
|
+
*/
|
|
42
|
+
graphql?: string;
|
|
28
43
|
/**
|
|
29
44
|
* Handler class to delegate to (overrides the default `{Entity}Handler` lookup).
|
|
30
45
|
* Class name is used to resolve from DI. E.g. `ArchiveHandler` → `app.resolve('ArchiveHandler')`.
|
|
31
46
|
*/
|
|
32
|
-
handler?:
|
|
47
|
+
handler?: EntityConstructor;
|
|
33
48
|
/** Method name on `handler` (defaults to the operation name). */
|
|
34
49
|
method?: string;
|
|
35
50
|
/**
|
|
@@ -51,6 +66,8 @@ export interface OperationOverride {
|
|
|
51
66
|
* from the method signature. An empty array is meaningful: "this op takes nothing".
|
|
52
67
|
*/
|
|
53
68
|
binding?: BindingPlan;
|
|
69
|
+
/** Per-operation output view, below prefab declarations and above handler/entity defaults. */
|
|
70
|
+
output?: SchemaView;
|
|
54
71
|
}
|
|
55
72
|
export interface FrondConfig {
|
|
56
73
|
/** Class names exposed as the frond's public contract (all surfaces). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frond-config.d.ts","sourceRoot":"","sources":["../src/frond-config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"frond-config.d.ts","sourceRoot":"","sources":["../src/frond-config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAIhB,kFAAkF;IAClF,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB,8FAA8F;IAC9F,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,oFAAoF;IACpF,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACpC,wFAAwF;IACxF,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,gFAAgF;IAChF,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CAChD;AAID;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CAE5D;AAMD;;;GAGG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CASzF"}
|
package/dist/frond-config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frond-config.js","sourceRoot":"","sources":["../src/frond-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"frond-config.js","sourceRoot":"","sources":["../src/frond-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAwGrC,oDAAoD;AAEpD;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW,CAAC,MAAmB;IAC7C,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,oDAAoD;AAEpD,MAAM,kBAAkB,GAAG,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,kBAAkB,CAAC,CAAC;AAEtF;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,SAAiB;IACrD,KAAK,MAAM,IAAI,IAAI,kBAAkB,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACtC,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;YAC/B,OAAO,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC;QAC5B,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
package/dist/graph.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Entity dependency graph — analyzes ref() links between entities
|
|
3
3
|
* to suggest domain boundaries for splitting fronds.
|
|
4
4
|
*/
|
|
5
|
-
import type { FrondDescriptor } from './
|
|
5
|
+
import type { FrondDescriptor } from './scan/frond.js';
|
|
6
6
|
export interface EntityNode {
|
|
7
7
|
name: string;
|
|
8
8
|
frond: string;
|
package/dist/graph.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"AACA;;;GAGG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAClE;AAED,kEAAkE;AAClE,wBAAgB,UAAU,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CA6B7E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,aAAa,EAAE,CAwC/E;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EAC9B,cAAc,SAAI,GACjB,aAAa,EAAE,CAmDjB"}
|
package/dist/graph.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Role } from '@fougere/schema';
|
|
1
2
|
/** Build the full entity dependency graph from scanned fronds. */
|
|
2
3
|
export function buildGraph(fronds) {
|
|
3
4
|
const nodes = new Map();
|
|
@@ -6,8 +7,8 @@ export function buildGraph(fronds) {
|
|
|
6
7
|
for (const entity of frond.entities) {
|
|
7
8
|
const refs = [];
|
|
8
9
|
for (const [, field] of Object.entries(entity.entityClass.getFields())) {
|
|
9
|
-
if (field.
|
|
10
|
-
const resolved =
|
|
10
|
+
if (Role.of(field).isReference) {
|
|
11
|
+
const resolved = Role.of(field).target;
|
|
11
12
|
const targetName = typeof resolved === 'function' && 'name' in resolved
|
|
12
13
|
? resolved.name.toLowerCase()
|
|
13
14
|
: undefined;
|
package/dist/graph.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** A fresh Ed25519 pair, PEM both ways. The root's and a frond's are the same kind. */
|
|
2
|
+
export declare function generateKeyPair(): {
|
|
3
|
+
privateKey: string;
|
|
4
|
+
publicKey: string;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Bind a name to a public key, signed by the root — the whole of what a receiver
|
|
8
|
+
* needs to recognize a frond it has never seen.
|
|
9
|
+
*
|
|
10
|
+
* `ttlDays` bounds the damage of a leaked frond key without a revocation list:
|
|
11
|
+
* re-issuing is a deployment, which is the same gesture that leaked it.
|
|
12
|
+
*/
|
|
13
|
+
export declare function issueGrant(rootPrivateKey: string, name: string, frondPublicKey: string, ttlDays?: number): string;
|
|
14
|
+
//# sourceMappingURL=identity-keys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity-keys.d.ts","sourceRoot":"","sources":["../src/identity-keys.ts"],"names":[],"mappings":"AAcA,uFAAuF;AACvF,wBAAgB,eAAe,IAAI;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAM3E;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,MAAM,EACtB,OAAO,SAAK,GACX,MAAM,CAOR"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Making keys and issuing grants — the half of identity that runs at a DEPLOYMENT.
|
|
3
|
+
*
|
|
4
|
+
* It sits on the Node entry because it is the CLI speaking: `fougere keys` generates a
|
|
5
|
+
* pair, `fougere grant` binds a name to one, and both happen once, on a machine with a
|
|
6
|
+
* filesystem. Neither is reachable from a request path, so nothing here is on any hot
|
|
7
|
+
* path and `generateKeyPairSync` — the one gesture WebCrypto could not replace without
|
|
8
|
+
* changing what a key IS — never has to leave `node:crypto`.
|
|
9
|
+
*
|
|
10
|
+
* The verifying half is elsewhere (`identity.ts`) because it runs per call, everywhere.
|
|
11
|
+
*/
|
|
12
|
+
import { createPrivateKey, createPublicKey, generateKeyPairSync, sign } from 'node:crypto';
|
|
13
|
+
import { b64url } from './crypto/encoding.js';
|
|
14
|
+
/** A fresh Ed25519 pair, PEM both ways. The root's and a frond's are the same kind. */
|
|
15
|
+
export function generateKeyPair() {
|
|
16
|
+
const { privateKey, publicKey } = generateKeyPairSync('ed25519');
|
|
17
|
+
return {
|
|
18
|
+
privateKey: privateKey.export({ type: 'pkcs8', format: 'pem' }).toString(),
|
|
19
|
+
publicKey: publicKey.export({ type: 'spki', format: 'pem' }).toString(),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Bind a name to a public key, signed by the root — the whole of what a receiver
|
|
24
|
+
* needs to recognize a frond it has never seen.
|
|
25
|
+
*
|
|
26
|
+
* `ttlDays` bounds the damage of a leaked frond key without a revocation list:
|
|
27
|
+
* re-issuing is a deployment, which is the same gesture that leaked it.
|
|
28
|
+
*/
|
|
29
|
+
export function issueGrant(rootPrivateKey, name, frondPublicKey, ttlDays = 90) {
|
|
30
|
+
const jwk = createPublicKey(frondPublicKey).export({ format: 'jwk' });
|
|
31
|
+
const now = Date.now();
|
|
32
|
+
const header = b64url(JSON.stringify({ alg: 'EdDSA', typ: 'fougere-grant' }));
|
|
33
|
+
const payload = b64url(JSON.stringify({ sub: name, jwk, iat: now, exp: now + ttlDays * 86_400_000 }));
|
|
34
|
+
const signingInput = `${header}.${payload}`;
|
|
35
|
+
return `${signingInput}.${b64url(new Uint8Array(sign(null, Buffer.from(signingInput), createPrivateKey(rootPrivateKey))))}`;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=identity-keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity-keys.js","sourceRoot":"","sources":["../src/identity-keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,mBAAmB,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAC3F,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,uFAAuF;AACvF,MAAM,UAAU,eAAe;IAC7B,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;IACjE,OAAO;QACL,UAAU,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE;QAC1E,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE;KACxE,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CACxB,cAAsB,EACtB,IAAY,EACZ,cAAsB,EACtB,OAAO,GAAG,EAAE;IAEZ,MAAM,GAAG,GAAG,eAAe,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IACtE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC;IAC9E,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,GAAG,UAAU,EAAE,CAAC,CAAC,CAAC;IACtG,MAAM,YAAY,GAAG,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC;IAC5C,OAAO,GAAG,YAAY,IAAI,MAAM,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,gBAAgB,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC9H,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { SignedCall } from './wire/call.js';
|
|
2
|
+
export type { SignedCall } from './wire/call.js';
|
|
3
|
+
/** What a deployment hands a frond that CALLS: its own key, and the root's word for it. */
|
|
4
|
+
export interface FrondIdentity {
|
|
5
|
+
/** The frond's private key, PEM (PKCS#8). */
|
|
6
|
+
privateKey: string;
|
|
7
|
+
/** The root's statement binding this frond's name to its public key. */
|
|
8
|
+
grant: string;
|
|
9
|
+
}
|
|
10
|
+
/** What `verifyEnvelope` establishes — never what the caller asked for. */
|
|
11
|
+
export interface VerifiedCall {
|
|
12
|
+
/** The frond that signed, as the root named it. */
|
|
13
|
+
caller: string;
|
|
14
|
+
/** The state it asserted, now proven to come from `caller`. */
|
|
15
|
+
state: Record<string, unknown>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Sign one call, whole: who is asking, what is asked, and on whose behalf.
|
|
19
|
+
*
|
|
20
|
+
* The private key is parsed on every call here, which is the convenience form. A process
|
|
21
|
+
* that signs in a request path builds its signer once — `identityFromEnv` does exactly
|
|
22
|
+
* that, and `sign` on the value it returns holds the parsed key.
|
|
23
|
+
*/
|
|
24
|
+
export declare function signEnvelope(identity: FrondIdentity, call: SignedCall): Promise<string>;
|
|
25
|
+
/**
|
|
26
|
+
* Establish the caller, or throw. Order matters: the grant is checked against the ROOT
|
|
27
|
+
* first, and only the key it carries verifies the envelope — reading the envelope's own
|
|
28
|
+
* claim of who it is before that would be believing the thing under examination.
|
|
29
|
+
*/
|
|
30
|
+
export declare function verifyEnvelope(token: string, rootPublicKey: string, presented: SignedCall): Promise<VerifiedCall>;
|
|
31
|
+
/** The two halves a boot needs, and the environment they come from. */
|
|
32
|
+
export interface CallIdentity {
|
|
33
|
+
/**
|
|
34
|
+
* Signs an outgoing call, whole. Absent when this process holds no key — it only answers.
|
|
35
|
+
*
|
|
36
|
+
* A promise because WebCrypto has no synchronous form. On Node the work stays
|
|
37
|
+
* synchronous inside and only the answer is wrapped: measured at 14.28 µs awaited
|
|
38
|
+
* against 14.30 µs called directly, while WebCrypto on the same curve costs 22.72.
|
|
39
|
+
*/
|
|
40
|
+
sign?: (call: SignedCall) => Promise<string>;
|
|
41
|
+
/** Establishes an incoming caller, against the call that actually arrived. */
|
|
42
|
+
verify?: (identity: string, presented: SignedCall) => Promise<VerifiedCall>;
|
|
43
|
+
/** Refuse an unsigned call. True exactly when a root is trusted. */
|
|
44
|
+
requireIdentity: boolean;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* What the deployment injected, read once at boot.
|
|
48
|
+
*
|
|
49
|
+
* Three variables, no config key: a private key never belongs in a committed file, and
|
|
50
|
+
* `fougere keys` prints exactly these. A process may hold either half or both — a frond
|
|
51
|
+
* that only answers has no key, one that only calls trusts no root, one in the middle
|
|
52
|
+
* does both.
|
|
53
|
+
*
|
|
54
|
+
* Trusting a root IS asking to refuse: there is no separate flag, because a deployment
|
|
55
|
+
* that names an authority and then accepts unsigned calls has said two things at once.
|
|
56
|
+
*/
|
|
57
|
+
export declare function identityFromEnv(env?: Record<string, string | undefined>): Promise<CallIdentity>;
|
|
58
|
+
//# sourceMappingURL=identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,YAAY,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAOjD,2FAA2F;AAC3F,MAAM,WAAW,aAAa;IAC5B,6CAA6C;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,KAAK,EAAE,MAAM,CAAC;CACf;AAuBD,2EAA2E;AAC3E,MAAM,WAAW,YAAY;IAC3B,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAkCD;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAE7F;AAaD;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAEvH;AA+BD,uEAAuE;AACvE,MAAM,WAAW,YAAY;IAC3B;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7C,8EAA8E;IAC9E,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAC5E,oEAAoE;IACpE,eAAe,EAAE,OAAO,CAAC;CAC1B;AAcD;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAkB,GAAG,OAAO,CAAC,YAAY,CAAC,CAgBrH"}
|
package/dist/identity.js
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Who is calling — the proof, not the claim.
|
|
3
|
+
*
|
|
4
|
+
* `InvocationContext.state` is what a caller SAYS about itself, and a split receiver
|
|
5
|
+
* used to believe it: identity read straight off the wire, so a reader could post
|
|
6
|
+
* `{ state: { user: { role: 'admin' } } }` and be one. This module is what turns that
|
|
7
|
+
* sack into something a receiver establishes instead of accepts.
|
|
8
|
+
*
|
|
9
|
+
* Two signatures, one public key to distribute:
|
|
10
|
+
*
|
|
11
|
+
* GRANT the root says "this key is `blog`" — issued once, at deployment
|
|
12
|
+
* ENVELOPE `blog` says "here is my whole call" — signed per call
|
|
13
|
+
*
|
|
14
|
+
* The envelope binds the CALL and not only its state: address, params, query, a digest
|
|
15
|
+
* of the body. Signing the state alone proved WHO without proving WHAT, so anyone on the
|
|
16
|
+
* wire could replay a captured envelope against another operation for as long as it
|
|
17
|
+
* stayed valid — `post.list` re-sent as `post.delete`, same signature, still good.
|
|
18
|
+
*
|
|
19
|
+
* A receiver holds the root's public key and nothing else: it validates any frond it
|
|
20
|
+
* has never seen, which is what a per-caller list could not do. The private root key
|
|
21
|
+
* signs grants and never leaves the machine that issued them.
|
|
22
|
+
*
|
|
23
|
+
* Ed25519 and a JWS-shaped grant rather than X.509: node can PARSE a certificate but
|
|
24
|
+
* not ISSUE one, so a real chain would mean openssl or a library. The grant says the
|
|
25
|
+
* same thing — a name bound to a public key, signed by the root — with no dependency.
|
|
26
|
+
*
|
|
27
|
+
* The Ed25519 itself comes through `#crypto`, which has two realizations: `node:crypto`
|
|
28
|
+
* everywhere, WebCrypto under `workerd`. Everything here is therefore async — WebCrypto
|
|
29
|
+
* has no synchronous form — and a key is parsed ONCE, into a `Signer` or a `Verifier`,
|
|
30
|
+
* never per call. Making the keys and issuing grants happen at a deployment and live in
|
|
31
|
+
* `identity-keys.ts`, on the Node entry.
|
|
32
|
+
*/
|
|
33
|
+
import { crypto } from '#crypto';
|
|
34
|
+
import { b64url, unb64url, bytesOf, textOf, unb64 } from './crypto/encoding.js';
|
|
35
|
+
/** How long a call envelope stays valid. A signed call is not a session. */
|
|
36
|
+
const ENVELOPE_TTL_MS = 60_000;
|
|
37
|
+
/** Clock skew tolerated on both sides of a validity window. */
|
|
38
|
+
const SKEW_MS = 30_000;
|
|
39
|
+
/** The body's fingerprint. Absence and explicit null are different signed calls. */
|
|
40
|
+
async function digestOf(body) {
|
|
41
|
+
// The tag is outside the caller value, so no user object can collide with it. JSON's
|
|
42
|
+
// own omission rule still applies inside `value`, matching what crosses the wire.
|
|
43
|
+
const canonical = body === undefined
|
|
44
|
+
? { kind: 'undefined' }
|
|
45
|
+
: { kind: 'value', value: body };
|
|
46
|
+
return b64url(await crypto.sha256(bytesOf(JSON.stringify(canonical))));
|
|
47
|
+
}
|
|
48
|
+
/** What the envelope pins, as one comparable value. */
|
|
49
|
+
async function boundTo(call) {
|
|
50
|
+
return {
|
|
51
|
+
entity: call.entity,
|
|
52
|
+
op: call.op,
|
|
53
|
+
params: call.params ?? {},
|
|
54
|
+
query: call.query ?? {},
|
|
55
|
+
body: await digestOf(call.body),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/** A JWS compact serialization, signed with Ed25519. */
|
|
59
|
+
async function signJws(header, payload, signer) {
|
|
60
|
+
const signingInput = `${b64url(JSON.stringify(header))}.${b64url(JSON.stringify(payload))}`;
|
|
61
|
+
return `${signingInput}.${b64url(await signer.sign(bytesOf(signingInput)))}`;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The payload, once the signature holds. Throws rather than returning a falsy value:
|
|
65
|
+
* every caller here is deciding whether to admit a call, and an unverified payload
|
|
66
|
+
* must never be reachable by forgetting a check.
|
|
67
|
+
*/
|
|
68
|
+
async function verifyJws(token, verifier, what) {
|
|
69
|
+
const parts = token.split('.');
|
|
70
|
+
if (parts.length !== 3)
|
|
71
|
+
throw new Error(`Malformed ${what}`);
|
|
72
|
+
const [encodedHeader, encodedPayload, encodedSignature] = parts;
|
|
73
|
+
if (!await verifier.verify(bytesOf(`${encodedHeader}.${encodedPayload}`), unb64url(encodedSignature))) {
|
|
74
|
+
throw new Error(`Bad ${what} signature`);
|
|
75
|
+
}
|
|
76
|
+
const payload = JSON.parse(textOf(unb64url(encodedPayload)));
|
|
77
|
+
const now = Date.now();
|
|
78
|
+
if (typeof payload.exp === 'number' && now > payload.exp + SKEW_MS)
|
|
79
|
+
throw new Error(`Expired ${what}`);
|
|
80
|
+
if (typeof payload.nbf === 'number' && now < payload.nbf - SKEW_MS)
|
|
81
|
+
throw new Error(`${what} not yet valid`);
|
|
82
|
+
return payload;
|
|
83
|
+
}
|
|
84
|
+
/** Read a JWS header without verifying anything — only to find which key to verify WITH. */
|
|
85
|
+
function headerOf(token) {
|
|
86
|
+
const encodedHeader = token.split('.')[0];
|
|
87
|
+
if (!encodedHeader)
|
|
88
|
+
throw new Error('Malformed envelope');
|
|
89
|
+
return JSON.parse(textOf(unb64url(encodedHeader)));
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Sign one call, whole: who is asking, what is asked, and on whose behalf.
|
|
93
|
+
*
|
|
94
|
+
* The private key is parsed on every call here, which is the convenience form. A process
|
|
95
|
+
* that signs in a request path builds its signer once — `identityFromEnv` does exactly
|
|
96
|
+
* that, and `sign` on the value it returns holds the parsed key.
|
|
97
|
+
*/
|
|
98
|
+
export async function signEnvelope(identity, call) {
|
|
99
|
+
return sealWith(await crypto.signerOf(identity.privateKey), identity.grant, call);
|
|
100
|
+
}
|
|
101
|
+
/** The same envelope, against a key someone already parsed. */
|
|
102
|
+
async function sealWith(signer, grant, call) {
|
|
103
|
+
const now = Date.now();
|
|
104
|
+
const { sub } = JSON.parse(textOf(unb64url(grant.split('.')[1])));
|
|
105
|
+
return signJws({ alg: 'EdDSA', typ: 'fougere-call', grant }, { iss: sub, state: call.state ?? {}, bound: await boundTo(call), iat: now, exp: now + ENVELOPE_TTL_MS }, signer);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Establish the caller, or throw. Order matters: the grant is checked against the ROOT
|
|
109
|
+
* first, and only the key it carries verifies the envelope — reading the envelope's own
|
|
110
|
+
* claim of who it is before that would be believing the thing under examination.
|
|
111
|
+
*/
|
|
112
|
+
export async function verifyEnvelope(token, rootPublicKey, presented) {
|
|
113
|
+
return openWith(await crypto.verifierOf(rootPublicKey), token, presented);
|
|
114
|
+
}
|
|
115
|
+
/** The same check, against a root key someone already parsed. */
|
|
116
|
+
async function openWith(root, token, presented) {
|
|
117
|
+
const { grant } = headerOf(token);
|
|
118
|
+
if (typeof grant !== 'string')
|
|
119
|
+
throw new Error('Envelope carries no grant');
|
|
120
|
+
const granted = await verifyJws(grant, root, 'grant');
|
|
121
|
+
if (typeof granted.sub !== 'string' || typeof granted.jwk !== 'object' || granted.jwk === null) {
|
|
122
|
+
throw new Error('Grant names no frond');
|
|
123
|
+
}
|
|
124
|
+
const payload = await verifyJws(token, await crypto.verifierOf(granted.jwk), 'envelope');
|
|
125
|
+
// The grant is the authority on the name; the envelope only repeats it. They disagree
|
|
126
|
+
// when a frond signs under someone else's name with its own key.
|
|
127
|
+
if (payload.iss !== granted.sub)
|
|
128
|
+
throw new Error(`Envelope signed by '${granted.sub}' claims to be '${String(payload.iss)}'`);
|
|
129
|
+
// The signature says this envelope was made by `blog`; this says it was made for THIS
|
|
130
|
+
// call. Without it a captured envelope is a blank cheque until it expires.
|
|
131
|
+
const bound = JSON.stringify(payload.bound);
|
|
132
|
+
if (bound !== JSON.stringify(await boundTo(presented))) {
|
|
133
|
+
throw new Error(`Envelope was signed for a different call than ${presented.entity}.${presented.op}`);
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
caller: granted.sub,
|
|
137
|
+
state: payload.state ?? {},
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* A PEM, however the deployment chose to carry it.
|
|
142
|
+
*
|
|
143
|
+
* A PEM is multi-line and an environment variable that spans lines survives poorly —
|
|
144
|
+
* docker-compose, systemd and CI secret stores each mangle it differently — so
|
|
145
|
+
* `fougere keys` prints base64. Both forms are read here rather than one being decreed:
|
|
146
|
+
* a human pasting a real PEM is not making a mistake.
|
|
147
|
+
*/
|
|
148
|
+
function pemOf(value) {
|
|
149
|
+
return value.trimStart().startsWith('-----') ? value : textOf(unb64(value));
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* What the deployment injected, read once at boot.
|
|
153
|
+
*
|
|
154
|
+
* Three variables, no config key: a private key never belongs in a committed file, and
|
|
155
|
+
* `fougere keys` prints exactly these. A process may hold either half or both — a frond
|
|
156
|
+
* that only answers has no key, one that only calls trusts no root, one in the middle
|
|
157
|
+
* does both.
|
|
158
|
+
*
|
|
159
|
+
* Trusting a root IS asking to refuse: there is no separate flag, because a deployment
|
|
160
|
+
* that names an authority and then accepts unsigned calls has said two things at once.
|
|
161
|
+
*/
|
|
162
|
+
export async function identityFromEnv(env = envOfProcess()) {
|
|
163
|
+
const root = env.FOUGERE_ROOT ? pemOf(env.FOUGERE_ROOT) : undefined;
|
|
164
|
+
const privateKey = env.FOUGERE_KEY ? pemOf(env.FOUGERE_KEY) : undefined;
|
|
165
|
+
const grant = env.FOUGERE_GRANT;
|
|
166
|
+
// Async because the keys are parsed HERE, once, and both closures below capture the
|
|
167
|
+
// result: importing a key is per-key work, and a per-call import would put it inside
|
|
168
|
+
// every request. This is the one gesture a boot pays for.
|
|
169
|
+
const signer = privateKey ? await crypto.signerOf(privateKey) : undefined;
|
|
170
|
+
const rootKey = root ? await crypto.verifierOf(root) : undefined;
|
|
171
|
+
return {
|
|
172
|
+
...(signer && grant ? { sign: (call) => sealWith(signer, grant, call) } : {}),
|
|
173
|
+
...(rootKey ? { verify: (identity, presented) => openWith(rootKey, identity, presented) } : {}),
|
|
174
|
+
requireIdentity: Boolean(root),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
/** A Worker has no `process`. Reading the global is what makes an absent one an empty env. */
|
|
178
|
+
function envOfProcess() {
|
|
179
|
+
const proc = globalThis.process;
|
|
180
|
+
return proc?.env ?? {};
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAKhF,4EAA4E;AAC5E,MAAM,eAAe,GAAG,MAAM,CAAC;AAC/B,+DAA+D;AAC/D,MAAM,OAAO,GAAG,MAAM,CAAC;AAUvB,oFAAoF;AACpF,KAAK,UAAU,QAAQ,CAAC,IAAa;IACnC,qFAAqF;IACrF,kFAAkF;IAClF,MAAM,SAAS,GAAG,IAAI,KAAK,SAAS;QAClC,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE;QACvB,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACnC,OAAO,MAAM,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AACzE,CAAC;AAED,uDAAuD;AACvD,KAAK,UAAU,OAAO,CAAC,IAAgB;IACrC,OAAO;QACL,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE;QACzB,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE;QACvB,IAAI,EAAE,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;KAChC,CAAC;AACJ,CAAC;AAUD,wDAAwD;AACxD,KAAK,UAAU,OAAO,CAAC,MAAc,EAAE,OAAe,EAAE,MAAc;IACpE,MAAM,YAAY,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;IAC5F,OAAO,GAAG,YAAY,IAAI,MAAM,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;AAC/E,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,SAAS,CAAC,KAAa,EAAE,QAAkB,EAAE,IAAY;IACtE,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;IAC7D,MAAM,CAAC,aAAa,EAAE,cAAc,EAAE,gBAAgB,CAAC,GAAG,KAAK,CAAC;IAChE,IAAI,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,aAAa,IAAI,cAAc,EAAE,CAAC,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC;QACtG,MAAM,IAAI,KAAK,CAAC,OAAO,IAAI,YAAY,CAAC,CAAC;IAC3C,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAA4B,CAAC;IACxF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ,IAAI,GAAG,GAAG,OAAO,CAAC,GAAG,GAAG,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;IACvG,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ,IAAI,GAAG,GAAG,OAAO,CAAC,GAAG,GAAG,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,gBAAgB,CAAC,CAAC;IAC7G,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,4FAA4F;AAC5F,SAAS,QAAQ,CAAC,KAAa;IAC7B,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,IAAI,CAAC,aAAa;QAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAC1D,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAA4B,CAAC;AAChF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAuB,EAAE,IAAgB;IAC1E,OAAO,QAAQ,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AACpF,CAAC;AAED,+DAA+D;AAC/D,KAAK,UAAU,QAAQ,CAAC,MAAc,EAAE,KAAa,EAAE,IAAgB;IACrE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAoB,CAAC;IACrF,OAAO,OAAO,CACZ,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,EAC5C,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,eAAe,EAAE,EACvG,MAAM,CACP,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAa,EAAE,aAAqB,EAAE,SAAqB;IAC9F,OAAO,QAAQ,CAAC,MAAM,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;AAC5E,CAAC;AAED,iEAAiE;AACjE,KAAK,UAAU,QAAQ,CAAC,IAAc,EAAE,KAAa,EAAE,SAAqB;IAC1E,MAAM,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAE5E,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IACtD,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ,IAAI,OAAO,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC;QAC/F,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,MAAM,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,GAAgB,CAAC,EAAE,UAAU,CAAC,CAAC;IAEtG,sFAAsF;IACtF,iEAAiE;IACjE,IAAI,OAAO,CAAC,GAAG,KAAK,OAAO,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,OAAO,CAAC,GAAG,mBAAmB,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAE9H,sFAAsF;IACtF,2EAA2E;IAC3E,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC5C,IAAI,KAAK,KAAK,IAAI,CAAC,SAAS,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,iDAAiD,SAAS,CAAC,MAAM,IAAI,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC;IACvG,CAAC;IAED,OAAO;QACL,MAAM,EAAE,OAAO,CAAC,GAAG;QACnB,KAAK,EAAG,OAAO,CAAC,KAAiC,IAAI,EAAE;KACxD,CAAC;AACJ,CAAC;AAkBD;;;;;;;GAOG;AACH,SAAS,KAAK,CAAC,KAAa;IAC1B,OAAO,KAAK,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAA0C,YAAY,EAAE;IAC5F,MAAM,IAAI,GAAG,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACpE,MAAM,UAAU,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACxE,MAAM,KAAK,GAAG,GAAG,CAAC,aAAa,CAAC;IAEhC,oFAAoF;IACpF,qFAAqF;IACrF,0DAA0D;IAC1D,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1E,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAEjE,OAAO;QACL,GAAG,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,IAAgB,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzF,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,QAAgB,EAAE,SAAqB,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnH,eAAe,EAAE,OAAO,CAAC,IAAI,CAAC;KAC/B,CAAC;AACJ,CAAC;AAED,8FAA8F;AAC9F,SAAS,YAAY;IACnB,MAAM,IAAI,GAAI,UAAyE,CAAC,OAAO,CAAC;IAChG,OAAO,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;AACzB,CAAC"}
|
package/dist/imports.d.ts
CHANGED
package/dist/imports.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"imports.d.ts","sourceRoot":"","sources":["../src/imports.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"imports.d.ts","sourceRoot":"","sources":["../src/imports.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAQvD,MAAM,WAAW,gBAAgB;IAC/B,8DAA8D;IAC9D,IAAI,EAAE,oBAAoB,CAAC;IAC3B,oCAAoC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AA2BD;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,aAAa,CAAC,IAAI,CAAC,eAAe,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,GAC9D,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAwC7B"}
|
package/dist/imports.js
CHANGED
|
@@ -3,7 +3,7 @@ import { join, resolve, dirname, relative, isAbsolute } from 'node:path';
|
|
|
3
3
|
let _ts;
|
|
4
4
|
async function loadTs() {
|
|
5
5
|
if (!_ts)
|
|
6
|
-
_ts = (await import('typescript')).default;
|
|
6
|
+
_ts = (await import('@typescript/typescript6')).default;
|
|
7
7
|
return _ts;
|
|
8
8
|
}
|
|
9
9
|
/** Is `child` inside `parent`? Path-based, so it says nothing about either existing. */
|
|
@@ -42,7 +42,11 @@ async function sourcesUnder(dir) {
|
|
|
42
42
|
*/
|
|
43
43
|
export async function crossFrondImports(fronds) {
|
|
44
44
|
const typescript = await loadTs();
|
|
45
|
-
|
|
45
|
+
// `source.package` is the scoped name the scan already resolved — the remedy this rule
|
|
46
|
+
// prints must be the name that actually resolves, not one rebuilt from a prefix here.
|
|
47
|
+
const roots = fronds.map((frond) => ({
|
|
48
|
+
name: frond.name, path: resolve(frond.source.path), package: frond.source.package,
|
|
49
|
+
}));
|
|
46
50
|
const found = [];
|
|
47
51
|
for (const root of roots) {
|
|
48
52
|
for (const filePath of await sourcesUnder(root.path)) {
|
|
@@ -65,7 +69,7 @@ export async function crossFrondImports(fronds) {
|
|
|
65
69
|
message: target
|
|
66
70
|
? `'${specifier}' resolves into frond '${target.name}'. A relative path states that `
|
|
67
71
|
+ `these two fronds share a directory tree — a constraint nothing declares, and one `
|
|
68
|
-
+ `that nothing here can see. Write '
|
|
72
|
+
+ `that nothing here can see. Write '${target.package}/…' instead: it says the `
|
|
69
73
|
+ `same dependency in terms the model reads, and it is the form \`fougere sync\` writes, `
|
|
70
74
|
+ `so it survives '${target.name}' moving out.`
|
|
71
75
|
: `'${specifier}' resolves outside frond '${root.name}', into no frond at all. `
|