mirror of
				https://github.com/186526/handlers.js
				synced 2024-10-13 00:29:43 +00:00 
			
		
		
		
	Implements most platform-independent features
This commit is contained in:
		
							
								
								
									
										3
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| { | ||||
|     "compile-hero.disable-compile-files-on-did-save-code": false | ||||
| } | ||||
							
								
								
									
										12
									
								
								index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| import { rootRouter } from "./src/router"; | ||||
|  | ||||
| export { handler } from "./src/handler"; | ||||
| export { route } from "./src/route"; | ||||
| export { router } from "./src/router"; | ||||
| export { method } from "./src/interface/method"; | ||||
| export { response } from "./src/interface/response"; | ||||
| export { request } from "./src/interface/request"; | ||||
| export { ChainInterrupted } from "./src/interface"; | ||||
|  | ||||
| export { rootRouter }; | ||||
| export default rootRouter; | ||||
							
								
								
									
										23
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | ||||
| { | ||||
|   "dependencies": { | ||||
|     "path-to-regexp": "^6.2.1" | ||||
|   }, | ||||
|   "name": "handlers.js", | ||||
|   "version": "0.0.1", | ||||
|   "main": "index.ts", | ||||
|   "author": "186526 <i@186526.xyz>", | ||||
|   "license": "MIT", | ||||
|   "repository": { | ||||
|     "type": "git", | ||||
|     "url": "https://github.com/186526/handlers.js" | ||||
|   }, | ||||
|   "keywords": [ | ||||
|     "web framework", | ||||
|     "lightweight", | ||||
|     "cross-platform", | ||||
|     "unified" | ||||
|   ], | ||||
|   "devDependencies": { | ||||
|     "@types/node": "^18.0.0" | ||||
|   } | ||||
| } | ||||
							
								
								
									
										42
									
								
								src/handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/handler.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | ||||
