@fougere/core 0.2.0-alpha.2 → 0.3.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/boot/AppLifecycle.d.ts +18 -0
- package/dist/boot/AppLifecycle.d.ts.map +1 -0
- package/dist/boot/AppLifecycle.js +42 -0
- package/dist/boot/AppLifecycle.js.map +1 -0
- package/dist/boot/Emissions.d.ts +126 -0
- package/dist/boot/Emissions.d.ts.map +1 -0
- package/dist/boot/Emissions.js +233 -0
- package/dist/boot/Emissions.js.map +1 -0
- package/dist/boot/HandlerFacade.d.ts +72 -0
- package/dist/boot/HandlerFacade.d.ts.map +1 -0
- package/dist/boot/HandlerFacade.js +174 -0
- package/dist/boot/HandlerFacade.js.map +1 -0
- package/dist/boot/Lifecycle.d.ts +4 -0
- package/dist/boot/Lifecycle.d.ts.map +1 -0
- package/dist/boot/Lifecycle.js +3 -0
- package/dist/boot/Lifecycle.js.map +1 -0
- package/dist/boot/ambient-port.d.ts +38 -0
- package/dist/boot/ambient-port.d.ts.map +1 -0
- package/dist/boot/ambient-port.js +2 -0
- package/dist/boot/ambient-port.js.map +1 -0
- package/dist/boot/ambient.als.d.ts +3 -0
- package/dist/boot/ambient.als.d.ts.map +1 -0
- package/dist/boot/ambient.als.js +34 -0
- package/dist/boot/ambient.als.js.map +1 -0
- package/dist/boot/ambient.queue.d.ts +10 -0
- package/dist/boot/ambient.queue.d.ts.map +1 -0
- package/dist/boot/ambient.queue.js +60 -0
- package/dist/boot/ambient.queue.js.map +1 -0
- package/dist/boot/apply.d.ts +22 -0
- package/dist/boot/apply.d.ts.map +1 -0
- package/dist/boot/apply.js +48 -0
- package/dist/boot/apply.js.map +1 -0
- package/dist/boot/auth.d.ts +53 -0
- package/dist/boot/auth.d.ts.map +1 -0
- package/dist/boot/auth.js +2 -0
- package/dist/boot/auth.js.map +1 -0
- package/dist/{binding.d.ts → boot/binding.d.ts} +14 -17
- package/dist/boot/binding.d.ts.map +1 -0
- package/dist/{binding.js → boot/binding.js} +19 -10
- package/dist/boot/binding.js.map +1 -0
- package/dist/{boot.d.ts → boot/boot.d.ts} +25 -5
- package/dist/boot/boot.d.ts.map +1 -0
- package/dist/boot/boot.js +70 -0
- package/dist/boot/boot.js.map +1 -0
- package/dist/boot/bootstrap.d.ts.map +1 -0
- package/dist/boot/bootstrap.js +721 -0
- package/dist/boot/bootstrap.js.map +1 -0
- package/dist/boot/egress.d.ts +8 -0
- package/dist/boot/egress.d.ts.map +1 -0
- package/dist/boot/egress.js +11 -0
- package/dist/boot/egress.js.map +1 -0
- package/dist/boot/frame.d.ts +44 -0
- package/dist/boot/frame.d.ts.map +1 -0
- package/dist/boot/frame.js +181 -0
- package/dist/boot/frame.js.map +1 -0
- package/dist/boot/ownership.d.ts +42 -0
- package/dist/boot/ownership.d.ts.map +1 -0
- package/dist/boot/ownership.js +127 -0
- package/dist/boot/ownership.js.map +1 -0
- package/dist/boot/ports.d.ts +17 -0
- package/dist/boot/ports.d.ts.map +1 -0
- package/dist/boot/ports.js +57 -0
- package/dist/boot/ports.js.map +1 -0
- package/dist/{remote.d.ts → boot/remote.d.ts} +11 -3
- package/dist/boot/remote.d.ts.map +1 -0
- package/dist/{remote.js → boot/remote.js} +24 -26
- package/dist/boot/remote.js.map +1 -0
- package/dist/{seed.d.ts → boot/seed.d.ts} +13 -1
- package/dist/boot/seed.d.ts.map +1 -0
- package/dist/{seed.js → boot/seed.js} +24 -3
- package/dist/boot/seed.js.map +1 -0
- package/dist/boot/together.d.ts +26 -0
- package/dist/boot/together.d.ts.map +1 -0
- package/dist/boot/together.js +163 -0
- package/dist/boot/together.js.map +1 -0
- package/dist/boot/types.d.ts +260 -0
- package/dist/boot/types.d.ts.map +1 -0
- package/dist/boot/types.js.map +1 -0
- package/dist/builtins/config.d.ts +9 -0
- package/dist/builtins/config.d.ts.map +1 -1
- package/dist/builtins/config.js +16 -1
- package/dist/builtins/config.js.map +1 -1
- package/dist/builtins/logger.d.ts +37 -4
- package/dist/builtins/logger.d.ts.map +1 -1
- package/dist/builtins/logger.js +66 -7
- package/dist/builtins/logger.js.map +1 -1
- package/dist/config-loader.d.ts +39 -35
- package/dist/config-loader.d.ts.map +1 -1
- package/dist/config-loader.js +15 -54
- package/dist/config-loader.js.map +1 -1
- package/dist/contract/Call.d.ts +10 -0
- package/dist/contract/Call.d.ts.map +1 -0
- package/dist/contract/Call.js +15 -0
- package/dist/contract/Call.js.map +1 -0
- package/dist/contract/Invocation.d.ts +27 -0
- package/dist/contract/Invocation.d.ts.map +1 -0
- package/dist/contract/Invocation.js +59 -0
- package/dist/contract/Invocation.js.map +1 -0
- package/dist/contract/RouteAddress.d.ts +17 -0
- package/dist/contract/RouteAddress.d.ts.map +1 -0
- package/dist/contract/RouteAddress.js +38 -0
- package/dist/contract/RouteAddress.js.map +1 -0
- package/dist/contract.d.ts +25 -19
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +25 -10
- package/dist/contract.js.map +1 -1
- package/dist/crypto/encoding.d.ts +25 -0
- package/dist/crypto/encoding.d.ts.map +1 -0
- package/dist/crypto/encoding.js +58 -0
- package/dist/crypto/encoding.js.map +1 -0
- package/dist/crypto/node.d.ts +4 -0
- package/dist/crypto/node.d.ts.map +1 -0
- package/dist/crypto/node.js +25 -0
- package/dist/crypto/node.js.map +1 -0
- package/dist/crypto/port.d.ts +42 -0
- package/dist/crypto/port.d.ts.map +1 -0
- package/dist/crypto/port.js +19 -0
- package/dist/crypto/port.js.map +1 -0
- package/dist/crypto/webcrypto.d.ts +4 -0
- package/dist/crypto/webcrypto.d.ts.map +1 -0
- package/dist/crypto/webcrypto.js +34 -0
- package/dist/crypto/webcrypto.js.map +1 -0
- package/dist/dispatch/ArgumentResolver.d.ts +10 -0
- package/dist/dispatch/ArgumentResolver.d.ts.map +1 -0
- package/dist/dispatch/ArgumentResolver.js +12 -0
- package/dist/dispatch/ArgumentResolver.js.map +1 -0
- package/dist/dispatch/ArrayResult.d.ts +3 -0
- package/dist/dispatch/ArrayResult.d.ts.map +1 -0
- package/dist/dispatch/ArrayResult.js +11 -0
- package/dist/dispatch/ArrayResult.js.map +1 -0
- package/dist/dispatch/DispatchEvent.d.ts +18 -0
- package/dist/dispatch/DispatchEvent.d.ts.map +1 -0
- package/dist/dispatch/DispatchEvent.js +30 -0
- package/dist/dispatch/DispatchEvent.js.map +1 -0
- package/dist/dispatch/DispatchLifecycle.d.ts +9 -0
- package/dist/dispatch/DispatchLifecycle.d.ts.map +1 -0
- package/dist/dispatch/DispatchLifecycle.js +25 -0
- package/dist/dispatch/DispatchLifecycle.js.map +1 -0
- package/dist/dispatch/DispatchPort.d.ts +6 -0
- package/dist/dispatch/DispatchPort.d.ts.map +1 -0
- package/dist/dispatch/DispatchPort.js +2 -0
- package/dist/dispatch/DispatchPort.js.map +1 -0
- package/dist/dispatch/Dispatcher.d.ts +16 -0
- package/dist/dispatch/Dispatcher.d.ts.map +1 -0
- package/dist/dispatch/Dispatcher.js +44 -0
- package/dist/dispatch/Dispatcher.js.map +1 -0
- package/dist/dispatch/InFlight.d.ts +12 -0
- package/dist/dispatch/InFlight.d.ts.map +1 -0
- package/dist/dispatch/InFlight.js +46 -0
- package/dist/dispatch/InFlight.js.map +1 -0
- package/dist/dispatch/InputValidator.d.ts +7 -0
- package/dist/dispatch/InputValidator.d.ts.map +1 -0
- package/dist/dispatch/InputValidator.js +21 -0
- package/dist/dispatch/InputValidator.js.map +1 -0
- package/dist/dispatch/LocalRoutePolicy.d.ts +11 -0
- package/dist/dispatch/LocalRoutePolicy.d.ts.map +1 -0
- package/dist/dispatch/LocalRoutePolicy.js +32 -0
- package/dist/dispatch/LocalRoutePolicy.js.map +1 -0
- package/dist/dispatch/OperationExecutor.d.ts +25 -0
- package/dist/dispatch/OperationExecutor.d.ts.map +1 -0
- package/dist/dispatch/OperationExecutor.js +32 -0
- package/dist/dispatch/OperationExecutor.js.map +1 -0
- package/dist/dispatch/OperationRoute.d.ts +13 -0
- package/dist/dispatch/OperationRoute.d.ts.map +1 -0
- package/dist/dispatch/OperationRoute.js +15 -0
- package/dist/dispatch/OperationRoute.js.map +1 -0
- package/dist/dispatch/OutputProjector.d.ts +12 -0
- package/dist/dispatch/OutputProjector.d.ts.map +1 -0
- package/dist/dispatch/OutputProjector.js +30 -0
- package/dist/dispatch/OutputProjector.js.map +1 -0
- package/dist/dispatch/OutputView.d.ts +8 -0
- package/dist/dispatch/OutputView.d.ts.map +1 -0
- package/dist/dispatch/OutputView.js +10 -0
- package/dist/dispatch/OutputView.js.map +1 -0
- package/dist/dispatch/PresenterArgumentResolver.d.ts +12 -0
- package/dist/dispatch/PresenterArgumentResolver.d.ts.map +1 -0
- package/dist/dispatch/PresenterArgumentResolver.js +20 -0
- package/dist/dispatch/PresenterArgumentResolver.js.map +1 -0
- package/dist/dispatch/PresenterExecutor.d.ts +11 -0
- package/dist/dispatch/PresenterExecutor.d.ts.map +1 -0
- package/dist/dispatch/PresenterExecutor.js +56 -0
- package/dist/dispatch/PresenterExecutor.js.map +1 -0
- package/dist/dispatch/RemoteRouteResolver.d.ts +13 -0
- package/dist/dispatch/RemoteRouteResolver.d.ts.map +1 -0
- package/dist/dispatch/RemoteRouteResolver.js +18 -0
- package/dist/dispatch/RemoteRouteResolver.js.map +1 -0
- package/dist/dispatch/Route.d.ts +10 -0
- package/dist/dispatch/Route.d.ts.map +1 -0
- package/dist/dispatch/Route.js +2 -0
- package/dist/dispatch/Route.js.map +1 -0
- package/dist/dispatch/RouteNotFoundError.d.ts +10 -0
- package/dist/dispatch/RouteNotFoundError.d.ts.map +1 -0
- package/dist/dispatch/RouteNotFoundError.js +24 -0
- package/dist/dispatch/RouteNotFoundError.js.map +1 -0
- package/dist/dispatch/RoutePolicy.d.ts +8 -0
- package/dist/dispatch/RoutePolicy.d.ts.map +1 -0
- package/dist/dispatch/RoutePolicy.js +2 -0
- package/dist/dispatch/RoutePolicy.js.map +1 -0
- package/dist/dispatch/RouteRegistry.d.ts +18 -0
- package/dist/dispatch/RouteRegistry.d.ts.map +1 -0
- package/dist/dispatch/RouteRegistry.js +62 -0
- package/dist/dispatch/RouteRegistry.js.map +1 -0
- package/dist/dispatch/RouteResolver.d.ts +7 -0
- package/dist/dispatch/RouteResolver.d.ts.map +1 -0
- package/dist/dispatch/RouteResolver.js +2 -0
- package/dist/dispatch/RouteResolver.js.map +1 -0
- package/dist/dispatch/StorageGuard.d.ts +15 -0
- package/dist/dispatch/StorageGuard.d.ts.map +1 -0
- package/dist/dispatch/StorageGuard.js +63 -0
- package/dist/dispatch/StorageGuard.js.map +1 -0
- package/dist/effective-operation.d.ts +90 -0
- package/dist/effective-operation.d.ts.map +1 -0
- package/dist/effective-operation.js +450 -0
- package/dist/effective-operation.js.map +1 -0
- package/dist/emit.js +2 -2
- package/dist/emit.js.map +1 -1
- package/dist/entry/DynamicFacade.d.ts +10 -0
- package/dist/entry/DynamicFacade.d.ts.map +1 -0
- package/dist/entry/DynamicFacade.js +27 -0
- package/dist/entry/DynamicFacade.js.map +1 -0
- package/dist/entry/FacadeEntry.d.ts +11 -0
- package/dist/entry/FacadeEntry.d.ts.map +1 -0
- package/dist/entry/FacadeEntry.js +26 -0
- package/dist/entry/FacadeEntry.js.map +1 -0
- package/dist/entry/TransportEntry.d.ts +13 -0
- package/dist/entry/TransportEntry.d.ts.map +1 -0
- package/dist/entry/TransportEntry.js +24 -0
- package/dist/entry/TransportEntry.js.map +1 -0
- package/dist/frond-config.d.ts +24 -7
- package/dist/frond-config.d.ts.map +1 -1
- package/dist/frond-config.js.map +1 -1
- package/dist/graph.d.ts +1 -1
- package/dist/graph.d.ts.map +1 -1
- package/dist/graph.js +3 -2
- package/dist/graph.js.map +1 -1
- package/dist/identity-keys.d.ts +14 -0
- package/dist/identity-keys.d.ts.map +1 -0
- package/dist/identity-keys.js +37 -0
- package/dist/identity-keys.js.map +1 -0
- package/dist/identity.d.ts +58 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +182 -0
- package/dist/identity.js.map +1 -0
- package/dist/imports.d.ts +1 -1
- package/dist/imports.d.ts.map +1 -1
- package/dist/imports.js +7 -3
- package/dist/imports.js.map +1 -1
- package/dist/index.d.ts +57 -38
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +38 -32
- package/dist/index.js.map +1 -1
- package/dist/loader.d.ts +16 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +25 -0
- package/dist/loader.js.map +1 -0
- package/dist/node.d.ts +21 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +24 -0
- package/dist/node.js.map +1 -0
- package/dist/orm.d.ts +69 -8
- package/dist/orm.d.ts.map +1 -1
- package/dist/orm.js +35 -2
- package/dist/orm.js.map +1 -1
- package/dist/prefab/collector.d.ts +29 -0
- package/dist/prefab/collector.d.ts.map +1 -0
- package/dist/prefab/collector.js +34 -0
- package/dist/prefab/collector.js.map +1 -0
- package/dist/{crud.d.ts → prefab/crud.d.ts} +7 -8
- package/dist/prefab/crud.d.ts.map +1 -0
- package/dist/{crud.js → prefab/crud.js} +39 -5
- package/dist/prefab/crud.js.map +1 -0
- package/dist/prefab/mirror.d.ts +52 -0
- package/dist/prefab/mirror.d.ts.map +1 -0
- package/dist/prefab/mirror.js +66 -0
- package/dist/prefab/mirror.js.map +1 -0
- package/dist/prefab/prefab.d.ts +15 -0
- package/dist/prefab/prefab.d.ts.map +1 -0
- package/dist/prefab/prefab.js +19 -0
- package/dist/prefab/prefab.js.map +1 -0
- package/dist/{presenter.d.ts → prefab/presenter.d.ts} +6 -17
- package/dist/prefab/presenter.d.ts.map +1 -0
- package/dist/{presenter.js → prefab/presenter.js} +5 -23
- package/dist/prefab/presenter.js.map +1 -0
- package/dist/prefab/repository.d.ts +104 -0
- package/dist/prefab/repository.d.ts.map +1 -0
- package/dist/prefab/repository.js +62 -0
- package/dist/prefab/repository.js.map +1 -0
- package/dist/scan/Fronds.d.ts +45 -0
- package/dist/scan/Fronds.d.ts.map +1 -0
- package/dist/scan/Fronds.js +66 -0
- package/dist/scan/Fronds.js.map +1 -0
- package/dist/scan/conventions.d.ts +74 -0
- package/dist/scan/conventions.d.ts.map +1 -0
- package/dist/scan/conventions.js +82 -0
- package/dist/scan/conventions.js.map +1 -0
- package/dist/scan/emit.d.ts +14 -0
- package/dist/scan/emit.d.ts.map +1 -0
- package/dist/scan/emit.js +211 -0
- package/dist/scan/emit.js.map +1 -0
- package/dist/scan/frond.d.ts +224 -0
- package/dist/scan/frond.d.ts.map +1 -0
- package/dist/scan/frond.js +2 -0
- package/dist/scan/frond.js.map +1 -0
- package/dist/{handler-parser.d.ts → scan/handler-parser.d.ts} +18 -9
- package/dist/scan/handler-parser.d.ts.map +1 -0
- package/dist/scan/handler-parser.js +625 -0
- package/dist/scan/handler-parser.js.map +1 -0
- package/dist/scan/scan-cache.d.ts +16 -0
- package/dist/scan/scan-cache.d.ts.map +1 -0
- package/dist/{scan-cache.js → scan/scan-cache.js} +27 -20
- package/dist/scan/scan-cache.js.map +1 -0
- package/dist/scan/scanner.d.ts +20 -0
- package/dist/scan/scanner.d.ts.map +1 -0
- package/dist/{scanner.js → scan/scanner.js} +185 -167
- package/dist/scan/scanner.js.map +1 -0
- package/dist/verify.d.ts +16 -3
- package/dist/verify.d.ts.map +1 -1
- package/dist/verify.js +21 -18
- package/dist/verify.js.map +1 -1
- package/dist/{call.d.ts → wire/call.d.ts} +70 -1
- package/dist/wire/call.d.ts.map +1 -0
- package/dist/{call.js → wire/call.js} +48 -75
- package/dist/wire/call.js.map +1 -0
- package/dist/{middleware.d.ts → wire/errors.d.ts} +18 -19
- package/dist/wire/errors.d.ts.map +1 -0
- package/dist/{middleware.js → wire/errors.js} +26 -14
- package/dist/wire/errors.js.map +1 -0
- package/dist/{errors.d.ts → wire/http-error.d.ts} +5 -6
- package/dist/wire/http-error.d.ts.map +1 -0
- package/dist/{errors.js → wire/http-error.js} +7 -6
- package/dist/wire/http-error.js.map +1 -0
- package/dist/wire/invocation.d.ts +4 -0
- package/dist/wire/invocation.d.ts.map +1 -0
- package/dist/wire/invocation.js +3 -0
- package/dist/wire/invocation.js.map +1 -0
- package/dist/{middleware/logger.d.ts → wire/loggerMiddleware.d.ts} +3 -3
- package/dist/wire/loggerMiddleware.d.ts.map +1 -0
- package/dist/{middleware/logger.js → wire/loggerMiddleware.js} +2 -2
- package/dist/wire/loggerMiddleware.js.map +1 -0
- package/dist/wire/middleware.d.ts +29 -0
- package/dist/wire/middleware.d.ts.map +1 -0
- package/dist/wire/middleware.js +20 -0
- package/dist/wire/middleware.js.map +1 -0
- package/dist/{operation.d.ts → wire/operation.d.ts} +39 -10
- package/dist/wire/operation.d.ts.map +1 -0
- package/dist/wire/operation.js +167 -0
- package/dist/wire/operation.js.map +1 -0
- package/package.json +24 -7
- package/dist/binding.d.ts.map +0 -1
- package/dist/binding.js.map +0 -1
- package/dist/boot.d.ts.map +0 -1
- package/dist/boot.js +0 -53
- package/dist/boot.js.map +0 -1
- package/dist/bootstrap.d.ts.map +0 -1
- package/dist/bootstrap.js +0 -879
- package/dist/bootstrap.js.map +0 -1
- package/dist/call.d.ts.map +0 -1
- package/dist/call.js.map +0 -1
- package/dist/collector.d.ts +0 -28
- package/dist/collector.d.ts.map +0 -1
- package/dist/collector.js +0 -32
- package/dist/collector.js.map +0 -1
- package/dist/crud.d.ts.map +0 -1
- package/dist/crud.js.map +0 -1
- package/dist/egress.d.ts +0 -52
- package/dist/egress.d.ts.map +0 -1
- package/dist/egress.js +0 -186
- package/dist/egress.js.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js.map +0 -1
- package/dist/handler-parser.d.ts.map +0 -1
- package/dist/handler-parser.js +0 -505
- package/dist/handler-parser.js.map +0 -1
- package/dist/invocation.d.ts +0 -20
- package/dist/invocation.d.ts.map +0 -1
- package/dist/invocation.js +0 -15
- package/dist/invocation.js.map +0 -1
- package/dist/middleware/error-handler.d.ts +0 -15
- package/dist/middleware/error-handler.d.ts.map +0 -1
- package/dist/middleware/error-handler.js +0 -29
- package/dist/middleware/error-handler.js.map +0 -1
- package/dist/middleware/logger.d.ts.map +0 -1
- package/dist/middleware/logger.js.map +0 -1
- package/dist/middleware.d.ts.map +0 -1
- package/dist/middleware.js.map +0 -1
- package/dist/mirror.d.ts +0 -93
- package/dist/mirror.d.ts.map +0 -1
- package/dist/mirror.js +0 -96
- package/dist/mirror.js.map +0 -1
- package/dist/operation.d.ts.map +0 -1
- package/dist/operation.js +0 -95
- package/dist/operation.js.map +0 -1
- package/dist/presenter.d.ts.map +0 -1
- package/dist/presenter.js.map +0 -1
- package/dist/remote.d.ts.map +0 -1
- package/dist/remote.js.map +0 -1
- package/dist/repository.d.ts +0 -55
- package/dist/repository.d.ts.map +0 -1
- package/dist/repository.js +0 -26
- package/dist/repository.js.map +0 -1
- package/dist/scan-cache.d.ts +0 -10
- package/dist/scan-cache.d.ts.map +0 -1
- package/dist/scan-cache.js.map +0 -1
- package/dist/scanner.d.ts +0 -34
- package/dist/scanner.d.ts.map +0 -1
- package/dist/scanner.js.map +0 -1
- package/dist/seed.d.ts.map +0 -1
- package/dist/seed.js.map +0 -1
- package/dist/types.d.ts +0 -421
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- /package/dist/{bootstrap.d.ts → boot/bootstrap.d.ts} +0 -0
- /package/dist/{types.js → boot/types.js} +0 -0
package/dist/config-loader.js
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
import { resolve
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
2
|
import { existsSync } from 'node:fs';
|
|
3
|
-
import {
|
|
4
|
-
import { getModuleLoader } from './scanner.js';
|
|
3
|
+
import { getModuleLoader } from './loader.js';
|
|
5
4
|
// ── Loading ──────────────────────────────────────
|
|
6
5
|
const CONFIG_FILES = ['fougere.config.ts', 'fougere.config.js', 'fougere.config.mjs'];
|
|
7
|
-
async function loadConfigFrom(dir) {
|
|
6
|
+
async function loadConfigFrom(dir, fresh) {
|
|
8
7
|
const loader = getModuleLoader();
|
|
9
8
|
for (const file of CONFIG_FILES) {
|
|
10
9
|
const path = resolve(dir, file);
|
|
11
10
|
if (existsSync(path)) {
|
|
12
|
-
|
|
11
|
+
// A module is cached by its specifier, so a second load of an EDITED file hands
|
|
12
|
+
// back what was read the first time — measured, and it made re-reading a config
|
|
13
|
+
// return the config already in force. The loader owns its own cache, so it is the
|
|
14
|
+
// one told; the old module stays in memory, re-reading being for a change.
|
|
15
|
+
const mod = await loader(path, fresh ? { fresh } : undefined);
|
|
13
16
|
return (mod.default ?? mod);
|
|
14
17
|
}
|
|
15
18
|
}
|
|
@@ -17,28 +20,13 @@ async function loadConfigFrom(dir) {
|
|
|
17
20
|
}
|
|
18
21
|
/**
|
|
19
22
|
* Load the root fougere.config.{ts,js,mjs} from the given directory.
|
|
23
|
+
*
|
|
24
|
+
* `fresh` re-reads a file that may have changed since the last load — what a host
|
|
25
|
+
* calls when it decides to reconsider its config, and the only way `applyConfig` has
|
|
26
|
+
* anything new to apply.
|
|
20
27
|
*/
|
|
21
|
-
export async function loadConfig(root) {
|
|
22
|
-
return loadConfigFrom(root);
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Load per-frond config files from each frond's directory.
|
|
26
|
-
*/
|
|
27
|
-
export async function loadFrondConfigs(root, frondsDir = 'fronds') {
|
|
28
|
-
const dir = join(root, frondsDir);
|
|
29
|
-
if (!existsSync(dir))
|
|
30
|
-
return {};
|
|
31
|
-
const entries = await readdir(dir, { withFileTypes: true });
|
|
32
|
-
const configs = {};
|
|
33
|
-
for (const entry of entries) {
|
|
34
|
-
if (!entry.isDirectory())
|
|
35
|
-
continue;
|
|
36
|
-
const frondConfig = await loadConfigFrom(join(dir, entry.name));
|
|
37
|
-
if (Object.keys(frondConfig).length > 0) {
|
|
38
|
-
configs[entry.name] = frondConfig;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return configs;
|
|
28
|
+
export async function loadConfig(root, options) {
|
|
29
|
+
return loadConfigFrom(root, options?.fresh);
|
|
42
30
|
}
|
|
43
31
|
// ── Merging ──────────────────────────────────────
|
|
44
32
|
/**
|
|
@@ -47,31 +35,13 @@ export async function loadFrondConfigs(root, frondsDir = 'fronds') {
|
|
|
47
35
|
* or redirects a frond without erasing the others. Used for workspace→app and
|
|
48
36
|
* for global→CLI alike.
|
|
49
37
|
*/
|
|
50
|
-
|
|
38
|
+
function mergeGlobal(base, override) {
|
|
51
39
|
const merged = { ...base, ...override };
|
|
52
40
|
if (base.remotes || override.remotes) {
|
|
53
41
|
merged.remotes = { ...base.remotes, ...override.remotes };
|
|
54
42
|
}
|
|
55
43
|
return merged;
|
|
56
44
|
}
|
|
57
|
-
/**
|
|
58
|
-
* Merge configs with cascade: global → frond → CLI overrides.
|
|
59
|
-
*
|
|
60
|
-
* Returns a ResolvedConfig with the merged global and per-frond overrides.
|
|
61
|
-
*/
|
|
62
|
-
export function mergeConfig(global, frondConfigs, cliOverrides = {}) {
|
|
63
|
-
return { global: mergeGlobal(global, cliOverrides), fronds: frondConfigs };
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Get the effective config for a specific frond.
|
|
67
|
-
* Cascade: global → frond override.
|
|
68
|
-
*/
|
|
69
|
-
export function configForFrond(resolved, frondName) {
|
|
70
|
-
const frondOverride = resolved.fronds[frondName];
|
|
71
|
-
if (!frondOverride)
|
|
72
|
-
return resolved.global;
|
|
73
|
-
return { ...resolved.global, ...frondOverride };
|
|
74
|
-
}
|
|
75
45
|
/**
|
|
76
46
|
* Load config along the workspace→app frontier. The workspace-root config is
|
|
77
47
|
* the base (canonical topology: `remotes`, shared `db`); the app-root config
|
|
@@ -85,13 +55,4 @@ export async function loadCascadedConfig(workspaceRoot, appRoot) {
|
|
|
85
55
|
return base;
|
|
86
56
|
return mergeGlobal(base, await loadConfig(appRoot));
|
|
87
57
|
}
|
|
88
|
-
/**
|
|
89
|
-
* Load everything: root config + frond configs + merge with CLI overrides.
|
|
90
|
-
*/
|
|
91
|
-
export async function resolveConfig(root, cliOverrides = {}) {
|
|
92
|
-
const global = await loadConfig(root);
|
|
93
|
-
const frondsDir = cliOverrides.frondsDir ?? global.frondsDir ?? 'fronds';
|
|
94
|
-
const frondConfigs = await loadFrondConfigs(root, frondsDir);
|
|
95
|
-
return mergeConfig(global, frondConfigs, cliOverrides);
|
|
96
|
-
}
|
|
97
58
|
//# sourceMappingURL=config-loader.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAIrC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAkF9C,oDAAoD;AAEpD,MAAM,YAAY,GAAG,CAAC,mBAAmB,EAAE,mBAAmB,EAAE,oBAAoB,CAAC,CAAC;AAEtF,KAAK,UAAU,cAAc,CAAC,GAAW,EAAE,KAAe;IACxD,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;IACjC,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAChC,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,gFAAgF;YAChF,gFAAgF;YAChF,kFAAkF;YAClF,2EAA2E;YAC3E,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YAC9D,OAAO,CAAE,GAAmC,CAAC,OAAO,IAAI,GAAG,CAAkB,CAAC;QAChF,CAAC;IACH,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY,EAAE,OAA6B;IAC1E,OAAO,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;AAC9C,CAAC;AAED,oDAAoD;AAEpD;;;;;GAKG;AACH,SAAS,WAAW,CAAC,IAAmB,EAAE,QAAgC;IACxE,MAAM,MAAM,GAAkB,EAAE,GAAG,IAAI,EAAE,GAAG,QAAQ,EAAE,CAAC;IACvD,IAAI,IAAI,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QACrC,MAAM,CAAC,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;IAC5D,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,aAAqB,EAAE,OAAe;IAC7E,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,aAAa,CAAC,CAAC;IAC7C,IAAI,OAAO,CAAC,aAAa,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7D,OAAO,WAAW,CAAC,IAAI,EAAE,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Invocation, type InvocationInput } from './Invocation.js';
|
|
2
|
+
import type { RouteAddress } from './RouteAddress.js';
|
|
3
|
+
/** One normalized request: where it goes and what the caller supplied. */
|
|
4
|
+
export declare class Call {
|
|
5
|
+
readonly address: RouteAddress;
|
|
6
|
+
readonly invocation: Invocation;
|
|
7
|
+
constructor(address: RouteAddress, invocation?: InvocationInput);
|
|
8
|
+
withInvocation(invocation: Invocation): Call;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=Call.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Call.d.ts","sourceRoot":"","sources":["../../src/contract/Call.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,0EAA0E;AAC1E,qBAAa,IAAI;IACf,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;gBAEpB,OAAO,EAAE,YAAY,EAAE,UAAU,CAAC,EAAE,eAAe;IAM/D,cAAc,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI;CAG7C"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Invocation } from './Invocation.js';
|
|
2
|
+
/** One normalized request: where it goes and what the caller supplied. */
|
|
3
|
+
export class Call {
|
|
4
|
+
address;
|
|
5
|
+
invocation;
|
|
6
|
+
constructor(address, invocation) {
|
|
7
|
+
this.address = address;
|
|
8
|
+
this.invocation = Invocation.from(invocation);
|
|
9
|
+
Object.freeze(this);
|
|
10
|
+
}
|
|
11
|
+
withInvocation(invocation) {
|
|
12
|
+
return new Call(this.address, invocation);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=Call.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Call.js","sourceRoot":"","sources":["../../src/contract/Call.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAwB,MAAM,iBAAiB,CAAC;AAGnE,0EAA0E;AAC1E,MAAM,OAAO,IAAI;IACN,OAAO,CAAe;IACtB,UAAU,CAAa;IAEhC,YAAY,OAAqB,EAAE,UAA4B;QAC7D,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IAED,cAAc,CAAC,UAAsB;QACnC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAC5C,CAAC;CACF"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface InvocationContext {
|
|
2
|
+
params: Record<string, unknown>;
|
|
3
|
+
query: Record<string, unknown>;
|
|
4
|
+
body: unknown;
|
|
5
|
+
state: Record<string, unknown>;
|
|
6
|
+
trace?: string;
|
|
7
|
+
identity?: string;
|
|
8
|
+
caller?: string;
|
|
9
|
+
}
|
|
10
|
+
export type InvocationInput = Partial<InvocationContext>;
|
|
11
|
+
/** Canonical invocation shared by every entry and transport. */
|
|
12
|
+
export declare class Invocation implements InvocationContext {
|
|
13
|
+
readonly params: Record<string, unknown>;
|
|
14
|
+
readonly query: Record<string, unknown>;
|
|
15
|
+
readonly body: unknown;
|
|
16
|
+
readonly state: Record<string, unknown>;
|
|
17
|
+
readonly trace?: string;
|
|
18
|
+
readonly identity?: string;
|
|
19
|
+
readonly caller?: string;
|
|
20
|
+
private constructor();
|
|
21
|
+
static from(input?: InvocationInput): Invocation;
|
|
22
|
+
withBody(body: unknown): Invocation;
|
|
23
|
+
withState(state: Record<string, unknown>): Invocation;
|
|
24
|
+
}
|
|
25
|
+
export declare const EMPTY_INVOCATION: Invocation;
|
|
26
|
+
export declare function canonicalInvocation(input?: InvocationInput): Invocation;
|
|
27
|
+
//# sourceMappingURL=Invocation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Invocation.d.ts","sourceRoot":"","sources":["../../src/contract/Invocation.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAqBzD,gEAAgE;AAChE,qBAAa,UAAW,YAAW,iBAAiB;IAClD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAEzB,OAAO;IAaP,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,eAAe,GAAG,UAAU;IAIhD,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,UAAU;IAInC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,UAAU;CAGtD;AAED,eAAO,MAAM,gBAAgB,YAAoB,CAAC;AAElD,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE,eAAe,GAAG,UAAU,CAEvE"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
function canonicalValue(value) {
|
|
2
|
+
if (value === null || value === undefined || typeof value !== 'object')
|
|
3
|
+
return value;
|
|
4
|
+
if (Array.isArray(value))
|
|
5
|
+
return Object.freeze(value.map(canonicalValue));
|
|
6
|
+
const prototype = Object.getPrototypeOf(value);
|
|
7
|
+
if (prototype !== Object.prototype && prototype !== null)
|
|
8
|
+
return value;
|
|
9
|
+
return canonicalRecord(value);
|
|
10
|
+
}
|
|
11
|
+
function canonicalRecord(value) {
|
|
12
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
13
|
+
return Object.freeze({});
|
|
14
|
+
const result = {};
|
|
15
|
+
for (const [key, member] of Object.entries(value)) {
|
|
16
|
+
if (member !== undefined)
|
|
17
|
+
result[key] = canonicalValue(member);
|
|
18
|
+
}
|
|
19
|
+
return Object.freeze(result);
|
|
20
|
+
}
|
|
21
|
+
/** Canonical invocation shared by every entry and transport. */
|
|
22
|
+
export class Invocation {
|
|
23
|
+
params;
|
|
24
|
+
query;
|
|
25
|
+
body;
|
|
26
|
+
state;
|
|
27
|
+
trace;
|
|
28
|
+
identity;
|
|
29
|
+
caller;
|
|
30
|
+
constructor(input) {
|
|
31
|
+
this.params = canonicalRecord(input.params);
|
|
32
|
+
this.query = canonicalRecord(input.query);
|
|
33
|
+
this.body = canonicalValue(input.body);
|
|
34
|
+
// State is host-owned and may still be enriched by existing middlewares. Moving it
|
|
35
|
+
// to immutable lifecycle context is a separate migration.
|
|
36
|
+
this.state = input.state ?? {};
|
|
37
|
+
if (input.trace !== undefined)
|
|
38
|
+
this.trace = input.trace;
|
|
39
|
+
if (input.identity !== undefined)
|
|
40
|
+
this.identity = input.identity;
|
|
41
|
+
if (input.caller !== undefined)
|
|
42
|
+
this.caller = input.caller;
|
|
43
|
+
Object.freeze(this);
|
|
44
|
+
}
|
|
45
|
+
static from(input) {
|
|
46
|
+
return input instanceof Invocation ? input : new Invocation(input ?? {});
|
|
47
|
+
}
|
|
48
|
+
withBody(body) {
|
|
49
|
+
return new Invocation({ ...this, body });
|
|
50
|
+
}
|
|
51
|
+
withState(state) {
|
|
52
|
+
return new Invocation({ ...this, state });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export const EMPTY_INVOCATION = Invocation.from();
|
|
56
|
+
export function canonicalInvocation(input) {
|
|
57
|
+
return Invocation.from(input);
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=Invocation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Invocation.js","sourceRoot":"","sources":["../../src/contract/Invocation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface RouteAddressInput {
|
|
2
|
+
entity: string;
|
|
3
|
+
operation: string;
|
|
4
|
+
surface?: string;
|
|
5
|
+
}
|
|
6
|
+
/** Canonical identity of one callable operation. */
|
|
7
|
+
export declare class RouteAddress {
|
|
8
|
+
readonly entity: string;
|
|
9
|
+
readonly operation: string;
|
|
10
|
+
readonly surface?: string;
|
|
11
|
+
constructor(input: RouteAddressInput);
|
|
12
|
+
key(): string;
|
|
13
|
+
equals(other: RouteAddress): boolean;
|
|
14
|
+
toString(): string;
|
|
15
|
+
toJSON(): RouteAddressInput;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=RouteAddress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RouteAddress.d.ts","sourceRoot":"","sources":["../../src/contract/RouteAddress.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAWD,oDAAoD;AACpD,qBAAa,YAAY;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;gBAEd,KAAK,EAAE,iBAAiB;IAOpC,GAAG,IAAI,MAAM;IAIb,MAAM,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO;IAIpC,QAAQ,IAAI,MAAM;IAKlB,MAAM,IAAI,iBAAiB;CAO5B"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
function required(value, name) {
|
|
2
|
+
if (value.trim().length === 0)
|
|
3
|
+
throw new TypeError(`Route ${name} cannot be empty`);
|
|
4
|
+
return value;
|
|
5
|
+
}
|
|
6
|
+
function optional(value, name) {
|
|
7
|
+
return value === undefined ? undefined : required(value, name);
|
|
8
|
+
}
|
|
9
|
+
/** Canonical identity of one callable operation. */
|
|
10
|
+
export class RouteAddress {
|
|
11
|
+
entity;
|
|
12
|
+
operation;
|
|
13
|
+
surface;
|
|
14
|
+
constructor(input) {
|
|
15
|
+
this.entity = required(input.entity, 'entity');
|
|
16
|
+
this.operation = required(input.operation, 'operation');
|
|
17
|
+
this.surface = optional(input.surface, 'surface');
|
|
18
|
+
Object.freeze(this);
|
|
19
|
+
}
|
|
20
|
+
key() {
|
|
21
|
+
return JSON.stringify([this.surface ?? null, this.entity, this.operation]);
|
|
22
|
+
}
|
|
23
|
+
equals(other) {
|
|
24
|
+
return this.key() === other.key();
|
|
25
|
+
}
|
|
26
|
+
toString() {
|
|
27
|
+
const audience = this.surface ? `${this.surface}/` : '';
|
|
28
|
+
return `${audience}${this.entity}.${this.operation}`;
|
|
29
|
+
}
|
|
30
|
+
toJSON() {
|
|
31
|
+
return {
|
|
32
|
+
entity: this.entity,
|
|
33
|
+
operation: this.operation,
|
|
34
|
+
...(this.surface !== undefined ? { surface: this.surface } : {}),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=RouteAddress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RouteAddress.js","sourceRoot":"","sources":["../../src/contract/RouteAddress.ts"],"names":[],"mappings":"AAMA,SAAS,QAAQ,CAAC,KAAa,EAAE,IAAY;IAC3C,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,SAAS,IAAI,kBAAkB,CAAC,CAAC;IACpF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,QAAQ,CAAC,KAAyB,EAAE,IAAY;IACvD,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AACjE,CAAC;AAED,oDAAoD;AACpD,MAAM,OAAO,YAAY;IACd,MAAM,CAAS;IACf,SAAS,CAAS;IAClB,OAAO,CAAU;IAE1B,YAAY,KAAwB;QAClC,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC/C,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QACxD,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IAED,GAAG;QACD,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IAC7E,CAAC;IAED,MAAM,CAAC,KAAmB;QACxB,OAAO,IAAI,CAAC,GAAG,EAAE,KAAK,KAAK,CAAC,GAAG,EAAE,CAAC;IACpC,CAAC;IAED,QAAQ;QACN,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACxD,OAAO,GAAG,QAAQ,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;IACvD,CAAC;IAED,MAAM;QACJ,OAAO;YACL,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACjE,CAAC;IACJ,CAAC;CACF"}
|
package/dist/contract.d.ts
CHANGED
|
@@ -1,19 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
export {
|
|
13
|
-
export type {
|
|
14
|
-
export { EMPTY_INVOCATION } from './invocation.js';
|
|
15
|
-
export type { InvocationContext } from './invocation.js';
|
|
16
|
-
export type { FrondCall, Transport } from './call.js';
|
|
1
|
+
import { type InvocationContext } from './wire/invocation.js';
|
|
2
|
+
import type { FrondCall } from './wire/call.js';
|
|
3
|
+
export { FougereError, ErrorCode, validationErrorsOf } from './wire/errors.js';
|
|
4
|
+
export { toPublicError } from './wire/http-error.js';
|
|
5
|
+
export type { FougereErrorOptions } from './wire/errors.js';
|
|
6
|
+
export { canonicalInvocation, EMPTY_INVOCATION } from './wire/invocation.js';
|
|
7
|
+
export type { InvocationContext } from './wire/invocation.js';
|
|
8
|
+
export { Invocation } from './contract/Invocation.js';
|
|
9
|
+
export type { InvocationInput } from './contract/Invocation.js';
|
|
10
|
+
export { Call } from './contract/Call.js';
|
|
11
|
+
export { RouteAddress } from './contract/RouteAddress.js';
|
|
12
|
+
export type { RouteAddressInput } from './contract/RouteAddress.js';
|
|
13
|
+
export type { FrondCall, Transport, SignedCall } from './wire/call.js';
|
|
17
14
|
/**
|
|
18
15
|
* What `rpc.discover` answers. It belongs here and not to the runtime: the
|
|
19
16
|
* reserved op travels on the same wire as every other call, so a consumer that
|
|
@@ -23,9 +20,18 @@ export type { FrondCall, Transport } from './call.js';
|
|
|
23
20
|
* Stated once, on purpose: two private copies of this interface have already gone
|
|
24
21
|
* stale (the CLI's, then the Rust demo's) the day an op stopped being a bare name.
|
|
25
22
|
*/
|
|
26
|
-
export type { IdentityCard, CardOp } from './call.js';
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
export type { IdentityCard, CardOp, TopologyReport, FrondPlacement, Edge } from './wire/call.js';
|
|
24
|
+
export { assertIdentityCard } from './wire/call.js';
|
|
25
|
+
/**
|
|
26
|
+
* The key a class name is filed under — 'Post' → 'post'. Re-exported rather than
|
|
27
|
+
* respelled: a card writes it and a foreign key derives from it, so the convention
|
|
28
|
+
* belongs to the schema, and a second copy here is a second opinion. It travels
|
|
29
|
+
* through this subpath because a consumer of the wire (a browser bundle) may hold no
|
|
30
|
+
* schema dependency of its own — that audience only. Inside the package it is read from
|
|
31
|
+
* `@fougere/schema` directly: routing four modules through here bought nothing and put
|
|
32
|
+
* this file inside a cycle.
|
|
33
|
+
*/
|
|
34
|
+
export { registrationKeyOf } from '@fougere/schema';
|
|
29
35
|
/** A call, fully fabricated: the designation and its completed invocation. */
|
|
30
36
|
export interface CallValue {
|
|
31
37
|
call: FrondCall;
|
package/dist/contract.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAWA,OAAO,EAAuB,KAAK,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACnF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAG/E,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7E,YAAY,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,YAAY,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,YAAY,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACpE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEvE;;;;;;;;GAQG;AACH,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACjG,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEpD;;;;;;;;GAQG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,8EAA8E;AAC9E,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,UAAU,EAAE,iBAAiB,CAAC;CAC/B;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,EACpC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,EAC/C,KAAK,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,GACjC,SAAS,CAMX"}
|
package/dist/contract.js
CHANGED
|
@@ -5,15 +5,30 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Browser-safe by design: no node builtin may enter this module's import
|
|
7
7
|
* graph. Published as the `@fougere/core/contract` subpath so client
|
|
8
|
-
* bundles never touch the full index (scanner, config loader).
|
|
8
|
+
* bundles never touch the full index (scanner, config loader). `@fougere/schema`
|
|
9
|
+
* is allowed in — measured, it imports no node builtin either.
|
|
9
10
|
*/
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
export {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
11
|
+
import { registrationKeyOf } from '@fougere/schema';
|
|
12
|
+
import { canonicalInvocation } from './wire/invocation.js';
|
|
13
|
+
export { FougereError, ErrorCode, validationErrorsOf } from './wire/errors.js';
|
|
14
|
+
// A receiver turns a refusal into what may cross a process boundary, and it is not
|
|
15
|
+
// core's boot — reaching it through the main entry dragged the scanner into a bundle.
|
|
16
|
+
export { toPublicError } from './wire/http-error.js';
|
|
17
|
+
export { canonicalInvocation, EMPTY_INVOCATION } from './wire/invocation.js';
|
|
18
|
+
export { Invocation } from './contract/Invocation.js';
|
|
19
|
+
export { Call } from './contract/Call.js';
|
|
20
|
+
export { RouteAddress } from './contract/RouteAddress.js';
|
|
21
|
+
export { assertIdentityCard } from './wire/call.js';
|
|
22
|
+
/**
|
|
23
|
+
* The key a class name is filed under — 'Post' → 'post'. Re-exported rather than
|
|
24
|
+
* respelled: a card writes it and a foreign key derives from it, so the convention
|
|
25
|
+
* belongs to the schema, and a second copy here is a second opinion. It travels
|
|
26
|
+
* through this subpath because a consumer of the wire (a browser bundle) may hold no
|
|
27
|
+
* schema dependency of its own — that audience only. Inside the package it is read from
|
|
28
|
+
* `@fougere/schema` directly: routing four modules through here bought nothing and put
|
|
29
|
+
* this file inside a cycle.
|
|
30
|
+
*/
|
|
31
|
+
export { registrationKeyOf } from '@fougere/schema';
|
|
17
32
|
/**
|
|
18
33
|
* Fabricate the call value — one designation, two spellings:
|
|
19
34
|
* `callValueOf(Post, 'list', { query })` (class + verb) or
|
|
@@ -22,8 +37,8 @@ export function toRegistrationName(name) {
|
|
|
22
37
|
*/
|
|
23
38
|
export function callValueOf(target, opOrInput, input) {
|
|
24
39
|
const [call, given] = typeof opOrInput === 'string'
|
|
25
|
-
? [{ entity:
|
|
40
|
+
? [{ entity: registrationKeyOf(target.name), op: opOrInput }, input]
|
|
26
41
|
: [target, opOrInput];
|
|
27
|
-
return { call, invocation:
|
|
42
|
+
return { call, invocation: canonicalInvocation(given) };
|
|
28
43
|
}
|
|
29
44
|
//# sourceMappingURL=contract.js.map
|
package/dist/contract.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAA0B,MAAM,sBAAsB,CAAC;AAGnF,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC/E,mFAAmF;AACnF,sFAAsF;AACtF,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7E,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAc1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEpD;;;;;;;;GAQG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAQpD;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CACzB,MAAoC,EACpC,SAA+C,EAC/C,KAAkC;IAElC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GACjB,OAAO,SAAS,KAAK,QAAQ;QAC3B,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,iBAAiB,CAAE,MAA2B,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,KAAK,CAAC;QAC1F,CAAC,CAAC,CAAC,MAAmB,EAAE,SAAS,CAAC,CAAC;IACvC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC;AAC1D,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What both realizations spell identically — bytes in, bytes out, no platform.
|
|
3
|
+
*
|
|
4
|
+
* `Buffer` did all of this and does not exist on a Worker; `atob`/`btoa` exist on both.
|
|
5
|
+
* Nothing here is a policy decision, which is why it sits beside the port rather than
|
|
6
|
+
* inside either half: two copies of a base64url would be two chances to disagree on the
|
|
7
|
+
* padding, and the disagreement would show up as a bad signature.
|
|
8
|
+
*/
|
|
9
|
+
export declare const bytesOf: (text: string) => Uint8Array;
|
|
10
|
+
export declare const textOf: (bytes: Uint8Array) => string;
|
|
11
|
+
/** Base64url, unpadded — what JWS puts between the dots. */
|
|
12
|
+
export declare function b64url(input: Uint8Array | string): string;
|
|
13
|
+
export declare function unb64url(input: string): Uint8Array;
|
|
14
|
+
/** Plain base64, padded — what an environment variable carries a PEM as. */
|
|
15
|
+
export declare function b64(input: Uint8Array | string): string;
|
|
16
|
+
export declare const unb64: (input: string) => Uint8Array;
|
|
17
|
+
/**
|
|
18
|
+
* The DER a PEM wraps. WebCrypto imports DER and knows nothing about the armour.
|
|
19
|
+
*
|
|
20
|
+
* The label is not checked: a caller asking for a private key and handed a public one
|
|
21
|
+
* fails at `importKey` with a message about the key, which is the truer error than one
|
|
22
|
+
* about a header line.
|
|
23
|
+
*/
|
|
24
|
+
export declare function derOf(pem: string): Uint8Array;
|
|
25
|
+
//# sourceMappingURL=encoding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encoding.d.ts","sourceRoot":"","sources":["../../src/crypto/encoding.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,eAAO,MAAM,OAAO,GAAI,MAAM,MAAM,KAAG,UAAkC,CAAC;AAC1E,eAAO,MAAM,MAAM,GAAI,OAAO,UAAU,KAAG,MAA+B,CAAC;AAE3E,4DAA4D;AAC5D,wBAAgB,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,CAOzD;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAKlD;AAED,4EAA4E;AAC5E,wBAAgB,GAAG,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,CAKtD;AAED,eAAO,MAAM,KAAK,GAAI,OAAO,MAAM,KAAG,UAKrC,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAI7C"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What both realizations spell identically — bytes in, bytes out, no platform.
|
|
3
|
+
*
|
|
4
|
+
* `Buffer` did all of this and does not exist on a Worker; `atob`/`btoa` exist on both.
|
|
5
|
+
* Nothing here is a policy decision, which is why it sits beside the port rather than
|
|
6
|
+
* inside either half: two copies of a base64url would be two chances to disagree on the
|
|
7
|
+
* padding, and the disagreement would show up as a bad signature.
|
|
8
|
+
*/
|
|
9
|
+
const encoder = new TextEncoder();
|
|
10
|
+
const decoder = new TextDecoder();
|
|
11
|
+
export const bytesOf = (text) => encoder.encode(text);
|
|
12
|
+
export const textOf = (bytes) => decoder.decode(bytes);
|
|
13
|
+
/** Base64url, unpadded — what JWS puts between the dots. */
|
|
14
|
+
export function b64url(input) {
|
|
15
|
+
const bytes = typeof input === 'string' ? bytesOf(input) : input;
|
|
16
|
+
let binary = '';
|
|
17
|
+
// One character at a time: `String.fromCharCode(...bytes)` overflows the argument
|
|
18
|
+
// limit on a key, and a signature is small enough that the loop costs nothing.
|
|
19
|
+
for (const byte of bytes)
|
|
20
|
+
binary += String.fromCharCode(byte);
|
|
21
|
+
return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
22
|
+
}
|
|
23
|
+
export function unb64url(input) {
|
|
24
|
+
const binary = atob(input.replace(/-/g, '+').replace(/_/g, '/'));
|
|
25
|
+
const bytes = new Uint8Array(binary.length);
|
|
26
|
+
for (let i = 0; i < binary.length; i += 1)
|
|
27
|
+
bytes[i] = binary.charCodeAt(i);
|
|
28
|
+
return bytes;
|
|
29
|
+
}
|
|
30
|
+
/** Plain base64, padded — what an environment variable carries a PEM as. */
|
|
31
|
+
export function b64(input) {
|
|
32
|
+
const bytes = typeof input === 'string' ? bytesOf(input) : input;
|
|
33
|
+
let binary = '';
|
|
34
|
+
for (const byte of bytes)
|
|
35
|
+
binary += String.fromCharCode(byte);
|
|
36
|
+
return btoa(binary);
|
|
37
|
+
}
|
|
38
|
+
export const unb64 = (input) => {
|
|
39
|
+
const binary = atob(input);
|
|
40
|
+
const bytes = new Uint8Array(binary.length);
|
|
41
|
+
for (let i = 0; i < binary.length; i += 1)
|
|
42
|
+
bytes[i] = binary.charCodeAt(i);
|
|
43
|
+
return bytes;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* The DER a PEM wraps. WebCrypto imports DER and knows nothing about the armour.
|
|
47
|
+
*
|
|
48
|
+
* The label is not checked: a caller asking for a private key and handed a public one
|
|
49
|
+
* fails at `importKey` with a message about the key, which is the truer error than one
|
|
50
|
+
* about a header line.
|
|
51
|
+
*/
|
|
52
|
+
export function derOf(pem) {
|
|
53
|
+
const body = pem.replace(/-----(BEGIN|END)[^-]+-----/g, '').replace(/\s+/g, '');
|
|
54
|
+
if (body.length === 0)
|
|
55
|
+
throw new Error('Not a PEM: no base64 body between the armour');
|
|
56
|
+
return unb64(body);
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=encoding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encoding.js","sourceRoot":"","sources":["../../src/crypto/encoding.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/crypto/node.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEzE,eAAO,MAAM,MAAM,EAAE,UAiBpB,CAAC;AAEF,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ed25519 through `node:crypto` — the default realization, and the fast one.
|
|
3
|
+
*
|
|
4
|
+
* `sign`/`verify` are synchronous here and stay synchronous: the promise is put around
|
|
5
|
+
* the answer, never around the work. That is the whole reason this file exists rather
|
|
6
|
+
* than everyone sharing the WebCrypto half.
|
|
7
|
+
*/
|
|
8
|
+
import { createHash, createPrivateKey, createPublicKey, sign, verify } from 'node:crypto';
|
|
9
|
+
export const crypto = {
|
|
10
|
+
async sha256(data) {
|
|
11
|
+
return new Uint8Array(createHash('sha256').update(data).digest());
|
|
12
|
+
},
|
|
13
|
+
async signerOf(privateKeyPem) {
|
|
14
|
+
// Parsed here and captured, so a call signs against a KeyObject and never a string.
|
|
15
|
+
const key = createPrivateKey(privateKeyPem);
|
|
16
|
+
return { async sign(data) { return new Uint8Array(sign(null, data, key)); } };
|
|
17
|
+
},
|
|
18
|
+
async verifierOf(key) {
|
|
19
|
+
const parsed = typeof key === 'string'
|
|
20
|
+
? createPublicKey(key)
|
|
21
|
+
: createPublicKey({ key: key, format: 'jwk' });
|
|
22
|
+
return { async verify(data, signature) { return verify(null, data, parsed, signature); } };
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/crypto/node.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG1F,MAAM,CAAC,MAAM,MAAM,GAAe;IAChC,KAAK,CAAC,MAAM,CAAC,IAAI;QACf,OAAO,IAAI,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,aAAa;QAC1B,oFAAoF;QACpF,MAAM,GAAG,GAAG,gBAAgB,CAAC,aAAa,CAAC,CAAC;QAC5C,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAChF,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,GAAG;QAClB,MAAM,MAAM,GAAG,OAAO,GAAG,KAAK,QAAQ;YACpC,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC;YACtB,CAAC,CAAC,eAAe,CAAC,EAAE,GAAG,EAAE,GAAY,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1D,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,IAAI,OAAO,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7F,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two Ed25519 gestures a signed call needs, and the one hash that binds it.
|
|
3
|
+
*
|
|
4
|
+
* Node signs 59% faster than WebCrypto on the same curve (measured 2026-08-23: 14.30 µs
|
|
5
|
+
* against 22.72 µs per signature, 34.42 against 41.81 to verify), so this is a PORT with
|
|
6
|
+
* two realizations and not one implementation at the lowest common denominator. `#crypto`
|
|
7
|
+
* resolves to `crypto/node.ts` everywhere except under the `workerd` condition — the
|
|
8
|
+
* bundler picks at build time, and neither half ever appears in the other's output.
|
|
9
|
+
*
|
|
10
|
+
* The shape is async because WebCrypto is. On Node that costs one microtask, which the
|
|
11
|
+
* same measurement puts inside the noise of the signature itself (14.30 sync against
|
|
12
|
+
* 14.28 awaited) — awaiting is free, converting is not.
|
|
13
|
+
*
|
|
14
|
+
* A KEY IS PARSED ONCE. `crypto.subtle.importKey` is async and per-key, so an interface
|
|
15
|
+
* shaped `sign(key, data)` would import on every call; `signerOf(pem)` hands back
|
|
16
|
+
* something that holds the parsed key, and a boot builds it once.
|
|
17
|
+
*/
|
|
18
|
+
/** A parsed private key. */
|
|
19
|
+
export interface Signer {
|
|
20
|
+
sign(data: Uint8Array): Promise<Uint8Array>;
|
|
21
|
+
}
|
|
22
|
+
/** A parsed public key. */
|
|
23
|
+
export interface Verifier {
|
|
24
|
+
/** False, never a throw: a bad signature is an answer, not a failure. */
|
|
25
|
+
verify(data: Uint8Array, signature: Uint8Array): Promise<boolean>;
|
|
26
|
+
}
|
|
27
|
+
/** A public key as a grant carries it — `{ kty: 'OKP', crv: 'Ed25519', x }`. */
|
|
28
|
+
export interface PublicJwk {
|
|
29
|
+
kty: string;
|
|
30
|
+
crv?: string;
|
|
31
|
+
x?: string;
|
|
32
|
+
[key: string]: unknown;
|
|
33
|
+
}
|
|
34
|
+
export interface CryptoPort {
|
|
35
|
+
/** SHA-256. What binds a body to an envelope without carrying the body. */
|
|
36
|
+
sha256(data: Uint8Array): Promise<Uint8Array>;
|
|
37
|
+
/** From a PKCS#8 PEM — what `fougere keys` writes. */
|
|
38
|
+
signerOf(privateKeyPem: string): Promise<Signer>;
|
|
39
|
+
/** From an SPKI PEM (the root's) or a JWK (the one a grant embeds). */
|
|
40
|
+
verifierOf(key: string | PublicJwk): Promise<Verifier>;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=port.d.ts.map
|