Template
1
0

feat: react zitadel

This commit is contained in:
2025-11-23 22:56:58 +01:00
parent 2b462993cc
commit fe4220ede0
139 changed files with 3389 additions and 2771 deletions

View File

@@ -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,
};
}

View File

@@ -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);

View File

@@ -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;
};

View File

@@ -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

View File

@@ -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";

View File

@@ -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"
}
}