{"id":18084836,"url":"https://github.com/coderofsalvation/gexpress-middleware-restsheet","last_synced_at":"2025-04-12T20:09:50.129Z","repository":{"id":146965217,"uuid":"178372825","full_name":"coderofsalvation/Gexpress-middleware-RESTsheet","owner":"coderofsalvation","description":"Gexpress middleware to expose Gspreadsheet as REST endpoints in 4 lines of appscript","archived":false,"fork":false,"pushed_at":"2020-05-28T19:06:11.000Z","size":1099,"stargazers_count":55,"open_issues_count":2,"forks_count":9,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-12T20:09:42.966Z","etag":null,"topics":[],"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/coderofsalvation.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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},"funding":{"custom":"https://gumroad.com/l/hGYGh"}},"created_at":"2019-03-29T09:17:35.000Z","updated_at":"2025-03-09T01:57:21.000Z","dependencies_parsed_at":"2023-05-05T22:31:08.427Z","dependency_job_id":null,"html_url":"https://github.com/coderofsalvation/Gexpress-middleware-RESTsheet","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coderofsalvation%2FGexpress-middleware-RESTsheet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coderofsalvation%2FGexpress-middleware-RESTsheet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coderofsalvation%2FGexpress-middleware-RESTsheet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coderofsalvation%2FGexpress-middleware-RESTsheet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/coderofsalvation","download_url":"https://codeload.github.com/coderofsalvation/Gexpress-middleware-RESTsheet/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248625493,"owners_count":21135513,"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":[],"created_at":"2024-10-31T15:08:23.556Z","updated_at":"2025-04-12T20:09:50.101Z","avatar_url":"https://github.com/coderofsalvation.png","language":"JavaScript","funding_links":["https://gumroad.com/l/hGYGh"],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"https://github.com/coderofsalvation/Gexpress/raw/master/gexpress.png\"/\u003e\n\n[Gexpress](https://github.com/coderofsalvation/Gexpress) middleware to expose spreadsheet as REST endpoints\n\n## Usage\n\n```\nvar app      = new Gexpress.App() // see https://github.com/coderofsalvation/Gexpress\nvar sheet    = SpreadsheetApp.openById('1AImZywpGLsOWZafgyHUHBo')\nvar person   = GexpressTamotsu.middleware('/person', {sheet:sheet,tab:'persons'})\n\napp.use( person )\n```\n\n\u003e Voila! now the following urls are exposed:\n\n| url | will return |\n|-|-|\n|GET `https://{scripturl}/?path=/person`                     | all rows from 'persons'-sheettab             |\n|GET `https://{scripturl}/?path=/person/123`                 | get row with value '123' in column '#'        |\n|DELETE `https://{scripturl}/?path=/person/123\u0026method=DELETE`| remove row with value '123' in column '#'        |\n|POST `https://{scripturl}/?path=/person\u0026method=POST` {...}  | append (person) jsondata to 'persons'-sheettab |\n|PUT `https://{scripturl}/?path=/person/123\u0026method=PUT` {...}| update person '123' with jsondata            |\n\n## Install\n\n1. Include the __latest version__ of this library (`1u4tNXyogsenLfbzOYk7JCyxzgxvJSo2GtdmI3pfUKWtodYIyWMXQ89NX`) (see screenshot)\n2. Include [Gexpress](https://github.com/coderofsalvation/Gexpress) in similar fashion\n\n\u003ccenter\u003e\u003cimg src=\"include.gif\"/\u003e\u003c/center\u003e\n\nSetup the sheet:\n\n\u003ccenter\u003e\u003cimg src=\"sheet.gif\"/\u003e\u003c/center\u003e\n\n\u003e NOTE: make sure to format the '#'-column as 'plain text'. Also extract the sheet id from the url (https://docs.google.com/spreadsheets/d/{id}/edit#gid=0 and put it into the openById(..)-call.\n\n\u003e OPTIONAL: you can put json-strings in columns for nested data (it will be parsed automatically).\n\n## querying the sheet\n\n| query param | example | info |\n|-|-|-|\n| ?query=.. | {active:1} | mongodb-ish query to match candidates in sheet |\n| ?limit=.. | 4          | return max 4 results |\n| ?offset=.. | 0         | skip n items from result, for pagination purposes |\n| ?order=.. | 'date_modify DESC' | sort results on date_modify column |\n\n\u003e EXAMPLE: `https://{scripturl}/?path=/person\u0026limit=5\u0026offset=0\u0026order=[date_modify]\u0026query={\"active\":1}` \n\n## Generate JS Client (browser+node.js)\n\n[Gexpress](https://github.com/coderofsalvation/Gexpress) automatically generate a JS client, so here's how to extend it:\n\n```\n    app.get('/client.js', app.client(function(code){\n        return code + person.generateClientCode() \n      }) \n    )\n```\n\n\u003e Voila, now you can run the following in your __jquery/vue/react/whatever__-app after including `\u003cscript src=\"https://script.google.com/{SCRIPTID}/exec?path=/client.js\"\u003e\u003c/script\u003e` in your html:\n\n```\n    gclient.user.get('l2k3l').then( console.dir ).catch( console.error )\n    gclient.user.delete('l2k3l').then( console.dir ).catch( console.error )\n    gclient.user.put('l2k3l',{...data..}).then( console.dir ).catch( console.error )\n    gclient.user.post({...data..}).then( console.dir ).catch( console.error )\n\n    // the following assumes columns '#', 'date_created' and 'active' to exist in your spreadsheet\n    gclient.user.find({active:1},{offset:0,limit:10,order:['date_created']}).then( console.dir ).catch( console.error )\n```\n\n\n\n## Advanced usage\n\n\u003e NOTE: this middleware is based on [tamotsu](https://github.com/itmammoth/Tamotsu)\n                                                                          \n```                                                                       \n    var opts     = {\n      sheet:sheet,\n      tab:'foo',\n      query: {active:1},        // default 'where'-query\n      limit: 25,                // default limit on .all() results\n      order: ['date_modify']    // default order on .all() results\n    }        \n\n    opts.tamotsu = {    // generated output properties             \n      fullName: function() {   // for options see https://github.com/itmammoth/Tamotsu\n        return [this['First Name'], this['Last Name']].join(' ');\n      }\n    }\n\n    var person = GexpressTamotsu.middleware('/foo',opts )\n               \n    // lets hook into GET /person\n    person.get = function(req,res,handler){\n               \n      if( req.route == '/person/:id' ){  \n          var result = handler()\n          // to access sheetdata: handler.table.where({foo:12}).all()             \n          return result;\n      }                  \n                         \n      if( req.url == '/person' ){\n         var result = handler()\n         result.items = result.items.map( function(person){\n           var forbidden = ['email','phone']\n           forbidden.map(function(f){ delete person[f] })\n           return person\n         })        \n         return result\n       }else return handler()\n               \n    }             \n\n    app.use(person)\n```             \n\n## Mongoquery Support + multiple ordering\n\nThis would be a basic query:\n\n\u003e `https://{scripturl}/?path=/person\u0026limit=5\u0026offset=0\u0026order=[date_modify]\u0026query={\"active\":1}` \n\nWhich could be extended further like this:\n\n\u003e `https://{scripturl}/?path=/person\u0026limit=5\u0026offset=0\u0026order=['-date_modify','price']\u0026query={\"$or\":[{price:5},{name:\"foo\"}]}` \n\nAs you can see `['-date_modify','price']`: ordering can take place using an array of properties (the minus-sign flips between ASC/DESC).\n\n#### Query Comparison operators \n\n| | |\n|-|-|\n| Greater than| $gt |\n| Greater Equal than| $gte |\n| Less than| $lt |\n| Less Equal than| $lte |\n| Strict equality| $eq |\n| Strict inequality| $ne |\n\n\n#### Query Text matching operators\n\n| | |\n|-|-|\n| Like| $like |\n| Not like| $nlike |\n| RegExp| $regex |\n\n#### Query Subset operator\n\n| | |\n|-|-|\n| In| $in |\n| Not in| $nin |\n\n#### Query Logical operators\n\n| | |\n|-|-|\n| And| $and |\n| Or| $or |\n| Nor| $nor |\n| Not| $not |\n\n\u003e For detailed usage see [mongoqueries](https://docs.mongodb.com/manual/tutorial/query-documents/). To convert searchterms to mongoqueries see [human-search-mongoquery](https://www.npmjs.com/package/human-search-mongoquery)\n\n## Todo \n\n* ✓ GET /foo\n* ✓ GET /foo/:id\n* ✓ POST /foo\n* ✓ PUT /foo/:id\n* ✓ DELETE /foo/:id\n* ✓ support for 'query'-arg \n* ✓ support for 'limit'-arg \n* ✓ support for 'order'-arg \n* ✓ support for 'offset'-arg \n* ✓ automatically parse JSON in columns \n* ✓ added mongoquery support \n* ✓ added multiple orderby support \n* ◔ more tests\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoderofsalvation%2Fgexpress-middleware-restsheet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcoderofsalvation%2Fgexpress-middleware-restsheet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoderofsalvation%2Fgexpress-middleware-restsheet/lists"}