Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@trpc/server

Package Overview
Dependencies
Maintainers
2
Versions
1072
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@trpc/server - npm Package Compare versions

Comparing version 1.4.4-alpha.2 to 1.4.4-alpha.3

dist/adapters/express.js

164

dist/adapters/express.d.ts

@@ -1,9 +0,161 @@

import type * as express from 'express';
import { BaseOptions, CreateContextFn, CreateContextFnOptions } from '../http';
import { Router } from '../router';
export declare type CreateExpressContextOptions = CreateContextFnOptions<express.Request, express.Response>;
export declare type CreateExpressContextFn<TContext> = CreateContextFn<TContext, express.Request, express.Response>;
export declare function createExpressMiddleware<TContext, TRouter extends Router<TContext, any, any, any>>(opts: {
/// <reference types="node" />
/// <reference types="express" />
import * as express from 'express';
import { EventEmitter } from "events";
interface SubscriptionEvents<TOutput> {
data: (data: TOutput) => void;
destroy: () => void;
error: (error: Error) => void;
}
interface SubscriptionEventEmitter<TOutput> {
on<U extends keyof SubscriptionEvents<TOutput>>(event: U, listener: SubscriptionEvents<TOutput>[U]): this;
once<U extends keyof SubscriptionEvents<TOutput>>(event: U, listener: SubscriptionEvents<TOutput>[U]): this;
emit<U extends keyof SubscriptionEvents<TOutput>>(event: U, ...args: Parameters<SubscriptionEvents<TOutput>[U]>): boolean;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
declare class SubscriptionEventEmitter<TOutput> extends EventEmitter {
}
type UnsubscribeFn = () => void;
type EmitFn<TOutput> = (data: TOutput) => void;
type SubscriptionEmit<TOutput> = {
data: EmitFn<TOutput>;
error: EmitFn<Error>;
};
interface SubscriptionOptions<TOutput> {
start: (emit: SubscriptionEmit<TOutput>) => UnsubscribeFn | Promise<UnsubscribeFn>;
}
declare class Subscription<TOutput = unknown> {
private readonly events;
private opts;
private isDestroyed;
constructor(opts: SubscriptionOptions<TOutput>);
destroy(): void;
start(): Promise<void>;
/**
* This method is just here to help with `inferSubscriptionOutput` which I can't get working without it
*/
protected output(): TOutput;
/**
* Emit data
*/
emitOutput(data: TOutput): void;
/**
* Emit error
*/
emitError(err: Error): void;
on(...args: Parameters<SubscriptionEventEmitter<TOutput>["on"]>): SubscriptionEventEmitter<TOutput>;
off(...args: Parameters<SubscriptionEventEmitter<TOutput>["off"]>): SubscriptionEventEmitter<TOutput>;
}
/* eslint-disable @typescript-eslint/ban-types */
/* eslint-disable @typescript-eslint/no-explicit-any */
type Prefix<K extends string, T extends string> = `${K}${T}`;
type format<T> = {
[k in keyof T]: T[k];
};
type Prefixer<TObj extends Record<string, any>, TPrefix extends string> = format<{
[P in keyof TObj as Prefix<TPrefix, string & P>]: TObj[P];
}>;
type RouteInputParserZodEsque<TInput = unknown> = {
parse: (input: any) => TInput;
};
type RouteInputParserCustomValidatorEsque<TInput = unknown> = (input: unknown) => TInput;
type RouteInputParserYupEsque<TInput = unknown> = {
validateSync: (input: unknown) => TInput;
};
type RouteInputParser<TInput = unknown> = RouteInputParserZodEsque<TInput> | RouteInputParserYupEsque<TInput> | RouteInputParserCustomValidatorEsque<TInput>;
type RouteResolver<TContext = unknown, TInput = unknown, TOutput = unknown> = (opts: {
ctx: TContext;
input: TInput;
}) => Promise<TOutput> | TOutput;
type RouteWithInput<TContext = unknown, TInput = unknown, TOutput = unknown> = {
input: RouteInputParser<TInput>;
resolve: RouteResolver<TContext, TInput, TOutput>;
};
type RouteWithoutInput<TContext = unknown, TInput = unknown, TOutput = unknown> = {
input?: undefined | null;
resolve: RouteResolver<TContext, TInput, TOutput>;
};
type Route<TContext = unknown, TInput = unknown, TOutput = unknown> = RouteWithInput<TContext, TInput, TOutput> | RouteWithoutInput<TContext, TInput, TOutput>;
type RouteRecord<TContext = unknown, TInput = unknown, TOutput = unknown> = Record<string, Route<TContext, TInput, TOutput>>;
type AnyRouter<TContext = any> = Router<TContext, any, any, any>;
declare class Router<TContext, TQueries extends RouteRecord<TContext>, TMutations extends RouteRecord<TContext>, TSubscriptions extends RouteRecord<TContext, unknown, Subscription<unknown>>> {
readonly _def: Readonly<{
queries: Readonly<TQueries>;
mutations: Readonly<TMutations>;
subscriptions: Readonly<TSubscriptions>;
}>;
constructor(def?: {
queries: TQueries;
mutations: TMutations;
subscriptions: TSubscriptions;
});
private static prefixRoutes;
query<TPath extends string, TInput, TOutput>(path: TPath, route: Route<TContext, TInput, TOutput>): Router<TContext, TQueries & Record<TPath, typeof route>, TMutations, TSubscriptions>;
// TODO / help: https://github.com/trpc/trpc/pull/37
// public queries<TRoutes extends RouteRecord<TContext, any, any>>(
// routes: TRoutes,
// ): Router<TContext, TQueries & TRoutes, TMutations, TSubscriptions> {
// const router = new Router<TContext, any, {}, {}>({
// queries: routes,
// mutations: {},
// subscriptions: {},
// });
// return this.merge(router) as any;
// }
mutation<TPath extends string, TInput, TOutput>(path: TPath, route: Route<TContext, TInput, TOutput>): Router<TContext, TQueries, TMutations & Record<TPath, typeof route>, TSubscriptions>;
subscription<TPath extends string, TInput, TOutput extends Subscription>(path: TPath, route: Route<TContext, TInput, TOutput>): Router<TContext, TQueries, TMutations, TSubscriptions & Record<TPath, typeof route>>;
/**
* Merge router with other router
* @param router
*/
merge<TChildRouter extends AnyRouter<TContext>>(router: TChildRouter): Router<TContext, TQueries & TChildRouter["_def"]["queries"], TMutations & TChildRouter["_def"]["mutations"], TSubscriptions & TChildRouter["_def"]["subscriptions"]>;
/**
* Merge router with other router
* @param prefix Prefix that this router should live under
* @param router
*/
merge<TPath extends string, TChildRouter extends AnyRouter<TContext>>(prefix: TPath, router: TChildRouter): Router<TContext, TQueries & Prefixer<TChildRouter["_def"]["queries"], `${TPath}`>, TMutations & Prefixer<TChildRouter["_def"]["mutations"], `${TPath}`>, TSubscriptions & Prefixer<TChildRouter["_def"]["subscriptions"], `${TPath}`>>;
private static getInput;
invoke(opts: {
target: "queries" | "subscriptions" | "mutations";
ctx: TContext;
path: string;
input?: unknown;
}): Promise<unknown>;
has(what: "subscriptions" | "mutations" | "queries", path: string): boolean;
}
/* eslint-disable @typescript-eslint/no-explicit-any */
type DataTransformer = {
serialize(object: any): any;
deserialize(object: any): any;
};
type CreateContextFnOptions<TRequest, TResponse> = {
req: TRequest;
res: TResponse;
};
type CreateContextFn<TContext, TRequest, TResponse> = (opts: CreateContextFnOptions<TRequest, TResponse>) => TContext | Promise<TContext>;
interface BaseOptions {
subscriptions?: {
/**
* Time in milliseconds before `408` is sent
*/
requestTimeoutMs?: number;
/**
* Allow for some backpressure and batch send events every X ms
*/
backpressureMs?: number;
};
teardown?: () => Promise<void>;
/**
* Optional transformer too serialize/deserialize input args + data
*/
transformer?: DataTransformer;
maxBodySize?: number;
}
type CreateExpressContextOptions = CreateContextFnOptions<express.Request, express.Response>;
type CreateExpressContextFn<TContext> = CreateContextFn<TContext, express.Request, express.Response>;
declare function createExpressMiddleware<TContext, TRouter extends Router<TContext, any, any, any>>(opts: {
router: TRouter;
createContext: CreateExpressContextFn<TContext>;
} & BaseOptions): express.Handler;
export { CreateExpressContextOptions, CreateExpressContextFn, createExpressMiddleware };

@@ -1,9 +0,160 @@

import type * as Next from 'next';
import { BaseOptions, CreateContextFn, CreateContextFnOptions } from '../http';
import { Router } from '../router';
export declare type CreateNextContextOptions = CreateContextFnOptions<Next.NextApiRequest, Next.NextApiResponse>;
export declare type CreateNextContextFn<TContext> = CreateContextFn<TContext, Next.NextApiRequest, Next.NextApiResponse>;
export declare function createNextApiHandler<TContext, TRouter extends Router<TContext, any, any, any>>(opts: {
/// <reference types="node" />
import * as Next from 'next';
import { EventEmitter } from "events";
interface SubscriptionEvents<TOutput> {
data: (data: TOutput) => void;
destroy: () => void;
error: (error: Error) => void;
}
interface SubscriptionEventEmitter<TOutput> {
on<U extends keyof SubscriptionEvents<TOutput>>(event: U, listener: SubscriptionEvents<TOutput>[U]): this;
once<U extends keyof SubscriptionEvents<TOutput>>(event: U, listener: SubscriptionEvents<TOutput>[U]): this;
emit<U extends keyof SubscriptionEvents<TOutput>>(event: U, ...args: Parameters<SubscriptionEvents<TOutput>[U]>): boolean;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
declare class SubscriptionEventEmitter<TOutput> extends EventEmitter {
}
type UnsubscribeFn = () => void;
type EmitFn<TOutput> = (data: TOutput) => void;
type SubscriptionEmit<TOutput> = {
data: EmitFn<TOutput>;
error: EmitFn<Error>;
};
interface SubscriptionOptions<TOutput> {
start: (emit: SubscriptionEmit<TOutput>) => UnsubscribeFn | Promise<UnsubscribeFn>;
}
declare class Subscription<TOutput = unknown> {
private readonly events;
private opts;
private isDestroyed;
constructor(opts: SubscriptionOptions<TOutput>);
destroy(): void;
start(): Promise<void>;
/**
* This method is just here to help with `inferSubscriptionOutput` which I can't get working without it
*/
protected output(): TOutput;
/**
* Emit data
*/
emitOutput(data: TOutput): void;
/**
* Emit error
*/
emitError(err: Error): void;
on(...args: Parameters<SubscriptionEventEmitter<TOutput>["on"]>): SubscriptionEventEmitter<TOutput>;
off(...args: Parameters<SubscriptionEventEmitter<TOutput>["off"]>): SubscriptionEventEmitter<TOutput>;
}
/* eslint-disable @typescript-eslint/ban-types */
/* eslint-disable @typescript-eslint/no-explicit-any */
type Prefix<K extends string, T extends string> = `${K}${T}`;
type format<T> = {
[k in keyof T]: T[k];
};
type Prefixer<TObj extends Record<string, any>, TPrefix extends string> = format<{
[P in keyof TObj as Prefix<TPrefix, string & P>]: TObj[P];
}>;
type RouteInputParserZodEsque<TInput = unknown> = {
parse: (input: any) => TInput;
};
type RouteInputParserCustomValidatorEsque<TInput = unknown> = (input: unknown) => TInput;
type RouteInputParserYupEsque<TInput = unknown> = {
validateSync: (input: unknown) => TInput;
};
type RouteInputParser<TInput = unknown> = RouteInputParserZodEsque<TInput> | RouteInputParserYupEsque<TInput> | RouteInputParserCustomValidatorEsque<TInput>;
type RouteResolver<TContext = unknown, TInput = unknown, TOutput = unknown> = (opts: {
ctx: TContext;
input: TInput;
}) => Promise<TOutput> | TOutput;
type RouteWithInput<TContext = unknown, TInput = unknown, TOutput = unknown> = {
input: RouteInputParser<TInput>;
resolve: RouteResolver<TContext, TInput, TOutput>;
};
type RouteWithoutInput<TContext = unknown, TInput = unknown, TOutput = unknown> = {
input?: undefined | null;
resolve: RouteResolver<TContext, TInput, TOutput>;
};
type Route<TContext = unknown, TInput = unknown, TOutput = unknown> = RouteWithInput<TContext, TInput, TOutput> | RouteWithoutInput<TContext, TInput, TOutput>;
type RouteRecord<TContext = unknown, TInput = unknown, TOutput = unknown> = Record<string, Route<TContext, TInput, TOutput>>;
type AnyRouter<TContext = any> = Router<TContext, any, any, any>;
declare class Router<TContext, TQueries extends RouteRecord<TContext>, TMutations extends RouteRecord<TContext>, TSubscriptions extends RouteRecord<TContext, unknown, Subscription<unknown>>> {
readonly _def: Readonly<{
queries: Readonly<TQueries>;
mutations: Readonly<TMutations>;
subscriptions: Readonly<TSubscriptions>;
}>;
constructor(def?: {
queries: TQueries;
mutations: TMutations;
subscriptions: TSubscriptions;
});
private static prefixRoutes;
query<TPath extends string, TInput, TOutput>(path: TPath, route: Route<TContext, TInput, TOutput>): Router<TContext, TQueries & Record<TPath, typeof route>, TMutations, TSubscriptions>;
// TODO / help: https://github.com/trpc/trpc/pull/37
// public queries<TRoutes extends RouteRecord<TContext, any, any>>(
// routes: TRoutes,
// ): Router<TContext, TQueries & TRoutes, TMutations, TSubscriptions> {
// const router = new Router<TContext, any, {}, {}>({
// queries: routes,
// mutations: {},
// subscriptions: {},
// });
// return this.merge(router) as any;
// }
mutation<TPath extends string, TInput, TOutput>(path: TPath, route: Route<TContext, TInput, TOutput>): Router<TContext, TQueries, TMutations & Record<TPath, typeof route>, TSubscriptions>;
subscription<TPath extends string, TInput, TOutput extends Subscription>(path: TPath, route: Route<TContext, TInput, TOutput>): Router<TContext, TQueries, TMutations, TSubscriptions & Record<TPath, typeof route>>;
/**
* Merge router with other router
* @param router
*/
merge<TChildRouter extends AnyRouter<TContext>>(router: TChildRouter): Router<TContext, TQueries & TChildRouter["_def"]["queries"], TMutations & TChildRouter["_def"]["mutations"], TSubscriptions & TChildRouter["_def"]["subscriptions"]>;
/**
* Merge router with other router
* @param prefix Prefix that this router should live under
* @param router
*/
merge<TPath extends string, TChildRouter extends AnyRouter<TContext>>(prefix: TPath, router: TChildRouter): Router<TContext, TQueries & Prefixer<TChildRouter["_def"]["queries"], `${TPath}`>, TMutations & Prefixer<TChildRouter["_def"]["mutations"], `${TPath}`>, TSubscriptions & Prefixer<TChildRouter["_def"]["subscriptions"], `${TPath}`>>;
private static getInput;
invoke(opts: {
target: "queries" | "subscriptions" | "mutations";
ctx: TContext;
path: string;
input?: unknown;
}): Promise<unknown>;
has(what: "subscriptions" | "mutations" | "queries", path: string): boolean;
}
/* eslint-disable @typescript-eslint/no-explicit-any */
type DataTransformer = {
serialize(object: any): any;
deserialize(object: any): any;
};
type CreateContextFnOptions<TRequest, TResponse> = {
req: TRequest;
res: TResponse;
};
type CreateContextFn<TContext, TRequest, TResponse> = (opts: CreateContextFnOptions<TRequest, TResponse>) => TContext | Promise<TContext>;
interface BaseOptions {
subscriptions?: {
/**
* Time in milliseconds before `408` is sent
*/
requestTimeoutMs?: number;
/**
* Allow for some backpressure and batch send events every X ms
*/
backpressureMs?: number;
};
teardown?: () => Promise<void>;
/**
* Optional transformer too serialize/deserialize input args + data
*/
transformer?: DataTransformer;
maxBodySize?: number;
}
type CreateNextContextOptions = CreateContextFnOptions<Next.NextApiRequest, Next.NextApiResponse>;
type CreateNextContextFn<TContext> = CreateContextFn<TContext, Next.NextApiRequest, Next.NextApiResponse>;
declare function createNextApiHandler<TContext, TRouter extends Router<TContext, any, any, any>>(opts: {
router: TRouter;
createContext: CreateNextContextFn<TContext>;
} & BaseOptions): Next.NextApiHandler;
export { CreateNextContextOptions, CreateNextContextFn, createNextApiHandler };
/// <reference types="node" />
import http from 'http';
import { BaseOptions, CreateContextFn, CreateContextFnOptions } from '../http';
import { AnyRouter } from '../router';
export declare type CreateHttpContextOptions = CreateContextFnOptions<http.IncomingMessage, http.ServerResponse>;
export declare type CreateHttpContextFn<TContext> = CreateContextFn<TContext, http.IncomingMessage, http.ServerResponse>;
export interface CreateHttpHandlerOptions<TRouter extends AnyRouter<TContext>, TContext> extends BaseOptions {
import { EventEmitter } from "events";
interface SubscriptionEvents<TOutput> {
data: (data: TOutput) => void;
destroy: () => void;
error: (error: Error) => void;
}
interface SubscriptionEventEmitter<TOutput> {
on<U extends keyof SubscriptionEvents<TOutput>>(event: U, listener: SubscriptionEvents<TOutput>[U]): this;
once<U extends keyof SubscriptionEvents<TOutput>>(event: U, listener: SubscriptionEvents<TOutput>[U]): this;
emit<U extends keyof SubscriptionEvents<TOutput>>(event: U, ...args: Parameters<SubscriptionEvents<TOutput>[U]>): boolean;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
declare class SubscriptionEventEmitter<TOutput> extends EventEmitter {
}
type UnsubscribeFn = () => void;
type EmitFn<TOutput> = (data: TOutput) => void;
type SubscriptionEmit<TOutput> = {
data: EmitFn<TOutput>;
error: EmitFn<Error>;
};
interface SubscriptionOptions<TOutput> {
start: (emit: SubscriptionEmit<TOutput>) => UnsubscribeFn | Promise<UnsubscribeFn>;
}
declare class Subscription<TOutput = unknown> {
private readonly events;
private opts;
private isDestroyed;
constructor(opts: SubscriptionOptions<TOutput>);
destroy(): void;
start(): Promise<void>;
/**
* This method is just here to help with `inferSubscriptionOutput` which I can't get working without it
*/
protected output(): TOutput;
/**
* Emit data
*/
emitOutput(data: TOutput): void;
/**
* Emit error
*/
emitError(err: Error): void;
on(...args: Parameters<SubscriptionEventEmitter<TOutput>["on"]>): SubscriptionEventEmitter<TOutput>;
off(...args: Parameters<SubscriptionEventEmitter<TOutput>["off"]>): SubscriptionEventEmitter<TOutput>;
}
/* eslint-disable @typescript-eslint/ban-types */
/* eslint-disable @typescript-eslint/no-explicit-any */
type Prefix<K extends string, T extends string> = `${K}${T}`;
type format<T> = {
[k in keyof T]: T[k];
};
type Prefixer<TObj extends Record<string, any>, TPrefix extends string> = format<{
[P in keyof TObj as Prefix<TPrefix, string & P>]: TObj[P];
}>;
type RouteInputParserZodEsque<TInput = unknown> = {
parse: (input: any) => TInput;
};
type RouteInputParserCustomValidatorEsque<TInput = unknown> = (input: unknown) => TInput;
type RouteInputParserYupEsque<TInput = unknown> = {
validateSync: (input: unknown) => TInput;
};
type RouteInputParser<TInput = unknown> = RouteInputParserZodEsque<TInput> | RouteInputParserYupEsque<TInput> | RouteInputParserCustomValidatorEsque<TInput>;
type RouteResolver<TContext = unknown, TInput = unknown, TOutput = unknown> = (opts: {
ctx: TContext;
input: TInput;
}) => Promise<TOutput> | TOutput;
type RouteWithInput<TContext = unknown, TInput = unknown, TOutput = unknown> = {
input: RouteInputParser<TInput>;
resolve: RouteResolver<TContext, TInput, TOutput>;
};
type RouteWithoutInput<TContext = unknown, TInput = unknown, TOutput = unknown> = {
input?: undefined | null;
resolve: RouteResolver<TContext, TInput, TOutput>;
};
type Route<TContext = unknown, TInput = unknown, TOutput = unknown> = RouteWithInput<TContext, TInput, TOutput> | RouteWithoutInput<TContext, TInput, TOutput>;
type RouteRecord<TContext = unknown, TInput = unknown, TOutput = unknown> = Record<string, Route<TContext, TInput, TOutput>>;
type AnyRouter<TContext = any> = Router<TContext, any, any, any>;
declare class Router<TContext, TQueries extends RouteRecord<TContext>, TMutations extends RouteRecord<TContext>, TSubscriptions extends RouteRecord<TContext, unknown, Subscription<unknown>>> {
readonly _def: Readonly<{
queries: Readonly<TQueries>;
mutations: Readonly<TMutations>;
subscriptions: Readonly<TSubscriptions>;
}>;
constructor(def?: {
queries: TQueries;
mutations: TMutations;
subscriptions: TSubscriptions;
});
private static prefixRoutes;
query<TPath extends string, TInput, TOutput>(path: TPath, route: Route<TContext, TInput, TOutput>): Router<TContext, TQueries & Record<TPath, typeof route>, TMutations, TSubscriptions>;
// TODO / help: https://github.com/trpc/trpc/pull/37
// public queries<TRoutes extends RouteRecord<TContext, any, any>>(
// routes: TRoutes,
// ): Router<TContext, TQueries & TRoutes, TMutations, TSubscriptions> {
// const router = new Router<TContext, any, {}, {}>({
// queries: routes,
// mutations: {},
// subscriptions: {},
// });
// return this.merge(router) as any;
// }
mutation<TPath extends string, TInput, TOutput>(path: TPath, route: Route<TContext, TInput, TOutput>): Router<TContext, TQueries, TMutations & Record<TPath, typeof route>, TSubscriptions>;
subscription<TPath extends string, TInput, TOutput extends Subscription>(path: TPath, route: Route<TContext, TInput, TOutput>): Router<TContext, TQueries, TMutations, TSubscriptions & Record<TPath, typeof route>>;
/**
* Merge router with other router
* @param router
*/
merge<TChildRouter extends AnyRouter<TContext>>(router: TChildRouter): Router<TContext, TQueries & TChildRouter["_def"]["queries"], TMutations & TChildRouter["_def"]["mutations"], TSubscriptions & TChildRouter["_def"]["subscriptions"]>;
/**
* Merge router with other router
* @param prefix Prefix that this router should live under
* @param router
*/
merge<TPath extends string, TChildRouter extends AnyRouter<TContext>>(prefix: TPath, router: TChildRouter): Router<TContext, TQueries & Prefixer<TChildRouter["_def"]["queries"], `${TPath}`>, TMutations & Prefixer<TChildRouter["_def"]["mutations"], `${TPath}`>, TSubscriptions & Prefixer<TChildRouter["_def"]["subscriptions"], `${TPath}`>>;
private static getInput;
invoke(opts: {
target: "queries" | "subscriptions" | "mutations";
ctx: TContext;
path: string;
input?: unknown;
}): Promise<unknown>;
has(what: "subscriptions" | "mutations" | "queries", path: string): boolean;
}
/* eslint-disable @typescript-eslint/no-explicit-any */
type DataTransformer = {
serialize(object: any): any;
deserialize(object: any): any;
};
type CreateContextFnOptions<TRequest, TResponse> = {
req: TRequest;
res: TResponse;
};
type CreateContextFn<TContext, TRequest, TResponse> = (opts: CreateContextFnOptions<TRequest, TResponse>) => TContext | Promise<TContext>;
interface BaseOptions {
subscriptions?: {
/**
* Time in milliseconds before `408` is sent
*/
requestTimeoutMs?: number;
/**
* Allow for some backpressure and batch send events every X ms
*/
backpressureMs?: number;
};
teardown?: () => Promise<void>;
/**
* Optional transformer too serialize/deserialize input args + data
*/
transformer?: DataTransformer;
maxBodySize?: number;
}
type CreateHttpContextOptions = CreateContextFnOptions<http.IncomingMessage, http.ServerResponse>;
type CreateHttpContextFn<TContext> = CreateContextFn<TContext, http.IncomingMessage, http.ServerResponse>;
interface CreateHttpHandlerOptions<TRouter extends AnyRouter<TContext>, TContext> extends BaseOptions {
createContext: CreateHttpContextFn<TContext>;
router: TRouter;
}
export declare function createHttpHandler<TContext, TRouter extends AnyRouter<TContext>>(opts: CreateHttpHandlerOptions<TRouter, TContext>): (req: http.IncomingMessage, res: http.ServerResponse) => Promise<void>;
export declare function createHttpServer<TContext, TRouter extends AnyRouter<TContext>>(opts: CreateHttpHandlerOptions<TRouter, TContext>): {
declare function createHttpHandler<TContext, TRouter extends AnyRouter<TContext>>(opts: CreateHttpHandlerOptions<TRouter, TContext>): (req: http.IncomingMessage, res: http.ServerResponse) => Promise<void>;
declare function createHttpServer<TContext, TRouter extends AnyRouter<TContext>>(opts: CreateHttpHandlerOptions<TRouter, TContext>): {
server: http.Server;

@@ -18,1 +167,2 @@ listen(port?: number | undefined): {

};
export { CreateHttpContextOptions, CreateHttpContextFn, CreateHttpHandlerOptions, createHttpHandler, createHttpServer };

@@ -1,9 +0,224 @@

export * from './assertNotBrowser';
export * from './http';
export * from './router';
export * from './types';
export * from './subscription';
export * from './transformer';
export * from './adapters/express';
export * from './adapters/next';
export * from './adapters/standalone';
/// <reference types="node" />
/// <reference types="qs" />
/* eslint-disable @typescript-eslint/no-explicit-any */
import * as http from "http";
import qs from "qs";
import { EventEmitter } from "events";
declare function assertNotBrowser(): void;
declare class InputValidationError<TError extends Error> extends Error {
readonly originalError: TError;
constructor(originalError: TError);
}
interface SubscriptionEvents<TOutput> {
data: (data: TOutput) => void;
destroy: () => void;
error: (error: Error) => void;
}
interface SubscriptionEventEmitter<TOutput> {
on<U extends keyof SubscriptionEvents<TOutput>>(event: U, listener: SubscriptionEvents<TOutput>[U]): this;
once<U extends keyof SubscriptionEvents<TOutput>>(event: U, listener: SubscriptionEvents<TOutput>[U]): this;
emit<U extends keyof SubscriptionEvents<TOutput>>(event: U, ...args: Parameters<SubscriptionEvents<TOutput>[U]>): boolean;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
declare class SubscriptionEventEmitter<TOutput> extends EventEmitter {
}
type UnsubscribeFn = () => void;
type EmitFn<TOutput> = (data: TOutput) => void;
type SubscriptionEmit<TOutput> = {
data: EmitFn<TOutput>;
error: EmitFn<Error>;
};
interface SubscriptionOptions<TOutput> {
start: (emit: SubscriptionEmit<TOutput>) => UnsubscribeFn | Promise<UnsubscribeFn>;
}
declare class Subscription<TOutput = unknown> {
private readonly events;
private opts;
private isDestroyed;
constructor(opts: SubscriptionOptions<TOutput>);
destroy(): void;
start(): Promise<void>;
/**
* This method is just here to help with `inferSubscriptionOutput` which I can't get working without it
*/
protected output(): TOutput;
/**
* Emit data
*/
emitOutput(data: TOutput): void;
/**
* Emit error
*/
emitError(err: Error): void;
on(...args: Parameters<SubscriptionEventEmitter<TOutput>["on"]>): SubscriptionEventEmitter<TOutput>;
off(...args: Parameters<SubscriptionEventEmitter<TOutput>["off"]>): SubscriptionEventEmitter<TOutput>;
}
declare function subscriptionPullFactory<TOutput>(opts: {
/**
* The interval of how often the function should run
*/
intervalMs: number;
pull(emit: SubscriptionEmit<TOutput>): void | Promise<void>;
}): Subscription<TOutput>;
/* eslint-disable @typescript-eslint/ban-types */
/* eslint-disable @typescript-eslint/no-explicit-any */
type Prefix<K extends string, T extends string> = `${K}${T}`;
type identity<T> = T;
type format<T> = {
[k in keyof T]: T[k];
};
type flatten<T, Q> = identity<{
[k in keyof T | keyof Q]: k extends keyof T ? T[k] : k extends keyof Q ? Q[k] : never;
}>;
type Prefixer<TObj extends Record<string, any>, TPrefix extends string> = format<{
[P in keyof TObj as Prefix<TPrefix, string & P>]: TObj[P];
}>;
type Maybe<T> = T | undefined | null;
type ThenArg<T> = T extends PromiseLike<infer U> ? ThenArg<U> : T;
type RouteInputParserZodEsque<TInput = unknown> = {
parse: (input: any) => TInput;
};
type RouteInputParserCustomValidatorEsque<TInput = unknown> = (input: unknown) => TInput;
type RouteInputParserYupEsque<TInput = unknown> = {
validateSync: (input: unknown) => TInput;
};
type RouteInputParser<TInput = unknown> = RouteInputParserZodEsque<TInput> | RouteInputParserYupEsque<TInput> | RouteInputParserCustomValidatorEsque<TInput>;
type RouteResolver<TContext = unknown, TInput = unknown, TOutput = unknown> = (opts: {
ctx: TContext;
input: TInput;
}) => Promise<TOutput> | TOutput;
type RouteWithInput<TContext = unknown, TInput = unknown, TOutput = unknown> = {
input: RouteInputParser<TInput>;
resolve: RouteResolver<TContext, TInput, TOutput>;
};
type RouteWithoutInput<TContext = unknown, TInput = unknown, TOutput = unknown> = {
input?: undefined | null;
resolve: RouteResolver<TContext, TInput, TOutput>;
};
type Route<TContext = unknown, TInput = unknown, TOutput = unknown> = RouteWithInput<TContext, TInput, TOutput> | RouteWithoutInput<TContext, TInput, TOutput>;
type RouteRecord<TContext = unknown, TInput = unknown, TOutput = unknown> = Record<string, Route<TContext, TInput, TOutput>>;
type inferRouteInput<TRoute extends Route<any, any, any>> = TRoute extends RouteWithInput<any, infer Input, any> ? Input : never;
type inferAsyncReturnType<TFunction extends (...args: any) => any> = ThenArg<ReturnType<TFunction>>;
type inferRouteOutput<TRoute extends Route> = inferAsyncReturnType<TRoute["resolve"]>;
type inferSubscriptionOutput<TRouter extends AnyRouter, TPath extends keyof TRouter["_def"]["subscriptions"]> = ReturnType<inferAsyncReturnType<TRouter["_def"]["subscriptions"][TPath]["resolve"]>["output"]>;
type inferHandlerFn<TRoutes extends RouteRecord<any, any, any>> = <TPath extends keyof TRoutes & string, TRoute extends TRoutes[TPath]>(path: TPath, ...args: TRoute extends RouteWithInput<any, any, any> ? [
inferRouteInput<TRoute>
] : [
undefined?
]) => Promise<inferRouteOutput<TRoutes[TPath]>>;
type AnyRouter<TContext = any> = Router<TContext, any, any, any>;
declare class Router<TContext, TQueries extends RouteRecord<TContext>, TMutations extends RouteRecord<TContext>, TSubscriptions extends RouteRecord<TContext, unknown, Subscription<unknown>>> {
readonly _def: Readonly<{
queries: Readonly<TQueries>;
mutations: Readonly<TMutations>;
subscriptions: Readonly<TSubscriptions>;
}>;
constructor(def?: {
queries: TQueries;
mutations: TMutations;
subscriptions: TSubscriptions;
});
private static prefixRoutes;
query<TPath extends string, TInput, TOutput>(path: TPath, route: Route<TContext, TInput, TOutput>): Router<TContext, TQueries & Record<TPath, typeof route>, TMutations, TSubscriptions>;
// TODO / help: https://github.com/trpc/trpc/pull/37
// public queries<TRoutes extends RouteRecord<TContext, any, any>>(
// routes: TRoutes,
// ): Router<TContext, TQueries & TRoutes, TMutations, TSubscriptions> {
// const router = new Router<TContext, any, {}, {}>({
// queries: routes,
// mutations: {},
// subscriptions: {},
// });
// return this.merge(router) as any;
// }
mutation<TPath extends string, TInput, TOutput>(path: TPath, route: Route<TContext, TInput, TOutput>): Router<TContext, TQueries, TMutations & Record<TPath, typeof route>, TSubscriptions>;
subscription<TPath extends string, TInput, TOutput extends Subscription>(path: TPath, route: Route<TContext, TInput, TOutput>): Router<TContext, TQueries, TMutations, TSubscriptions & Record<TPath, typeof route>>;
/**
* Merge router with other router
* @param router
*/
merge<TChildRouter extends AnyRouter<TContext>>(router: TChildRouter): Router<TContext, TQueries & TChildRouter["_def"]["queries"], TMutations & TChildRouter["_def"]["mutations"], TSubscriptions & TChildRouter["_def"]["subscriptions"]>;
/**
* Merge router with other router
* @param prefix Prefix that this router should live under
* @param router
*/
merge<TPath extends string, TChildRouter extends AnyRouter<TContext>>(prefix: TPath, router: TChildRouter): Router<TContext, TQueries & Prefixer<TChildRouter["_def"]["queries"], `${TPath}`>, TMutations & Prefixer<TChildRouter["_def"]["mutations"], `${TPath}`>, TSubscriptions & Prefixer<TChildRouter["_def"]["subscriptions"], `${TPath}`>>;
private static getInput;
invoke(opts: {
target: "queries" | "subscriptions" | "mutations";
ctx: TContext;
path: string;
input?: unknown;
}): Promise<unknown>;
has(what: "subscriptions" | "mutations" | "queries", path: string): boolean;
}
declare function router<TContext>(): Router<TContext, {}, {}, {}>;
/* eslint-disable @typescript-eslint/no-explicit-any */
type DataTransformer = {
serialize(object: any): any;
deserialize(object: any): any;
};
declare class HTTPError extends Error {
readonly statusCode: number;
constructor(statusCode: number, message: string);
}
declare const httpError: {
forbidden: (message?: string | undefined) => HTTPError;
unauthorized: (message?: string | undefined) => HTTPError;
badRequest: (message?: string | undefined) => HTTPError;
notFound: (message?: string | undefined) => HTTPError;
};
type HTTPSuccessResponseEnvelope<TOutput> = {
ok: true;
statusCode: number;
data: TOutput;
};
type HTTPErrorResponseEnvelope = {
ok: false;
statusCode: number;
error: {
message: string;
stack?: string | undefined;
};
};
type HTTPResponseEnvelope<TOutput> = HTTPSuccessResponseEnvelope<TOutput> | HTTPErrorResponseEnvelope;
declare function getErrorResponseEnvelope(_err?: Partial<HTTPError> | InputValidationError<Error>): HTTPErrorResponseEnvelope;
declare function getQueryInput(query: qs.ParsedQs): unknown;
type CreateContextFnOptions<TRequest, TResponse> = {
req: TRequest;
res: TResponse;
};
type CreateContextFn<TContext, TRequest, TResponse> = (opts: CreateContextFnOptions<TRequest, TResponse>) => TContext | Promise<TContext>;
type BaseRequest = http.IncomingMessage & {
method?: string;
query?: qs.ParsedQs;
body?: any;
};
type BaseResponse = http.ServerResponse;
interface BaseOptions {
subscriptions?: {
/**
* Time in milliseconds before `408` is sent
*/
requestTimeoutMs?: number;
/**
* Allow for some backpressure and batch send events every X ms
*/
backpressureMs?: number;
};
teardown?: () => Promise<void>;
/**
* Optional transformer too serialize/deserialize input args + data
*/
transformer?: DataTransformer;
maxBodySize?: number;
}
declare function requestHandler<TContext, TRouter extends Router<TContext, any, any, any>, TCreateContextFn extends CreateContextFn<TContext, TRequest, TResponse>, TRequest extends BaseRequest, TResponse extends BaseResponse>({ req, res, router, path, subscriptions, createContext, teardown, transformer, maxBodySize }: {
req: TRequest;
res: TResponse;
path: string;
router: TRouter;
createContext: TCreateContextFn;
} & BaseOptions): Promise<void>;
export { assertNotBrowser, HTTPError, httpError, HTTPSuccessResponseEnvelope, HTTPErrorResponseEnvelope, HTTPResponseEnvelope, getErrorResponseEnvelope, getQueryInput, CreateContextFnOptions, CreateContextFn, BaseRequest, BaseResponse, BaseOptions, requestHandler, RouteInputParserZodEsque, RouteInputParserCustomValidatorEsque, RouteInputParserYupEsque, RouteInputParser, RouteResolver, RouteWithInput, RouteWithoutInput, Route, RouteRecord, inferRouteInput, inferAsyncReturnType, inferRouteOutput, inferSubscriptionOutput, inferHandlerFn, AnyRouter, Router, router, Prefix, identity, format, flatten, Prefixer, Maybe, ThenArg, SubscriptionEmit, SubscriptionOptions, Subscription, subscriptionPullFactory, DataTransformer };

@@ -0,8 +1,1952 @@

'use strict';
'use strict'
Object.defineProperty(exports, '__esModule', { value: true });
if (process.env.NODE_ENV === 'production') {
module.exports = require('./server.cjs.production.min.js')
} else {
module.exports = require('./server.cjs.development.js')
var tslib = require('tslib');
var events = require('events');
function assertNotBrowser() {
if (typeof window !== 'undefined' &&
process.env.NODE_ENV !== 'test' &&
process.env.JEST_WORKER_ID === undefined) {
throw new Error('Imported server-only code in the broowser');
}
}
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
var punycode = createCommonjsModule(function (module, exports) {
(function(root) {
/** Detect free variables */
var freeExports = exports &&
!exports.nodeType && exports;
var freeModule = module &&
!module.nodeType && module;
var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal;
if (
freeGlobal.global === freeGlobal ||
freeGlobal.window === freeGlobal ||
freeGlobal.self === freeGlobal
) {
root = freeGlobal;
}
/**
* The `punycode` object.
* @name punycode
* @type Object
*/
var punycode,
/** Highest positive signed 32-bit float value */
maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1
/** Bootstring parameters */
base = 36,
tMin = 1,
tMax = 26,
skew = 38,
damp = 700,
initialBias = 72,
initialN = 128, // 0x80
delimiter = '-', // '\x2D'
/** Regular expressions */
regexPunycode = /^xn--/,
regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars
regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators
/** Error messages */
errors = {
'overflow': 'Overflow: input needs wider integers to process',
'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
'invalid-input': 'Invalid input'
},
/** Convenience shortcuts */
baseMinusTMin = base - tMin,
floor = Math.floor,
stringFromCharCode = String.fromCharCode,
/** Temporary variable */
key;
/*--------------------------------------------------------------------------*/
/**
* A generic error utility function.
* @private
* @param {String} type The error type.
* @returns {Error} Throws a `RangeError` with the applicable error message.
*/
function error(type) {
throw RangeError(errors[type]);
}
/**
* A generic `Array#map` utility function.
* @private
* @param {Array} array The array to iterate over.
* @param {Function} callback The function that gets called for every array
* item.
* @returns {Array} A new array of values returned by the callback function.
*/
function map(array, fn) {
var length = array.length;
var result = [];
while (length--) {
result[length] = fn(array[length]);
}
return result;
}
/**
* A simple `Array#map`-like wrapper to work with domain name strings or email
* addresses.
* @private
* @param {String} domain The domain name or email address.
* @param {Function} callback The function that gets called for every
* character.
* @returns {Array} A new string of characters returned by the callback
* function.
*/
function mapDomain(string, fn) {
var parts = string.split('@');
var result = '';
if (parts.length > 1) {
// In email addresses, only the domain name should be punycoded. Leave
// the local part (i.e. everything up to `@`) intact.
result = parts[0] + '@';
string = parts[1];
}
// Avoid `split(regex)` for IE8 compatibility. See #17.
string = string.replace(regexSeparators, '\x2E');
var labels = string.split('.');
var encoded = map(labels, fn).join('.');
return result + encoded;
}
/**
* Creates an array containing the numeric code points of each Unicode
* character in the string. While JavaScript uses UCS-2 internally,
* this function will convert a pair of surrogate halves (each of which
* UCS-2 exposes as separate characters) into a single code point,
* matching UTF-16.
* @see `punycode.ucs2.encode`
* @see <https://mathiasbynens.be/notes/javascript-encoding>
* @memberOf punycode.ucs2
* @name decode
* @param {String} string The Unicode input string (UCS-2).
* @returns {Array} The new array of code points.
*/
function ucs2decode(string) {
var output = [],
counter = 0,
length = string.length,
value,
extra;
while (counter < length) {
value = string.charCodeAt(counter++);
if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
// high surrogate, and there is a next character
extra = string.charCodeAt(counter++);
if ((extra & 0xFC00) == 0xDC00) { // low surrogate
output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
} else {
// unmatched surrogate; only append this code unit, in case the next
// code unit is the high surrogate of a surrogate pair
output.push(value);
counter--;
}
} else {
output.push(value);
}
}
return output;
}
/**
* Creates a string based on an array of numeric code points.
* @see `punycode.ucs2.decode`
* @memberOf punycode.ucs2
* @name encode
* @param {Array} codePoints The array of numeric code points.
* @returns {String} The new Unicode string (UCS-2).
*/
function ucs2encode(array) {
return map(array, function(value) {
var output = '';
if (value > 0xFFFF) {
value -= 0x10000;
output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
value = 0xDC00 | value & 0x3FF;
}
output += stringFromCharCode(value);
return output;
}).join('');
}
/**
* Converts a basic code point into a digit/integer.
* @see `digitToBasic()`
* @private
* @param {Number} codePoint The basic numeric code point value.
* @returns {Number} The numeric value of a basic code point (for use in
* representing integers) in the range `0` to `base - 1`, or `base` if
* the code point does not represent a value.
*/
function basicToDigit(codePoint) {
if (codePoint - 48 < 10) {
return codePoint - 22;
}
if (codePoint - 65 < 26) {
return codePoint - 65;
}
if (codePoint - 97 < 26) {
return codePoint - 97;
}
return base;
}
/**
* Converts a digit/integer into a basic code point.
* @see `basicToDigit()`
* @private
* @param {Number} digit The numeric value of a basic code point.
* @returns {Number} The basic code point whose value (when used for
* representing integers) is `digit`, which needs to be in the range
* `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
* used; else, the lowercase form is used. The behavior is undefined
* if `flag` is non-zero and `digit` has no uppercase form.
*/
function digitToBasic(digit, flag) {
// 0..25 map to ASCII a..z or A..Z
// 26..35 map to ASCII 0..9
return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
}
/**
* Bias adaptation function as per section 3.4 of RFC 3492.
* http://tools.ietf.org/html/rfc3492#section-3.4
* @private
*/
function adapt(delta, numPoints, firstTime) {
var k = 0;
delta = firstTime ? floor(delta / damp) : delta >> 1;
delta += floor(delta / numPoints);
for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
delta = floor(delta / baseMinusTMin);
}
return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
}
/**
* Converts a Punycode string of ASCII-only symbols to a string of Unicode
* symbols.
* @memberOf punycode
* @param {String} input The Punycode string of ASCII-only symbols.
* @returns {String} The resulting string of Unicode symbols.
*/
function decode(input) {
// Don't use UCS-2
var output = [],
inputLength = input.length,
out,
i = 0,
n = initialN,
bias = initialBias,
basic,
j,
index,
oldi,
w,
k,
digit,
t,
/** Cached calculation results */
baseMinusT;
// Handle the basic code points: let `basic` be the number of input code
// points before the last delimiter, or `0` if there is none, then copy
// the first basic code points to the output.
basic = input.lastIndexOf(delimiter);
if (basic < 0) {
basic = 0;
}
for (j = 0; j < basic; ++j) {
// if it's not a basic code point
if (input.charCodeAt(j) >= 0x80) {
error('not-basic');
}
output.push(input.charCodeAt(j));
}
// Main decoding loop: start just after the last delimiter if any basic code
// points were copied; start at the beginning otherwise.
for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {
// `index` is the index of the next character to be consumed.
// Decode a generalized variable-length integer into `delta`,
// which gets added to `i`. The overflow checking is easier
// if we increase `i` as we go, then subtract off its starting
// value at the end to obtain `delta`.
for (oldi = i, w = 1, k = base; /* no condition */; k += base) {
if (index >= inputLength) {
error('invalid-input');
}
digit = basicToDigit(input.charCodeAt(index++));
if (digit >= base || digit > floor((maxInt - i) / w)) {
error('overflow');
}
i += digit * w;
t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
if (digit < t) {
break;
}
baseMinusT = base - t;
if (w > floor(maxInt / baseMinusT)) {
error('overflow');
}
w *= baseMinusT;
}
out = output.length + 1;
bias = adapt(i - oldi, out, oldi == 0);
// `i` was supposed to wrap around from `out` to `0`,
// incrementing `n` each time, so we'll fix that now:
if (floor(i / out) > maxInt - n) {
error('overflow');
}
n += floor(i / out);
i %= out;
// Insert `n` at position `i` of the output
output.splice(i++, 0, n);
}
return ucs2encode(output);
}
/**
* Converts a string of Unicode symbols (e.g. a domain name label) to a
* Punycode string of ASCII-only symbols.
* @memberOf punycode
* @param {String} input The string of Unicode symbols.
* @returns {String} The resulting Punycode string of ASCII-only symbols.
*/
function encode(input) {
var n,
delta,
handledCPCount,
basicLength,
bias,
j,
m,
q,
k,
t,
currentValue,
output = [],
/** `inputLength` will hold the number of code points in `input`. */
inputLength,
/** Cached calculation results */
handledCPCountPlusOne,
baseMinusT,
qMinusT;
// Convert the input in UCS-2 to Unicode
input = ucs2decode(input);
// Cache the length
inputLength = input.length;
// Initialize the state
n = initialN;
delta = 0;
bias = initialBias;
// Handle the basic code points
for (j = 0; j < inputLength; ++j) {
currentValue = input[j];
if (currentValue < 0x80) {
output.push(stringFromCharCode(currentValue));
}
}
handledCPCount = basicLength = output.length;
// `handledCPCount` is the number of code points that have been handled;
// `basicLength` is the number of basic code points.
// Finish the basic string - if it is not empty - with a delimiter
if (basicLength) {
output.push(delimiter);
}
// Main encoding loop:
while (handledCPCount < inputLength) {
// All non-basic code points < n have been handled already. Find the next
// larger one:
for (m = maxInt, j = 0; j < inputLength; ++j) {
currentValue = input[j];
if (currentValue >= n && currentValue < m) {
m = currentValue;
}
}
// Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,
// but guard against overflow
handledCPCountPlusOne = handledCPCount + 1;
if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
error('overflow');
}
delta += (m - n) * handledCPCountPlusOne;
n = m;
for (j = 0; j < inputLength; ++j) {
currentValue = input[j];
if (currentValue < n && ++delta > maxInt) {
error('overflow');
}
if (currentValue == n) {
// Represent delta as a generalized variable-length integer
for (q = delta, k = base; /* no condition */; k += base) {
t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
if (q < t) {
break;
}
qMinusT = q - t;
baseMinusT = base - t;
output.push(
stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
);
q = floor(qMinusT / baseMinusT);
}
output.push(stringFromCharCode(digitToBasic(q, 0)));
bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
delta = 0;
++handledCPCount;
}
}
++delta;
++n;
}
return output.join('');
}
/**
* Converts a Punycode string representing a domain name or an email address
* to Unicode. Only the Punycoded parts of the input will be converted, i.e.
* it doesn't matter if you call it on a string that has already been
* converted to Unicode.
* @memberOf punycode
* @param {String} input The Punycoded domain name or email address to
* convert to Unicode.
* @returns {String} The Unicode representation of the given Punycode
* string.
*/
function toUnicode(input) {
return mapDomain(input, function(string) {
return regexPunycode.test(string)
? decode(string.slice(4).toLowerCase())
: string;
});
}
/**
* Converts a Unicode string representing a domain name or an email address to
* Punycode. Only the non-ASCII parts of the domain name will be converted,
* i.e. it doesn't matter if you call it with a domain that's already in
* ASCII.
* @memberOf punycode
* @param {String} input The domain name or email address to convert, as a
* Unicode string.
* @returns {String} The Punycode representation of the given domain name or
* email address.
*/
function toASCII(input) {
return mapDomain(input, function(string) {
return regexNonASCII.test(string)
? 'xn--' + encode(string)
: string;
});
}
/*--------------------------------------------------------------------------*/
/** Define the public API */
punycode = {
/**
* A string representing the current Punycode.js version number.
* @memberOf punycode
* @type String
*/
'version': '1.3.2',
/**
* An object of methods to convert from JavaScript's internal character
* representation (UCS-2) to Unicode code points, and back.
* @see <https://mathiasbynens.be/notes/javascript-encoding>
* @memberOf punycode
* @type Object
*/
'ucs2': {
'decode': ucs2decode,
'encode': ucs2encode
},
'decode': decode,
'encode': encode,
'toASCII': toASCII,
'toUnicode': toUnicode
};
/** Expose `punycode` */
// Some AMD build optimizers, like r.js, check for specific condition patterns
// like the following:
if (freeExports && freeModule) {
if (module.exports == freeExports) { // in Node.js or RingoJS v0.8.0+
freeModule.exports = punycode;
} else { // in Narwhal or RingoJS v0.7.0-
for (key in punycode) {
punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
}
}
} else { // in Rhino or a web browser
root.punycode = punycode;
}
}(commonjsGlobal));
});
var util = {
isString: function(arg) {
return typeof(arg) === 'string';
},
isObject: function(arg) {
return typeof(arg) === 'object' && arg !== null;
},
isNull: function(arg) {
return arg === null;
},
isNullOrUndefined: function(arg) {
return arg == null;
}
};
// Copyright Joyent, Inc. and other Node contributors.
// If obj.hasOwnProperty has been overridden, then calling
// obj.hasOwnProperty(prop) will break.
// See: https://github.com/joyent/node/issues/1707
function hasOwnProperty(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
var decode = function(qs, sep, eq, options) {
sep = sep || '&';
eq = eq || '=';
var obj = {};
if (typeof qs !== 'string' || qs.length === 0) {
return obj;
}
var regexp = /\+/g;
qs = qs.split(sep);
var maxKeys = 1000;
if (options && typeof options.maxKeys === 'number') {
maxKeys = options.maxKeys;
}
var len = qs.length;
// maxKeys <= 0 means that we should not limit keys count
if (maxKeys > 0 && len > maxKeys) {
len = maxKeys;
}
for (var i = 0; i < len; ++i) {
var x = qs[i].replace(regexp, '%20'),
idx = x.indexOf(eq),
kstr, vstr, k, v;
if (idx >= 0) {
kstr = x.substr(0, idx);
vstr = x.substr(idx + 1);
} else {
kstr = x;
vstr = '';
}
k = decodeURIComponent(kstr);
v = decodeURIComponent(vstr);
if (!hasOwnProperty(obj, k)) {
obj[k] = v;
} else if (Array.isArray(obj[k])) {
obj[k].push(v);
} else {
obj[k] = [obj[k], v];
}
}
return obj;
};
// Copyright Joyent, Inc. and other Node contributors.
var stringifyPrimitive = function(v) {
switch (typeof v) {
case 'string':
return v;
case 'boolean':
return v ? 'true' : 'false';
case 'number':
return isFinite(v) ? v : '';
default:
return '';
}
};
var encode = function(obj, sep, eq, name) {
sep = sep || '&';
eq = eq || '=';
if (obj === null) {
obj = undefined;
}
if (typeof obj === 'object') {
return Object.keys(obj).map(function(k) {
var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
if (Array.isArray(obj[k])) {
return obj[k].map(function(v) {
return ks + encodeURIComponent(stringifyPrimitive(v));
}).join(sep);
} else {
return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
}
}).join(sep);
}
if (!name) return '';
return encodeURIComponent(stringifyPrimitive(name)) + eq +
encodeURIComponent(stringifyPrimitive(obj));
};
var querystring = createCommonjsModule(function (module, exports) {
exports.decode = exports.parse = decode;
exports.encode = exports.stringify = encode;
});
querystring.decode;
querystring.parse;
querystring.encode;
querystring.stringify;
var parse = urlParse;
var resolve = urlResolve;
var resolveObject = urlResolveObject;
var format = urlFormat;
var Url_1 = Url;
function Url() {
this.protocol = null;
this.slashes = null;
this.auth = null;
this.host = null;
this.port = null;
this.hostname = null;
this.hash = null;
this.search = null;
this.query = null;
this.pathname = null;
this.path = null;
this.href = null;
}
// Reference: RFC 3986, RFC 1808, RFC 2396
// define these here so at least they only have to be
// compiled once on the first module load.
var protocolPattern = /^([a-z0-9.+-]+:)/i,
portPattern = /:[0-9]*$/,
// Special case for a simple path URL
simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,
// RFC 2396: characters reserved for delimiting URLs.
// We actually just auto-escape these.
delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'],
// RFC 2396: characters not allowed for various reasons.
unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims),
// Allowed by RFCs, but cause of XSS attacks. Always escape these.
autoEscape = ['\''].concat(unwise),
// Characters that are never ever allowed in a hostname.
// Note that any invalid chars are also handled, but these
// are the ones that are *expected* to be seen, so we fast-path
// them.
nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape),
hostEndingChars = ['/', '?', '#'],
hostnameMaxLen = 255,
hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/,
hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/,
// protocols that can allow "unsafe" and "unwise" chars.
unsafeProtocol = {
'javascript': true,
'javascript:': true
},
// protocols that never have a hostname.
hostlessProtocol = {
'javascript': true,
'javascript:': true
},
// protocols that always contain a // bit.
slashedProtocol = {
'http': true,
'https': true,
'ftp': true,
'gopher': true,
'file': true,
'http:': true,
'https:': true,
'ftp:': true,
'gopher:': true,
'file:': true
};
function urlParse(url, parseQueryString, slashesDenoteHost) {
if (url && util.isObject(url) && url instanceof Url) return url;
var u = new Url;
u.parse(url, parseQueryString, slashesDenoteHost);
return u;
}
Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
if (!util.isString(url)) {
throw new TypeError("Parameter 'url' must be a string, not " + typeof url);
}
// Copy chrome, IE, opera backslash-handling behavior.
// Back slashes before the query string get converted to forward slashes
// See: https://code.google.com/p/chromium/issues/detail?id=25916
var queryIndex = url.indexOf('?'),
splitter =
(queryIndex !== -1 && queryIndex < url.indexOf('#')) ? '?' : '#',
uSplit = url.split(splitter),
slashRegex = /\\/g;
uSplit[0] = uSplit[0].replace(slashRegex, '/');
url = uSplit.join(splitter);
var rest = url;
// trim before proceeding.
// This is to support parse stuff like " http://foo.com \n"
rest = rest.trim();
if (!slashesDenoteHost && url.split('#').length === 1) {
// Try fast path regexp
var simplePath = simplePathPattern.exec(rest);
if (simplePath) {
this.path = rest;
this.href = rest;
this.pathname = simplePath[1];
if (simplePath[2]) {
this.search = simplePath[2];
if (parseQueryString) {
this.query = querystring.parse(this.search.substr(1));
} else {
this.query = this.search.substr(1);
}
} else if (parseQueryString) {
this.search = '';
this.query = {};
}
return this;
}
}
var proto = protocolPattern.exec(rest);
if (proto) {
proto = proto[0];
var lowerProto = proto.toLowerCase();
this.protocol = lowerProto;
rest = rest.substr(proto.length);
}
// figure out if it's got a host
// user@server is *always* interpreted as a hostname, and url
// resolution will treat //foo/bar as host=foo,path=bar because that's
// how the browser resolves relative URLs.
if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) {
var slashes = rest.substr(0, 2) === '//';
if (slashes && !(proto && hostlessProtocol[proto])) {
rest = rest.substr(2);
this.slashes = true;
}
}
if (!hostlessProtocol[proto] &&
(slashes || (proto && !slashedProtocol[proto]))) {
// there's a hostname.
// the first instance of /, ?, ;, or # ends the host.
//
// If there is an @ in the hostname, then non-host chars *are* allowed
// to the left of the last @ sign, unless some host-ending character
// comes *before* the @-sign.
// URLs are obnoxious.
//
// ex:
// http://a@b@c/ => user:a@b host:c
// http://a@b?@c => user:a host:c path:/?@c
// v0.12 TODO(isaacs): This is not quite how Chrome does things.
// Review our test case against browsers more comprehensively.
// find the first instance of any hostEndingChars
var hostEnd = -1;
for (var i = 0; i < hostEndingChars.length; i++) {
var hec = rest.indexOf(hostEndingChars[i]);
if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
hostEnd = hec;
}
// at this point, either we have an explicit point where the
// auth portion cannot go past, or the last @ char is the decider.
var auth, atSign;
if (hostEnd === -1) {
// atSign can be anywhere.
atSign = rest.lastIndexOf('@');
} else {
// atSign must be in auth portion.
// http://a@b/c@d => host:b auth:a path:/c@d
atSign = rest.lastIndexOf('@', hostEnd);
}
// Now we have a portion which is definitely the auth.
// Pull that off.
if (atSign !== -1) {
auth = rest.slice(0, atSign);
rest = rest.slice(atSign + 1);
this.auth = decodeURIComponent(auth);
}
// the host is the remaining to the left of the first non-host char
hostEnd = -1;
for (var i = 0; i < nonHostChars.length; i++) {
var hec = rest.indexOf(nonHostChars[i]);
if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
hostEnd = hec;
}
// if we still have not hit it, then the entire thing is a host.
if (hostEnd === -1)
hostEnd = rest.length;
this.host = rest.slice(0, hostEnd);
rest = rest.slice(hostEnd);
// pull out port.
this.parseHost();
// we've indicated that there is a hostname,
// so even if it's empty, it has to be present.
this.hostname = this.hostname || '';
// if hostname begins with [ and ends with ]
// assume that it's an IPv6 address.
var ipv6Hostname = this.hostname[0] === '[' &&
this.hostname[this.hostname.length - 1] === ']';
// validate a little.
if (!ipv6Hostname) {
var hostparts = this.hostname.split(/\./);
for (var i = 0, l = hostparts.length; i < l; i++) {
var part = hostparts[i];
if (!part) continue;
if (!part.match(hostnamePartPattern)) {
var newpart = '';
for (var j = 0, k = part.length; j < k; j++) {
if (part.charCodeAt(j) > 127) {
// we replace non-ASCII char with a temporary placeholder
// we need this to make sure size of hostname is not
// broken by replacing non-ASCII by nothing
newpart += 'x';
} else {
newpart += part[j];
}
}
// we test again with ASCII char only
if (!newpart.match(hostnamePartPattern)) {
var validParts = hostparts.slice(0, i);
var notHost = hostparts.slice(i + 1);
var bit = part.match(hostnamePartStart);
if (bit) {
validParts.push(bit[1]);
notHost.unshift(bit[2]);
}
if (notHost.length) {
rest = '/' + notHost.join('.') + rest;
}
this.hostname = validParts.join('.');
break;
}
}
}
}
if (this.hostname.length > hostnameMaxLen) {
this.hostname = '';
} else {
// hostnames are always lower case.
this.hostname = this.hostname.toLowerCase();
}
if (!ipv6Hostname) {
// IDNA Support: Returns a punycoded representation of "domain".
// It only converts parts of the domain name that
// have non-ASCII characters, i.e. it doesn't matter if
// you call it with a domain that already is ASCII-only.
this.hostname = punycode.toASCII(this.hostname);
}
var p = this.port ? ':' + this.port : '';
var h = this.hostname || '';
this.host = h + p;
this.href += this.host;
// strip [ and ] from the hostname
// the host field still retains them, though
if (ipv6Hostname) {
this.hostname = this.hostname.substr(1, this.hostname.length - 2);
if (rest[0] !== '/') {
rest = '/' + rest;
}
}
}
// now rest is set to the post-host stuff.
// chop off any delim chars.
if (!unsafeProtocol[lowerProto]) {
// First, make 100% sure that any "autoEscape" chars get
// escaped, even if encodeURIComponent doesn't think they
// need to be.
for (var i = 0, l = autoEscape.length; i < l; i++) {
var ae = autoEscape[i];
if (rest.indexOf(ae) === -1)
continue;
var esc = encodeURIComponent(ae);
if (esc === ae) {
esc = escape(ae);
}
rest = rest.split(ae).join(esc);
}
}
// chop off from the tail first.
var hash = rest.indexOf('#');
if (hash !== -1) {
// got a fragment string.
this.hash = rest.substr(hash);
rest = rest.slice(0, hash);
}
var qm = rest.indexOf('?');
if (qm !== -1) {
this.search = rest.substr(qm);
this.query = rest.substr(qm + 1);
if (parseQueryString) {
this.query = querystring.parse(this.query);
}
rest = rest.slice(0, qm);
} else if (parseQueryString) {
// no query string, but parseQueryString still requested
this.search = '';
this.query = {};
}
if (rest) this.pathname = rest;
if (slashedProtocol[lowerProto] &&
this.hostname && !this.pathname) {
this.pathname = '/';
}
//to support http.request
if (this.pathname || this.search) {
var p = this.pathname || '';
var s = this.search || '';
this.path = p + s;
}
// finally, reconstruct the href based on what has been validated.
this.href = this.format();
return this;
};
// format a parsed object into a url string
function urlFormat(obj) {
// ensure it's an object, and not a string url.
// If it's an obj, this is a no-op.
// this way, you can call url_format() on strings
// to clean up potentially wonky urls.
if (util.isString(obj)) obj = urlParse(obj);
if (!(obj instanceof Url)) return Url.prototype.format.call(obj);
return obj.format();
}
Url.prototype.format = function() {
var auth = this.auth || '';
if (auth) {
auth = encodeURIComponent(auth);
auth = auth.replace(/%3A/i, ':');
auth += '@';
}
var protocol = this.protocol || '',
pathname = this.pathname || '',
hash = this.hash || '',
host = false,
query = '';
if (this.host) {
host = auth + this.host;
} else if (this.hostname) {
host = auth + (this.hostname.indexOf(':') === -1 ?
this.hostname :
'[' + this.hostname + ']');
if (this.port) {
host += ':' + this.port;
}
}
if (this.query &&
util.isObject(this.query) &&
Object.keys(this.query).length) {
query = querystring.stringify(this.query);
}
var search = this.search || (query && ('?' + query)) || '';
if (protocol && protocol.substr(-1) !== ':') protocol += ':';
// only the slashedProtocols get the //. Not mailto:, xmpp:, etc.
// unless they had them to begin with.
if (this.slashes ||
(!protocol || slashedProtocol[protocol]) && host !== false) {
host = '//' + (host || '');
if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;
} else if (!host) {
host = '';
}
if (hash && hash.charAt(0) !== '#') hash = '#' + hash;
if (search && search.charAt(0) !== '?') search = '?' + search;
pathname = pathname.replace(/[?#]/g, function(match) {
return encodeURIComponent(match);
});
search = search.replace('#', '%23');
return protocol + host + pathname + search + hash;
};
function urlResolve(source, relative) {
return urlParse(source, false, true).resolve(relative);
}
Url.prototype.resolve = function(relative) {
return this.resolveObject(urlParse(relative, false, true)).format();
};
function urlResolveObject(source, relative) {
if (!source) return relative;
return urlParse(source, false, true).resolveObject(relative);
}
Url.prototype.resolveObject = function(relative) {
if (util.isString(relative)) {
var rel = new Url();
rel.parse(relative, false, true);
relative = rel;
}
var result = new Url();
var tkeys = Object.keys(this);
for (var tk = 0; tk < tkeys.length; tk++) {
var tkey = tkeys[tk];
result[tkey] = this[tkey];
}
// hash is always overridden, no matter what.
// even href="" will remove it.
result.hash = relative.hash;
// if the relative url is empty, then there's nothing left to do here.
if (relative.href === '') {
result.href = result.format();
return result;
}
// hrefs like //foo/bar always cut to the protocol.
if (relative.slashes && !relative.protocol) {
// take everything except the protocol from relative
var rkeys = Object.keys(relative);
for (var rk = 0; rk < rkeys.length; rk++) {
var rkey = rkeys[rk];
if (rkey !== 'protocol')
result[rkey] = relative[rkey];
}
//urlParse appends trailing / to urls like http://www.example.com
if (slashedProtocol[result.protocol] &&
result.hostname && !result.pathname) {
result.path = result.pathname = '/';
}
result.href = result.format();
return result;
}
if (relative.protocol && relative.protocol !== result.protocol) {
// if it's a known url protocol, then changing
// the protocol does weird things
// first, if it's not file:, then we MUST have a host,
// and if there was a path
// to begin with, then we MUST have a path.
// if it is file:, then the host is dropped,
// because that's known to be hostless.
// anything else is assumed to be absolute.
if (!slashedProtocol[relative.protocol]) {
var keys = Object.keys(relative);
for (var v = 0; v < keys.length; v++) {
var k = keys[v];
result[k] = relative[k];
}
result.href = result.format();
return result;
}
result.protocol = relative.protocol;
if (!relative.host && !hostlessProtocol[relative.protocol]) {
var relPath = (relative.pathname || '').split('/');
while (relPath.length && !(relative.host = relPath.shift()));
if (!relative.host) relative.host = '';
if (!relative.hostname) relative.hostname = '';
if (relPath[0] !== '') relPath.unshift('');
if (relPath.length < 2) relPath.unshift('');
result.pathname = relPath.join('/');
} else {
result.pathname = relative.pathname;
}
result.search = relative.search;
result.query = relative.query;
result.host = relative.host || '';
result.auth = relative.auth;
result.hostname = relative.hostname || relative.host;
result.port = relative.port;
// to support http.request
if (result.pathname || result.search) {
var p = result.pathname || '';
var s = result.search || '';
result.path = p + s;
}
result.slashes = result.slashes || relative.slashes;
result.href = result.format();
return result;
}
var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'),
isRelAbs = (
relative.host ||
relative.pathname && relative.pathname.charAt(0) === '/'
),
mustEndAbs = (isRelAbs || isSourceAbs ||
(result.host && relative.pathname)),
removeAllDots = mustEndAbs,
srcPath = result.pathname && result.pathname.split('/') || [],
relPath = relative.pathname && relative.pathname.split('/') || [],
psychotic = result.protocol && !slashedProtocol[result.protocol];
// if the url is a non-slashed url, then relative
// links like ../.. should be able
// to crawl up to the hostname, as well. This is strange.
// result.protocol has already been set by now.
// Later on, put the first path part into the host field.
if (psychotic) {
result.hostname = '';
result.port = null;
if (result.host) {
if (srcPath[0] === '') srcPath[0] = result.host;
else srcPath.unshift(result.host);
}
result.host = '';
if (relative.protocol) {
relative.hostname = null;
relative.port = null;
if (relative.host) {
if (relPath[0] === '') relPath[0] = relative.host;
else relPath.unshift(relative.host);
}
relative.host = null;
}
mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');
}
if (isRelAbs) {
// it's absolute.
result.host = (relative.host || relative.host === '') ?
relative.host : result.host;
result.hostname = (relative.hostname || relative.hostname === '') ?
relative.hostname : result.hostname;
result.search = relative.search;
result.query = relative.query;
srcPath = relPath;
// fall through to the dot-handling below.
} else if (relPath.length) {
// it's relative
// throw away the existing file, and take the new path instead.
if (!srcPath) srcPath = [];
srcPath.pop();
srcPath = srcPath.concat(relPath);
result.search = relative.search;
result.query = relative.query;
} else if (!util.isNullOrUndefined(relative.search)) {
// just pull out the search.
// like href='?foo'.
// Put this after the other two cases because it simplifies the booleans
if (psychotic) {
result.hostname = result.host = srcPath.shift();
//occationaly the auth can get stuck only in host
//this especially happens in cases like
//url.resolveObject('mailto:local1@domain1', 'local2@domain2')
var authInHost = result.host && result.host.indexOf('@') > 0 ?
result.host.split('@') : false;
if (authInHost) {
result.auth = authInHost.shift();
result.host = result.hostname = authInHost.shift();
}
}
result.search = relative.search;
result.query = relative.query;
//to support http.request
if (!util.isNull(result.pathname) || !util.isNull(result.search)) {
result.path = (result.pathname ? result.pathname : '') +
(result.search ? result.search : '');
}
result.href = result.format();
return result;
}
if (!srcPath.length) {
// no path at all. easy.
// we've already handled the other stuff above.
result.pathname = null;
//to support http.request
if (result.search) {
result.path = '/' + result.search;
} else {
result.path = null;
}
result.href = result.format();
return result;
}
// if a url ENDs in . or .., then it must get a trailing slash.
// however, if it ends in anything else non-slashy,
// then it must NOT get a trailing slash.
var last = srcPath.slice(-1)[0];
var hasTrailingSlash = (
(result.host || relative.host || srcPath.length > 1) &&
(last === '.' || last === '..') || last === '');
// strip single dots, resolve double dots to parent dir
// if the path tries to go above the root, `up` ends up > 0
var up = 0;
for (var i = srcPath.length; i >= 0; i--) {
last = srcPath[i];
if (last === '.') {
srcPath.splice(i, 1);
} else if (last === '..') {
srcPath.splice(i, 1);
up++;
} else if (up) {
srcPath.splice(i, 1);
up--;
}
}
// if the path is allowed to go above the root, restore leading ..s
if (!mustEndAbs && !removeAllDots) {
for (; up--; up) {
srcPath.unshift('..');
}
}
if (mustEndAbs && srcPath[0] !== '' &&
(!srcPath[0] || srcPath[0].charAt(0) !== '/')) {
srcPath.unshift('');
}
if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) {
srcPath.push('');
}
var isAbsolute = srcPath[0] === '' ||
(srcPath[0] && srcPath[0].charAt(0) === '/');
// put the host back
if (psychotic) {
result.hostname = result.host = isAbsolute ? '' :
srcPath.length ? srcPath.shift() : '';
//occationaly the auth can get stuck only in host
//this especially happens in cases like
//url.resolveObject('mailto:local1@domain1', 'local2@domain2')
var authInHost = result.host && result.host.indexOf('@') > 0 ?
result.host.split('@') : false;
if (authInHost) {
result.auth = authInHost.shift();
result.host = result.hostname = authInHost.shift();
}
}
mustEndAbs = mustEndAbs || (result.host && srcPath.length);
if (mustEndAbs && !isAbsolute) {
srcPath.unshift('');
}
if (!srcPath.length) {
result.pathname = null;
result.path = null;
} else {
result.pathname = srcPath.join('/');
}
//to support request.http
if (!util.isNull(result.pathname) || !util.isNull(result.search)) {
result.path = (result.pathname ? result.pathname : '') +
(result.search ? result.search : '');
}
result.auth = relative.auth || result.auth;
result.slashes = result.slashes || relative.slashes;
result.href = result.format();
return result;
};
Url.prototype.parseHost = function() {
var host = this.host;
var port = portPattern.exec(host);
if (port) {
port = port[0];
if (port !== ':') {
this.port = port.substr(1);
}
host = host.substr(0, host.length - port.length);
}
if (host) this.hostname = host;
};
var url = {
parse: parse,
resolve: resolve,
resolveObject: resolveObject,
format: format,
Url: Url_1
};
var InputValidationError = /** @class */ (function (_super) {
tslib.__extends(InputValidationError, _super);
function InputValidationError(originalError) {
var _this = _super.call(this, originalError.message) || this;
_this.originalError = originalError;
Object.setPrototypeOf(_this, InputValidationError.prototype);
return _this;
}
return InputValidationError;
}(Error));
var RouteNotFoundError = /** @class */ (function (_super) {
tslib.__extends(RouteNotFoundError, _super);
function RouteNotFoundError(message) {
var _this = _super.call(this, message) || this;
Object.setPrototypeOf(_this, RouteNotFoundError.prototype);
return _this;
}
return RouteNotFoundError;
}(Error));
assertNotBrowser();
var HTTPError = /** @class */ (function (_super) {
tslib.__extends(HTTPError, _super);
function HTTPError(statusCode, message) {
var _this = _super.call(this, message) || this;
_this.statusCode = statusCode;
Object.setPrototypeOf(_this, HTTPError.prototype);
return _this;
}
return HTTPError;
}(Error));
var httpError = {
forbidden: function (message) { return new HTTPError(403, message !== null && message !== void 0 ? message : 'Forbidden'); },
unauthorized: function (message) {
return new HTTPError(401, message !== null && message !== void 0 ? message : 'Unauthorized');
},
badRequest: function (message) {
return new HTTPError(400, message !== null && message !== void 0 ? message : 'Bad Request');
},
notFound: function (message) { return new HTTPError(404, message !== null && message !== void 0 ? message : 'Not found'); }
};
function getErrorResponseEnvelope(_err) {
var err = _err;
if (err instanceof InputValidationError) {
err = httpError.badRequest(err.message);
}
else if (err instanceof RouteNotFoundError) {
err = httpError.notFound(err.message);
}
var statusCode = typeof (err === null || err === void 0 ? void 0 : err.statusCode) === 'number' ? err.statusCode : 500;
var message = typeof (err === null || err === void 0 ? void 0 : err.message) === 'string' ? err.message : 'Internal Server Error';
var stack = process.env.NODE_ENV !== 'production' && typeof (err === null || err === void 0 ? void 0 : err.stack) === 'string'
? err.stack
: undefined;
var json = {
ok: false,
statusCode: statusCode,
error: {
message: message,
stack: stack
}
};
return json;
}
function getQueryInput(query) {
var input = undefined;
var queryInput = query.input;
if (!queryInput) {
return input;
}
// console.log('query', queryInput);
if (typeof queryInput !== 'string') {
throw httpError.badRequest('Expected query.input to be a JSON string');
}
try {
input = JSON.parse(queryInput);
}
catch (err) {
throw httpError.badRequest('Expected query.input to be a JSON string');
}
return input;
}
function getPostBody(_a) {
var req = _a.req, maxBodySize = _a.maxBodySize;
return tslib.__awaiter(this, void 0, void 0, function () {
return tslib.__generator(this, function (_b) {
return [2 /*return*/, new Promise(function (resolve, reject) {
if (req.body) {
resolve(req.body);
return;
}
var body = '';
req.on('data', function (data) {
body += data;
if (typeof maxBodySize === 'number' && body.length > maxBodySize) {
reject(new HTTPError(413, 'Payload Too Large'));
req.connection.destroy();
}
});
req.on('end', function () {
try {
var json = JSON.parse(body);
resolve(json);
}
catch (err) {
reject(httpError.badRequest("Body couldn't be parsed as json"));
}
});
})];
});
});
}
function requestHandler(_a) {
var _b, _c;
var req = _a.req, res = _a.res, router = _a.router, path = _a.path, subscriptions = _a.subscriptions, createContext = _a.createContext, teardown = _a.teardown, _d = _a.transformer, transformer = _d === void 0 ? {
serialize: function (data) { return data; },
deserialize: function (data) { return data; }
} : _d, maxBodySize = _a.maxBodySize;
return tslib.__awaiter(this, void 0, void 0, function () {
var output, ctx, _e, method, deserializeInput, body, input, query, input, body, input, sub_1, json, err_1, json, _f, err_2;
return tslib.__generator(this, function (_g) {
switch (_g.label) {
case 0:
_g.trys.push([0, 13, , 14]);
output = void 0;
_e = createContext;
if (!_e) return [3 /*break*/, 2];
return [4 /*yield*/, createContext({ req: req, res: res })];
case 1:
_e = (_g.sent());
_g.label = 2;
case 2:
ctx = _e;
method = (_b = req.method) !== null && _b !== void 0 ? _b : 'GET';
deserializeInput = function (input) {
return input ? transformer.deserialize(input) : input;
};
if (!(method === 'POST')) return [3 /*break*/, 5];
return [4 /*yield*/, getPostBody({ req: req, maxBodySize: maxBodySize })];
case 3:
body = _g.sent();
input = deserializeInput(body.input);
return [4 /*yield*/, router.invoke({
target: 'mutations',
input: input,
ctx: ctx,
path: path
})];
case 4:
output = _g.sent();
return [3 /*break*/, 12];
case 5:
if (!(method === 'GET')) return [3 /*break*/, 7];
query = req.query ? req.query : url.parse(req.url, true).query;
input = deserializeInput(getQueryInput(query));
return [4 /*yield*/, router.invoke({
target: 'queries',
input: input,
ctx: ctx,
path: path
})];
case 6:
output = _g.sent();
return [3 /*break*/, 12];
case 7:
if (!(method === 'PATCH')) return [3 /*break*/, 11];
return [4 /*yield*/, getPostBody({ req: req, maxBodySize: maxBodySize })];
case 8:
body = _g.sent();
input = deserializeInput(body.input);
return [4 /*yield*/, router.invoke({
target: 'subscriptions',
input: input,
ctx: ctx,
path: path
})];
case 9:
sub_1 = (_g.sent());
return [4 /*yield*/, new Promise(function (resolve, reject) {
var _a, _b;
var startTime = Date.now();
var buffer = [];
var requestTimeoutMs = (_a = subscriptions === null || subscriptions === void 0 ? void 0 : subscriptions.requestTimeoutMs) !== null && _a !== void 0 ? _a : 9000; // 10s is vercel's api timeout
var backpressureMs = (_b = subscriptions === null || subscriptions === void 0 ? void 0 : subscriptions.backpressureMs) !== null && _b !== void 0 ? _b : 0;
// timers
var backpressureTimer = null;
var requestTimeoutTimer = null;
function cleanup() {
sub_1.off('data', onData);
sub_1.off('error', onError);
sub_1.off('destroy', onDestroy);
req.off('close', onClose);
clearTimeout(requestTimeoutTimer);
clearTimeout(backpressureTimer);
sub_1.destroy();
}
function onData(data) {
buffer.push(data);
var requestTimeLeft = requestTimeoutMs - (Date.now() - startTime);
var success = function () {
cleanup();
resolve(buffer);
};
if (requestTimeLeft <= backpressureMs) {
// will timeout before next backpressure tick
success();
return;
}
if (!backpressureTimer) {
backpressureTimer = setTimeout(success, backpressureMs);
return;
}
}
function onError(err) {
cleanup();
// maybe if `buffer` has length here we should just return instead?
reject(err);
}
function onClose() {
cleanup();
reject(new HTTPError(499, "Client Closed Request"));
}
function onRequestTimeout() {
cleanup();
reject(new HTTPError(408, "Subscription exceeded " + requestTimeoutMs + "ms - please reconnect."));
}
function onDestroy() {
reject(new HTTPError(500, "Subscription was destroyed prematurely"));
cleanup();
}
sub_1.on('data', onData);
sub_1.on('error', onError);
sub_1.on('destroy', onDestroy);
req.once('close', onClose);
requestTimeoutTimer = setTimeout(onRequestTimeout, requestTimeoutMs);
sub_1.start();
})];
case 10:
output = _g.sent();
return [3 /*break*/, 12];
case 11: throw httpError.badRequest("Unexpected request method " + method);
case 12:
json = {
ok: true,
statusCode: (_c = res.statusCode) !== null && _c !== void 0 ? _c : 200,
data: output
};
res.statusCode = json.statusCode;
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify(transformer.serialize(json)));
return [3 /*break*/, 14];
case 13:
err_1 = _g.sent();
json = getErrorResponseEnvelope(err_1);
res.statusCode = json.statusCode;
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify(transformer.serialize(json)));
return [3 /*break*/, 14];
case 14:
_g.trys.push([14, 17, , 18]);
_f = teardown;
if (!_f) return [3 /*break*/, 16];
return [4 /*yield*/, teardown()];
case 15:
_f = (_g.sent());
_g.label = 16;
case 16:
return [3 /*break*/, 18];
case 17:
err_2 = _g.sent();
console.error('Teardown failed', err_2);
return [3 /*break*/, 18];
case 18: return [2 /*return*/];
}
});
});
}
/* eslint-disable @typescript-eslint/ban-types */
assertNotBrowser();
var Router = /** @class */ (function () {
function Router(def) {
this._def = def !== null && def !== void 0 ? def : {
queries: {},
mutations: {},
subscriptions: {}
};
}
Router.prefixRoutes = function (routes, prefix) {
var eps = {};
for (var key in routes) {
eps[prefix + key] = routes[key];
}
return eps;
};
Router.prototype.query = function (path, route) {
var _a;
var router = new Router({
queries: (_a = {},
_a[path] = route,
_a),
mutations: {},
subscriptions: {}
});
return this.merge(router);
};
// TODO / help: https://github.com/trpc/trpc/pull/37
// public queries<TRoutes extends RouteRecord<TContext, any, any>>(
// routes: TRoutes,
// ): Router<TContext, TQueries & TRoutes, TMutations, TSubscriptions> {
// const router = new Router<TContext, any, {}, {}>({
// queries: routes,
// mutations: {},
// subscriptions: {},
// });
// return this.merge(router) as any;
// }
Router.prototype.mutation = function (path, route) {
var _a;
var router = new Router({
queries: {},
mutations: (_a = {},
_a[path] = route,
_a),
subscriptions: {}
});
return this.merge(router);
};
Router.prototype.subscription = function (path, route) {
var _a;
var router = new Router({
queries: {},
mutations: {},
subscriptions: (_a = {},
_a[path] = route,
_a)
});
return this.merge(router);
};
Router.prototype.merge = function (prefixOrRouter, maybeRouter) {
var _this = this;
var prefix = '';
var router;
if (typeof prefixOrRouter === 'string' && maybeRouter instanceof Router) {
prefix = prefixOrRouter;
router = maybeRouter;
}
else if (prefixOrRouter instanceof Router) {
router = prefixOrRouter;
}
else {
throw new Error('Invalid args');
}
var duplicateQueries = Object.keys(router._def.queries).filter(function (key) {
return _this.has('queries', key);
});
var duplicateMutations = Object.keys(router._def.mutations).filter(function (key) { return _this.has('mutations', key); });
var duplicateSubscriptions = Object.keys(router._def.subscriptions).filter(function (key) { return _this.has('subscriptions', key); });
var duplicates = tslib.__spreadArrays(duplicateQueries, duplicateMutations, duplicateSubscriptions);
if (duplicates.length) {
throw new Error("Duplicate endpoint(s): " + duplicates.join(', '));
}
return new Router({
queries: tslib.__assign(tslib.__assign({}, this._def.queries), Router.prefixRoutes(router._def.queries, prefix)),
mutations: tslib.__assign(tslib.__assign({}, this._def.mutations), Router.prefixRoutes(router._def.mutations, prefix)),
subscriptions: tslib.__assign(tslib.__assign({}, this._def.subscriptions), Router.prefixRoutes(router._def.subscriptions, prefix))
});
};
Router.getInput = function (route, rawInput) {
if (!route.input) {
return undefined;
}
try {
var anyInput = route.input;
if (typeof anyInput.parse === 'function') {
return anyInput.parse(rawInput);
}
if (typeof anyInput === 'function') {
return anyInput(rawInput);
}
if (typeof anyInput.validateSync === 'function') {
return anyInput.validateSync(rawInput);
}
throw new Error('Could not find a validator fn');
}
catch (_err) {
var err = new InputValidationError(_err);
throw err;
}
};
Router.prototype.invoke = function (opts) {
return tslib.__awaiter(this, void 0, void 0, function () {
var target, route, input, ctx;
return tslib.__generator(this, function (_a) {
if (!this.has(opts.target, opts.path)) {
throw new RouteNotFoundError("No such route \"" + opts.path + "\"");
}
target = this._def[opts.target];
route = target[opts.path];
input = Router.getInput(route, opts.input);
ctx = opts.ctx;
return [2 /*return*/, route.resolve({ ctx: ctx, input: input })];
});
});
};
Router.prototype.has = function (what, path) {
return !!this._def[what][path];
};
return Router;
}());
function router() {
return new Router();
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
var SubscriptionEventEmitter = /** @class */ (function (_super) {
tslib.__extends(SubscriptionEventEmitter, _super);
function SubscriptionEventEmitter() {
return _super !== null && _super.apply(this, arguments) || this;
}
return SubscriptionEventEmitter;
}(events.EventEmitter));
var Subscription = /** @class */ (function () {
function Subscription(opts) {
this.isDestroyed = false;
this.events = new SubscriptionEventEmitter();
this.opts = tslib.__assign({}, opts);
}
Subscription.prototype.destroy = function () {
if (this.isDestroyed) {
return;
}
// debug('Subscription.destroy()', reason);
this.isDestroyed = true;
this.events.emit('destroy');
this.events.removeAllListeners();
};
Subscription.prototype.start = function () {
return tslib.__awaiter(this, void 0, void 0, function () {
var emit, cancel, err_1;
var _this = this;
return tslib.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (this.isDestroyed) {
throw new Error('Called start() on a destroyed subscription');
}
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
emit = {
error: function (err) { return _this.emitError(err); },
data: function (data) { return _this.emitOutput(data); }
};
return [4 /*yield*/, this.opts.start(emit)];
case 2:
cancel = _a.sent();
if (this.isDestroyed) {
cancel();
}
else {
this.events.on('destroy', cancel);
}
return [3 /*break*/, 4];
case 3:
err_1 = _a.sent();
this.emitError(err_1);
return [3 /*break*/, 4];
case 4: return [2 /*return*/];
}
});
});
};
/**
* This method is just here to help with `inferSubscriptionOutput` which I can't get working without it
*/
Subscription.prototype.output = function () {
throw new Error('Legacy');
};
/**
* Emit data
*/
Subscription.prototype.emitOutput = function (data) {
this.events.emit('data', data);
};
/**
* Emit error
*/
Subscription.prototype.emitError = function (err) {
this.events.emit('error', err);
};
Subscription.prototype.on = function () {
var _a;
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return (_a = this.events).on.apply(_a, args);
};
Subscription.prototype.off = function () {
var _a;
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return (_a = this.events).off.apply(_a, args);
};
return Subscription;
}());
function subscriptionPullFactory(opts) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var timer;
var stopped = false;
function _pull(emit) {
return tslib.__awaiter(this, void 0, void 0, function () {
var err_2;
return tslib.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (stopped) {
return [2 /*return*/];
}
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, opts.pull(emit)];
case 2:
_a.sent();
return [3 /*break*/, 4];
case 3:
err_2 = _a.sent();
emit.error(err_2);
return [3 /*break*/, 4];
case 4:
if (!stopped) {
timer = setTimeout(function () { return _pull(emit); }, opts.intervalMs);
}
return [2 /*return*/];
}
});
});
}
return new Subscription({
start: function (emit) {
_pull(emit);
return function () {
clearTimeout(timer);
stopped = true;
};
}
});
}
exports.HTTPError = HTTPError;
exports.Router = Router;
exports.Subscription = Subscription;
exports.assertNotBrowser = assertNotBrowser;
exports.getErrorResponseEnvelope = getErrorResponseEnvelope;
exports.getQueryInput = getQueryInput;
exports.httpError = httpError;
exports.requestHandler = requestHandler;
exports.router = router;
exports.subscriptionPullFactory = subscriptionPullFactory;
//# sourceMappingURL=index.js.map

