{"id":36503359,"url":"https://github.com/bertolo1988/saco","last_synced_at":"2026-01-12T02:26:33.400Z","repository":{"id":65492273,"uuid":"85430953","full_name":"bertolo1988/saco","owner":"bertolo1988","description":"A pre customized, express server for single page web apps that aims to be production ready.","archived":false,"fork":false,"pushed_at":"2019-03-19T20:08:52.000Z","size":539,"stargazers_count":23,"open_issues_count":0,"forks_count":4,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-09-16T20:42:42.299Z","etag":null,"topics":["cache","express","favicon","front-end","gzip","multi-core","nodejs","production-ready","server","typescript","web"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bertolo1988.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-03-18T20:46:05.000Z","updated_at":"2024-03-23T14:42:22.000Z","dependencies_parsed_at":"2023-01-26T02:16:35.259Z","dependency_job_id":null,"html_url":"https://github.com/bertolo1988/saco","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/bertolo1988/saco","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bertolo1988%2Fsaco","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bertolo1988%2Fsaco/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bertolo1988%2Fsaco/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bertolo1988%2Fsaco/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bertolo1988","download_url":"https://codeload.github.com/bertolo1988/saco/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bertolo1988%2Fsaco/sbom","scorecard":{"id":234616,"data":{"date":"2025-08-11","repo":{"name":"github.com/bertolo1988/saco","commit":"0990e4ed241e5ebe7154982a2826c334f66e0488"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.7,"checks":[{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":0,"reason":"Found 1/21 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 12 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"45 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-qwcr-r2fm-qrc7","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-pxg6-pf52-xh8x","Warn: Project is vulnerable to: GHSA-h452-7996-h45h","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-rv95-896h-c2vc","Warn: Project is vulnerable to: GHSA-qw6h-vgh9-j6wx","Warn: Project is vulnerable to: GHSA-2j2x-2gpw-g8fm","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-4q6p-r6v2-jvc5","Warn: Project is vulnerable to: GHSA-c429-5p7v-vgjp","Warn: Project is vulnerable to: GHSA-qqgx-2p2h-9c37","Warn: Project is vulnerable to: GHSA-2pr6-76vf-7546","Warn: Project is vulnerable to: GHSA-8j8c-7jfh-h6hx","Warn: Project is vulnerable to: GHSA-896r-f27r-55mw","Warn: Project is vulnerable to: GHSA-6c8f-qphg-qjgp","Warn: Project is vulnerable to: GHSA-jf85-cpcp-j695","Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-fhjf-83wg-r2j9","Warn: Project is vulnerable to: GHSA-76c9-3jph-rj3q","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j","Warn: Project is vulnerable to: GHSA-rhx6-c78j-4q9w","Warn: Project is vulnerable to: GHSA-g6ww-v8xp-vmwg","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-m6fv-jmcg-4jfg","Warn: Project is vulnerable to: GHSA-cm22-4g7w-348p","Warn: Project is vulnerable to: GHSA-4g88-fppr-53pp","Warn: Project is vulnerable to: GHSA-4jqc-8m5r-9rpr","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh","Warn: Project is vulnerable to: GHSA-p9pc-299p-vxgp"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-17T05:24:20.555Z","repository_id":65492273,"created_at":"2025-08-17T05:24:20.555Z","updated_at":"2025-08-17T05:24:20.555Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28332425,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T00:36:25.062Z","status":"online","status_checked_at":"2026-01-12T02:00:08.677Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cache","express","favicon","front-end","gzip","multi-core","nodejs","production-ready","server","typescript","web"],"created_at":"2026-01-12T02:26:33.057Z","updated_at":"2026-01-12T02:26:33.395Z","avatar_url":"https://github.com/bertolo1988.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Saco\n\nA pre customized, express server for single page web apps that aims to be production ready.\nSaco promotes separation of concerns, quality, best practices and testability when deploying front end single page web apps.\n\n[![dependencies Status](https://david-dm.org/bertolo1988/saco/status.svg)](https://david-dm.org/bertolo1988/saco)\n[![devDependencies Status](https://david-dm.org/bertolo1988/saco/dev-status.svg)](https://david-dm.org/bertolo1988/saco?type=dev)\n[![npm version](https://badge.fury.io/js/saco.svg)](https://badge.fury.io/js/saco)\n[![Build Status](https://travis-ci.org/bertolo1988/saco.svg?branch=master)](https://travis-ci.org/bertolo1988/saco)\n[![Maintainability](https://api.codeclimate.com/v1/badges/bee30e158db90b070049/maintainability)](https://codeclimate.com/github/bertolo1988/saco/maintainability)\n\n## By using Saco\n\n...you avoid the following common mistakes:\n\n- using development servers in production\n- poluting your front end project with extra dependencies\n- having your front end app on the same server of your back end server\n- using non [nodejs](https://nodejs.org/en/) solutions\n- incomplete production configuration\n\nand benefit from having:\n\n- [expressjs](https://expressjs.com/) properly configured for production\n- http \u0026\u0026 https static folder hosting\n- high quality and tested code launching your production server\n- beautifully bootstrapped cluster with stop and start methods\n- favicon hosted with [serve-favicon](https://github.com/expressjs/serve-favicon)\n- gzip with [compression](https://github.com/expressjs/compression)\n- customizable logging with [debug](https://github.com/visionmedia/debug)\n- [customizable format timestamps](https://github.com/felixge/node-dateformat)\n- [multi core server](https://nodejs.org/docs/latest/api/cluster.html)\n- resource caching\n- configured to work behind proxies\n\n## Demo\n\n`npm run http-demo`, `npm run https-demo` or `npm run cluster-https-demo`\n\n## How to use\n\n1. Create a folder `mkdir my-saco-launcher` and `cd` into it.\n\n2. Start new npm project with `npm init -y` and drag your single page web app files inside.\n\n3. `npm i --save saco`\n\n4. Create a script such as:\n\n```javascript\nconst path = require(\"path\");\nconst Saco = require(\"saco\");\nnew Saco.Server({ rootPath: path.join(__dirname, \"/dist\") }).start();\n```\n\n5. Run it as: `cross-env NODE_ENV=production DEBUG=saco:* node my-script.js`.\n\nNotice that we used [cross-env](https://github.com/kentcdodds/cross-env) to set the environment variables. You may use another method.\n\n## How does it work exactly?\n\nWell... Take a look at the code, its not much.\n\n## Behind a proxy\n\nIf your saco instance is behind proxy such as [nginx](https://www.nginx.com/resources/wiki/), in order to have the request ip properly shown in the console\ndo not forget to set the option `behindProxy` to true.\n\nThis will configure our server to trust a proxy and behave as explained [here](https://expressjs.com/en/guide/behind-proxies.html).\n\nIf your reverse proxy is Nginx you can add this `proxy_set_header X-Forwarded-For $remote_addr;` in your `.conf` file.\n\nThis will allow redefining or appending fields to the request header passed to the proxied server.\n\n## Inside Docker\n\nInside docker you need to define `ip` as '0.0.0.0'.\n\n## Server API\n\n```\nconstructor(options: ServerOptions)\n```\n\n```\n// returnes a promise that resolves only after all workers\n// have sent ClusterMessage.WORKER_LISTENING to the master\nstart(): Promise\u003cnumber\u003e\n```\n\n```\n// returnes a promise that resolves only after all\n// workers have send 'exit' event to the master\nstop(): Promise\u003cany\u003e\n```\n\n## Options\n\nSaco server supports the following options:\n\n[Link to ServerOptions.ts.](/src/ServerOptions.ts)\n\nRemember values with `?` are optional.\n\nIn order to have an https server `key` and `cert` paths must be defined.\n\nWorkers has a default and maximum value equal to the number of cores of your processor.\n\n| option      | What it does                                                                                                                               |\n| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------ |\n| name        | Just a string to easily identify the server in the log.                                                                                    |\n| port        | Where the server is going to listen.                                                                                                       |\n| ip          | The address where the server will be. For most cases this should be either 'localhost or '0.0.0.0'.                                        |\n| cors        | Set to true if you want to allow cross origin requests.                                                                                    |\n| dateformat  | String describing logs dateformat. Must be supported by [dateformat npm package](https://www.npmjs.com/package/dateformat).                |\n| verbose     | Set to true if you want to have logs in the console.                                                                                       |\n| key         | HTTPS key.                                                                                                                                 |\n| cert        | HTTPS certificate.                                                                                                                         |\n| workers     | Number of forks. Default value depends on number of processor cores.                                                                       |\n| maxAge      | Specifies, in milliseconds, for how long should resources stay in client cache.                                                            |\n| behindProxy | Enables trust proxy header.                                                                                                                |\n| rootPath    | Specify the path where the resources will be in the server local hard drive.                                                               |\n| index       | Expects an object with url and path. Path is the relative path from rootPath until the file and url is the default url used by the server. |\n| assets      | Same as index but for the assets used by the page.                                                                                         |\n| favicon     | Same as index but for favicon file.                                                                                                        |\n\n## Linting\n\n`npm run lint`\n\n## Testing\n\n`npm run test`\n\n## Logging\n\nUse `DEBUG=saco:* npm run your-launcher.js` to have the logs printed on your console.\n\n## Contributing\n\nContributions will be highly appreciated.\n\nFeel free to open any issues on any related matter.\n\nRecommended versions\n\n- node : v8.11.2\n\n- npm: 5.6.0\n\n- typescript: 2.8.3\n\n## LICENSE\n\nCode released under the [MIT license](./LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbertolo1988%2Fsaco","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbertolo1988%2Fsaco","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbertolo1988%2Fsaco/lists"}