@casual-simulation/aux-common
Version:
Common library for AUX projects
328 lines • 12.3 kB
TypeScript
import type { GenericHttpRequest, GenericHttpResponse } from '../http/GenericHttpInterface';
import type z from 'zod';
import * as _z from 'zod/v4/core';
import type { KnownErrorCodes } from './ErrorCodes';
import type { Span } from '@opentelemetry/api';
import type { DenialReason } from '../common/DenialReason';
import type { IsAny } from 'zod/v4/core/util.cjs';
/**
* Defines an interface for the context that an RPC call is made with.
*/
export interface RPCContext {
/**
* The IP Address that the RPC call is coming from.
*/
ipAddress: string;
/**
* The session key that was included in the request.
*/
sessionKey: string | null;
/**
* The HTTP request that the RPC call is coming from.
*/
httpRequest?: GenericHttpRequest;
/**
* The HTTP origin that the request was made from.
*/
origin: string | null;
/**
* The URL that the request was made to.
*/
url: URL | null;
/**
* The span that the RPC call is being made in.
*/
span?: Span;
}
export type ProcedureOutput = ProcedureOutputSuccess | ProcedureOutputError | ProcedureOutputStream;
export interface ProcedureOutputSuccess {
success: true;
}
export interface ProcedureOutputError {
success: false;
errorCode: KnownErrorCodes;
errorMessage: string;
reason?: DenialReason;
}
export interface ProcedureOutputStream extends AsyncGenerator<any, ProcedureOutputSuccess | ProcedureOutputError> {
}
/**
* Defines a basic interface for a single RPC call.
*/
export interface Procedure<TSchema extends z.ZodType | void, TOutput extends ProcedureOutput, TQuery extends z.ZodType | void> {
/**
* The schema that should be used for the input into the RPC.
*/
schema: TSchema;
/**
* The schema that should be used for the query parameters into the RPC.
*/
querySchema: TQuery;
/**
* The handler for the RPC.
* @param input The input that was parsed from the request.
* @param context The context that the handler was called with.
* @param query The query parameters that were parsed from the request.
* @returns Returns a promise that resolves with the output of the RPC.
*/
handler: (input: z.output<TSchema>, context: RPCContext, query?: z.output<TQuery>) => Promise<TOutput>;
/**
* The function that can map the output of the handler to an HTTP response.
* @param output The output of the handler.
* @param context The context that the handler was called with.
*/
mapToResponse?: (output: TOutput, context: RPCContext) => Promise<Partial<GenericHttpResponse>>;
/**
* The set of origins that are allowed for the route.
* If true, then all origins are allowed.
* If 'account', then only the configured account origins are allowed.
* If 'api', then only the configured API origins are allowed.
* If 'self', then either the API or account origins are allowed.
* If omitted, then it is up to the handler to determine if the origin is allowed.
*/
allowedOrigins?: Set<string> | true | 'account' | 'api' | 'self';
/**
* The HTTP-specific configuration for the procedure.
*/
http?: {
/**
* The HTTP method that should be used for the route.
*/
method: GenericHttpRequest['method'];
/**
* The path for the HTTP route.
*/
path: string;
/**
* The scope of the HTTP route.
*/
scope?: 'player' | 'auth';
};
/**
* The view-specific configuration for the procedure.
*/
view?: {
/**
* The scope of the view (e.g. player or auth).
*/
scope: 'player' | 'auth';
/**
* The path for the view.
* If true, then the path will be treated as a default path.
*/
path: string | true;
};
}
export interface Procedures {
[key: string]: Procedure<any, any, any>;
}
export interface CallProcedureOptions {
/**
* The session key that should be used instead of the one that is currently set on the client.
*/
sessionKey?: string;
/**
* The endpoint that should be used instead of the one that is currently set on the client.
*/
endpoint?: string;
/**
* The headers that should be included in the request.
*/
headers?: Record<string, string>;
}
export type OnlyFirstArg<T> = T extends (input: infer U, ...args: any[]) => any ? (input: U, options?: CallProcedureOptions) => ReturnType<T> : never;
export type RemoteProcedures<T extends Procedures> = {
[K in keyof T]: (input: ProcedureInputs<T>[K], options?: CallProcedureOptions) => Promise<ProcedureOutputs<T>[K]>;
};
type IsVoid<T> = T extends void ? true : false;
type IsUnknown<T> = IsAny<T> extends false ? unknown extends T ? true : false : false;
export type ProcedureInput<T extends z.ZodType | void> = IsVoid<T> extends true ? void : IsUnknown<z.input<T>> extends true ? z.input<T> | void : z.input<T>;
export type ProcedureInputs<T extends Procedures> = {
[K in keyof T]: ProcedureInput<T[K]['schema']>;
};
export type ProcedureQueries<T extends Procedures> = {
[K in keyof T]: ProcedureInput<T[K]['querySchema']>;
};
export type ProcedureActions<T extends Procedures> = {
[K in keyof T]: {
input: ProcedureInputs<T>[K];
query?: ProcedureQueries<T>[K];
};
};
export type ProcedureOutputs<T extends Procedures> = {
[K in keyof T]: T[K] extends Procedure<any, infer U, any> ? U : never;
};
export type SuccessfulOutputs<T extends Procedures> = {
[K in keyof T]: T[K] extends Procedure<any, infer U, any> ? U extends {
success: true;
} ? U : never : never;
};
export interface ProcedureBuilder {
/**
* Configures the origins that are allowed for the route.
* @param allowedOrigins The origins that are allowed.
*/
origins(allowedOrigins: Set<string> | true | 'account' | 'api' | 'self'): this;
/**
* Configures the HTTP method and path for this RPC.
* @param method The method that should be used for http requests to this RPC.
* @param scope The scope of the HTTP route.
*/
http(method: GenericHttpRequest['method'], path: string, scope?: 'player' | 'auth'): this;
/**
* Configures the view for this RPC.
* @param scope The scope of the view (e.g. player or auth).
* @param path The path for the view. If true, then the path will be treated as a default path.
*/
view(scope: 'player' | 'auth', path: string | true): this;
}
export interface InputlessProcedureBuilder extends ProcedureBuilder {
/**
* Configures the input schema for the RPC.
* @param schema The schema that inputs should conform to.
*/
inputs<TInput extends z.ZodType, TQuery extends z.ZodType>(schema: TInput, query?: TQuery): OutputlessProcedureBuilder<TInput, TQuery>;
/**
* Configures the handler for the RPC.
* Because this is an inputless procedure, the input is void.
* @param handler The handler.
* @param mapToResponse The function that should be used to map the handler output to an HTTP response.
*/
handler<TOutput extends ProcedureOutput>(handler: (input: void, context: RPCContext) => Promise<TOutput>, mapToResponse?: (output: TOutput, context: RPCContext) => Promise<Partial<GenericHttpResponse>>): Procedure<void, TOutput, void>;
}
export interface OutputlessProcedureBuilder<TInput extends z.ZodType | void, TQuery extends z.ZodType | void> extends ProcedureBuilder {
/**
* Configures the handler for the RPC.
* @param handler The handler.
* @param mapToResponse The function that should be used to map the handler output to an HTTP response.
*/
handler<TOutput extends ProcedureOutput>(handler: (input: z.output<TInput>, context: RPCContext, query?: z.output<TQuery>) => Promise<TOutput>, mapToResponse?: (output: TOutput, context: RPCContext) => Promise<Partial<GenericHttpResponse>>): Procedure<TInput, TOutput, TQuery>;
}
/**
* Constructs a new procedure.
*/
export declare function procedure(): InputlessProcedureBuilder;
export interface ProceduresMetadata {
/**
* The list of procedures.
*/
procedures: ProcedureMetadata[];
}
export interface ProcedureMetadata {
/**
* The name of the procedure.
*/
name: string;
/**
* The schema that should be used for the input into the RPC.
*/
inputs: SchemaMetadata;
/**
* The schema that should be used for the query parameters into the RPC.
* Most procedures do not have distinct query parameters, but some that deal directly with HTTP requests do (such as webhooks).
*/
query?: SchemaMetadata;
/**
* The set of origins that are allowed for the route.
* If true, then all origins are allowed.
* If 'account', then only the configured account origins are allowed.
* If 'api', then only the configured API origins are allowed.
* If 'self', then either the API or account origins are allowed.
* If omitted, then it is up to the handler to determine if the origin is allowed.
*/
origins?: Set<string> | true | 'account' | 'api' | 'self';
/**
* The HTTP-specific configuration for the procedure.
*/
http?: {
/**
* The HTTP method that should be used for the route.
*/
method: GenericHttpRequest['method'];
/**
* The path for the HTTP route.
*/
path: string;
};
}
/**
* Gets the metadata for the given procedures.
* @param procedures The procedures to get metadata for.
*/
export declare function getProcedureMetadata(procedures: Procedures): ProceduresMetadata;
export interface BaseSchemaMetadata {
type: string;
nullable?: boolean;
optional?: boolean;
description?: string;
hasDefault?: boolean;
defaultValue?: any;
}
export interface StringSchemaMetadata extends BaseSchemaMetadata {
type: 'string';
}
export interface BooleanSchemaMetadata extends BaseSchemaMetadata {
type: 'boolean';
}
export interface NumberSchemaMetadata extends BaseSchemaMetadata {
type: 'number';
}
export interface ObjectSchemaMetadata extends BaseSchemaMetadata {
type: 'object';
schema: Record<string, SchemaMetadata>;
catchall?: SchemaMetadata;
}
export interface ArraySchemaMetadata extends BaseSchemaMetadata {
type: 'array';
schema: SchemaMetadata;
maxLength?: number;
minLength?: number;
exactLength?: number;
}
export interface LiteralSchemaMetadata extends BaseSchemaMetadata {
type: 'literal';
value: any;
}
export interface EnumSchemaMetadata extends BaseSchemaMetadata {
type: 'enum';
values: string[];
}
export interface DateSchemaMetadata extends BaseSchemaMetadata {
type: 'date';
}
export interface AnySchemaMetadata extends BaseSchemaMetadata {
type: 'any';
}
export interface NullSchemaMetadata extends BaseSchemaMetadata {
type: 'null';
}
export interface UnionSchemaMetadata extends BaseSchemaMetadata {
type: 'union';
options: SchemaMetadata[];
}
export interface DiscriminatedUnionSchemaMetadata extends UnionSchemaMetadata {
options: ObjectSchemaMetadata[];
discriminator: string;
}
export interface RecordSchemaMetadata extends BaseSchemaMetadata {
type: 'record';
/**
* The schema of the values in the record.
*/
valueSchema: SchemaMetadata;
}
export interface TupleSchemaMetadata extends BaseSchemaMetadata {
type: 'tuple';
/**
* The schema of the items in the tuple.
*/
items: SchemaMetadata[];
}
export type SchemaMetadata = StringSchemaMetadata | BooleanSchemaMetadata | NumberSchemaMetadata | ObjectSchemaMetadata | ArraySchemaMetadata | LiteralSchemaMetadata | EnumSchemaMetadata | DateSchemaMetadata | AnySchemaMetadata | NullSchemaMetadata | UnionSchemaMetadata | DiscriminatedUnionSchemaMetadata | RecordSchemaMetadata | TupleSchemaMetadata;
/**
* Gets a serializable version of the schema metdata.
* @param schema The schema to get metadata for.
*/
export declare function getSchemaMetadata(schema: _z.$ZodType): SchemaMetadata;
export {};
//# sourceMappingURL=GenericRPCInterface.d.ts.map