UNPKG

easy-api.ts

Version:

A powerful library to create your own API with ease.

1 lines 7.41 kB
Object.defineProperty(exports,"__esModule",{value:!0}),exports.API=void 0;let tslib_1=require("tslib"),FunctionManager_1=require("../managers/FunctionManager"),RouteCompilationManager_1=require("../managers/RouteCompilationManager"),DatabaseManager_1=require("../managers/DatabaseManager"),RouteDataManager_1=require("../managers/RouteDataManager"),APIFunction_1=require("./APIFunction"),main_1=require("../../main"),tiny_typed_emitter_1=require("tiny-typed-emitter"),package_json_1=require("../../../package.json"),Interpreter_1=require("../core/Interpreter"),Logger_1=require("../core/Logger"),types_1=require("util/types"),Addon_1=require("./Addon"),F=tslib_1.__importStar(require("fastify")),colors_1=tslib_1.__importDefault(require("colors")),path_1=require("path"),fs=tslib_1.__importStar(require("fs")),yaml_1=tslib_1.__importDefault(require("yaml")),Compiler_1=require("../core/Compiler");class API extends tiny_typed_emitter_1.TypedEmitter{options;uptime=-1;app;functions=new FunctionManager_1.FunctionManager;interpreter=new Interpreter_1.Interpreter;compilationManager=new RouteCompilationManager_1.RouteCompilationManager;db;#somethingIsUsingReverse=!1;constructor(e){if(super(),this.options=e,this.app=F.fastify(e),this.options.reverse=e.reverse??!1,this.db=new DatabaseManager_1.NativeDatabase(e?.databaseOptions?.customOptions),"function"==typeof e?.databaseOptions?.overrideDatabaseWith&&(this.db=new(e?.databaseOptions?.overrideDatabaseWith())(e?.databaseOptions?.customOptions)),e.addons?.length)for(var t of e.addons)this.#validateAddon(t)}addFunction(...e){for(var t of e){var r;t instanceof APIFunction_1.APIFunction?(t.init(),this.functions.add(t.name,t)):main_1.Util.isFunctionLike(t)?this.functions.add(t.name,t):APIFunction_1.APIFunction.prototype.isPrototypeOf(t.prototype)?((r=new t).init(),this.functions.add(r.name,r)):"function"!=typeof t&&!(0,types_1.isAsyncFunction)(t)||this.functions.add(t.name,{name:t.name,description:"Native function.",run:t,compile:!0,usage:"",parameters:[],returns:APIFunction_1.ParamType.Unknown,init(){}})}}route(o){let a=o.reverse??this.options.reverse??!1,e;a&&(this.#somethingIsUsingReverse=!0),void 0!==o.extraData&&RouteDataManager_1.RouteDataManager.addData(o.url,o.extraData),main_1.Util.areBracketsBalanced(o.code)?(console.log(`${colors_1.default.green((new Date).toLocaleString())} | ${colors_1.default.green("Endpoint loaded")}: `+colors_1.default.bold(o.url+" => "+o.method.toUpperCase())),e=(new Compiler_1.Compiler).remap(o.code,this.rs,!0),this.compilationManager.addRoute(o.url,e),this.app.route({...o,handler:async(e,t)=>{try{var r=new main_1.Data(a,this.functions.entries(),{server:this,request:e,reply:t,stream:null}).setStart(performance.now()),n=await this.interpreter.run(this.compilationManager.getRoute(o.url),{comments:o.comments,data:r,reverse:a});if(this.emit("request",n),n.stream)return n.stream}catch(e){throw console.log(e),e}}})):Logger_1.Logger.danger(`${colors_1.default.bold("Brackets are not balanced at route")}: "${o.url}"`)}event(n){let o=n.reverse??this.options.reverse??!1,a=n.comments??!1,e;o&&(this.#somethingIsUsingReverse=!0),main_1.Util.areBracketsBalanced(n.code)?(console.log(`${colors_1.default.green((new Date).toLocaleString())} | ${colors_1.default.green("Event loaded")}: `+colors_1.default.bold(n.name)),e=(new Compiler_1.Compiler).remap(n.code,this.rs,!0),this.compilationManager.addEvent(n.name,e),this.on(n.name,async(...e)=>{try{var t,r=e[0]instanceof main_1.Data?e[0]:new main_1.Data(o,this.functions.entries(),{server:this,request:null,reply:null,stream:null});for(t of this.compilationManager.getEvents(n.name))await this.interpreter.run(t.compiled,{comments:a,reverse:o,data:r})}catch(e){throw console.log(e),e}})):Logger_1.Logger.danger(`${colors_1.default.bold("Brackets are not balanced at event")}: "${n.name}"`)}load(e){var t,r,n=process.cwd(),o=[];for(t of fs.readdirSync((0,path_1.join)(n,e)))if(fs.lstatSync((0,path_1.join)(n,e,t)).isDirectory())this.load((0,path_1.join)(e,t));else if(t.endsWith(".yaml")||t.endsWith(".yml")){var a=fs.readFileSync((0,path_1.join)(n,e,t),"utf-8"),a=/@(event|route)/g.test(a)?a.split(/\@(event|route)/g).map(e=>yaml_1.default.parse(e)).filter(e=>"object"==typeof e&&null!==e):[yaml_1.default.parse(a)];o.push(...a)}else if(t.endsWith(".js")){var i,a=require((0,path_1.join)(n,e,t));for(i of Array.isArray(a)?a:[a])i.route&&this.#isRoute(i.route)?o.push(i.route):i.event&&this.#isEvent(i.event)&&o.push(i.event)}for(r of o)this.#isRoute(r)?this.route(r):this.#isEvent(r)&&this.event(r)}setNotFoundHandler(r){if("string"!=typeof r)throw new main_1.EATS_Error("Missing handler code at: API#set404!");main_1.Util.areBracketsBalanced(r)?this.app.setNotFoundHandler(async(e,t)=>{e=new main_1.Data(this.rs,this.functions.entries(),{server:this,request:e,reply:t,stream:null}),await main_1.Util.resolveCode(e,r)}):Logger_1.Logger.danger("Brackets are not balanced at: API#setNotFoundHandler")}#isEvent(e){return"name"in e&&"string"==typeof e.name&&"code"in e&&"string"==typeof e.code}#isRoute(e){return"url"in e&&"string"==typeof e.url&&"code"in e&&"string"==typeof e.code}#validateAddon(e){if(!(e instanceof Addon_1.Addon))throw new main_1.EATS_Error(["Invalid add-on provided!",`"${e.constructor.name}" must be instance of Addon!`].join("\n"));if(0<e.requiredVersions.length&&!e.requiredVersions.includes(package_json_1.version))throw new main_1.EATS_Error([`Unsupported easy-api.ts version by the next plugin: "${e.name}"`,"Make sure to use one of the following versions: "+e.requiredVersions.join(", ")].join("\n"));for(var t of e.requiredAddons)if(!(this.options.addons?.map(e=>e.name)??[]).includes(t))throw new main_1.EATS_Error([`"${e.name}" required the next plugin: "${t}"`].join("\n"))}connect(e){process.on("uncaughtException",e=>{this.emit("error",e)}),this.functions.load(),Array.isArray(this.options?.omitFunctions)&&this.options.omitFunctions.forEach(e=>{e=(e.startsWith("$")?e:"$"+e).toLowerCase(),this.functions.delete(e)}),0<FunctionManager_1.overrides.length&&Logger_1.Logger.log(Logger_1.LogType.Info,`FunctionManager overrided ${FunctionManager_1.overrides.length} function${1<FunctionManager_1.overrides.length?"s":""}: `+FunctionManager_1.overrides.join(", ")),!0===this.options?.databaseOptions?.disableDefault&&this.db instanceof DatabaseManager_1.NativeDatabase&&(this.db=null);for(var t of this.options.addons??[])t.init(this),Logger_1.Logger.log(Logger_1.LogType.Info,`Extension loaded${colors_1.default.reset("")}: `+colors_1.default.bold(t.name));let r=this.options.reverse??!1,n=new main_1.Data(r,this.functions.entries(),{server:this,request:null,reply:null,stream:null}).setStart(performance.now());this.app.listen(e).then(()=>{this.uptime=Date.now(),this.emit("ready",n),Logger_1.Logger.log(Logger_1.LogType.Info,`Listening the server at PORT:${colors_1.default.reset("")} `+colors_1.default.bold(colors_1.default.yellow(e.port?.toString()??"Not defined"))),Logger_1.Logger.log(Logger_1.LogType.Start,require("../../../package.json").version),this.options.reverse?Logger_1.Logger.log(Logger_1.LogType.Danger,"! Reverse reading is enabled, this mode can be unstable; use it at your own risk."):this.#somethingIsUsingReverse&&Logger_1.Logger.log(Logger_1.LogType.Danger,"! Some events/routes are using reverse mode, this mode can be unstable; use it at your own risk.")})}get rs(){return this.options.dots??!1}}exports.API=API;