chore(project) cleanup; structure adjustments; preparational work
This commit is contained in:
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -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.
|
||||
0
docs/.gitkeep
Normal file
0
docs/.gitkeep
Normal file
@@ -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": []
|
||||
}
|
||||
}
|
||||
|
||||
29
package.json
29
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": {}
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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');
|
||||
Reference in New Issue
Block a user