| import { method, request, responder, response } from "./interface"; | ||||
|  | ||||
| export class handler<RequestCustomType, ResponseCustomType> { | ||||
| 	public responders: responder<RequestCustomType, ResponseCustomType>[]; | ||||
| 	public method: method; | ||||
|  | ||||
| 	constructor( | ||||
| 		method: method, | ||||
| 		responders: responder<RequestCustomType, ResponseCustomType>[] | ||||
| 	) { | ||||
| 		this.responders = responders; | ||||
| 		this.method = method; | ||||
| 	} | ||||
|  | ||||
| 	add(responder: responder<RequestCustomType, ResponseCustomType>) { | ||||
| 		this.responders.push(responder); | ||||
| 	} | ||||
|  | ||||
| 	async respond( | ||||
| 		request: request<RequestCustomType>, | ||||
| 		responseMessage: response<ResponseCustomType> = new response<ResponseCustomType>( | ||||
| 			"" | ||||
| 		) | ||||
| 	): Promise<response<ResponseCustomType> | void> { | ||||
| 		switch (this.responders.length) { | ||||
| 			case 0: | ||||
| 				Promise.reject("No responders found in this handler."); | ||||
| 				break; | ||||
| 			case 1: | ||||
| 				return this.responders[0](request, responseMessage); | ||||
| 			default: | ||||
| 				for (let responder of this.responders) { | ||||
| 					let thisResponse = await responder(request, responseMessage); | ||||
| 					if (thisResponse instanceof response) { | ||||
| 						responseMessage = thisResponse; | ||||
| 					} | ||||
| 				} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| export default handler; | ||||
							
								
								
									
										26
									
								
								src/interface/headers.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/interface/headers.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| import * as lib from "../lib"; | ||||
| export class headers { | ||||
| 	public headers: { [key: string]: string } = {}; | ||||
| 	constructor(headers: { [key: string]: string }) { | ||||
| 		this.headers = {}; | ||||
| 		Object.keys(this.headers).forEach((key) => { | ||||
| 			this.headers[lib.firstUpperCase(key)] = headers[key]; | ||||
| 		}); | ||||
| 	} | ||||
| 	delete(key: string) { | ||||
| 		delete this.headers[lib.firstUpperCase(key)]; | ||||
| 	} | ||||
| 	get(key: string): string | undefined { | ||||
| 		return this.headers[lib.firstUpperCase(key)]; | ||||
| 	} | ||||
| 	has(key: string): boolean { | ||||
| 		return this.headers.hasOwnProperty(lib.firstUpperCase(key)); | ||||
| 	} | ||||
| 	set(key: string, value: string) { | ||||
| 		this.headers[lib.firstUpperCase(key)] = value; | ||||
| 	} | ||||
| 	toObject() { | ||||
| 		return this.headers; | ||||
| 	} | ||||
| } | ||||
| export default headers; | ||||
							
								
								
									
										7
									
								
								src/interface/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/interface/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| export { request } from "./request"; | ||||
| export { response } from "./response"; | ||||
| export { method } from "./method"; | ||||
| export { headers } from "./headers"; | ||||
| export { responder } from "./responder"; | ||||
| export const ChainInterrupted = new Error("ChainInterrupted"); | ||||
| export type path = string | RegExp; | ||||
							
								
								
									
										58
									
								
								src/interface/method.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/interface/method.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,58 @@ | ||||
| export enum method { | ||||
| 	/** | ||||
| 	 * The `CONNECT` method establishes a tunnel to the server identified by the | ||||
| 	 * target resource. | ||||
| 	 */ | ||||
| 	CONNECT = "CONNECT", | ||||
|  | ||||
| 	/** | ||||
| 	 * The `DELETE` method deletes the specified resource. | ||||
| 	 */ | ||||
| 	DELETE = "DELETE", | ||||
|  | ||||
| 	/** | ||||
| 	 * The `GET` method requests a representation of the specified resource. | ||||
| 	 * Requests using GET should only retrieve data. | ||||
| 	 */ | ||||
| 	GET = "GET", | ||||
|  | ||||
| 	/** | ||||
| 	 * The `HEAD` method asks for a response identical to that of a GET request, | ||||
| 	 * but without the response body. | ||||
| 	 */ | ||||
| 	HEAD = "HEAD", | ||||
|  | ||||
| 	/** | ||||
| 	 * The `OPTIONS` method is used to describe the communication options for the | ||||
| 	 * target resource. | ||||
| 	 */ | ||||
| 	OPTIONS = "OPTIONS", | ||||
|  | ||||
| 	/** | ||||
| 	 * The PATCH method is used to apply partial modifications to a resource. | ||||
| 	 */ | ||||
| 	PATCH = "PATCH", | ||||
|  | ||||
| 	/** | ||||
| 	 * The `POST` method is used to submit an entity to the specified resource, | ||||
| 	 * often causing a change in state or side effects on the server. | ||||
| 	 */ | ||||
| 	POST = "POST", | ||||
|  | ||||
| 	/** | ||||
| 	 * The `PUT` method replaces all current representations of the target | ||||
| 	 * resource with the request payload. | ||||
| 	 */ | ||||
| 	PUT = "PUT", | ||||
|  | ||||
| 	/** | ||||
| 	 * The `TRACE` method performs a message loop-back test along the path to the | ||||
| 	 * target resource. | ||||
| 	 */ | ||||
| 	TRACE = "TRACE", | ||||
| 	/** | ||||
| 	 * The `ANY` method will match any method. | ||||
| 	 */ | ||||
| 	ANY = "ANY", | ||||
| } | ||||
| export default method; | ||||
							
								
								
									
										31
									
								
								src/interface/request.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/interface/request.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | ||||
| import method from "./method"; | ||||
| import headers from "./headers"; | ||||
| export class request<RequestCustomType> { | ||||
| 	public readonly method: method; | ||||
| 	public readonly url: URL; | ||||
| 	public originURL?: URL; | ||||
| 	public readonly headers: headers; | ||||
| 	public readonly body: any; | ||||
| 	public readonly query: URLSearchParams; | ||||
| 	public params: { [key: string]: string | undefined }; | ||||
| 	public custom: RequestCustomType; | ||||
| 	public constructor( | ||||
| 		method: method, | ||||
| 		url: URL, | ||||
| 		headers: headers, | ||||
| 		body: any, | ||||
| 		params: { [key: string]: string } | ||||
| 	) { | ||||
| 		this.method = method; | ||||
| 		this.url = url; | ||||
| 		this.headers = headers; | ||||
| 		this.body = body; | ||||
| 		this.query = new URLSearchParams(url.search); | ||||
| 		this.params = params; | ||||
| 	} | ||||
| 	public extends(custom: RequestCustomType): request<RequestCustomType> { | ||||
| 		this.custom = custom; | ||||
| 		return this; | ||||
| 	} | ||||
| } | ||||
| export default request; | ||||
							
								
								
									
										8
									
								
								src/interface/responder.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/interface/responder.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | ||||
| import { request, response } from "./index"; | ||||
| export interface responder<RequestCustomType, ResponseCustomType> { | ||||
| 	( | ||||
| 		request: request<RequestCustomType>, | ||||
| 		reponse?: response<ResponseCustomType> | ||||
| 	): Promise<response<ResponseCustomType>> | Promise<void> | void; | ||||
| } | ||||
| export default responder; | ||||
							
								
								
									
										35
									
								
								src/interface/response.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/interface/response.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | ||||
| import headers from "./headers"; | ||||
| import packageJSON from "../../package.json"; | ||||
| import { platform, version } from "../lib"; | ||||
|  | ||||
| export class defaultHeaders extends headers { | ||||
| 	constructor(headers: { [key: string]: string } = {}) { | ||||
| 		super(headers); | ||||
| 		if (!this.has("Content-Type")) | ||||
| 			this.set("Content-Type", "plain/text; charset=utf-8"); | ||||
| 		this.set( | ||||
| 			"Server", | ||||
| 			`Handler.JS/${packageJSON.version} ${platform}/${version}` | ||||
| 		); | ||||
| 	} | ||||
| } | ||||
| export class response<ResponseCustomType> { | ||||
| 	public status: number; | ||||
| 	public headers: headers; | ||||
| 	public body: any; | ||||
| 	public custom: ResponseCustomType; | ||||
| 	public constructor( | ||||
| 		body: any, | ||||
| 		status: number = 200, | ||||
| 		headers: headers = new defaultHeaders() | ||||
| 	) { | ||||
| 		this.status = status; | ||||
| 		this.headers = headers; | ||||
| 		this.body = body; | ||||
| 	} | ||||
| 	public extends(custom: ResponseCustomType): response<ResponseCustomType> { | ||||
| 		this.custom = custom; | ||||
| 		return this; | ||||
| 	} | ||||
| } | ||||
| export default response; | ||||
							
								
								
									
										16
									
								
								src/lib.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/lib.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | ||||
| export const firstUpperCase = ([first, ...rest]: string) => | ||||
| 	first?.toUpperCase() + rest.join(""); | ||||
| export const platform = (() => { | ||||
| 	if (typeof process != "undefined") { | ||||
| 		return "Node.js"; | ||||
| 	} | ||||
| 	return "UNKNOWN"; | ||||
| })(); | ||||
| export const version = (() => { | ||||
| 	switch (platform) { | ||||
| 		case "Node.js": | ||||
| 			return process.version; | ||||
| 		default: | ||||
| 			return "UNKNOWN"; | ||||
| 	} | ||||
| })(); | ||||
							
								
								
									
										7
									
								
								src/platform/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/platform/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| import { request, response } from "../interface"; | ||||
|  | ||||
| export interface PlatformAdapater<T = any, K = any> { | ||||
| 	listen(port: number): void; | ||||
| 	handleRequest(request: any): request<T>; | ||||
| 	handleResponse(response: response<K>, NativeResponse?: any): any; | ||||
| } | ||||
							
								
								
									
										27
									
								
								src/platform/node.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/platform/node.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| import { PlatformAdapater } from "."; | ||||
| import { request, response } from "../interface"; | ||||
| import router from "../router"; | ||||
| import http from "http"; | ||||
|  | ||||
| export class NodePlatformAdapter<T = any, K = any> implements PlatformAdapater { | ||||
| 	constructor(Router: ) | ||||
| 	listen(port: number): void { | ||||
| 		const server = http.createServer(); | ||||
| 		server.on( | ||||
| 			"request", | ||||
| 			(req: http.IncomingMessage, res: http.ServerResponse) => { | ||||
| 				const request = this.handleRequest(req); | ||||
|  | ||||
| 			} | ||||
| 		); | ||||
| 		server.listen(port); | ||||
| 	} | ||||
|  | ||||
| 	handleRequest(request: http.IncomingMessage): request<T> { | ||||
| 		throw new Error("Method not implemented."); | ||||
| 	} | ||||
|  | ||||
| 	handleResponse(response: response<K>, NativeResponse: http.ServerResponse) { | ||||
| 		throw new Error("Method not implemented."); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										64
									
								
								src/route.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/route.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,64 @@ | ||||
| import { path } from "./interface"; | ||||
| import handler from "./handler"; | ||||
| import { pathToRegexp } from "path-to-regexp"; | ||||
|  | ||||
| interface matchedStatus { | ||||
| 	matched: boolean; | ||||
| 	attributes: { | ||||
| 		name: string; | ||||
| 		value: string | undefined; | ||||
| 	}[]; | ||||
| } | ||||
|  | ||||
| export class route { | ||||
| 	public paths: path[]; | ||||
| 	public handler: handler<any, any>; | ||||
|  | ||||
| 	constructor(paths: path[], handler: handler<any, any>) { | ||||
| 		this.paths = paths; | ||||
| 		this.handler = handler; | ||||
| 	} | ||||
| 	async exec(path: string): Promise<matchedStatus> { | ||||
| 		let Answer = await Promise.all<Promise<matchedStatus>>( | ||||
| 			this.paths.map(async (it) => { | ||||
| 				const keys: { | ||||
| 					name: string; | ||||
| 					prefix: string; | ||||
| 					suffix: string; | ||||
| 					pattern: string; | ||||
| 					modifier: string; | ||||
| 				}[] = []; | ||||
| 				const regExp = pathToRegexp(it, keys); | ||||
| 				const answer = regExp.exec(path); | ||||
| 				if (answer === null) | ||||
| 					return { | ||||
| 						matched: false, | ||||
| 						attributes: [], | ||||
| 					}; | ||||
|  | ||||
| 				let attributes: matchedStatus["attributes"] = []; | ||||
|  | ||||
| 				keys.forEach((key, index) => { | ||||
| 					attributes.push({ | ||||
| 						name: key.name, | ||||
| 						value: answer[index + 1], | ||||
| 					}); | ||||
| 				}); | ||||
|  | ||||
| 				return { | ||||
| 					matched: true, | ||||
| 					attributes: attributes, | ||||
| 				}; | ||||
| 			}) | ||||
| 		); | ||||
| 		Answer = Answer.filter((it) => it.matched); | ||||
| 		if (Answer.length === 0) | ||||
| 			return { | ||||
| 				matched: false, | ||||
| 				attributes: [], | ||||
| 			}; | ||||
| 		else return Answer[0]; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| export default route; | ||||
							
								
								
									
										131
									
								
								src/router.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								src/router.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,131 @@ | ||||
| import handler from "./handler"; | ||||
| import { | ||||
| 	path, | ||||
| 	method, | ||||
| 	response, | ||||
| 	request, | ||||
| 	ChainInterrupted, | ||||
| } from "./interface/index"; | ||||
| import { defaultHeaders } from "./interface/response"; | ||||
| import route from "./route"; | ||||
|  | ||||
| export class router<K = any, V = any> { | ||||
| 	public routes: route[]; | ||||
|  | ||||
| 	constructor(routes: route[] = []) { | ||||
| 		this.routes = routes; | ||||
| 	} | ||||
|  | ||||
| 	add(route: route) { | ||||
| 		this.routes.push(route); | ||||
| 		return this; | ||||
| 	} | ||||
|  | ||||
| 	binding(path: path, handler: handler<K, V>) { | ||||
| 		this.add(new route([path], handler)); | ||||
| 		return this; | ||||
| 	} | ||||
|  | ||||
| 	create( | ||||
| 		method: method, | ||||
| 		responder: ( | ||||
| 			request: request<K> | ||||
| 		) => | ||||
| 			| Promise<response<V>> | ||||
| 			| Promise<string> | ||||
| 			| Promise<object> | ||||
| 			| Promise<number> | ||||
| 			| Promise<void> | ||||
| 	) { | ||||
| 		return new handler<K, V>(method, [ | ||||
| 			async (request: request<K>) => { | ||||
| 				const answer = await responder(request); | ||||
| 				if (answer instanceof response) { | ||||
| 					return answer; | ||||
| 				} else if (answer instanceof String) { | ||||
| 					return new response(answer); | ||||
| 				} else if (answer instanceof Number) { | ||||
| 					return new response(answer.toString()); | ||||
| 				} else if (answer instanceof Object) { | ||||
| 					return new response( | ||||
| 						JSON.stringify(answer), | ||||
| 						200, | ||||
| 						new defaultHeaders({ | ||||
| 							"Content-Type": "application/json; charset=utf-8", | ||||
| 						}) | ||||
| 					); | ||||
| 				} else { | ||||
| 					return new response("", 204); | ||||
| 				} | ||||
| 			}, | ||||
| 		]); | ||||
| 	} | ||||
|  | ||||
| 	use(routers: router[], path: path): void { | ||||
| 		routers.forEach((router) => { | ||||
| 			this.binding(path, router.toHandler(path)); | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	route(path: path): router { | ||||
| 		const Router = new router([]); | ||||
| 		this.use([Router], path); | ||||
| 		return Router; | ||||
| 	} | ||||
|  | ||||
| 	async respond(request: request<K>, basePath: path): Promise<response<V>> { | ||||
| 		request.originURL = request.url; | ||||
| 		request.url.pathname = request.url.pathname.replace(basePath, ""); | ||||
|  | ||||
| 		let responseMessage: response<V> = new response(""); | ||||
|  | ||||
| 		for (let route of this.routes) { | ||||
| 			if ( | ||||
| 				route.handler.method != request.method || | ||||
| 				route.handler.method != method.ANY | ||||
| 			) { | ||||
| 				continue; | ||||
| 			} | ||||
|  | ||||
| 			const isMatched = await route.exec(request.url.pathname); | ||||
|  | ||||
| 			if (!isMatched.matched) { | ||||
| 				continue; | ||||
| 			} | ||||
|  | ||||
| 			isMatched.attributes.forEach((e) => { | ||||
| 				request.params[e.name] = e.value; | ||||
| 			}); | ||||
|  | ||||
| 			let thisResponse = await route.handler.respond(request, responseMessage); | ||||
| 			if (thisResponse instanceof response) { | ||||
| 				responseMessage = thisResponse; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		return responseMessage; | ||||
| 	} | ||||
|  | ||||
| 	toHandler(basePath: path): handler<K, V> { | ||||
| 		return this.create(method.ANY, (request: request<K>) => { | ||||
| 			return this.respond(request, basePath); | ||||
| 		}); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| export default router; | ||||
|  | ||||
| export class rootRouter<K = any, V = any> extends router<K, V> { | ||||
| 	private readonly originRespond = this.respond; | ||||
| 	async respond(request: request<K>, basePath: path): Promise<response<V>> { | ||||
| 		try { | ||||
| 			return this.originRespond(request, basePath); | ||||
| 		} catch (e) { | ||||
| 			if (e === ChainInterrupted) { | ||||
| 				return e.response; | ||||
| 			} else { | ||||
| 				throw e; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										43
									
								
								test/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								test/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | ||||
| import * as handlerJS from "../"; | ||||
|  | ||||
| interface requestType { | ||||
| 	hood: boolean; | ||||
| 	id: number; | ||||
| } | ||||
|  | ||||
| const App = new handlerJS.rootRouter<requestType, any>(); | ||||
|  | ||||
| App.binding( | ||||
| 	"/", | ||||
| 	App.create(handlerJS.method["ANY"], async (request) => { | ||||
| 		Promise.resolve("Hello World!"); | ||||
| 		throw handlerJS.ChainInterrupted; | ||||
| 	}) | ||||
| ); | ||||
|  | ||||
| App.binding( | ||||
| 	"/*", | ||||
| 	App.create(handlerJS.method["ANY"], async (request) => "Fuck World!") | ||||
| ); | ||||
|  | ||||
| App.route("/v1") | ||||
| 	.add( | ||||
| 		new handlerJS.route( | ||||
| 			["/echo", "/echo/*"], | ||||
| 			new handlerJS.handler(handlerJS.method["GET"], [ | ||||
| 				async (request, response) => { | ||||
| 					response = response ?? new handlerJS.response(""); | ||||
| 					response?.headers.set("Hello", "World"); | ||||
| 					response.body = "echo"; | ||||
| 					return response; | ||||
| 				}, | ||||
| 			]) | ||||
| 		) | ||||
| 	) | ||||
| 	.binding( | ||||
| 		"/:a/echo", | ||||
| 		App.create( | ||||
| 			handlerJS.method["GET"], | ||||
| 			async (request) => `echo with ${request.params.a}` | ||||
| 		) | ||||
| 	); | ||||
							
								
								
									
										38
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | ||||
| { | ||||
|   "compilerOptions": { | ||||
|     "target": "es2017", | ||||
|     "module": "commonjs", | ||||
|     "lib": [ | ||||
|       "es6", | ||||
|       "es2017", | ||||
|       "esnext", | ||||
|       "webworker" | ||||
|     ], | ||||
|     "skipLibCheck": true, | ||||
|     "sourceMap": true, | ||||
|     "outDir": "./dist", | ||||
|     "moduleResolution": "node", | ||||
|     "removeComments": true, | ||||
|     "noImplicitAny": true, | ||||
|     "strictNullChecks": true, | ||||
|     "strictFunctionTypes": true, | ||||
|     "noImplicitThis": true, | ||||
|     "noUnusedLocals": true, | ||||
|     "noUnusedParameters": true, | ||||
|     "noImplicitReturns": true, | ||||
|     "noFallthroughCasesInSwitch": true, | ||||
|     "allowSyntheticDefaultImports": true, | ||||
|     "esModuleInterop": true, | ||||
|     "emitDecoratorMetadata": true, | ||||
|     "experimentalDecorators": true, | ||||
|     "resolveJsonModule": true, | ||||
|     "baseUrl": "." | ||||
|   }, | ||||
|   "exclude": [ | ||||
|     "node_modules" | ||||
|   ], | ||||
|   "include": [ | ||||
|     "index.ts", | ||||
|     "src/**/*.ts" | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										13
									
								
								yarn.lock
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								yarn.lock
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | ||||
| # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. | ||||
| # yarn lockfile v1 | ||||
|  | ||||
|  | ||||
| "@types/node@^18.0.0": | ||||
|   version "18.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.0.tgz#67c7b724e1bcdd7a8821ce0d5ee184d3b4dd525a" | ||||
|   integrity sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA== | ||||
|  | ||||
| path-to-regexp@^6.2.1: | ||||
|   version "6.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.2.1.tgz#d54934d6798eb9e5ef14e7af7962c945906918e5" | ||||
|   integrity sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw== | ||||
		Reference in New Issue
	
	Block a user