npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

cwserver

v4.0.0

Published

A Complete NodeJS Web Server

Downloads

70

Readme

Cwserver Logo

NPM Downloads Coverage Status

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 );*/
    } )
} );

See more test here

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