diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..b49d9a3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 gh0stedBuddy + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/docs/.gitkeep b/docs/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/jsconfig.json b/jsconfig.json index 1449bc3..d9f42c7 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -1,22 +1,20 @@ { - "compilerOptions": { - "lib": ["ESNext"], - "module": "esnext", - "target": "esnext", - "moduleResolution": "bundler", - "moduleDetection": "force", - "allowImportingTsExtensions": true, - "noEmit": true, - "composite": true, - "strict": true, - "downlevelIteration": true, - "skipLibCheck": true, - "jsx": "preserve", - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "allowJs": true, - "types": [ - "bun-types" // add Bun global - ] - } + "compilerOptions": { + "lib": ["ESNext"], + "module": "esnext", + "target": "esnext", + "moduleResolution": "bundler", + "moduleDetection": "force", + "allowImportingTsExtensions": true, + "noEmit": true, + "composite": true, + "strict": true, + "downlevelIteration": true, + "skipLibCheck": true, + "jsx": "preserve", + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "allowJs": true, + "types": [] + } } diff --git a/package.json b/package.json index 999b949..0b8129e 100644 --- a/package.json +++ b/package.json @@ -1,19 +1,14 @@ { - "name": "layc", - "version": "1.0.0", - "main": "lib/layc.cjs.js", - "module": "lib/layc.js", - "devDependencies": { - "bun-types": "latest", - "chokidar": "^3.5.3" - }, - "scripts": { - "test": "bun test", - "examples": "bun run ./examples/index.js" - }, - "type": "module", - "dependencies": { - "@googleapis/youtube": "^12.0.0", - "googleapis": "^127.0.0" - } + "name": "layc", + "version": "1.0.0", + "devDependencies": { + "bun-types": "latest", + "chokidar": "^3.5.3" + }, + "scripts": { + "test": "bun test", + "examples": "bun run ./examples/index.js" + }, + "type": "module", + "dependencies": {} } diff --git a/lib/IO/LayRequest.js b/src/IO/LayRequest.js similarity index 100% rename from lib/IO/LayRequest.js rename to src/IO/LayRequest.js diff --git a/lib/IO/LayResponse.js b/src/IO/LayResponse.js similarity index 92% rename from lib/IO/LayResponse.js rename to src/IO/LayResponse.js index 37cf653..a3db51c 100644 --- a/lib/IO/LayResponse.js +++ b/src/IO/LayResponse.js @@ -99,4 +99,11 @@ export default class LayResponse { headers: this.headers(), }); } + + render(path, data = {}) { + return new Response(this.router.getServer().load(path).parse(data), { + status: this.status(), + headers: this.headers(), + }); + } } diff --git a/lib/IO/MimeTypeMap.js b/src/IO/MimeTypeMap.js similarity index 100% rename from lib/IO/MimeTypeMap.js rename to src/IO/MimeTypeMap.js diff --git a/lib/LayServer.js b/src/LayServer.js similarity index 72% rename from lib/LayServer.js rename to src/LayServer.js index 14fb806..d000bd8 100644 --- a/lib/LayServer.js +++ b/src/LayServer.js @@ -5,17 +5,18 @@ import HtmlEngine from './Views/HtmlEngine'; export default class LayServer { controllers = new Map(); + loaders = new Map(); proc = null; router; publicFiles; options = new Map([ + ['loaders', undefined], ['publicDir', undefined], ['viewsPath', undefined], - ['viewsEngine', undefined], - ['onlySingleRoutes', true], ['preferIndexFiles', false], - ['discoverPublicFiles', true], - ['enforceTrailingSlash', true], + ['discoverPublicFiles', false], + ['enforceTrailingSlash', false], + ['laycLoading', false], ]); constructor(options = {}) { @@ -25,7 +26,11 @@ export default class LayServer { for (const key of optionKeys) { if (!this.options.has(key)) continue; const valueType = typeof this.options.get(key); - if (typeof options[key] == valueType) + if ( + typeof options[key] !== 'undefined' && + (typeof options[key] == valueType || + valueType == 'undefined') + ) this.options.set(key, options[key]); } } @@ -37,6 +42,7 @@ export default class LayServer { } if (options.publicFiles) { + console.log('publicFiles', options.publicFiles); this.addPublicFileRoutes(options.publicFiles); } @@ -64,7 +70,11 @@ export default class LayServer { throw new Error( 'publicFiles option has to be an array or undefined' ); + if (!this.publicFiles || !Array.isArray(this.publicFiles)) + this.publicFiles = []; for (let path of filePaths) { + if (typeof path != 'string') continue; + this.publicFiles.push(path); } } @@ -77,8 +87,7 @@ export default class LayServer { } registerControllers(controllers) { - if (!Array.isArray(controllers)) - throw new Error('controllers is not an Array'); + if (!Array.isArray(controllers)) controllers = [controllers]; for (let controller of controllers) { if (typeof controller != 'function') { @@ -86,8 +95,14 @@ export default class LayServer { continue; } + // if the given controller is just an anonymous function defining the routes itself + if (!controller?.prototype?.constructor?.name) { + controller(this.routeControl); + continue; + } + this.controllers.set( - controller.name, + controller?.name, this.instantiateController(controller) ); } @@ -118,10 +133,16 @@ export default class LayServer { if (path) { try { return new Response( - Bun.file(resolvePath(import.meta.dir, 'public', path)) + Bun.file( + resolvePath( + this.options.get('publicDir') ?? + `${import.meta.dir}/public`, + path + ) + ) ); } catch (err) { - console.log(err); + console.log(err, import.meta.dir, 'public', path); return new Response('Internal Server Error', { status: 500, }); @@ -133,7 +154,11 @@ export default class LayServer { return Response.redirect(`${url.toString()}/`, 302); } - return await this.router.handle(req); + let resp = await this.router.handle(req); + + if (!resp) return new Response('Not Found', { status: 404 }); + + return resp; } listen(port = 8080) { @@ -165,4 +190,15 @@ export default class LayServer { console.error(err); } } + + load(filepath) { + const filename = filepath.split('/').pop().toString(); + const ext = filename.split('.').pop().toLowerCase(); + + for (const keys of this.loaders.keys()) { + if (keys.includes(ext)) { + return this.loaders.get(keys)(filepath); + } + } + } } diff --git a/lib/Routing/BaseController.js b/src/Routing/BaseController.js similarity index 100% rename from lib/Routing/BaseController.js rename to src/Routing/BaseController.js diff --git a/lib/Routing/LayRouting.js b/src/Routing/LayRouting.js similarity index 100% rename from lib/Routing/LayRouting.js rename to src/Routing/LayRouting.js diff --git a/lib/Routing/Router.js b/src/Routing/Router.js similarity index 99% rename from lib/Routing/Router.js rename to src/Routing/Router.js index 3fe2b0b..5e602ea 100644 --- a/lib/Routing/Router.js +++ b/src/Routing/Router.js @@ -13,6 +13,10 @@ export default class Router { this.server = server; } + getServer() { + return this.server; + } + async handle(req) { if (!(req instanceof Request)) { throw new Error('`req` is not a proper Request'); diff --git a/lib/Utils/Logger.js b/src/Utils/Logger.js similarity index 100% rename from lib/Utils/Logger.js rename to src/Utils/Logger.js diff --git a/lib/Utils/RequestParser.js b/src/Utils/RequestParser.js similarity index 100% rename from lib/Utils/RequestParser.js rename to src/Utils/RequestParser.js diff --git a/lib/Views/HtmlEngine.js b/src/Views/HtmlEngine.js similarity index 100% rename from lib/Views/HtmlEngine.js rename to src/Views/HtmlEngine.js diff --git a/lib/index.js b/src/index.js similarity index 100% rename from lib/index.js rename to src/index.js