UNPKG

alepha

Version:

Alepha is a convention-driven TypeScript framework for building robust, end-to-end type-safe applications, from serverless APIs to full-stack React apps.

316 lines (315 loc) 10.9 kB
import { ServerRouteSecure } from "alepha/server/security"; import * as _alepha_core2 from "alepha"; import { Alepha, Descriptor, KIND, Static } from "alepha"; import * as _alepha_server0 from "alepha/server"; import { ActionDescriptor, ClientRequestEntry, ClientRequestOptions, ClientRequestResponse, FetchResponse, HttpClient, RequestConfigSchema, ServerHandler, ServerRequestConfigEntry, ServerTimingProvider } from "alepha/server"; import * as _alepha_logger0 from "alepha/logger"; import * as _alepha_retry0 from "alepha/retry"; import { ProxyDescriptorOptions, ServerProxyProvider } from "alepha/server/proxy"; import { ServiceAccountDescriptor, UserAccountToken } from "alepha/security"; import * as typebox18 from "typebox"; //#region src/schemas/apiLinksResponseSchema.d.ts declare const apiLinkSchema: typebox18.TObject<{ name: typebox18.TString; group: typebox18.TOptional<typebox18.TString>; path: typebox18.TString; method: typebox18.TOptional<typebox18.TString>; requestBodyType: typebox18.TOptional<typebox18.TString>; service: typebox18.TOptional<typebox18.TString>; }>; declare const apiLinksResponseSchema: typebox18.TObject<{ prefix: typebox18.TOptional<typebox18.TString>; links: typebox18.TArray<typebox18.TObject<{ name: typebox18.TString; group: typebox18.TOptional<typebox18.TString>; path: typebox18.TString; method: typebox18.TOptional<typebox18.TString>; requestBodyType: typebox18.TOptional<typebox18.TString>; service: typebox18.TOptional<typebox18.TString>; }>>; }>; type ApiLinksResponse = Static<typeof apiLinksResponseSchema>; type ApiLink = Static<typeof apiLinkSchema>; //#endregion //#region src/providers/LinkProvider.d.ts /** * Browser, SSR friendly, service to handle links. */ declare class LinkProvider { static path: { apiLinks: string; apiSchema: string; }; protected readonly log: _alepha_logger0.Logger; protected readonly alepha: Alepha; protected readonly httpClient: HttpClient; protected serverLinks: Array<HttpClientLink>; /** * Get applicative links registered on the server. * This does not include lazy-loaded remote links. */ getServerLinks(): HttpClientLink[]; /** * Register a new link for the application. */ registerLink(link: HttpClientLink): void; get links(): HttpClientLink[]; /** * Force browser to refresh links from the server. */ fetchLinks(): Promise<HttpClientLink[]>; /** * Create a virtual client that can be used to call actions. * * Use js Proxy under the hood. */ client<T extends object>(scope?: ClientScope): HttpVirtualClient<T>; /** * Check if a link with the given name exists. * @param name */ can(name: string): boolean; /** * Resolve a link by its name and call it. * - If link is local, it will call the local handler. * - If link is remote, it will make a fetch request to the remote server. */ follow(name: string, config?: Partial<ServerRequestConfigEntry>, options?: ClientRequestOptions & ClientScope): Promise<any>; protected createVirtualAction<T extends RequestConfigSchema>(name: string, scope?: ClientScope): VirtualAction<T>; protected followRemote(link: HttpClientLink, config?: Partial<ServerRequestConfigEntry>, options?: ClientRequestOptions): Promise<FetchResponse>; protected getLinkByName(name: string, options?: ClientScope): Promise<HttpClientLink>; } interface HttpClientLink extends ApiLink { secured?: boolean | ServerRouteSecure; prefix?: string; host?: string; service?: string; schema?: RequestConfigSchema; handler?: ServerHandler; } interface ClientScope { group?: string; service?: string; hostname?: string; } type HttpVirtualClient<T> = { [K in keyof T as T[K] extends ActionDescriptor<RequestConfigSchema> ? K : never]: T[K] extends ActionDescriptor<infer Schema> ? VirtualAction<Schema> : never }; interface VirtualAction<T extends RequestConfigSchema> extends Pick<ActionDescriptor<T>, "name" | "run" | "fetch"> { (config?: ClientRequestEntry<T>, opts?: ClientRequestOptions): Promise<ClientRequestResponse<T>>; can: () => boolean; } //#endregion //#region src/descriptors/$client.d.ts /** * Create a new client. */ declare const $client: { <T extends object>(scope?: ClientScope): HttpVirtualClient<T>; [KIND]: string; }; //#endregion //#region src/descriptors/$remote.d.ts /** * $remote is a descriptor that allows you to define remote service access. * * Use it only when you have 2 or more services that need to communicate with each other. * * All remote services can be exposed as actions, ... or not. * * You can add a service account if you want to use a security layer. */ declare const $remote: { (options: RemoteDescriptorOptions): RemoteDescriptor; [KIND]: typeof RemoteDescriptor; }; interface RemoteDescriptorOptions { /** * The URL of the remote service. * You can use a function to generate the URL dynamically. * You probably should use $env(env) to get the URL from the environment. * * @example * ```ts * import { $remote } from "alepha/server"; * import { $inject, t } from "alepha"; * * class App { * env = $env(t.object({ * REMOTE_URL: t.text({default: "http://localhost:3000"}), * })); * remote = $remote({ * url: this.env.REMOTE_URL, * }); * } * ``` */ url: string | (() => string); /** * The name of the remote service. * * @default Member of the class containing the remote service. */ name?: string; /** * If true, all methods of the remote service will be exposed as actions in this context. * > Note: Proxy will never use the service account, it just... proxies the request. */ proxy?: boolean | Partial<ProxyDescriptorOptions & { /** * If true, the remote service won't be available internally, only through the proxy. */ noInternal: boolean; }>; /** * For communication between the server and the remote service with a security layer. * This will be used for internal communication and will not be exposed to the client. */ serviceAccount?: ServiceAccountDescriptor; } declare class RemoteDescriptor extends Descriptor<RemoteDescriptorOptions> { get name(): string; } //#endregion //#region src/providers/RemoteDescriptorProvider.d.ts declare class RemoteDescriptorProvider { protected readonly env: { SERVER_API_PREFIX: string; }; protected readonly alepha: Alepha; protected readonly proxyProvider: ServerProxyProvider; protected readonly linkProvider: LinkProvider; protected readonly remotes: Array<ServerRemote>; protected readonly log: _alepha_logger0.Logger; getRemotes(): ServerRemote[]; readonly configure: _alepha_core2.HookDescriptor<"configure">; readonly start: _alepha_core2.HookDescriptor<"start">; registerRemote(value: RemoteDescriptor): Promise<void>; protected readonly fetchLinks: _alepha_retry0.RetryDescriptorFn<(opts: FetchLinksOptions) => Promise<ApiLinksResponse>>; } interface FetchLinksOptions { /** * Name of the remote service. */ service: string; /** * URL to fetch links from. */ url: string; /** * Authorization header containing access token. */ authorization?: string; } interface ServerRemote { /** * URL of the remote service. */ url: string; /** * Name of the remote service. */ name: string; /** * Expose links as endpoint. It's not only internal. */ proxy: boolean; /** * It's only used inside the application. */ internal: boolean; /** * Links fetcher. */ links: (args: { authorization?: string; }) => Promise<ApiLinksResponse>; /** * Fetches schema for the remote service. */ schema: (args: { name: string; authorization?: string; }) => Promise<any>; /** * Force a default access token provider when not provided. */ serviceAccount?: ServiceAccountDescriptor; /** * Prefix for the remote service links. */ prefix: string; } //#endregion //#region src/providers/ServerLinksProvider.d.ts declare class ServerLinksProvider { protected readonly env: { SERVER_API_PREFIX: string; }; protected readonly alepha: Alepha; protected readonly linkProvider: LinkProvider; protected readonly remoteProvider: RemoteDescriptorProvider; protected readonly serverTimingProvider: ServerTimingProvider; get prefix(): string; readonly onRoute: _alepha_core2.HookDescriptor<"configure">; /** * First API - Get all API links for the user. * * This is based on the user's permissions. */ readonly links: _alepha_server0.RouteDescriptor<{ response: typebox18.TObject<{ prefix: typebox18.TOptional<typebox18.TString>; links: typebox18.TArray<typebox18.TObject<{ name: typebox18.TString; group: typebox18.TOptional<typebox18.TString>; path: typebox18.TString; method: typebox18.TOptional<typebox18.TString>; requestBodyType: typebox18.TOptional<typebox18.TString>; service: typebox18.TOptional<typebox18.TString>; }>>; }>; }>; /** * Second API - Get schema for a specific API link. * * Note: Body/Response schema are not included in `links` API because it's TOO BIG. * I mean for 150+ links, you got 50ms of serialization time. */ readonly schema: _alepha_server0.RouteDescriptor<{ params: typebox18.TObject<{ name: typebox18.TString; }>; response: typebox18.TRecord<string, typebox18.TAny>; }>; getSchemaByName(name: string, options?: GetApiLinksOptions): Promise<RequestConfigSchema>; /** * Retrieves API links for the user based on their permissions. * Will check on local links and remote links. */ getUserApiLinks(options: GetApiLinksOptions): Promise<ApiLinksResponse>; } interface GetApiLinksOptions { user?: UserAccountToken; authorization?: string; } //#endregion //#region src/index.d.ts declare module "alepha" { interface State { api?: ApiLinksResponse; } } /** * Provides server-side link management and remote capabilities for client-server interactions. * * The server-links module enables declarative link definitions using `$remote` and `$client` descriptors, * facilitating seamless API endpoint management and client-server communication. It integrates with server * security features to ensure safe and controlled access to resources. * * @see {@link $remote} * @see {@link $client} * @module alepha.server.links */ declare const AlephaServerLinks: _alepha_core2.Service<_alepha_core2.Module<{}>>; //#endregion export { $client, $remote, AlephaServerLinks, ApiLink, ApiLinksResponse, ClientScope, FetchLinksOptions, GetApiLinksOptions, HttpClientLink, HttpVirtualClient, LinkProvider, RemoteDescriptor, RemoteDescriptorOptions, RemoteDescriptorProvider, ServerLinksProvider, ServerRemote, VirtualAction, apiLinkSchema, apiLinksResponseSchema }; //# sourceMappingURL=index.d.ts.map