@fougere/core 0.6.0-alpha.0 → 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 +13 -90
- 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 +2 -12
- package/dist/boot/auth.d.ts.map +1 -1
- package/dist/boot/boot.d.ts +3 -16
- package/dist/boot/boot.d.ts.map +1 -1
- package/dist/boot/boot.js +3 -10
- package/dist/boot/boot.js.map +1 -1
- package/dist/boot/bootstrap.d.ts.map +1 -1
- package/dist/boot/bootstrap.js +61 -127
- package/dist/boot/bootstrap.js.map +1 -1
- package/dist/boot/card.d.ts +1 -17
- package/dist/boot/card.d.ts.map +1 -1
- package/dist/boot/card.js +3 -32
- package/dist/boot/card.js.map +1 -1
- package/dist/boot/frame.d.ts +8 -32
- package/dist/boot/frame.d.ts.map +1 -1
- package/dist/boot/frame.js +20 -54
- package/dist/boot/frame.js.map +1 -1
- package/dist/boot/hosted.d.ts +2 -24
- package/dist/boot/hosted.d.ts.map +1 -1
- package/dist/boot/hosted.js +10 -15
- package/dist/boot/hosted.js.map +1 -1
- package/dist/boot/ownership.d.ts +3 -36
- package/dist/boot/ownership.d.ts.map +1 -1
- package/dist/boot/ownership.js +5 -40
- package/dist/boot/ownership.js.map +1 -1
- package/dist/boot/ports.d.ts +1 -14
- 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 +4 -21
- package/dist/boot/runner.d.ts.map +1 -1
- package/dist/boot/runner.js +4 -17
- package/dist/boot/runner.js.map +1 -1
- package/dist/boot/seed.d.ts +4 -31
- package/dist/boot/seed.d.ts.map +1 -1
- package/dist/boot/seed.js +6 -37
- package/dist/boot/seed.js.map +1 -1
- package/dist/boot/statement-drift.d.ts +2 -21
- 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 +4 -8
- package/dist/boot/together.d.ts.map +1 -1
- package/dist/boot/together.js +15 -50
- package/dist/boot/together.js.map +1 -1
- package/dist/boot/types.d.ts +28 -173
- 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 +6 -36
- package/dist/declare.d.ts.map +1 -1
- package/dist/declare.js +4 -29
- package/dist/declare.js.map +1 -1
- 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 +3 -28
- package/dist/descriptor/Fronds.d.ts.map +1 -1
- package/dist/descriptor/Fronds.js +6 -31
- package/dist/descriptor/Fronds.js.map +1 -1
- package/dist/descriptor/frond.d.ts +14 -63
- package/dist/descriptor/frond.d.ts.map +1 -1
- package/dist/dispatch/ArgumentResolver.d.ts +1 -1
- package/dist/dispatch/ArgumentResolver.d.ts.map +1 -1
- package/dist/dispatch/ArgumentResolver.js +5 -5
- 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 -2
- 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 +8 -7
- package/dist/dispatch/StorageGuard.d.ts.map +1 -1
- package/dist/dispatch/StorageGuard.js +61 -18
- 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 +1 -24
- package/dist/effective-operation.d.ts.map +1 -1
- package/dist/effective-operation.js +21 -50
- 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 +7 -70
- 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/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 +1 -7
- 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 +17 -24
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -18
- 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 +16 -32
- package/dist/prefab/crud.d.ts.map +1 -1
- package/dist/prefab/crud.js +31 -58
- package/dist/prefab/crud.js.map +1 -1
- package/dist/prefab/mirror.d.ts +2 -24
- package/dist/prefab/mirror.d.ts.map +1 -1
- package/dist/prefab/mirror.js +2 -20
- 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 +5 -73
- package/dist/prefab/repository.d.ts.map +1 -1
- package/dist/prefab/repository.js +3 -16
- 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 +1 -5
- package/dist/scan/emit.d.ts.map +1 -1
- package/dist/scan/emit.js +4 -38
- package/dist/scan/emit.js.map +1 -1
- package/dist/scan/handler-parser.d.ts +4 -26
- package/dist/scan/handler-parser.d.ts.map +1 -1
- package/dist/scan/handler-parser.js +26 -83
- package/dist/scan/handler-parser.js.map +1 -1
- package/dist/scan/result.d.ts +3 -16
- package/dist/scan/result.d.ts.map +1 -1
- package/dist/scan/scanner.d.ts +2 -27
- package/dist/scan/scanner.d.ts.map +1 -1
- package/dist/scan/scanner.js +28 -127
- package/dist/scan/scanner.js.map +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 +13 -210
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +4 -68
- package/dist/storage.js.map +1 -1
- 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 +5 -38
- package/dist/verify.d.ts.map +1 -1
- package/dist/verify.js +17 -37
- 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/{contract → wire}/RouteAddress.d.ts +5 -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 +5 -21
- package/dist/wire/binding.d.ts.map +1 -1
- package/dist/wire/binding.js +5 -10
- package/dist/wire/binding.js.map +1 -1
- package/dist/wire/call.d.ts +24 -133
- package/dist/wire/call.d.ts.map +1 -1
- package/dist/wire/call.js +15 -41
- 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 +7 -43
- package/dist/wire/operation.d.ts.map +1 -1
- package/dist/wire/operation.js +4 -15
- package/dist/wire/operation.js.map +1 -1
- package/dist/wire/signature.d.ts +4 -25
- package/dist/wire/signature.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/boot/Emissions.ts +21 -118
- 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 +2 -12
- package/src/boot/boot.ts +5 -20
- package/src/boot/bootstrap.ts +69 -136
- package/src/boot/card.ts +4 -33
- package/src/boot/frame.ts +28 -62
- package/src/boot/hosted.ts +12 -34
- package/src/boot/ownership.ts +5 -39
- package/src/boot/ports.ts +1 -14
- package/src/boot/remote.ts +11 -58
- package/src/boot/runner.ts +5 -22
- package/src/boot/seed.ts +6 -37
- package/src/boot/statement-drift.ts +5 -24
- package/src/boot/together.ts +18 -51
- package/src/boot/types.ts +28 -173
- 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/declare.ts +8 -39
- package/src/define.ts +2 -3
- package/src/descriptor/Fronds.ts +6 -31
- package/src/descriptor/frond.ts +14 -63
- package/src/dispatch/ArgumentResolver.ts +6 -6
- 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 -2
- 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 +70 -18
- 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 +21 -50
- 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 +7 -70
- package/src/identity-keys.ts +3 -16
- package/src/identity.ts +12 -80
- package/src/imports.ts +2 -31
- package/src/index.ts +17 -24
- package/src/loader.ts +2 -16
- package/src/node.ts +2 -11
- package/src/prefab/collector.ts +1 -22
- package/src/prefab/crud.ts +37 -76
- package/src/prefab/mirror.ts +4 -44
- package/src/prefab/prefab.ts +2 -21
- package/src/prefab/presenter.ts +2 -36
- package/src/prefab/repository.ts +7 -83
- 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 +4 -38
- package/src/scan/handler-parser.ts +27 -96
- package/src/scan/result.ts +3 -16
- package/src/scan/scanner.ts +27 -126
- package/src/scan/statement.ts +4 -30
- package/src/source.ts +44 -0
- package/src/storage.ts +14 -234
- package/src/store.ts +152 -0
- package/src/verify.ts +16 -57
- package/src/wire/CallLog.ts +30 -0
- package/src/{contract → wire}/Invocation.ts +24 -17
- package/src/{contract → wire}/RouteAddress.ts +7 -0
- package/src/wire/binding.ts +9 -25
- package/src/wire/call.ts +30 -133
- 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 +8 -48
- package/src/wire/signature.ts +4 -25
- package/dist/boot/HandlerFacade.d.ts.map +0 -1
- package/dist/boot/HandlerFacade.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.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/rows.d.ts +0 -40
- package/dist/rows.d.ts.map +0 -1
- package/dist/rows.js +0 -146
- package/dist/rows.js.map +0 -1
- package/src/boot/HandlerFacade.ts +0 -242
- 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/rows.ts +0 -155
- /package/dist/{contract → wire}/CallLog.js +0 -0
package/src/scan/conventions.ts
CHANGED
|
@@ -1,19 +1,7 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The names the scan READS instead of deriving them.
|
|
3
|
-
*
|
|
4
|
-
* Everything else a frond states, it states by its shape; these seven directories and the
|
|
5
|
-
* import prefix are the one place where a name is the declaration. They were spelled as
|
|
6
|
-
* literals in five packages, so a project could not move any of them and `frondsDir` was
|
|
7
|
-
* a declared key with no reader.
|
|
8
|
-
*/
|
|
1
|
+
/** The names the scan READS instead of deriving them. */
|
|
9
2
|
|
|
10
3
|
export interface Conventions {
|
|
11
|
-
/**
|
|
12
|
-
* The scope a frond's package name carries — `@fronds/blog`.
|
|
13
|
-
*
|
|
14
|
-
* A real package name, not only an alias: the CLI writes it as `name` in a scaffolded
|
|
15
|
-
* frond and as a `workspace:*` dependency in the app that consumes it.
|
|
16
|
-
*/
|
|
4
|
+
/** The scope a frond's package name carries — `@fronds/blog`. */
|
|
17
5
|
scope: string;
|
|
18
6
|
/** The directory holding fronds, below the project root. */
|
|
19
7
|
fronds: string;
|
|
@@ -31,12 +19,7 @@ export interface Conventions {
|
|
|
31
19
|
};
|
|
32
20
|
}
|
|
33
21
|
|
|
34
|
-
/**
|
|
35
|
-
* What a project means when it declares nothing — the convention itself.
|
|
36
|
-
*
|
|
37
|
-
* `@fronds` and not `@frond`: the npm org for the singular belongs to someone else, and a
|
|
38
|
-
* scope is a name that must be ownable.
|
|
39
|
-
*/
|
|
22
|
+
/** What a project means when it declares nothing — the convention itself. */
|
|
40
23
|
export const DEFAULT_CONVENTIONS: Conventions = {
|
|
41
24
|
scope: '@fronds',
|
|
42
25
|
fronds: 'fronds',
|
|
@@ -59,13 +42,7 @@ export type ConventionsInput = {
|
|
|
59
42
|
dirs?: Partial<Conventions['dirs']>;
|
|
60
43
|
};
|
|
61
44
|
|
|
62
|
-
/**
|
|
63
|
-
* The convention, with a project's exceptions folded in.
|
|
64
|
-
*
|
|
65
|
-
* Merged one level into `dirs` so renaming one directory does not require restating the
|
|
66
|
-
* other six — the same reading `sources:` and `ports:` get, where only the exception is
|
|
67
|
-
* declared.
|
|
68
|
-
*/
|
|
45
|
+
/** The convention, with a project's exceptions folded in. */
|
|
69
46
|
export function resolveConventions(input?: ConventionsInput): Conventions {
|
|
70
47
|
return {
|
|
71
48
|
scope: input?.scope ?? DEFAULT_CONVENTIONS.scope,
|
|
@@ -79,23 +56,12 @@ export function frondPackage(name: string, conventions: Conventions): string {
|
|
|
79
56
|
return `${conventions.scope}/${name}`;
|
|
80
57
|
}
|
|
81
58
|
|
|
82
|
-
/**
|
|
83
|
-
* Directories whose classes register as providers — two spellings, one behaviour.
|
|
84
|
-
*
|
|
85
|
-
* A project may point both roles at one directory; the scan must then read it once, or
|
|
86
|
-
* every provider would be registered twice.
|
|
87
|
-
*/
|
|
59
|
+
/** Directories whose classes register as providers — two spellings, one behaviour. */
|
|
88
60
|
export function providerDirsOf(conventions: Conventions): string[] {
|
|
89
61
|
return [...new Set([conventions.dirs.services, conventions.dirs.repositories])];
|
|
90
62
|
}
|
|
91
63
|
|
|
92
|
-
/**
|
|
93
|
-
* The frond vocabulary — every directory the scan reads.
|
|
94
|
-
*
|
|
95
|
-
* What a reader needs to bound a frond: the Nuxt module watches these for the root frond
|
|
96
|
-
* (watching the root itself would match every write), and a flat app's tsconfig lists
|
|
97
|
-
* them instead of `["."]`, which would swallow `app/` and `nuxt.config.ts`.
|
|
98
|
-
*/
|
|
64
|
+
/** The frond vocabulary — every directory the scan reads. */
|
|
99
65
|
export function frondDirsOf(conventions: Conventions): string[] {
|
|
100
66
|
const { entities, handlers, presenters, collectors, seeds, versions } = conventions.dirs;
|
|
101
67
|
return [...new Set([
|
package/src/scan/emit.ts
CHANGED
|
@@ -1,19 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The scan, written down as a module — what `createApp` is handed where there is no disk.
|
|
3
|
-
*
|
|
4
|
-
* It RE-RESOLVES NOTHING. By the time this runs the scan has already decided what every
|
|
5
|
-
* slot holds, and `resolveSchema` put the entity's own class in `contract.output` — the
|
|
6
|
-
* very object `EntityEntry.entityClass` holds. So the emitter keeps a table from object
|
|
7
|
-
* to import alias and writes the alias. Identity is preserved because it is the same
|
|
8
|
-
* object that becomes the same import, which is what three call sites depend on
|
|
9
|
-
* (`adapter/graphql`'s `view === entity.entityClass` and its WeakMap, and `bootstrap`'s
|
|
10
|
-
* `outputSchema !== entity.entityClass`). An emitter that re-resolved instead would build
|
|
11
|
-
* a second class for `Post` and those three would silently take the other branch.
|
|
12
|
-
*
|
|
13
|
-
* Measured on three real projects: every live reference is either a class the descriptor
|
|
14
|
-
* already names by `filePath`, a named export of the file that declared the signature, or
|
|
15
|
-
* `Partial<X>` — the one derivation `resolveSchema` fabricates.
|
|
16
|
-
*/
|
|
1
|
+
/** The scan, written down as a module — what `createApp` is handed where there is no disk. */
|
|
17
2
|
import { dirname, relative } from 'node:path';
|
|
18
3
|
import { ANONYMOUS_SCHEMA_NAME, Card, type SchemaView } from '@fougere/schema';
|
|
19
4
|
import type { FrondDescriptor, EntityEntry, HandlerEntry, PresenterEntry, CollectorEntry, ProviderEntry, SeedEntry } from '../descriptor/frond.js';
|
|
@@ -32,14 +17,7 @@ type Live = object;
|
|
|
32
17
|
/** Is a TypeScript compiler going to read this module? Its name is the only thing that says. */
|
|
33
18
|
const isTypeScript = (outFile: string): boolean => /\.tsx?$/.test(outFile);
|
|
34
19
|
|
|
35
|
-
/**
|
|
36
|
-
* A source file becomes a specifier its reader can follow — and the two readers differ.
|
|
37
|
-
*
|
|
38
|
-
* A `.ts` destination is compiled by tsc under Node16 resolution, which spells a
|
|
39
|
-
* TypeScript source with `.js`. A `.mjs` destination is read by a bundler, which resolves
|
|
40
|
-
* the path AS IT IS ON DISK — measured, Nitro's rollup refused `Post.seed.js` because no
|
|
41
|
-
* such file exists. One rule, read off the destination, exactly like the type annotation.
|
|
42
|
-
*/
|
|
20
|
+
/** A source file becomes a specifier its reader can follow — and the two readers differ. */
|
|
43
21
|
function specifierOf(filePath: string, outFile: string): string {
|
|
44
22
|
const path = relative(dirname(outFile), filePath);
|
|
45
23
|
const rel = isTypeScript(outFile) ? path.replace(/\.tsx?$/, '.js') : path;
|
|
@@ -81,15 +59,7 @@ class Imports {
|
|
|
81
59
|
render(): string { return this.lines.join('\n'); }
|
|
82
60
|
}
|
|
83
61
|
|
|
84
|
-
/**
|
|
85
|
-
* What a schema slot becomes in the generated module.
|
|
86
|
-
*
|
|
87
|
-
* Three answers, and the third is the only rule: a class already imported is its alias; a
|
|
88
|
-
* named export of the file that declared the signature is imported by its own name — it
|
|
89
|
-
* IS exported there, because that is where `resolveSchema` found it; and an anonymous
|
|
90
|
-
* schema is `Partial<X>`, the one derivation `resolveSchema` builds, so it is written as
|
|
91
|
-
* the derivation rather than as a value.
|
|
92
|
-
*/
|
|
62
|
+
/** What a schema slot becomes in the generated module. */
|
|
93
63
|
function schemaRef(schema: SchemaView | undefined, declaredIn: string, imports: Imports): string | undefined {
|
|
94
64
|
if (!schema) return undefined;
|
|
95
65
|
const known = imports.aliasOf(schema as Live);
|
|
@@ -178,11 +148,7 @@ function frondOf(f: FrondDescriptor, imports: Imports): string {
|
|
|
178
148
|
].filter(Boolean).join('\n');
|
|
179
149
|
}
|
|
180
150
|
|
|
181
|
-
/**
|
|
182
|
-
* Write a scan down. The result is a TypeScript module whose only imports are the classes
|
|
183
|
-
* the scan found — static, so a bundler traces them — and whose only value is the
|
|
184
|
-
* descriptor `createApp` asks for.
|
|
185
|
-
*/
|
|
151
|
+
/** Write a scan down. */
|
|
186
152
|
export function emitScan(result: ScanResult, options: EmitOptions): string {
|
|
187
153
|
const imports = new Imports(options.outFile);
|
|
188
154
|
const core = options.core ?? '@fougere/core';
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Handler signature parser — extracts method signatures from handler source files.
|
|
3
|
-
*
|
|
4
|
-
* The AST says what the author declared; TypeScript's checker says what those types mean.
|
|
5
|
-
* TypeScript is lazy-loaded to avoid bundling the compiler in production builds.
|
|
6
|
-
*/
|
|
1
|
+
/** Handler signature parser — extracts method signatures from handler source files. */
|
|
7
2
|
import type { TypeRef, Param, Signature } from '../wire/signature.js';
|
|
8
3
|
import type ts from '@typescript/typescript6';
|
|
9
4
|
import { readFileSync, existsSync, statSync } from 'node:fs';
|
|
@@ -26,26 +21,11 @@ interface TypeProject {
|
|
|
26
21
|
program: ts.Program;
|
|
27
22
|
}
|
|
28
23
|
|
|
29
|
-
/**
|
|
30
|
-
* One checked program per project/configuration during a scan.
|
|
31
|
-
*
|
|
32
|
-
* A checker is a project reader, not a file parser: creating one per handler would reopen
|
|
33
|
-
* the standard library and every imported declaration for each method. `scanProject`
|
|
34
|
-
* resets this map at the start of a run, so an edited source can never meet a program from
|
|
35
|
-
* the previous run.
|
|
36
|
-
*/
|
|
24
|
+
/** One checked program per project/configuration during a scan. */
|
|
37
25
|
const typeProjects = new Map<string, TypeProject>();
|
|
38
26
|
const compilerProjects = new Map<string, { key: string; roots: string[]; options: ts.CompilerOptions }>();
|
|
39
27
|
|
|
40
|
-
/**
|
|
41
|
-
* What survives a run: the parsed declarations, and the program built over them.
|
|
42
|
-
*
|
|
43
|
-
* Rebuilding a program re-reads `lib.d.ts` and every imported `.d.ts`, and that is FIXED
|
|
44
|
-
* work — measured, a second scan in one process cost the same at 16 frond files as at 406.
|
|
45
|
-
* The mtime is the guard, so a run still cannot see a stale type: a file that moved is
|
|
46
|
-
* re-read and TypeScript invalidates it and everything depending on it, which is a
|
|
47
|
-
* narrower rule than discarding the program and not a weaker one.
|
|
48
|
-
*/
|
|
28
|
+
/** What survives a run. */
|
|
49
29
|
const sourceFiles = new Map<string, { mtime: number; file: ts.SourceFile }>();
|
|
50
30
|
const retained = new Map<string, { host: ts.CompilerHost; program: ts.Program }>();
|
|
51
31
|
|
|
@@ -61,8 +41,8 @@ export function forgetParsedSources(): void {
|
|
|
61
41
|
}
|
|
62
42
|
|
|
63
43
|
function keptHost(key: string, options: ts.CompilerOptions): ts.CompilerHost {
|
|
64
|
-
const
|
|
65
|
-
if (
|
|
44
|
+
const cached = retained.get(key);
|
|
45
|
+
if (cached) return cached.host;
|
|
66
46
|
const typescript = getTS();
|
|
67
47
|
const base = typescript.createCompilerHost(options);
|
|
68
48
|
const host: ts.CompilerHost = {
|
|
@@ -138,13 +118,7 @@ function compilerProjectOf(filePath: string, projectRoot?: string): { key: strin
|
|
|
138
118
|
return configured;
|
|
139
119
|
}
|
|
140
120
|
|
|
141
|
-
/**
|
|
142
|
-
* Declare every file a run will read, so one program covers it.
|
|
143
|
-
*
|
|
144
|
-
* `checkedSourceOf` rebuilds whenever it meets a root it has not seen, and a frond lives
|
|
145
|
-
* outside its project's tsconfig `include`, so every declaration was a new root: 44 files
|
|
146
|
-
* cost 7.3 s that way against 0.34 s for one program.
|
|
147
|
-
*/
|
|
121
|
+
/** Declare every file a run will read, so one program covers it. */
|
|
148
122
|
export async function seedTypeProgram(filePaths: readonly string[], projectRoot?: string): Promise<void> {
|
|
149
123
|
const typescript = await loadTS();
|
|
150
124
|
const grouped = new Map<string, { options: ts.CompilerOptions; paths: string[] }>();
|
|
@@ -152,9 +126,9 @@ export async function seedTypeProgram(filePaths: readonly string[], projectRoot?
|
|
|
152
126
|
for (const filePath of filePaths) {
|
|
153
127
|
const absolute = resolvePath(filePath);
|
|
154
128
|
const configured = compilerProjectOf(absolute, projectRoot);
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
grouped.set(configured.key,
|
|
129
|
+
const group = grouped.get(configured.key) ?? { options: configured.options, paths: [] };
|
|
130
|
+
group.paths.push(absolute);
|
|
131
|
+
grouped.set(configured.key, group);
|
|
158
132
|
}
|
|
159
133
|
|
|
160
134
|
for (const [key, { options, paths }] of grouped) {
|
|
@@ -168,25 +142,25 @@ function checkedSourceOf(filePath: string, projectRoot?: string): { source: ts.S
|
|
|
168
142
|
const typescript = getTS();
|
|
169
143
|
const absolute = resolvePath(filePath);
|
|
170
144
|
const configured = compilerProjectOf(absolute, projectRoot);
|
|
171
|
-
let
|
|
145
|
+
let project = typeProjects.get(configured.key);
|
|
172
146
|
|
|
173
|
-
if (!
|
|
147
|
+
if (!project) {
|
|
174
148
|
// `path.resolve` is variadic, so handing it directly to `map` also passed the
|
|
175
149
|
// index and the whole roots array as path segments. A fixture without a warm scan
|
|
176
150
|
// cache exposed that first-run-only failure.
|
|
177
151
|
const roots = new Set(configured.roots.map((root) => resolvePath(root)));
|
|
178
152
|
roots.add(absolute);
|
|
179
153
|
const program = builtProgram(configured.key, [...roots], configured.options);
|
|
180
|
-
|
|
181
|
-
typeProjects.set(configured.key,
|
|
182
|
-
} else if (!
|
|
183
|
-
|
|
184
|
-
|
|
154
|
+
project = { roots, options: configured.options, program };
|
|
155
|
+
typeProjects.set(configured.key, project);
|
|
156
|
+
} else if (!project.roots.has(absolute)) {
|
|
157
|
+
project.roots.add(absolute);
|
|
158
|
+
project.program = builtProgram(configured.key, [...project.roots], project.options);
|
|
185
159
|
}
|
|
186
160
|
|
|
187
|
-
const source =
|
|
161
|
+
const source = project.program.getSourceFile(absolute);
|
|
188
162
|
if (!source) throw new Error(`TypeScript did not include '${absolute}' in its program.`);
|
|
189
|
-
return { source, checker:
|
|
163
|
+
return { source, checker: project.program.getTypeChecker() };
|
|
190
164
|
}
|
|
191
165
|
|
|
192
166
|
/** A file, opened. Five places read and parsed one, each spelling the same two calls. */
|
|
@@ -428,20 +402,7 @@ function resolveSpecifier(specifier: string, fromFile: string, projectRoot: stri
|
|
|
428
402
|
|
|
429
403
|
// ── Mixin / heritage parsing ─────────────────
|
|
430
404
|
|
|
431
|
-
/**
|
|
432
|
-
* The class a returned expression carries, however it is wrapped.
|
|
433
|
-
*
|
|
434
|
-
* A mixin does not always hand its class back bare. `Crud` returns
|
|
435
|
-
* `asCrudConstructor(class CrudHandler { … })` — one assertion helper standing between
|
|
436
|
-
* `return` and the class — and a parser accepting only a bare `return class` found
|
|
437
|
-
* nothing there, silently: the five inherited CRUD ops stopped being derived, and a warm
|
|
438
|
-
* scan cache kept answering the old parse for weeks (`scan-cache.ts` keys on source, not
|
|
439
|
-
* on parser version).
|
|
440
|
-
*
|
|
441
|
-
* So unwrap rather than match one shape: descend through call arguments, `as` and
|
|
442
|
-
* `satisfies` assertions, and parentheses. What is looked for is a class; where the
|
|
443
|
-
* author put it is their business.
|
|
444
|
-
*/
|
|
405
|
+
/** The class a returned expression carries, however it is wrapped. */
|
|
445
406
|
function classInExpression(expr: ts.Node, depth = 0): ts.ClassExpression | undefined {
|
|
446
407
|
const ts = getTS();
|
|
447
408
|
if (depth > 8) return undefined;
|
|
@@ -502,7 +463,7 @@ function extractClassMethods(
|
|
|
502
463
|
// `private`/`protected` is a statement about the surface, and the AST carries it —
|
|
503
464
|
// it was read past. Every helper a handler names by intent (`mustOwn`, `readMany`,
|
|
504
465
|
// `refuse`) became a callable op: measured on the bench, `list.readMany` executed
|
|
505
|
-
// and `list.mayPublish`
|
|
466
|
+
// and `list.mayPublish` validated its argument. A door is what the author declares
|
|
506
467
|
// public, and TypeScript already has the word for it. `#name` is private too, but
|
|
507
468
|
// it is not an identifier, so it never reached here in the first place.
|
|
508
469
|
if (member.modifiers?.some((m) => m.kind === ts.SyntaxKind.PrivateKeyword || m.kind === ts.SyntaxKind.ProtectedKeyword)) continue;
|
|
@@ -521,14 +482,7 @@ function extractClassMethods(
|
|
|
521
482
|
return results;
|
|
522
483
|
}
|
|
523
484
|
|
|
524
|
-
/**
|
|
525
|
-
* The first sentence of a member's doc comment, or nothing.
|
|
526
|
-
*
|
|
527
|
-
* One sentence on purpose: what a caller needs to choose an operation is a claim,
|
|
528
|
-
* not an essay, and the rest of the comment addresses whoever edits the method.
|
|
529
|
-
* Reads the leading trivia rather than `ts.getJSDocTags` — the comment is what the
|
|
530
|
-
* author wrote, tags are a schema they never agreed to.
|
|
531
|
-
*/
|
|
485
|
+
/** The first sentence of a member's doc comment, or nothing. */
|
|
532
486
|
function docSentenceOf(member: ts.Node, source: ts.SourceFile): string | undefined {
|
|
533
487
|
const ts = getTS();
|
|
534
488
|
const ranges = ts.getLeadingCommentRanges(source.text, member.pos) ?? [];
|
|
@@ -551,11 +505,7 @@ function docSentenceOf(member: ts.Node, source: ts.SourceFile): string | undefin
|
|
|
551
505
|
* Parse inherited methods from a class's heritage clause.
|
|
552
506
|
* Handles both `extends Crud(Entity)` (mixin) and `extends BaseClass` patterns.
|
|
553
507
|
*/
|
|
554
|
-
/**
|
|
555
|
-
* Where a name used here is declared. The checker follows the import, the re-export chain
|
|
556
|
-
* and an installed package's types — the three cases three hand-rolled functions treated
|
|
557
|
-
* separately.
|
|
558
|
-
*/
|
|
508
|
+
/** Where a name used here is declared. */
|
|
559
509
|
function declarationFileOf(node: ts.Node, checker: ts.TypeChecker): string | undefined {
|
|
560
510
|
const typescript = getTS();
|
|
561
511
|
let symbol = checker.getSymbolAtLocation(node);
|
|
@@ -564,13 +514,7 @@ function declarationFileOf(node: ts.Node, checker: ts.TypeChecker): string | und
|
|
|
564
514
|
return symbol.declarations?.[0]?.getSourceFile().fileName;
|
|
565
515
|
}
|
|
566
516
|
|
|
567
|
-
/**
|
|
568
|
-
* The methods a base class contributes, read from the INSTANTIATED type.
|
|
569
|
-
*
|
|
570
|
-
* `extends Crud(Post)` gives `create(input: Partial<Post>)` directly: the checker has
|
|
571
|
-
* already substituted the mixin's type parameter. The three functions this replaces
|
|
572
|
-
* detected the generic names and mapped them to the mixin's arguments by position.
|
|
573
|
-
*/
|
|
517
|
+
/** The methods a base class contributes, read from the INSTANTIATED type. */
|
|
574
518
|
function inheritedFromBase(
|
|
575
519
|
base: ts.ExpressionWithTypeArguments,
|
|
576
520
|
checker: ts.TypeChecker,
|
|
@@ -617,10 +561,8 @@ function parseInheritedMethods(
|
|
|
617
561
|
checker: ts.TypeChecker,
|
|
618
562
|
skip: Set<string>,
|
|
619
563
|
/**
|
|
620
|
-
* Base classes this pass could not open — an INSTALLED one, typically, whose
|
|
621
|
-
*
|
|
622
|
-
* method": the two used to be the same answer, so an op inherited from a
|
|
623
|
-
* published base class was absent from the façade without a word.
|
|
564
|
+
* Base classes this pass could not open — an INSTALLED one, typically, whose source is not in
|
|
565
|
+
* the workspace.
|
|
624
566
|
*/
|
|
625
567
|
unresolved: string[],
|
|
626
568
|
): Signature[] {
|
|
@@ -685,14 +627,7 @@ function findDefaultClass(source: ts.SourceFile): ts.ClassDeclaration | undefine
|
|
|
685
627
|
return undefined;
|
|
686
628
|
}
|
|
687
629
|
|
|
688
|
-
/**
|
|
689
|
-
* What a handler file yielded — its methods, AND what the pass could not open.
|
|
690
|
-
*
|
|
691
|
-
* The second half is why this is a pair rather than an array: an unresolvable base
|
|
692
|
-
* class used to give the same answer as a base class with no method, so an op
|
|
693
|
-
* inherited from an installed package was missing from the façade in silence. The
|
|
694
|
-
* pair travels through the scan cache, which is why {@link PARSER_VERSION} moved.
|
|
695
|
-
*/
|
|
630
|
+
/** What a handler file yielded — its methods, AND what the pass could not open. */
|
|
696
631
|
export interface HandlerParse {
|
|
697
632
|
methods: Signature[];
|
|
698
633
|
/** Base classes whose source this pass could not open. Empty is a claim. */
|
|
@@ -708,11 +643,7 @@ export async function parseAllHandlerMethods(filePath: string, projectRoot?: str
|
|
|
708
643
|
return parseClassMethods(filePath, CONSTRUCTOR_ONLY, projectRoot);
|
|
709
644
|
}
|
|
710
645
|
|
|
711
|
-
/**
|
|
712
|
-
* Parse a presenter source file and extract all method signatures.
|
|
713
|
-
*
|
|
714
|
-
* Returns all methods (no CRUD filtering) — each method is a computed field.
|
|
715
|
-
*/
|
|
646
|
+
/** Parse a presenter source file and extract all method signatures. */
|
|
716
647
|
export async function parsePresenterMethods(filePath: string, projectRoot?: string): Promise<Signature[]> {
|
|
717
648
|
await loadTS();
|
|
718
649
|
// No `projectRoot`, so no heritage pass and nothing to report: a presenter's
|
package/src/scan/result.ts
CHANGED
|
@@ -1,24 +1,11 @@
|
|
|
1
1
|
import type { Fronds } from '../descriptor/Fronds.js';
|
|
2
2
|
|
|
3
3
|
/** Result of scanning a project directory. */
|
|
4
|
-
/**
|
|
5
|
-
* Something the scan could NOT do — recorded instead of swallowed.
|
|
6
|
-
*
|
|
7
|
-
* The scan answers with what it found. Until now it answered the same way whether
|
|
8
|
-
* a directory held nothing or could not be read, and whether a handler declared no
|
|
9
|
-
* operation or failed to parse: `catch → empty`. So every downstream reader — the
|
|
10
|
-
* façade, the identity card, anything asking "what does this app serve?" — could
|
|
11
|
-
* not tell **"there is nothing"** from **"I could not look"**.
|
|
12
|
-
*
|
|
13
|
-
* That distinction is what makes a rule about an ABSENCE sound. Without it, a check
|
|
14
|
-
* derived from the scan reports "nothing wrong" precisely when it read nothing.
|
|
15
|
-
*/
|
|
4
|
+
/** Something the scan could NOT do — recorded instead of swallowed. */
|
|
16
5
|
export interface ScanDiagnostic {
|
|
17
6
|
/**
|
|
18
|
-
* `blocking` — the app now serves less than its source declares, and no caller
|
|
19
|
-
*
|
|
20
|
-
* `warning` — something may be missing and the scan cannot decide, e.g. a base
|
|
21
|
-
* class it is not allowed to resolve. Statable in `frond.config.ts`.
|
|
7
|
+
* `blocking` — the app now serves less than its source declares, and no caller can know it: a
|
|
8
|
+
* handler that failed to parse contributes zero operations.
|
|
22
9
|
*/
|
|
23
10
|
severity: 'blocking' | 'warning';
|
|
24
11
|
/** Stable rule name — `handler-parse-failed`, `directory-unreadable`. */
|
package/src/scan/scanner.ts
CHANGED
|
@@ -31,13 +31,7 @@ import {
|
|
|
31
31
|
|
|
32
32
|
// FS
|
|
33
33
|
|
|
34
|
-
/**
|
|
35
|
-
* What this scan run could not do. Reset by {@link scanProject}, which owns a run.
|
|
36
|
-
*
|
|
37
|
-
* Module-scoped like the loader and the cache root above: the scanner already has a
|
|
38
|
-
* notion of "the current run". Three sites record — measured — so a per-run object
|
|
39
|
-
* would carry twenty methods to spare one line of reset.
|
|
40
|
-
*/
|
|
34
|
+
/** What this scan run could not do. */
|
|
41
35
|
let diagnostics: ScanDiagnostic[] = [];
|
|
42
36
|
|
|
43
37
|
function record(d: ScanDiagnostic): void {
|
|
@@ -45,10 +39,8 @@ function record(d: ScanDiagnostic): void {
|
|
|
45
39
|
}
|
|
46
40
|
|
|
47
41
|
/**
|
|
48
|
-
* An absent convention directory is the ordinary case — a frond without
|
|
49
|
-
*
|
|
50
|
-
* that is not a directory) means the scan did not look, and answering `[]` says
|
|
51
|
-
* it did. One `catch` used to conflate the two.
|
|
42
|
+
* An absent convention directory is the ordinary case — a frond without `presenters/` is not a
|
|
43
|
+
* defect.
|
|
52
44
|
*/
|
|
53
45
|
async function readEntries(path: string): Promise<Dirent[]> {
|
|
54
46
|
try {
|
|
@@ -115,13 +107,7 @@ function findWorkspaceRoot(from: string): string {
|
|
|
115
107
|
return resolvePath(from); // fallback: use project root itself
|
|
116
108
|
}
|
|
117
109
|
|
|
118
|
-
/**
|
|
119
|
-
* Strip the 'Handler' suffix → the name the handler answers to. 'PostHandler' → 'post'.
|
|
120
|
-
*
|
|
121
|
-
* Nothing here checks that an entity carries the result, and nothing should: a handler
|
|
122
|
-
* about no stored row is ordinary. The old name of this function — `toEntityName` — is
|
|
123
|
-
* what let "one façade per entity" be repeated until it read as a rule.
|
|
124
|
-
*/
|
|
110
|
+
/** Strip the 'Handler' suffix → the name the handler answers to. */
|
|
125
111
|
function toAddress(className: string): string {
|
|
126
112
|
const base = className.endsWith('Handler') ? className.slice(0, -7) : className;
|
|
127
113
|
return lowerFirst(base);
|
|
@@ -130,18 +116,8 @@ function toAddress(className: string): string {
|
|
|
130
116
|
// Scan
|
|
131
117
|
|
|
132
118
|
/**
|
|
133
|
-
* The container key a constructor parameter asks for — derived from its TYPE, not from
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
* `deps` used to be `p.type.name`, so the key WAS the alias's name: `type ListStorage =
|
|
137
|
-
* Storage<List>` resolved only because someone had spelled it exactly like the
|
|
138
|
-
* registration key (`ListStorage`), while `type ListRepo = Storage<List>` — the same type —
|
|
139
|
-
* typechecked and died at boot on `'ListRepo' is not registered`. And `Storage<List>`
|
|
140
|
-
* written out in full asked for `'Storage'`, which nothing registers.
|
|
141
|
-
*
|
|
142
|
-
* `Storage<X>` names X's storage, so that is the key. The generic argument was already
|
|
143
|
-
* parsed (`TypeRef.generics`) and thrown away. Anything else keeps its own name: a
|
|
144
|
-
* plain service IS designated by its class name.
|
|
119
|
+
* The container key a constructor parameter asks for — derived from its TYPE, not from how the
|
|
120
|
+
* type was spelled.
|
|
145
121
|
*/
|
|
146
122
|
function depKeyOf(type: TypeRef): string {
|
|
147
123
|
// `Facade<PostHandler>` — the second port, read exactly like the first. The type names
|
|
@@ -166,32 +142,25 @@ function depKeyOf(type: TypeRef): string {
|
|
|
166
142
|
// `RepositoryOf<Post>` — what an author writes when no repository file exists. The dual
|
|
167
143
|
// of the line below: one names the port, the other the holder, and both resolve to a key
|
|
168
144
|
// rather than to a class the author would have to invent.
|
|
169
|
-
const
|
|
170
|
-
if (
|
|
145
|
+
const subject = type.name === 'RepositoryOf' ? type.generics?.[0]?.name : undefined;
|
|
146
|
+
if (subject) return repositoryKeyOf(subject);
|
|
171
147
|
|
|
172
|
-
|
|
148
|
+
// The GENERIC names the subject, so a prefix does not change the key — `MeiliStorage<Card>`
|
|
149
|
+
// is `Card`'s storage. A class named `FileStorage` is untouched: it carries no generic.
|
|
150
|
+
const target = type.name.endsWith('Storage') && type.generics?.length === 1
|
|
151
|
+
? type.generics[0]?.name
|
|
152
|
+
: undefined;
|
|
173
153
|
if (!target) return type.name;
|
|
174
154
|
|
|
175
155
|
return storageKeyOf(target);
|
|
176
156
|
}
|
|
177
157
|
|
|
178
|
-
/**
|
|
179
|
-
* `'[Account, Ledger]'` → `['Account', 'Ledger']`.
|
|
180
|
-
*
|
|
181
|
-
* The tuple was chosen over the variadic form the parser reads more cleanly, because the
|
|
182
|
-
* variadic one costs arities-with-defaults and a `never` filter on the TypeScript side
|
|
183
|
-
* while the tuple maps to `[Storage<Account>, Storage<Ledger>]` in one line. The
|
|
184
|
-
* parser does not get to decide alone; this split is what that choice costs.
|
|
185
|
-
*/
|
|
158
|
+
/** `'[Account, Ledger]'` → `['Account', 'Ledger']`. */
|
|
186
159
|
function tupleMembers(raw: string): string[] {
|
|
187
160
|
return raw.replace(/^\[|\]$/g, '').split(',').map((member) => member.trim()).filter(Boolean);
|
|
188
161
|
}
|
|
189
162
|
|
|
190
|
-
/**
|
|
191
|
-
* These readings are semantic: an unchanged file can mean something different after an
|
|
192
|
-
* imported alias changes. The parser's TypeScript Program is the cache for one scan; a
|
|
193
|
-
* cache keyed only by this file's bytes would be unsound.
|
|
194
|
-
*/
|
|
163
|
+
/** These readings are semantic. */
|
|
195
164
|
const ctorParamsOf = (filePath: string) =>
|
|
196
165
|
parseConstructorParams(filePath);
|
|
197
166
|
|
|
@@ -272,12 +241,7 @@ function resolveSchema(type: TypeRef, moduleExports: Record<string, unknown>): S
|
|
|
272
241
|
return undefined;
|
|
273
242
|
}
|
|
274
243
|
|
|
275
|
-
/**
|
|
276
|
-
* Parse ALL method signatures for unified binding.
|
|
277
|
-
*
|
|
278
|
-
* Resolves schemas for all params (not just the first) and stores
|
|
279
|
-
* full signatures for the binding algorithm.
|
|
280
|
-
*/
|
|
244
|
+
/** Parse ALL method signatures for unified binding. */
|
|
281
245
|
async function inferOperations(
|
|
282
246
|
filePath: string,
|
|
283
247
|
handlerName: string,
|
|
@@ -308,15 +272,8 @@ async function inferOperations(
|
|
|
308
272
|
}
|
|
309
273
|
|
|
310
274
|
/**
|
|
311
|
-
* A base class the parse could not open — an installed package, typically, whose
|
|
312
|
-
*
|
|
313
|
-
* the scan cannot tell whether there were any.
|
|
314
|
-
*
|
|
315
|
-
* A warning, not a refusal: an installed base class with no operation is perfectly
|
|
316
|
-
* ordinary, and the boot has no way to decide between the two. So it names the
|
|
317
|
-
* clause and stops there. Stating the contract in `frond.config.ts` is the answer
|
|
318
|
-
* — the third producer, which creates an op neither other producer found — and it
|
|
319
|
-
* silences this by making the op exist.
|
|
275
|
+
* A base class the parse could not open — an installed package, typically, whose source is not
|
|
276
|
+
* in the workspace.
|
|
320
277
|
*/
|
|
321
278
|
for (const base of parsed.unresolvedHeritage) {
|
|
322
279
|
record({
|
|
@@ -342,10 +299,10 @@ async function inferOperations(
|
|
|
342
299
|
// caller supplies through the body are candidates: a schema-typed collector, fact or
|
|
343
300
|
// context parameter is not input merely because it names an entity. The old loop
|
|
344
301
|
// ignored provenance and assigned the first schema it met, so swapping two parameters
|
|
345
|
-
// silently changed the contract the façade used to
|
|
302
|
+
// silently changed the contract the façade used to validate the request body.
|
|
346
303
|
const binding = computeBindingPlan(method.params, collectorTypeNames);
|
|
347
304
|
const candidates = method.params.flatMap((param, index) => {
|
|
348
|
-
if (binding[index]?.source.kind !== '
|
|
305
|
+
if (binding[index]?.source.kind !== 'input') return [];
|
|
349
306
|
const schema = resolveSchema(param.type, moduleExports);
|
|
350
307
|
return schema ? [{ param, schema }] : [];
|
|
351
308
|
});
|
|
@@ -522,13 +479,7 @@ async function scanFrond(frondPath: string, name: string, source: FrondDescripto
|
|
|
522
479
|
entities: entitiesDir, handlers: handlersDir,
|
|
523
480
|
presenters: presentersDir, collectors: collectorsDir, seeds: seedsDir,
|
|
524
481
|
} = conventions.dirs;
|
|
525
|
-
/**
|
|
526
|
-
* A convention directory, read by whoever knows the shape it holds.
|
|
527
|
-
*
|
|
528
|
-
* The same three lines were written six times — list, read in parallel, drop what the
|
|
529
|
-
* reader refused — which is what made `handlers/` quietly special: it grew a second
|
|
530
|
-
* pass for its surfaces and nothing else could.
|
|
531
|
-
*/
|
|
482
|
+
/** A convention directory, read by whoever knows the shape it holds. */
|
|
532
483
|
const collect = async <T extends object>(
|
|
533
484
|
dir: string,
|
|
534
485
|
read: (filePath: string) => Promise<T | null>,
|
|
@@ -615,15 +566,7 @@ async function scanFrond(frondPath: string, name: string, source: FrondDescripto
|
|
|
615
566
|
};
|
|
616
567
|
}
|
|
617
568
|
|
|
618
|
-
/**
|
|
619
|
-
* The frond's name — the directory, unless its `package.json` renames it. One rule for a
|
|
620
|
-
* frond under `fronds/` and for the root frond alike, so the root needs no second spelling.
|
|
621
|
-
*
|
|
622
|
-
* Carrying the convention is what makes a frond; the key never marked anything and
|
|
623
|
-
* nothing read it. It earns its keep as the one thing the directory cannot say: that
|
|
624
|
-
* `fronds/blog-v2/` serves the frond still called `blog` — so a rename on disk does not
|
|
625
|
-
* rename the entity keys, the `@fronds/*` import or a `remotes:` entry.
|
|
626
|
-
*/
|
|
569
|
+
/** The frond's name — the directory, unless its `package.json` renames it. */
|
|
627
570
|
async function frondNameOf(frondPath: string, dirName: string): Promise<string> {
|
|
628
571
|
try {
|
|
629
572
|
const pkg = JSON.parse(await readFile(join(frondPath, 'package.json'), 'utf8')) as {
|
|
@@ -637,15 +580,8 @@ async function frondNameOf(frondPath: string, dirName: string): Promise<string>
|
|
|
637
580
|
}
|
|
638
581
|
|
|
639
582
|
/**
|
|
640
|
-
* A frond is a directory carrying the convention, and the project root is one such
|
|
641
|
-
*
|
|
642
|
-
* anything. `fronds/` is not the definition, it is where the OTHERS live: the root frond
|
|
643
|
-
* stays put when a second domain appears, which is what makes flattening free instead of
|
|
644
|
-
* a deferred move.
|
|
645
|
-
*
|
|
646
|
-
* `entities/` is the test, not "any convention directory". `services/` and `repositories/`
|
|
647
|
-
* are ordinary top-level names in projects that never heard of Fougere, and a domain
|
|
648
|
-
* without a single entity is not a domain.
|
|
583
|
+
* A frond is a directory carrying the convention, and the project root is one such directory — so
|
|
584
|
+
* a single-domain app writes `entities/` next to `app/` and never names anything.
|
|
649
585
|
*/
|
|
650
586
|
async function rootFrondOf(root: string, workspaceRoot: string, conventions: Conventions): Promise<FrondDescriptor | null> {
|
|
651
587
|
if ((await files(join(root, conventions.dirs.entities))).length === 0) return null;
|
|
@@ -653,21 +589,7 @@ async function rootFrondOf(root: string, workspaceRoot: string, conventions: Con
|
|
|
653
589
|
return scanFrond(root, name, { path: root, package: frondPackage(name, conventions) }, conventions, workspaceRoot);
|
|
654
590
|
}
|
|
655
591
|
|
|
656
|
-
/**
|
|
657
|
-
* `@fronds/<name>` → the directory it names, for every frond of a project.
|
|
658
|
-
*
|
|
659
|
-
* The framework states this convention — `FrondSource.package` has always spelled it, and
|
|
660
|
-
* `fougere sync` writes it into a consumer's tsconfig — and until now its own reader could
|
|
661
|
-
* not resolve it. The Nuxt module registered a Vite alias, so a `.vue` page could import
|
|
662
|
-
* `@fronds/blog/entities/Post`, while the SCAN loaded sources through a bare jiti: a frond
|
|
663
|
-
* naming its neighbour got `Cannot find module '@fronds/user/entities/User.js'`. So the one
|
|
664
|
-
* form that survives a split was the one form that did not run.
|
|
665
|
-
*
|
|
666
|
-
* Hand it to the module loader — `createJiti(url, { alias: await frondAliases(root) })` —
|
|
667
|
-
* and the named form resolves everywhere the framework reads. A directory listing and a
|
|
668
|
-
* `package.json` read, no parsing: it is deliberately callable BEFORE the loader exists,
|
|
669
|
-
* which is what makes the chicken-and-egg go away.
|
|
670
|
-
*/
|
|
592
|
+
/** `@fronds/<name>` → the directory it names, for every frond of a project. */
|
|
671
593
|
export async function frondAliases(root: string, conventions: Conventions = DEFAULT_CONVENTIONS): Promise<Record<string, string>> {
|
|
672
594
|
const frondsDir = join(root, conventions.fronds);
|
|
673
595
|
const aliases: Record<string, string> = {};
|
|
@@ -681,17 +603,7 @@ export async function frondAliases(root: string, conventions: Conventions = DEFA
|
|
|
681
603
|
aliases[frondPackage(await frondNameOf(path, dir), conventions)] = resolvePath(path);
|
|
682
604
|
}
|
|
683
605
|
|
|
684
|
-
/**
|
|
685
|
-
* A SYNCED frond answers to the same name.
|
|
686
|
-
*
|
|
687
|
-
* `fougere sync` writes `.fougere/remotes/<name>/` and registers it in `remotes.json`,
|
|
688
|
-
* which the Nuxt module already reads to alias `@fronds/<name>`. Doing it here too is
|
|
689
|
-
* what makes the convention mean ONE thing: a consumer writes `@fronds/blog/entities/Post`
|
|
690
|
-
* and never learns whether that frond is on this disk or was fetched from a card.
|
|
691
|
-
*
|
|
692
|
-
* A local frond wins a name collision — its source is the truth, a synced copy is a
|
|
693
|
-
* mirror of somebody else's.
|
|
694
|
-
*/
|
|
606
|
+
/** A SYNCED frond answers to the same name. */
|
|
695
607
|
try {
|
|
696
608
|
const registry = JSON.parse(
|
|
697
609
|
await readFile(join(root, '.fougere', 'remotes.json'), 'utf8'),
|
|
@@ -757,18 +669,7 @@ export async function scanProject(
|
|
|
757
669
|
return { fronds, diagnostics };
|
|
758
670
|
}
|
|
759
671
|
|
|
760
|
-
/**
|
|
761
|
-
* What changes when a frond's domain changes — the paths a dev loop watches.
|
|
762
|
-
*
|
|
763
|
-
* It lives beside the scan rather than beside the conventions it reads, because it turns
|
|
764
|
-
* names into DISK paths: `join` is `node:path`, and `conventions.ts` is reached from
|
|
765
|
-
* `index` through `frond()`, which an edge bundle imports. Measured — esbuild refused the
|
|
766
|
-
* Worker with `Could not resolve "node:path"`.
|
|
767
|
-
*
|
|
768
|
-
* The root frond IS the scan root, so watching its path would match every write in the
|
|
769
|
-
* project: `.nuxt/`, `node_modules/`, the build output. Its convention directories are
|
|
770
|
-
* the frond, and they are what a scan re-reads.
|
|
771
|
-
*/
|
|
672
|
+
/** What changes when a frond's domain changes — the paths a dev loop watches. */
|
|
772
673
|
export function watchPathsOf(
|
|
773
674
|
frond: { source: { path: string } },
|
|
774
675
|
scanRoot: string,
|