feat: react zitadel
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
import { encrypt } from "@platform/vault";
|
||||
|
||||
import {
|
||||
assertServerErrorResponse,
|
||||
type RelayAdapter,
|
||||
@@ -69,10 +67,7 @@ export class HttpAdapter implements RelayAdapter {
|
||||
return `${this.url}${endpoint}`;
|
||||
}
|
||||
|
||||
async send(
|
||||
{ method, endpoint, query, body, headers = new Headers() }: RelayInput,
|
||||
publicKey: string,
|
||||
): Promise<RelayResponse> {
|
||||
async send({ method, endpoint, query, body, headers = new Headers() }: RelayInput): Promise<RelayResponse> {
|
||||
const init: RequestInit = { method, headers };
|
||||
|
||||
// ### Before Request
|
||||
@@ -95,14 +90,6 @@ export class HttpAdapter implements RelayAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
// ### Internal
|
||||
// If public key is present we create a encrypted token on the header that
|
||||
// is verified by the server before allowing the request through.
|
||||
|
||||
if (publicKey !== undefined) {
|
||||
headers.set("x-internal", await encrypt("internal", publicKey));
|
||||
}
|
||||
|
||||
// ### Response
|
||||
|
||||
return this.request(`${endpoint}${query}`, init);
|
||||
@@ -138,6 +125,9 @@ export class HttpAdapter implements RelayAdapter {
|
||||
* @param body - Request body.
|
||||
*/
|
||||
#getRequestFormat(body: unknown): "form-data" | "json" {
|
||||
if (body instanceof FormData) {
|
||||
return "form-data";
|
||||
}
|
||||
if (containsFile(body) === true) {
|
||||
return "form-data";
|
||||
}
|
||||
@@ -245,14 +235,30 @@ export class HttpAdapter implements RelayAdapter {
|
||||
};
|
||||
}
|
||||
|
||||
// ### Error
|
||||
// If the 'content-type' is not a JSON response from the API then we check if the
|
||||
// response status is an error code.
|
||||
|
||||
if (response.status >= 400) {
|
||||
return {
|
||||
result: "error",
|
||||
headers: response.headers,
|
||||
error: {
|
||||
code: "SERVER_ERROR_RESPONSE",
|
||||
status: response.status,
|
||||
message: await response.text(),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// ### Success
|
||||
// If the 'content-type' is not a JSON response from the API and the request is not
|
||||
// an error we simply return the pure response in the data key.
|
||||
|
||||
return {
|
||||
result: "error",
|
||||
result: "success",
|
||||
headers: response.headers,
|
||||
error: {
|
||||
code: "UNSUPPORTED_CONTENT_TYPE",
|
||||
status: response.status,
|
||||
message: "Unsupported 'content-type' in header returned from server.",
|
||||
},
|
||||
data: response,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ function getRouteFn(route: Route, { adapter }: Config) {
|
||||
|
||||
// ### Fetch
|
||||
|
||||
const response = await adapter.send(input, route.state.crypto?.publicKey);
|
||||
const response = await adapter.send(input);
|
||||
|
||||
if ("data" in response && route.state.response !== undefined) {
|
||||
response.data = route.state.response.parse(response.data);
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
export type Hooks = {
|
||||
/**
|
||||
* Executes when any error is thrown before or during the lifetime
|
||||
* of the route. This allows for custom handling of errors if the
|
||||
* route has unique requirements to error handling.
|
||||
*
|
||||
* @param error - Error which has been thrown.
|
||||
*/
|
||||
onError?: (error: unknown) => Response;
|
||||
};
|
||||
@@ -3,7 +3,6 @@ import z, { type ZodObject, type ZodRawShape, type ZodType } from "zod";
|
||||
|
||||
import type { ServerContext } from "./context.ts";
|
||||
import { ServerError, type ServerErrorClass } from "./errors.ts";
|
||||
import type { Hooks } from "./hooks.ts";
|
||||
|
||||
export class Route<const TState extends RouteState = RouteState> {
|
||||
readonly type = "route" as const;
|
||||
@@ -85,23 +84,6 @@ export class Route<const TState extends RouteState = RouteState> {
|
||||
return new Route({ ...this.state, meta });
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cryptographic keys used to resolve cryptographic requests.
|
||||
*
|
||||
* @param crypto - Crypto configuration object.
|
||||
*
|
||||
* @examples
|
||||
*
|
||||
* ```ts
|
||||
* route.post("/foo").crypto({ publicKey: "..." });
|
||||
* ```
|
||||
*/
|
||||
crypto<TCrypto extends { publicKey: string }>(
|
||||
crypto: TCrypto,
|
||||
): Route<Prettify<Omit<TState, "crypto"> & { crypto: TCrypto }>> {
|
||||
return new Route({ ...this.state, crypto });
|
||||
}
|
||||
|
||||
/**
|
||||
* Access level of the route which acts as the first barrier of entry
|
||||
* to ensure that requests are valid.
|
||||
@@ -307,19 +289,6 @@ export class Route<const TState extends RouteState = RouteState> {
|
||||
): Route<Omit<TState, "handle"> & { handle: THandleFn }> {
|
||||
return new Route({ ...this.state, handle });
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign lifetime hooks to a route allowing for custom handling of
|
||||
* events that can occur during a request or response.
|
||||
*
|
||||
* Can be used on both server and client with the appropriate
|
||||
* implementation.
|
||||
*
|
||||
* @param hooks - Hooks to register with the route.
|
||||
*/
|
||||
hooks<THooks extends Hooks>(hooks: THooks): Route<Prettify<Omit<TState, "hooks"> & { hooks: THooks }>> {
|
||||
return new Route({ ...this.state, hooks });
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -451,9 +420,6 @@ export type RouteFn = (...args: any[]) => any;
|
||||
type RouteState = {
|
||||
method: RouteMethod;
|
||||
path: string;
|
||||
crypto?: {
|
||||
publicKey: string;
|
||||
};
|
||||
meta?: RouteMeta;
|
||||
access?: RouteAccess;
|
||||
params?: ZodObject;
|
||||
@@ -462,7 +428,6 @@ type RouteState = {
|
||||
errors: ServerErrorClass[];
|
||||
response?: ZodType;
|
||||
handle?: HandleFn;
|
||||
hooks?: Hooks;
|
||||
};
|
||||
|
||||
export type RouteMeta = {
|
||||
@@ -474,7 +439,7 @@ export type RouteMeta = {
|
||||
|
||||
export type RouteMethod = "POST" | "GET" | "PUT" | "PATCH" | "DELETE";
|
||||
|
||||
export type RouteAccess = "public" | "session" | ["internal:public", string] | ["internal:session", string];
|
||||
export type RouteAccess = "public" | "authenticated";
|
||||
|
||||
type HandleFn<TArgs extends Array<any> = any[], TResponse = any> = (
|
||||
...args: TArgs
|
||||
|
||||
@@ -3,6 +3,5 @@ export * from "./libraries/adapter.ts";
|
||||
export * from "./libraries/client.ts";
|
||||
export * from "./libraries/context.ts";
|
||||
export * from "./libraries/errors.ts";
|
||||
export * from "./libraries/hooks.ts";
|
||||
export * from "./libraries/procedure.ts";
|
||||
export * from "./libraries/route.ts";
|
||||
|
||||
@@ -11,8 +11,7 @@
|
||||
"@platform/auth": "workspace:*",
|
||||
"@platform/socket": "workspace:*",
|
||||
"@platform/supertokens": "workspace:*",
|
||||
"@platform/vault": "workspace:*",
|
||||
"path-to-regexp": "8",
|
||||
"zod": "4.1.11"
|
||||
"zod": "4.1.12"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user