domainkit 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -12
- package/dist/canonical-json-CQYKsZw7.mjs +310 -0
- package/dist/canonical-json-CQYKsZw7.mjs.map +1 -0
- package/dist/connect-10vHuShV.d.mts +1401 -0
- package/dist/connect-oI8hcMxc.mjs +185 -0
- package/dist/connect-oI8hcMxc.mjs.map +1 -0
- package/dist/connection-C0xsU41C.d.mts +186 -0
- package/dist/connection-api-DW7xUJdj.d.mts +26 -0
- package/dist/index.d.mts +7 -26
- package/dist/index.mjs +12 -5
- package/dist/index.mjs.map +1 -1
- package/dist/managed-dns-connections-C3A_GBaz.mjs +99 -0
- package/dist/managed-dns-connections-C3A_GBaz.mjs.map +1 -0
- package/dist/promise.d.mts +104 -223
- package/dist/promise.mjs +45 -126
- package/dist/promise.mjs.map +1 -1
- package/dist/{resolver-tZU6gEVq.mjs → resolver-DPJs8h0a.mjs} +54 -250
- package/dist/resolver-DPJs8h0a.mjs.map +1 -0
- package/dist/{resolver-BGBLnPjJ.d.mts → resolver-DRrLm_hB.d.mts} +911 -1140
- package/dist/server.d.mts +128 -0
- package/dist/server.mjs +319 -0
- package/dist/server.mjs.map +1 -0
- package/dist/testing.d.mts +5 -4
- package/dist/testing.mjs +13 -18
- package/dist/testing.mjs.map +1 -1
- package/dist/{verify-6xK05pwL.d.mts → verify-C3V_GtzL.d.mts} +45 -20
- package/dist/{verify-B2fPyjde.mjs → verify-DDnK8U7C.mjs} +138 -323
- package/dist/verify-DDnK8U7C.mjs.map +1 -0
- package/package.json +8 -2
- package/dist/resolver-tZU6gEVq.mjs.map +0 -1
- package/dist/verify-B2fPyjde.mjs.map +0 -1
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { O as Service, a as Continuation, l as InteractiveFlow } from "./connect-10vHuShV.mjs";
|
|
2
|
+
import "./connection-api-DW7xUJdj.mjs";
|
|
3
|
+
import { i as AsyncInterface, t as InteractiveFlow$1 } from "./connection-C0xsU41C.mjs";
|
|
4
|
+
import { Context, Crypto, Effect, Layer, Schema } from "effect";
|
|
5
|
+
declare namespace index_d_exports {
|
|
6
|
+
export { AsyncConnectionPolicy, AsyncIdentity, AsyncInteractiveFlow, AsyncInteractiveProvider, AsyncPendingAuthorizations, AuthorizationReuseInput, Configuration, ConnectionPolicy, ConnectionPolicyInterface, CreateDomainKitOptions, DEFAULT_BASE_PATH, Error, Handler, Identity, IdentityInterface, InteractiveFlowInput, InteractiveProvider, Interface, PendingAuthorization, PendingAuthorizationContext, PendingAuthorizations, PendingAuthorizationsInterface, Principal, Providers, ProvidersInterface, WebHandler, createDomainKit, layer, make, providersLayer, toWebHandler };
|
|
7
|
+
}
|
|
8
|
+
declare const DEFAULT_BASE_PATH = "/api/domainkit";
|
|
9
|
+
declare const Error_base: Schema.Class<Error, Schema.TaggedStruct<"DomainKitServerError", {
|
|
10
|
+
readonly category: Schema.Literals<readonly ["authentication", "authorization", "configuration", "provider", "request", "storage"]>;
|
|
11
|
+
readonly message: Schema.String;
|
|
12
|
+
readonly operation: Schema.String;
|
|
13
|
+
readonly retry: Schema.Literals<readonly ["never", "after-user-action", "safe", "unknown"]>;
|
|
14
|
+
}>, import("effect/Cause").YieldableError>;
|
|
15
|
+
declare class Error extends Error_base {}
|
|
16
|
+
interface Principal {
|
|
17
|
+
readonly authorizedById: string;
|
|
18
|
+
readonly ownerId: string;
|
|
19
|
+
}
|
|
20
|
+
interface IdentityInterface {
|
|
21
|
+
readonly authenticate: (request: Request) => Effect.Effect<Principal, Error>;
|
|
22
|
+
}
|
|
23
|
+
declare const Identity_base: Context.ServiceClass<Identity, "@domainkit/server/Identity", IdentityInterface>;
|
|
24
|
+
declare class Identity extends Identity_base {}
|
|
25
|
+
interface AuthorizationReuseInput {
|
|
26
|
+
readonly authorizationId: string;
|
|
27
|
+
readonly domain: string | undefined;
|
|
28
|
+
readonly method: "integration" | "oauth2";
|
|
29
|
+
readonly principal: Principal;
|
|
30
|
+
readonly providerId: string;
|
|
31
|
+
}
|
|
32
|
+
interface ConnectionPolicyInterface {
|
|
33
|
+
readonly authorizeReuse: (input: AuthorizationReuseInput) => Effect.Effect<void, Error>;
|
|
34
|
+
}
|
|
35
|
+
declare const ConnectionPolicy_base: Context.ServiceClass<ConnectionPolicy, "@domainkit/server/ConnectionPolicy", ConnectionPolicyInterface>;
|
|
36
|
+
/** Host authorization boundary for reusing an existing provider authorization. */
|
|
37
|
+
declare class ConnectionPolicy extends ConnectionPolicy_base {}
|
|
38
|
+
interface InteractiveFlowInput {
|
|
39
|
+
readonly callbackUrl: URL;
|
|
40
|
+
readonly domain: string | undefined;
|
|
41
|
+
readonly method: "integration" | "oauth2";
|
|
42
|
+
readonly providerId: string;
|
|
43
|
+
}
|
|
44
|
+
interface ProvidersInterface {
|
|
45
|
+
readonly interactiveFlow: (input: InteractiveFlowInput) => Effect.Effect<InteractiveFlow, Error>;
|
|
46
|
+
}
|
|
47
|
+
declare const Providers_base: Context.ServiceClass<Providers, "@domainkit/server/Providers", ProvidersInterface>;
|
|
48
|
+
declare class Providers extends Providers_base {}
|
|
49
|
+
interface InteractiveProvider {
|
|
50
|
+
readonly create: (input: Omit<InteractiveFlowInput, "method" | "providerId">) => Effect.Effect<InteractiveFlow, Error>;
|
|
51
|
+
readonly method: "integration" | "oauth2";
|
|
52
|
+
readonly providerId: string;
|
|
53
|
+
}
|
|
54
|
+
/** Configure all interactive providers once at the host composition root. */
|
|
55
|
+
declare const providersLayer: (definitions: ReadonlyArray<InteractiveProvider>) => Layer.Layer<Providers>;
|
|
56
|
+
interface PendingAuthorizationContext {
|
|
57
|
+
readonly baseURL: string;
|
|
58
|
+
readonly domain: string | undefined;
|
|
59
|
+
readonly method: "integration" | "oauth2";
|
|
60
|
+
readonly providerId: string;
|
|
61
|
+
readonly returnTo: string;
|
|
62
|
+
}
|
|
63
|
+
interface PendingAuthorization {
|
|
64
|
+
readonly context: PendingAuthorizationContext;
|
|
65
|
+
readonly continuation: Continuation;
|
|
66
|
+
}
|
|
67
|
+
interface PendingAuthorizationsInterface {
|
|
68
|
+
readonly consume: (id: string, now: Date) => Effect.Effect<PendingAuthorization | null, Error>;
|
|
69
|
+
readonly get: (id: string, now: Date) => Effect.Effect<PendingAuthorization | null, Error>;
|
|
70
|
+
readonly put: (pending: PendingAuthorization) => Effect.Effect<void, Error>;
|
|
71
|
+
}
|
|
72
|
+
declare const PendingAuthorizations_base: Context.ServiceClass<PendingAuthorizations, "@domainkit/server/PendingAuthorizations", PendingAuthorizationsInterface>;
|
|
73
|
+
declare class PendingAuthorizations extends PendingAuthorizations_base {}
|
|
74
|
+
interface Configuration {
|
|
75
|
+
/** Public origin used to construct provider callbacks. Defaults to the incoming request origin. */
|
|
76
|
+
readonly baseURL?: string;
|
|
77
|
+
/** Catch-all mount path. */
|
|
78
|
+
readonly basePath?: string;
|
|
79
|
+
/** Relative same-origin destination used when a start request omits `returnTo`. */
|
|
80
|
+
readonly defaultReturnTo?: string;
|
|
81
|
+
}
|
|
82
|
+
interface AsyncIdentity {
|
|
83
|
+
readonly authenticate: (request: Request) => Promise<Principal>;
|
|
84
|
+
}
|
|
85
|
+
interface AsyncConnectionPolicy {
|
|
86
|
+
readonly authorizeReuse: (input: AuthorizationReuseInput) => Promise<void>;
|
|
87
|
+
}
|
|
88
|
+
type AsyncInteractiveFlow = InteractiveFlow$1;
|
|
89
|
+
interface AsyncInteractiveProvider {
|
|
90
|
+
readonly create: (input: Omit<InteractiveFlowInput, "method" | "providerId">) => Promise<AsyncInteractiveFlow>;
|
|
91
|
+
readonly method: "integration" | "oauth2";
|
|
92
|
+
readonly providerId: string;
|
|
93
|
+
}
|
|
94
|
+
interface AsyncPendingAuthorizations {
|
|
95
|
+
readonly consume: (id: string, now: Date) => Promise<PendingAuthorization | null>;
|
|
96
|
+
readonly get: (id: string, now: Date) => Promise<PendingAuthorization | null>;
|
|
97
|
+
readonly put: (pending: PendingAuthorization) => Promise<void>;
|
|
98
|
+
}
|
|
99
|
+
interface CreateDomainKitOptions extends Configuration {
|
|
100
|
+
readonly connectionPolicy: AsyncConnectionPolicy;
|
|
101
|
+
readonly identity: AsyncIdentity;
|
|
102
|
+
readonly pendingAuthorizations: AsyncPendingAuthorizations;
|
|
103
|
+
/** Host-owned Promise persistence. DomainKit does not initialize or dispose this resource. */
|
|
104
|
+
readonly persistence: AsyncInterface;
|
|
105
|
+
readonly providers: ReadonlyArray<AsyncInteractiveProvider>;
|
|
106
|
+
}
|
|
107
|
+
interface Interface {
|
|
108
|
+
readonly handle: (request: Request) => Effect.Effect<Response>;
|
|
109
|
+
}
|
|
110
|
+
declare const Handler_base: Context.ServiceClass<Handler, "@domainkit/server/Handler", Interface>;
|
|
111
|
+
declare class Handler extends Handler_base {}
|
|
112
|
+
/** Construct the Effect-native server handler from host-provided services. */
|
|
113
|
+
declare const make: (configuration?: Configuration) => Effect.Effect<Interface, never, ConnectionPolicy | Crypto.Crypto | Identity | PendingAuthorizations | Providers | Service>;
|
|
114
|
+
/** Provide the Effect-native server handler as a Layer. */
|
|
115
|
+
declare const layer: (configuration?: Configuration) => Layer.Layer<Handler, never, ConnectionPolicy | Crypto.Crypto | Identity | PendingAuthorizations | Providers | Service>;
|
|
116
|
+
interface WebHandler {
|
|
117
|
+
readonly dispose: () => Promise<void>;
|
|
118
|
+
readonly fetch: (request: Request) => Promise<Response>;
|
|
119
|
+
}
|
|
120
|
+
/** Build one reusable Web handler from a fully provided Effect server Layer. */
|
|
121
|
+
declare function toWebHandler<E>(serverLayer: Layer.Layer<Handler, E>): WebHandler;
|
|
122
|
+
/**
|
|
123
|
+
* Build a Web handler for async hosts. The host owns persistence setup, migrations, and disposal.
|
|
124
|
+
*/
|
|
125
|
+
declare function createDomainKit(options: CreateDomainKitOptions): Promise<WebHandler>;
|
|
126
|
+
//#endregion
|
|
127
|
+
export { index_d_exports as Server, createDomainKit };
|
|
128
|
+
//# sourceMappingURL=server.d.mts.map
|
package/dist/server.mjs
ADDED
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
|
+
import { i as webCryptoLayer, o as Error$1, s as Service } from "./canonical-json-CQYKsZw7.mjs";
|
|
3
|
+
import { a as start, i as complete, n as Method, t as Error$2 } from "./connect-oI8hcMxc.mjs";
|
|
4
|
+
import { t as layerFromAsync } from "./managed-dns-connections-C3A_GBaz.mjs";
|
|
5
|
+
import { Context, Crypto, Effect, Layer, ManagedRuntime, Schema } from "effect";
|
|
6
|
+
//#region src/server/index.ts
|
|
7
|
+
var server_exports = /* @__PURE__ */ __exportAll({
|
|
8
|
+
ConnectionPolicy: () => ConnectionPolicy,
|
|
9
|
+
DEFAULT_BASE_PATH: () => DEFAULT_BASE_PATH,
|
|
10
|
+
Error: () => Error,
|
|
11
|
+
Handler: () => Handler,
|
|
12
|
+
Identity: () => Identity,
|
|
13
|
+
PendingAuthorizations: () => PendingAuthorizations,
|
|
14
|
+
Providers: () => Providers,
|
|
15
|
+
createDomainKit: () => createDomainKit,
|
|
16
|
+
layer: () => layer,
|
|
17
|
+
make: () => make,
|
|
18
|
+
providersLayer: () => providersLayer,
|
|
19
|
+
toWebHandler: () => toWebHandler
|
|
20
|
+
});
|
|
21
|
+
const DEFAULT_BASE_PATH = "/api/domainkit";
|
|
22
|
+
var Error = class extends Schema.TaggedError()("DomainKitServerError", {
|
|
23
|
+
category: Schema.Literals([
|
|
24
|
+
"authentication",
|
|
25
|
+
"authorization",
|
|
26
|
+
"configuration",
|
|
27
|
+
"provider",
|
|
28
|
+
"request",
|
|
29
|
+
"storage"
|
|
30
|
+
]),
|
|
31
|
+
message: Schema.String,
|
|
32
|
+
operation: Schema.String,
|
|
33
|
+
retry: Schema.Literals([
|
|
34
|
+
"never",
|
|
35
|
+
"after-user-action",
|
|
36
|
+
"safe",
|
|
37
|
+
"unknown"
|
|
38
|
+
])
|
|
39
|
+
}) {};
|
|
40
|
+
var Identity = class extends Context.Service()("@domainkit/server/Identity") {};
|
|
41
|
+
/** Host authorization boundary for reusing an existing provider authorization. */
|
|
42
|
+
var ConnectionPolicy = class extends Context.Service()("@domainkit/server/ConnectionPolicy") {};
|
|
43
|
+
var Providers = class extends Context.Service()("@domainkit/server/Providers") {};
|
|
44
|
+
/** Configure all interactive providers once at the host composition root. */
|
|
45
|
+
const providersLayer = (definitions) => {
|
|
46
|
+
const providers = /* @__PURE__ */ new Map();
|
|
47
|
+
for (const definition of definitions) {
|
|
48
|
+
const key = `${definition.providerId}:${definition.method}`;
|
|
49
|
+
if (providers.has(key)) throw new globalThis.Error(`Interactive provider ${key} is configured more than once`);
|
|
50
|
+
providers.set(key, definition);
|
|
51
|
+
}
|
|
52
|
+
return Layer.succeed(Providers)({ interactiveFlow: (input) => {
|
|
53
|
+
const provider = providers.get(`${input.providerId}:${input.method}`);
|
|
54
|
+
return provider === void 0 ? Effect.fail(new Error({
|
|
55
|
+
category: "configuration",
|
|
56
|
+
message: `Interactive provider ${input.providerId}:${input.method} is not configured`,
|
|
57
|
+
operation: "Server.Providers.interactiveFlow",
|
|
58
|
+
retry: "never"
|
|
59
|
+
})) : provider.create({
|
|
60
|
+
callbackUrl: input.callbackUrl,
|
|
61
|
+
domain: input.domain
|
|
62
|
+
});
|
|
63
|
+
} });
|
|
64
|
+
};
|
|
65
|
+
var PendingAuthorizations = class extends Context.Service()("@domainkit/server/PendingAuthorizations") {};
|
|
66
|
+
var Handler = class extends Context.Service()("@domainkit/server/Handler") {};
|
|
67
|
+
const requestError = (operation, message) => new Error({
|
|
68
|
+
category: "request",
|
|
69
|
+
message,
|
|
70
|
+
operation,
|
|
71
|
+
retry: "after-user-action"
|
|
72
|
+
});
|
|
73
|
+
const connectionError = (operation, cause) => new Error$2({
|
|
74
|
+
category: cause.category === "provider" ? "provider" : "authorization",
|
|
75
|
+
message: cause.message,
|
|
76
|
+
operation,
|
|
77
|
+
retry: cause.retry
|
|
78
|
+
});
|
|
79
|
+
const serverError = (operation, cause) => {
|
|
80
|
+
if (cause instanceof Error) return cause;
|
|
81
|
+
if (cause instanceof Error$2) return new Error({
|
|
82
|
+
category: cause.operation.startsWith("Server.pending.") ? "storage" : cause.category === "provider" ? "provider" : "request",
|
|
83
|
+
message: cause.message,
|
|
84
|
+
operation,
|
|
85
|
+
retry: cause.retry
|
|
86
|
+
});
|
|
87
|
+
if (cause instanceof Error$1) return new Error({
|
|
88
|
+
category: "storage",
|
|
89
|
+
message: cause.message,
|
|
90
|
+
operation,
|
|
91
|
+
retry: cause.retry
|
|
92
|
+
});
|
|
93
|
+
return new Error({
|
|
94
|
+
category: "provider",
|
|
95
|
+
message: cause instanceof globalThis.Error ? cause.message : "Domain connection failed",
|
|
96
|
+
operation,
|
|
97
|
+
retry: "unknown"
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
const normalizeBasePath = (input) => {
|
|
101
|
+
const path = input ?? "/api/domainkit";
|
|
102
|
+
if (!path.startsWith("/") || path.includes("?") || path.includes("#")) throw new globalThis.Error("DomainKit server basePath must be an absolute path");
|
|
103
|
+
if (path === "/") return "";
|
|
104
|
+
return path.endsWith("/") ? path.slice(0, -1) : path;
|
|
105
|
+
};
|
|
106
|
+
const configuredBaseUrl = (input) => {
|
|
107
|
+
if (input === void 0) return void 0;
|
|
108
|
+
const url = new URL(input);
|
|
109
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") throw new globalThis.Error("DomainKit server baseURL must use http or https");
|
|
110
|
+
url.pathname = "/";
|
|
111
|
+
url.search = "";
|
|
112
|
+
url.hash = "";
|
|
113
|
+
return url;
|
|
114
|
+
};
|
|
115
|
+
const canonicalReturnTo = Effect.fn("Server.canonicalReturnTo")((input, baseUrl) => Effect.try({
|
|
116
|
+
try: () => new URL(input, baseUrl),
|
|
117
|
+
catch: () => requestError("Server.start", "returnTo must be a valid application URL")
|
|
118
|
+
}).pipe(Effect.filterOrFail((target) => target.origin === baseUrl.origin, () => requestError("Server.start", "returnTo must stay on the configured application origin")), Effect.map((target) => `${target.pathname}${target.search}${target.hash}`)));
|
|
119
|
+
const parseStartInput = Effect.fn("Server.parseStartInput")((request) => Effect.tryPromise({
|
|
120
|
+
try: () => request.json(),
|
|
121
|
+
catch: () => requestError("Server.start", "Request body must be valid JSON")
|
|
122
|
+
}).pipe(Effect.flatMap((input) => {
|
|
123
|
+
if (typeof input !== "object" || input === null) return Effect.fail(requestError("Server.start", "Request body must be an object"));
|
|
124
|
+
const value = input;
|
|
125
|
+
if (typeof value.providerId !== "string" || !/^[a-z0-9][a-z0-9._-]*$/.test(value.providerId) || value.method !== "oauth2" && value.method !== "integration" || value.domain !== void 0 && typeof value.domain !== "string" || value.returnTo !== void 0 && typeof value.returnTo !== "string" || value.authorizationId !== void 0 && typeof value.authorizationId !== "string") return Effect.fail(requestError("Server.start", "providerId and a supported interactive method are required"));
|
|
126
|
+
return Effect.succeed({
|
|
127
|
+
...value.authorizationId === void 0 ? {} : { authorizationId: value.authorizationId },
|
|
128
|
+
...value.domain === void 0 ? {} : { domain: value.domain },
|
|
129
|
+
method: value.method,
|
|
130
|
+
providerId: value.providerId,
|
|
131
|
+
...value.returnTo === void 0 ? {} : { returnTo: value.returnTo }
|
|
132
|
+
});
|
|
133
|
+
})));
|
|
134
|
+
const errorStatus = (cause) => {
|
|
135
|
+
switch (cause.category) {
|
|
136
|
+
case "authentication": return 401;
|
|
137
|
+
case "authorization": return 403;
|
|
138
|
+
case "request": return 400;
|
|
139
|
+
case "storage": return 503;
|
|
140
|
+
case "configuration": return 500;
|
|
141
|
+
case "provider": return cause.retry === "safe" || cause.retry === "unknown" ? 502 : 400;
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
const jsonError = (cause) => Response.json({ error: {
|
|
145
|
+
category: cause.category,
|
|
146
|
+
message: cause.message,
|
|
147
|
+
operation: cause.operation,
|
|
148
|
+
retry: cause.retry
|
|
149
|
+
} }, { status: errorStatus(cause) });
|
|
150
|
+
/** Construct the Effect-native server handler from host-provided services. */
|
|
151
|
+
const make = (configuration = {}) => Effect.gen(function* () {
|
|
152
|
+
const identity = yield* Identity;
|
|
153
|
+
const policy = yield* ConnectionPolicy;
|
|
154
|
+
const providers = yield* Providers;
|
|
155
|
+
const pending = yield* PendingAuthorizations;
|
|
156
|
+
const repository = yield* Service;
|
|
157
|
+
const crypto = yield* Crypto.Crypto;
|
|
158
|
+
const basePath = normalizeBasePath(configuration.basePath);
|
|
159
|
+
const fixedBaseUrl = configuredBaseUrl(configuration.baseURL);
|
|
160
|
+
const defaultReturnTo = configuration.defaultReturnTo ?? "/";
|
|
161
|
+
const withCore = (effect) => effect.pipe(Effect.provideService(Service, repository), Effect.provideService(Crypto.Crypto, crypto));
|
|
162
|
+
const start$1 = Effect.fn("Server.start")(function* (request) {
|
|
163
|
+
const principal = yield* identity.authenticate(request);
|
|
164
|
+
const input = yield* parseStartInput(request);
|
|
165
|
+
if (input.authorizationId !== void 0) yield* policy.authorizeReuse({
|
|
166
|
+
authorizationId: input.authorizationId,
|
|
167
|
+
domain: input.domain,
|
|
168
|
+
method: input.method,
|
|
169
|
+
principal,
|
|
170
|
+
providerId: input.providerId
|
|
171
|
+
});
|
|
172
|
+
const requestUrl = new URL(request.url);
|
|
173
|
+
const baseUrl = fixedBaseUrl ?? new URL(requestUrl.origin);
|
|
174
|
+
const callbackUrl = new URL(`${basePath}/callback/${encodeURIComponent(input.providerId)}`, baseUrl);
|
|
175
|
+
const returnTo = yield* canonicalReturnTo(input.returnTo ?? defaultReturnTo, baseUrl);
|
|
176
|
+
const flow = yield* providers.interactiveFlow({
|
|
177
|
+
callbackUrl,
|
|
178
|
+
domain: input.domain,
|
|
179
|
+
method: input.method,
|
|
180
|
+
providerId: input.providerId
|
|
181
|
+
});
|
|
182
|
+
if (flow.providerId !== input.providerId || flow.method !== input.method) return yield* requestError("Server.start", "Configured provider flow does not match the requested provider and method");
|
|
183
|
+
const continuations = {
|
|
184
|
+
consume: () => Effect.succeed(null),
|
|
185
|
+
put: (continuation) => pending.put({
|
|
186
|
+
context: {
|
|
187
|
+
baseURL: baseUrl.origin,
|
|
188
|
+
domain: input.domain,
|
|
189
|
+
method: input.method,
|
|
190
|
+
providerId: input.providerId,
|
|
191
|
+
returnTo
|
|
192
|
+
},
|
|
193
|
+
continuation
|
|
194
|
+
}).pipe(Effect.mapError((cause) => connectionError("Server.pending.put", cause)))
|
|
195
|
+
};
|
|
196
|
+
const result = yield* withCore(start({
|
|
197
|
+
authorizedById: principal.authorizedById,
|
|
198
|
+
...input.authorizationId === void 0 ? {} : { authorizationId: input.authorizationId },
|
|
199
|
+
method: Method.Interactive({
|
|
200
|
+
continuations,
|
|
201
|
+
flow
|
|
202
|
+
}),
|
|
203
|
+
ownerId: principal.ownerId
|
|
204
|
+
}));
|
|
205
|
+
if (result._tag !== "Redirect") return yield* requestError("Server.start", "Interactive connection did not redirect");
|
|
206
|
+
return Response.json({
|
|
207
|
+
authorizationUrl: result.authorizationUrl.toString(),
|
|
208
|
+
continuationId: result.continuationId
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
const complete$1 = Effect.fn("Server.complete")(function* (request, providerId) {
|
|
212
|
+
const callbackUrl = new URL(request.url);
|
|
213
|
+
const continuationId = callbackUrl.searchParams.get("state");
|
|
214
|
+
if (continuationId === null || continuationId.length === 0) return yield* requestError("Server.complete", "Provider callback is missing state");
|
|
215
|
+
const now = /* @__PURE__ */ new Date();
|
|
216
|
+
const stored = yield* pending.get(continuationId, now);
|
|
217
|
+
if (stored === null) return yield* requestError("Server.complete", "Connection continuation is expired, unknown, or already consumed");
|
|
218
|
+
if (stored.context.providerId !== providerId) return yield* requestError("Server.complete", "Provider callback does not match its continuation");
|
|
219
|
+
const callbackBaseUrl = yield* Effect.try({
|
|
220
|
+
try: () => configuredBaseUrl(stored.context.baseURL),
|
|
221
|
+
catch: () => new Error({
|
|
222
|
+
category: "storage",
|
|
223
|
+
message: "Stored provider callback origin is invalid",
|
|
224
|
+
operation: "Server.complete",
|
|
225
|
+
retry: "never"
|
|
226
|
+
})
|
|
227
|
+
}).pipe(Effect.flatMap((value) => value === void 0 ? Effect.fail(new Error({
|
|
228
|
+
category: "storage",
|
|
229
|
+
message: "Stored provider callback origin is missing",
|
|
230
|
+
operation: "Server.complete",
|
|
231
|
+
retry: "never"
|
|
232
|
+
})) : Effect.succeed(value)));
|
|
233
|
+
if (fixedBaseUrl !== void 0 && callbackBaseUrl.origin !== fixedBaseUrl.origin) return yield* requestError("Server.complete", "Provider callback does not match the configured application origin");
|
|
234
|
+
const expectedCallback = new URL(`${basePath}/callback/${encodeURIComponent(providerId)}`, callbackBaseUrl);
|
|
235
|
+
if (callbackUrl.origin !== expectedCallback.origin || callbackUrl.pathname !== expectedCallback.pathname) return yield* requestError("Server.complete", "Provider callback URL is invalid");
|
|
236
|
+
const flow = yield* providers.interactiveFlow({
|
|
237
|
+
callbackUrl: expectedCallback,
|
|
238
|
+
domain: stored.context.domain,
|
|
239
|
+
method: stored.context.method,
|
|
240
|
+
providerId
|
|
241
|
+
});
|
|
242
|
+
if (flow.providerId !== providerId || flow.method !== stored.context.method) return yield* requestError("Server.complete", "Configured provider flow does not match the stored continuation");
|
|
243
|
+
const connection = yield* withCore(complete({
|
|
244
|
+
callbackUrl,
|
|
245
|
+
continuationId,
|
|
246
|
+
continuations: {
|
|
247
|
+
consume: (id, consumedAt) => pending.consume(id, consumedAt).pipe(Effect.map((value) => value?.continuation ?? null), Effect.mapError((cause) => connectionError("Server.pending.consume", cause))),
|
|
248
|
+
put: () => Effect.die("Callback continuation store cannot put")
|
|
249
|
+
},
|
|
250
|
+
flow
|
|
251
|
+
}));
|
|
252
|
+
const returnTo = yield* canonicalReturnTo(stored.context.returnTo, callbackBaseUrl);
|
|
253
|
+
const destination = new URL(returnTo, callbackBaseUrl);
|
|
254
|
+
destination.searchParams.set("domainkit", "connected");
|
|
255
|
+
destination.searchParams.set("connectionId", connection.id);
|
|
256
|
+
return new Response(null, {
|
|
257
|
+
headers: { location: destination.toString() },
|
|
258
|
+
status: 303
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
const handle = (request) => {
|
|
262
|
+
const url = new URL(request.url);
|
|
263
|
+
const callbackPrefix = `${basePath}/callback/`;
|
|
264
|
+
return (request.method === "POST" && url.pathname === `${basePath}/connection/start` ? start$1(request) : request.method === "GET" && url.pathname.startsWith(callbackPrefix) ? complete$1(request, url.pathname.slice(callbackPrefix.length)) : Effect.succeed(Response.json({ error: { message: "Not found" } }, { status: 404 }))).pipe(Effect.mapError((cause) => serverError("Server.handle", cause)), Effect.catch((cause) => Effect.succeed(jsonError(cause))));
|
|
265
|
+
};
|
|
266
|
+
return Handler.of({ handle });
|
|
267
|
+
});
|
|
268
|
+
/** Provide the Effect-native server handler as a Layer. */
|
|
269
|
+
const layer = (configuration = {}) => Layer.effect(Handler, make(configuration));
|
|
270
|
+
const fromPromise = (operation, category, evaluate) => Effect.tryPromise({
|
|
271
|
+
try: evaluate,
|
|
272
|
+
catch: (cause) => cause instanceof Error ? cause : new Error({
|
|
273
|
+
category,
|
|
274
|
+
message: cause instanceof globalThis.Error ? cause.message : String(cause),
|
|
275
|
+
operation,
|
|
276
|
+
retry: category === "storage" ? "safe" : "unknown"
|
|
277
|
+
})
|
|
278
|
+
});
|
|
279
|
+
const asyncProvidersLayer = (definitions) => providersLayer(definitions.map((definition) => ({
|
|
280
|
+
create: (input) => fromPromise("Server.Providers.interactiveFlow", "provider", () => definition.create(input)).pipe(Effect.map((flow) => ({
|
|
281
|
+
complete: (payload, callbackUrl) => fromPromise("Server.Provider.complete", "provider", () => flow.complete(payload, callbackUrl)).pipe(Effect.mapError((cause) => connectionError("Server.Provider.complete", cause))),
|
|
282
|
+
method: flow.method,
|
|
283
|
+
providerId: flow.providerId,
|
|
284
|
+
requiredCapabilities: flow.requiredCapabilities,
|
|
285
|
+
start: (continuationId) => fromPromise("Server.Provider.start", "provider", () => flow.start(continuationId)).pipe(Effect.mapError((cause) => connectionError("Server.Provider.start", cause)))
|
|
286
|
+
}))),
|
|
287
|
+
method: definition.method,
|
|
288
|
+
providerId: definition.providerId
|
|
289
|
+
})));
|
|
290
|
+
const asyncDependencies = (options) => Layer.mergeAll(Layer.succeed(Identity, { authenticate: (request) => fromPromise("Server.Identity.authenticate", "authentication", () => options.identity.authenticate(request)) }), Layer.succeed(ConnectionPolicy, { authorizeReuse: (input) => fromPromise("Server.ConnectionPolicy.authorizeReuse", "authorization", () => options.connectionPolicy.authorizeReuse(input)) }), asyncProvidersLayer(options.providers), Layer.succeed(PendingAuthorizations, {
|
|
291
|
+
consume: (id, now) => fromPromise("Server.PendingAuthorizations.consume", "storage", () => options.pendingAuthorizations.consume(id, now)),
|
|
292
|
+
get: (id, now) => fromPromise("Server.PendingAuthorizations.get", "storage", () => options.pendingAuthorizations.get(id, now)),
|
|
293
|
+
put: (pending) => fromPromise("Server.PendingAuthorizations.put", "storage", () => options.pendingAuthorizations.put(pending))
|
|
294
|
+
}), layerFromAsync(options.persistence), webCryptoLayer);
|
|
295
|
+
const webHandler = (runtime) => ({
|
|
296
|
+
dispose: () => runtime.dispose(),
|
|
297
|
+
fetch: (request) => runtime.runPromise(Effect.flatMap(Handler, (handler) => handler.handle(request)), { signal: request.signal })
|
|
298
|
+
});
|
|
299
|
+
/** Build one reusable Web handler from a fully provided Effect server Layer. */
|
|
300
|
+
function toWebHandler(serverLayer) {
|
|
301
|
+
return webHandler(ManagedRuntime.make(serverLayer));
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Build a Web handler for async hosts. The host owns persistence setup, migrations, and disposal.
|
|
305
|
+
*/
|
|
306
|
+
async function createDomainKit(options) {
|
|
307
|
+
const runtime = ManagedRuntime.make(layer(options).pipe(Layer.provide(asyncDependencies(options))));
|
|
308
|
+
try {
|
|
309
|
+
await runtime.context();
|
|
310
|
+
return webHandler(runtime);
|
|
311
|
+
} catch (cause) {
|
|
312
|
+
await runtime.dispose();
|
|
313
|
+
throw cause;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
//#endregion
|
|
317
|
+
export { server_exports as Server, createDomainKit };
|
|
318
|
+
|
|
319
|
+
//# sourceMappingURL=server.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.mjs","names":["Connection.Error","Lifecycle.Error","Lifecycle.Service","start","Connection.start","complete","Connection.complete","ManagedDnsConnections.layerFromAsync"],"sources":["../src/server/index.ts"],"sourcesContent":["import { Context, Crypto, Effect, Layer, ManagedRuntime, Schema } from \"effect\";\n\nimport * as Connection from \"../auth/connection-api.ts\";\nimport * as Lifecycle from \"../auth/lifecycle-repository.ts\";\nimport { webCryptoLayer } from \"../plan/canonical-json.ts\";\nimport type * as PromiseConnection from \"../promise/connection.ts\";\nimport * as ManagedDnsConnections from \"../promise/managed-dns-connections.ts\";\n\nexport const DEFAULT_BASE_PATH = \"/api/domainkit\";\n\nexport class Error extends Schema.TaggedError<Error>()(\"DomainKitServerError\", {\n category: Schema.Literals([\n \"authentication\",\n \"authorization\",\n \"configuration\",\n \"provider\",\n \"request\",\n \"storage\",\n ]),\n message: Schema.String,\n operation: Schema.String,\n retry: Schema.Literals([\"never\", \"after-user-action\", \"safe\", \"unknown\"]),\n}) {}\n\nexport interface Principal {\n readonly authorizedById: string;\n readonly ownerId: string;\n}\n\nexport interface IdentityInterface {\n readonly authenticate: (request: Request) => Effect.Effect<Principal, Error>;\n}\n\nexport class Identity extends Context.Service<Identity, IdentityInterface>()(\n \"@domainkit/server/Identity\",\n) {}\n\nexport interface AuthorizationReuseInput {\n readonly authorizationId: string;\n readonly domain: string | undefined;\n readonly method: \"integration\" | \"oauth2\";\n readonly principal: Principal;\n readonly providerId: string;\n}\n\nexport interface ConnectionPolicyInterface {\n readonly authorizeReuse: (input: AuthorizationReuseInput) => Effect.Effect<void, Error>;\n}\n\n/** Host authorization boundary for reusing an existing provider authorization. */\nexport class ConnectionPolicy extends Context.Service<\n ConnectionPolicy,\n ConnectionPolicyInterface\n>()(\"@domainkit/server/ConnectionPolicy\") {}\n\nexport interface InteractiveFlowInput {\n readonly callbackUrl: URL;\n readonly domain: string | undefined;\n readonly method: \"integration\" | \"oauth2\";\n readonly providerId: string;\n}\n\nexport interface ProvidersInterface {\n readonly interactiveFlow: (\n input: InteractiveFlowInput,\n ) => Effect.Effect<Connection.InteractiveFlow, Error>;\n}\n\nexport class Providers extends Context.Service<Providers, ProvidersInterface>()(\n \"@domainkit/server/Providers\",\n) {}\n\nexport interface InteractiveProvider {\n readonly create: (\n input: Omit<InteractiveFlowInput, \"method\" | \"providerId\">,\n ) => Effect.Effect<Connection.InteractiveFlow, Error>;\n readonly method: \"integration\" | \"oauth2\";\n readonly providerId: string;\n}\n\n/** Configure all interactive providers once at the host composition root. */\nexport const providersLayer = (\n definitions: ReadonlyArray<InteractiveProvider>,\n): Layer.Layer<Providers> => {\n const providers = new Map<string, InteractiveProvider>();\n for (const definition of definitions) {\n const key = `${definition.providerId}:${definition.method}`;\n if (providers.has(key)) {\n throw new globalThis.Error(`Interactive provider ${key} is configured more than once`);\n }\n providers.set(key, definition);\n }\n return Layer.succeed(Providers)({\n interactiveFlow: (input) => {\n const provider = providers.get(`${input.providerId}:${input.method}`);\n return provider === undefined\n ? Effect.fail(\n new Error({\n category: \"configuration\",\n message: `Interactive provider ${input.providerId}:${input.method} is not configured`,\n operation: \"Server.Providers.interactiveFlow\",\n retry: \"never\",\n }),\n )\n : provider.create({\n callbackUrl: input.callbackUrl,\n domain: input.domain,\n });\n },\n });\n};\n\nexport interface PendingAuthorizationContext {\n readonly baseURL: string;\n readonly domain: string | undefined;\n readonly method: \"integration\" | \"oauth2\";\n readonly providerId: string;\n readonly returnTo: string;\n}\n\nexport interface PendingAuthorization {\n readonly context: PendingAuthorizationContext;\n readonly continuation: Connection.Continuation;\n}\n\nexport interface PendingAuthorizationsInterface {\n readonly consume: (id: string, now: Date) => Effect.Effect<PendingAuthorization | null, Error>;\n readonly get: (id: string, now: Date) => Effect.Effect<PendingAuthorization | null, Error>;\n readonly put: (pending: PendingAuthorization) => Effect.Effect<void, Error>;\n}\n\nexport class PendingAuthorizations extends Context.Service<\n PendingAuthorizations,\n PendingAuthorizationsInterface\n>()(\"@domainkit/server/PendingAuthorizations\") {}\n\nexport interface Configuration {\n /** Public origin used to construct provider callbacks. Defaults to the incoming request origin. */\n readonly baseURL?: string;\n /** Catch-all mount path. */\n readonly basePath?: string;\n /** Relative same-origin destination used when a start request omits `returnTo`. */\n readonly defaultReturnTo?: string;\n}\n\nexport interface AsyncIdentity {\n readonly authenticate: (request: Request) => Promise<Principal>;\n}\n\nexport interface AsyncConnectionPolicy {\n readonly authorizeReuse: (input: AuthorizationReuseInput) => Promise<void>;\n}\n\nexport type AsyncInteractiveFlow = PromiseConnection.InteractiveFlow;\n\nexport interface AsyncInteractiveProvider {\n readonly create: (\n input: Omit<InteractiveFlowInput, \"method\" | \"providerId\">,\n ) => Promise<AsyncInteractiveFlow>;\n readonly method: \"integration\" | \"oauth2\";\n readonly providerId: string;\n}\n\nexport interface AsyncPendingAuthorizations {\n readonly consume: (id: string, now: Date) => Promise<PendingAuthorization | null>;\n readonly get: (id: string, now: Date) => Promise<PendingAuthorization | null>;\n readonly put: (pending: PendingAuthorization) => Promise<void>;\n}\n\nexport interface CreateDomainKitOptions extends Configuration {\n readonly connectionPolicy: AsyncConnectionPolicy;\n readonly identity: AsyncIdentity;\n readonly pendingAuthorizations: AsyncPendingAuthorizations;\n /** Host-owned Promise persistence. DomainKit does not initialize or dispose this resource. */\n readonly persistence: ManagedDnsConnections.AsyncInterface;\n readonly providers: ReadonlyArray<AsyncInteractiveProvider>;\n}\n\nexport interface Interface {\n readonly handle: (request: Request) => Effect.Effect<Response>;\n}\n\nexport class Handler extends Context.Service<Handler, Interface>()(\"@domainkit/server/Handler\") {}\n\ninterface StartInput {\n readonly authorizationId?: string;\n readonly domain?: string;\n readonly method: \"integration\" | \"oauth2\";\n readonly providerId: string;\n readonly returnTo?: string;\n}\n\nconst requestError = (operation: string, message: string) =>\n new Error({\n category: \"request\",\n message,\n operation,\n retry: \"after-user-action\",\n });\n\nconst connectionError = (operation: string, cause: Error) =>\n new Connection.Error({\n category: cause.category === \"provider\" ? \"provider\" : \"authorization\",\n message: cause.message,\n operation,\n retry: cause.retry,\n });\n\nconst serverError = (operation: string, cause: unknown): Error => {\n if (cause instanceof Error) return cause;\n if (cause instanceof Connection.Error) {\n return new Error({\n category: cause.operation.startsWith(\"Server.pending.\")\n ? \"storage\"\n : cause.category === \"provider\"\n ? \"provider\"\n : \"request\",\n message: cause.message,\n operation,\n retry: cause.retry,\n });\n }\n if (cause instanceof Lifecycle.Error) {\n return new Error({\n category: \"storage\",\n message: cause.message,\n operation,\n retry: cause.retry,\n });\n }\n return new Error({\n category: \"provider\",\n message: cause instanceof globalThis.Error ? cause.message : \"Domain connection failed\",\n operation,\n retry: \"unknown\",\n });\n};\n\nconst normalizeBasePath = (input: string | undefined): string => {\n const path = input ?? DEFAULT_BASE_PATH;\n if (!path.startsWith(\"/\") || path.includes(\"?\") || path.includes(\"#\")) {\n throw new globalThis.Error(\"DomainKit server basePath must be an absolute path\");\n }\n if (path === \"/\") return \"\";\n return path.endsWith(\"/\") ? path.slice(0, -1) : path;\n};\n\nconst configuredBaseUrl = (input: string | undefined): URL | undefined => {\n if (input === undefined) return undefined;\n const url = new URL(input);\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n throw new globalThis.Error(\"DomainKit server baseURL must use http or https\");\n }\n url.pathname = \"/\";\n url.search = \"\";\n url.hash = \"\";\n return url;\n};\n\nconst canonicalReturnTo = Effect.fn(\"Server.canonicalReturnTo\")((input: string, baseUrl: URL) =>\n Effect.try({\n try: () => new URL(input, baseUrl),\n catch: () => requestError(\"Server.start\", \"returnTo must be a valid application URL\"),\n }).pipe(\n Effect.filterOrFail(\n (target) => target.origin === baseUrl.origin,\n () => requestError(\"Server.start\", \"returnTo must stay on the configured application origin\"),\n ),\n Effect.map((target) => `${target.pathname}${target.search}${target.hash}`),\n ),\n);\n\nconst parseStartInput = Effect.fn(\"Server.parseStartInput\")((request: Request) =>\n Effect.tryPromise({\n try: () => request.json(),\n catch: () => requestError(\"Server.start\", \"Request body must be valid JSON\"),\n }).pipe(\n Effect.flatMap((input) => {\n if (typeof input !== \"object\" || input === null) {\n return Effect.fail(requestError(\"Server.start\", \"Request body must be an object\"));\n }\n const value = input as Record<string, unknown>;\n if (\n typeof value.providerId !== \"string\" ||\n !/^[a-z0-9][a-z0-9._-]*$/.test(value.providerId) ||\n (value.method !== \"oauth2\" && value.method !== \"integration\") ||\n (value.domain !== undefined && typeof value.domain !== \"string\") ||\n (value.returnTo !== undefined && typeof value.returnTo !== \"string\") ||\n (value.authorizationId !== undefined && typeof value.authorizationId !== \"string\")\n ) {\n return Effect.fail(\n requestError(\n \"Server.start\",\n \"providerId and a supported interactive method are required\",\n ),\n );\n }\n return Effect.succeed({\n ...(value.authorizationId === undefined ? {} : { authorizationId: value.authorizationId }),\n ...(value.domain === undefined ? {} : { domain: value.domain }),\n method: value.method,\n providerId: value.providerId,\n ...(value.returnTo === undefined ? {} : { returnTo: value.returnTo }),\n } satisfies StartInput);\n }),\n ),\n);\n\nconst errorStatus = (cause: Error): number => {\n switch (cause.category) {\n case \"authentication\":\n return 401;\n case \"authorization\":\n return 403;\n case \"request\":\n return 400;\n case \"storage\":\n return 503;\n case \"configuration\":\n return 500;\n case \"provider\":\n return cause.retry === \"safe\" || cause.retry === \"unknown\" ? 502 : 400;\n }\n};\n\nconst jsonError = (cause: Error): Response =>\n Response.json(\n {\n error: {\n category: cause.category,\n message: cause.message,\n operation: cause.operation,\n retry: cause.retry,\n },\n },\n { status: errorStatus(cause) },\n );\n\n/** Construct the Effect-native server handler from host-provided services. */\nexport const make = (configuration: Configuration = {}) =>\n Effect.gen(function* () {\n const identity = yield* Identity;\n const policy = yield* ConnectionPolicy;\n const providers = yield* Providers;\n const pending = yield* PendingAuthorizations;\n const repository = yield* Lifecycle.Service;\n const crypto = yield* Crypto.Crypto;\n const basePath = normalizeBasePath(configuration.basePath);\n const fixedBaseUrl = configuredBaseUrl(configuration.baseURL);\n const defaultReturnTo = configuration.defaultReturnTo ?? \"/\";\n\n const withCore = <A, E>(effect: Effect.Effect<A, E, Lifecycle.Service | Crypto.Crypto>) =>\n effect.pipe(\n Effect.provideService(Lifecycle.Service, repository),\n Effect.provideService(Crypto.Crypto, crypto),\n );\n\n const start = Effect.fn(\"Server.start\")(function* (request: Request) {\n const principal = yield* identity.authenticate(request);\n const input = yield* parseStartInput(request);\n if (input.authorizationId !== undefined) {\n yield* policy.authorizeReuse({\n authorizationId: input.authorizationId,\n domain: input.domain,\n method: input.method,\n principal,\n providerId: input.providerId,\n });\n }\n const requestUrl = new URL(request.url);\n const baseUrl = fixedBaseUrl ?? new URL(requestUrl.origin);\n const callbackUrl = new URL(\n `${basePath}/callback/${encodeURIComponent(input.providerId)}`,\n baseUrl,\n );\n const returnTo = yield* canonicalReturnTo(input.returnTo ?? defaultReturnTo, baseUrl);\n const flow = yield* providers.interactiveFlow({\n callbackUrl,\n domain: input.domain,\n method: input.method,\n providerId: input.providerId,\n });\n if (flow.providerId !== input.providerId || flow.method !== input.method) {\n return yield* requestError(\n \"Server.start\",\n \"Configured provider flow does not match the requested provider and method\",\n );\n }\n const continuations: Connection.ContinuationStore = {\n consume: () => Effect.succeed(null),\n put: (continuation) =>\n pending\n .put({\n context: {\n baseURL: baseUrl.origin,\n domain: input.domain,\n method: input.method,\n providerId: input.providerId,\n returnTo,\n },\n continuation,\n })\n .pipe(Effect.mapError((cause) => connectionError(\"Server.pending.put\", cause))),\n };\n const result = yield* withCore(\n Connection.start({\n authorizedById: principal.authorizedById,\n ...(input.authorizationId === undefined\n ? {}\n : { authorizationId: input.authorizationId }),\n method: Connection.Method.Interactive({ continuations, flow }),\n ownerId: principal.ownerId,\n }),\n );\n if (result._tag !== \"Redirect\") {\n return yield* requestError(\"Server.start\", \"Interactive connection did not redirect\");\n }\n return Response.json({\n authorizationUrl: result.authorizationUrl.toString(),\n continuationId: result.continuationId,\n });\n });\n\n const complete = Effect.fn(\"Server.complete\")(function* (request: Request, providerId: string) {\n const callbackUrl = new URL(request.url);\n const continuationId = callbackUrl.searchParams.get(\"state\");\n if (continuationId === null || continuationId.length === 0) {\n return yield* requestError(\"Server.complete\", \"Provider callback is missing state\");\n }\n const now = new Date();\n const stored = yield* pending.get(continuationId, now);\n if (stored === null) {\n return yield* requestError(\n \"Server.complete\",\n \"Connection continuation is expired, unknown, or already consumed\",\n );\n }\n if (stored.context.providerId !== providerId) {\n return yield* requestError(\n \"Server.complete\",\n \"Provider callback does not match its continuation\",\n );\n }\n const callbackBaseUrl = yield* Effect.try({\n try: () => configuredBaseUrl(stored.context.baseURL),\n catch: () =>\n new Error({\n category: \"storage\",\n message: \"Stored provider callback origin is invalid\",\n operation: \"Server.complete\",\n retry: \"never\",\n }),\n }).pipe(\n Effect.flatMap((value) =>\n value === undefined\n ? Effect.fail(\n new Error({\n category: \"storage\",\n message: \"Stored provider callback origin is missing\",\n operation: \"Server.complete\",\n retry: \"never\",\n }),\n )\n : Effect.succeed(value),\n ),\n );\n if (fixedBaseUrl !== undefined && callbackBaseUrl.origin !== fixedBaseUrl.origin) {\n return yield* requestError(\n \"Server.complete\",\n \"Provider callback does not match the configured application origin\",\n );\n }\n const expectedCallback = new URL(\n `${basePath}/callback/${encodeURIComponent(providerId)}`,\n callbackBaseUrl,\n );\n if (\n callbackUrl.origin !== expectedCallback.origin ||\n callbackUrl.pathname !== expectedCallback.pathname\n ) {\n return yield* requestError(\"Server.complete\", \"Provider callback URL is invalid\");\n }\n const flow = yield* providers.interactiveFlow({\n callbackUrl: expectedCallback,\n domain: stored.context.domain,\n method: stored.context.method,\n providerId,\n });\n if (flow.providerId !== providerId || flow.method !== stored.context.method) {\n return yield* requestError(\n \"Server.complete\",\n \"Configured provider flow does not match the stored continuation\",\n );\n }\n const continuations: Connection.ContinuationStore = {\n consume: (id, consumedAt) =>\n pending.consume(id, consumedAt).pipe(\n Effect.map((value) => value?.continuation ?? null),\n Effect.mapError((cause) => connectionError(\"Server.pending.consume\", cause)),\n ),\n put: () => Effect.die(\"Callback continuation store cannot put\"),\n };\n const connection = yield* withCore(\n Connection.complete({\n callbackUrl,\n continuationId,\n continuations,\n flow,\n }),\n );\n const returnTo = yield* canonicalReturnTo(stored.context.returnTo, callbackBaseUrl);\n const destination = new URL(returnTo, callbackBaseUrl);\n destination.searchParams.set(\"domainkit\", \"connected\");\n destination.searchParams.set(\"connectionId\", connection.id);\n return new Response(null, {\n headers: { location: destination.toString() },\n status: 303,\n });\n });\n\n const handle = (request: Request): Effect.Effect<Response> => {\n const url = new URL(request.url);\n const callbackPrefix = `${basePath}/callback/`;\n const route =\n request.method === \"POST\" && url.pathname === `${basePath}/connection/start`\n ? start(request)\n : request.method === \"GET\" && url.pathname.startsWith(callbackPrefix)\n ? complete(request, url.pathname.slice(callbackPrefix.length))\n : Effect.succeed(Response.json({ error: { message: \"Not found\" } }, { status: 404 }));\n return route.pipe(\n Effect.mapError((cause) => serverError(\"Server.handle\", cause)),\n Effect.catch((cause) => Effect.succeed(jsonError(cause))),\n );\n };\n\n return Handler.of({ handle });\n });\n\n/** Provide the Effect-native server handler as a Layer. */\nexport const layer = (configuration: Configuration = {}) =>\n Layer.effect(Handler, make(configuration));\n\nexport interface WebHandler {\n readonly dispose: () => Promise<void>;\n readonly fetch: (request: Request) => Promise<Response>;\n}\n\nconst fromPromise = <A>(\n operation: string,\n category: Error[\"category\"],\n evaluate: () => Promise<A>,\n): Effect.Effect<A, Error> =>\n Effect.tryPromise({\n try: evaluate,\n catch: (cause) =>\n cause instanceof Error\n ? cause\n : new Error({\n category,\n message: cause instanceof globalThis.Error ? cause.message : String(cause),\n operation,\n retry: category === \"storage\" ? \"safe\" : \"unknown\",\n }),\n });\n\nconst asyncProvidersLayer = (\n definitions: ReadonlyArray<AsyncInteractiveProvider>,\n): Layer.Layer<Providers> =>\n providersLayer(\n definitions.map((definition) => ({\n create: (input) =>\n fromPromise(\"Server.Providers.interactiveFlow\", \"provider\", () =>\n definition.create(input),\n ).pipe(\n Effect.map((flow) => ({\n complete: (payload, callbackUrl) =>\n fromPromise(\"Server.Provider.complete\", \"provider\", () =>\n flow.complete(payload, callbackUrl),\n ).pipe(\n Effect.mapError((cause) => connectionError(\"Server.Provider.complete\", cause)),\n ),\n method: flow.method,\n providerId: flow.providerId,\n requiredCapabilities: flow.requiredCapabilities,\n start: (continuationId) =>\n fromPromise(\"Server.Provider.start\", \"provider\", () =>\n flow.start(continuationId),\n ).pipe(Effect.mapError((cause) => connectionError(\"Server.Provider.start\", cause))),\n })),\n ),\n method: definition.method,\n providerId: definition.providerId,\n })),\n );\n\nconst asyncDependencies = (options: CreateDomainKitOptions) =>\n Layer.mergeAll(\n Layer.succeed(Identity, {\n authenticate: (request) =>\n fromPromise(\"Server.Identity.authenticate\", \"authentication\", () =>\n options.identity.authenticate(request),\n ),\n }),\n Layer.succeed(ConnectionPolicy, {\n authorizeReuse: (input) =>\n fromPromise(\"Server.ConnectionPolicy.authorizeReuse\", \"authorization\", () =>\n options.connectionPolicy.authorizeReuse(input),\n ),\n }),\n asyncProvidersLayer(options.providers),\n Layer.succeed(PendingAuthorizations, {\n consume: (id, now) =>\n fromPromise(\"Server.PendingAuthorizations.consume\", \"storage\", () =>\n options.pendingAuthorizations.consume(id, now),\n ),\n get: (id, now) =>\n fromPromise(\"Server.PendingAuthorizations.get\", \"storage\", () =>\n options.pendingAuthorizations.get(id, now),\n ),\n put: (pending) =>\n fromPromise(\"Server.PendingAuthorizations.put\", \"storage\", () =>\n options.pendingAuthorizations.put(pending),\n ),\n }),\n ManagedDnsConnections.layerFromAsync(options.persistence),\n webCryptoLayer,\n );\n\nconst webHandler = <E>(runtime: ManagedRuntime.ManagedRuntime<Handler, E>): WebHandler => ({\n dispose: () => runtime.dispose(),\n fetch: (request) =>\n runtime.runPromise(\n Effect.flatMap(Handler, (handler) => handler.handle(request)),\n {\n signal: request.signal,\n },\n ),\n});\n\n/** Build one reusable Web handler from a fully provided Effect server Layer. */\nexport function toWebHandler<E>(serverLayer: Layer.Layer<Handler, E>): WebHandler {\n return webHandler(ManagedRuntime.make(serverLayer));\n}\n\n/**\n * Build a Web handler for async hosts. The host owns persistence setup, migrations, and disposal.\n */\nexport async function createDomainKit(options: CreateDomainKitOptions): Promise<WebHandler> {\n const runtime = ManagedRuntime.make(\n layer(options).pipe(Layer.provide(asyncDependencies(options))),\n );\n try {\n await runtime.context();\n return webHandler(runtime);\n } catch (cause) {\n await runtime.dispose();\n throw cause;\n }\n}\n"],"mappings":"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"}
|
package/dist/testing.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { D as
|
|
1
|
+
import { D as Interface, E as Error$1, Nt as Error$3, O as Service, b as Aggregate, ct as Service$1, it as AsyncInterface, kt as DomainName, o as ContinuationStore, ot as Error$2, st as Interface$1, v as CryptoError, vt as Observed } from "./connect-10vHuShV.mjs";
|
|
2
|
+
import { D as StaleError, T as PartialApplyError, a as Interface$2, c as Service$2, h as PartialError, i as Error$4, j as ApplyReceipt, n as AsyncInterface$1, o as Query, p as Error$5, s as Resolution, x as ConflictError, y as AuthorizationError } from "./resolver-DRrLm_hB.mjs";
|
|
2
3
|
import { Effect, Layer, Schema } from "effect";
|
|
3
4
|
declare namespace in_memory_lifecycle_repository_d_exports {
|
|
4
5
|
export { Options$1 as Options, layer$2 as layer, make$3 as make };
|
|
@@ -25,7 +26,7 @@ declare const toAsync$1: (options?: Options) => AsyncInterface;
|
|
|
25
26
|
declare namespace in_memory_d_exports$1 {
|
|
26
27
|
export { Resolve, layer, make, toAsync };
|
|
27
28
|
}
|
|
28
|
-
type Resolve = (query: Query) => Resolution | Effect.Effect<Resolution, Error$
|
|
29
|
+
type Resolve = (query: Query) => Resolution | Effect.Effect<Resolution, Error$4>;
|
|
29
30
|
declare function make(resolve: Resolve): Interface$2;
|
|
30
31
|
declare const layer: (resolve: Resolve) => Layer.Layer<Service$2>;
|
|
31
32
|
declare const toAsync: (resolve: Resolve) => AsyncInterface$1;
|
|
@@ -39,7 +40,7 @@ declare const Error_base: Schema.Class<Error, Schema.TaggedStruct<"ProviderConfo
|
|
|
39
40
|
}>, import("effect/Cause").YieldableError>;
|
|
40
41
|
declare class Error extends Error_base {}
|
|
41
42
|
interface Input {
|
|
42
|
-
readonly makeProvider: () => Effect.Effect<Interface$1, Error$
|
|
43
|
+
readonly makeProvider: () => Effect.Effect<Interface$1, Error$2>;
|
|
43
44
|
readonly prefix?: string;
|
|
44
45
|
readonly zone: DomainName;
|
|
45
46
|
}
|
|
@@ -55,7 +56,7 @@ declare const run: (input: Input) => Effect.Effect<{
|
|
|
55
56
|
cases: readonly ["create-readback-cleanup", "exact-noop", "conflict", "stale-plan", "partial-apply-cleanup"];
|
|
56
57
|
providerId: string;
|
|
57
58
|
zone: string & import("effect/Brand").Brand<"DomainName">;
|
|
58
|
-
}, ApplyReceipt | AuthorizationError | ConflictError | CryptoError | Error$
|
|
59
|
+
}, ApplyReceipt | AuthorizationError | ConflictError | CryptoError | Error$3 | Error$2 | Error$5 | Error | PartialApplyError | PartialError | StaleError, never>;
|
|
59
60
|
//#endregion
|
|
60
61
|
export { in_memory_continuation_d_exports as InMemoryConnectionContinuations, in_memory_d_exports as InMemoryDnsProvider, in_memory_d_exports$1 as InMemoryDnsResolver, in_memory_lifecycle_repository_d_exports as InMemoryManagedDnsConnections, provider_conformance_d_exports as ProviderConformance };
|
|
61
62
|
//# sourceMappingURL=testing.d.mts.map
|