cwserver
v4.0.0
Published
A Complete NodeJS Web Server
Downloads
70
Maintainers
Readme
cwserver
The aim of the project is to create an easy to use, lightweight, Complete Web Server Framework
with default NodeJs HTTP Server
.
- The framework also provides default
Secure User Session
,Cookie Parser
,Flexible Router
,Multiple Views
,Virtual Directory
,Hidden Directory
,Template Engine
,Nested Master Template Engine
,Post Data Handler (with multipart form data and large file)
,Mimetype Handler
,WebStream Handler
,JS/CSS Bundler
,socket.io Interface
,Easy way to bind with IIS/NGINX
Install cwserver
by this command npm i cwserver
How to use cwserver
core IApplication
?
const { App } = require('cwserver');
const app = App();
const port = 8080;
app.on("request-begain", (req) => {
console.log(`${req.method} ${req.path}`);
});
app.on("response-end", (req, res) => {
console.log(`Send ${res.statusCode} ${req.path}`);
});
app.use((req, res, next) => {
res.status(200).send("Hello World...");
});
app.listen(port, () => {
console.log(`Listing port => ${port}`);
});
Or you may use full application by following:
Create createProjectTemplate.js
as following
const { createProjectTemplate } = require( 'cwserver' );
createProjectTemplate( {
appRoot: __dirname,
projectRoot: "www" /** Your project root folder name*/,
allExample: false
} );
Then run this commmand node createProjectTemplate
It will create default project template for cwserver
in your application root.
Now your appRoot look like this
appRoot
├─┬ wwww ( projectRoot )
│ └─┬ config
│ ├ lib
│ ├ template (this contains master template file)
│ ├ web (this contains temp and cache files)
│ └ index.html
├─ node_modules
├─ server.js
├─ package.json
└─ README.md
After, run this command node server www /**your project root*/
How to setup middleware
First process app.prerequisites
every request and then run app.use
global.cw.server.on( "register-view", ( app, controller, server ) => {
app.prerequisites( ( req, res, next ): void => {
res.setHeader( 'x-frame-options', 'sameorigin' );
return next();
} );
app.use( ( req, res, next ): void => {
res.setHeader( 'x-frame-options', 'sameorigin' );
return next();
} );
} );
How to setup router ?
global.cw.server.on( "register-view", ( app, controller, server ) => {
controller
.any( '/test-any/*', ( ctx, match ) => {
return ctx.res.json( { reqPath: ctx.path, servedFrom: "/test-any/*", q: match } );
} )
.get( '/task/:id/*', ( ctx, match ) => {
return ctx.res.json( { reqPath: ctx.path, servedFrom: "/task/:id/*", q: match } );
} )
.get( '/dist/*', ( ctx, match ) => {
return ctx.res.json( { reqPath: ctx.path, servedFrom: "/dist/*", q: match } );
} )
.get( '/user/:id/settings', ( ctx, match ) => {
return ctx.res.json( { reqPath: ctx.path, servedFrom: "/user/:id/settings", q: match } );
} );
} );
How to add Virtual Directory ?
global.cw.server.on( "register-view", ( app, controller, server ) => {
const vDir = path.join( path.resolve( server.getRoot(), '..' ), "/project_template/test/" );
server.addVirtualDir( "/vtest", vDir, ( ctx ) => {
return mimeHandler.render( ctx, vDir, true );
} );
server.addVirtualDir( "/test-virtual", vDir );
server.addVirtualDir( "/vtest/virtual/", vDir );
} );
Authetication
Session cookie name use from app.config.json => session.cookie
and session encryption use app.config.json => session.key
global.cw.server.on( "register-view", ( app, controller, server ) => {
controller.get( '/authenticate/:loginId/:roleid', ( ctx, requestParam ) => {
if ( ctx.req.session.isAuthenticated ) {
ctx.res.status( 200 ).type( "html" ).send( `Hello ${ctx.req.session.loginId}` );
} else {
ctx.setSession(/*loginId*/requestParam.query.loginId,/*roleId*/requestParam.query.roleId, /*userData*/{ token: ctx.req.query.token } );
ctx.res.status( 200 ).type( "html" ).send( `Authentication success ${ctx.req.query.loginId}` );
}
return ctx.next( 200 );
} );
} );
SignOut From Application
global.cw.server.on( "register-view", ( app, controller, server ) => {
controller.get( '/signout', ( ctx, requestParam ) => {
if ( ctx.session.isAuthenticated ) {
ctx.signOut();
}
ctx.redirect( "/" ).next( 302, true );
} );
} );
Handle post data
const { getBodyParser, fsw } = require( 'cwserver' );
global.cw.server.on( "register-view", ( app, controller, server ) => {
const downloadDir = server.mapPath( "/upload/data/" );
if ( !fs.existsSync( downloadDir ) ) {
fsw.mkdirSync( server.mapPath( "/" ), "/upload/data/" );
}
const tempDir = server.mapPath( "/upload/temp/" );
controller.post( '/post-async', async ( ctx ) => {
const parser = getBodyParser( ctx.req, tempDir );
await parser.parseSync();
if ( parser.isUrlEncoded() || parser.isAppJson() ) {
ctx.res.status( 200, { 'Content-Type': 'application/json' } );
ctx.res.end( JSON.stringify( parser.getJson() ) );
parser.dispose();
return ctx.next( 200 );
}
parser.saveAsSync( downloadDir ); parser.dispose();
return ctx.res.status( 200 ).send( "<h1>success</h1>" );
// or
// return ctx.res.asHTML( 200 ).end( "<h1>success</h1>" );
// or
/*const data = [];
parser.getFilesSync( ( file ) => {
data.push( {
content_type: file.getContentType(),
name: file.getName(),
file_name: file.getFileName(),
content_disposition: file.getContentDisposition(),
temp_path: file.getTempPath()
} );
file.saveAsSync( `${downloadDir}/${Util.guid()}_${file.getFileName()}` );
} );
return ctx.res.status( 200 ).json( data );*/
} )
} );
Template Engine
Template can run config.defaultExt
file extension or ctx.res.render( ctx, to_file_path )
Example of server-side script in config.defaultExt
or app.config.json => template.ext
ctx.res.render( ctx, server.mapPath( `/index${server.config.defaultExt || ".html"}` ) );
Code block:
{%
if( !ctx.session.isAuthenticated ){
return ctx.next( 401, true );
} else {
ctx.write( JSON.stringify( ctx.session ) );
}
%}
<ul>
{% users.forEach(function(user){ %}
{= user =}
{% }); %}
</ul>
<ul>
<!--{%--> users.forEach(function(user){ <!--%}-->
{= user =}
<!--{%--> }); <!--%}-->
</ul>
<script>
var userLength = 0;
/*{%*/ if ( users.length > 0 ) {/*%}*/
userLength = {= users.length =};
/*{%*/ } /*%}*/
</script>
<script>
var userLength = 0;
{% if ( users.length > 0 ) { %}
userLength = {= users.length =};
{% } %}
</script>
Response write: {= myVar =}
or ctx.write(myVar)
{%
const result = await ctx.server.db.pgsql.executeIoAsync( "my_shcema.__get_dataset", JSON.stringify( {
login_id: ctx.req.session.loginId
} ), JSON.stringify( {
trade_date: "2020-02-03"
} ) );
%}
{% if ( result.ret_val < 0) { %}
<span style="color:red">No Data Found...</span>
{% } else { %}
<table style="width:100%">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
</thead>
<tbody>
{% for( const row of result.ret_data_table ){ %}
<tr>
<td>{= row.first_name =}</td>
<td>{= row.last_name =}</td>
<td>{= row.age_name =}</td>
</tr>
{% } %}
</tbody>
</table>
{% } %}
Nested Master Template
#extends
keyword define my master template
You can add multiple file by #attach
keyword
www
├─┬ template
│ └─┬ master.html
│ ├ footer.html
│ ├ header.html
│ └ readme.html
├─ index.html
index.html ==> #extends /template/readme.html
==> index.html impliment placeholder id of readme.html (parent master)
-------------------------------------------
#extends /template/readme.html
<impl-placeholder id="container">
container here
</impl-placeholder>
-------------------------------------------
readme.html ==> #extends /template/master.html (parent master)
==> readme.html like as master template and its contains own placeholder and impliment placeholder id of master.html
-------------------------------------------
#extends /template/master.html
<impl-placeholder id="body">
<!--Here create new placeholder-->
<placeholder id="container">
</placeholder>
</impl-placeholder>
<impl-placeholder id="header">
#attach /template/header.html
</impl-placeholder>
-------------------------------------------
master.html ==> root master template
--------------------------------------------
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<placeholder id="header">
</placeholder>
<body>
<placeholder id="body">
</placeholder>
#attach /template/footer.html
</body>
</html>
--------------------------------------------
see more about template /dist/project_template/www
server.js
You may create server.js file by you:
const { ConsoleColor, initilizeServer } = require( 'cwserver' );
let wwwName = void 0;
if ( process.argv.length > 2 ) {
wwwName = process.argv[2];
} else {
if ( process.env.APP_POOL_ID ) {
wwwName = process.env[process.env.APP_POOL_ID];
}
}
const server = initilizeServer( __dirname, wwwName );
const app = server.init();
process.on( 'exit', () => {
console.log( "Exited..." );
} );
process.on( 'SIGINT', () => {
server.log.error( "Caught interrupt signal" );
server.log.error( "Application Exited..." );
server.log.reset(); server.log.dispose();
setTimeout( () => {
process.exit( 0 );
}, 200 );
} );
app.listen( server.port, () => server.log.write( `
[+] Maintance : https://www.fsys.tech
[+] Server : http://localhost:${server.port}
[+] Socket : ws://localhost:${server.port}${server.socketPath}
[~] Running Server...
`, ConsoleColor.FgMagenta ) );
Read more about app.config.json
run node server your_app_dir_name
or npm start your_app_dir_name