Gathering detailed insights and metrics for pasar
Gathering detailed insights and metrics for pasar
Gathering detailed insights and metrics for pasar
Gathering detailed insights and metrics for pasar
npm install pasar
Typescript
Module System
Node Version
NPM Version
JavaScript (84.81%)
Pug (8.92%)
SCSS (3.25%)
CSS (3.02%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
GPL-3.0 License
2 Stars
137 Commits
2 Watchers
3 Branches
1 Contributors
Updated on May 16, 2023
Latest Version
1.4.4
Package Id
pasar@1.4.4
Unpacked Size
256.91 kB
Size
80.12 kB
File Count
26
NPM Version
6.14.17
Node Version
14.21.2
Published on
May 17, 2023
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
Promise Aware Smart API REST builder to easily implement Express routers with advanced capabilities.
PASAR main goal is to asist you in building consistent and full-featured promise-based APIs focusing in your business logic and not bothering about plumbing details.
To achieve it, PASAR proposes a clear and consistent routing schema with a few conventions to achieve orthogonal feature access.
That is: To build a full featured API REST, you only need to provide one or two things:
Example:
1 var Pasar = require("pasar"); 2 3 var Options = { 4 // ... 5 }; 6 7 var myApi = { 8 myServiceName: { 9 // Service definition. 10 }, 11 // ... 12 }; 13 14 module.exports = Pasar(myApi, Options);
Service definitions consists in an object with one or more attributes. Simples't service definition looks like:
1 myServiceName: { 2 _all: function myActionFunction(input, ac) { // Use _get, _post, etc.. to attach your handler to specific http method. 3 // input: Your input data. No matter if send by get, post, put, etc... 4 // ...but you can fine-tune this by overridding default request mapper. 5 // auth: FIXME: Document it!!. 6 7 return new Pasar.Promise(function(resolve, reject) { 8 // Do some (async) logic... 9 10 // ...and finally: 11 resolve(someData); 12 // ...or: 13 reject(reason); 14 }); 15 }, 16 },
If your API grows too much, you can provide an array of smaller service definiton sets instead of single one. Ex.:
1 2 var myApi = [ 3 requere("path1/sumbmodule1.js", // Services defined in other module. 4 requere("path2/sumbmodule2.js", // More modularyzed services... 5 { // And of course, some others can be defined directly here... 6 myServiceName: { 7 // Service definition. 8 }, 9 // ... 10 } 11 ]; 12
Action functions are expected to return a promise but they are actually able to directly return a result (which is automatically promisified).
On promise rejections (or thrown errors) an http 500 error code (Internal Server Error) is send to the client and, from version 1.2.14, if logErrors option is not set to false, the error/rejection message is logged to stderr (except ).
(See more complete examples later...)
Service : With "Service" we mean any functionality attached to unique url of our API no matter which methods (get, post...) attends or not.
Service Definition : Javascript object providing all functions needed to implement all available methods of service and some other optional properties which lets us to change service behaviour in any manner.
Actions
: Actions (or Action Handlers) are functions attached to _get
, _post
, _put
, _delete
or _all
properties of a Service Definition. They are expected to return a promise of the result data. But, if don't, it's actual result will be automatically promisified.
Request Mapper : A Request Mapper is a function responsible to receive the request object and a second parameter with the actual method name and return propper input for the Action Handler. This pattern let's us to access exactly same functionality implementations thouth http as a REST API, or locally as library functions.
Response Mapper : Response Mappers are the counterpart of Request Mappers. They receives the promise returned by Actions and perform proper http response (We probably should never override default one).
Facility : Facilities are fully automated extra functionalities over all Services (accessed thought serviceUrl/facilityName) and/or over the whole API (accessed thought /facilityName/. The only currently implemented facility is /help.
Output Filters : Output Filters (or Output Formatters) let all our services output to be exported to distinct output formats, such as csv, html, etc... SIMPLY adding corresponding extension (.csv, .html...) to the original service url.
PASAR does not implement POST processings itself. Instead expects proper middlewares to be used by our app. (If they are not used, POST (or PUT / DELETE) data will not be detected). This middlewares are:
body-parser: For regular url-encoded or json requests. Examples:
app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json());
express-fileupload: For multipart requests (Ex with forms like <form enctype="multipart/form-data" ...>
).
app.use(fileUpload());
_get
, _post
, _put
and/or _delete
or simply to _all
(which attaches it to all methods except explicitly specified thought _get
, _post
, etc...). But actions never knows about actual requested method. So, if we want different behaviour, for example, in GET requests than in POST ones, we should specify our own Request Mapper to provide propper Action input depending on the actual request method.Easy method (GET, POST, etc...) attachment handling.
Multiple output formats selected by extension (default is .json). Including html (to easy data inspection).
Easy access to self explanation (adding '/help' to each url) and fully automated help index.
Consistent routing schema:
Global, per-api, per-service and per-method configurable timeouts (via promise rejection).
Internally reusable: Services implementation can easily make use of other functions.
this.srvName.method()
from other service methods.
var me=this
trick when needed.Externally reusable: All service actions are externally exposed thought 'fn' property of the resulting router.
Externally reusable SYNCHRONOUSLY: Just like 'fn', router is provided with 'syncFn' vector providing sync versions of your service actions (Available only for Node version v0.11.0 or hihger).
Easy querying while developing with automated (but customizable) '/form' facilities.
Advanced access control policies:
Custom request mapping:
requestMapper: myRequestMapper,
...for more details about how to implement your own request mapper, see default Request Mapper implementation.
Custom response mapping:
responseMapper: myResponseMapper,
...for more details about how to implement your own response mapper, see default Response Mapper implementation.
Currently the only existing documentation consist in below examples and an incomplete Usage Manual.
Maybe you would like to help in building better one... (see Contributing)
Below are documentary examples. If you need fully functional examples see PASAR demos.
All API definitions should look's like follows:
1 var Promise = require("promise"); // Or your favorite promise library. 2 var Pasar = require("pasar"); 3 4 var Options = { // Comment-out / modify as you need... 5 // logErrors: false, // ...to disable rejection logging. 6 // noLib: true, // ...to disable .fn and .syncFn facilites. 7 // noHelp: true, // ...to disable /help facilities. 8 // noForm: true, // ...to disable /form facilities. 9 // noFilters: true, // ...to disable optional formatting filters. 10 // "defaults.help.examples.get": [{}], // ...to automatically provide all your functions help with simple example. 11 // "defaults.authHanlder": myAuthHandler, // ...to sepcify your own authentication handler. 12 // "defaults.requestMapper": myRequestMapper, // ...to sepcify your own request mapper. 13 // "defaults.responseMapper": myResponseMapper, // ...to sepcify your own response mapper. 14 // promiseEngine: myPromiseEngine, // ...to provide your own promise engine. 15 // "client.jQuery": "url_to_jQuery" // ...to override jQuery path in facility views. 16 // ... (See documentation for more details on available options). 17 }; 18 19 var myApi = { 20 someFunction: { 21 _get: function(input) { 22 // Do some stuff... 23 return new Promise(function(resolve, reject) { 24 // Do some async stuff... 25 // And somewhere: 26 resolve({ 27 data: {...}, // Actual function response. 28 meta: {...}, // Some optional metadata which could be used by many output filteres. 29 // i.e. page title, field types, etc... 30 }); 31 // And in some other place: 32 reject(error); 33 }); 34 }, 35 _post: function(input) { 36 // ... 37 }, 38 timeout: 3000, // Reject with timeout error if promise is not resolved after 3 seconds. 39 // Or: timeout: {all: 3000}, 40 // 41 // NOTE: You can set different timeouts for specific methods (i.e.: "{get:5000, post:3000}") 42 // ...but this only works if defined separately. Methods defined in block thought _all 43 // property will only get generic timeout (because it also becomes single express route). 44 // 45 // NOTE 2: You can customize timeout error message passing an array like this: 46 // timeout: [3000, "Operation taken too long"], 47 help: { 48 contents: "Explain what this function does...", 49 brief: "Brief explanation to be shown in whole API help index", 50 // If not given, brief will be auto-extracted from contents. 51 methods: { 52 all: "Method specific explanation", // Default text. I ommitted, defaults to "(Undocumented)". 53 _get: "Specific explanation for GET method", // 'get' and '_get' are threated the same. 54 // post: "", // As commented out, it will default to "all" text. 55 put: "Some future method explanation.", // Will be marked as "UNIMPLEMENTD". 56 // delete: "", // As commented out and unimplemented, will NOT be shown. 57 }, 58 examples: { // (get/_get, post...) Just like methods definitions... 59 get: [, // Simple GET example without parameters labelled by its url. 60 {}, // Add example to query without parameters. 61 ['label', {foo: "bar"}, "Some optional comment"], // Another with parameters. 62 [null, [bar: "baz"}], // Another auto-labelled example. 63 // NOTE: All get examples are automatically linked to it's url. 64 // NOTE 2: Post, put, etc... are actually linked to "#". 65 // In (I hope) near future I expect to implement links to them via ajax call (TODO). 66 // NOTE 3: Simplest get specification is: «get: [{}]», 67 ], 68 post: [ 69 ['Hello', {foo: "bar"}, "long explanation"], 70 ['World', {foo: "bar"}, "More longer explanation"], 71 ], 72 put: [{foo: "bar"}], 73 // ... 74 }, 75 }, 76 }, 77 someOtherFunction: { 78 _all: function(input) { 79 // Do some stuff... 80 return new Promise(function(resolve, reject) { 81 // Do some async stuff... 82 // And somewhere: 83 resolve({...}); 84 // If no need for metadata and no data vector specified, 85 // this will be automagically remapped to: 86 // { 87 // data: {...}, // Actual function response. 88 // meta: {...}, // Some optional metadata which could be used by many output filteres. 89 // // i.e. page title, field types, etc... 90 // } 91 // ...so you can simply resolve with your actual result EXCEPT if it could contain 92 // a 'data' vector in its root level. In which case you should at least resolve 93 // with {data:{...}} 94 95 // And in some other place: 96 reject(error); 97 }); 98 }, 99 help: "Explain what this function does..." // Simplest way to specify minimal help text. 100 }, 101 }; 102 103 module.exports = Pasar(myApi, Options); 104
Then, to mount your API REST to your Express app or router simply:
1 // Load API definitions: 2 var someAPI = require("__path_to_my_api__"); 3 var someOtherAPI = require("__path_to_my_other_api__"); 4 5 // REST API usage: 6 // =============== 7 8 // Having your Express app is 'app' variable... 9 10 // To mount your api at /api route: 11 app.use('/api', someAPI); 12 // ...Or symply 'app.use("/api", require("__path_to_my_api__"))' 13 14 // To mount your api at your app root: 15 app.use(someOtherAPI); 16 // ...Or simply 'app.use(require("__path_to_my_other_api__"))' 17 18 // Of course, you also can mount it on existing express router's subpath or root: 19 myRouter.use(...); 20 21 22 // Usage as internal library: 23 // ========================== 24 25 // To access Services as library: 26 someApi.fn.someFunction.get({foo: "bar"}) 27 .then(function(data){console.log(data);}) 28 .catch(throw) 29 ; 30 31 // Also with available output filters: 32 var resultPromise = somApi.fn["someFunction.html"]({foo: "bar"}); 33 // Returns promise (Use .then(), .catch()...) 34 // ".get", ".post", etc... can be ommited when only one method is implemented. 35 // ...Or simply 'var myAsyncLib = require("__path_to_my_api__").fn;' 36 37 // To access Services as sync library: 38 var result = someApi.syncFn.someFunction({foo: "bar"}); 39 // WARNING: 40 // * Sync functions are blocking. Use at your own risk!! 41 // * They are not availible in Node versions under v0.11.0. 42 // * In earlier Node versions, it will throw an exception if you try to use it. 43 // * Not yet tested (sorry) could not properly work even with node v0.11.0 or higher. 44 // ...Or simply 'var mySyncLib = require("__path_to_my_api__").syncFn;' 45
Let's use promise rejection to generate valid http error responses.
Make requirement of 'meta' and 'data' vectors in returned data to be configurable.
Posibility to execute predefined tests clientside thought /test facilities.
Configurable logging capabilites (including time measurement).
Promise-level caching.
Make it NESTABLE: If another PASAR router is passed instead of service definition:
Unified backend (usability + avoid collisions between services and facilities):
WebSocket update events interface (DRAFT).
Client-side javascript library.
Unit testing:
If you are interested in contributing with this project, you can do it in many ways:
Creating and/or mantainig documentation.
Implementing new features or improving code implementation.
Reporting bugs and/or fixing it.
Sending me any other feedback.
Whatever you like...
Please, contact-me, open issues or send pull-requests thought this project GIT repository
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
9 existing vulnerabilities detected
Details
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
Found 0/26 approved changesets -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Score
Last Scanned on 2025-07-07
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More