{"_id":"@carlosjimenohernandez/restomatic","_rev":"6-a80d66d67a95593b3931946d4f368c3f","name":"@carlosjimenohernandez/restomatic","dist-tags":{"latest":"1.0.5"},"versions":{"1.0.0":{"name":"@carlosjimenohernandez/restomatic","version":"1.0.0","keywords":[],"author":{"name":"carlosjimenohernandez"},"license":"WTFPL","_id":"@carlosjimenohernandez/restomatic@1.0.0","maintainers":[{"name":"carlosjimenohernandez","email":"jimenohernandezcarlos@gmail.com"}],"bin":{"restomatic":"restomatic.js"},"dist":{"shasum":"2855617390fee94ab79d4600ed229e340afc2abd","tarball":"https://registry.npmjs.org/@carlosjimenohernandez/restomatic/-/restomatic-1.0.0.tgz","fileCount":31,"integrity":"sha512-EMC+1SKpuW5/u8hQu23Im7c/mJCa82fEsYD5JeQpW1MWKnjjDFVT7iYtLBYgX1sP2u34vZ7ZMsPzVeDOXwi/uw==","signatures":[{"sig":"MEUCIQDCg6WcPpETXvrBeGhDePSgjmK7fLtCGF4kd19PFbnNhwIgLFkTN41QSxsFzY3xsid6r/8zEwcq6ODAi1bY5mfFDp8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":39022},"main":"restomatic.js","gitHead":"2a8d84f5b4df82b35c6181f1ba378f147f7a2052","scripts":{"dev":"npx nodemon -w src -e 'js' -x 'node build.js'","test":"echo 'no test yet'","build":"node build.js"},"_npmUser":{"name":"carlosjimenohernandez","email":"jimenohernandezcarlos@gmail.com"},"_npmVersion":"9.6.7","description":"Set up REST automatically","directories":{},"_nodeVersion":"18.17.1","dependencies":{"multer":"^2.0.2","express":"^5.1.0","sqlstring":"^2.3.3","body-parser":"^2.2.0","better-sqlite3":"^12.2.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/restomatic_1.0.0_1756651613466_0.4162360402721672","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@carlosjimenohernandez/restomatic","version":"1.0.1","keywords":[],"author":{"name":"carlosjimenohernandez"},"license":"WTFPL","_id":"@carlosjimenohernandez/restomatic@1.0.1","maintainers":[{"name":"carlosjimenohernandez","email":"jimenohernandezcarlos@gmail.com"}],"bin":{"restomatic":"restomatic.js"},"dist":{"shasum":"dc5a2e0dbf76b7acd35af9e5ec63ae4dc1cc7ba9","tarball":"https://registry.npmjs.org/@carlosjimenohernandez/restomatic/-/restomatic-1.0.1.tgz","fileCount":35,"integrity":"sha512-pd8xEqpz58AGMmoywtrjJHw4VLcPf3Yox+aSRgRfD82YnJpNAjSTFhrlawZXwH9REtwRDcqAKMs/M3mWS/c8mQ==","signatures":[{"sig":"MEYCIQCU570ugSwP5cNDH0Bw5H6pp67RYu87uMImz75WK2mo1QIhAOewAMUX0ihZHkp6GF2xitBSGrjMLhPZtyfD2Kg11EPr","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":346446},"main":"restomatic.js","gitHead":"7d2c0d394ad76a0f57f88518fbb4abf1512805e7","scripts":{"dev":"npx nodemon -w src -e 'js' -x 'node build.js'","test":"echo 'no test yet'","build":"node build.js"},"_npmUser":{"name":"carlosjimenohernandez","email":"jimenohernandezcarlos@gmail.com"},"_npmVersion":"9.6.7","description":"Set up REST automatically","directories":{},"_nodeVersion":"18.17.1","dependencies":{"ejs":"^3.1.10","multer":"^2.0.2","express":"^5.1.0","sqlstring":"^2.3.3","body-parser":"^2.2.0","better-sqlite3":"^12.2.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/restomatic_1.0.1_1756665311548_0.7194319781915957","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@carlosjimenohernandez/restomatic","version":"1.0.2","keywords":[],"author":{"name":"carlosjimenohernandez"},"license":"WTFPL","_id":"@carlosjimenohernandez/restomatic@1.0.2","maintainers":[{"name":"carlosjimenohernandez","email":"jimenohernandezcarlos@gmail.com"}],"bin":{"restomatic":"restomatic.bin.js"},"dist":{"shasum":"cdc4de95b3d9294e3dc3bc1be3334b9cf9692fd6","tarball":"https://registry.npmjs.org/@carlosjimenohernandez/restomatic/-/restomatic-1.0.2.tgz","fileCount":55,"integrity":"sha512-4ddEg8R1I0IJgx44xP4+22rKUrEXvRfRJuCpFKYpgGYtiTu+Knmp+pjwGVSnbju/E7KIOLpGPGdUbg5Y9ShPRA==","signatures":[{"sig":"MEQCIGFb9KFf6g7xsJJs/hRzaNgtY0gFzZNvYKpUoCWbnO6+AiA4WmHbIlTaAZPEfoTR9i4l0v2t9BZAQ20ppbLHf7eOxQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":529083},"main":"restomatic.js","gitHead":"ecd7d475890faeda0c32d2add26d3da0dd6929e2","scripts":{"dev":"npx nodemon -w src -e 'js' -x 'node build.js'","test":"echo 'no test yet'","build":"node build.js"},"_npmUser":{"name":"carlosjimenohernandez","email":"jimenohernandezcarlos@gmail.com"},"_npmVersion":"9.6.7","description":"Set up REST automatically","directories":{},"_nodeVersion":"18.17.1","dependencies":{"ejs":"^3.1.10","multer":"^2.0.2","express":"^5.1.0","sqlstring":"^2.3.3","body-parser":"^2.2.0","better-sqlite3":"^12.2.0"},"_hasShrinkwrap":false,"devDependencies":{"form-data":"^4.0.4","node-fetch":"^3.3.2"},"_npmOperationalInternal":{"tmp":"tmp/restomatic_1.0.2_1756733552885_0.7559102905317905","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@carlosjimenohernandez/restomatic","version":"1.0.3","keywords":[],"author":{"name":"carlosjimenohernandez"},"license":"WTFPL","_id":"@carlosjimenohernandez/restomatic@1.0.3","maintainers":[{"name":"carlosjimenohernandez","email":"jimenohernandezcarlos@gmail.com"}],"bin":{"restomatic":"restomatic.bin.js"},"dist":{"shasum":"fad25bd5d5276adcc31aba3bf2c3c13a5b629616","tarball":"https://registry.npmjs.org/@carlosjimenohernandez/restomatic/-/restomatic-1.0.3.tgz","fileCount":55,"integrity":"sha512-/PzojqLLCiHR9msY8CSLSisRF8ZP0WoKQu09TSy8jxp7xmeFNSbuGOen9q6JjeQQG6i8rG7MXaXKHz1jj5rDoQ==","signatures":[{"sig":"MEQCIHkGDG/so3FnlMk8m3jidP0O5cRu0qXDT8LxJw9+i8AAAiAUD+Jw383+lqnMlRC5ZSVgZjzxWvXMRLt+LjaTcdUMrw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":529879},"main":"restomatic.js","gitHead":"dfeffaed08f4aa89130ab662fbf5c36cc433c1df","scripts":{"dev":"npx nodemon -w src -e 'js' -x 'node build.js'","test":"echo 'no test yet'","build":"node build.js"},"_npmUser":{"name":"carlosjimenohernandez","email":"jimenohernandezcarlos@gmail.com"},"_npmVersion":"9.6.7","description":"Set up REST automatically","directories":{},"_nodeVersion":"18.17.1","dependencies":{"ejs":"^3.1.10","multer":"^2.0.2","express":"^5.1.0","sqlstring":"^2.3.3","body-parser":"^2.2.0","better-sqlite3":"^12.2.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/restomatic_1.0.3_1756733903088_0.7341534874040949","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@carlosjimenohernandez/restomatic","version":"1.0.4","keywords":[],"author":{"name":"carlosjimenohernandez"},"license":"WTFPL","_id":"@carlosjimenohernandez/restomatic@1.0.4","maintainers":[{"name":"carlosjimenohernandez","email":"jimenohernandezcarlos@gmail.com"}],"bin":{"restomatic":"restomatic.bin.js"},"dist":{"shasum":"f26a91d5a700bcb361ac0879d3f4bd02b5c80f0e","tarball":"https://registry.npmjs.org/@carlosjimenohernandez/restomatic/-/restomatic-1.0.4.tgz","fileCount":56,"integrity":"sha512-5TTT9j47rbJJhZkBW/+00rc1D9XCgxq0pApfT8xkcJBcup9ua1WgIUlwihp9hzfxLIquUaHKoPVhK2IV/legug==","signatures":[{"sig":"MEQCIDU1A9ixEC6387cY3SROfSvV9lsW3Fe4vkt3AERuvgHUAiBdnbdfz7a6xqwA349tDXDY5PWyCTBgLn5fcSGYQEOrsg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":530740},"main":"restomatic.js","gitHead":"fa89664f9e1102ad4b113bb895290dae90be497a","scripts":{"dev":"npx nodemon -w src -e 'js' -x 'node build.js'","test":"echo 'no test yet'","build":"node build.js"},"_npmUser":{"name":"carlosjimenohernandez","email":"jimenohernandezcarlos@gmail.com"},"_npmVersion":"9.6.7","description":"Set up REST automatically","directories":{},"_nodeVersion":"18.17.1","dependencies":{"ejs":"^3.1.10","multer":"^2.0.2","express":"^5.1.0","sqlstring":"^2.3.3","body-parser":"^2.2.0","better-sqlite3":"^12.2.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/restomatic_1.0.4_1756886373486_0.3875624048929649","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@carlosjimenohernandez/restomatic","version":"1.0.5","description":"Set up REST automatically","main":"restomatic.js","bin":{"restomatic":"restomatic.bin.js"},"scripts":{"dev":"npx nodemon -w src -e 'js' -x 'node build.js'","build":"node build.js","test":"echo 'no test yet'"},"keywords":[],"author":{"name":"carlosjimenohernandez"},"license":"WTFPL","dependencies":{"better-sqlite3":"^12.2.0","body-parser":"^2.2.0","ejs":"^3.1.10","express":"^5.1.0","multer":"^2.0.2","sqlstring":"^2.3.3"},"gitHead":"fb6a2c949af82504c829ff35b676f08d61d30420","_id":"@carlosjimenohernandez/restomatic@1.0.5","_nodeVersion":"18.17.1","_npmVersion":"9.6.7","dist":{"integrity":"sha512-cG492EVBRfH7J/ZLdYlCH877fxUFNKRFDEi3xipNfKaWbGu3q8xMhLY/C55jUl9OsgQxosveXGCaiJuPr+FM2g==","shasum":"dad34299959fbe054e12fa7e77c4a8c9bbb35da4","tarball":"https://registry.npmjs.org/@carlosjimenohernandez/restomatic/-/restomatic-1.0.5.tgz","fileCount":63,"unpackedSize":551951,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDqWRvGZgh0pfiEPf8Ut83u6fu/5Z+NyxDILAmJHF3LdgIhAL2PefCVF4aU4fqzRYHjxjORhYuBUBrcehaJYUa2ZPQm"}]},"_npmUser":{"name":"carlosjimenohernandez","email":"jimenohernandezcarlos@gmail.com"},"directories":{},"maintainers":[{"name":"carlosjimenohernandez","email":"jimenohernandezcarlos@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/restomatic_1.0.5_1756996106911_0.8437372284400633"},"_hasShrinkwrap":false}},"time":{"created":"2025-08-31T14:46:53.341Z","modified":"2025-09-04T14:28:27.285Z","1.0.0":"2025-08-31T14:46:53.652Z","1.0.1":"2025-08-31T18:35:11.719Z","1.0.2":"2025-09-01T13:32:33.068Z","1.0.3":"2025-09-01T13:38:23.272Z","1.0.4":"2025-09-03T07:59:33.674Z","1.0.5":"2025-09-04T14:28:27.089Z"},"author":{"name":"carlosjimenohernandez"},"license":"WTFPL","keywords":[],"description":"Set up REST automatically","maintainers":[{"name":"carlosjimenohernandez","email":"jimenohernandezcarlos@gmail.com"}],"readme":"# restomatic\n\nAutomatic REST on top of Node.js + SQLite + Express.\n\n## Installation\n\n```sh\nnpm i -g @carlosjimenohernandez/restomatic\n```\n\n## Features\n\n- REST operations:\n   - select: at `/api/v1/data/select`\n   - insert: at `/api/v1/data/insert?token=admin`\n   - update: at `/api/v1/data/update?token=admin`\n   - delete: at `/api/v1/data/delete?token=admin`\n   - createTable: at `/api/v1/data/createTable?token=admin`\n   - createColumn: at `/api/v1/data/createColumn?token=admin`\n   - removeTable: at `/api/v1/data/removeTable?token=admin`\n   - removeColumn: at `/api/v1/data/removeColumn?token=admin`\n   - setFile: at `/api/v1/data/setFile?token=admin`\n- Static files: `/static/...`\n   - to load js, css, images, etc.\n- Dynamic templates: `/template/...`\n   - to load custom [`ejs`](https://github.com/mde/ejs)-rendered content.\n- Filesystem operations:\n   - readDirectory: at `/api/v1/filesystem/readDirectory?token=admin`\n   - makeDirectory: at `/api/v1/filesystem/makeDirectory?token=admin`\n   - deleteDirectory: at `/api/v1/filesystem/deleteDirectory?token=admin`\n   - readFile: at `/api/v1/filesystem/readFile?token=admin`\n   - writeFile: at `/api/v1/filesystem/writeFile?token=admin`\n   - deleteFile: at `/api/v1/filesystem/deleteFile?token=admin`\n   - isFile: at `/api/v1/filesystem/isFile?token=admin`\n\n## Dependencies\n\nThis is part of the `package.json`:\n\n```json\n  \"dependencies\": {\n    \"better-sqlite3\": \"^12.2.0\",\n    \"body-parser\": \"^2.2.0\",\n    \"ejs\": \"^3.1.10\",\n    \"express\": \"^5.1.0\",\n    \"multer\": \"^2.0.2\",\n    \"sqlstring\": \"^2.3.3\"\n  }\n```\n\n## Usage\n\nYou have 2 options to run `restomatic`:\n\n  - From **command line**\n  - From **node.js script**\n\nBoth are explained below.\n\n### Usage from command line\n\nFrom command line you can:\n\n```sh\nnpx restomatic\n  --port \"9090\"             # Port to listen\n  --models \"models.js\"      # Models to import\n  --routes \"routes.js\"      # Routes to include beside defaults\n  --token \"admin\"           # Token for advanced operations\n  --database \"test.sqlite\"  # File for database\n```\n\n### Usage from node.js script\n\nFrom a node.js script you can:\n\n```js\nconst restomaticInstance = await require(\"@carlosjimenohernandez/restomatic\").create({\n    port: \"9090\",\n    models: \"models.js\",\n    routes: \"routes.js\",\n    token: \"admin\",\n    database: \"test.sqlite\",\n});\n```\n\n## Parameters\n\nThe previous calls overstand some meaningful parameters, which are explained below.\n\n### Parameter `port`\n\nYou specify the port number which must open the instance.\n\n### Parameter `token`\n\nThe `token` parameter is used to filter advanced operations that require permissions, like:\n  - `/api/v1/data/insert`\n  - `/api/v1/data/update`\n  - `/api/v1/data/delete`\n  - `/api/v1/data/createTable`\n  - `/api/v1/data/createColumn`\n  - `/api/v1/data/removeTable`\n  - `/api/v1/data/removeColumn`\n  - `/api/v1/filesystem/makeDirectory`\n  - `/api/v1/filesystem/readDirectory`\n  - `/api/v1/filesystem/deleteDirectory`\n  - `/api/v1/filesystem/writeFile`\n  - `/api/v1/filesystem/readFile`\n  - `/api/v1/filesystem/deleteFile`\n  - `/api/v1/filesystem/isFile`\n\nYou have to provide directly the string that can match the `token` parameter on the request, either by, in this order:\n  - `request.headers.token`\n  - `request.body.token`\n  - `request.query.token`\n\n### Parameter `database`\n\nYou specify the file that will be used (or created) as `sqlite` database.\n\n### Parameter `models`\n\nOn `models.js` you must have something like:\n\n```js\nmodule.exports = {\n  individuals: {\n    columns: {\n      nombre: { sql: \"VARCHAR(255) UNIQUE\", },\n      edad:   { sql: \"VARCHAR(255)\", },\n      tipo:   { sql: \"VARCHAR(255)\", },\n      padre:  { sql: \"INTEGER REFERENCES individuals(id)\" }\n    }\n  }\n};\n```\n\n### Parameter `routes`\n\nOn `routes.js` you will want to have something like:\n\n```js\nRestomatic.router.use(\"/path\", function(request, response) {\n    try {\n        return response.success({\n            message: \"Your message\",\n            note: \"This method is injected by «XXX.create-application.js»'\n        });\n    } catch(error) {\n        return response.success(new Error(\"This method is injected by «XXX.create-application.js» too\"));\n    }\n});\n```\n\nAnd a REST is set up for you automatically.\n\n## Operations\n\nThe following titles describe the common operations enabled by default on `/api/v1/data/{operation}` path of the application.\n\n  - **Schema** at `/api/v1/data/schema`\n  - **Select data** at `/api/v1/data/select`\n     - Parameter `from`: **String**\n        - with the name of the table\n     - Parameter `where`: **Array**\n        - with the conditions\n     - Parameter `order`: **Array**\n        - with the columns in order\n        - Can use `!` to reverse the order\n     - Parameter `page`: **Integer**\n        - with the page\n        - Starts on `1`\n     - Parameter `items`: **Integer**\n        - Defaults to `100`\n  - **Insert data** at `/api/v1/data/insert`\n     - Parameter `into`: **String**\n        - with the name of the table\n     - Parameter `values`: **Array | Object**\n        - with the values for the new object/s\n  - **Update data** at `/api/v1/data/update`\n     - Parameter `from`: **String**\n        - with the name of the table\n     - Parameter `where`: **Array**\n        - with the conditions\n     - Parameter `set`: **Object**\n        - with the new values\n  - **Delete data** at `/api/v1/data/delete`\n     - Parameter `from`: **String**\n        - with the name of the table\n     - Parameter `where`: **Array**\n        - with the conditions\n\nAlso, you can alter the schema by the following operations:\n\n  - **Create table** at `/api/v1/data/createTable`\n     - Parameter `table`: **String**\n        - with the name of the table\n     - Parameter `content`: **String**\n        - with the SQLite code of the table\n  - **Create column** at `/api/v1/data/createColumn`\n     - Parameter `table`: **String**\n        - with the name of the table\n     - Parameter `column`: **String**\n        - with the name of the column\n     - Parameter `content`: **String**\n        - with the SQLite code of the column\n  - **Remove table** at `/api/v1/data/removeTable`\n     - Parameter `table`: **String**\n        - with the name of the table\n  - **Remove column** at `/api/v1/data/removeColumn`\n     - Parameter `table`: **String**\n        - with the name of the table\n     - Parameter `column`: **String**\n        - with the name of the column\n  - **Set file** at `/api/v1/data/setFile`\n     - This operation requires `multipart/form-data` (see [`test/run.js`](./test/run.js))\n     - Parameter `file`: **Blob**\n        - with the contents of the file\n\nAlso, you can access and modify the filesystem (only `/static` and `/template` folders) by the following operations:\n\n  - **Read file** at `/api/v1/filesystem/readFile`\n     - Parameter `path`: **String**\n  - **Write file** at `/api/v1/filesystem/writeFile`\n     - Parameter `path`: **String**\n     - Parameter `content`: **String**\n  - **Delete file** at `/api/v1/filesystem/deleteFile`\n     - Parameter `path`: **String**\n  - **Read directory** at `/api/v1/filesystem/readDirectory`\n     - Parameter `path`: **String**\n  - **Make directory** at `/api/v1/filesystem/makeDirectory`\n     - Parameter `path`: **String**\n  - **Delete directory** at `/api/v1/filesystem/deleteDirectory`\n     - Parameter `path`: **String**\n  - **Is file** at `/api/v1/filesystem/isFile`\n     - Parameter `path`: **String**\n\n### Select data\n\nYou can select (**without** admin token):\n\n```js\nconst res = await fetch(\"http://127.0.0.1:9090/api/v1/data/select\", {\n    method: \"POST\",\n    headers: {\"Content-Type\": \"application/json\"},\n    body: JSON.stringify({\n        token: \"none\", // This is not required for select operations\n        from: \"individuals\",\n        where: [\n            [\"id\", \"is not null\"],\n            [\"id\", \"!=\", \"1000\"],\n            [\"id\", \">=\", \"1\"],\n            [\"id\", \">\", \"0\"],\n            [\"id\", \"<\", \"1000\"],\n            [\"id\", \"<=\", \"1000\"],\n            [\"id\", \"like\", \"%\"],\n            [\"id\", \"not like\", \"x%\"],\n            [\"id\", \"in\", [1,2,3]],\n            [\"id\", \"not in\", [4,5,6]],\n        ],\n        order: [\"!id\"]    // with ! for DESC [endant]\n        page: 1,          // defaults to 1\n        items: 100,       // defaults to 100\n    })\n});\nconsole.log(await res.json());\n```\n\n### Insert data\n\nOnce running, you can insert **with** admin token:\n\n```js\nconst res = await fetch(\"http://127.0.0.1:9090/api/v1/data/insert\", {\n    method: \"POST\",\n    headers: {\"Content-Type\": \"application/json\"},\n    body: JSON.stringify({\n        token: \"admin\", // This has to match with provided cmd token\n        into: \"individuals\",\n        values: [{\n            nombre: \"Carlos Jimeno Hernández\",\n            edad: 35\n        }, {\n            nombre: \"Ada Jimeno Hernández\",\n            edad: 9,\n        }, {\n            nombre: \"Gatito Jimeno Hernández\",\n            edad: 4,\n        }]\n    })\n});\nconsole.log(await res.json());\n```\n\n### Update data\n\nYou can update **with** admin token:\n\n```js\nconst res = await fetch(\"http://127.0.0.1:9090/api/v1/data/select\", {\n    method: \"POST\",\n    headers: {\"Content-Type\": \"application/json\"},\n    body: JSON.stringify({\n        token: \"admin\", // This has to match with provided cmd token\n        from: \"individuals\",\n        set: {\n            tipo: \"Familiar\"\n        },\n        where: [\n            [\"id\", \"is not null\"],\n            [\"id\", \"!=\", \"1000\"],\n            [\"id\", \">=\", \"1\"],\n            [\"id\", \">\", \"0\"],\n            [\"id\", \"<\", \"1000\"],\n            [\"id\", \"<=\", \"1000\"],\n            [\"id\", \"like\", \"%\"],\n            [\"id\", \"not like\", \"x%\"],\n            [\"id\", \"in\", [1,2,3]],\n            [\"id\", \"not in\", [4,5,6]],\n        ]\n    })\n});\nconsole.log(await res.json());\n```\n\n### Delete data\n\nYou can delete **with** admin token:\n\n```js\nconst res = await fetch(\"http://127.0.0.1:9090/api/v1/data/delete\", {\n    method: \"POST\",\n    headers: {\"Content-Type\": \"application/json\"},\n    body: JSON.stringify({\n        token: \"admin\", // This has to match with provided cmd token\n        from: \"individuals\",\n        where: [\n            [\"id\", \"is null\"],\n            [\"id\", \"!=\", \"1000\"],\n            [\"id\", \">=\", \"1\"],\n            [\"id\", \">\", \"0\"],\n            [\"id\", \"<\", \"1000\"],\n            [\"id\", \"<=\", \"1000\"],\n            [\"id\", \"like\", \"%\"],\n            [\"id\", \"not like\", \"x%\"],\n            [\"id\", \"in\", [1,2,3]],\n            [\"id\", \"not in\", [4,5,6]],\n        ]\n    })\n});\nconsole.log(await res.json());\n```\n\n### Create table\n\nFor example, using GET:\n\n`http://127.0.0.1:9090/api/v1/data/createTable?token=admin&table=lote`\n\nOr using POST:\n\n```js\nconst res = await fetch(\"http://127.0.0.1:9090/api/v1/data/createTable\", {\n    method: \"POST\",\n    headers: {\"Content-Type\": \"application/json\"},\n    body: JSON.stringify({\n        token: \"admin\", // This has to match with provided cmd token\n        table: \"lote\",\n        content: `\n            numero INTEGER UNIQUE NOT NULL,\n            contenedor INTEGER REFERENCES lote(id)\n        `\n    })\n});\nconsole.log(await res.json());\n```\n\n### Create column\n\nFor example:\n\n```js\nconst res = await fetch(\"http://127.0.0.1:9090/api/v1/data/createColumn\", {\n    method: \"POST\",\n    headers: {\"Content-Type\": \"application/json\"},\n    body: JSON.stringify({\n        token: \"admin\", // This has to match with provided cmd token\n        table: \"lote\",\n        column: \"identificador\",\n        content: `VARCHAR(255) NOT NULL`\n    })\n});\nconsole.log(await res.json());\n```\n\n### Remove table\n\nFor example:\n\n```js\nconst res = await fetch(\"http://127.0.0.1:9090/api/v1/data/removeTable\", {\n    method: \"POST\",\n    headers: {\"Content-Type\": \"application/json\"},\n    body: JSON.stringify({\n        token: \"admin\", // This has to match with provided cmd token\n        table: \"lote\",\n    })\n});\nconsole.log(await res.json());\n```\n\n### Remove column\n\nFor example:\n\n```js\nconst res = await fetch(\"http://127.0.0.1:9090/api/v1/data/removeTable\", {\n    method: \"POST\",\n    headers: {\"Content-Type\": \"application/json\"},\n    body: JSON.stringify({\n        token: \"admin\", // This has to match with provided cmd token\n        table: \"lote\",\n        column: \"identificador\",\n    })\n});\nconsole.log(await res.json());\n```\n\n## Other features\n\nBelow are listed other features the tool offers automatically.\n\n  - Static content\n  - Dynamic content\n  - Upload files\n\n### Static content\n\nYou can access the files under `src/static` by:\n\n`http://127.0.0.1/static/whatever.txt`\n\n### Dynamic content\n\nYou can access the files under `src/template` by:\n\n`http://127.0.0.1/static/whatever.ejs`\n\nThey will always be rendered as [`ejs`](https://github.com/mde/ejs) files.\n\nYou can access the following variables:\n   - `request`\n   - `response`\n   - `Restomatic`\n\nYou can use this snippet to force some mime-type when rendering and serving a file, and so, load `css` or `html` or any, but dynamically:\n\n```html\n<% response.type(\"html\") %>\n<% response.type(\"css\") %>\n<% response.type(\"js\") %>\n```\n\n### Upload files\n\nOnly admin can upload files, as it is a potentially conflictive behaviour.\n\nThe example run on `test/run.js` demonstrates how this can work without downloading libraries in node.js:\n\n```js\nconst fs = require(\"fs\");\nconst form = new FormData();\nconst fileBuffer = fs.readFileSync(__dirname + \"/example.txt\");\n\nform.append(\"file\", new Blob([fileBuffer]), \"example.txt\");\n\nconst r = await fetch(\"http://127.0.0.1:9090/api/v1/data/setFile\", {\n    method: \"POST\",\n    body: form,\n    headers: {\n        token: \"admin\"\n    }\n});\n\nconst response = await r.text();\n\nconsole.log(response);\n```\n\n## Filesystem operations\n\nOnly admin can commit filesystem operations, as they have potentially conflictive behaviours.\n\n### Make directory\n\nFor example:\n\n```js\nconst res = await fetch(\"http://127.0.0.1:9090/api/v1/filesystem/makeDirectory\", {\n    method: \"POST\",\n    headers: {\"Content-Type\": \"application/json\"},\n    body: JSON.stringify({\n        token: \"admin\", // This has to match with provided cmd token\n        path: \"/static/newdir\", // This has to start with /static or /template\n    })\n});\nconsole.log(await res.json());\n```\n\n### Read directory\n\nFor example:\n\n```js\nconst res = await fetch(\"http://127.0.0.1:9090/api/v1/filesystem/readDirectory\", {\n    method: \"POST\",\n    headers: {\"Content-Type\": \"application/json\"},\n    body: JSON.stringify({\n        token: \"admin\", // This has to match with provided cmd token\n        path: \"/static/newdir\", // This has to start with /static or /template\n    })\n});\nconsole.log(await res.json());\n```\n\n### Delete directory\n\nFor example:\n\n```js\nconst res = await fetch(\"http://127.0.0.1:9090/api/v1/filesystem/deleteDirectory\", {\n    method: \"POST\",\n    headers: {\"Content-Type\": \"application/json\"},\n    body: JSON.stringify({\n        token: \"admin\", // This has to match with provided cmd token\n        path: \"/static/newdir\", // This has to start with /static or /template\n    })\n});\nconsole.log(await res.json());\n```\n\n### Write file\n\nFor example:\n\n```js\nconst res = await fetch(\"http://127.0.0.1:9090/api/v1/filesystem/writeFile\", {\n    method: \"POST\",\n    headers: {\"Content-Type\": \"application/json\"},\n    body: JSON.stringify({\n        token: \"admin\", // This has to match with provided cmd token\n        path: \"/static/newdir/file1.txt\", // This has to start with /static or /template\n        content: \"Hello!\", \n    })\n});\nconsole.log(await res.json());\n```\n\n### Read file\n\nFor example:\n\n```js\nconst res = await fetch(\"http://127.0.0.1:9090/api/v1/filesystem/readFile\", {\n    method: \"POST\",\n    headers: {\"Content-Type\": \"application/json\"},\n    body: JSON.stringify({\n        token: \"admin\", // This has to match with provided cmd token\n        path: \"/static/newdir/file1.txt\", // This has to start with /static or /template\n    })\n});\nconsole.log(await res.json());\n```\n\n### Delete file\n\nFor example:\n\n```js\nconst res = await fetch(\"http://127.0.0.1:9090/api/v1/filesystem/deleteFile\", {\n    method: \"POST\",\n    headers: {\"Content-Type\": \"application/json\"},\n    body: JSON.stringify({\n        token: \"admin\", // This has to match with provided cmd token\n        path: \"/static/newdir/file1.txt\", // This has to start with /static or /template\n    })\n});\nconsole.log(await res.json());\n```\n\n### Is file?\n\nFor example:\n\n```js\nconst res = await fetch(\"http://127.0.0.1:9090/api/v1/filesystem/isFile\", {\n    method: \"POST\",\n    headers: {\"Content-Type\": \"application/json\"},\n    body: JSON.stringify({\n        token: \"admin\", // This has to match with provided cmd token\n        path: \"/static/jquery.js\", // This has to start with /static or /template\n    })\n});\nconsole.log(await res.json());\n```\n\n## Customize by your own\n\nThe `npm run build` command takes `bundlelist.js` exported files and dumps them in a all-in-one file called `restomatic.js`.\n\nBy this reason, all the files have its `__dirname` pointing on top of the project.\n\nUse it at your own convenience, the final file is quite short.","readmeFilename":"README.md"}