@shivaedev/platform 0.14.0 → 0.14.2
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/CHANGELOG.md +19 -0
- package/README.md +26 -9
- package/dist/server/appHost.d.ts +7 -15
- package/dist/server/appHost.d.ts.map +1 -1
- package/dist/server/appHost.js +4 -1
- package/dist/server/appHost.js.map +1 -1
- package/dist/server/appHostHttp.d.ts +3 -2
- package/dist/server/appHostHttp.d.ts.map +1 -1
- package/dist/server/appHostHttp.js +3 -0
- package/dist/server/appHostHttp.js.map +1 -1
- package/dist/server/databaseLayer.d.ts +8 -1
- package/dist/server/databaseLayer.d.ts.map +1 -1
- package/dist/server/databaseLayer.js.map +1 -1
- package/dist/server/otlpHttpClient.d.ts +4 -0
- package/dist/server/otlpHttpClient.d.ts.map +1 -0
- package/dist/server/otlpHttpClient.js +24 -0
- package/dist/server/otlpHttpClient.js.map +1 -0
- package/dist/server/otlpTracing.d.ts.map +1 -1
- package/dist/server/otlpTracing.js +6 -3
- package/dist/server/otlpTracing.js.map +1 -1
- package/dist/server/redactOtlpUrl.d.ts +2 -0
- package/dist/server/redactOtlpUrl.d.ts.map +1 -0
- package/dist/server/redactOtlpUrl.js +41 -0
- package/dist/server/redactOtlpUrl.js.map +1 -0
- package/dist/server/safeOtlpSerialization.d.ts +2 -1
- package/dist/server/safeOtlpSerialization.d.ts.map +1 -1
- package/dist/server/safeOtlpSerialization.js +25 -16
- package/dist/server/safeOtlpSerialization.js.map +1 -1
- package/docs/roadmap.md +7 -6
- package/package.json +16 -5
- package/src/server/appHost.ts +39 -28
- package/src/server/appHostHttp.ts +24 -1
- package/src/server/databaseLayer.ts +9 -2
- package/src/server/otlpHttpClient.ts +35 -0
- package/src/server/otlpTracing.ts +15 -5
- package/src/server/redactOtlpUrl.ts +48 -0
- package/src/server/safeOtlpSerialization.ts +42 -29
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.14.2 - 2026-10-17
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Align published framework dependencies with the current releases.
|
|
8
|
+
|
|
9
|
+
## 0.14.1 - 2026-10-17
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- `appHost({ application, migrations, config? })` evaluates a native Effect returning HTTP host options only after migrations or the schema-current check finishes. Construction keeps typed errors, requirements and scoped resources in the host Layer.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- Honour OTLP protocol configuration, including the traces-specific override, with native Effect JSON and protobuf encoders and sensitive diagnostic redaction in both. Default to `http/protobuf` as recommended by OpenTelemetry and fail configuration for unsupported protocols.
|
|
18
|
+
- Name exported HTTP server spans with the method and matched route template, preserving `http.route` and incoming trace context; unmatched requests retain the method alone.
|
|
19
|
+
- Warn on the first failed OTLP export with the collector status and redacted answer, and include `OTEL_SERVICE_VERSION` as `service.version`.
|
|
20
|
+
- Security fix: `otlpTracing` redacts every URL query value, fragment and userinfo before exporting traces, including HTTP server and client spans, events and links. Paths and query parameter names remain readable. Platform 0.13.0 and 0.14.0 exported URL query values; apps with tracing enabled should upgrade.
|
|
21
|
+
|
|
3
22
|
## 0.14.0 - 2026-10-17
|
|
4
23
|
|
|
5
24
|
### Added
|
package/README.md
CHANGED
|
@@ -86,17 +86,34 @@ RPC uses the existing `localRpcGuard`: it requires a loopback peer and Host, sam
|
|
|
86
86
|
|
|
87
87
|
For local tools, use `policy: "loopback"` with contracts that do not use session middleware to serve RPC without a session provider. The guard requires a loopback peer and Host, absent or same-origin Origin, and NDJSON content type. This policy does not use `TRUSTED_PROXY` or `config.trustedProxy`. Set `rpcPath` to choose another native RPC route; `/rpc` remains the default.
|
|
88
88
|
|
|
89
|
-
Omit `migrations` to host an app without a database. This form creates no SQL pool and reads no `DATABASE_URL`; `AppHttpHostOptions` describes it. `AppHostOptions`
|
|
89
|
+
Omit `migrations` to host an app without a database. This form creates no SQL pool and reads no `DATABASE_URL`; `AppHttpHostOptions` describes it. `AppHostOptions` requires migrations for database-backed hosts. A service that needs SQL still requires a SQL Layer. Provide `appDatabase` to the application’s service Layer when it owns database composition, as Fleet's daemon does with its migration loader and namespace ledger. Real HTTP tests cover the custom route, session-free loopback guard and database-free startup; Fleet's PostgreSQL daemon tests cover the adopted composition.
|
|
90
90
|
|
|
91
91
|
`appHost` serves unauthenticated `GET /health`. It queries its SQL client on each request and returns `200` only when the query succeeds within two seconds; a missing SQL client, query failure or timeout returns `503`. Both responses have an empty body and `Cache-Control: no-store`. This route also works when the SQL client comes from the application’s `services` Layer. Use it for database readiness checks.
|
|
92
92
|
|
|
93
|
-
Set `migrations.mode: "check"` on `appDatabase` or a database-backed `appHost` when a separate pre-deploy command owns migrations. Startup reads the ledger and fails with native `MigrationError` (`kind: "BadState"`) if any required migration ID or name is missing; it does not run migrations or create a ledger. Later ledger entries are allowed for rolling deployments. With `mode` omitted or `"migrate"`,
|
|
93
|
+
Set `migrations.mode: "check"` on `appDatabase` or a database-backed `appHost` when a separate pre-deploy command owns migrations. Startup reads the ledger and fails with native `MigrationError` (`kind: "BadState"`) if any required migration ID or name is missing; it does not run migrations or create a ledger. Later ledger entries are allowed for rolling deployments. With `mode` omitted or `"migrate"`, startup applies pending migrations with a five-second lock timeout unless `migrations.lockTimeout` overrides it.
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
When construction itself touches the schema, use `appHost({ migrations, config, application })`. `application` is a native Effect that returns the HTTP host options (`group`, handler and service Layers, session policy, and optional HTTP config). The host first builds `appDatabase`, then evaluates this Effect in the host scope with SQL, Reactivity and `AppChanges` available. A failed migration or schema-current check prevents construction. Initialization requirements and errors stay in the returned Layer's types, and acquired resources close with the host scope.
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
```ts
|
|
98
|
+
const host = appHost({
|
|
99
|
+
config: { databaseUrl },
|
|
100
|
+
migrations: { loader: migrations, mode: "check" },
|
|
101
|
+
application: Effect.gen(function* () {
|
|
102
|
+
const { routes, sessions } = yield* makeAuth();
|
|
103
|
+
return { group: Api, handlers: Handlers, services: Services, routes, sessions };
|
|
104
|
+
}),
|
|
105
|
+
});
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Construct Better Auth inside `application`, since its constructor starts schema validation. Keep validation enabled so a current migration ledger with missing auth columns still reports drift. The starter uses this form after its pre-deploy migrations.
|
|
109
|
+
|
|
110
|
+
Set `OTEL_EXPORTER_OTLP_ENDPOINT` (the collector base URL; `/v1/traces` is appended) or `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` (the complete traces URL, which takes precedence) to export `appHost`'s Effect spans over OTLP/HTTP. `OTEL_EXPORTER_OTLP_PROTOCOL` selects `http/protobuf` or `http/json`; `OTEL_EXPORTER_OTLP_TRACES_PROTOCOL` takes precedence for traces. When neither protocol variable is set, the default is `http/protobuf`, following the [OpenTelemetry recommendation](https://opentelemetry.io/docs/specs/otel/protocol/exporter/#specify-protocol). Unsupported protocols, including `grpc`, fail startup with a `ConfigError` naming the value. `OTEL_EXPORTER_OTLP_HEADERS` supplies comma-separated `key=value` exporter headers with URL-encoded values. `OTEL_SERVICE_NAME` sets the service name and `OTEL_SERVICE_VERSION` sets `service.version`; `OTEL_RESOURCE_ATTRIBUTES` adds comma-separated, URL-encoded resource attributes and can supply `service.name` when no service name is set. The fallback name is `unknown_service`. Configuration is read through Effect Config. Without an endpoint, no exporter or export loop is built, even when service metadata is set.
|
|
111
|
+
|
|
112
|
+
On Railway, enable the per-service tracing setting separately for the web service and worker, and leave both exporter endpoint variables unset in your app's configuration. Railway injects the `OTEL_*` variables, including `OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf`, only when the app sets no endpoint of its own. The framework exports through Effect's own `effect/observability` OTLP tracer; eBPF auto-instrumentation is outside this path. For a worker, provide `otlpTracing` from `@shivaedev/platform/otlpTracing.ts` to its application Layer. It batches ended Effect spans and flushes during scoped shutdown with a three-second bound. The first failed export logs a warning with the collector status and redacted response body, or the transport failure kind when no response arrives. Repeated failures stay quiet until a successful export. Collector connection failures and HTTP errors leave requests, jobs and shutdown successful. HTTP receiver tests cover the host and the starter's PostgreSQL word-count worker; they do not establish delivery in a deployed collector.
|
|
113
|
+
|
|
114
|
+
Exported HTTP server spans use `{method} {route}` with `http.route` for matched RPC and router paths, including parameter templates; unmatched requests use the method alone. The production host continues incoming W3C `traceparent` context, including one sent by an edge proxy.
|
|
98
115
|
|
|
99
|
-
|
|
116
|
+
Both JSON and protobuf export serialization apply sensitive-key and credential-text redaction to span attributes, events, links, error details and resource attributes. Exporter headers stay in the collector request, outside the spans. Applications must still avoid placing secrets in span names, free text or custom attributes.
|
|
100
117
|
|
|
101
118
|
Set `config.maxConnections` on `appDatabase` or a migrated `appHost` to bound the pool. A daemon with long-lived RPC streams can use `config.disablePreemptiveShutdown: true` to let scope closure interrupt those streams before closing the listener; omitting it keeps Node's native graceful-shutdown default. Fleet's daemon tests cover one bounded pool and scoped provider and listener cleanup, including follower reconnection after shutdown.
|
|
102
119
|
|
|
@@ -320,9 +337,7 @@ await runtime.dispose();
|
|
|
320
337
|
|
|
321
338
|
`base` is `"application"` and `request` is `"request"`. The application's resource Layer is acquired once across calls. An explicit `developmentCacheKey` shares a runtime between calls with that key during development. Each key belongs to one application runtime definition.
|
|
322
339
|
|
|
323
|
-
A nested `runWithServices` call replaces the outer invocation's overrides for
|
|
324
|
-
its callback. Merge the contexts explicitly when the nested call must retain
|
|
325
|
-
those overrides.
|
|
340
|
+
A nested `runWithServices` call replaces the outer invocation's overrides for its callback. Merge the contexts explicitly when the nested call must retain those overrides.
|
|
326
341
|
|
|
327
342
|
### Node subscriptions: combine cancellation and clean up
|
|
328
343
|
|
|
@@ -425,7 +440,8 @@ Import the module that defines the name; there is no package-root entry. Paths b
|
|
|
425
440
|
| Module | Names and purpose |
|
|
426
441
|
| --- | --- |
|
|
427
442
|
| `otlpTracing.ts` | `otlpTracing`: scoped, opt-in Effect OTLP trace export configured through standard exporter variables; provide it to worker Layers. |
|
|
428
|
-
| `
|
|
443
|
+
| `boundedBody.ts` | `readBoundedBody`, `RequestBodyTooLarge`: bounded body bytes and a typed HTTP 413 failure. |
|
|
444
|
+
| `appHost.ts` | `appHost({ group, handlers, services, migrations?, sessions?, policy?, rpcPath?, assets?, routes?, config? })` or `appHost({ application, migrations, config? })`, `appDatabase({ migrations, config? })`, `AppChanges`, `AppHostOptions`, `AppHttpHostOptions`, `AppLocalHostOptions`, `AppDatabaseOptions`: scoped HTTP and PostgreSQL composition with loopback defaults and optional proxy trust. |
|
|
429
445
|
| `errors/taxonomy.ts` | `NotFound`, `Unauthorized`, `Forbidden`, `BadRequest`, `Conflict`, `PreconditionFailed`, `TooManyRequests`, `AuthUnavailable`, `InternalServerError`, `ServiceUnavailable`: Schema tagged error classes with a `message`; `BadRequest` and `Conflict` also accept an optional `field`. |
|
|
430
446
|
| `errors/rejected-field.ts` | `rejectedField(unknown): Option<RejectedField>`; `RejectedField` is `{ field: string, message: string }`. |
|
|
431
447
|
| `rpc/identity.ts` | `RequestId`: string service. `Identity`: `IdentityValue`, `{ id: string }`. `OptionalIdentity`: `Option<IdentityValue>`. `SessionUser`: `SessionUserValue`, `{ id, name, email }`. |
|
|
@@ -463,6 +479,7 @@ Install the optional peers for the selected integration:
|
|
|
463
479
|
|
|
464
480
|
| Integration | Additional peers |
|
|
465
481
|
| --- | --- |
|
|
482
|
+
| `boundedBody.ts` | `@effect/platform-node` |
|
|
466
483
|
| `appHost.ts` | `@effect/platform-node`, `@effect/sql-pg` |
|
|
467
484
|
| `better-auth/adapter.ts` | `better-auth`, `@shivaedev/effect-prisma`, `@prisma-next/sql-orm-client` |
|
|
468
485
|
| `testing/vitest.ts` | `@effect/vitest`, `@shivaedev/effect-prisma`, `@shivaedev/effect-trpc`, `@trpc/server` |
|
package/dist/server/appHost.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Context, type Duration, type Effect
|
|
1
|
+
import { Context, type Duration, type Effect } from "effect";
|
|
2
2
|
import type { Rpc } from "effect/rpc";
|
|
3
3
|
import type { Migrator } from "effect/sql";
|
|
4
|
-
import type { PostgresChangesOptions } from "@shivaedev/effect-sql/postgresChanges.ts";
|
|
5
4
|
import type { SessionPolicy, SessionShape } from "#rpc-server/session.ts";
|
|
6
|
-
import { appHostHttp,
|
|
5
|
+
import { appHostHttp, deferredHost } from "#server/appHostHttp.ts";
|
|
6
|
+
import { type DatabaseConfig } from "#server/databaseLayer.ts";
|
|
7
7
|
import type { HostOptions, HostPolicy } from "#server/hostOptions.ts";
|
|
8
8
|
declare const AppChanges_base: Context.ServiceClass<AppChanges, "@shivaedev/platform/AppChanges", {
|
|
9
9
|
resync: Effect.Effect<void, never, never>;
|
|
@@ -24,12 +24,7 @@ declare const AppChanges_base: Context.ServiceClass<AppChanges, "@shivaedev/plat
|
|
|
24
24
|
export declare class AppChanges extends AppChanges_base {
|
|
25
25
|
}
|
|
26
26
|
export interface AppDatabaseOptions<R = never> {
|
|
27
|
-
readonly config?:
|
|
28
|
-
readonly databaseUrl?: Redacted.Redacted<string>;
|
|
29
|
-
readonly applicationName?: string;
|
|
30
|
-
readonly maxConnections?: number;
|
|
31
|
-
readonly changes?: Omit<PostgresChangesOptions, "client" | "resync">;
|
|
32
|
-
};
|
|
27
|
+
readonly config?: DatabaseConfig;
|
|
33
28
|
readonly migrations: {
|
|
34
29
|
readonly loader: Migrator.Loader<R>;
|
|
35
30
|
readonly mode?: "migrate" | "check";
|
|
@@ -51,12 +46,9 @@ export type AppLocalHostOptions<TRpcs extends Rpc.Any, THandlers, THandlerError,
|
|
|
51
46
|
export type AppHttpHostOptions<TRpcs extends Rpc.Any, THandlers, THandlerError, THandlerRequirements, TServices = never, TServiceError = never, TServiceRequirements = never, TSession extends SessionShape = SessionShape> = HostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements> & HostPolicy<TSession> & {
|
|
52
47
|
readonly migrations?: undefined;
|
|
53
48
|
};
|
|
54
|
-
export declare function appHost<TRpcs extends Rpc.Any, THandlers, THandlerError, THandlerRequirements, TServices = never, TServiceError = never, TServiceRequirements = never, TMigrations = never, TSession extends SessionShape = SessionShape
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
readonly sessions?: never;
|
|
58
|
-
readonly migrations?: undefined;
|
|
59
|
-
}): ReturnType<typeof appHostHttp<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, SessionShape>>;
|
|
49
|
+
export declare function appHost<TRpcs extends Rpc.Any, THandlers, THandlerError, THandlerRequirements, TServices = never, TServiceError = never, TServiceRequirements = never, TMigrations = never, TSession extends SessionShape = SessionShape, TApplicationError = never, TApplicationRequirements = never>(options: (AppDatabaseOptions<TMigrations> & {
|
|
50
|
+
readonly application: Effect.Effect<AppHttpHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TSession>, TApplicationError, TApplicationRequirements>;
|
|
51
|
+
}) | AppHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TMigrations, TSession> | AppLocalHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TMigrations>): ReturnType<typeof deferredHost<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TMigrations, TSession, TApplicationError, TApplicationRequirements>>;
|
|
60
52
|
export declare function appHost<TRpcs extends Rpc.Any, THandlers, THandlerError, THandlerRequirements, TServices = never, TServiceError = never, TServiceRequirements = never, TSession extends SessionShape = SessionShape>(options: AppHttpHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TSession>): ReturnType<typeof appHostHttp<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TSession>>;
|
|
61
53
|
export {};
|
|
62
54
|
//# sourceMappingURL=appHost.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appHost.d.ts","sourceRoot":"","sources":["../../src/server/appHost.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"appHost.d.ts","sourceRoot":"","sources":["../../src/server/appHost.ts"],"names":[],"mappings":"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"}
|
package/dist/server/appHost.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Context } from "effect";
|
|
2
|
-
import { appHostHttp, migratedHost } from "#server/appHostHttp.ts";
|
|
2
|
+
import { appHostHttp, deferredHost, migratedHost } from "#server/appHostHttp.ts";
|
|
3
3
|
import { databaseLayer } from "#server/databaseLayer.ts";
|
|
4
4
|
export class AppChanges extends Context.Service()("@shivaedev/platform/AppChanges") {
|
|
5
5
|
}
|
|
@@ -7,6 +7,9 @@ export function appDatabase(options) {
|
|
|
7
7
|
return databaseLayer(options, AppChanges);
|
|
8
8
|
}
|
|
9
9
|
export function appHost(options) {
|
|
10
|
+
if ("application" in options) {
|
|
11
|
+
return deferredHost(options.application, appDatabase(options));
|
|
12
|
+
}
|
|
10
13
|
return options.migrations === undefined
|
|
11
14
|
? appHostHttp(options)
|
|
12
15
|
: migratedHost({ ...options, migrations: options.migrations }, appDatabase({ ...options, migrations: options.migrations }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appHost.js","sourceRoot":"","sources":["../../src/server/appHost.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"appHost.js","sourceRoot":"","sources":["../../src/server/appHost.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAA8B,MAAM,QAAQ,CAAC;AAK7D,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACjF,OAAO,EAAuB,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAG9E,MAAM,OAAO,UAAW,SAAQ,OAAO,CAAC,OAAO,EAAqD,CAAC,gCAAgC,CAAC;CAAG;AAWzI,MAAM,UAAU,WAAW,CAAI,OAA8B;IAC5D,OAAO,aAAa,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AAC3C,CAAC;AAgGD,MAAM,UAAU,OAAO,CAatB,OAUsI;IAEtI,IAAI,aAAa,IAAI,OAAO,EAAE,CAAC;QAC9B,OAAO,YAAY,CAAC,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,OAAO,CAAC,UAAU,KAAK,SAAS;QACtC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC;QACtB,CAAC,CAAC,YAAY,CAAC,EAAE,GAAG,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,EAAE,WAAW,CAAC,EAAE,GAAG,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;AAC9H,CAAC"}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { NodeServices } from "@effect/platform-node";
|
|
2
|
-
import { Config, Layer } from "effect";
|
|
2
|
+
import { Config, Effect, Layer } from "effect";
|
|
3
3
|
import { HttpRouter } from "effect/http";
|
|
4
4
|
import { type Rpc, RpcSerialization } from "effect/rpc";
|
|
5
|
-
import type { AppHostOptions, AppLocalHostOptions } from "#appHost.ts";
|
|
5
|
+
import type { AppHostOptions, AppHttpHostOptions, AppLocalHostOptions } from "#appHost.ts";
|
|
6
6
|
import type { databaseLayer } from "#databaseLayer.ts";
|
|
7
7
|
import type { HostOptions, HostPolicy } from "#hostOptions.ts";
|
|
8
8
|
import type { RequestTracing } from "#rpc/middleware.ts";
|
|
9
9
|
import { type SessionShape } from "#rpc-server/session.ts";
|
|
10
10
|
export declare function appHostHttp<TRpcs extends Rpc.Any, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TSession extends SessionShape>(options: HostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements> & HostPolicy<TSession>): Layer.Layer<TServices | import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices, TServiceError | Config.ConfigError | import("effect/PlatformError").PlatformError | import("effect/http/HttpServerError").ServeError | HttpRouter.Request.Without<THandlerError>, Exclude<Exclude<Exclude<TServiceRequirements, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<import("effect/FileSystem").FileSystem, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<import("effect/http/HttpPlatform").HttpPlatform, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<import("effect/http/HttpServer").HttpServer, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<import("effect/Path").Path, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"GlobalRequires", Exclude<THandlerRequirements, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"GlobalRequires", Exclude<Exclude<HttpRouter.HttpRouter, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"GlobalRequires", Exclude<Exclude<RpcSerialization.RpcSerialization, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"GlobalRequires", Exclude<Exclude<Exclude<Rpc.ServicesServer<TRpcs>, import("effect/Scope").Scope>, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"GlobalRequires", Exclude<Exclude<Exclude<Rpc.ToHandler<TRpcs>, import("effect/Scope").Scope>, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"Requires", Exclude<THandlerRequirements, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"Requires", Exclude<Exclude<HttpRouter.HttpRouter, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"Requires", Exclude<Exclude<RpcSerialization.RpcSerialization, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"Requires", Exclude<Exclude<Exclude<Rpc.ServicesServer<TRpcs>, import("effect/Scope").Scope>, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"Requires", Exclude<Exclude<Exclude<Rpc.ToHandler<TRpcs>, import("effect/Scope").Scope>, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Without<Exclude<THandlerRequirements, RpcSerialization.RpcSerialization>>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Without<Exclude<Exclude<HttpRouter.HttpRouter, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Without<Exclude<Exclude<RpcSerialization.RpcSerialization, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Without<Exclude<Exclude<Exclude<Rpc.ServicesServer<TRpcs>, import("effect/Scope").Scope>, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Without<Exclude<Exclude<Exclude<Rpc.ToHandler<TRpcs>, import("effect/Scope").Scope>, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never>>;
|
|
11
11
|
export declare function migratedHost<TRpcs extends Rpc.Any, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TMigrations, TSession extends SessionShape>(options: AppHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TMigrations, TSession> | AppLocalHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TMigrations>, database: ReturnType<typeof databaseLayer<TMigrations>>): Layer.Layer<TServices | import("#appHost.ts").AppChanges | import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient | NodeServices.NodeServices, TServiceError | Config.ConfigError | import("effect/sql/Migrator").MigrationError | import("effect/PlatformError").PlatformError | import("effect/http/HttpServerError").ServeError | import("effect/sql/SqlError").SqlError | HttpRouter.Request.Without<THandlerError>, Exclude<Exclude<Exclude<Exclude<TServiceRequirements, import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<import("effect/FileSystem").FileSystem, TServices | import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<import("effect/http/HttpPlatform").HttpPlatform, TServices | import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<import("effect/http/HttpServer").HttpServer, TServices | import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<import("effect/Path").Path, TServices | import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<TMigrations, import("effect/Scope").Scope>, import("@effect/sql-pg/PgClient").PgClient | import("effect/sql/SqlClient").SqlClient>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"GlobalRequires", Exclude<THandlerRequirements, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices | import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"GlobalRequires", Exclude<Exclude<HttpRouter.HttpRouter, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices | import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"GlobalRequires", Exclude<Exclude<RpcSerialization.RpcSerialization, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices | import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"GlobalRequires", Exclude<Exclude<Exclude<Rpc.ServicesServer<TRpcs>, import("effect/Scope").Scope>, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices | import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"GlobalRequires", Exclude<Exclude<Exclude<Rpc.ToHandler<TRpcs>, import("effect/Scope").Scope>, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices | import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"Requires", Exclude<THandlerRequirements, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices | import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"Requires", Exclude<Exclude<HttpRouter.HttpRouter, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices | import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"Requires", Exclude<Exclude<RpcSerialization.RpcSerialization, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices | import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"Requires", Exclude<Exclude<Exclude<Rpc.ServicesServer<TRpcs>, import("effect/Scope").Scope>, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices | import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"Requires", Exclude<Exclude<Exclude<Rpc.ToHandler<TRpcs>, import("effect/Scope").Scope>, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices | import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Without<Exclude<THandlerRequirements, RpcSerialization.RpcSerialization>>, HttpRouter.HttpRouter>, TServices | import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Without<Exclude<Exclude<HttpRouter.HttpRouter, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.HttpRouter>, TServices | import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Without<Exclude<Exclude<RpcSerialization.RpcSerialization, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.HttpRouter>, TServices | import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Without<Exclude<Exclude<Exclude<Rpc.ServicesServer<TRpcs>, import("effect/Scope").Scope>, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.HttpRouter>, TServices | import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never> | Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Without<Exclude<Exclude<Exclude<Rpc.ToHandler<TRpcs>, import("effect/Scope").Scope>, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.HttpRouter>, TServices | import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never>>;
|
|
12
|
+
export declare function deferredHost<TRpcs extends Rpc.Any, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TMigrations, TSession extends SessionShape, TApplicationError, TApplicationRequirements>(application: Effect.Effect<AppHttpHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TSession>, TApplicationError, TApplicationRequirements>, database: ReturnType<typeof databaseLayer<TMigrations>>): Layer.Layer<TServices | import("#appHost.ts").AppChanges | import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient | NodeServices.NodeServices, TApplicationError | TServiceError | Config.ConfigError | import("effect/sql/Migrator").MigrationError | import("effect/PlatformError").PlatformError | import("effect/http/HttpServerError").ServeError | import("effect/sql/SqlError").SqlError | HttpRouter.Request.Without<THandlerError>, Exclude<Exclude<TApplicationRequirements, import("effect/Scope").Scope>, import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient> | Exclude<Exclude<TMigrations, import("effect/Scope").Scope>, import("@effect/sql-pg/PgClient").PgClient | import("effect/sql/SqlClient").SqlClient> | Exclude<Exclude<Exclude<Exclude<TServiceRequirements, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never>, import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient> | Exclude<Exclude<Exclude<Exclude<Exclude<import("effect/FileSystem").FileSystem, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never>, import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient> | Exclude<Exclude<Exclude<Exclude<Exclude<import("effect/http/HttpPlatform").HttpPlatform, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never>, import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient> | Exclude<Exclude<Exclude<Exclude<Exclude<import("effect/http/HttpServer").HttpServer, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never>, import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient> | Exclude<Exclude<Exclude<Exclude<Exclude<import("effect/Path").Path, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never>, import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"GlobalRequires", Exclude<THandlerRequirements, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never>, import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"GlobalRequires", Exclude<Exclude<HttpRouter.HttpRouter, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never>, import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"GlobalRequires", Exclude<Exclude<RpcSerialization.RpcSerialization, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never>, import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"GlobalRequires", Exclude<Exclude<Exclude<Rpc.ServicesServer<TRpcs>, import("effect/Scope").Scope>, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never>, import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"GlobalRequires", Exclude<Exclude<Exclude<Rpc.ToHandler<TRpcs>, import("effect/Scope").Scope>, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never>, import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"Requires", Exclude<THandlerRequirements, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never>, import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"Requires", Exclude<Exclude<HttpRouter.HttpRouter, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never>, import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"Requires", Exclude<Exclude<RpcSerialization.RpcSerialization, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never>, import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"Requires", Exclude<Exclude<Exclude<Rpc.ServicesServer<TRpcs>, import("effect/Scope").Scope>, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never>, import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Only<"Requires", Exclude<Exclude<Exclude<Rpc.ToHandler<TRpcs>, import("effect/Scope").Scope>, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.GlobalProvided>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never>, import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Without<Exclude<THandlerRequirements, RpcSerialization.RpcSerialization>>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never>, import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Without<Exclude<Exclude<HttpRouter.HttpRouter, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never>, import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Without<Exclude<Exclude<RpcSerialization.RpcSerialization, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never>, import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Without<Exclude<Exclude<Exclude<Rpc.ServicesServer<TRpcs>, import("effect/Scope").Scope>, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never>, import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient> | Exclude<Exclude<Exclude<Exclude<Exclude<Exclude<HttpRouter.Request.Without<Exclude<Exclude<Exclude<Rpc.ToHandler<TRpcs>, import("effect/Scope").Scope>, THandlers | RequestTracing>, RpcSerialization.RpcSerialization>>, HttpRouter.HttpRouter>, TServices>, import("effect/http/Etag").Generator | import("effect/http/HttpPlatform").HttpPlatform | import("effect/http/HttpServer").HttpServer | NodeServices.NodeServices>, NodeServices.NodeServices>, never>, import("#appHost.ts").AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient>>;
|
|
12
13
|
//# sourceMappingURL=appHostHttp.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appHostHttp.d.ts","sourceRoot":"","sources":["../../src/server/appHostHttp.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAY,MAAM,
|
|
1
|
+
{"version":3,"file":"appHostHttp.d.ts","sourceRoot":"","sources":["../../src/server/appHostHttp.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAY,MAAM,EAAE,MAAM,EAAE,KAAK,EAAkB,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAuB,UAAU,EAAuC,MAAM,aAAa,CAAC;AACnG,OAAO,EAAE,KAAK,GAAG,EAAE,gBAAgB,EAAa,MAAM,YAAY,CAAC;AACnE,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAE3F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE/D,OAAO,KAAK,EAAqC,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAE5F,OAAO,EAA+C,KAAK,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAIxG,wBAAgB,WAAW,CAC1B,KAAK,SAAS,GAAG,CAAC,GAAG,EACrB,SAAS,EACT,aAAa,EACb,oBAAoB,EACpB,SAAS,EACT,aAAa,EACb,oBAAoB,EACpB,QAAQ,SAAS,YAAY,EAE7B,OAAO,EAAE,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,oBAAoB,EAAE,SAAS,EAAE,aAAa,EAAE,oBAAoB,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,m0QA0DlJ;AAED,wBAAgB,YAAY,CAC3B,KAAK,SAAS,GAAG,CAAC,GAAG,EACrB,SAAS,EACT,aAAa,EACb,oBAAoB,EACpB,SAAS,EACT,aAAa,EACb,oBAAoB,EACpB,WAAW,EACX,QAAQ,SAAS,YAAY,EAE7B,OAAO,EACJ,cAAc,CAAC,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,oBAAoB,EAAE,SAAS,EAAE,aAAa,EAAE,oBAAoB,EAAE,WAAW,EAAE,QAAQ,CAAC,GAC5I,mBAAmB,CAAC,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,oBAAoB,EAAE,SAAS,EAAE,aAAa,EAAE,oBAAoB,EAAE,WAAW,CAAC,EAC1I,QAAQ,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,WAAW,CAAC,CAAC,k3YAIvD;AAED,wBAAgB,YAAY,CAC3B,KAAK,SAAS,GAAG,CAAC,GAAG,EACrB,SAAS,EACT,aAAa,EACb,oBAAoB,EACpB,SAAS,EACT,aAAa,EACb,oBAAoB,EACpB,WAAW,EACX,QAAQ,SAAS,YAAY,EAC7B,iBAAiB,EACjB,wBAAwB,EAExB,WAAW,EAAE,MAAM,CAAC,MAAM,CACzB,kBAAkB,CAAC,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,oBAAoB,EAAE,SAAS,EAAE,aAAa,EAAE,oBAAoB,EAAE,QAAQ,CAAC,EACnI,iBAAiB,EACjB,wBAAwB,CACxB,EACD,QAAQ,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,WAAW,CAAC,CAAC,wjZAGvD"}
|
|
@@ -51,4 +51,7 @@ export function migratedHost(options, database) {
|
|
|
51
51
|
const services = Layer.mergeAll(options.services ?? Layer.empty);
|
|
52
52
|
return appHostHttp({ ...options, services: services.pipe(Layer.provideMerge(database)) });
|
|
53
53
|
}
|
|
54
|
+
export function deferredHost(application, database) {
|
|
55
|
+
return Layer.unwrap(Effect.map(application, (options) => appHostHttp(options))).pipe(Layer.provideMerge(database));
|
|
56
|
+
}
|
|
54
57
|
//# sourceMappingURL=appHostHttp.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appHostHttp.js","sourceRoot":"","sources":["../../src/server/appHostHttp.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"appHostHttp.js","sourceRoot":"","sources":["../../src/server/appHostHttp.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import * as PgClient from "@effect/sql-pg/PgClient";
|
|
2
|
-
import { Config, Layer } from "effect";
|
|
2
|
+
import { Config, Layer, type Redacted } from "effect";
|
|
3
3
|
import * as Reactivity from "effect/reactivity/Reactivity";
|
|
4
|
+
import { type PostgresChangesOptions } from "@shivaedev/effect-sql/postgresChanges.ts";
|
|
4
5
|
import type { AppChanges, AppDatabaseOptions } from "#server/appHost.ts";
|
|
6
|
+
export interface DatabaseConfig {
|
|
7
|
+
readonly applicationName?: string;
|
|
8
|
+
readonly changes?: Omit<PostgresChangesOptions, "client" | "resync">;
|
|
9
|
+
readonly databaseUrl?: Redacted.Redacted<string>;
|
|
10
|
+
readonly maxConnections?: number;
|
|
11
|
+
}
|
|
5
12
|
export declare function databaseLayer<R>(options: AppDatabaseOptions<R>, changesService: typeof AppChanges): Layer.Layer<AppChanges | PgClient.PgClient | Reactivity.Reactivity | import("effect/sql/SqlClient").SqlClient, Config.ConfigError | import("effect/sql/Migrator").MigrationError | import("effect/sql/SqlError").SqlError, Exclude<Exclude<R, import("effect/Scope").Scope>, PgClient.PgClient | import("effect/sql/SqlClient").SqlClient>>;
|
|
6
13
|
//# sourceMappingURL=databaseLayer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"databaseLayer.d.ts","sourceRoot":"","sources":["../../src/server/databaseLayer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,MAAM,EAAU,KAAK,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"databaseLayer.d.ts","sourceRoot":"","sources":["../../src/server/databaseLayer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,MAAM,EAAU,KAAK,EAAE,KAAK,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,KAAK,UAAU,MAAM,8BAA8B,CAAC;AAI3D,OAAO,EAAE,KAAK,sBAAsB,EAAmB,MAAM,0CAA0C,CAAC;AACxG,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAEzE,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,QAAQ,GAAG,QAAQ,CAAC,CAAC;IACrE,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACjD,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,UAAU,+UA6BjG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"databaseLayer.js","sourceRoot":"","sources":["../../src/server/databaseLayer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"databaseLayer.js","sourceRoot":"","sources":["../../src/server/databaseLayer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAiB,MAAM,QAAQ,CAAC;AAC9D,OAAO,KAAK,UAAU,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,8CAA8C,CAAC;AAC9E,OAAO,EAAE,wBAAwB,EAAE,MAAM,mDAAmD,CAAC;AAC7F,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,EAA+B,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAUxG,MAAM,UAAU,aAAa,CAAI,OAA8B,EAAE,cAAiC;IACjG,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CACxB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACnB,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,EAAE,WAAW,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC;QACpF,OAAO,QAAQ,CAAC,KAAK,CAAC;YACrB,GAAG;YACH,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;YAC1G,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;SAC7G,CAAC,CAAC;IACJ,CAAC,CAAC,CACF,CAAC;IACF,MAAM,QAAQ,GAAG,KAAK,CAAC,aAAa,CACnC,OAAO,CAAC,UAAU,CAAC,IAAI,KAAK,OAAO;QAClC,CAAC,CAAC,wBAAwB,CAAC,OAAO,CAAC,UAAU,CAAC;QAC9C,CAAC,CAAC,eAAe,CAAC,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,WAAW,EAAE,OAAO,CAAC,UAAU,CAAC,WAAW,IAAI,WAAW,EAAE,CAAC,CACzG,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;IACrG,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC;IACxC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC;IACb,CAAC;IACD,OAAO,KAAK,CAAC,MAAM,CAClB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACnB,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACxC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,cAAc,CAAC;QACpC,OAAO,eAAe,CAAC,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IACtE,CAAC,CAAC,CACF,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"otlpHttpClient.d.ts","sourceRoot":"","sources":["../../src/server/otlpHttpClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAmB,UAAU,EAAE,MAAM,aAAa,CAAC;AAG1D,eAAO,MAAM,cAAc,kDA8BiB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Effect, Layer } from "effect";
|
|
2
|
+
import { FetchHttpClient, HttpClient } from "effect/http";
|
|
3
|
+
import { redactOtlpText } from "#safeOtlpSerialization.ts";
|
|
4
|
+
export const otlpHttpClient = Layer.effect(HttpClient.HttpClient, Effect.gen(function* () {
|
|
5
|
+
const client = yield* HttpClient.HttpClient;
|
|
6
|
+
let warned = false;
|
|
7
|
+
function warnOnce(diagnostic) {
|
|
8
|
+
return Effect.suspend(() => {
|
|
9
|
+
if (warned) {
|
|
10
|
+
return Effect.void;
|
|
11
|
+
}
|
|
12
|
+
warned = true;
|
|
13
|
+
return Effect.flatMap(diagnostic, (annotations) => Effect.logWarning("OTLP trace export failed").pipe(Effect.annotateLogs(annotations)));
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return client.pipe(HttpClient.tap((response) => {
|
|
17
|
+
if (response.status >= 200 && response.status < 300) {
|
|
18
|
+
warned = false;
|
|
19
|
+
return Effect.void;
|
|
20
|
+
}
|
|
21
|
+
return warnOnce(response.text.pipe(Effect.orElseSucceed(() => "Unable to read collector response"), Effect.map((body) => ({ "otlp.response": redactOtlpText(body), "otlp.status": response.status }))));
|
|
22
|
+
}), HttpClient.tapError((error) => warnOnce(Effect.succeed({ "otlp.failure": error.reason._tag }))));
|
|
23
|
+
})).pipe(Layer.provide(FetchHttpClient.layer));
|
|
24
|
+
//# sourceMappingURL=otlpHttpClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"otlpHttpClient.js","sourceRoot":"","sources":["../../src/server/otlpHttpClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CACzC,UAAU,CAAC,UAAU,EACrB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IACnB,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;IAC5C,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,SAAS,QAAQ,CAAC,UAAkD;QACnE,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE;YAC1B,IAAI,MAAM,EAAE,CAAC;gBACZ,OAAO,MAAM,CAAC,IAAI,CAAC;YACpB,CAAC;YACD,MAAM,GAAG,IAAI,CAAC;YACd,OAAO,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,0BAA0B,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAC1I,CAAC,CAAC,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CACjB,UAAU,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;QAC3B,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;YACrD,MAAM,GAAG,KAAK,CAAC;YACf,OAAO,MAAM,CAAC,IAAI,CAAC;QACpB,CAAC;QACD,OAAO,QAAQ,CACd,QAAQ,CAAC,IAAI,CAAC,IAAI,CACjB,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,CAAC,mCAAmC,CAAC,EAC/D,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,eAAe,EAAE,cAAc,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CACjG,CACD,CAAC;IACH,CAAC,CAAC,EACF,UAAU,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,cAAc,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAC/F,CAAC;AACH,CAAC,CAAC,CACF,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"otlpTracing.d.ts","sourceRoot":"","sources":["../../src/server/otlpTracing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAU,KAAK,EAAU,MAAM,QAAQ,CAAC;AAKvD,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,WAAW,
|
|
1
|
+
{"version":3,"file":"otlpTracing.d.ts","sourceRoot":"","sources":["../../src/server/otlpTracing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAU,KAAK,EAAU,MAAM,QAAQ,CAAC;AAKvD,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,WAAW,CAsC9D,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Config, Effect, Layer, Schema } from "effect";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { OtlpSerialization, OtlpTracer } from "effect/observability";
|
|
3
|
+
import { otlpHttpClient } from "#otlpHttpClient.ts";
|
|
4
4
|
import { safeOtlpSerialization } from "#safeOtlpSerialization.ts";
|
|
5
5
|
export const otlpTracing = Layer.unwrap(Effect.gen(function* () {
|
|
6
6
|
const endpoint = yield* Config.URL("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT").pipe(Config.orElse(() => Config.URL("OTEL_EXPORTER_OTLP_ENDPOINT").pipe(Config.map((url) => {
|
|
@@ -10,9 +10,12 @@ export const otlpTracing = Layer.unwrap(Effect.gen(function* () {
|
|
|
10
10
|
if (endpoint === undefined) {
|
|
11
11
|
return Layer.empty;
|
|
12
12
|
}
|
|
13
|
+
const configuredProtocol = yield* Config.String("OTEL_EXPORTER_OTLP_TRACES_PROTOCOL").pipe(Config.orElse(() => Config.String("OTEL_EXPORTER_OTLP_PROTOCOL")), Config.withDefault("http/protobuf"));
|
|
14
|
+
const protocol = yield* Schema.decodeUnknownEffect(Schema.Literals(["http/protobuf", "http/json"]), { reportInput: true })(configuredProtocol).pipe(Effect.mapError((cause) => new Config.ConfigError(cause)));
|
|
13
15
|
const attributes = yield* Config.Record(Schema.StringFromUriComponent, Schema.StringFromUriComponent, "OTEL_RESOURCE_ATTRIBUTES").pipe(Config.withDefault({}));
|
|
14
16
|
const serviceName = yield* Config.String("OTEL_SERVICE_NAME").pipe(Config.withDefault(attributes["service.name"] ?? "unknown_service"));
|
|
17
|
+
const serviceVersion = yield* Config.String("OTEL_SERVICE_VERSION").pipe(Config.withDefault(undefined));
|
|
15
18
|
const headers = yield* Config.Record(Schema.String, Schema.StringFromUriComponent, "OTEL_EXPORTER_OTLP_HEADERS").pipe(Config.withDefault({}));
|
|
16
|
-
return OtlpTracer.layer({ headers, resource: { attributes, serviceName }, url: endpoint.toString() }).pipe(Layer.provide(safeOtlpSerialization), Layer.provide(
|
|
19
|
+
return OtlpTracer.layer({ headers, resource: { attributes, serviceName, serviceVersion }, url: endpoint.toString() }).pipe(Layer.provide(safeOtlpSerialization.pipe(Layer.provide(protocol === "http/protobuf" ? OtlpSerialization.layerProtobuf : OtlpSerialization.layerJson))), Layer.provide(otlpHttpClient));
|
|
17
20
|
}));
|
|
18
21
|
//# sourceMappingURL=otlpTracing.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"otlpTracing.js","sourceRoot":"","sources":["../../src/server/otlpTracing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACvD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"otlpTracing.js","sourceRoot":"","sources":["../../src/server/otlpTracing.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redactOtlpUrl.d.ts","sourceRoot":"","sources":["../../src/server/redactOtlpUrl.ts"],"names":[],"mappings":"AA6BA,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,SAAK,GAAG,MAAM,CAkB7D"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { REDACTED } from "#rpc-server/sensitive.ts";
|
|
2
|
+
function query(value) {
|
|
3
|
+
return value
|
|
4
|
+
.split("&")
|
|
5
|
+
.map((part) => (part === "" ? part : `${part.split("=", 1)[0]}=${REDACTED}`))
|
|
6
|
+
.join("&");
|
|
7
|
+
}
|
|
8
|
+
function url(value) {
|
|
9
|
+
const fragment = value.indexOf("#");
|
|
10
|
+
const target = fragment === -1 ? value : value.slice(0, fragment);
|
|
11
|
+
const separator = target.indexOf("?");
|
|
12
|
+
return ((separator === -1 ? target : `${target.slice(0, separator + 1)}${query(target.slice(separator + 1))}`).replaceAll(/(?<authority>(?:\b[a-z][a-z0-9+.-]*:)?\/\/)[^/?#]*@/giu, `$<authority>${REDACTED}@`) + (fragment === -1 ? "" : `#${REDACTED}`));
|
|
13
|
+
}
|
|
14
|
+
function structured(value) {
|
|
15
|
+
try {
|
|
16
|
+
return JSON.stringify(JSON.parse(value, (key, item) => (typeof item === "string" ? redactOtlpUrl(item, key) : item)));
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export function redactOtlpUrl(value, key = "") {
|
|
23
|
+
if (/(?:^|[._-])(?:fragment|userinfo|username|password)$/iu.test(key)) {
|
|
24
|
+
return REDACTED;
|
|
25
|
+
}
|
|
26
|
+
if (/(?:^|[._-])query$/iu.test(key)) {
|
|
27
|
+
return url(`?${value}`).slice(1);
|
|
28
|
+
}
|
|
29
|
+
if (/(?:^|[._-])(?:url|uri|target)(?:$|[._-])/iu.test(key) || /(?:^|[._-])(?:referer|referrer|location|origin)$/iu.test(key)) {
|
|
30
|
+
return url(value);
|
|
31
|
+
}
|
|
32
|
+
if (/^\s*[[{]/u.test(value)) {
|
|
33
|
+
const redacted = structured(value);
|
|
34
|
+
if (redacted !== undefined) {
|
|
35
|
+
return redacted;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Quotes and whitespace can belong to secret values, so free text has no safe closing delimiter.
|
|
39
|
+
return value.replaceAll(/(?:[a-z][a-z0-9+.-]*:\/\/|[/?#]).*/gisu, url);
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=redactOtlpUrl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redactOtlpUrl.js","sourceRoot":"","sources":["../../src/server/redactOtlpUrl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEpD,SAAS,KAAK,CAAC,KAAa;IAC3B,OAAO,KAAK;SACV,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC,CAAC;SAC5E,IAAI,CAAC,GAAG,CAAC,CAAC;AACb,CAAC;AAED,SAAS,GAAG,CAAC,KAAa;IACzB,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAClE,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACtC,OAAO,CACN,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,UAAU,CAChH,wDAAwD,EACxD,eAAe,QAAQ,GAAG,CAC1B,GAAG,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC,CAC3C,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAChC,IAAI,CAAC;QACJ,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,GAAW,EAAE,IAAa,EAAE,EAAE,CAAC,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxI,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,SAAS,CAAC;IAClB,CAAC;AACF,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAa,EAAE,GAAG,GAAG,EAAE;IACpD,IAAI,uDAAuD,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACvE,OAAO,QAAQ,CAAC;IACjB,CAAC;IACD,IAAI,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACrC,OAAO,GAAG,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC;IACD,IAAI,4CAA4C,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,oDAAoD,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9H,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC;IACD,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC5B,OAAO,QAAQ,CAAC;QACjB,CAAC;IACF,CAAC;IACD,iGAAiG;IACjG,OAAO,KAAK,CAAC,UAAU,CAAC,wCAAwC,EAAE,GAAG,CAAC,CAAC;AACxE,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Layer } from "effect";
|
|
2
2
|
import { OtlpSerialization } from "effect/observability";
|
|
3
|
-
export declare
|
|
3
|
+
export declare function redactOtlpText(value: string, key?: string): string;
|
|
4
|
+
export declare const safeOtlpSerialization: Layer.Layer<OtlpSerialization.OtlpSerialization, never, OtlpSerialization.OtlpSerialization>;
|
|
4
5
|
//# sourceMappingURL=safeOtlpSerialization.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"safeOtlpSerialization.d.ts","sourceRoot":"","sources":["../../src/server/safeOtlpSerialization.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"safeOtlpSerialization.d.ts","sourceRoot":"","sources":["../../src/server/safeOtlpSerialization.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,EAAE,MAAM,QAAQ,CAAC;AAEvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAOzD,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,SAAK,UAErD;AA2BD,eAAO,MAAM,qBAAqB,8FAwBjC,CAAC"}
|
|
@@ -1,31 +1,40 @@
|
|
|
1
|
-
import { Layer } from "effect";
|
|
2
|
-
import { HttpBody } from "effect/http";
|
|
1
|
+
import { Effect, Layer } from "effect";
|
|
3
2
|
import { OtlpSerialization } from "effect/observability";
|
|
3
|
+
import { redactOtlpUrl } from "#redactOtlpUrl.ts";
|
|
4
4
|
import { isSensitiveKey, REDACTED, redactText } from "#rpc-server/sensitive.ts";
|
|
5
5
|
function sensitive(key) {
|
|
6
6
|
return isSensitiveKey(key) || ["db.user", "db.user.name", "db.connection_string"].includes(key.toLowerCase());
|
|
7
7
|
}
|
|
8
|
-
function
|
|
9
|
-
return redactText(value,
|
|
8
|
+
export function redactOtlpText(value, key = "") {
|
|
9
|
+
return redactText(redactOtlpUrl(value, key), sensitive);
|
|
10
10
|
}
|
|
11
|
-
function attributeValue(value) {
|
|
11
|
+
function attributeValue(value, key) {
|
|
12
12
|
return {
|
|
13
13
|
...value,
|
|
14
|
-
...(typeof value.stringValue === "string" ? { stringValue:
|
|
15
|
-
...(value.arrayValue ? { arrayValue: { values: value.arrayValue.values.map(attributeValue) } } : {}),
|
|
14
|
+
...(typeof value.stringValue === "string" ? { stringValue: redactOtlpText(value.stringValue, key) } : {}),
|
|
15
|
+
...(value.arrayValue ? { arrayValue: { values: value.arrayValue.values.map((item) => attributeValue(item, key)) } } : {}),
|
|
16
16
|
...(value.kvlistValue ? { kvlistValue: { values: attributes(value.kvlistValue.values) } } : {}),
|
|
17
17
|
};
|
|
18
18
|
}
|
|
19
19
|
function attributes(values) {
|
|
20
20
|
return values.map(({ key, value }) => ({
|
|
21
21
|
key,
|
|
22
|
-
value: sensitive(key) ? { stringValue: REDACTED } : attributeValue(value),
|
|
22
|
+
value: sensitive(key) ? { stringValue: REDACTED } : attributeValue(value, key),
|
|
23
23
|
}));
|
|
24
24
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
function spanName(span) {
|
|
26
|
+
if (span.kind === 2) {
|
|
27
|
+
const method = span.attributes.find(({ key }) => key === "http.request.method")?.value.stringValue;
|
|
28
|
+
const route = span.attributes.find(({ key }) => key === "http.route")?.value.stringValue;
|
|
29
|
+
if (typeof method === "string") {
|
|
30
|
+
return typeof route === "string" ? `${method} ${route}` : method;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return span.name;
|
|
34
|
+
}
|
|
35
|
+
export const safeOtlpSerialization = Layer.effect(OtlpSerialization.OtlpSerialization, Effect.map(OtlpSerialization.OtlpSerialization, (serialization) => ({
|
|
36
|
+
...serialization,
|
|
37
|
+
traces: (data) => serialization.traces({
|
|
29
38
|
...data,
|
|
30
39
|
resourceSpans: data.resourceSpans.map((resource) => ({
|
|
31
40
|
...resource,
|
|
@@ -35,13 +44,13 @@ export const safeOtlpSerialization = Layer.succeed(OtlpSerialization.OtlpSeriali
|
|
|
35
44
|
spans: scope.spans.map((span) => ({
|
|
36
45
|
...span,
|
|
37
46
|
attributes: attributes(span.attributes),
|
|
38
|
-
events: span.events.map((event) => ({ ...event, attributes: attributes(event.attributes), name:
|
|
47
|
+
events: span.events.map((event) => ({ ...event, attributes: attributes(event.attributes), name: redactOtlpText(event.name) })),
|
|
39
48
|
links: span.links.map((link) => ({ ...link, attributes: attributes(link.attributes) })),
|
|
40
|
-
name:
|
|
41
|
-
status: { ...span.status, ...(span.status.message === undefined ? {} : { message:
|
|
49
|
+
name: redactOtlpText(spanName(span)),
|
|
50
|
+
status: { ...span.status, ...(span.status.message === undefined ? {} : { message: redactOtlpText(span.status.message) }) },
|
|
42
51
|
})),
|
|
43
52
|
})),
|
|
44
53
|
})),
|
|
45
54
|
}),
|
|
46
|
-
});
|
|
55
|
+
})));
|
|
47
56
|
//# sourceMappingURL=safeOtlpSerialization.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"safeOtlpSerialization.js","sourceRoot":"","sources":["../../src/server/safeOtlpSerialization.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"safeOtlpSerialization.js","sourceRoot":"","sources":["../../src/server/safeOtlpSerialization.ts"],"names":[],"mappings":"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"}
|
package/docs/roadmap.md
CHANGED
|
@@ -9,22 +9,23 @@ This file owns Platform's module implementation, package tests and scope questio
|
|
|
9
9
|
- [x] Shared Schema tagged errors and field-rejection extraction, with native RPC JSON and tRPC rejection tests.
|
|
10
10
|
- [x] Browser-safe native RPC middleware declarations and request-id, identity and optional-identity services, with compile-time checks on guarded handlers.
|
|
11
11
|
- [x] Request-local session middleware, a Better Auth session-provider boundary and an explicit Origin policy. Tests cover concurrent identities, anonymous callers, provider failures and rejection before provider lookup.
|
|
12
|
-
- [x] HTTP transport-header authentication and a WebSocket protocol fixture that uses upgrade-request headers instead of RPC message credentials.
|
|
13
|
-
- [x] Request-id log/span annotations and redaction of failure payloads, defects, reported causes and credential-shaped strings, with bounded collection and string output.
|
|
14
|
-
- [x] An application runtime that acquires its Layer once, shares an explicit development cache key and carries service overrides across Promise calls.
|
|
12
|
+
- [x] HTTP transport-header authentication, direct tests of the RPC-header fallback and HTTP-header precedence, and a WebSocket protocol fixture that uses upgrade-request headers instead of RPC message credentials. [Header selection evidence](https://github.com/ShivaeDev/platform/blob/main/packages/platform/src/server/rpc-server/transportHeaders.test.ts).
|
|
13
|
+
- [x] Request-id log/span annotations and redaction of failure payloads, defects, reported causes and credential-shaped strings, with bounded collection and string output. [Tracing tests](https://github.com/ShivaeDev/platform/blob/main/packages/platform/src/server/rpc-server/tracing.test.ts) cover successful requests and interruption without failure logs.
|
|
14
|
+
- [x] An application runtime that acquires its Layer once, releases it exactly once, shares an explicit development cache key and recreates disposed cache entries, bypasses caching in production, and carries service overrides across Promise calls. [Runtime tests](https://github.com/ShivaeDev/platform/blob/main/packages/platform/src/server/runtime/makePlatform.test.ts) cover typed Layer build failures, Promise rejection, signal interruption with finalization, and nested override replacement and restoration.
|
|
15
15
|
- [x] Node subscription cancellation from Web/procedure signals and simulated request/socket close events, with listener cleanup.
|
|
16
16
|
- [x] A Better Auth Effect Prisma database adapter and Prisma/tRPC rollback harness. Real PostgreSQL tests cover shared transactions, failed transaction rollback, selected row operations and harness types; they require `PLATFORM_EFFECT_PRISMA_TEST_DATABASE_URL`.
|
|
17
|
+
- [x] Better Auth adapter filters, ordering, pagination, projection, native-join rejection and configured model mapping have [PostgreSQL regression tests](https://github.com/ShivaeDev/platform/blob/main/packages/platform/src/server/better-auth/filterBoundaries.spec.ts).
|
|
17
18
|
- [x] Packed-consumer checks for defining-module imports, types and core entries installed without optional peers.
|
|
18
19
|
- [x] A local app host Layer and reusable database Layer, extracted from the PostgreSQL composition: migrations before services, guarded NDJSON RPC, session policy, static assets, scoped shutdown and commit-bound live delivery. The composed fixture covers two HTTP server processes and a worker. Fleet’s daemon adopts `appHost` and `appDatabase` with a custom RPC route, session-free loopback policy and its existing migration ledger. Platform’s real HTTP option tests cover hosting without a database, while Fleet’s PostgreSQL daemon tests cover pool limits, migration upgrades and existing clients.
|
|
19
20
|
|
|
20
21
|
## Next
|
|
21
22
|
|
|
22
|
-
- [ ] Add
|
|
23
|
-
- [ ] Extend adapter tests to the remaining public options and filter, selection, ordering and pagination paths. Add a regression test for the rejection of experimental native joins.
|
|
24
|
-
- [ ] Exercise the no-HTTP-request `transportHeaders` fallback directly and the tracing boundary's successful and interrupted paths.
|
|
23
|
+
- [ ] Add adapter coverage for the `usePlural` option.
|
|
25
24
|
|
|
26
25
|
## Open questions
|
|
27
26
|
|
|
27
|
+
- What comprehensive application redaction policy should cover span names, free text and custom attributes, and how should request/action correlation work across boundaries?
|
|
28
|
+
|
|
28
29
|
- Should the package keep the optional Better Auth storage adapter and Prisma/tRPC harness beside its native request-context modules, or should those compositions live with the integration packages? Both serve real boundary work, but they give this package a wider surface than its request-identity job alone.
|
|
29
30
|
- If an application needs Better Auth storage on native Effect SQL, should Platform own that adapter or should the provider retain separate storage? The request middleware needs a session provider, not a particular database.
|
|
30
31
|
- The exports make Better Auth translation helpers importable beside the adapter. Are these helpers intended as supported consumer APIs, or should a future public API change narrow the surface to the adapter?
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shivaedev/platform",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.2",
|
|
4
4
|
"description": "Opinionated Effect application infrastructure for ShivaeDev services",
|
|
5
5
|
"homepage": "https://github.com/ShivaeDev/platform/tree/main/packages/platform#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -186,10 +186,20 @@
|
|
|
186
186
|
"types": "./dist/server/hostOptions.d.ts",
|
|
187
187
|
"default": "./dist/server/hostOptions.js"
|
|
188
188
|
},
|
|
189
|
+
"#otlpHttpClient.ts": {
|
|
190
|
+
"source": "./src/server/otlpHttpClient.ts",
|
|
191
|
+
"types": "./dist/server/otlpHttpClient.d.ts",
|
|
192
|
+
"default": "./dist/server/otlpHttpClient.js"
|
|
193
|
+
},
|
|
189
194
|
"#safeOtlpSerialization.ts": {
|
|
190
195
|
"source": "./src/server/safeOtlpSerialization.ts",
|
|
191
196
|
"types": "./dist/server/safeOtlpSerialization.d.ts",
|
|
192
197
|
"default": "./dist/server/safeOtlpSerialization.js"
|
|
198
|
+
},
|
|
199
|
+
"#redactOtlpUrl.ts": {
|
|
200
|
+
"source": "./src/server/redactOtlpUrl.ts",
|
|
201
|
+
"types": "./dist/server/redactOtlpUrl.d.ts",
|
|
202
|
+
"default": "./dist/server/redactOtlpUrl.js"
|
|
193
203
|
}
|
|
194
204
|
},
|
|
195
205
|
"exports": {
|
|
@@ -376,12 +386,13 @@
|
|
|
376
386
|
"@prisma-next/sql-contract": "0.16.0",
|
|
377
387
|
"@prisma-next/sql-orm-client": "0.16.0",
|
|
378
388
|
"@prisma-next/target-postgres": "0.16.0",
|
|
379
|
-
"@shivaedev/effect-prisma": "0.9.
|
|
389
|
+
"@shivaedev/effect-prisma": "0.9.2",
|
|
380
390
|
"@shivaedev/effect-trpc": "0.7.1",
|
|
381
|
-
"@shivaedev/quality": "0.
|
|
391
|
+
"@shivaedev/quality": "0.23.0",
|
|
392
|
+
"@shivaedev/test-story": "0.5.0",
|
|
382
393
|
"@trpc/client": "11.19.0",
|
|
383
394
|
"@trpc/server": "11.19.0",
|
|
384
|
-
"@types/node": "24.19.
|
|
395
|
+
"@types/node": "24.19.2",
|
|
385
396
|
"@typescript/native": "npm:typescript@7.0.2",
|
|
386
397
|
"better-auth": "1.7.7",
|
|
387
398
|
"effect": "4.0.4",
|
|
@@ -394,7 +405,7 @@
|
|
|
394
405
|
"@effect/sql-pg": "4.0.4",
|
|
395
406
|
"@effect/vitest": "4.0.4",
|
|
396
407
|
"@prisma-next/sql-orm-client": "0.16.0",
|
|
397
|
-
"@shivaedev/effect-prisma": "0.9.
|
|
408
|
+
"@shivaedev/effect-prisma": "0.9.2",
|
|
398
409
|
"@shivaedev/effect-trpc": "0.7.1",
|
|
399
410
|
"@trpc/server": "11.19.0",
|
|
400
411
|
"better-auth": "1.7.7",
|
package/src/server/appHost.ts
CHANGED
|
@@ -1,21 +1,15 @@
|
|
|
1
|
-
import { Context, type Duration, type Effect
|
|
1
|
+
import { Context, type Duration, type Effect } from "effect";
|
|
2
2
|
import type { Rpc } from "effect/rpc";
|
|
3
3
|
import type { Migrator } from "effect/sql";
|
|
4
4
|
import type { makeLiveServer } from "@shivaedev/effect-contract/makeLiveServer.ts";
|
|
5
|
-
import type { PostgresChangesOptions } from "@shivaedev/effect-sql/postgresChanges.ts";
|
|
6
5
|
import type { SessionPolicy, SessionShape } from "#rpc-server/session.ts";
|
|
7
|
-
import { appHostHttp, migratedHost } from "#server/appHostHttp.ts";
|
|
8
|
-
import { databaseLayer } from "#server/databaseLayer.ts";
|
|
6
|
+
import { appHostHttp, deferredHost, migratedHost } from "#server/appHostHttp.ts";
|
|
7
|
+
import { type DatabaseConfig, databaseLayer } from "#server/databaseLayer.ts";
|
|
9
8
|
import type { HostOptions, HostPolicy } from "#server/hostOptions.ts";
|
|
10
9
|
|
|
11
10
|
export class AppChanges extends Context.Service<AppChanges, Effect.Success<typeof makeLiveServer>>()("@shivaedev/platform/AppChanges") {}
|
|
12
11
|
export interface AppDatabaseOptions<R = never> {
|
|
13
|
-
readonly config?:
|
|
14
|
-
readonly databaseUrl?: Redacted.Redacted<string>;
|
|
15
|
-
readonly applicationName?: string;
|
|
16
|
-
readonly maxConnections?: number;
|
|
17
|
-
readonly changes?: Omit<PostgresChangesOptions, "client" | "resync">;
|
|
18
|
-
};
|
|
12
|
+
readonly config?: DatabaseConfig;
|
|
19
13
|
readonly migrations: {
|
|
20
14
|
readonly loader: Migrator.Loader<R>;
|
|
21
15
|
readonly mode?: "migrate" | "check";
|
|
@@ -81,30 +75,35 @@ export function appHost<
|
|
|
81
75
|
TServiceRequirements = never,
|
|
82
76
|
TMigrations = never,
|
|
83
77
|
TSession extends SessionShape = SessionShape,
|
|
78
|
+
TApplicationError = never,
|
|
79
|
+
TApplicationRequirements = never,
|
|
84
80
|
>(
|
|
85
81
|
options:
|
|
82
|
+
| (AppDatabaseOptions<TMigrations> & {
|
|
83
|
+
readonly application: Effect.Effect<
|
|
84
|
+
AppHttpHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TSession>,
|
|
85
|
+
TApplicationError,
|
|
86
|
+
TApplicationRequirements
|
|
87
|
+
>;
|
|
88
|
+
})
|
|
86
89
|
| AppHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TMigrations, TSession>
|
|
87
90
|
| AppLocalHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TMigrations>,
|
|
88
91
|
): ReturnType<
|
|
89
|
-
typeof
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
readonly sessions?: never;
|
|
103
|
-
readonly migrations?: undefined;
|
|
104
|
-
},
|
|
105
|
-
): ReturnType<
|
|
106
|
-
typeof appHostHttp<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, SessionShape>
|
|
92
|
+
typeof deferredHost<
|
|
93
|
+
TRpcs,
|
|
94
|
+
THandlers,
|
|
95
|
+
THandlerError,
|
|
96
|
+
THandlerRequirements,
|
|
97
|
+
TServices,
|
|
98
|
+
TServiceError,
|
|
99
|
+
TServiceRequirements,
|
|
100
|
+
TMigrations,
|
|
101
|
+
TSession,
|
|
102
|
+
TApplicationError,
|
|
103
|
+
TApplicationRequirements
|
|
104
|
+
>
|
|
107
105
|
>;
|
|
106
|
+
|
|
108
107
|
export function appHost<
|
|
109
108
|
TRpcs extends Rpc.Any,
|
|
110
109
|
THandlers,
|
|
@@ -127,12 +126,24 @@ export function appHost<
|
|
|
127
126
|
TServiceRequirements = never,
|
|
128
127
|
TMigrations = never,
|
|
129
128
|
TSession extends SessionShape = SessionShape,
|
|
129
|
+
TApplicationError = never,
|
|
130
|
+
TApplicationRequirements = never,
|
|
130
131
|
>(
|
|
131
132
|
options:
|
|
133
|
+
| (AppDatabaseOptions<TMigrations> & {
|
|
134
|
+
readonly application: Effect.Effect<
|
|
135
|
+
AppHttpHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TSession>,
|
|
136
|
+
TApplicationError,
|
|
137
|
+
TApplicationRequirements
|
|
138
|
+
>;
|
|
139
|
+
})
|
|
132
140
|
| AppHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TMigrations, TSession>
|
|
133
141
|
| AppLocalHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TMigrations>
|
|
134
142
|
| AppHttpHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TSession>,
|
|
135
143
|
) {
|
|
144
|
+
if ("application" in options) {
|
|
145
|
+
return deferredHost(options.application, appDatabase(options));
|
|
146
|
+
}
|
|
136
147
|
return options.migrations === undefined
|
|
137
148
|
? appHostHttp(options)
|
|
138
149
|
: migratedHost({ ...options, migrations: options.migrations }, appDatabase({ ...options, migrations: options.migrations }));
|
|
@@ -3,7 +3,7 @@ import { NodeHttpServer, NodeServices } from "@effect/platform-node";
|
|
|
3
3
|
import { ByteSize, Config, Effect, Layer, Option, Schema } from "effect";
|
|
4
4
|
import { HttpIncomingMessage, HttpRouter, HttpServerRequest, HttpStaticServer } from "effect/http";
|
|
5
5
|
import { type Rpc, RpcSerialization, RpcServer } from "effect/rpc";
|
|
6
|
-
import type { AppHostOptions, AppLocalHostOptions } from "#appHost.ts";
|
|
6
|
+
import type { AppHostOptions, AppHttpHostOptions, AppLocalHostOptions } from "#appHost.ts";
|
|
7
7
|
import { boundedRpcRequest } from "#boundedRpcRequest.ts";
|
|
8
8
|
import type { databaseLayer } from "#databaseLayer.ts";
|
|
9
9
|
import type { HostOptions, HostPolicy } from "#hostOptions.ts";
|
|
@@ -103,3 +103,26 @@ export function migratedHost<
|
|
|
103
103
|
const services = Layer.mergeAll(options.services ?? Layer.empty);
|
|
104
104
|
return appHostHttp({ ...options, services: services.pipe(Layer.provideMerge(database)) });
|
|
105
105
|
}
|
|
106
|
+
|
|
107
|
+
export function deferredHost<
|
|
108
|
+
TRpcs extends Rpc.Any,
|
|
109
|
+
THandlers,
|
|
110
|
+
THandlerError,
|
|
111
|
+
THandlerRequirements,
|
|
112
|
+
TServices,
|
|
113
|
+
TServiceError,
|
|
114
|
+
TServiceRequirements,
|
|
115
|
+
TMigrations,
|
|
116
|
+
TSession extends SessionShape,
|
|
117
|
+
TApplicationError,
|
|
118
|
+
TApplicationRequirements,
|
|
119
|
+
>(
|
|
120
|
+
application: Effect.Effect<
|
|
121
|
+
AppHttpHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TSession>,
|
|
122
|
+
TApplicationError,
|
|
123
|
+
TApplicationRequirements
|
|
124
|
+
>,
|
|
125
|
+
database: ReturnType<typeof databaseLayer<TMigrations>>,
|
|
126
|
+
) {
|
|
127
|
+
return Layer.unwrap(Effect.map(application, (options) => appHostHttp(options))).pipe(Layer.provideMerge(database));
|
|
128
|
+
}
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import * as PgClient from "@effect/sql-pg/PgClient";
|
|
2
|
-
import { Config, Effect, Layer } from "effect";
|
|
2
|
+
import { Config, Effect, Layer, type Redacted } from "effect";
|
|
3
3
|
import * as Reactivity from "effect/reactivity/Reactivity";
|
|
4
4
|
import { makeLiveServer } from "@shivaedev/effect-contract/makeLiveServer.ts";
|
|
5
5
|
import { assertPostgresMigrations } from "@shivaedev/effect-sql/assertPostgresMigrations.ts";
|
|
6
6
|
import { migratePostgres } from "@shivaedev/effect-sql/migrations.ts";
|
|
7
|
-
import { postgresChanges } from "@shivaedev/effect-sql/postgresChanges.ts";
|
|
7
|
+
import { type PostgresChangesOptions, postgresChanges } from "@shivaedev/effect-sql/postgresChanges.ts";
|
|
8
8
|
import type { AppChanges, AppDatabaseOptions } from "#server/appHost.ts";
|
|
9
9
|
|
|
10
|
+
export interface DatabaseConfig {
|
|
11
|
+
readonly applicationName?: string;
|
|
12
|
+
readonly changes?: Omit<PostgresChangesOptions, "client" | "resync">;
|
|
13
|
+
readonly databaseUrl?: Redacted.Redacted<string>;
|
|
14
|
+
readonly maxConnections?: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
10
17
|
export function databaseLayer<R>(options: AppDatabaseOptions<R>, changesService: typeof AppChanges) {
|
|
11
18
|
const pool = Layer.unwrap(
|
|
12
19
|
Effect.gen(function* () {
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Effect, Layer } from "effect";
|
|
2
|
+
import { FetchHttpClient, HttpClient } from "effect/http";
|
|
3
|
+
import { redactOtlpText } from "#safeOtlpSerialization.ts";
|
|
4
|
+
|
|
5
|
+
export const otlpHttpClient = Layer.effect(
|
|
6
|
+
HttpClient.HttpClient,
|
|
7
|
+
Effect.gen(function* () {
|
|
8
|
+
const client = yield* HttpClient.HttpClient;
|
|
9
|
+
let warned = false;
|
|
10
|
+
function warnOnce(diagnostic: Effect.Effect<Record<string, unknown>>) {
|
|
11
|
+
return Effect.suspend(() => {
|
|
12
|
+
if (warned) {
|
|
13
|
+
return Effect.void;
|
|
14
|
+
}
|
|
15
|
+
warned = true;
|
|
16
|
+
return Effect.flatMap(diagnostic, (annotations) => Effect.logWarning("OTLP trace export failed").pipe(Effect.annotateLogs(annotations)));
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
return client.pipe(
|
|
20
|
+
HttpClient.tap((response) => {
|
|
21
|
+
if (response.status >= 200 && response.status < 300) {
|
|
22
|
+
warned = false;
|
|
23
|
+
return Effect.void;
|
|
24
|
+
}
|
|
25
|
+
return warnOnce(
|
|
26
|
+
response.text.pipe(
|
|
27
|
+
Effect.orElseSucceed(() => "Unable to read collector response"),
|
|
28
|
+
Effect.map((body) => ({ "otlp.response": redactOtlpText(body), "otlp.status": response.status })),
|
|
29
|
+
),
|
|
30
|
+
);
|
|
31
|
+
}),
|
|
32
|
+
HttpClient.tapError((error) => warnOnce(Effect.succeed({ "otlp.failure": error.reason._tag }))),
|
|
33
|
+
);
|
|
34
|
+
}),
|
|
35
|
+
).pipe(Layer.provide(FetchHttpClient.layer));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Config, Effect, Layer, Schema } from "effect";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { OtlpSerialization, OtlpTracer } from "effect/observability";
|
|
3
|
+
import { otlpHttpClient } from "#otlpHttpClient.ts";
|
|
4
4
|
import { safeOtlpSerialization } from "#safeOtlpSerialization.ts";
|
|
5
5
|
|
|
6
6
|
export const otlpTracing: Layer.Layer<never, Config.ConfigError> = Layer.unwrap(
|
|
@@ -19,16 +19,26 @@ export const otlpTracing: Layer.Layer<never, Config.ConfigError> = Layer.unwrap(
|
|
|
19
19
|
if (endpoint === undefined) {
|
|
20
20
|
return Layer.empty;
|
|
21
21
|
}
|
|
22
|
+
const configuredProtocol = yield* Config.String("OTEL_EXPORTER_OTLP_TRACES_PROTOCOL").pipe(
|
|
23
|
+
Config.orElse(() => Config.String("OTEL_EXPORTER_OTLP_PROTOCOL")),
|
|
24
|
+
Config.withDefault("http/protobuf"),
|
|
25
|
+
);
|
|
26
|
+
const protocol = yield* Schema.decodeUnknownEffect(Schema.Literals(["http/protobuf", "http/json"]), { reportInput: true })(
|
|
27
|
+
configuredProtocol,
|
|
28
|
+
).pipe(Effect.mapError((cause) => new Config.ConfigError(cause)));
|
|
22
29
|
const attributes: Record<string, string> = yield* Config.Record(
|
|
23
30
|
Schema.StringFromUriComponent,
|
|
24
31
|
Schema.StringFromUriComponent,
|
|
25
32
|
"OTEL_RESOURCE_ATTRIBUTES",
|
|
26
33
|
).pipe(Config.withDefault({}));
|
|
27
34
|
const serviceName = yield* Config.String("OTEL_SERVICE_NAME").pipe(Config.withDefault(attributes["service.name"] ?? "unknown_service"));
|
|
35
|
+
const serviceVersion = yield* Config.String("OTEL_SERVICE_VERSION").pipe(Config.withDefault(undefined));
|
|
28
36
|
const headers = yield* Config.Record(Schema.String, Schema.StringFromUriComponent, "OTEL_EXPORTER_OTLP_HEADERS").pipe(Config.withDefault({}));
|
|
29
|
-
return OtlpTracer.layer({ headers, resource: { attributes, serviceName }, url: endpoint.toString() }).pipe(
|
|
30
|
-
Layer.provide(
|
|
31
|
-
|
|
37
|
+
return OtlpTracer.layer({ headers, resource: { attributes, serviceName, serviceVersion }, url: endpoint.toString() }).pipe(
|
|
38
|
+
Layer.provide(
|
|
39
|
+
safeOtlpSerialization.pipe(Layer.provide(protocol === "http/protobuf" ? OtlpSerialization.layerProtobuf : OtlpSerialization.layerJson)),
|
|
40
|
+
),
|
|
41
|
+
Layer.provide(otlpHttpClient),
|
|
32
42
|
);
|
|
33
43
|
}),
|
|
34
44
|
);
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { REDACTED } from "#rpc-server/sensitive.ts";
|
|
2
|
+
|
|
3
|
+
function query(value: string): string {
|
|
4
|
+
return value
|
|
5
|
+
.split("&")
|
|
6
|
+
.map((part) => (part === "" ? part : `${part.split("=", 1)[0]}=${REDACTED}`))
|
|
7
|
+
.join("&");
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function url(value: string): string {
|
|
11
|
+
const fragment = value.indexOf("#");
|
|
12
|
+
const target = fragment === -1 ? value : value.slice(0, fragment);
|
|
13
|
+
const separator = target.indexOf("?");
|
|
14
|
+
return (
|
|
15
|
+
(separator === -1 ? target : `${target.slice(0, separator + 1)}${query(target.slice(separator + 1))}`).replaceAll(
|
|
16
|
+
/(?<authority>(?:\b[a-z][a-z0-9+.-]*:)?\/\/)[^/?#]*@/giu,
|
|
17
|
+
`$<authority>${REDACTED}@`,
|
|
18
|
+
) + (fragment === -1 ? "" : `#${REDACTED}`)
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function structured(value: string): string | undefined {
|
|
23
|
+
try {
|
|
24
|
+
return JSON.stringify(JSON.parse(value, (key: string, item: unknown) => (typeof item === "string" ? redactOtlpUrl(item, key) : item)));
|
|
25
|
+
} catch {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function redactOtlpUrl(value: string, key = ""): string {
|
|
31
|
+
if (/(?:^|[._-])(?:fragment|userinfo|username|password)$/iu.test(key)) {
|
|
32
|
+
return REDACTED;
|
|
33
|
+
}
|
|
34
|
+
if (/(?:^|[._-])query$/iu.test(key)) {
|
|
35
|
+
return url(`?${value}`).slice(1);
|
|
36
|
+
}
|
|
37
|
+
if (/(?:^|[._-])(?:url|uri|target)(?:$|[._-])/iu.test(key) || /(?:^|[._-])(?:referer|referrer|location|origin)$/iu.test(key)) {
|
|
38
|
+
return url(value);
|
|
39
|
+
}
|
|
40
|
+
if (/^\s*[[{]/u.test(value)) {
|
|
41
|
+
const redacted = structured(value);
|
|
42
|
+
if (redacted !== undefined) {
|
|
43
|
+
return redacted;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Quotes and whitespace can belong to secret values, so free text has no safe closing delimiter.
|
|
47
|
+
return value.replaceAll(/(?:[a-z][a-z0-9+.-]*:\/\/|[/?#]).*/gisu, url);
|
|
48
|
+
}
|
|
@@ -1,50 +1,63 @@
|
|
|
1
|
-
import { Layer } from "effect";
|
|
2
|
-
import { HttpBody } from "effect/http";
|
|
1
|
+
import { Effect, Layer } from "effect";
|
|
3
2
|
import type { OtlpResource } from "effect/observability";
|
|
4
3
|
import { OtlpSerialization } from "effect/observability";
|
|
4
|
+
import { redactOtlpUrl } from "#redactOtlpUrl.ts";
|
|
5
5
|
import { isSensitiveKey, REDACTED, redactText } from "#rpc-server/sensitive.ts";
|
|
6
6
|
|
|
7
7
|
function sensitive(key: string) {
|
|
8
8
|
return isSensitiveKey(key) || ["db.user", "db.user.name", "db.connection_string"].includes(key.toLowerCase());
|
|
9
9
|
}
|
|
10
|
-
function
|
|
11
|
-
return redactText(value,
|
|
10
|
+
export function redactOtlpText(value: string, key = "") {
|
|
11
|
+
return redactText(redactOtlpUrl(value, key), sensitive);
|
|
12
12
|
}
|
|
13
|
-
function attributeValue(value: OtlpResource.AnyValue): OtlpResource.AnyValue {
|
|
13
|
+
function attributeValue(value: OtlpResource.AnyValue, key: string): OtlpResource.AnyValue {
|
|
14
14
|
return {
|
|
15
15
|
...value,
|
|
16
|
-
...(typeof value.stringValue === "string" ? { stringValue:
|
|
17
|
-
...(value.arrayValue ? { arrayValue: { values: value.arrayValue.values.map(attributeValue) } } : {}),
|
|
16
|
+
...(typeof value.stringValue === "string" ? { stringValue: redactOtlpText(value.stringValue, key) } : {}),
|
|
17
|
+
...(value.arrayValue ? { arrayValue: { values: value.arrayValue.values.map((item) => attributeValue(item, key)) } } : {}),
|
|
18
18
|
...(value.kvlistValue ? { kvlistValue: { values: attributes(value.kvlistValue.values) } } : {}),
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
21
|
function attributes(values: OtlpResource.KeyValue[]): OtlpResource.KeyValue[] {
|
|
22
22
|
return values.map(({ key, value }) => ({
|
|
23
23
|
key,
|
|
24
|
-
value: sensitive(key) ? { stringValue: REDACTED } : attributeValue(value),
|
|
24
|
+
value: sensitive(key) ? { stringValue: REDACTED } : attributeValue(value, key),
|
|
25
25
|
}));
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
28
|
+
function spanName(span: { readonly name: string; readonly kind: number; readonly attributes: OtlpResource.KeyValue[] }) {
|
|
29
|
+
if (span.kind === 2) {
|
|
30
|
+
const method = span.attributes.find(({ key }) => key === "http.request.method")?.value.stringValue;
|
|
31
|
+
const route = span.attributes.find(({ key }) => key === "http.route")?.value.stringValue;
|
|
32
|
+
if (typeof method === "string") {
|
|
33
|
+
return typeof route === "string" ? `${method} ${route}` : method;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return span.name;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const safeOtlpSerialization = Layer.effect(
|
|
40
|
+
OtlpSerialization.OtlpSerialization,
|
|
41
|
+
Effect.map(OtlpSerialization.OtlpSerialization, (serialization) => ({
|
|
42
|
+
...serialization,
|
|
43
|
+
traces: (data) =>
|
|
44
|
+
serialization.traces({
|
|
45
|
+
...data,
|
|
46
|
+
resourceSpans: data.resourceSpans.map((resource) => ({
|
|
47
|
+
...resource,
|
|
48
|
+
resource: { ...resource.resource, attributes: attributes(resource.resource.attributes) },
|
|
49
|
+
scopeSpans: resource.scopeSpans.map((scope) => ({
|
|
50
|
+
...scope,
|
|
51
|
+
spans: scope.spans.map((span) => ({
|
|
52
|
+
...span,
|
|
53
|
+
attributes: attributes(span.attributes),
|
|
54
|
+
events: span.events.map((event) => ({ ...event, attributes: attributes(event.attributes), name: redactOtlpText(event.name) })),
|
|
55
|
+
links: span.links.map((link) => ({ ...link, attributes: attributes(link.attributes) })),
|
|
56
|
+
name: redactOtlpText(spanName(span)),
|
|
57
|
+
status: { ...span.status, ...(span.status.message === undefined ? {} : { message: redactOtlpText(span.status.message) }) },
|
|
58
|
+
})),
|
|
46
59
|
})),
|
|
47
60
|
})),
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
|
|
61
|
+
}),
|
|
62
|
+
})),
|
|
63
|
+
);
|