{"id":24671870,"url":"https://github.com/dotWee/stwno-mensa_api","last_synced_at":"2025-10-08T07:30:41.428Z","repository":{"id":32995105,"uuid":"148933532","full_name":"dotWee/stwno-mensa_api","owner":"dotWee","description":"A json- / grpc- / graphql-wrapper around the inofficial API for different canteens managed by the Studentenwerk Niederbayern/Oberpfalz.","archived":false,"fork":false,"pushed_at":"2025-06-22T14:52:39.000Z","size":913,"stargazers_count":2,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-03T18:06:59.832Z","etag":null,"topics":["api-server","api-wrapper","canteen","germany","graphql","grpc","json","json-api","node","nodemon","npm","oth","regensburg","university"],"latest_commit_sha":null,"homepage":"https://stwno-mensa-api.herokuapp.com/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dotWee.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-09-15T19:31:34.000Z","updated_at":"2025-06-22T14:51:07.000Z","dependencies_parsed_at":"2024-03-22T19:50:44.397Z","dependency_job_id":"3b9c72be-070a-42b8-a10f-22b523edeb9b","html_url":"https://github.com/dotWee/stwno-mensa_api","commit_stats":{"total_commits":215,"total_committers":5,"mean_commits":43.0,"dds":0.6372093023255814,"last_synced_commit":"067c15024f299d3ac346097bb13949dedc5f191a"},"previous_names":["dotwee/rgb-mensa_api","dotwee/uni-oth_mensa_api"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/dotWee/stwno-mensa_api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dotWee%2Fstwno-mensa_api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dotWee%2Fstwno-mensa_api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dotWee%2Fstwno-mensa_api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dotWee%2Fstwno-mensa_api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dotWee","download_url":"https://codeload.github.com/dotWee/stwno-mensa_api/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dotWee%2Fstwno-mensa_api/sbom","scorecard":{"id":352928,"data":{"date":"2025-08-11","repo":{"name":"github.com/dotWee/stwno-mensa_api","commit":"4eb0a0d5bfb34f1560c39bfb31ec7a63c854b4a3"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.8,"checks":[{"name":"Code-Review","score":-1,"reason":"Found no human activity in the last 15 changesets","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":"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":"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":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/nodejs.yml:1","Info: no jobLevel write permissions found"],"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":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","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":"Maintained","score":1,"reason":"2 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 1","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":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/nodejs.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/dotWee/stwno-mensa_api/nodejs.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/nodejs.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/dotWee/stwno-mensa_api/nodejs.yml/master?enable=pin","Warn: npmCommand not pinned by hash: .github/workflows/nodejs.yml:22","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 npmCommand dependencies pinned"],"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":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"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":"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 30 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":"25 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-j5g3-5c8r-7qfx","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","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-wm7h-9275-46v2","Warn: Project is vulnerable to: GHSA-ff7x-qrg7-qggm","Warn: Project is vulnerable to: GHSA-pfrx-2q88-qq97","Warn: Project is vulnerable to: GHSA-qqgx-2p2h-9c37","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-r683-j2x4-v87g","Warn: Project is vulnerable to: GHSA-v39p-96qg-c8rf","Warn: Project is vulnerable to: GHSA-8v63-cqqc-6r2c","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q"],"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-18T08:46:59.677Z","repository_id":32995105,"created_at":"2025-08-18T08:46:59.677Z","updated_at":"2025-08-18T08:46:59.677Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278908564,"owners_count":26066882,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"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":["api-server","api-wrapper","canteen","germany","graphql","grpc","json","json-api","node","nodemon","npm","oth","regensburg","university"],"created_at":"2025-01-26T10:12:03.012Z","updated_at":"2025-10-08T07:30:40.115Z","avatar_url":"https://github.com/dotWee.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# stwno-mensa_api\n\n[![npm @latest](https://img.shields.io/npm/v/stwno-mensa_api.svg)](https://www.npmjs.com/package/stwno-mensa_api)\n[![dependencies Status](https://david-dm.org/dotWee/stwno-mensa_api/status.svg)](https://david-dm.org/dotWee/stwno-mensa_api)\n[![devDependencies Status](https://david-dm.org/dotWee/stwno-mensa_api/dev-status.svg)](https://david-dm.org/dotWee/stwno-mensa_api?type=dev)\n[![GitHub issues](https://img.shields.io/github/issues/dotWee/stwno-mensa_api.svg)](https://github.com/dotWee/stwno-mensa_api/issues)\n[![GitHub license](https://img.shields.io/github/license/dotWee/stwno-mensa_api.svg)](https://github.com/dotWee/stwno-mensa_api)\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FdotWee%2Fstwno-mensa_api.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2FdotWee%2Fstwno-mensa_api?ref=badge_large)\n\nA json- / grpc- / graphql-wrapper around the inofficial API for different canteens managed by the Studentenwerk Niederbayern/Oberpfalz.\n\nThe original 'API' is kind of unhandy, as it serves its weekly data in the **CSV** format and updates only weekly. To improve the handling for more simple applications, this wrapper allows **RESTful** routes and serves its data in the **JSON** format (and also provides a **gRPC** and **GraphQL** backend!).\n\nYou can check on their [official site](https://www.stwno.de/de/gastronomie/speiseplan) or [Locations.json](src/consts/Locations.json) if your canteen is supported.\n\n## Table of contents\n\n1. [Build](#Build)\n2. [Run](#Run)\n3. [Usage](#Usage)  \n   - [RESTful API](#RESTful-API)  \n   - [GraphQL](#GraphQL)  \n   - [gRPC](#gRPC)\n4. [Development](#Development)\n5. [Acknowledges](#Acknowledges)\n6. [License](#License)\n\n## Build\u003ca name=\"Build\"\u003e\u003c/a\u003e\n\nClone repository:\n\n`$ git clone https://github.com/dotWee/stwno-mensa_api \u0026\u0026 cd stwno-mensa_api`\n\nInstall dependencies:\n\n`$ npm install`\n\n## Run\u003ca name=\"Run\"\u003e\u003c/a\u003e\n\nStart the application by executing `$ npm run start`:\n\n```bash\n$ npm run start\n\n\u003e stwno-mensa_api@3.0.0 start /Users/lukas/Git/Projects/Javascript/stwno-mensa_api\n\u003e node src/server.js\n\nUpdating local cache...\nWebserver started on port: 3000\nGRPC listening on port: 3001\n\nSee http://localhost:3000/api-docs for RESTful API docs\nOr http://localhost:3000/graphql about GraphQL usage\n```\n\n## Usage\u003ca name=\"Usage\"\u003e\u003c/a\u003e\n\nThis Node.js application is deployed to herokuapp:\n\n- https://rgb-mensa-api.herokuapp.com/\n\n### RESTful-API\u003ca name=\"RESTful-API\"\u003e\u003c/a\u003e\n\nCheckout the [API documentation](https://rgb-mensa-api.herokuapp.com/api-docs) generated by [Swagger](http://swagger.io) for informations on how to use the RESTful API (see the configuration file _[swagger.json](src/swagger.json)_, also hosted on [Swagger-Hub](https://app.swaggerhub.com/apis/dotWee/stwno-mensa_api)).\n\nExample path to get todays menu for the university canteen:\n\n    GET /api/items/regensburg-university/today\n\n```json\n[\n    {\n    \"name\": \"Karotten-Ingwer-Suppe\",\n    \"date\": \"26.11.2018\",\n    \"day\": \"monday\",\n    \"category\": \"Suppe\",\n    \"labels\": [\n      \"V\"\n    ],\n    \"ingredients\": [\n      {\n        \"key\": \"3\",\n        \"value\": \"mit Antioxidationsmittel\"\n      },\n      {\n        \"key\": \"A\",\n        \"value\": \"Gluten\"\n      },\n      {\n        \"key\": \"AA\",\n        \"value\": \"Weizen\"\n      },\n      {\n        \"key\": \"I\",\n        \"value\": \"Sellerie\"\n      }\n    ],\n    \"price\": {\n      \"students\": \"0,70\",\n      \"employees\": \"0,90\",\n      \"guests\": \"1,40\"\n    }\n  }, ...\n]\n```\n\n### GraphQL\u003ca name=\"GraphQL\"\u003e\u003c/a\u003e\n\nBeside the usual RESTful API, this application also provides a [GraphQL](https://graphql.github.io/) service. From GraphQL's website:\n\n\u003e GraphQL is a query language for your API, and a server-side runtime for executing queries by using a type system you define for your data. GraphQL isn't tied to any specific database or storage engine and is instead backed by your existing code and data.\n\nYou can play with its service by visiting [rgb-mensa-api.herokuapp.com/graphql](https://rgb-mensa-api.herokuapp.com/graphql) (or [localhost:3000/graphql](http://localhost:3000/graphql) in case of local execution).\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003cth\u003eExample GraphQL query\u003c/th\u003e\n\u003cth\u003eExample response\u003c/th\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n\n```graphql\n{\n  ingredients(key: \"5\") {\n    value\n  }\n  menu(location: \"uni\", day: \"monday\") {\n    args {\n      location\n      day\n    }\n    count\n    items {\n      name\n      date\n      day\n      category\n      labels\n      ingredients {\n        key\n        value\n      }\n      price {\n        students\n        guests\n        employees\n      }\n    }\n  }\n}\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n```json\n{\n    \"data\": {\n        \"ingredients\": [{\n            \"value\": \"geschwefelt\"\n        }],\n        \"menu\": {\n            \"args\": {\n                \"location\": \"uni\",\n                \"day\": \"monday\"\n            },\n            \"count\": 1,\n            \"items\": [{\n                \"name\": \"Karotten-Ingwer-Suppe\",\n                \"date\": \"26.11.2018\",\n                \"day\": \"monday\",\n                \"category\": \"Suppe\",\n                \"labels\": [\n                    \"V\"\n                ],\n                \"ingredients\": [{\n                        \"key\": \"3\",\n                        \"value\": \"mit Antioxidationsmittel\"\n                    },\n                    {\n                        \"key\": \"A\",\n                        \"value\": \"Gluten\"\n                    },\n                    {\n                        \"key\": \"AA\",\n                        \"value\": \"Weizen\"\n                    },\n                    {\n                        \"key\": \"I\",\n                        \"value\": \"Sellerie\"\n                    }\n                ],\n                \"price\": {\n                    \"students\": \"0,70\",\n                    \"guests\": \"1,40\",\n                    \"employees\": \"0,90\"\n                }\n            }]\n        }\n    }\n}\n```\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n### gRPC\u003ca name=\"gRPC\"\u003e\u003c/a\u003e\n\nThis application also supports access using the [gRPC Framework](https://grpc.io/about/) with Google's Protocol Buffers as JSON alternative.\n\nThis is what the protocol configuration looks like (_File [schema.proto](src/protos/schema.proto)_):\n\n```protobuf\nsyntax = \"proto3\";\n\npackage stwno_mensa_api;\n\n// The items service definition.\nservice Items {\n  // Returns items\n  rpc GetItems (ItemsRequest) returns (ItemsResponse) {}\n}\n\n// The items request, may containing arguments\nmessage ItemsRequest {\n  string location = 1;\n  string day = 2;\n}\n\n// The items response\nmessage ItemsResponse {\n  Error error = 1;\n  repeated Item items = 2;\n}\n\nmessage Item {\n  string name = 1;\n  string date = 2;\n  string day = 3;\n  string category = 4;\n  repeated string labels = 5;\n\n  message Ingredient {\n    string key = 1;\n    string value = 2;\n  }\n  repeated Ingredient ingredients = 6;\n\n  message Price {\n    string students = 1;\n    string employees = 2;\n    string guests = 3; \n  }\n  Price price = 7;\n}\n```\n\n#### Example client (using Node.js)\n\nYou can find an example client written in Node.js source code in _[clients/client_grpc.js](clients/client_grpc.js)_.\n\nFor execution: Open a shell window and run `$ npm run start` to get the server running. Then, open another window and run `$ node ./clients/client_grpc.js` to perform some requests and print the responses.\n\n## Development\u003ca name=\"Development\"\u003e\u003c/a\u003e\n\nFor local development, use `$ npm run nodemon` to work at the source code. The application will reload on code changes.\n\n## Acknowledges\u003ca name=\"Acknowledges\"\u003e\u003c/a\u003e\n\nThis application is heavily inspired by @alexanderbazo's [URMensa-JSON-API](https://github.com/alexanderbazo/URMensa-JSON-API) project.\n\n## License\u003ca name=\"License\"\u003e\u003c/a\u003e\n\nCopyright (c) 2018 Lukas Wolfsteiner. This project is licensed under the [_GNU General Public License v3_](/LICENSE) public license:\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see \u003chttp://www.gnu.org/licenses/\u003e.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FdotWee%2Fstwno-mensa_api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FdotWee%2Fstwno-mensa_api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FdotWee%2Fstwno-mensa_api/lists"}