A Complete NodeJS Web Server
npm install cwserver[![Cwserver Logo][cwserver-logo]][cwserver-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![Coverage Status][coveralls-image]][coveralls-url]
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/`
$3
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();
} );
} );
`
$3
`
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 } );
} );
} );
`
$3
`
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 );
} );
`
$3
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 );
} );
} );
`
$3
`
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 );
} );
} );
`
$3
`
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( "success
" );
// or
// return ctx.res.asHTML( 200 ).end( "success
" );
// 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 );*/
} )
} );
`
See more test here
$3
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 ) );
}
%}
`
`
{% users.forEach(function(user){ %}
{= user =}
{% }); %}
users.forEach(function(user){
{= user =}
});
`
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) { %}
No Data Found...
{% } else { %}
Firstname
Lastname
Age
{% for( const row of result.ret_data_table ){ %}
{= row.first_name =}
{= row.last_name =}
{= row.age_name =}
{% } %}
{% } %}
`
$3
`#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
container here
-------------------------------------------
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
#attach /template/header.html
-------------------------------------------
master.html ==> root master template
--------------------------------------------
#attach /template/footer.html
--------------------------------------------
`
see more about template /dist/project_template/www
$3
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(
, ConsoleColor.FgMagenta ) );
`
Read more about app.config.json
run `node server your_app_dir_name` or `npm start your_app_dir_name``