{"id":21973077,"url":"https://github.com/marcinrek/loco-server","last_synced_at":"2026-02-23T23:11:29.061Z","repository":{"id":41101779,"uuid":"463833886","full_name":"marcinrek/loco-server","owner":"marcinrek","description":"HTTP Proxy and/or mockup server","archived":false,"fork":false,"pushed_at":"2023-11-22T12:51:32.000Z","size":192,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-07-09T13:30:53.941Z","etag":null,"topics":["express","mockup","proxy","server"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marcinrek.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2022-02-26T11:28:24.000Z","updated_at":"2022-02-26T12:16:28.000Z","dependencies_parsed_at":"2024-11-18T23:36:48.352Z","dependency_job_id":"31376f1a-eafd-4b9b-93d5-442b14303723","html_url":"https://github.com/marcinrek/loco-server","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcinrek%2Floco-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcinrek%2Floco-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcinrek%2Floco-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcinrek%2Floco-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marcinrek","download_url":"https://codeload.github.com/marcinrek/loco-server/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245031516,"owners_count":20549926,"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","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":["express","mockup","proxy","server"],"created_at":"2024-11-29T15:24:49.753Z","updated_at":"2026-02-23T23:11:24.024Z","avatar_url":"https://github.com/marcinrek.png","language":"JavaScript","funding_links":["https://www.paypal.com/donate?hosted_button_id=ZPSPDRNU99V4Y"],"categories":[],"sub_categories":[],"readme":"# Loco\nLoco is a http proxy and/or mockup server.\n\n## Features\n* forward a request using node-fetch\n* mock API response\n* supports using .env variables\n\n## Changelog\n- 4.0.3\n    - function files can now have .js or .cjs extenstion\n- 4.0.2\n    - fix typo in docs\n- 4.0.0\n    - add an option to load functions on each request so that it is not required to reload the app on a function file change/add/remove. It does require updating the config by adding reloadOnRequest key and setting it to true\n    - change require node version to v18.16.0\n- 3.2.0\n    - make PUT,PATCH and DELETE requests available\n    - support wildcard requests like /{function_name}/{id}/{something} - /{id}/{something} will be available as an array [\\{id\\}, \\{something\\}] in param.paths\n- 3.1.0\n    - add multer middleware for multipart/form-data support\n- 3.0.0\n    - change process function to only have one parameter now called 'param'.\n    - change config _functionsPath_ to be an array of glob entries instead of just one\n- 2.0.0\n    - add live reload for function files\n    - additional loco helper - loco.requireUncached('path');\n    - additional loco helper - loco.chalk;\n    - config _functionsDir_ replace with _functionsPath_ which is a glob\n- 1.1.1\n    - fix loco.corsHeaders() error when no headersOverwrites provided\n- 1.1.0\n    - pass reqMethod to processFunction to distinguish type of request if required\n    - add OPTIONS request support\n    - enable ovewriting headers in loco.corsHeaders() helper\n\n## Installation\n```\nnpm install -sD loco-server\n```\n\n## Usage\nStraight from the command line:\n```\nnpx loco \u003cconfig_file\u003e\n```\nor if used in package.json scripts:\n```\nloco \u003cconfig_file\u003e\n```\n\n## Configuration\nSample config file:\n```\n{\n  \"appPort\": 8888,\n  \"appHost\": \"127.0.0.1\",\n  \"functionsPath\": [\"loco_functions/*.js\"],\n  \"envFile\": \".env\",\n  \"reloadOnRequest\": true,\n  \"optionsRequestHeaders\": {\n    \"Access-Control-Allow-Origin\": \"*\",\n    \"Access-Control-Allow-Methods\": \"GET, POST, OPTIONS\",\n    \"Access-Control-Allow-Headers\": \"*\"\n  },\n  \"optionsRequestStatusCode\": 200\n}\n```\n\n| Field | Description |\n|---|---|\n| appPort | Port to run the server on |\n| appHost | Host to run the server on |\n| functionsPath | Glob to where to look for loco functions |\n| envFile | .env file name with path |\n| reloadOnRequest | Flag should funtions be reload on each request which will function as live-reload |\n| optionsRequestHeaders | Response headers for OPTIONS request |\n| optionsRequestStatusCode | OPTIONS request status code |\n\n## Functions\nFunctions are understood as JS files specified by _functionsPath_ in the configuration. Each file will be served under a separate webpath in the server. This webpath is equal to the file namie without _.js_ extension.\n\nFunction file scaffold:\n```\n/**\n * Function description string\n */\nconst description = 'Blank function scaffold.';\n\n/**\n * Main process function\n * @param {object} param.req entire request object\n * @param {object} param.query GET request query\n * @param {object} param.bodyJSON POST request body\n * @param {string} param.reqMethod request method\n * @param {object} param.loco helper functions object\n * @param {object} param.envVars environment variables\n * @param {array} param.paths array of wildcard paths\n * @returns {object} response object consisting of response statusCode, body and headers object\n */\nconst processFunction = async (param) =\u003e {\n    return {\n        statusCode: 200,\n        headers: param.loco.corsHeaders(),\n        body: {mockup: true}\n    };\n};\n\n// Export\nmodule.exports = {\n    processFunction,\n    description,\n};\n\n```\n\nThe _descriptions_ const is used for providing a short summary of a given function.\nMain required function in each function file is the _processFunction_.\nIt has one parameter called param which is an object containing:\n| Argument | Descriptions |\n|---|---|\n| req | full express request object |\n| query | GET query requested represented as JSON, example:  ```{\"query\":\"test\"}``` |\n| bodyJSON | POST body requested as as JSON, example: ```{\"login\":\"john\"}``` |\n| reqMethod | Request method as a string, example: ```GET```|\n| loco | object containing predefined helper function, described below in the function helpers section|\n| envVars | environment variables from the .env file defined in the config |\n| paths | array of paths that were used when this is a wildcard request |\n\nThe function must return an object with a given structure:\n```\n{\n    statusCode: 200,\n    headers: param.loco.corsHeaders(),\n    body: {mockup: true}\n}\n```\n| Key| Value |\n|---|---|\n| statusCode | response status code |\n| headers | object containig response header as key and header value as value |\n| body | response body |\n\n## Function helpers\nCurrent list of helpers passed as a _param.loco_ argument to the _processFunction_\n* ```param.loco.fetchJSON(url:string, options:object)``` - node-fetch module\n* ```param.loco.returnJsonWithDelay(sec, jsonResponse)``` - usefull when a mocked response is return to fake a time delay. Example usage:\n```\nreturn {\n    [...]\n    body: await loco.returnJsonWithDelay(3, jsonData),\n};\n```\nthis will return _jsonData_ after 3 seconds.\n* ```loco.corsHeaders(headersOverwrites)``` - returns headers that can be used when you want to enable cors:\n```\n{\n    'Content-Type': 'application/json; charset=utf-8',\n    'Access-Control-Allow-Origin': '*',\n    'Access-Control-Allow-Headers': 'Content-type',\n    'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',\n}\n```\nExample usage:\n```\nreturn {\n    [...]\n    headers: param.loco.corsHeaders(),\n    [...]\n};\n```\nYou can also overwrite a default header or add a new one:\n```\nheaders: param.loco.corsHeaders({\"Content-Type\": \"text/html; charset=utf-8\"}),\n```\n* ```loco.fetchJSON(url:string, options:object)``` - utility function to make a fetch request to an endpoint that returns JSON response. Example usage:\n```\nconst jsonData = await param.loco.fetchJSON('https://api.url/', {\n    method: \"PATCH\",\n    headers: {\n        \"Content-Type\": \"application/json\",\n    },\n    body: JSON.stringify(param.bodyJSON.payload)\n}).catch((err) =\u003e {\n    return {error: err.message};\n});\n[...]\nreturn {\n    [...]\n    body: jsonData,\n};\n```\n* ```param.loco.requireUncached(path)``` - clear cache for _path_ and then require. Usefull when you modify data in processFunction often.\n\n## Donate\nIf you find this piece of code to be useful, please consider a donation :)\n\n[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/donate?hosted_button_id=ZPSPDRNU99V4Y)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcinrek%2Floco-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarcinrek%2Floco-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcinrek%2Floco-server/lists"}