@fougere/core 0.2.0-alpha.1 → 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} +13 -5
- 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} +14 -2
- package/dist/boot/seed.d.ts.map +1 -0
- package/dist/{seed.js → boot/seed.js} +25 -4
- 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 +62 -38
- 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 +38 -8
- 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 -36
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +38 -31
- 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 +123 -12
- 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} +186 -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} +42 -13
- 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 -848
- 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 -78
- package/dist/egress.d.ts.map +0 -1
- package/dist/egress.js +0 -185
- 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/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 -407
- 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,104 @@
|
|
|
1
|
+
import { type EntityConstructor } from '@fougere/schema';
|
|
2
|
+
import type { EntityOrm } from '../orm.js';
|
|
3
|
+
/**
|
|
4
|
+
* Repository(…entities) — who owns an entity's storage, and where its questions are named.
|
|
5
|
+
*
|
|
6
|
+
* **The arity decides**, which is the second reading of what `orm.ts` already states for
|
|
7
|
+
* `EntityOrm` against `Together`: the arity of the unit is the whole distinction.
|
|
8
|
+
*
|
|
9
|
+
* ONE entity — the repository IS that entity's storage, with your methods added. The port's
|
|
10
|
+
* thirteen gestures are forwarded, so a handler reads `this.posts.list()` whether or not
|
|
11
|
+
* anyone wrote the file, and a named question sits beside them:
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* // repositories/PostRepository.ts
|
|
15
|
+
* export default class PostRepository extends Repository(Post) {
|
|
16
|
+
* published() {
|
|
17
|
+
* return this.list({ where: { status: 'published' }, orderBy: 'publishedAt', order: 'desc' });
|
|
18
|
+
* }
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* TWO OR MORE — an aggregate. It owns them: nothing else in the app is handed their
|
|
23
|
+
* storage, and no gesture is forwarded (which entity would `create` write to?), so the only
|
|
24
|
+
* way in is a method this class names. That is what lets a rule spanning two tables exist:
|
|
25
|
+
* it is ordinary TypeScript inside the method that does the writing.
|
|
26
|
+
*
|
|
27
|
+
* ```ts
|
|
28
|
+
* // repositories/CommandeRepository.ts
|
|
29
|
+
* export default class CommandeRepository extends Repository(Commande, Stock) {
|
|
30
|
+
* avecLignes(id: string) {
|
|
31
|
+
* const [commandes, stock] = this.orms;
|
|
32
|
+
* …
|
|
33
|
+
* }
|
|
34
|
+
* }
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* `this.orms` is protected, because the whole point is that the storage stops at this file.
|
|
38
|
+
* `protected` is erased at runtime, like `abstract` on a port: a compile-time guarantee, not
|
|
39
|
+
* a barrier. The same bargain, already accepted.
|
|
40
|
+
*
|
|
41
|
+
* **The boundary is not the unit of work.** An aggregate says the rules of these entities
|
|
42
|
+
* hold together; a frame says these writes land together, and the two lists coincide only
|
|
43
|
+
* often. Deriving the frame from the membership would make a read-only aggregate carry one
|
|
44
|
+
* — refusals included, and `registerFrames` refuses without storage or over `remotes:` —
|
|
45
|
+
* and would put `Together<[Commande, Stock], [StockMirror]>` out of reach forever. So a
|
|
46
|
+
* frame is ASKED FOR here as anywhere else, which is what makes it declared:
|
|
47
|
+
*
|
|
48
|
+
* ```ts
|
|
49
|
+
* constructor(commandes: CommandeOrm, stock: StockOrm, private frame: Together<[Commande, Stock]>) {
|
|
50
|
+
* super(commandes, stock);
|
|
51
|
+
* }
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* The ORM words come back in that line, and only there: this class IS the holder, which is
|
|
55
|
+
* the one case `boot/ownership.ts` lets name the storage it was built on.
|
|
56
|
+
*
|
|
57
|
+
* A repository is NOT a door: it has no façade, so nothing here is reachable from the wire.
|
|
58
|
+
*/
|
|
59
|
+
/**
|
|
60
|
+
* The shape a repository of ONE entity has — the port itself, plus whatever the subclass
|
|
61
|
+
* names on top. Written by an author who has not written the file: `RepositoryOf<Post>` is
|
|
62
|
+
* to `PostRepository` what `EntityOrm<Post>` is to `PostOrm`, one spelling of one key, and
|
|
63
|
+
* `depKeyOf` reads both.
|
|
64
|
+
*/
|
|
65
|
+
export type RepositoryOf<T> = EntityOrm<T>;
|
|
66
|
+
/** The single-entity form: the port, plus whatever the subclass names. */
|
|
67
|
+
export interface RepositoryConstructor<T> {
|
|
68
|
+
new (orm: EntityOrm<T>): EntityOrm<T>;
|
|
69
|
+
readonly __entity: unknown;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* What an aggregate's subclass sees: the storage of the members it owns, in declared order,
|
|
73
|
+
* and `protected` — the storage stops at that file, which is the whole mechanism.
|
|
74
|
+
*
|
|
75
|
+
* A class and not an interface, because `protected` cannot be spelled in one. Ambient: the
|
|
76
|
+
* value it describes is fabricated by `many()` for an arity only known at the call.
|
|
77
|
+
*/
|
|
78
|
+
declare abstract class AggregateShape<E extends readonly EntityConstructor[]> {
|
|
79
|
+
protected orms: {
|
|
80
|
+
[K in keyof E]: EntityOrm<InstanceType<E[K]>>;
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/** The tuple an aggregate holds — the readable form of {@link AggregateShape}'s member. */
|
|
84
|
+
export type AggregateOf<E extends readonly EntityConstructor[]> = {
|
|
85
|
+
[K in keyof E]: EntityOrm<InstanceType<E[K]>>;
|
|
86
|
+
};
|
|
87
|
+
export type AggregateConstructor<E extends readonly EntityConstructor[]> = (new (...orms: unknown[]) => AggregateShape<E>) & {
|
|
88
|
+
readonly __entity: unknown;
|
|
89
|
+
/** The entities this class owns. Present from two on — an owner of one owns nothing. */
|
|
90
|
+
readonly __owns: E;
|
|
91
|
+
};
|
|
92
|
+
export declare function Repository<E extends EntityConstructor>(entity: E): RepositoryConstructor<InstanceType<E>>;
|
|
93
|
+
export declare function Repository<E extends readonly [EntityConstructor, EntityConstructor, ...EntityConstructor[]]>(...entities: E): AggregateConstructor<E>;
|
|
94
|
+
/** Container key of an entity's repository — 'reading' → 'ReadingRepository'. */
|
|
95
|
+
export declare function repositoryKeyOf(entity: string): string;
|
|
96
|
+
/**
|
|
97
|
+
* The entities a class owns — empty for anything that is not an aggregate.
|
|
98
|
+
*
|
|
99
|
+
* Read from the mark rather than from the constructor, for the reason `Crud.__ops` exists:
|
|
100
|
+
* the AST scan is workspace-only, so an installed prefab resolves to nothing.
|
|
101
|
+
*/
|
|
102
|
+
export declare function ownedBy(ctor: unknown): readonly EntityConstructor[];
|
|
103
|
+
export {};
|
|
104
|
+
//# sourceMappingURL=repository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../src/prefab/repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAyC,MAAM,WAAW,CAAC;AAGlF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AAEH;;;;;GAKG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC;AAE3C,0EAA0E;AAC1E,MAAM,WAAW,qBAAqB,CAAC,CAAC;IACtC,KAAK,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;GAMG;AACH,OAAO,CAAC,QAAQ,OAAO,cAAc,CAAC,CAAC,SAAS,SAAS,iBAAiB,EAAE;IAC1E,SAAS,CAAC,IAAI,EAAE;SAAG,CAAC,IAAI,MAAM,CAAC,GAAG,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;KAAE,CAAC;CACnE;AAED,2FAA2F;AAC3F,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,SAAS,iBAAiB,EAAE,IAC5D;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,CAAC;AAEpD,MAAM,MAAM,oBAAoB,CAAC,CAAC,SAAS,SAAS,iBAAiB,EAAE,IACrE,CAAC,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG;IAChD,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,wFAAwF;IACxF,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;CACpB,CAAC;AAEJ,wBAAgB,UAAU,CAAC,CAAC,SAAS,iBAAiB,EAAE,MAAM,EAAE,CAAC,GAAG,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3G,wBAAgB,UAAU,CAAC,CAAC,SAAS,SAAS,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,GAAG,iBAAiB,EAAE,CAAC,EAC1G,GAAG,QAAQ,EAAE,CAAC,GACb,oBAAoB,CAAC,CAAC,CAAC,CAAC;AAwD3B,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,iBAAiB,EAAE,CAEnE"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { classNameOf } from '@fougere/schema';
|
|
2
|
+
export function Repository(...entities) {
|
|
3
|
+
return entities.length === 1 ? one(entities[0]) : many(entities);
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* The port forwarded, member by member. Written out rather than proxied: a Proxy would
|
|
7
|
+
* answer every name including the ones the port does not have, and this file would then
|
|
8
|
+
* state the surface nowhere. Thirteen lines against one declaration that can be read.
|
|
9
|
+
*/
|
|
10
|
+
function one(entity) {
|
|
11
|
+
class RepositoryBase {
|
|
12
|
+
orm;
|
|
13
|
+
static __entity = entity;
|
|
14
|
+
constructor(orm) {
|
|
15
|
+
this.orm = orm;
|
|
16
|
+
}
|
|
17
|
+
list(options) { return this.orm.list(options); }
|
|
18
|
+
findById(id, options) { return this.orm.findById(id, options); }
|
|
19
|
+
findBy(criteria, options) { return this.orm.findBy(criteria, options); }
|
|
20
|
+
findAllBy(criteria, options) { return this.orm.findAllBy(criteria, options); }
|
|
21
|
+
findByKeys(ids, options) { return this.orm.findByKeys(ids, options); }
|
|
22
|
+
findAllByKeys(field, keys, options) { return this.orm.findAllByKeys(field, keys, options); }
|
|
23
|
+
create(input, options) { return this.orm.create(input, options); }
|
|
24
|
+
upsert(input, options) { return this.orm.upsert(input, options); }
|
|
25
|
+
upsertAll(inputs, options) { return this.orm.upsertAll(inputs, options); }
|
|
26
|
+
update(id, input, options) { return this.orm.update(id, input, options); }
|
|
27
|
+
delete(id) { return this.orm.delete(id); }
|
|
28
|
+
output(schema) { return this.orm.output(schema); }
|
|
29
|
+
get client() { return this.orm.client; }
|
|
30
|
+
}
|
|
31
|
+
return RepositoryBase;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The aggregate. Its constructor takes the members' storage in the DECLARED order — the
|
|
35
|
+
* order `toProvider` fills its `deps` with, and the order a subclass hands back to `super()`
|
|
36
|
+
* when it declares a constructor of its own.
|
|
37
|
+
*/
|
|
38
|
+
function many(entities) {
|
|
39
|
+
class AggregateBase {
|
|
40
|
+
static __entity = entities[0];
|
|
41
|
+
static __owns = entities;
|
|
42
|
+
orms;
|
|
43
|
+
constructor(...orms) {
|
|
44
|
+
this.orms = orms.slice(0, entities.length);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return AggregateBase;
|
|
48
|
+
}
|
|
49
|
+
/** Container key of an entity's repository — 'reading' → 'ReadingRepository'. */
|
|
50
|
+
export function repositoryKeyOf(entity) {
|
|
51
|
+
return `${classNameOf(entity)}Repository`;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The entities a class owns — empty for anything that is not an aggregate.
|
|
55
|
+
*
|
|
56
|
+
* Read from the mark rather than from the constructor, for the reason `Crud.__ops` exists:
|
|
57
|
+
* the AST scan is workspace-only, so an installed prefab resolves to nothing.
|
|
58
|
+
*/
|
|
59
|
+
export function ownedBy(ctor) {
|
|
60
|
+
return ctor?.__owns ?? [];
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository.js","sourceRoot":"","sources":["../../src/prefab/repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { SchemaView } from '@fougere/schema';
|
|
2
|
+
import type { EntityEntry, FrondDescriptor } from './frond.js';
|
|
3
|
+
/**
|
|
4
|
+
* What this app hosts — the scan's answer, with the questions everyone was asking it
|
|
5
|
+
* by hand.
|
|
6
|
+
*
|
|
7
|
+
* The list was a bare array, so every reader re-walked it: "which frond owns this
|
|
8
|
+
* entity" was spelled four times, "every entity by name" three times as three literal
|
|
9
|
+
* copies of the same `Map`, and the two inside the boot even carried comments saying so.
|
|
10
|
+
* A concept nobody can question is a concept everyone rebuilds.
|
|
11
|
+
*
|
|
12
|
+
* It IS an array — the same reason `ListResult` is one: twenty call sites iterate,
|
|
13
|
+
* filter and spread it, and none of them is wrong to. `Symbol.species` is `Array` so a
|
|
14
|
+
* `.map()` over it answers a plain array rather than something that claims to be a
|
|
15
|
+
* hosting table and holds strings.
|
|
16
|
+
*/
|
|
17
|
+
export declare class Fronds extends Array<FrondDescriptor> {
|
|
18
|
+
static get [Symbol.species](): ArrayConstructor;
|
|
19
|
+
/** What one scan run found. The only gate in — `Array.of` is taken, and named. */
|
|
20
|
+
static scanned(fronds: readonly FrondDescriptor[]): Fronds;
|
|
21
|
+
/** The frond that hosts an entity — `undefined` when no loaded frond does. */
|
|
22
|
+
owner(entity: string): FrondDescriptor | undefined;
|
|
23
|
+
/** The entity of that name, wherever it was scanned. */
|
|
24
|
+
entity(name: string): EntityEntry | undefined;
|
|
25
|
+
/**
|
|
26
|
+
* Every scanned entity class, by name — across all fronds and never per-frond.
|
|
27
|
+
*
|
|
28
|
+
* A fact is announced in one frond and heard in another, so the subscriber's own
|
|
29
|
+
* frond does not hold the shape it must judge; a `reads:` clause names entities
|
|
30
|
+
* that belong to neighbours by definition.
|
|
31
|
+
*/
|
|
32
|
+
schemas(): Map<string, SchemaView>;
|
|
33
|
+
/** Every scanned entity, sorted. What was FOUND, not what answers. */
|
|
34
|
+
entityNames(): string[];
|
|
35
|
+
/**
|
|
36
|
+
* The names a call may address, sorted — what a NOT_FOUND must print.
|
|
37
|
+
*
|
|
38
|
+
* Not `entityNames()`, which is what the scan found: an entity with no handler is
|
|
39
|
+
* scanned and serves nothing, so the refusal read *"Entity 'indexed' is not hosted
|
|
40
|
+
* here. Hosted here: indexed."* — naming the very thing it had just refused. A façade
|
|
41
|
+
* is keyed on a HANDLER's address, and that is what this lists.
|
|
42
|
+
*/
|
|
43
|
+
servedNames(surface?: string): string[];
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=Fronds.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Fronds.d.ts","sourceRoot":"","sources":["../../src/scan/Fronds.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE/D;;;;;;;;;;;;;GAaG;AACH,qBAAa,MAAO,SAAQ,KAAK,CAAC,eAAe,CAAC;IAChD,WAAoB,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,gBAAgB,CAEvD;IAED,kFAAkF;IAClF,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,GAAG,MAAM;IAM1D,8EAA8E;IAC9E,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAIlD,wDAAwD;IACxD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAQ7C;;;;;;OAMG;IACH,OAAO,IAAI,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC;IAIlC,sEAAsE;IACtE,WAAW,IAAI,MAAM,EAAE;IAIvB;;;;;;;OAOG;IACH,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;CAKxC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What this app hosts — the scan's answer, with the questions everyone was asking it
|
|
3
|
+
* by hand.
|
|
4
|
+
*
|
|
5
|
+
* The list was a bare array, so every reader re-walked it: "which frond owns this
|
|
6
|
+
* entity" was spelled four times, "every entity by name" three times as three literal
|
|
7
|
+
* copies of the same `Map`, and the two inside the boot even carried comments saying so.
|
|
8
|
+
* A concept nobody can question is a concept everyone rebuilds.
|
|
9
|
+
*
|
|
10
|
+
* It IS an array — the same reason `ListResult` is one: twenty call sites iterate,
|
|
11
|
+
* filter and spread it, and none of them is wrong to. `Symbol.species` is `Array` so a
|
|
12
|
+
* `.map()` over it answers a plain array rather than something that claims to be a
|
|
13
|
+
* hosting table and holds strings.
|
|
14
|
+
*/
|
|
15
|
+
export class Fronds extends Array {
|
|
16
|
+
static get [Symbol.species]() {
|
|
17
|
+
return Array;
|
|
18
|
+
}
|
|
19
|
+
/** What one scan run found. The only gate in — `Array.of` is taken, and named. */
|
|
20
|
+
static scanned(fronds) {
|
|
21
|
+
const held = new Fronds();
|
|
22
|
+
held.push(...fronds);
|
|
23
|
+
return held;
|
|
24
|
+
}
|
|
25
|
+
/** The frond that hosts an entity — `undefined` when no loaded frond does. */
|
|
26
|
+
owner(entity) {
|
|
27
|
+
return this.find((frond) => frond.entities.some((e) => e.name === entity));
|
|
28
|
+
}
|
|
29
|
+
/** The entity of that name, wherever it was scanned. */
|
|
30
|
+
entity(name) {
|
|
31
|
+
for (const frond of this) {
|
|
32
|
+
const found = frond.entities.find((e) => e.name === name);
|
|
33
|
+
if (found)
|
|
34
|
+
return found;
|
|
35
|
+
}
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Every scanned entity class, by name — across all fronds and never per-frond.
|
|
40
|
+
*
|
|
41
|
+
* A fact is announced in one frond and heard in another, so the subscriber's own
|
|
42
|
+
* frond does not hold the shape it must judge; a `reads:` clause names entities
|
|
43
|
+
* that belong to neighbours by definition.
|
|
44
|
+
*/
|
|
45
|
+
schemas() {
|
|
46
|
+
return new Map(this.flatMap((frond) => frond.entities.map((e) => [e.name, e.entityClass])));
|
|
47
|
+
}
|
|
48
|
+
/** Every scanned entity, sorted. What was FOUND, not what answers. */
|
|
49
|
+
entityNames() {
|
|
50
|
+
return this.flatMap((frond) => frond.entities.map((e) => e.name)).sort();
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The names a call may address, sorted — what a NOT_FOUND must print.
|
|
54
|
+
*
|
|
55
|
+
* Not `entityNames()`, which is what the scan found: an entity with no handler is
|
|
56
|
+
* scanned and serves nothing, so the refusal read *"Entity 'indexed' is not hosted
|
|
57
|
+
* here. Hosted here: indexed."* — naming the very thing it had just refused. A façade
|
|
58
|
+
* is keyed on a HANDLER's address, and that is what this lists.
|
|
59
|
+
*/
|
|
60
|
+
servedNames(surface) {
|
|
61
|
+
return this.flatMap((frond) => frond.handlers
|
|
62
|
+
.filter((handler) => (handler.surface ?? undefined) === surface)
|
|
63
|
+
.map((handler) => handler.address)).sort();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=Fronds.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Fronds.js","sourceRoot":"","sources":["../../src/scan/Fronds.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,MAAO,SAAQ,KAAsB;IAChD,MAAM,KAAc,CAAC,MAAM,CAAC,OAAO,CAAC;QAClC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,kFAAkF;IAClF,MAAM,CAAC,OAAO,CAAC,MAAkC;QAC/C,MAAM,IAAI,GAAG,IAAI,MAAM,EAAE,CAAC;QAC1B,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,8EAA8E;IAC9E,KAAK,CAAC,MAAc;QAClB,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC;IAC7E,CAAC;IAED,wDAAwD;IACxD,MAAM,CAAC,IAAY;QACjB,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;YACzB,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;YAC1D,IAAI,KAAK;gBAAE,OAAO,KAAK,CAAC;QAC1B,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;;;;OAMG;IACH,OAAO;QACL,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,CAAU,CAAC,CAAC,CAAC,CAAC;IACvG,CAAC;IAED,sEAAsE;IACtE,WAAW;QACT,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3E,CAAC;IAED;;;;;;;OAOG;IACH,WAAW,CAAC,OAAgB;QAC1B,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ;aAC1C,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,IAAI,SAAS,CAAC,KAAK,OAAO,CAAC;aAC/D,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/C,CAAC;CACF"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export interface Conventions {
|
|
2
|
+
/**
|
|
3
|
+
* The scope a frond's package name carries — `@fronds/blog`.
|
|
4
|
+
*
|
|
5
|
+
* A real package name, not only an alias: the CLI writes it as `name` in a scaffolded
|
|
6
|
+
* frond and as a `workspace:*` dependency in the app that consumes it.
|
|
7
|
+
*/
|
|
8
|
+
scope: string;
|
|
9
|
+
/** The directory holding fronds, below the project root. */
|
|
10
|
+
fronds: string;
|
|
11
|
+
/** Directory per role. The role is the key; the name on disk is the value. */
|
|
12
|
+
dirs: {
|
|
13
|
+
entities: string;
|
|
14
|
+
handlers: string;
|
|
15
|
+
services: string;
|
|
16
|
+
repositories: string;
|
|
17
|
+
presenters: string;
|
|
18
|
+
collectors: string;
|
|
19
|
+
seeds: string;
|
|
20
|
+
/** What its shapes used to be — written by `fougere freeze`, replayed by `migrate`. */
|
|
21
|
+
versions: string;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* What a project means when it declares nothing — the convention itself.
|
|
26
|
+
*
|
|
27
|
+
* `@fronds` and not `@frond`: the npm org for the singular belongs to someone else, and a
|
|
28
|
+
* scope is a name that must be ownable.
|
|
29
|
+
*/
|
|
30
|
+
export declare const DEFAULT_CONVENTIONS: Conventions;
|
|
31
|
+
/** What a `fougere.config.ts` may state: only the names that differ. */
|
|
32
|
+
export type ConventionsInput = {
|
|
33
|
+
scope?: string;
|
|
34
|
+
fronds?: string;
|
|
35
|
+
dirs?: Partial<Conventions['dirs']>;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* The convention, with a project's exceptions folded in.
|
|
39
|
+
*
|
|
40
|
+
* Merged one level into `dirs` so renaming one directory does not require restating the
|
|
41
|
+
* other six — the same reading `sources:` and `ports:` get, where only the exception is
|
|
42
|
+
* declared.
|
|
43
|
+
*/
|
|
44
|
+
export declare function resolveConventions(input?: ConventionsInput): Conventions;
|
|
45
|
+
/** The package name a frond answers to. */
|
|
46
|
+
export declare function frondPackage(name: string, conventions: Conventions): string;
|
|
47
|
+
/**
|
|
48
|
+
* Directories whose classes register as providers — two spellings, one behaviour.
|
|
49
|
+
*
|
|
50
|
+
* A project may point both roles at one directory; the scan must then read it once, or
|
|
51
|
+
* every provider would be registered twice.
|
|
52
|
+
*/
|
|
53
|
+
export declare function providerDirsOf(conventions: Conventions): string[];
|
|
54
|
+
/**
|
|
55
|
+
* The frond vocabulary — every directory the scan reads.
|
|
56
|
+
*
|
|
57
|
+
* What a reader needs to bound a frond: the Nuxt module watches these for the root frond
|
|
58
|
+
* (watching the root itself would match every write), and a flat app's tsconfig lists
|
|
59
|
+
* them instead of `["."]`, which would swallow `app/` and `nuxt.config.ts`.
|
|
60
|
+
*/
|
|
61
|
+
export declare function frondDirsOf(conventions: Conventions): string[];
|
|
62
|
+
/**
|
|
63
|
+
* What changes when a frond's domain changes — the paths a dev loop watches.
|
|
64
|
+
*
|
|
65
|
+
* The root frond IS the scan root, so watching its path would match every write in the
|
|
66
|
+
* project: `.nuxt/`, `node_modules/`, the build output. Its convention directories are
|
|
67
|
+
* the frond, and they are what a scan re-reads.
|
|
68
|
+
*/
|
|
69
|
+
export declare function watchPathsOf(frond: {
|
|
70
|
+
source: {
|
|
71
|
+
path: string;
|
|
72
|
+
};
|
|
73
|
+
}, scanRoot: string, conventions: Conventions): string[];
|
|
74
|
+
//# sourceMappingURL=conventions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conventions.d.ts","sourceRoot":"","sources":["../../src/scan/conventions.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,WAAW;IAC1B;;;;;OAKG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,IAAI,EAAE;QACJ,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,uFAAuF;QACvF,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,EAAE,WAajC,CAAC;AAEF,wEAAwE;AACxE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;CACrC,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,EAAE,gBAAgB,GAAG,WAAW,CAMxE;AAED,2CAA2C;AAC3C,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,GAAG,MAAM,CAE3E;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,EAAE,CAEjE;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,EAAE,CAK9D;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE;IAAE,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EACnC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,WAAW,GACvB,MAAM,EAAE,CAIV"}
|
|
@@ -0,0 +1,82 @@
|
|
|
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
|
+
*/
|
|
9
|
+
import { join } from 'node:path';
|
|
10
|
+
/**
|
|
11
|
+
* What a project means when it declares nothing — the convention itself.
|
|
12
|
+
*
|
|
13
|
+
* `@fronds` and not `@frond`: the npm org for the singular belongs to someone else, and a
|
|
14
|
+
* scope is a name that must be ownable.
|
|
15
|
+
*/
|
|
16
|
+
export const DEFAULT_CONVENTIONS = {
|
|
17
|
+
scope: '@fronds',
|
|
18
|
+
fronds: 'fronds',
|
|
19
|
+
dirs: {
|
|
20
|
+
entities: 'entities',
|
|
21
|
+
handlers: 'handlers',
|
|
22
|
+
services: 'services',
|
|
23
|
+
repositories: 'repositories',
|
|
24
|
+
presenters: 'presenters',
|
|
25
|
+
collectors: 'collectors',
|
|
26
|
+
seeds: 'seeds',
|
|
27
|
+
versions: 'versions',
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* The convention, with a project's exceptions folded in.
|
|
32
|
+
*
|
|
33
|
+
* Merged one level into `dirs` so renaming one directory does not require restating the
|
|
34
|
+
* other six — the same reading `sources:` and `ports:` get, where only the exception is
|
|
35
|
+
* declared.
|
|
36
|
+
*/
|
|
37
|
+
export function resolveConventions(input) {
|
|
38
|
+
return {
|
|
39
|
+
scope: input?.scope ?? DEFAULT_CONVENTIONS.scope,
|
|
40
|
+
fronds: input?.fronds ?? DEFAULT_CONVENTIONS.fronds,
|
|
41
|
+
dirs: { ...DEFAULT_CONVENTIONS.dirs, ...input?.dirs },
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/** The package name a frond answers to. */
|
|
45
|
+
export function frondPackage(name, conventions) {
|
|
46
|
+
return `${conventions.scope}/${name}`;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Directories whose classes register as providers — two spellings, one behaviour.
|
|
50
|
+
*
|
|
51
|
+
* A project may point both roles at one directory; the scan must then read it once, or
|
|
52
|
+
* every provider would be registered twice.
|
|
53
|
+
*/
|
|
54
|
+
export function providerDirsOf(conventions) {
|
|
55
|
+
return [...new Set([conventions.dirs.services, conventions.dirs.repositories])];
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The frond vocabulary — every directory the scan reads.
|
|
59
|
+
*
|
|
60
|
+
* What a reader needs to bound a frond: the Nuxt module watches these for the root frond
|
|
61
|
+
* (watching the root itself would match every write), and a flat app's tsconfig lists
|
|
62
|
+
* them instead of `["."]`, which would swallow `app/` and `nuxt.config.ts`.
|
|
63
|
+
*/
|
|
64
|
+
export function frondDirsOf(conventions) {
|
|
65
|
+
const { entities, handlers, presenters, collectors, seeds, versions } = conventions.dirs;
|
|
66
|
+
return [...new Set([
|
|
67
|
+
entities, handlers, presenters, collectors, seeds, versions, ...providerDirsOf(conventions),
|
|
68
|
+
])];
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* What changes when a frond's domain changes — the paths a dev loop watches.
|
|
72
|
+
*
|
|
73
|
+
* The root frond IS the scan root, so watching its path would match every write in the
|
|
74
|
+
* project: `.nuxt/`, `node_modules/`, the build output. Its convention directories are
|
|
75
|
+
* the frond, and they are what a scan re-reads.
|
|
76
|
+
*/
|
|
77
|
+
export function watchPathsOf(frond, scanRoot, conventions) {
|
|
78
|
+
return frond.source.path === scanRoot
|
|
79
|
+
? frondDirsOf(conventions).map((dir) => join(scanRoot, dir))
|
|
80
|
+
: [frond.source.path];
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=conventions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conventions.js","sourceRoot":"","sources":["../../src/scan/conventions.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AA0BjC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAgB;IAC9C,KAAK,EAAE,SAAS;IAChB,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE;QACJ,QAAQ,EAAE,UAAU;QACpB,QAAQ,EAAE,UAAU;QACpB,QAAQ,EAAE,UAAU;QACpB,YAAY,EAAE,cAAc;QAC5B,UAAU,EAAE,YAAY;QACxB,UAAU,EAAE,YAAY;QACxB,KAAK,EAAE,OAAO;QACd,QAAQ,EAAE,UAAU;KACrB;CACF,CAAC;AASF;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAwB;IACzD,OAAO;QACL,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,mBAAmB,CAAC,KAAK;QAChD,MAAM,EAAE,KAAK,EAAE,MAAM,IAAI,mBAAmB,CAAC,MAAM;QACnD,IAAI,EAAE,EAAE,GAAG,mBAAmB,CAAC,IAAI,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE;KACtD,CAAC;AACJ,CAAC;AAED,2CAA2C;AAC3C,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,WAAwB;IACjE,OAAO,GAAG,WAAW,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;AACxC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,WAAwB;IACrD,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AAClF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,WAAwB;IAClD,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC;IACzF,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC;YACjB,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,cAAc,CAAC,WAAW,CAAC;SAC5F,CAAC,CAAC,CAAC;AACN,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAC1B,KAAmC,EACnC,QAAgB,EAChB,WAAwB;IAExB,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ;QACnC,CAAC,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ScanResult } from './frond.js';
|
|
2
|
+
export interface EmitOptions {
|
|
3
|
+
/** Where the generated module will sit. Imports are written relative to it. */
|
|
4
|
+
outFile: string;
|
|
5
|
+
/** How `@fougere/core` is reached from there. Default: the package name. */
|
|
6
|
+
core?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Write a scan down. The result is a TypeScript module whose only imports are the classes
|
|
10
|
+
* the scan found — static, so a bundler traces them — and whose only value is the
|
|
11
|
+
* descriptor `createApp` asks for.
|
|
12
|
+
*/
|
|
13
|
+
export declare function emitScan(result: ScanResult, options: EmitOptions): string;
|
|
14
|
+
//# sourceMappingURL=emit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../../src/scan/emit.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EACV,UAAU,EAEX,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,WAAW;IAC1B,+EAA+E;IAC/E,OAAO,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAwJD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,GAAG,MAAM,CA2CzE"}
|