18

package.json
{
"name": "@trpc/server",
"version": "1.4.4-alpha.2",
"version": "1.4.4-alpha.3",
"description": "TRPC Server",

@@ -18,4 +18,4 @@ "author": "KATT",

"scripts": {
"start": "tsdx watch --tsconfig tsconfig.build.json --verbose --noClean",
"build": "yarn tsdx build --tsconfig tsconfig.build.json",
"start": "rollup -c rollup.config.js --watch",
"build": "rollup -c rollup.config.js",
"test": "tsdx test",

@@ -33,4 +33,2 @@ "lint": "tsdx lint",

"dependencies": {
"@types/express": "^4.17.11",
"@types/next": "^9.0.0",
"tslib": "^2.1.0"

@@ -42,6 +40,14 @@ },

"devDependencies": {
"@rollup/plugin-typescript": "^8.1.1",
"@rollup/pluginutils": "^4.1.0",
"@types/express": "^4.17.11",
"@wessberg/rollup-plugin-ts": "^1.3.8",
"express": "^4.17.1",
"myzod": "^1.3.1",
"next": "^10.0.5",
"rollup": "^2.38.5",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-json": "^4.0.0",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-peer-deps-external": "^2.2.4",
"ts-json-validator": "^0.7.1",

@@ -51,3 +57,3 @@ "yup": "^0.32.8",

},
"gitHead": "7fb294b4ca54a26c28cc852d449f27272db69181"
"gitHead": "ada850671c74b537dffdbd0779414945c5151644"
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc