Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@typepoint/shared

Package Overview
Dependencies
Maintainers
2
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@typepoint/shared - npm Package Compare versions

Comparing version
3.0.2
to
4.0.0
+76
dist/index.d.ts
import { PathBuildingFunction } from './pathBuilder';
import { PathHelperParseMatch } from './pathHelper';
export { Logger, NoopLogger, } from './logger';
export { GetUrlOptions, PathHelperParseMatch, ParsedPathPattern, PathHelper, RequiredPathParametersNotFound, UnsupportedPathPatternError, } from './pathHelper';
export { parseQueryString, ParsedUrl, parseUrl, QueryParameterValues, } from './url';
export declare const cleanseHttpMethod: (method: string) => string;
export declare type Constructor<T> = new (...args: any[]) => T;
export interface ArrayOfTypeInfo<T> {
element: T;
}
export declare class ArrayOfClassInfo<T> {
readonly element: Constructor<T>;
constructor(element: Constructor<T>);
}
export declare abstract class ArrayOf<T> {
static isArrayOf: true;
readonly classInfo?: ArrayOfClassInfo<T>;
constructor(Class: Constructor<T>);
}
export declare function arrayOf<T>(Class: Constructor<T>): Constructor<ArrayOf<T>>;
export declare function isArrayOf(Class: any): Class is Constructor<ArrayOf<any>>;
export declare type NormalizeArrayOf<T> = T extends ArrayOf<infer TElementType> ? TElementType[] : T;
export declare class Empty {
readonly __isEmpty = true;
}
export declare function isEmptyClass(Class: any): boolean;
export declare function isEmptyValue(value: any): boolean;
export declare type NormalizeDefinitionType<T> = (T extends Array<Constructor<infer TInstance>> ? TInstance[] : T extends Constructor<infer TInstance> ? TInstance : T extends ArrayOf<infer TElementType> ? TElementType[] : T extends [infer TElementType] ? TElementType : T);
export declare type NormalizeTypePointType<T> = (T extends ArrayOf<infer TElementType> ? TElementType[] : T extends Empty ? ({} | undefined) : T);
export declare type AllowableRequestParams = Empty | Record<string, any>;
export declare type AllowableRequestBody = Empty | Record<string, any> | Array<any>;
export declare type AllowableResponseBody = Empty | Record<string, any> | Array<any>;
export declare type AllowableClassBasedRequestParams = Empty | Constructor<any>;
export declare type AllowableClassBasedRequestBody = Empty | Constructor<any> | Constructor<any>[];
export declare type AllowableClassBasedResponseBody = Empty | Constructor<any> | Constructor<any>[];
export interface EndpointDefinitionUrlOptions<TRequestParams> {
server?: string | undefined;
params?: NormalizeDefinitionType<TRequestParams> | undefined;
}
export interface ClassBasedEndpointDefinitionOptions<TRequestParams extends AllowableClassBasedRequestParams, TRequestBody extends AllowableClassBasedRequestBody, TResponseBody extends AllowableClassBasedResponseBody> {
method?: string;
path: PathBuildingFunction<NormalizeDefinitionType<TRequestParams>>;
requestParams?: TRequestParams;
requestBody?: TRequestBody;
responseBody?: TResponseBody;
}
export declare class EndpointDefinitionRequestClassInfo<TParams, TBody> {
readonly params: Constructor<TParams>;
readonly body: Constructor<TBody> | [any];
constructor(params: Constructor<TParams>, body: Constructor<TBody> | [any]);
}
export declare class EndpointDefinitionResponseClassInfo<TBody> {
readonly body: Constructor<TBody> | [any];
constructor(body: Constructor<TBody> | [any]);
}
export declare class EndpointDefinitionClassInfo {
readonly request: EndpointDefinitionRequestClassInfo<any, any>;
readonly response: EndpointDefinitionResponseClassInfo<any>;
constructor(requestParams: Constructor<any>, requestBody: Constructor<any> | [any], responseBody: Constructor<any> | [any]);
}
export declare class EndpointDefinitionInvalidConstructorArgs extends Error {
constructor(actualArgs: any[]);
}
export interface EndpointDefinition<TRequestParams extends AllowableRequestParams, TRequestBody extends AllowableRequestBody, TResponseBody extends AllowableResponseBody> {
readonly method: string;
readonly path: string;
readonly classInfo?: EndpointDefinitionClassInfo | undefined;
parse(url: string): PathHelperParseMatch | undefined;
url(options?: EndpointDefinitionUrlOptions<TRequestParams> | undefined): string;
}
export declare function defineEndpoint<TRequestParams extends AllowableRequestParams, TRequestBody extends AllowableRequestBody, TResponseBody extends AllowableResponseBody>(buildPath: PathBuildingFunction<TRequestParams>): EndpointDefinition<NormalizeDefinitionType<TRequestParams>, NormalizeDefinitionType<TRequestBody>, NormalizeDefinitionType<TResponseBody>>;
export declare function defineEndpoint<TRequestParams extends AllowableRequestParams = Empty, TRequestBody extends AllowableRequestBody = Empty, TResponseBody extends AllowableResponseBody = Empty>(method: string, buildPath: PathBuildingFunction<TRequestParams>): EndpointDefinition<NormalizeDefinitionType<TRequestParams>, NormalizeDefinitionType<TRequestBody>, NormalizeDefinitionType<TResponseBody>>;
export declare function defineEndpoint<TRequestParams extends AllowableClassBasedRequestParams = Empty, TRequestBody extends AllowableClassBasedRequestBody = Empty, TResponseBody extends AllowableClassBasedResponseBody = Empty>(options: ClassBasedEndpointDefinitionOptions<TRequestParams, TRequestBody, TResponseBody>): EndpointDefinition<NormalizeDefinitionType<TRequestParams>, NormalizeDefinitionType<TRequestBody>, NormalizeDefinitionType<TResponseBody>>;
export declare type GetEndpointDefinitionRequestParams<TEndpointDefinition extends EndpointDefinition<any, any, any>> = TEndpointDefinition extends EndpointDefinition<infer TRequestParams, any, any> ? TRequestParams : never;
export declare type GetEndpointDefinitionRequestBody<TEndpointDefinition extends EndpointDefinition<any, any, any>> = TEndpointDefinition extends EndpointDefinition<any, infer TRequestBody, any> ? TRequestBody : never;
export declare type GetEndpointDefinitionResponseBody<TEndpointDefinition extends EndpointDefinition<any, any, any>> = TEndpointDefinition extends EndpointDefinition<any, any, infer TResponseBody> ? TResponseBody : never;
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.defineEndpoint = exports.EndpointDefinitionInvalidConstructorArgs = exports.EndpointDefinitionClassInfo = exports.EndpointDefinitionResponseClassInfo = exports.EndpointDefinitionRequestClassInfo = exports.isEmptyValue = exports.isEmptyClass = exports.Empty = exports.isArrayOf = exports.arrayOf = exports.ArrayOf = exports.ArrayOfClassInfo = exports.cleanseHttpMethod = exports.parseUrl = exports.parseQueryString = exports.UnsupportedPathPatternError = exports.RequiredPathParametersNotFound = exports.PathHelper = exports.NoopLogger = void 0;
// eslint-disable-next-line max-classes-per-file
var pathBuilder_1 = require("./pathBuilder");
var pathHelper_1 = require("./pathHelper");
var logger_1 = require("./logger");
Object.defineProperty(exports, "NoopLogger", { enumerable: true, get: function () { return logger_1.NoopLogger; } });
var pathHelper_2 = require("./pathHelper");
Object.defineProperty(exports, "PathHelper", { enumerable: true, get: function () { return pathHelper_2.PathHelper; } });
Object.defineProperty(exports, "RequiredPathParametersNotFound", { enumerable: true, get: function () { return pathHelper_2.RequiredPathParametersNotFound; } });
Object.defineProperty(exports, "UnsupportedPathPatternError", { enumerable: true, get: function () { return pathHelper_2.UnsupportedPathPatternError; } });
var url_1 = require("./url");
Object.defineProperty(exports, "parseQueryString", { enumerable: true, get: function () { return url_1.parseQueryString; } });
Object.defineProperty(exports, "parseUrl", { enumerable: true, get: function () { return url_1.parseUrl; } });
var cleanseHttpMethod = function (method) { return method.toUpperCase(); };
exports.cleanseHttpMethod = cleanseHttpMethod;
var ArrayOfClassInfo = /** @class */ (function () {
function ArrayOfClassInfo(element) {
this.element = element;
}
return ArrayOfClassInfo;
}());
exports.ArrayOfClassInfo = ArrayOfClassInfo;
var ArrayOf = /** @class */ (function () {
function ArrayOf(Class) {
this.classInfo = new ArrayOfClassInfo(Class);
}
ArrayOf.isArrayOf = true;
return ArrayOf;
}());
exports.ArrayOf = ArrayOf;
function arrayOf(Class) {
var AnonymousArrayOf = /** @class */ (function (_super) {
__extends(AnonymousArrayOf, _super);
function AnonymousArrayOf() {
return _super.call(this, Class) || this;
}
return AnonymousArrayOf;
}(ArrayOf));
return AnonymousArrayOf;
}
exports.arrayOf = arrayOf;
function isArrayOf(Class) {
if (!Class) {
return false;
}
return Boolean(Class.isArrayOf);
}
exports.isArrayOf = isArrayOf;
var Empty = /** @class */ (function () {
function Empty() {
// istanbul ignore next
this.__isEmpty = true;
}
return Empty;
}());
exports.Empty = Empty;
function isEmptyClass(Class) {
return Class === Empty;
}
exports.isEmptyClass = isEmptyClass;
function isEmptyValue(value) {
if (value === null || value === undefined) {
return true;
}
if (typeof value === 'object' && !Object.keys(value).length) {
return true;
}
return false;
}
exports.isEmptyValue = isEmptyValue;
function normalizeDefinitionType(value) {
return value;
}
var EndpointDefinitionRequestClassInfo = /** @class */ (function () {
function EndpointDefinitionRequestClassInfo(params, body) {
this.params = params;
this.body = body;
}
return EndpointDefinitionRequestClassInfo;
}());
exports.EndpointDefinitionRequestClassInfo = EndpointDefinitionRequestClassInfo;
var EndpointDefinitionResponseClassInfo = /** @class */ (function () {
function EndpointDefinitionResponseClassInfo(body) {
this.body = body;
}
return EndpointDefinitionResponseClassInfo;
}());
exports.EndpointDefinitionResponseClassInfo = EndpointDefinitionResponseClassInfo;
var EndpointDefinitionClassInfo = /** @class */ (function () {
function EndpointDefinitionClassInfo(requestParams, requestBody, responseBody) {
this.request = new EndpointDefinitionRequestClassInfo(requestParams, requestBody);
this.response = new EndpointDefinitionResponseClassInfo(responseBody);
}
return EndpointDefinitionClassInfo;
}());
exports.EndpointDefinitionClassInfo = EndpointDefinitionClassInfo;
var EndpointDefinitionInvalidConstructorArgs = /** @class */ (function (_super) {
__extends(EndpointDefinitionInvalidConstructorArgs, _super);
function EndpointDefinitionInvalidConstructorArgs(actualArgs) {
var _this = this;
var received = (!actualArgs.length
? 'zero arguments'
: actualArgs.map(function (arg) { return typeof arg; }).join(', '));
// istanbul ignore next - typescript creates a branch for super calls
_this = _super.call(this, "Invalid EndpointDefinition constructor arguments - received " + actualArgs.length + " arguments: " + received) || this;
return _this;
}
return EndpointDefinitionInvalidConstructorArgs;
}(Error));
exports.EndpointDefinitionInvalidConstructorArgs = EndpointDefinitionInvalidConstructorArgs;
function defineEndpoint() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
var DEFAULT_METHOD = 'GET';
var make = function (_a) {
var classInfo = _a.classInfo, method = _a.method, pathFunc = _a.pathFunc;
var path = pathBuilder_1.createPath(pathFunc);
var pathHelper = new pathHelper_1.PathHelper(path);
return {
method: method,
path: path,
classInfo: classInfo,
parse: function (url) { return pathHelper.parse(url); },
url: function (options) { return pathHelper.url(options); },
};
};
switch (args.length) {
case 1: {
var firstArg = args[0];
if (typeof firstArg === 'function') {
return make({
method: DEFAULT_METHOD,
pathFunc: firstArg,
});
}
if (firstArg && typeof firstArg === 'object') {
var classInfo = new EndpointDefinitionClassInfo(normalizeDefinitionType(firstArg.requestParams || Empty), normalizeDefinitionType(firstArg.requestBody || Empty), normalizeDefinitionType(firstArg.responseBody || Empty));
return make({
classInfo: classInfo,
method: exports.cleanseHttpMethod(firstArg.method || DEFAULT_METHOD),
pathFunc: firstArg.path,
});
}
throw new EndpointDefinitionInvalidConstructorArgs(args);
}
case 2: {
var method = args[0], pathFunc = args[1];
if (typeof method !== 'string' || typeof pathFunc !== 'function') {
throw new EndpointDefinitionInvalidConstructorArgs(args);
}
return make({
method: exports.cleanseHttpMethod(method || DEFAULT_METHOD),
pathFunc: pathFunc,
});
}
default: {
throw new EndpointDefinitionInvalidConstructorArgs(args);
}
}
}
exports.defineEndpoint = defineEndpoint;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsZ0RBQWdEO0FBQ2hELDZDQUFpRTtBQUNqRSwyQ0FBZ0U7QUFFaEUsbUNBR2tCO0FBRGhCLG9HQUFBLFVBQVUsT0FBQTtBQUVaLDJDQU9zQjtBQUhwQix3R0FBQSxVQUFVLE9BQUE7QUFDViw0SEFBQSw4QkFBOEIsT0FBQTtBQUM5Qix5SEFBQSwyQkFBMkIsT0FBQTtBQUU3Qiw2QkFLZTtBQUpiLHVHQUFBLGdCQUFnQixPQUFBO0FBRWhCLCtGQUFBLFFBQVEsT0FBQTtBQUlILElBQU0saUJBQWlCLEdBQUcsVUFBQyxNQUFjLElBQUssT0FBQSxNQUFNLENBQUMsV0FBVyxFQUFFLEVBQXBCLENBQW9CLENBQUM7QUFBN0QsUUFBQSxpQkFBaUIscUJBQTRDO0FBUTFFO0lBQ0UsMEJBQXFCLE9BQXVCO1FBQXZCLFlBQU8sR0FBUCxPQUFPLENBQWdCO0lBQzVDLENBQUM7SUFDSCx1QkFBQztBQUFELENBQUMsQUFIRCxJQUdDO0FBSFksNENBQWdCO0FBSzdCO0lBS0UsaUJBQVksS0FBcUI7UUFDL0IsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQy9DLENBQUM7SUFOTSxpQkFBUyxHQUFTLElBQUksQ0FBQztJQU9oQyxjQUFDO0NBQUEsQUFSRCxJQVFDO0FBUnFCLDBCQUFPO0FBVTdCLFNBQWdCLE9BQU8sQ0FBSSxLQUFxQjtJQUM5QztRQUErQixvQ0FBVTtRQUN2QzttQkFDRSxrQkFBTSxLQUFLLENBQUM7UUFDZCxDQUFDO1FBQ0gsdUJBQUM7SUFBRCxDQUFDLEFBSkQsQ0FBK0IsT0FBTyxHQUlyQztJQUVELE9BQU8sZ0JBQWdCLENBQUM7QUFDMUIsQ0FBQztBQVJELDBCQVFDO0FBRUQsU0FBZ0IsU0FBUyxDQUFDLEtBQVU7SUFDbEMsSUFB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
export interface Logger {
log(...args: any[]): void;
debug(...args: any[]): void;
info(...args: any[]): void;
warn(...args: any[]): void;
error(...args: any[]): void;
}
export declare class NoopLogger {
log: () => void;
debug: () => void;
info: () => void;
warn: () => void;
error: () => void;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NoopLogger = void 0;
// eslint-disable-next-line @typescript-eslint/no-empty-function
var noop = function () { };
var NoopLogger = /** @class */ (function () {
function NoopLogger() {
this.log = noop;
this.debug = noop;
this.info = noop;
this.warn = noop;
this.error = noop;
}
return NoopLogger;
}());
exports.NoopLogger = NoopLogger;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2xvZ2dlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFRQSxnRUFBZ0U7QUFDaEUsSUFBTSxJQUFJLEdBQUcsY0FBUSxDQUFDLENBQUM7QUFFdkI7SUFBQTtRQUNFLFFBQUcsR0FBRyxJQUFJLENBQUM7UUFFWCxVQUFLLEdBQUcsSUFBSSxDQUFDO1FBRWIsU0FBSSxHQUFHLElBQUksQ0FBQztRQUVaLFNBQUksR0FBRyxJQUFJLENBQUM7UUFFWixVQUFLLEdBQUcsSUFBSSxDQUFDO0lBQ2YsQ0FBQztJQUFELGlCQUFDO0FBQUQsQ0FBQyxBQVZELElBVUM7QUFWWSxnQ0FBVSJ9
export declare class PathBuilder<TRequestParams> {
private readonly parts;
protected constructor();
literal(path: string): PathBuilder<TRequestParams>;
param(name: keyof TRequestParams): PathBuilder<TRequestParams>;
toString(): string;
}
export declare type PathBuildingFunction<TRequestParams> = (path: PathBuilder<TRequestParams>) => PathBuilder<TRequestParams>;
export declare function createPath<TRequestParams>(build: PathBuildingFunction<TRequestParams>): string;
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.createPath = exports.PathBuilder = void 0;
var removeLeadingAndTrailingSlashes = (function (path) { return path
.replace(/^\/+/, '')
.replace(/\/+$/, ''); });
var PathBuilder = /** @class */ (function () {
// Marked as private to discourage consumers from instantiating directly.
// Use the createPath function instead
// eslint-disable-next-line @typescript-eslint/no-empty-function
function PathBuilder() {
this.parts = [];
}
PathBuilder.prototype.literal = function (path) {
if (path) {
this.parts.push(removeLeadingAndTrailingSlashes(path));
}
return this;
};
PathBuilder.prototype.param = function (name) {
if (name) {
this.parts.push(":" + name);
}
return this;
};
PathBuilder.prototype.toString = function () {
return "/" + this.parts.join('/');
};
return PathBuilder;
}());
exports.PathBuilder = PathBuilder;
function createPath(build) {
var ConstructablePathBuilder = /** @class */ (function (_super) {
__extends(ConstructablePathBuilder, _super);
function ConstructablePathBuilder() {
return _super.call(this) || this;
}
return ConstructablePathBuilder;
}(PathBuilder));
var pathBuilder = build(new ConstructablePathBuilder());
return pathBuilder.toString();
}
exports.createPath = createPath;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF0aEJ1aWxkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcGF0aEJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsSUFBTSwrQkFBK0IsR0FBRyxDQUN0QyxVQUFDLElBQVksSUFBSyxPQUFBLElBQUk7S0FDbkIsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUM7S0FDbkIsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsRUFGSixDQUVJLENBQ3ZCLENBQUM7QUFFRjtJQUdFLHlFQUF5RTtJQUN6RSxzQ0FBc0M7SUFDdEMsZ0VBQWdFO0lBQ2hFO1FBTGlCLFVBQUssR0FBYSxFQUFFLENBQUM7SUFNdEMsQ0FBQztJQUVELDZCQUFPLEdBQVAsVUFBUSxJQUFZO1FBQ2xCLElBQUksSUFBSSxFQUFFO1lBQ1IsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsK0JBQStCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztTQUN4RDtRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELDJCQUFLLEdBQUwsVUFBTSxJQUEwQjtRQUM5QixJQUFJLElBQUksRUFBRTtZQUNSLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQUksSUFBTSxDQUFDLENBQUM7U0FDN0I7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCw4QkFBUSxHQUFSO1FBQ0UsT0FBTyxNQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBRyxDQUFDO0lBQ3BDLENBQUM7SUFDSCxrQkFBQztBQUFELENBQUMsQUExQkQsSUEwQkM7QUExQlksa0NBQVc7QUE4QnhCLFNBQWdCLFVBQVUsQ0FBaUIsS0FBMkM7SUFDcEY7UUFBdUMsNENBQTJCO1FBQ2hFO21CQUNFLGlCQUFPO1FBQ1QsQ0FBQztRQUNILCtCQUFDO0lBQUQsQ0FBQyxBQUpELENBQXVDLFdBQVcsR0FJakQ7SUFDRCxJQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsSUFBSSx3QkFBd0IsRUFBRSxDQUFDLENBQUM7SUFDMUQsT0FBTyxXQUFXLENBQUMsUUFBUSxFQUFFLENBQUM7QUFDaEMsQ0FBQztBQVJELGdDQVFDIn0=
import { ParsedUrl } from './url';
export declare class UnsupportedPathPatternError extends Error {
constructor(path: string);
}
export declare class RequiredPathParametersNotFound extends Error {
constructor(parameterNames: string[]);
}
export interface PathHelperParseMatch extends ParsedUrl {
params: {
[key: string]: any;
};
}
export interface ParsedPathPattern extends ParsedUrl {
parameters: string[];
}
export interface GetUrlOptions {
params?: {
[key: string]: any;
} | undefined;
server?: string | undefined;
}
export declare class PathHelper {
readonly pathPattern: string;
static parsePathPattern(pathPattern: string): ParsedPathPattern;
private static generateParseFunction;
private static getPathPatternParameterRegExp;
private static getParameterNamesFromPathPattern;
private static checkForQueryString;
private readonly parsedPathPattern;
readonly parse: (path: string) => (PathHelperParseMatch | undefined);
constructor(pathPattern: string);
url(options?: GetUrlOptions): string;
}
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PathHelper = exports.RequiredPathParametersNotFound = exports.UnsupportedPathPatternError = void 0;
// eslint-disable-next-line max-classes-per-file
var regexp_1 = require("./regexp");
var url_1 = require("./url");
var UnsupportedPathPatternError = /** @class */ (function (_super) {
__extends(UnsupportedPathPatternError, _super);
// istanbul ignore next - typescript creates a branch for super calls
function UnsupportedPathPatternError(path) {
return _super.call(this, "Unsupported path pattern: \"" + path + "\"") || this;
}
return UnsupportedPathPatternError;
}(Error));
exports.UnsupportedPathPatternError = UnsupportedPathPatternError;
var RequiredPathParametersNotFound = /** @class */ (function (_super) {
__extends(RequiredPathParametersNotFound, _super);
// istanbul ignore next - typescript creates a branch for super calls
function RequiredPathParametersNotFound(parameterNames) {
return _super.call(this, "Required path parameters not found: " + parameterNames.join(', ')) || this;
}
return RequiredPathParametersNotFound;
}(Error));
exports.RequiredPathParametersNotFound = RequiredPathParametersNotFound;
var PathHelper = /** @class */ (function () {
function PathHelper(pathPattern) {
this.pathPattern = pathPattern;
this.parsedPathPattern = PathHelper.parsePathPattern(this.pathPattern);
this.parse = PathHelper.generateParseFunction(this.parsedPathPattern);
PathHelper.checkForQueryString(pathPattern);
}
PathHelper.parsePathPattern = function (pathPattern) {
var parsedUrl = url_1.parseUrl(pathPattern);
var parameters = this.getParameterNamesFromPathPattern(parsedUrl.path);
return __assign(__assign({}, parsedUrl), { parameters: parameters });
};
PathHelper.generateParseFunction = function (parsedPathPattern) {
var parameterNames = [];
var getParameterPlaceholder = function (index) { return "-----" + index + "-----"; };
var pathParametersRegExpPattern = parsedPathPattern.path.replace(this.getPathPatternParameterRegExp(), function (_, key) {
parameterNames.push(key);
return getParameterPlaceholder(parameterNames.length - 1);
});
pathParametersRegExpPattern = regexp_1.escapeRegExp(pathParametersRegExpPattern);
for (var parameterIndex = 0; parameterIndex < parameterNames.length; parameterIndex++) {
pathParametersRegExpPattern = pathParametersRegExpPattern
.replace(regexp_1.escapeRegExp(getParameterPlaceholder(parameterIndex)), '([^&?/\\\\]+)');
}
pathParametersRegExpPattern = "^" + pathParametersRegExpPattern + "$";
var pathParametersRegEx = new RegExp(pathParametersRegExpPattern, 'i');
return function (path) {
var parsedUrl = url_1.parseUrl(path);
// Test url and extract path parameters
pathParametersRegEx.lastIndex = -1;
// const parameterValues: string[] = [];
var match = pathParametersRegEx.exec(parsedUrl.path);
if (!match) {
return undefined;
}
var result = __assign(__assign({}, parsedUrl), { params: {} });
// Add path parameters to result
if (match.length > 1) {
for (var parameterIndex = 1; parameterIndex < match.length; parameterIndex++) {
var parameterName = parameterNames[parameterIndex - 1];
var parameterValue = match[parameterIndex];
result.params[parameterName] = parameterValue;
}
}
// Extract and add query string parameters to result
var queryStringParameters = url_1.parseQueryString(parsedUrl.postPath);
Object.getOwnPropertyNames(queryStringParameters).forEach(function (parameterName) {
var parameterValue = queryStringParameters[parameterName];
result.params[parameterName] = parameterValue;
});
return result;
};
};
// private static getPathAndQueryStringSplitterRegExp = () => /^([^?\n] +)(\?.*)?$/i;
PathHelper.getParameterNamesFromPathPattern = function (pathPattern) {
var parameterNames = [];
var pathParameterRegExp = PathHelper.getPathPatternParameterRegExp();
var match;
do {
match = pathParameterRegExp.exec(pathPattern);
if (match) {
parameterNames.push(match[1]);
}
} while (match);
return parameterNames;
};
PathHelper.checkForQueryString = function (path) {
if (path.indexOf('?') > -1) {
throw new UnsupportedPathPatternError(path);
}
};
PathHelper.prototype.url = function (options) {
var _this = this;
var params = (options && options.params) || {};
var server = (options && options.server) || '';
var providedParameterNames = Object.getOwnPropertyNames(params);
var missingParameterNames = [];
var queryStringParameterNames = [];
this.parsedPathPattern.parameters.forEach(function (requiredParameterName) {
var isRequiredParameterProvided = providedParameterNames.some(function (parameterName) { return parameterName === requiredParameterName; });
if (!isRequiredParameterProvided) {
missingParameterNames.push(requiredParameterName);
}
});
providedParameterNames.forEach(function (providedParameterName) {
var isProvidedParameterRequired = _this.parsedPathPattern.parameters.some(function (parameterName) { return parameterName === providedParameterName; });
if (!isProvidedParameterRequired) {
queryStringParameterNames.push(providedParameterName);
}
});
if (missingParameterNames.length) {
throw new RequiredPathParametersNotFound(missingParameterNames);
}
var url = this.pathPattern.replace(/:([^\s/?\n\d][^\s/?\n]*)/gim, function (_, key) { return "" + params[key]; });
var queryString = queryStringParameterNames
.map(function (parameterName) { return encodeURIComponent(parameterName) + "=" + encodeURIComponent(params[parameterName]); })
.join('&');
if (queryString) {
url = url_1.addQueryStringToUrl(url, queryString);
}
if (server) {
url = server + url;
}
return url;
};
PathHelper.getPathPatternParameterRegExp = function () { return /:([^\s/?\n\d][^\s/?\n]*)/gim; };
return PathHelper;
}());
exports.PathHelper = PathHelper;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF0aEhlbHBlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9wYXRoSGVscGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsZ0RBQWdEO0FBQ2hELG1DQUF3QztBQUN4Qyw2QkFFZTtBQUVmO0lBQWlELCtDQUFLO0lBQ3BELHFFQUFxRTtJQUNyRSxxQ0FBWSxJQUFZO2VBQ3RCLGtCQUFNLGlDQUE4QixJQUFJLE9BQUcsQ0FBQztJQUM5QyxDQUFDO0lBQ0gsa0NBQUM7QUFBRCxDQUFDLEFBTEQsQ0FBaUQsS0FBSyxHQUtyRDtBQUxZLGtFQUEyQjtBQU94QztJQUFvRCxrREFBSztJQUN2RCxxRUFBcUU7SUFDckUsd0NBQVksY0FBd0I7ZUFDbEMsa0JBQU0seUNBQXVDLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFHLENBQUM7SUFDM0UsQ0FBQztJQUNILHFDQUFDO0FBQUQsQ0FBQyxBQUxELENBQW9ELEtBQUssR0FLeEQ7QUFMWSx3RUFBOEI7QUFvQjNDO0lBK0ZFLG9CQUFxQixXQUFtQjtRQUFuQixnQkFBVyxHQUFYLFdBQVcsQ0FBUTtRQUp2QixzQkFBaUIsR0FBRyxVQUFVLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRTFFLFVBQUssR0FBRyxVQUFVLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFHeEUsVUFBVSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQzlDLENBQUM7SUFoR00sMkJBQWdCLEdBQXZCLFVBQXdCLFdBQW1CO1FBQ3pDLElBQU0sU0FBUyxHQUFHLGNBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUV4QyxJQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsZ0NBQWdDLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRXpFLDZCQUNLLFNBQVMsS0FDWixVQUFV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
export declare function escapeRegExp(input: string): string;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.escapeRegExp = void 0;
function escapeRegExp(input) {
return input.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
}
exports.escapeRegExp = escapeRegExp;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnZXhwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3JlZ2V4cC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxTQUFnQixZQUFZLENBQUMsS0FBYTtJQUN4QyxPQUFPLEtBQUssQ0FBQyxPQUFPLENBQUMsdUJBQXVCLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDeEQsQ0FBQztBQUZELG9DQUVDIn0=
export interface ParsedUrl {
prePath: string;
path: string;
postPath: string;
}
export declare function parseUrl(url: string): ParsedUrl;
export interface QueryParameterValues {
[key: string]: string | string[];
}
export declare function parseQueryString(queryString: string): QueryParameterValues;
export declare function addQueryStringToUrl(url: string, queryString: string): string;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.addQueryStringToUrl = exports.parseQueryString = exports.parseUrl = void 0;
function parseUrl(url) {
var index = 0;
var pathStartIndex;
var pathLength;
while (index < url.length && pathLength === undefined) {
if (pathStartIndex === undefined) {
if (url[index] === '/') {
if (url[index + 1] === '/') {
index += 2;
}
else {
pathStartIndex = index;
index++;
}
}
else {
index++;
}
}
else if (url[index] === '#' || url[index] === '?') {
pathLength = index - pathStartIndex;
}
else {
index++;
}
}
if (pathStartIndex !== undefined && pathLength === undefined) {
pathLength = url.length - pathStartIndex;
}
var prePath = url.substring(0, pathStartIndex === undefined ? url.length + 1 : pathStartIndex);
var path = pathStartIndex === undefined ? '' : url.substr(pathStartIndex, pathLength);
var postPath = ((pathStartIndex === undefined || pathLength === undefined)
? ''
: url.substr(pathStartIndex + pathLength));
return {
prePath: prePath,
path: path,
postPath: postPath,
};
}
exports.parseUrl = parseUrl;
function parseQueryString(queryString) {
var result = {};
// eslint-disable-next-line no-shadow
var Position;
(function (Position) {
Position[Position["key"] = 0] = "key";
Position[Position["value"] = 1] = "value";
})(Position || (Position = {}));
var trimmedQueryString = queryString.trim();
if (trimmedQueryString[0] !== '?') {
return result;
}
var position = Position.key;
var parameterName = '';
var parameterValue = '';
var addParameter = function () {
var existingValue = result[parameterName];
if (existingValue === undefined) {
result[parameterName] = parameterValue;
}
else if (typeof existingValue === 'string') {
result[parameterName] = [existingValue, parameterValue];
}
else {
existingValue.push(parameterValue);
}
parameterName = '';
parameterValue = '';
};
var index = 1;
while (index < trimmedQueryString.length) {
var char = trimmedQueryString[index];
if (char === '#') {
break;
}
if (position === Position.key) {
if (char === '=') {
position = Position.value;
}
else if (char === '&') {
addParameter();
}
else {
parameterName += char;
}
}
else if (char === '&') {
addParameter();
position = Position.key;
}
else {
parameterValue += char;
}
index++;
}
if (parameterName) {
addParameter();
}
return result;
}
exports.parseQueryString = parseQueryString;
function addQueryStringToUrl(url, queryString) {
var index = url.indexOf('?');
var endsWithQuestionMark = index === url.length - 1;
var separator = '';
if (index === -1) {
separator = '?';
}
else if (!endsWithQuestionMark) {
separator = '&';
}
url = url + separator + queryString;
return url;
}
exports.addQueryStringToUrl = addQueryStringToUrl;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXJsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3VybC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFNQSxTQUFnQixRQUFRLENBQUMsR0FBVztJQUNsQyxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7SUFDZCxJQUFJLGNBQWtDLENBQUM7SUFDdkMsSUFBSSxVQUE4QixDQUFDO0lBRW5DLE9BQU8sS0FBSyxHQUFHLEdBQUcsQ0FBQyxNQUFNLElBQUksVUFBVSxLQUFLLFNBQVMsRUFBRTtRQUNyRCxJQUFJLGNBQWMsS0FBSyxTQUFTLEVBQUU7WUFDaEMsSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxFQUFFO2dCQUN0QixJQUFJLEdBQUcsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEtBQUssR0FBRyxFQUFFO29CQUMxQixLQUFLLElBQUksQ0FBQyxDQUFDO2lCQUNaO3FCQUFNO29CQUNMLGNBQWMsR0FBRyxLQUFLLENBQUM7b0JBQ3ZCLEtBQUssRUFBRSxDQUFDO2lCQUNUO2FBQ0Y7aUJBQU07Z0JBQ0wsS0FBSyxFQUFFLENBQUM7YUFDVDtTQUNGO2FBQU0sSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxJQUFJLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLEVBQUU7WUFDbkQsVUFBVSxHQUFHLEtBQUssR0FBRyxjQUFjLENBQUM7U0FDckM7YUFBTTtZQUNMLEtBQUssRUFBRSxDQUFDO1NBQ1Q7S0FDRjtJQUVELElBQUksY0FBYyxLQUFLLFNBQVMsSUFBSSxVQUFVLEtBQUssU0FBUyxFQUFFO1FBQzVELFVBQVUsR0FBRyxHQUFHLENBQUMsTUFBTSxHQUFHLGNBQWMsQ0FBQztLQUMxQztJQUVELElBQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLGNBQWMsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENB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
// eslint-disable-next-line max-classes-per-file
import { Product, Todo } from '@typepoint/fixtures';
import { assert, Equal } from 'type-assertions';
import {
EndpointDefinitionInvalidConstructorArgs,
EndpointDefinition,
arrayOf,
ArrayOf,
cleanseHttpMethod,
Constructor,
defineEndpoint,
Empty,
isArrayOf,
isEmptyClass,
isEmptyValue,
} from './index';
describe('shared', () => {
describe('arrayOf', () => {
class User {
id = ''
name = '';
}
it('should describe the class that it is an array of when instantiated', () => {
const ArrayOfUser = arrayOf(User);
expect(typeof ArrayOfUser).toBe('function');
type Actual = typeof ArrayOfUser;
type Expected = Constructor<ArrayOf<User>>;
assert<Equal<Actual, Expected>>();
const arrayOfUser = new ArrayOfUser();
expect(arrayOfUser).toHaveProperty(['classInfo', 'element'], User);
});
});
describe('defineEndpoint', () => {
it('should return an endpoint definition with the specified method and path', () => {
const method = 'POST';
const addProduct = defineEndpoint<Empty, Product, Product>(method, (path) => path.literal('products'));
assert<Equal<typeof addProduct, EndpointDefinition<Empty, Product, Product>>>();
expect(addProduct).toBeDefined();
expect(addProduct).toHaveProperty('method', method);
expect(addProduct).toHaveProperty('path', '/products');
});
it('should default a GET method if method is not specified', () => {
const getProducts = defineEndpoint<Empty, Empty, Product[]>((path) => path.literal('products'));
assert<Equal<typeof getProducts, EndpointDefinition<Empty, Empty, Product[]>>>();
expect(getProducts).toBeDefined();
expect(getProducts).toHaveProperty('method', 'GET');
expect(getProducts).toHaveProperty('path', '/products');
const getTodos = defineEndpoint<Empty, Empty, Todo[]>('', (path) => path.literal('/api/todos'));
expect(getTodos).toHaveProperty('method', 'GET');
});
it('should include classInfo when defining endpoint using classes', () => {
class GetClientRequestParams {
constructor(public id: number) {
}
}
class Client {
constructor(
public name: string,
public creationDate: Date,
public modificationDate: Date,
_id?: number,
) {
}
}
const method = 'GET';
const getClient = defineEndpoint({
method,
path: (path) => path.literal('clients').param('id'),
requestParams: GetClientRequestParams,
requestBody: Empty,
responseBody: Client,
});
assert<Equal<typeof getClient, EndpointDefinition<GetClientRequestParams, Empty, Client>>>();
expect(getClient).toBeDefined();
expect(getClient).toHaveProperty('method', method);
expect(getClient).toHaveProperty('path', '/clients/:id');
expect(getClient.classInfo).toHaveProperty(['request', 'params'], GetClientRequestParams);
expect(getClient.classInfo).toHaveProperty(['request', 'body'], Empty);
expect(getClient.classInfo).toHaveProperty(['response', 'body'], Client);
});
it('should include classInfo when defining endpoint using classes that includes an array using arrayOf', () => {
class GetClientsParams {
includeInactive = false;
}
class Client {
constructor(
public name: string,
public creationDate: Date,
public modificationDate: Date,
id?: number,
) {
}
}
const arrayOfClient = arrayOf(Client);
const getClients = defineEndpoint({
path: (path) => path.literal('clients'),
requestParams: GetClientsParams,
requestBody: Empty,
responseBody: arrayOfClient,
});
assert<Equal<typeof getClients, EndpointDefinition<GetClientsParams, Empty, Client[]>>>();
expect(getClients).toBeDefined();
expect(getClients).toHaveProperty('method', 'GET');
expect(getClients).toHaveProperty('path', '/clients');
expect(getClients.classInfo).toHaveProperty(['request', 'params'], GetClientsParams);
expect(getClients.classInfo).toHaveProperty(['request', 'body'], Empty);
expect(getClients.classInfo).toHaveProperty(['response', 'body'], arrayOfClient);
});
});
it('should include classInfo when defining endpoint using classes that includes an array using [Type]', () => {
class GetClientsParams {
includeInactive = false;
}
class Client {
constructor(
public name: string,
public creationDate: Date,
public modificationDate: Date,
id?: number,
) {
}
}
const getClients = defineEndpoint({
path: (path) => path.literal('clients'),
requestParams: GetClientsParams,
requestBody: Empty,
responseBody: [Client],
});
assert<Equal<typeof getClients, EndpointDefinition<GetClientsParams, Empty, Client[]>>>();
expect(getClients).toBeDefined();
expect(getClients).toHaveProperty('method', 'GET');
expect(getClients).toHaveProperty('path', '/clients');
expect(getClients.classInfo).toHaveProperty(['request', 'params'], GetClientsParams);
expect(getClients.classInfo).toHaveProperty(['request', 'body'], Empty);
expect(getClients.classInfo).toHaveProperty(['response', 'body'], [Client]);
});
it('should default classInfo types to Empty when defining '
+ 'using options object but not specifying any classes', () => {
const generateThumbnailsEndpoint = defineEndpoint({
method: 'POST',
path: (path) => path.literal('/api/generateThumbnails'),
});
const { classInfo } = generateThumbnailsEndpoint;
expect(classInfo).toBeTruthy();
if (!classInfo) {
return;
}
expect(classInfo.request.params).toEqual(Empty);
expect(classInfo.request.body).toEqual(Empty);
expect(classInfo.response.body).toEqual(Empty);
});
it('should parse urls', () => {
class GetTodoRequestParams {
id!: string;
includeDetails?: boolean;
}
const getTodo = defineEndpoint({
path: (path) => path.literal('api/todos').param('id'),
requestParams: GetTodoRequestParams,
responseBody: Todo,
});
const match = getTodo.parse('https://todos.ninja/api/todos/123?includeDetails=true');
expect(match).toEqual({
params: {
id: '123',
includeDetails: 'true',
},
path: '/api/todos/123',
postPath: '?includeDetails=true',
prePath: 'https://todos.ninja',
});
});
it('should generate urls', () => {
class GetTodoRequestParams {
id!: string;
includeDetails?: boolean;
}
const getTodo = defineEndpoint({
path: (path) => path.literal('api/todos').param('id'),
requestParams: GetTodoRequestParams,
responseBody: Todo,
});
const url = getTodo.url({ params: { id: '123', includeDetails: true } });
expect(url).toEqual('/api/todos/123?includeDetails=true');
});
it('should error if called incorrectly', () => {
expect(() => (defineEndpoint as any)()).toThrow(
new EndpointDefinitionInvalidConstructorArgs([]),
);
expect(() => defineEndpoint('/api/products' as any)).toThrow(
new EndpointDefinitionInvalidConstructorArgs(['/api/products']),
);
expect(() => defineEndpoint('get', '/api/products' as any)).toThrow(
new EndpointDefinitionInvalidConstructorArgs(['get', '/api/products']),
);
expect(() => (defineEndpoint as any)('get', '/api/products' as any, true)).toThrow(
new EndpointDefinitionInvalidConstructorArgs(['get', '/api/products', true]),
);
});
});
describe('isArrayOf', () => {
class User {
id = ''
name = '';
}
it('should return true for arrayOf results', () => {
const ArrayOfUser = arrayOf(User);
expect(isArrayOf(ArrayOfUser)).toBe(true);
});
it('should return false for anything else', () => {
const ArrayOfUser = User;
expect(isArrayOf(ArrayOfUser)).toBe(false);
expect(isArrayOf(null)).toBe(false);
expect(isArrayOf(true)).toBe(false);
});
});
describe('isEmptyClass', () => {
it('should return true when passed in Empty', () => {
expect(isEmptyClass(Empty)).toBeTruthy();
});
it('should return false when not passed in Empty', () => {
class SomeOtherClass {}
expect(isEmptyClass(SomeOtherClass)).toBeFalsy();
});
});
describe('isEmptyValue', () => {
it('should return true for empty values', () => {
expect(isEmptyValue(null)).toBeTruthy();
expect(isEmptyValue(undefined)).toBeTruthy();
expect(isEmptyValue({})).toBeTruthy();
});
it('should return false for non empty values', () => {
expect(isEmptyValue({ key: 'value' })).toBeFalsy();
});
});
describe('cleanseHttpMethod', () => {
it('should return method in uppercase', () => {
expect(cleanseHttpMethod('get')).toBe('GET');
expect(cleanseHttpMethod('post')).toBe('POST');
expect(cleanseHttpMethod('squanch')).toBe('SQUANCH');
});
});
// eslint-disable-next-line max-classes-per-file
import { createPath, PathBuildingFunction } from './pathBuilder';
import { PathHelper, PathHelperParseMatch } from './pathHelper';
export {
Logger,
NoopLogger,
} from './logger';
export {
GetUrlOptions,
PathHelperParseMatch,
ParsedPathPattern,
PathHelper,
RequiredPathParametersNotFound,
UnsupportedPathPatternError,
} from './pathHelper';
export {
parseQueryString,
ParsedUrl,
parseUrl,
QueryParameterValues,
} from './url';
export const cleanseHttpMethod = (method: string) => method.toUpperCase();
export type Constructor<T> = new (...args: any[]) => T;
export interface ArrayOfTypeInfo<T> {
element: T;
}
export class ArrayOfClassInfo<T> {
constructor(readonly element: Constructor<T>) {
}
}
export abstract class ArrayOf<T> {
static isArrayOf: true = true;
readonly classInfo?: ArrayOfClassInfo<T>;
constructor(Class: Constructor<T>) {
this.classInfo = new ArrayOfClassInfo(Class);
}
}
export function arrayOf<T>(Class: Constructor<T>): Constructor<ArrayOf<T>> {
class AnonymousArrayOf extends ArrayOf<T> {
constructor() {
super(Class);
}
}
return AnonymousArrayOf;
}
export function isArrayOf(Class: any): Class is Constructor<ArrayOf<any>> {
if (!Class) {
return false;
}
return Boolean((Class as any).isArrayOf);
}
export type NormalizeArrayOf<T> = T extends ArrayOf<infer TElementType> ? TElementType[] : T;
export class Empty {
// istanbul ignore next
readonly __isEmpty = true;
}
export function isEmptyClass(Class: any): boolean {
return Class === Empty;
}
export function isEmptyValue(value: any) {
if (value === null || value === undefined) {
return true;
}
if (typeof value === 'object' && !Object.keys(value).length) {
return true;
}
return false;
}
export type NormalizeDefinitionType<T> = (
T extends Array<Constructor<infer TInstance>>
? TInstance[]
: T extends Constructor<infer TInstance>
? TInstance
: T extends ArrayOf<infer TElementType>
? TElementType[]
: T extends [infer TElementType]
? TElementType
: T
);
function normalizeDefinitionType<T>(value: T): NormalizeDefinitionType<T> {
return value as unknown as NormalizeDefinitionType<T>;
}
export type NormalizeTypePointType<T> = (
T extends ArrayOf<infer TElementType>
? TElementType[]
: T extends Empty
// TODO: Revisit this {} type
// eslint-disable-next-line @typescript-eslint/ban-types
? ({} | undefined)
: T
);
export type AllowableRequestParams = Empty | Record<string, any>;
export type AllowableRequestBody = Empty | Record<string, any> | Array<any>;
export type AllowableResponseBody = Empty | Record<string, any> | Array<any>;
export type AllowableClassBasedRequestParams = Empty | Constructor<any>;
export type AllowableClassBasedRequestBody = Empty | Constructor<any> | Constructor<any>[];
export type AllowableClassBasedResponseBody = Empty | Constructor<any> | Constructor<any>[];
export interface EndpointDefinitionUrlOptions<TRequestParams> {
server?: string | undefined;
params?: NormalizeDefinitionType<TRequestParams> | undefined;
}
export interface ClassBasedEndpointDefinitionOptions<
TRequestParams extends AllowableClassBasedRequestParams,
TRequestBody extends AllowableClassBasedRequestBody,
TResponseBody extends AllowableClassBasedResponseBody
> {
method?: string;
path: PathBuildingFunction<NormalizeDefinitionType<TRequestParams>>;
requestParams?: TRequestParams;
requestBody?: TRequestBody;
responseBody?: TResponseBody;
}
export class EndpointDefinitionRequestClassInfo<TParams, TBody> {
constructor(
readonly params: Constructor<TParams>,
readonly body: Constructor<TBody> | [any],
) {
}
}
export class EndpointDefinitionResponseClassInfo<TBody> {
constructor(
readonly body: Constructor<TBody> | [any],
) {
}
}
export class EndpointDefinitionClassInfo {
readonly request: EndpointDefinitionRequestClassInfo<any, any>;
readonly response: EndpointDefinitionResponseClassInfo<any>;
constructor(
requestParams: Constructor<any>,
requestBody: Constructor<any> | [any],
responseBody: Constructor<any> | [any],
) {
this.request = new EndpointDefinitionRequestClassInfo<any, any>(requestParams, requestBody);
this.response = new EndpointDefinitionResponseClassInfo<any>(responseBody);
}
}
export class EndpointDefinitionInvalidConstructorArgs extends Error {
constructor(actualArgs: any[]) {
const received = (
!actualArgs.length
? 'zero arguments'
: actualArgs.map((arg) => typeof arg).join(', ')
);
// istanbul ignore next - typescript creates a branch for super calls
super(`Invalid EndpointDefinition constructor arguments - received ${actualArgs.length} arguments: ${received}`);
}
}
export interface EndpointDefinition<
TRequestParams extends AllowableRequestParams,
TRequestBody extends AllowableRequestBody,
TResponseBody extends AllowableResponseBody
> {
readonly method: string;
readonly path: string;
readonly classInfo?: EndpointDefinitionClassInfo | undefined;
parse(url: string): PathHelperParseMatch | undefined;
url(options?: EndpointDefinitionUrlOptions<TRequestParams> | undefined): string;
}
export function defineEndpoint<
TRequestParams extends AllowableRequestParams,
TRequestBody extends AllowableRequestBody,
TResponseBody extends AllowableResponseBody
>(
buildPath: PathBuildingFunction<TRequestParams>
): EndpointDefinition<
NormalizeDefinitionType<TRequestParams>,
NormalizeDefinitionType<TRequestBody>,
NormalizeDefinitionType<TResponseBody>
>;
export function defineEndpoint<
TRequestParams extends AllowableRequestParams = Empty,
TRequestBody extends AllowableRequestBody = Empty,
TResponseBody extends AllowableResponseBody = Empty,
>(
method: string,
buildPath: PathBuildingFunction<TRequestParams>
): EndpointDefinition<
NormalizeDefinitionType<TRequestParams>,
NormalizeDefinitionType<TRequestBody>,
NormalizeDefinitionType<TResponseBody>
>;
export function defineEndpoint<
TRequestParams extends AllowableClassBasedRequestParams = Empty,
TRequestBody extends AllowableClassBasedRequestBody = Empty,
TResponseBody extends AllowableClassBasedResponseBody = Empty,
>(
options: ClassBasedEndpointDefinitionOptions<TRequestParams, TRequestBody, TResponseBody>,
): EndpointDefinition<
NormalizeDefinitionType<TRequestParams>,
NormalizeDefinitionType<TRequestBody>,
NormalizeDefinitionType<TResponseBody>
>;
export function defineEndpoint<
TRequestParams extends AllowableRequestParams,
TRequestBody extends AllowableRequestBody,
TResponseBody extends AllowableResponseBody,
>(...args: any[]): EndpointDefinition<
NormalizeDefinitionType<TRequestParams>,
NormalizeDefinitionType<TRequestBody>,
NormalizeDefinitionType<TResponseBody>
> {
const DEFAULT_METHOD = 'GET';
const make = ({ classInfo, method, pathFunc }: {
classInfo?: EndpointDefinitionClassInfo | undefined;
method: string;
pathFunc: PathBuildingFunction<NormalizeDefinitionType<TRequestParams>>;
}) => {
const path = createPath(pathFunc);
const pathHelper = new PathHelper(path);
return {
method,
path,
classInfo,
parse: (url: string) => pathHelper.parse(url),
url: (options?: EndpointDefinitionUrlOptions<NormalizeDefinitionType<TRequestParams>>) => pathHelper.url(options),
};
};
switch (args.length) {
case 1: {
const [firstArg] = args;
if (typeof firstArg === 'function') {
return make({
method: DEFAULT_METHOD,
pathFunc: firstArg,
});
}
if (firstArg && typeof firstArg === 'object') {
const classInfo = new EndpointDefinitionClassInfo(
normalizeDefinitionType(firstArg.requestParams || Empty),
normalizeDefinitionType(firstArg.requestBody || Empty),
normalizeDefinitionType(firstArg.responseBody || Empty),
);
return make({
classInfo,
method: cleanseHttpMethod(firstArg.method || DEFAULT_METHOD),
pathFunc: firstArg.path,
});
}
throw new EndpointDefinitionInvalidConstructorArgs(args);
}
case 2: {
const [method, pathFunc] = args;
if (typeof method !== 'string' || typeof pathFunc !== 'function') {
throw new EndpointDefinitionInvalidConstructorArgs(args);
}
return make({
method: cleanseHttpMethod(method || DEFAULT_METHOD),
pathFunc,
});
}
default: {
throw new EndpointDefinitionInvalidConstructorArgs(args);
}
}
}
export type GetEndpointDefinitionRequestParams<TEndpointDefinition extends EndpointDefinition<any, any, any>> =
TEndpointDefinition extends EndpointDefinition<infer TRequestParams, any, any> ? TRequestParams : never;
export type GetEndpointDefinitionRequestBody<TEndpointDefinition extends EndpointDefinition<any, any, any>> =
TEndpointDefinition extends EndpointDefinition<any, infer TRequestBody, any> ? TRequestBody : never;
export type GetEndpointDefinitionResponseBody<TEndpointDefinition extends EndpointDefinition<any, any, any>> =
TEndpointDefinition extends EndpointDefinition<any, any, infer TResponseBody> ? TResponseBody : never;
import { Logger, NoopLogger } from './logger';
describe('shared/logger', () => {
describe('NoopLogger', () => {
let logger: Logger;
beforeEach(() => {
logger = new NoopLogger();
});
it('should not log to console', () => {
jest.spyOn(console, 'log');
jest.spyOn(console, 'debug');
jest.spyOn(console, 'info');
jest.spyOn(console, 'warn');
jest.spyOn(console, 'error');
logger.log('Relax Morty');
// eslint-disable-next-line no-console
expect(console.log).not.toHaveBeenCalled();
logger.debug('Relax Morty');
// eslint-disable-next-line no-console
expect(console.debug).not.toHaveBeenCalled();
logger.info('Relax Morty');
// eslint-disable-next-line no-console
expect(console.info).not.toHaveBeenCalled();
logger.warn('Relax Morty');
// eslint-disable-next-line no-console
expect(console.warn).not.toHaveBeenCalled();
logger.error('Relax Morty');
// eslint-disable-next-line no-console
expect(console.error).not.toHaveBeenCalled();
});
it('should have a log method', () => {
expect(logger).toHaveProperty('log', expect.any(Function));
});
it('should have a debug method', () => {
expect(logger).toHaveProperty('debug', expect.any(Function));
});
it('should have an info method', () => {
expect(logger).toHaveProperty('info', expect.any(Function));
});
it('should have a warn method', () => {
expect(logger).toHaveProperty('warn', expect.any(Function));
});
it('should have an error method', () => {
expect(logger).toHaveProperty('error', expect.any(Function));
});
});
});
export interface Logger {
log(...args: any[]): void;
debug(...args: any[]): void;
info(...args: any[]): void;
warn(...args: any[]): void;
error(...args: any[]): void;
}
// eslint-disable-next-line @typescript-eslint/no-empty-function
const noop = () => { };
export class NoopLogger {
log = noop;
debug = noop;
info = noop;
warn = noop;
error = noop;
}
import { Empty } from '.';
import { createPath } from './pathBuilder';
describe('shared/pathBuilder', () => {
describe('createPath', () => {
interface ById {
id: string;
}
it('should generate an empty path by default', () => {
const result = createPath((path) => path);
expect(result).toBe('/');
});
it('should not add blank literals', () => {
expect(createPath((path) => path.literal(''))).toBe('/');
});
it('should not add blank params', () => {
expect(createPath((path) => path.param('' as never))).toBe('/');
});
it('should not add extraneous slashes', () => {
expect(createPath((path) => path.literal('/api/todos/').literal('/completed/'))).toBe('/api/todos/completed');
});
it('should generate a path with a literal', () => {
const result = createPath<Empty>((path) => path
.literal('todos'));
expect(result).toBe('/todos');
});
it('should generate a path with a param', () => {
const result = createPath<ById>((path) => path
.param('id'));
expect(result).toBe('/:id');
});
it('should generate a path with a literal and param', () => {
const result = createPath<ById>((path) => path
.literal('todos')
.param('id'));
expect(result).toBe('/todos/:id');
});
it('should generate a path with a literal, param and literal', () => {
const result = createPath<ById>((path) => path
.literal('todos')
.param('id')
.literal('tags'));
expect(result).toBe('/todos/:id/tags');
});
it('should generate a path with a literal, param, literal and param', () => {
interface ByTodoIdAndTagId {
todoId: string;
tagId: number;
}
const result = createPath<ByTodoIdAndTagId>((path) => path
.literal('todos')
.param('todoId')
.literal('tags')
.param('tagId'));
expect(result).toBe('/todos/:todoId/tags/:tagId');
});
});
});
const removeLeadingAndTrailingSlashes = (
(path: string) => path
.replace(/^\/+/, '')
.replace(/\/+$/, '')
);
export class PathBuilder<TRequestParams> {
private readonly parts: string[] = [];
// Marked as private to discourage consumers from instantiating directly.
// Use the createPath function instead
// eslint-disable-next-line @typescript-eslint/no-empty-function
protected constructor() {
}
literal(path: string): PathBuilder<TRequestParams> {
if (path) {
this.parts.push(removeLeadingAndTrailingSlashes(path));
}
return this;
}
param(name: keyof TRequestParams): PathBuilder<TRequestParams> {
if (name) {
this.parts.push(`:${name}`);
}
return this;
}
toString() {
return `/${this.parts.join('/')}`;
}
}
export type PathBuildingFunction<TRequestParams> = (path: PathBuilder<TRequestParams>) => PathBuilder<TRequestParams>;
export function createPath<TRequestParams>(build: PathBuildingFunction<TRequestParams>): string {
class ConstructablePathBuilder extends PathBuilder<TRequestParams> {
public constructor() {
super();
}
}
const pathBuilder = build(new ConstructablePathBuilder());
return pathBuilder.toString();
}
import { TestCase } from 'jest-helpers';
import {
PathHelper, UnsupportedPathPatternError, RequiredPathParametersNotFound, GetUrlOptions,
} from './pathHelper';
describe('shared/pathHelper', () => {
describe('UnsupportedPathPatternError', () => {
it('should have message', () => {
expect(new UnsupportedPathPatternError('cat.meow'))
.toHaveProperty('message', 'Unsupported path pattern: "cat.meow"');
});
});
describe('RequiredPathParametersNotFound', () => {
it('should have message', () => {
expect(new RequiredPathParametersNotFound(['customerId', 'orderId']))
.toHaveProperty('message', 'Required path parameters not found: customerId, orderId');
});
});
describe('parsePathPattern', () => {
it('should parse the path pattern correctly', () => {
type ParsePathPatternTestCase = TestCase<string, { prePath: string; path: string; postPath: string }>;
const testCases: ReadonlyArray<ParsePathPatternTestCase> = Object.freeze([
{
input: '/users',
expected: {
prePath: '',
path: '/users',
postPath: '',
parameters: [],
},
},
{
input: '/users/:userId',
expected: {
prePath: '',
path: '/users/:userId',
postPath: '',
parameters: ['userId'],
},
},
{
input: '/users/:userId/orders',
expected: {
prePath: '',
path: '/users/:userId/orders',
postPath: '',
parameters: ['userId'],
},
},
{
input: '/users/:userId/orders/:orderId',
expected: {
prePath: '',
path: '/users/:userId/orders/:orderId',
postPath: '',
parameters: ['userId', 'orderId'],
},
},
{
input: 'localhost/users/:userId/orders/:orderId',
expected: {
prePath: 'localhost',
path: '/users/:userId/orders/:orderId',
postPath: '',
parameters: ['userId', 'orderId'],
},
},
{
input: 'example.com/users/:userId/orders/:orderId',
expected: {
prePath: 'example.com',
path: '/users/:userId/orders/:orderId',
postPath: '',
parameters: ['userId', 'orderId'],
},
},
{
input: 'localhost:8080/users/:userId/orders/:orderId',
expected: {
prePath: 'localhost:8080',
path: '/users/:userId/orders/:orderId',
postPath: '',
parameters: ['userId', 'orderId'],
},
},
{
input: 'http://localhost:8080/users/:userId/orders/:orderId',
expected: {
prePath: 'http://localhost:8080',
path: '/users/:userId/orders/:orderId',
postPath: '',
parameters: ['userId', 'orderId'],
},
},
{
input: 'www.example.com/users/:userId/orders/:orderId',
expected: {
prePath: 'www.example.com',
path: '/users/:userId/orders/:orderId',
postPath: '',
parameters: ['userId', 'orderId'],
},
},
{
input: 'http://www.example.com/users/:userId/orders/:orderId',
expected: {
prePath: 'http://www.example.com',
path: '/users/:userId/orders/:orderId',
postPath: '',
parameters: ['userId', 'orderId'],
},
},
{
input: 'https://www.example.com/users/:userId/orders/:orderId',
expected: {
prePath: 'https://www.example.com',
path: '/users/:userId/orders/:orderId',
postPath: '',
parameters: ['userId', 'orderId'],
},
},
]);
testCases.forEach((testCase) => {
const actual = PathHelper.parsePathPattern(testCase.input);
expect(actual).toEqual(testCase.expected);
});
});
});
describe('url', () => {
it('should generate the url correctly', () => {
type UrlTestCase = TestCase<{ pathPattern: string; options?: GetUrlOptions }, string>;
const userId = '123';
const orderId = '456';
const format = 'xml';
const pretty = '1';
const testCases: ReadonlyArray<UrlTestCase> = Object.freeze([
{
input: {
pathPattern: '/users',
options: { params: {} },
},
expected: '/users',
},
{
input: {
pathPattern: '/users/:userId',
options: { params: { userId } },
},
expected: `/users/${userId}`,
},
{
input: {
pathPattern: '/users/:userId/orders',
options: { params: { userId } },
},
expected: `/users/${userId}/orders`,
},
{
input: {
pathPattern: '/users/:userId/orders',
options: { params: { userId } },
},
expected: `/users/${userId}/orders`,
},
{
input: {
pathPattern: '/users/:userId/orders/:orderId',
options: {
params: {
userId,
orderId,
},
},
},
expected: `/users/${userId}/orders/${orderId}`,
},
{
input: {
pathPattern: '/users/:userId/orders/:orderId',
options: {
params: {
userId,
orderId,
format,
},
},
},
expected: `/users/${userId}/orders/${orderId}?format=${format}`,
},
{
input: {
pathPattern: '/users/:userId/orders/:orderId',
options: {
params: {
userId,
orderId,
format,
pretty,
},
},
},
expected: `/users/${userId}/orders/${orderId}?format=${format}&pretty=${pretty}`,
},
{
input: {
pathPattern: 'example.com/users/:userId',
options: { params: { userId } },
},
expected: `example.com/users/${userId}`,
},
{
input: {
pathPattern: 'example.com:8080/users/:userId',
options: { params: { userId } },
},
expected: `example.com:8080/users/${userId}`,
},
{
input: {
pathPattern: 'wow.cool.example.com:8080/users/:userId',
options: { params: { userId } },
},
expected: `wow.cool.example.com:8080/users/${userId}`,
},
{
input: {
pathPattern: 'example.com:8080/users/:userId/orders/:orderId',
options: { params: { userId, orderId } },
},
expected: `example.com:8080/users/${userId}/orders/${orderId}`,
},
{
input: {
pathPattern: 'http://example.com:8080/users/:userId/orders/:orderId',
options: { params: { userId, orderId } },
},
expected: `http://example.com:8080/users/${userId}/orders/${orderId}`,
},
]);
testCases.forEach((testCase) => {
const helper = new PathHelper(testCase.input.pathPattern);
const url = helper.url(testCase.input.options);
expect(url).toBe(testCase.expected);
});
});
it('should use server in url when server specified', () => {
type UrlTestCase = TestCase<{ pathPattern: string; params: { [key: string]: any } }, string>;
const server = 'https://www.example.com';
const userId = '123';
const orderId = '456';
const format = 'xml';
const pretty = '1';
const testCases: ReadonlyArray<UrlTestCase> = Object.freeze([
{
input: {
pathPattern: '/users',
params: {},
},
expected: `${server}/users`,
},
{
input: {
pathPattern: '/users/:userId',
params: { userId },
},
expected: `${server}/users/${userId}`,
},
{
input: {
pathPattern: '/users/:userId/orders',
params: { userId },
},
expected: `${server}/users/${userId}/orders`,
},
{
input: {
pathPattern: '/users/:userId/orders',
params: { userId },
},
expected: `${server}/users/${userId}/orders`,
},
{
input: {
pathPattern: '/users/:userId/orders/:orderId',
params: {
userId,
orderId,
},
},
expected: `${server}/users/${userId}/orders/${orderId}`,
},
{
input: {
pathPattern: '/users/:userId/orders/:orderId',
params: {
userId,
orderId,
format,
},
},
expected: `${server}/users/${userId}/orders/${orderId}?format=${format}`,
},
{
input: {
pathPattern: '/users/:userId/orders/:orderId',
params: {
userId,
orderId,
format,
pretty,
},
},
expected: `${server}/users/${userId}/orders/${orderId}?format=${format}&pretty=${pretty}`,
},
]);
testCases.forEach((testCase) => {
const helper = new PathHelper(testCase.input.pathPattern);
const url = helper.url({
server,
params: testCase.input.params,
});
expect(url).toBe(testCase.expected);
});
});
it('should error when required parameters are not provided', () => {
type InvalidUrlTestCase = TestCase<{ pathPattern: string; params: { [key: string]: any } }, string>;
const testCases: InvalidUrlTestCase[] = [
{
input: {
pathPattern: 'http://example.com/users/:userId',
params: {},
},
expected: 'Required path parameters not found: userId',
},
{
input: {
pathPattern: 'http://example.com/users/:userId/products/:productId',
params: {},
},
expected: 'Required path parameters not found: userId, productId',
},
];
const createTestAction = (testCase: InvalidUrlTestCase) => () => {
const pathHelper = new PathHelper(testCase.input.pathPattern);
const actual = pathHelper.url(testCase.input.params);
return actual;
};
testCases.forEach((testCase) => {
const action = createTestAction(testCase);
expect(action).toThrow(testCase.expected);
});
});
it('should error on invalid url patterns', () => {
type InvalidUrlTestCase = TestCase<{ pathPattern: string; params: { [key: string]: any } }, string>;
const testCases: InvalidUrlTestCase[] = [
{
input: {
pathPattern: 'http://example.com/users/:userId?format=:format',
params: {},
},
expected: 'Unsupported path pattern: "http://example.com/users/:userId?format=:format"',
},
];
const createTestAction = (testCase: InvalidUrlTestCase) => () => {
const pathHelper = new PathHelper(testCase.input.pathPattern);
const actual = pathHelper.url(testCase.input.params);
return actual;
};
testCases.forEach((testCase) => {
const action = createTestAction(testCase);
expect(action).toThrow(testCase.expected);
});
});
});
describe('parse', () => {
it('should parse an url returning extracted values', () => {
const userId = '123';
const orderId = '456';
const format = 'xml';
const pretty = '1';
type ParseTestCase = TestCase<{ pattern: string; path: string }, { params: { [key: string]: any } } | undefined>;
const testCases: ReadonlyArray<ParseTestCase> = Object.freeze([
{
input: {
pattern: '/users',
path: '/users',
},
expected: {
prePath: '',
path: '/users',
postPath: '',
params: {},
},
},
{
input: {
pattern: '/users/:userId',
path: `/users/${userId}`,
},
expected: {
prePath: '',
path: `/users/${userId}`,
postPath: '',
params: { userId },
},
},
{
input: {
pattern: '/users/:userId/orders',
path: `/users/${userId}/orders`,
},
expected: {
prePath: '',
path: `/users/${userId}/orders`,
postPath: '',
params: { userId },
},
},
{
input: {
pattern: '/users/:userId/orders',
path: `/users/${userId}/orders`,
},
expected: {
prePath: '',
path: `/users/${userId}/orders`,
postPath: '',
params: { userId },
},
},
{
input: {
pattern: '/users/:userId/orders/:orderId',
path: `/users/${userId}/orders/${orderId}`,
},
expected: {
prePath: '',
path: `/users/${userId}/orders/${orderId}`,
postPath: '',
params: { userId, orderId },
},
},
{
input: {
pattern: '/users/:userId/orders/:orderId',
path: `/users/${userId}/orders/${orderId}?format=${format}`,
},
expected: {
prePath: '',
path: `/users/${userId}/orders/${orderId}`,
postPath: `?format=${format}`,
params: { userId, orderId, format },
},
},
{
input: {
pattern: '/users/:userId/orders/:orderId',
path: `/users/${userId}/orders/${orderId}?format=${format}&pretty=${pretty}`,
},
expected: {
prePath: '',
path: `/users/${userId}/orders/${orderId}`,
postPath: `?format=${format}&pretty=${pretty}`,
params: {
userId, orderId, format, pretty,
},
},
},
{
input: {
pattern: 'example.com/users/:userId',
path: `example.com/users/${userId}`,
},
expected: {
prePath: 'example.com',
path: `/users/${userId}`,
postPath: '',
params: { userId },
},
},
{
input: {
pattern: 'example.com:8080/users/:userId',
path: `example.com:8080/users/${userId}`,
},
expected: {
prePath: 'example.com:8080',
path: `/users/${userId}`,
postPath: '',
params: { userId },
},
},
{
input: {
pattern: 'wow.cool.example.com:8080/users/:userId',
path: `wow.cool.example.com:8080/users/${userId}`,
},
expected: {
prePath: 'wow.cool.example.com:8080',
path: `/users/${userId}`,
postPath: '',
params: { userId },
},
},
{
input: {
pattern: 'example.com:8080/users/:userId/orders/:orderId',
path: `example.com:8080/users/${userId}/orders/${orderId}`,
},
expected: {
prePath: 'example.com:8080',
path: `/users/${userId}/orders/${orderId}`,
postPath: '',
params: { userId, orderId },
},
},
{
input: {
pattern: 'http://example.com:8080/users/:userId/orders/:orderId',
path: `http://example.com:8080/users/${userId}/orders/${orderId}`,
},
expected: {
prePath: 'http://example.com:8080',
path: `/users/${userId}/orders/${orderId}`,
postPath: '',
params: { userId, orderId },
},
},
{
input: {
pattern: 'http://example.com:8080/users/:userId/orders/:orderId',
path: `http://example.com:8080/users/${userId}/orders/${orderId}?format=${format}#top`,
},
expected: {
prePath: 'http://example.com:8080',
path: `/users/${userId}/orders/${orderId}`,
postPath: `?format=${format}#top`,
params: { userId, orderId, format },
},
},
{
input: {
pattern: '/products',
path: '/products/1',
},
expected: undefined,
},
]);
testCases.forEach((testCase) => {
const helper = new PathHelper(testCase.input.pattern);
const result = helper.parse(testCase.input.path);
if (testCase.expected === undefined) {
// eslint-disable-next-line jest/no-conditional-expect
expect(result).toBeUndefined();
} else {
// eslint-disable-next-line jest/no-conditional-expect
expect(result).toEqual(testCase.expected);
}
});
});
});
});
// eslint-disable-next-line max-classes-per-file
import { escapeRegExp } from './regexp';
import {
addQueryStringToUrl, ParsedUrl, parseQueryString, parseUrl,
} from './url';
export class UnsupportedPathPatternError extends Error {
// istanbul ignore next - typescript creates a branch for super calls
constructor(path: string) {
super(`Unsupported path pattern: "${path}"`);
}
}
export class RequiredPathParametersNotFound extends Error {
// istanbul ignore next - typescript creates a branch for super calls
constructor(parameterNames: string[]) {
super(`Required path parameters not found: ${parameterNames.join(', ')}`);
}
}
export interface PathHelperParseMatch extends ParsedUrl {
params: { [key: string]: any };
}
export interface ParsedPathPattern extends ParsedUrl {
parameters: string[];
}
export interface GetUrlOptions {
params?: { [key: string]: any } | undefined;
server?: string | undefined;
}
export class PathHelper {
static parsePathPattern(pathPattern: string): ParsedPathPattern {
const parsedUrl = parseUrl(pathPattern);
const parameters = this.getParameterNamesFromPathPattern(parsedUrl.path);
return {
...parsedUrl,
parameters,
};
}
private static generateParseFunction(
parsedPathPattern: ParsedPathPattern,
): (path: string) => (PathHelperParseMatch | undefined) {
const parameterNames: string[] = [];
const getParameterPlaceholder = (index: number) => `-----${index}-----`;
let pathParametersRegExpPattern = parsedPathPattern.path.replace(this.getPathPatternParameterRegExp(), (_, key) => {
parameterNames.push(key);
return getParameterPlaceholder(parameterNames.length - 1);
});
pathParametersRegExpPattern = escapeRegExp(pathParametersRegExpPattern);
for (let parameterIndex = 0; parameterIndex < parameterNames.length; parameterIndex++) {
pathParametersRegExpPattern = pathParametersRegExpPattern
.replace(escapeRegExp(getParameterPlaceholder(parameterIndex)), '([^&?/\\\\]+)');
}
pathParametersRegExpPattern = `^${pathParametersRegExpPattern}$`;
const pathParametersRegEx = new RegExp(pathParametersRegExpPattern, 'i');
return (path: string): PathHelperParseMatch | undefined => {
const parsedUrl = parseUrl(path);
// Test url and extract path parameters
pathParametersRegEx.lastIndex = -1;
// const parameterValues: string[] = [];
const match = pathParametersRegEx.exec(parsedUrl.path);
if (!match) {
return undefined;
}
const result: PathHelperParseMatch = {
...parsedUrl,
params: {},
};
// Add path parameters to result
if (match.length > 1) {
for (let parameterIndex = 1; parameterIndex < match.length; parameterIndex++) {
const parameterName = parameterNames[parameterIndex - 1];
const parameterValue = match[parameterIndex];
result.params[parameterName] = parameterValue;
}
}
// Extract and add query string parameters to result
const queryStringParameters = parseQueryString(parsedUrl.postPath);
Object.getOwnPropertyNames(queryStringParameters).forEach((parameterName) => {
const parameterValue = queryStringParameters[parameterName];
result.params[parameterName] = parameterValue;
});
return result;
};
}
private static getPathPatternParameterRegExp = () => /:([^\s/?\n\d][^\s/?\n]*)/gim;
// private static getPathAndQueryStringSplitterRegExp = () => /^([^?\n] +)(\?.*)?$/i;
private static getParameterNamesFromPathPattern(pathPattern: string) {
const parameterNames: string[] = [];
const pathParameterRegExp = PathHelper.getPathPatternParameterRegExp();
let match: RegExpExecArray | null;
do {
match = pathParameterRegExp.exec(pathPattern);
if (match) {
parameterNames.push(match[1]);
}
} while (match);
return parameterNames;
}
private static checkForQueryString(path: string) {
if (path.indexOf('?') > -1) {
throw new UnsupportedPathPatternError(path);
}
}
private readonly parsedPathPattern = PathHelper.parsePathPattern(this.pathPattern);
readonly parse = PathHelper.generateParseFunction(this.parsedPathPattern);
constructor(readonly pathPattern: string) {
PathHelper.checkForQueryString(pathPattern);
}
url(options?: GetUrlOptions): string {
const params = (options && options.params) || {};
const server = (options && options.server) || '';
const providedParameterNames = Object.getOwnPropertyNames(params);
const missingParameterNames: string[] = [];
const queryStringParameterNames: string[] = [];
this.parsedPathPattern.parameters.forEach((requiredParameterName) => {
const isRequiredParameterProvided = providedParameterNames.some(
(parameterName) => parameterName === requiredParameterName,
);
if (!isRequiredParameterProvided) {
missingParameterNames.push(requiredParameterName);
}
});
providedParameterNames.forEach((providedParameterName) => {
const isProvidedParameterRequired = this.parsedPathPattern.parameters.some(
(parameterName) => parameterName === providedParameterName,
);
if (!isProvidedParameterRequired) {
queryStringParameterNames.push(providedParameterName);
}
});
if (missingParameterNames.length) {
throw new RequiredPathParametersNotFound(missingParameterNames);
}
let url = this.pathPattern.replace(/:([^\s/?\n\d][^\s/?\n]*)/gim, (_, key) => `${params[key]}`);
const queryString = queryStringParameterNames
.map((parameterName) => `${encodeURIComponent(parameterName)}=${encodeURIComponent(params[parameterName])}`)
.join('&');
if (queryString) {
url = addQueryStringToUrl(url, queryString);
}
if (server) {
url = server + url;
}
return url;
}
}
import { TestCase } from 'jest-helpers';
import { escapeRegExp } from './regexp';
describe('shared/regexp', () => {
describe('escapeRegExp', () => {
it('should escape text with regex characters characters', () => {
type EscapeRegExpTestCase = TestCase<string, string>;
const testCases: EscapeRegExpTestCase[] = [
{
input: 'Hello world',
expected: 'Hello world',
},
{
input: '[(\\hello|world/)]',
expected: '\\[\\(\\\\hello\\|world\\/\\)\\]',
},
];
testCases.forEach((testCase) => {
const actual = escapeRegExp(testCase.input);
expect(actual).toBe(testCase.expected);
});
});
});
});
export function escapeRegExp(input: string): string {
return input.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
}
import { TestCase } from 'jest-helpers';
import {
parseQueryString, parseUrl, QueryParameterValues, addQueryStringToUrl,
} from './url';
describe('shared/url', () => {
describe('parseUrl', () => {
type ParsePathPatternTestCase = TestCase<string, { prePath: string; path: string; postPath: string }>;
const testCases: ReadonlyArray<ParsePathPatternTestCase> = Object.freeze([
{
input: '',
expected: {
prePath: '',
path: '',
postPath: '',
},
},
{
input: '/',
expected: {
prePath: '',
path: '/',
postPath: '',
},
},
{
input: '/users',
expected: {
prePath: '',
path: '/users',
postPath: '',
},
},
{
input: 'users',
expected: {
prePath: 'users',
path: '',
postPath: '',
},
},
{
input: '/users/123',
expected: {
prePath: '',
path: '/users/123',
postPath: '',
},
},
{
input: 'example.com/users/123',
expected: {
prePath: 'example.com',
path: '/users/123',
postPath: '',
},
},
{
input: 'localhost:8080/users/123',
expected: {
prePath: 'localhost:8080',
path: '/users/123',
postPath: '',
},
},
{
input: 'http://localhost:8080/users/123',
expected: {
prePath: 'http://localhost:8080',
path: '/users/123',
postPath: '',
},
},
{
input: 'www.example.com/users/123',
expected: {
prePath: 'www.example.com',
path: '/users/123',
postPath: '',
},
},
{
input: 'http://www.example.com/users/123',
expected: {
prePath: 'http://www.example.com',
path: '/users/123',
postPath: '',
},
},
{
input: 'https://www.example.com/users/123',
expected: {
prePath: 'https://www.example.com',
path: '/users/123',
postPath: '',
},
},
{
input: 'https://www.example.com/users/123?format=xml',
expected: {
prePath: 'https://www.example.com',
path: '/users/123',
postPath: '?format=xml',
},
},
{
input: 'https://www.example.com/users/123#content',
expected: {
prePath: 'https://www.example.com',
path: '/users/123',
postPath: '#content',
},
},
{
input: 'https://www.example.com/users/123?format=html#content',
expected: {
prePath: 'https://www.example.com',
path: '/users/123',
postPath: '?format=html#content',
},
},
]);
it('should extract pre-path, path and post-path', () => {
testCases.forEach((testCase) => {
const actual = parseUrl(testCase.input);
expect(actual).toEqual(testCase.expected);
});
});
});
describe('parseQueryString', () => {
type ParseQueryStringTestCase = TestCase<string, QueryParameterValues>;
const format = 'json';
const id1 = '1';
const id2 = '2';
const id3 = '3';
const testCases: ParseQueryStringTestCase[] = [
{
input: '',
expected: {},
},
{
input: '?',
expected: {},
},
{
input: `?format=${format}`,
expected: { format },
},
{
input: `?format=${format}&id=${id1}`,
expected: {
format,
id: id1,
},
},
{
input: `?format=${format}&id=${id1}&id=${id2}&id=${id3}`,
expected: {
format,
id: [id1, id2, id3],
},
},
{
input: `?format=${format}&id=${id1}&id=${id2}#top`,
expected: {
format,
id: [id1, id2],
},
},
{
input: `?pretty&id=${id1}`,
expected: {
pretty: '',
id: id1,
},
},
{
input: '?pretty',
expected: {
pretty: '',
},
},
];
it('should return parameter names and values', () => {
testCases.forEach((testCase) => {
const actual = parseQueryString(testCase.input);
expect(actual).toEqual(testCase.expected);
});
});
});
describe('addQueryStringToUrl', () => {
it('should correctly add a query string to an url', () => {
const testCases: TestCase<{ url: string; queryString: string }, string>[] = [
{
input: {
url: 'http://catfinder.ninja',
queryString: 'breed=bengal',
},
expected: 'http://catfinder.ninja?breed=bengal',
},
{
input: {
url: 'http://catfinder.ninja?',
queryString: 'breed=bengal',
},
expected: 'http://catfinder.ninja?breed=bengal',
},
{
input: {
url: 'http://catfinder.ninja?breed=bengal',
queryString: 'temperament=feisty',
},
expected: 'http://catfinder.ninja?breed=bengal&temperament=feisty',
},
];
testCases.forEach(({ input: { url, queryString }, expected }) => {
const actual = addQueryStringToUrl(url, queryString);
expect(actual).toEqual(expected);
});
});
});
});
export interface ParsedUrl {
prePath: string;
path: string;
postPath: string;
}
export function parseUrl(url: string): ParsedUrl {
let index = 0;
let pathStartIndex: number | undefined;
let pathLength: number | undefined;
while (index < url.length && pathLength === undefined) {
if (pathStartIndex === undefined) {
if (url[index] === '/') {
if (url[index + 1] === '/') {
index += 2;
} else {
pathStartIndex = index;
index++;
}
} else {
index++;
}
} else if (url[index] === '#' || url[index] === '?') {
pathLength = index - pathStartIndex;
} else {
index++;
}
}
if (pathStartIndex !== undefined && pathLength === undefined) {
pathLength = url.length - pathStartIndex;
}
const prePath = url.substring(0, pathStartIndex === undefined ? url.length + 1 : pathStartIndex);
const path = pathStartIndex === undefined ? '' : url.substr(pathStartIndex, pathLength);
const postPath = (
(pathStartIndex === undefined || pathLength === undefined)
? ''
: url.substr(pathStartIndex + pathLength)
);
return {
prePath,
path,
postPath,
};
}
export interface QueryParameterValues {
[key: string]: string | string[];
}
export function parseQueryString(queryString: string): QueryParameterValues {
const result: QueryParameterValues = {};
// eslint-disable-next-line no-shadow
enum Position {
key,
value
}
const trimmedQueryString = queryString.trim();
if (trimmedQueryString[0] !== '?') {
return result;
}
let position = Position.key;
let parameterName = '';
let parameterValue = '';
const addParameter = () => {
const existingValue = result[parameterName];
if (existingValue === undefined) {
result[parameterName] = parameterValue;
} else if (typeof existingValue === 'string') {
result[parameterName] = [existingValue, parameterValue];
} else {
existingValue.push(parameterValue);
}
parameterName = '';
parameterValue = '';
};
let index = 1;
while (index < trimmedQueryString.length) {
const char = trimmedQueryString[index];
if (char === '#') {
break;
}
if (position === Position.key) {
if (char === '=') {
position = Position.value;
} else if (char === '&') {
addParameter();
} else {
parameterName += char;
}
} else if (char === '&') {
addParameter();
position = Position.key;
} else {
parameterValue += char;
}
index++;
}
if (parameterName) {
addParameter();
}
return result;
}
export function addQueryStringToUrl(url: string, queryString: string) {
const index = url.indexOf('?');
const endsWithQuestionMark = index === url.length - 1;
let separator = '';
if (index === -1) {
separator = '?';
} else if (!endsWithQuestionMark) {
separator = '&';
}
url = url + separator + queryString;
return url;
}
+1
-1

@@ -1,2 +0,2 @@

Copyright (c) 2019, Ben <codeandcats@gmail.com>.
Copyright (c) 2018 - 2021, Benji <codeandcats@gmail.com>.

@@ -3,0 +3,0 @@ Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.

{
"name": "@typepoint/shared",
"version": "3.0.2",
"main": "index.js",
"types": "index.d.ts",
"license": "SEE LICENSE IN LICENSE",
"author": "Ben <codeandcats@gmail.com> (https://github.com/codeandcats)",
"version": "4.0.0",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"license": "ISC",
"files": [
"/dist",
"/src",
"/LICENSE",
"/README.md"
],
"author": "Benji <codeandcats@gmail.com> (https://github.com/codeandcats)",
"contributors": [
"Ben <codeandcats@gmail.com> (https://github.com/codeandcats)"
"Benji <codeandcats@gmail.com> (https://github.com/codeandcats)"
],

@@ -18,3 +24,19 @@ "keywords": [

"request"
]
}
],
"scripts": {
"clean": "rm -rf ./dist ./LICENSE",
"build": "yarn clean && tsc -p ./tsconfig.main.json --noEmit false && cp ../../LICENSE ./",
"lint": "yarn eslint -c '../../.eslintrc.js' ./src/**/* --ext .js,.jsx,.ts,.tsx --format visualstudio",
"test": "jest",
"validate": "yarn lint && yarn build && yarn test"
},
"devDependencies": {
"@typepoint/fixtures": "^4.0.0",
"terser-webpack-plugin": "^5.1.4",
"ts-loader": "^9.2.4",
"typescript": "4.3.5",
"webpack": "^5.47.1",
"webpack-cli": "^4.7.2"
},
"gitHead": "18ca4a315efa227c921fd026cee72eb4d3b9d7cc"
}

@@ -21,7 +21,4 @@ <p align="center">

TypePoint requires at least TypeScript v3.6.4.
```sh
npm add @typepoint/shared
npm add typescript -D
```

@@ -28,0 +25,0 @@

## [3.0.2](https://github.com/typepoint/typepoint/compare/@typepoint/shared_v3.0.1...@typepoint/shared_v3.0.2) (2020-03-29)
### Bug Fixes
* remove private field from package.json ([8e7b3ca](https://github.com/typepoint/typepoint/commit/8e7b3ca894922e10b7e3566f60e0e58dadccf545))
## [3.0.1](https://github.com/typepoint/typepoint/compare/@typepoint/shared_v3.0.0...@typepoint/shared_v3.0.1) (2020-03-18)
### Bug Fixes
* update package author, contributors, keywords ([41ba6fa](https://github.com/typepoint/typepoint/commit/41ba6fa2f66ca147008046551cd917ce0a7f4ddc))
# [3.0.0](https://github.com/typepoint/typepoint/compare/@typepoint/shared_v2.0.5...@typepoint/shared_v3.0.0) (2020-03-10)
### Bug Fixes
* yarn validate was not validating server ([5558f9f](https://github.com/typepoint/typepoint/commit/5558f9f140bc52c228980e0defda67423dd008bf))
* **ci:** fix updating of types entry in package.json ([cf8ccc6](https://github.com/typepoint/typepoint/commit/cf8ccc681c71a4b1bc84edc6c9aefee9d0fc8959))
* **defineendpoint:** path will no longer include extraneous slashes ([000421d](https://github.com/typepoint/typepoint/commit/000421d8d01960b11b9a0f083008e6fff607f4af))
* **middleware:** remove chalk ([fe1b1c5](https://github.com/typepoint/typepoint/commit/fe1b1c5baea8ab5fadffdc4508bb646634300611))
* **package:** add author ([e131bcd](https://github.com/typepoint/typepoint/commit/e131bcdc3d39ee6e50819b6aee730ef1ea5509e3))
* **package:** add author ([7f95859](https://github.com/typepoint/typepoint/commit/7f9585912cfa342acdb324eb1f565b582383edcf))
* **package:** fix types entry in package.json ([c9633d5](https://github.com/typepoint/typepoint/commit/c9633d5e1addda49fa04c92be00a8c408b2e791e))
* **package:** fix types entry in package.json ([949f03a](https://github.com/typepoint/typepoint/commit/949f03adcf0c5c812d864e65a0da0ed5c23395f9))
* **package:** fix types entry in package.json ([27d0d38](https://github.com/typepoint/typepoint/commit/27d0d38545199c6a252bf947b21d27fb6ef108eb))
* **package:** fix types entry in package.json ([b026d91](https://github.com/typepoint/typepoint/commit/b026d918b1a42e7f68cda4192de887e2e48f5616))
* **package:** fix types entry, use latest shared ([649e724](https://github.com/typepoint/typepoint/commit/649e72406460d19483394c46222a2dffe0af92e3))
* **todoservice:** fix fixtures import ([23c8989](https://github.com/typepoint/typepoint/commit/23c898932fa59c81cda58f2307fe400ea57fa000))
### Features
* add dependency diagram for reference ([b3ff237](https://github.com/typepoint/typepoint/commit/b3ff237ae9c8eb8ac77adb01436c6aafb5df2201))
* force major version bump ([1a729f4](https://github.com/typepoint/typepoint/commit/1a729f41cad74f044745dc853e3389c7c6fcb3a1))
* move code around ([1481e81](https://github.com/typepoint/typepoint/commit/1481e81e3ac57b7830f66f2a97e8e61681b83ed8))
* **core:** type overhaul ([5731717](https://github.com/typepoint/typepoint/commit/573171725098204175d317debbbf9e4bcf2463fe))
* **types:** loosen types on validateAndTransform function ([79a2d37](https://github.com/typepoint/typepoint/commit/79a2d375aea799153dfe2c8e7c31478d3f1910f3))
### BREAKING CHANGES
* The breaking changes were in earlier commits not yet released. This commit is just to forcefully bump the major version.
## [2.0.5](https://github.com/typepoint/typepoint/compare/@typepoint/shared_v2.0.4...@typepoint/shared_v2.0.5) (2019-11-17)
### Bug Fixes
* **types:** fix types entry in package.json ([6b05c72](https://github.com/typepoint/typepoint/commit/6b05c72d74c8a8645957c3d56267dfa914647100))
## [2.0.4](https://github.com/typepoint/typepoint/compare/@typepoint/shared_v2.0.3...@typepoint/shared_v2.0.4) (2019-11-17)
### Bug Fixes
* **package:** add missing author tag ([a72b554](https://github.com/typepoint/typepoint/commit/a72b554aebaa0b9d0b48bed7d74ba35fab7c7047))
## [2.0.3](https://github.com/typepoint/typepoint/compare/@typepoint/shared_v2.0.2...@typepoint/shared_v2.0.3) (2019-11-17)
### Bug Fixes
* **readme:** add logo ([6590c68](https://github.com/typepoint/typepoint/commit/6590c6892e2130ba91e8839510087be2d2aaa06b))
* **release:** fix broken release script ([74bc382](https://github.com/typepoint/typepoint/commit/74bc38242ce07e8e8c9ea930e649ed17fa161968))
## [2.0.3](https://github.com/typepoint/typepoint/compare/@typepoint/shared_v2.0.2...@typepoint/shared_v2.0.3) (2019-11-17)
### Bug Fixes
* **readme:** add logo ([6590c68](https://github.com/typepoint/typepoint/commit/6590c6892e2130ba91e8839510087be2d2aaa06b))
# Changelog
All notable changes to this project will be documented in this file.
### [2.0.2](https://github.com/typepoint/typepoint/compare/v2.0.1...v2.0.2) (2019-10-24)
### [2.0.1](https://github.com/typepoint/typepoint/compare/v0.1.0...v2.0.1) (2019-10-24)
import { PathBuildingFunction } from './pathBuilder';
import { PathHelperParseMatch } from './pathHelper';
export { Logger, NoopLogger, } from './logger';
export { GetUrlOptions, PathHelperParseMatch, ParsedPathPattern, PathHelper, RequiredPathParametersNotFound, UnsupportedPathPatternError, } from './pathHelper';
export { parseQueryString, ParsedUrl, parseUrl, QueryParameterValues, } from './url';
export declare const cleanseHttpMethod: (method: string) => string;
export declare type Constructor<T> = new (...args: any[]) => T;
export interface ArrayOfTypeInfo<T> {
element: T;
}
export declare class ArrayOfClassInfo<T> {
readonly element: Constructor<T>;
constructor(element: Constructor<T>);
}
export declare abstract class ArrayOf<T> {
static isArrayOf: true;
readonly classInfo?: ArrayOfClassInfo<T>;
constructor(Class: Constructor<T>);
}
export declare function arrayOf<T>(Class: Constructor<T>): Constructor<ArrayOf<T>>;
export declare function isArrayOf(Class: any): Class is Constructor<ArrayOf<any>>;
export declare type NormalizeArrayOf<T> = T extends ArrayOf<infer TElementType> ? TElementType[] : T;
export declare class Empty {
readonly __isEmpty = true;
}
export declare function isEmptyClass(Class: any): boolean;
export declare function isEmptyValue(value: any): boolean;
export declare type NormalizeDefinitionType<T> = (T extends Array<Constructor<infer TInstance>> ? TInstance[] : T extends Constructor<infer TInstance> ? TInstance : T extends ArrayOf<infer TElementType> ? TElementType[] : T extends [infer TElementType] ? TElementType : T);
export declare type NormalizeTypePointType<T> = (T extends ArrayOf<infer TElementType> ? TElementType[] : T extends Empty ? ({} | undefined) : T);
export declare type AllowableRequestParams = Empty | Record<string, any>;
export declare type AllowableRequestBody = Empty | Record<string, any> | Array<any>;
export declare type AllowableResponseBody = Empty | Record<string, any> | Array<any>;
export declare type AllowableClassBasedRequestParams = Empty | Constructor<any>;
export declare type AllowableClassBasedRequestBody = Empty | Constructor<any> | Constructor<any>[];
export declare type AllowableClassBasedResponseBody = Empty | Constructor<any> | Constructor<any>[];
export interface EndpointDefinitionUrlOptions<TRequestParams> {
server?: string | undefined;
params?: NormalizeDefinitionType<TRequestParams> | undefined;
}
export interface ClassBasedEndpointDefinitionOptions<TRequestParams extends AllowableClassBasedRequestParams, TRequestBody extends AllowableClassBasedRequestBody, TResponseBody extends AllowableClassBasedResponseBody> {
method?: string;
path: PathBuildingFunction<NormalizeDefinitionType<TRequestParams>>;
requestParams?: TRequestParams;
requestBody?: TRequestBody;
responseBody?: TResponseBody;
}
export declare class EndpointDefinitionRequestClassInfo<TParams, TBody> {
readonly params: Constructor<TParams>;
readonly body: Constructor<TBody> | [any];
constructor(params: Constructor<TParams>, body: Constructor<TBody> | [any]);
}
export declare class EndpointDefinitionResponseClassInfo<TBody> {
readonly body: Constructor<TBody> | [any];
constructor(body: Constructor<TBody> | [any]);
}
export declare class EndpointDefinitionClassInfo {
readonly request: EndpointDefinitionRequestClassInfo<any, any>;
readonly response: EndpointDefinitionResponseClassInfo<any>;
constructor(requestParams: Constructor<any>, requestBody: Constructor<any> | [any], responseBody: Constructor<any> | [any]);
}
export declare class EndpointDefinitionInvalidConstructorArgs extends Error {
constructor(actualArgs: any[]);
}
export interface EndpointDefinition<TRequestParams extends AllowableRequestParams, TRequestBody extends AllowableRequestBody, TResponseBody extends AllowableResponseBody> {
readonly method: string;
readonly path: string;
readonly classInfo?: EndpointDefinitionClassInfo | undefined;
parse(url: string): PathHelperParseMatch | undefined;
url(options?: EndpointDefinitionUrlOptions<TRequestParams> | undefined): string;
}
export declare function defineEndpoint<TRequestParams extends AllowableRequestParams, TRequestBody extends AllowableRequestBody, TResponseBody extends AllowableResponseBody>(buildPath: PathBuildingFunction<TRequestParams>): EndpointDefinition<NormalizeDefinitionType<TRequestParams>, NormalizeDefinitionType<TRequestBody>, NormalizeDefinitionType<TResponseBody>>;
export declare function defineEndpoint<TRequestParams extends AllowableRequestParams = Empty, TRequestBody extends AllowableRequestBody = Empty, TResponseBody extends AllowableResponseBody = Empty>(method: string, buildPath: PathBuildingFunction<TRequestParams>): EndpointDefinition<NormalizeDefinitionType<TRequestParams>, NormalizeDefinitionType<TRequestBody>, NormalizeDefinitionType<TResponseBody>>;
export declare function defineEndpoint<TRequestParams extends AllowableClassBasedRequestParams = Empty, TRequestBody extends AllowableClassBasedRequestBody = Empty, TResponseBody extends AllowableClassBasedResponseBody = Empty>(options: ClassBasedEndpointDefinitionOptions<TRequestParams, TRequestBody, TResponseBody>): EndpointDefinition<NormalizeDefinitionType<TRequestParams>, NormalizeDefinitionType<TRequestBody>, NormalizeDefinitionType<TResponseBody>>;
export declare type GetEndpointDefinitionRequestParams<TEndpointDefinition extends EndpointDefinition<any, any, any>> = TEndpointDefinition extends EndpointDefinition<infer TRequestParams, any, any> ? TRequestParams : never;
export declare type GetEndpointDefinitionRequestBody<TEndpointDefinition extends EndpointDefinition<any, any, any>> = TEndpointDefinition extends EndpointDefinition<any, infer TRequestBody, any> ? TRequestBody : never;
export declare type GetEndpointDefinitionResponseBody<TEndpointDefinition extends EndpointDefinition<any, any, any>> = TEndpointDefinition extends EndpointDefinition<any, any, infer TResponseBody> ? TResponseBody : never;
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
// eslint-disable-next-line max-classes-per-file
var pathBuilder_1 = require("./pathBuilder");
var pathHelper_1 = require("./pathHelper");
var logger_1 = require("./logger");
exports.NoopLogger = logger_1.NoopLogger;
var pathHelper_2 = require("./pathHelper");
exports.PathHelper = pathHelper_2.PathHelper;
exports.RequiredPathParametersNotFound = pathHelper_2.RequiredPathParametersNotFound;
exports.UnsupportedPathPatternError = pathHelper_2.UnsupportedPathPatternError;
var url_1 = require("./url");
exports.parseQueryString = url_1.parseQueryString;
exports.parseUrl = url_1.parseUrl;
exports.cleanseHttpMethod = function (method) { return method.toUpperCase(); };
var ArrayOfClassInfo = /** @class */ (function () {
function ArrayOfClassInfo(element) {
this.element = element;
}
return ArrayOfClassInfo;
}());
exports.ArrayOfClassInfo = ArrayOfClassInfo;
var ArrayOf = /** @class */ (function () {
function ArrayOf(Class) {
this.classInfo = new ArrayOfClassInfo(Class);
}
ArrayOf.isArrayOf = true;
return ArrayOf;
}());
exports.ArrayOf = ArrayOf;
function arrayOf(Class) {
var AnonymousArrayOf = /** @class */ (function (_super) {
__extends(AnonymousArrayOf, _super);
function AnonymousArrayOf() {
return _super.call(this, Class) || this;
}
return AnonymousArrayOf;
}(ArrayOf));
return AnonymousArrayOf;
}
exports.arrayOf = arrayOf;
function isArrayOf(Class) {
if (!Class) {
return false;
}
return Boolean(Class.isArrayOf);
}
exports.isArrayOf = isArrayOf;
var Empty = /** @class */ (function () {
function Empty() {
// istanbul ignore next
this.__isEmpty = true;
}
return Empty;
}());
exports.Empty = Empty;
function isEmptyClass(Class) {
return Class === Empty;
}
exports.isEmptyClass = isEmptyClass;
function isEmptyValue(value) {
if (value === null || value === undefined) {
return true;
}
if (typeof value === 'object' && !Object.keys(value).length) {
return true;
}
return false;
}
exports.isEmptyValue = isEmptyValue;
function normalizeDefinitionType(value) {
return value;
}
var EndpointDefinitionRequestClassInfo = /** @class */ (function () {
function EndpointDefinitionRequestClassInfo(params, body) {
this.params = params;
this.body = body;
}
return EndpointDefinitionRequestClassInfo;
}());
exports.EndpointDefinitionRequestClassInfo = EndpointDefinitionRequestClassInfo;
var EndpointDefinitionResponseClassInfo = /** @class */ (function () {
function EndpointDefinitionResponseClassInfo(body) {
this.body = body;
}
return EndpointDefinitionResponseClassInfo;
}());
exports.EndpointDefinitionResponseClassInfo = EndpointDefinitionResponseClassInfo;
var EndpointDefinitionClassInfo = /** @class */ (function () {
function EndpointDefinitionClassInfo(requestParams, requestBody, responseBody) {
this.request = new EndpointDefinitionRequestClassInfo(requestParams, requestBody);
this.response = new EndpointDefinitionResponseClassInfo(responseBody);
}
return EndpointDefinitionClassInfo;
}());
exports.EndpointDefinitionClassInfo = EndpointDefinitionClassInfo;
var EndpointDefinitionInvalidConstructorArgs = /** @class */ (function (_super) {
__extends(EndpointDefinitionInvalidConstructorArgs, _super);
function EndpointDefinitionInvalidConstructorArgs(actualArgs) {
var _this = this;
var received = (!actualArgs.length
? 'zero arguments'
: actualArgs.map(function (arg) { return typeof arg; }).join(', '));
// istanbul ignore next - typescript creates a branch for super calls
_this = _super.call(this, "Invalid EndpointDefinition constructor arguments - received " + actualArgs.length + " arguments: " + received) || this;
return _this;
}
return EndpointDefinitionInvalidConstructorArgs;
}(Error));
exports.EndpointDefinitionInvalidConstructorArgs = EndpointDefinitionInvalidConstructorArgs;
function defineEndpoint() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
var DEFAULT_METHOD = 'GET';
var make = function (_a) {
var classInfo = _a.classInfo, method = _a.method, pathFunc = _a.pathFunc;
var path = pathBuilder_1.createPath(pathFunc);
var pathHelper = new pathHelper_1.PathHelper(path);
return {
method: method,
path: path,
classInfo: classInfo,
parse: function (url) { return pathHelper.parse(url); },
url: function (options) { return pathHelper.url(options); },
};
};
switch (args.length) {
case 1: {
var firstArg = args[0];
if (typeof firstArg === 'function') {
return make({
method: DEFAULT_METHOD,
pathFunc: firstArg,
});
}
if (firstArg && typeof firstArg === 'object') {
var classInfo = new EndpointDefinitionClassInfo(normalizeDefinitionType(firstArg.requestParams || Empty), normalizeDefinitionType(firstArg.requestBody || Empty), normalizeDefinitionType(firstArg.responseBody || Empty));
return make({
classInfo: classInfo,
method: exports.cleanseHttpMethod(firstArg.method || DEFAULT_METHOD),
pathFunc: firstArg.path,
});
}
throw new EndpointDefinitionInvalidConstructorArgs(args);
}
case 2: {
var method = args[0], pathFunc = args[1];
if (typeof method !== 'string' || typeof pathFunc !== 'function') {
throw new EndpointDefinitionInvalidConstructorArgs(args);
}
return make({
method: exports.cleanseHttpMethod(method || DEFAULT_METHOD),
pathFunc: pathFunc,
});
}
default: {
throw new EndpointDefinitionInvalidConstructorArgs(args);
}
}
}
exports.defineEndpoint = defineEndpoint;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsZ0RBQWdEO0FBQ2hELDZDQUFpRTtBQUNqRSwyQ0FBZ0U7QUFFaEUsbUNBR2tCO0FBRGhCLDhCQUFBLFVBQVUsQ0FBQTtBQUVaLDJDQU9zQjtBQUhwQixrQ0FBQSxVQUFVLENBQUE7QUFDVixzREFBQSw4QkFBOEIsQ0FBQTtBQUM5QixtREFBQSwyQkFBMkIsQ0FBQTtBQUU3Qiw2QkFLZTtBQUpiLGlDQUFBLGdCQUFnQixDQUFBO0FBRWhCLHlCQUFBLFFBQVEsQ0FBQTtBQUlHLFFBQUEsaUJBQWlCLEdBQUcsVUFBQyxNQUFjLElBQUssT0FBQSxNQUFNLENBQUMsV0FBVyxFQUFFLEVBQXBCLENBQW9CLENBQUM7QUFRMUU7SUFDRSwwQkFBcUIsT0FBdUI7UUFBdkIsWUFBTyxHQUFQLE9BQU8sQ0FBZ0I7SUFDNUMsQ0FBQztJQUNILHVCQUFDO0FBQUQsQ0FBQyxBQUhELElBR0M7QUFIWSw0Q0FBZ0I7QUFLN0I7SUFLRSxpQkFBWSxLQUFxQjtRQUMvQixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDL0MsQ0FBQztJQU5NLGlCQUFTLEdBQVMsSUFBSSxDQUFDO0lBT2hDLGNBQUM7Q0FBQSxBQVJELElBUUM7QUFScUIsMEJBQU87QUFVN0IsU0FBZ0IsT0FBTyxDQUFJLEtBQXFCO0lBQzlDO1FBQStCLG9DQUFVO1FBQ3ZDO21CQUNFLGtCQUFNLEtBQUssQ0FBQztRQUNkLENBQUM7UUFDSCx1QkFBQztJQUFELENBQUMsQUFKRCxDQUErQixPQUFPLEdBSXJDO0lBRUQsT0FBTyxnQkFBZ0IsQ0FBQztBQUMxQixDQUFDO0FBUkQsMEJBUUM7QUFFRCxTQUFnQixTQUFTLENBQUMsS0FBVTtJQUNsQyxJQUFJLENBQUMsS0FBSyxFQUFFO1FBQ1YsT0FBTyxL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
export interface Logger {
log(...args: any[]): void;
debug(...args: any[]): void;
info(...args: any[]): void;
warn(...args: any[]): void;
error(...args: any[]): void;
}
export declare class NoopLogger {
log: () => void;
debug: () => void;
info: () => void;
warn: () => void;
error: () => void;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var noop = function () { };
var NoopLogger = /** @class */ (function () {
function NoopLogger() {
this.log = noop;
this.debug = noop;
this.info = noop;
this.warn = noop;
this.error = noop;
}
return NoopLogger;
}());
exports.NoopLogger = NoopLogger;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2xvZ2dlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQVFBLElBQU0sSUFBSSxHQUFHLGNBQVEsQ0FBQyxDQUFDO0FBRXZCO0lBQUE7UUFDRSxRQUFHLEdBQUcsSUFBSSxDQUFDO1FBRVgsVUFBSyxHQUFHLElBQUksQ0FBQztRQUViLFNBQUksR0FBRyxJQUFJLENBQUM7UUFFWixTQUFJLEdBQUcsSUFBSSxDQUFDO1FBRVosVUFBSyxHQUFHLElBQUksQ0FBQztJQUNmLENBQUM7SUFBRCxpQkFBQztBQUFELENBQUMsQUFWRCxJQVVDO0FBVlksZ0NBQVUifQ==
export declare class PathBuilder<TRequestParams> {
private readonly parts;
protected constructor();
literal(path: string): PathBuilder<TRequestParams>;
param(name: keyof TRequestParams): PathBuilder<TRequestParams>;
toString(): string;
}
export declare type PathBuildingFunction<TRequestParams> = (path: PathBuilder<TRequestParams>) => PathBuilder<TRequestParams>;
export declare function createPath<TRequestParams>(build: PathBuildingFunction<TRequestParams>): string;
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var removeLeadingAndTrailingSlashes = (function (path) { return path
.replace(/^\/+/, '')
.replace(/\/+$/, ''); });
var PathBuilder = /** @class */ (function () {
// Marked as private to discourage consumers from instantiating directly.
// Use the createPath function instead
// eslint-disable-next-line @typescript-eslint/no-empty-function
function PathBuilder() {
this.parts = [];
}
PathBuilder.prototype.literal = function (path) {
if (path) {
this.parts.push(removeLeadingAndTrailingSlashes(path));
}
return this;
};
PathBuilder.prototype.param = function (name) {
if (name) {
this.parts.push(":" + name);
}
return this;
};
PathBuilder.prototype.toString = function () {
return "/" + this.parts.join('/');
};
return PathBuilder;
}());
exports.PathBuilder = PathBuilder;
function createPath(build) {
var ConstructablePathBuilder = /** @class */ (function (_super) {
__extends(ConstructablePathBuilder, _super);
function ConstructablePathBuilder() {
return _super.call(this) || this;
}
return ConstructablePathBuilder;
}(PathBuilder));
var pathBuilder = build(new ConstructablePathBuilder());
return pathBuilder.toString();
}
exports.createPath = createPath;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF0aEJ1aWxkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcGF0aEJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsSUFBTSwrQkFBK0IsR0FBRyxDQUN0QyxVQUFDLElBQVksSUFBSyxPQUFBLElBQUk7S0FDbkIsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUM7S0FDbkIsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsRUFGSixDQUVJLENBQ3ZCLENBQUM7QUFFRjtJQUdFLHlFQUF5RTtJQUN6RSxzQ0FBc0M7SUFDdEMsZ0VBQWdFO0lBQ2hFO1FBTGlCLFVBQUssR0FBYSxFQUFFLENBQUM7SUFNdEMsQ0FBQztJQUVELDZCQUFPLEdBQVAsVUFBUSxJQUFZO1FBQ2xCLElBQUksSUFBSSxFQUFFO1lBQ1IsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsK0JBQStCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztTQUN4RDtRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELDJCQUFLLEdBQUwsVUFBTSxJQUEwQjtRQUM5QixJQUFJLElBQUksRUFBRTtZQUNSLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQUksSUFBTSxDQUFDLENBQUM7U0FDN0I7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCw4QkFBUSxHQUFSO1FBQ0UsT0FBTyxNQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBRyxDQUFDO0lBQ3BDLENBQUM7SUFDSCxrQkFBQztBQUFELENBQUMsQUExQkQsSUEwQkM7QUExQlksa0NBQVc7QUE4QnhCLFNBQWdCLFVBQVUsQ0FBaUIsS0FBMkM7SUFDcEY7UUFBdUMsNENBQTJCO1FBQ2hFO21CQUNFLGlCQUFPO1FBQ1QsQ0FBQztRQUNILCtCQUFDO0lBQUQsQ0FBQyxBQUpELENBQXVDLFdBQVcsR0FJakQ7SUFDRCxJQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsSUFBSSx3QkFBd0IsRUFBRSxDQUFDLENBQUM7SUFDMUQsT0FBTyxXQUFXLENBQUMsUUFBUSxFQUFFLENBQUM7QUFDaEMsQ0FBQztBQVJELGdDQVFDIn0=
import { ParsedUrl } from './url';
export declare class UnsupportedPathPatternError extends Error {
constructor(path: string);
}
export declare class RequiredPathParametersNotFound extends Error {
constructor(parameterNames: string[]);
}
export interface PathHelperParseMatch extends ParsedUrl {
params: {
[key: string]: any;
};
}
export interface ParsedPathPattern extends ParsedUrl {
parameters: string[];
}
export interface GetUrlOptions {
params?: {
[key: string]: any;
} | undefined;
server?: string | undefined;
}
export declare class PathHelper {
readonly pathPattern: string;
static parsePathPattern(pathPattern: string): ParsedPathPattern;
private static generateParseFunction;
private static getPathPatternParameterRegExp;
private static getParameterNamesFromPathPattern;
private static checkForQueryString;
private readonly parsedPathPattern;
readonly parse: (path: string) => PathHelperParseMatch | undefined;
constructor(pathPattern: string);
url(options?: GetUrlOptions): string;
}
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
// eslint-disable-next-line max-classes-per-file
var regexp_1 = require("./regexp");
var url_1 = require("./url");
var UnsupportedPathPatternError = /** @class */ (function (_super) {
__extends(UnsupportedPathPatternError, _super);
// istanbul ignore next - typescript creates a branch for super calls
function UnsupportedPathPatternError(path) {
return _super.call(this, "Unsupported path pattern: \"" + path + "\"") || this;
}
return UnsupportedPathPatternError;
}(Error));
exports.UnsupportedPathPatternError = UnsupportedPathPatternError;
var RequiredPathParametersNotFound = /** @class */ (function (_super) {
__extends(RequiredPathParametersNotFound, _super);
// istanbul ignore next - typescript creates a branch for super calls
function RequiredPathParametersNotFound(parameterNames) {
return _super.call(this, "Required path parameters not found: " + parameterNames.join(', ')) || this;
}
return RequiredPathParametersNotFound;
}(Error));
exports.RequiredPathParametersNotFound = RequiredPathParametersNotFound;
var PathHelper = /** @class */ (function () {
function PathHelper(pathPattern) {
this.pathPattern = pathPattern;
this.parsedPathPattern = PathHelper.parsePathPattern(this.pathPattern);
this.parse = PathHelper.generateParseFunction(this.parsedPathPattern);
PathHelper.checkForQueryString(pathPattern);
}
PathHelper.parsePathPattern = function (pathPattern) {
var parsedUrl = url_1.parseUrl(pathPattern);
var parameters = this.getParameterNamesFromPathPattern(parsedUrl.path);
return __assign(__assign({}, parsedUrl), { parameters: parameters });
};
PathHelper.generateParseFunction = function (parsedPathPattern) {
var parameterNames = [];
var getParameterPlaceholder = function (index) { return "-----" + index + "-----"; };
var pathParametersRegExpPattern = parsedPathPattern.path.replace(this.getPathPatternParameterRegExp(), function (_, key) {
parameterNames.push(key);
return getParameterPlaceholder(parameterNames.length - 1);
});
pathParametersRegExpPattern = regexp_1.escapeRegExp(pathParametersRegExpPattern);
for (var parameterIndex = 0; parameterIndex < parameterNames.length; parameterIndex++) {
pathParametersRegExpPattern = pathParametersRegExpPattern
.replace(regexp_1.escapeRegExp(getParameterPlaceholder(parameterIndex)), '([^&?/\\\\]+)');
}
pathParametersRegExpPattern = "^" + pathParametersRegExpPattern + "$";
var pathParametersRegEx = new RegExp(pathParametersRegExpPattern, 'i');
return function (path) {
var parsedUrl = url_1.parseUrl(path);
// Test url and extract path parameters
pathParametersRegEx.lastIndex = -1;
// const parameterValues: string[] = [];
var match = pathParametersRegEx.exec(parsedUrl.path);
if (!match) {
return undefined;
}
var result = __assign(__assign({}, parsedUrl), { params: {} });
// Add path parameters to result
if (match.length > 1) {
for (var parameterIndex = 1; parameterIndex < match.length; parameterIndex++) {
var parameterName = parameterNames[parameterIndex - 1];
var parameterValue = match[parameterIndex];
result.params[parameterName] = parameterValue;
}
}
// Extract and add query string parameters to result
var queryStringParameters = url_1.parseQueryString(parsedUrl.postPath);
Object.getOwnPropertyNames(queryStringParameters).forEach(function (parameterName) {
var parameterValue = queryStringParameters[parameterName];
result.params[parameterName] = parameterValue;
});
return result;
};
};
// private static getPathAndQueryStringSplitterRegExp = () => /^([^?\n] +)(\?.*)?$/i;
PathHelper.getParameterNamesFromPathPattern = function (pathPattern) {
var parameterNames = [];
var pathParameterRegExp = PathHelper.getPathPatternParameterRegExp();
var match;
do {
match = pathParameterRegExp.exec(pathPattern);
if (match) {
parameterNames.push(match[1]);
}
} while (match);
return parameterNames;
};
PathHelper.checkForQueryString = function (path) {
if (path.indexOf('?') > -1) {
throw new UnsupportedPathPatternError(path);
}
};
PathHelper.prototype.url = function (options) {
var _this = this;
var params = (options && options.params) || {};
var server = (options && options.server) || '';
var providedParameterNames = Object.getOwnPropertyNames(params);
var missingParameterNames = [];
var queryStringParameterNames = [];
this.parsedPathPattern.parameters.forEach(function (requiredParameterName) {
var isRequiredParameterProvided = providedParameterNames.some(function (parameterName) { return parameterName === requiredParameterName; });
if (!isRequiredParameterProvided) {
missingParameterNames.push(requiredParameterName);
}
});
providedParameterNames.forEach(function (providedParameterName) {
var isProvidedParameterRequired = _this.parsedPathPattern.parameters.some(function (parameterName) { return parameterName === providedParameterName; });
if (!isProvidedParameterRequired) {
queryStringParameterNames.push(providedParameterName);
}
});
if (missingParameterNames.length) {
throw new RequiredPathParametersNotFound(missingParameterNames);
}
var url = this.pathPattern.replace(/:([^\s/?\n\d][^\s/?\n]*)/gim, function (_, key) { return "" + params[key]; });
var queryString = queryStringParameterNames
.map(function (parameterName) { return encodeURIComponent(parameterName) + "=" + encodeURIComponent(params[parameterName]); })
.join('&');
if (queryString) {
url = url_1.addQueryStringToUrl(url, queryString);
}
if (server) {
url = server + url;
}
return url;
};
PathHelper.getPathPatternParameterRegExp = function () { return /:([^\s/?\n\d][^\s/?\n]*)/gim; };
return PathHelper;
}());
exports.PathHelper = PathHelper;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF0aEhlbHBlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9wYXRoSGVscGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsZ0RBQWdEO0FBQ2hELG1DQUF3QztBQUN4Qyw2QkFFZTtBQUVmO0lBQWlELCtDQUFLO0lBQ3BELHFFQUFxRTtJQUNyRSxxQ0FBWSxJQUFZO2VBQ3RCLGtCQUFNLGlDQUE4QixJQUFJLE9BQUcsQ0FBQztJQUM5QyxDQUFDO0lBQ0gsa0NBQUM7QUFBRCxDQUFDLEFBTEQsQ0FBaUQsS0FBSyxHQUtyRDtBQUxZLGtFQUEyQjtBQU94QztJQUFvRCxrREFBSztJQUN2RCxxRUFBcUU7SUFDckUsd0NBQVksY0FBd0I7ZUFDbEMsa0JBQU0seUNBQXVDLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFHLENBQUM7SUFDM0UsQ0FBQztJQUNILHFDQUFDO0FBQUQsQ0FBQyxBQUxELENBQW9ELEtBQUssR0FLeEQ7QUFMWSx3RUFBOEI7QUFvQjNDO0lBK0ZFLG9CQUFxQixXQUFtQjtRQUFuQixnQkFBVyxHQUFYLFdBQVcsQ0FBUTtRQUp2QixzQkFBaUIsR0FBRyxVQUFVLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRTFFLFVBQUssR0FBRyxVQUFVLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFHeEUsVUFBVSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQzlDLENBQUM7SUFoR00sMkJBQWdCLEdBQXZCLFVBQXdCLFdBQW1CO1FBQ3pDLElBQU0sU0FBUyxHQUFHLGNBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUV4QyxJQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsZ0NBQWdDLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRXpFLDZCQUNLLFNBQVMsS0FDWixVQUFVLFlB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
export declare function escapeRegExp(input: string): string;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function escapeRegExp(input) {
return input.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
}
exports.escapeRegExp = escapeRegExp;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnZXhwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3JlZ2V4cC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLFNBQWdCLFlBQVksQ0FBQyxLQUFhO0lBQ3hDLE9BQU8sS0FBSyxDQUFDLE9BQU8sQ0FBQyx1QkFBdUIsRUFBRSxNQUFNLENBQUMsQ0FBQztBQUN4RCxDQUFDO0FBRkQsb0NBRUMifQ==
export interface ParsedUrl {
prePath: string;
path: string;
postPath: string;
}
export declare function parseUrl(url: string): ParsedUrl;
export interface QueryParameterValues {
[key: string]: string | string[];
}
export declare function parseQueryString(queryString: string): QueryParameterValues;
export declare function addQueryStringToUrl(url: string, queryString: string): string;
-118
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function parseUrl(url) {
var index = 0;
var pathStartIndex;
var pathLength;
while (index < url.length && pathLength === undefined) {
if (pathStartIndex === undefined) {
if (url[index] === '/') {
if (url[index + 1] === '/') {
index += 2;
}
else {
pathStartIndex = index;
index++;
}
}
else {
index++;
}
}
else if (url[index] === '#' || url[index] === '?') {
pathLength = index - pathStartIndex;
}
else {
index++;
}
}
if (pathStartIndex !== undefined && pathLength === undefined) {
pathLength = url.length - pathStartIndex;
}
var prePath = url.substring(0, pathStartIndex === undefined ? url.length + 1 : pathStartIndex);
var path = pathStartIndex === undefined ? '' : url.substr(pathStartIndex, pathLength);
var postPath = ((pathStartIndex === undefined || pathLength === undefined)
? ''
: url.substr(pathStartIndex + pathLength));
return {
prePath: prePath,
path: path,
postPath: postPath,
};
}
exports.parseUrl = parseUrl;
function parseQueryString(queryString) {
var result = {};
var Position;
(function (Position) {
Position[Position["key"] = 0] = "key";
Position[Position["value"] = 1] = "value";
})(Position || (Position = {}));
var trimmedQueryString = queryString.trim();
if (trimmedQueryString[0] !== '?') {
return result;
}
var position = Position.key;
var parameterName = '';
var parameterValue = '';
var addParameter = function () {
var existingValue = result[parameterName];
if (existingValue === undefined) {
result[parameterName] = parameterValue;
}
else if (typeof existingValue === 'string') {
result[parameterName] = [existingValue, parameterValue];
}
else {
existingValue.push(parameterValue);
}
parameterName = '';
parameterValue = '';
};
var index = 1;
while (index < trimmedQueryString.length) {
var char = trimmedQueryString[index];
if (char === '#') {
break;
}
if (position === Position.key) {
if (char === '=') {
position = Position.value;
}
else if (char === '&') {
addParameter();
}
else {
parameterName += char;
}
}
else if (char === '&') {
addParameter();
position = Position.key;
}
else {
parameterValue += char;
}
index++;
}
if (parameterName) {
addParameter();
}
return result;
}
exports.parseQueryString = parseQueryString;
function addQueryStringToUrl(url, queryString) {
var index = url.indexOf('?');
var endsWithQuestionMark = index === url.length - 1;
var separator = '';
if (index === -1) {
separator = '?';
}
else if (!endsWithQuestionMark) {
separator = '&';
}
url = url + separator + queryString;
return url;
}
exports.addQueryStringToUrl = addQueryStringToUrl;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXJsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3VybC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQU1BLFNBQWdCLFFBQVEsQ0FBQyxHQUFXO0lBQ2xDLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQztJQUNkLElBQUksY0FBa0MsQ0FBQztJQUN2QyxJQUFJLFVBQThCLENBQUM7SUFFbkMsT0FBTyxLQUFLLEdBQUcsR0FBRyxDQUFDLE1BQU0sSUFBSSxVQUFVLEtBQUssU0FBUyxFQUFFO1FBQ3JELElBQUksY0FBYyxLQUFLLFNBQVMsRUFBRTtZQUNoQyxJQUFJLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLEVBQUU7Z0JBQ3RCLElBQUksR0FBRyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsS0FBSyxHQUFHLEVBQUU7b0JBQzFCLEtBQUssSUFBSSxDQUFDLENBQUM7aUJBQ1o7cUJBQU07b0JBQ0wsY0FBYyxHQUFHLEtBQUssQ0FBQztvQkFDdkIsS0FBSyxFQUFFLENBQUM7aUJBQ1Q7YUFDRjtpQkFBTTtnQkFDTCxLQUFLLEVBQUUsQ0FBQzthQUNUO1NBQ0Y7YUFBTSxJQUFJLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLElBQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsRUFBRTtZQUNuRCxVQUFVLEdBQUcsS0FBSyxHQUFHLGNBQWMsQ0FBQztTQUNyQzthQUFNO1lBQ0wsS0FBSyxFQUFFLENBQUM7U0FDVDtLQUNGO0lBRUQsSUFBSSxjQUFjLEtBQUssU0FBUyxJQUFJLFVBQVUsS0FBSyxTQUFTLEVBQUU7UUFDNUQsVUFBVSxHQUFHLEdBQUcsQ0FBQyxNQUFNLEdBQUcsY0FBYyxDQUFDO0tBQzFDO0lBRUQsSUFBTSxPQUFPLEdBQUcsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsY0FBYyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FB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