{"id":20025376,"url":"https://github.com/alissonperez/deepicker","last_synced_at":"2025-05-05T02:31:07.911Z","repository":{"id":29143388,"uuid":"111739435","full_name":"alissonperez/deepicker","owner":"alissonperez","description":"🔪 A tiny library inspired in GraphQL but much more simple","archived":false,"fork":false,"pushed_at":"2023-03-01T14:56:58.000Z","size":597,"stargazers_count":16,"open_issues_count":14,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-05-01T11:11:32.715Z","etag":null,"topics":["js","json","mask","node","node-js","picker","picker-library"],"latest_commit_sha":null,"homepage":"https://alissonperez.github.io/deepicker/","language":"JavaScript","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/alissonperez.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","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}},"created_at":"2017-11-22T22:42:40.000Z","updated_at":"2022-05-24T20:13:25.000Z","dependencies_parsed_at":"2024-11-13T08:55:23.917Z","dependency_job_id":"ae4265b8-6802-42be-8a8c-bb5590ff3b28","html_url":"https://github.com/alissonperez/deepicker","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alissonperez%2Fdeepicker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alissonperez%2Fdeepicker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alissonperez%2Fdeepicker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alissonperez%2Fdeepicker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alissonperez","download_url":"https://codeload.github.com/alissonperez/deepicker/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252427778,"owners_count":21746270,"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":["js","json","mask","node","node-js","picker","picker-library"],"created_at":"2024-11-13T08:55:19.518Z","updated_at":"2025-05-05T02:31:07.459Z","avatar_url":"https://github.com/alissonperez.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![](https://github.com/alissonperez/deepicker/Build/badge.svg) ![](https://github.com/alissonperez/deepicker/Version%20tagged/badge.svg)\n\nDeepicker\n=============\n\nA tiny library inspired in GraphQL but much **more simple without buracratic things and large libraries** for clients and servers!\n\nFeatures:\n\n- Simple implementation.\n- Increases performance processing only what client asks for.\n- Non-blocking processing, it handles promisses in parallel very well.\n- Simple usage by clients. Just receive an `include` and `exclude` querystring and send them to Deepicker.\n- No worries about dependencies, Deepicker is pure JS implementation.\n\n### Installation\n\nNode support: **8+**\n\n```bash\n$ npm i --save deepicker\n```\n\nor, if you prefer `yarn`:\n\n```bash\n$ yarn add deepicker\n```\n\n### Usage\n\n#### Quickstart example\n\nLet's see a very simple example to warmup:\n\n```javascript\nconst deepicker = require('deepicker')\n\n// My object with a simple structure (for now!)\nconst myObject = {\n    title: 'Star Wars: Episode V - The Empire Strikes Back',\n    episodeNumber: '5',\n    releaseYear: 1980,\n    characters: [\n        { name: 'Luke Skywalker', actor: 'Mark Hamill' },\n        { name: 'Han Solo', actor: 'Harrison Ford' },\n        { name: 'Princess Leia Organa', actor: 'Carrie Fischer' },\n        { name: 'Darth Vader', actor: 'James Earl Jones' },\n        // ...\n    ],\n    description: 'Fleeing the evil Galactic Empire, the Rebels abandon...',\n}\n\n// Include/exclude string, you can receive then in a request querystring, for example\nconst include = 'title,description,characters'\nconst exclude = 'characters.actor'\n\n// Create our picker object\nconst picker = deepicker.simplePicker(include, exclude)\n\n// Let's process our object, picker will pick only especified fields deeply.\nconsole.log(picker.pick(myObject))\n```\n\nAs a result:\n\n```json\n{\n    \"title\":\"Star Wars: Episode V - The Empire Strikes Back\",\n    \"description\":\"Fleeing the evil Galactic Empire, the Rebels abandon...\",\n    \"characters\":[\n        { \"name\":\"Luke Skywalker\" },\n        { \"name\":\"Han Solo\" },\n        { \"name\":\"Princess Leia Organa\" },\n        { \"name\":\"Darth Vader\" }\n    ]\n}\n```\n\n\n#### Using nested functions\n\nBut we know, unfortunatelly, real life \"usually\" is not so simple. Thinking about it, Deepicker is able to handle a lot of data types inside our objects, like arrays, promises, functions... etc. And with this last data type is where Deepicker really shines and show its power! =)\n\nLet's see a more complex example using functions:\n\n```javascript\nconst deepicker = require('deepicker')\n\nconst myObject = {\n    title: 'Star Wars: Episode V - The Empire Strikes Back',\n    description: 'Fleeing the evil Galactic Empire, the Rebels abandon...',\n    releaseYear: 1980,\n\n    // Here, using a function to computate our 'nextMovie' key content (pay attention to \"picker\" arg)\n    nextMovie: function(picker) {\n        const movie = {\n            title: 'Star Wars: Episode IV - A New Hope)',\n            description: 'The galaxy is in the midst of a civil war. Spies for the Rebel Alliance have stolen plans...',\n            releaseYear: 1977\n        }\n\n        // Pay attention here, picker instance is with 'nextMovie' context,\n        // so, when we call \"pick\" method it knows exactly what needs to cut out\n        // or not.\n        return picker.pick(movie)\n    },\n\n    previousMovie: function(picker) {\n        const movie = {\n            title: 'Star Wars: Episode VI - Return of the Jedi',\n            description: 'The Galactic Empire, under the direction of the ruthless Emperor...',\n            releaseYear: 1983\n        }\n\n        return picker.pick(movie)\n    }\n}\n\n// Now, we add \"nextMovie\" in our include fields and exclude \"releaseYear\" from \"nextMovie\".\nconst include = 'title,description,nextMovie'\nconst exclude = 'nextMovie.releaseYear'\n\n// Create our picker object\nconst picker = deepicker.simplePicker(include, exclude)\n\n// Let's pick!\nconsole.log(picker.pick(myObject))\n```\n\nAnd we have the following as result:\n\n```json\n{\n    \"title\":\"Star Wars: Episode V - The Empire Strikes Back\",\n    \"description\":\"Fleeing the evil Galactic Empire, the Rebels abandon...\",\n    \"nextMovie\":{\n        \"title\":\"Star Wars: Episode IV - A New Hope)\",\n        \"description\":\"The galaxy is in the midst of a civil war. Spies for the Rebel Alliance have stolen plans...\"\n    }\n}\n```\n\nOk, what happened?!\n\nFirst of all, we didn't ask for \"previousMovie\", so deepicker don't evaluate this function. In this example this don't affect performance, but thinking about an operation like access to a database to get something or call some API this can increase performance significantly. The main gain here is **we process only what client asks for**.\n\nOther thing, pay attention to `picker` arg received in our functions. This picker instance is with correct context, in this example, with `releaseYear` in exclude option. This is very important to pick content inside these functions and, as you can imagine, we can the same `pick` operation nested:\n\n\n```javascript\nnextMovie: function(picker) {\n    const movie = {\n        title: 'Star Wars: Episode IV - A New Hope)',\n        description: 'The galaxy is in the midst of a civil war. Spies for the Rebel Alliance have stolen plans...',\n        releaseYear: 1977,\n\n        // Using a function to compute otherInfo about Episode IV\n        otherInfo: function(picker) {\n            // Perform somethig here to get movie info and return then\n\n            return picker.pick({\n                directedBy: \"George Lucas\",\n                producedBy: \"Gary Kurtz\",\n                writtenBy: \"George Lucas\"\n            })\n        }\n    }\n\n    return picker.pick(movie)\n},\n```\n\nIn this example, we can use `nextMovie.otherInfo.directedBy` in our `include` option to get only \"George Lucas\" name and exclude the other info. Or, `otherInfo` function even is called with `include` only with `nextMovie.releaseYear`.\n\n#### Using promises\n\nAll we know that using JS is use asyncronous code, a library in node with no support for that is useless. So, Deepicker has a very good support to use Promises, lets take a look in an example:\n\n```javascript\nconst deepicker = require('deepicker')\n\nconst myObject = {\n    // First, we can have promises direct associated with our keys\n    // Deepicker will \"resolve\" it for us\n    title: Promise.resolve('Star Wars: Episode V - The Empire Strikes Back'),\n\n    description: 'Fleeing the evil Galactic Empire, the Rebels abandon...',\n    releaseYear: 1980,\n\n    // Our function to calculate next movie\n    nextMovie: function(picker) {\n        // Let's think we need to get next movie from an API, so we'll need an asyncronous request\n        return new Promise((resolve, reject) =\u003e {\n            // ... calling some API here\n\n            const movie = {\n                title: 'Star Wars: Episode IV - A New Hope)',\n                description: 'The galaxy is in the midst of a civil war. Spies for the Rebel Alliance have stolen plans...',\n                releaseYear: 1977\n            }\n\n            resolve(picker.pick(movie))\n        })\n    },\n\n    // Our function to calculate previous movie\n    previousMovie: function(picker) {\n        // Let's think we need to get next movie from an API, so we'll need an asyncronous request\n        return new Promise((resolve, reject) =\u003e {\n            // ... calling some API here\n\n            const movie = {\n                title: 'Star Wars: Episode VI - Return of the Jedi',\n                description: 'The Galactic Empire, under the direction of the ruthless Emperor...',\n                releaseYear: 1983\n            }\n\n            resolve(picker.pick(movie))\n        })\n    }\n}\n\n// Our include / exclude as usually\nconst include = 'title,description,nextMovie'\nconst exclude = 'nextMovie.releaseYear'\n\nconst picker = deepicker.simplePicker(include, exclude)\n\n// To handle with promises in our object, we need to use 'pickPromise' method\npicker.pickPromise(myObject).then(result =\u003e {\n    console.log(result)\n})\n```\n\nAs result:\n\n```\n{\n    \"title\":\"Star Wars: Episode V - The Empire Strikes Back\",\n    \"description\":\"Fleeing the evil Galactic Empire, the Rebels abandon...\",\n    \"nextMovie\":{\n        \"title\":\"Star Wars: Episode IV - A New Hope)\",\n        \"description\":\"The galaxy is in the midst of a civil war. Spies for the Rebel Alliance have stolen plans...\"\n    }\n}\n```\n\n### Reference\n\n#### Constructor\n\nBuilding our picker is the first step to use it. Each constructors available uses one kind of include and exclude string.\n\n##### deepicker.simplePicker([includeStr], [excludeStr])\n\nThis option handles simple include and exclude string, e.g.:\n\n```javascript\nconst include = 'title,description,nextMovie'\nconst exclude = 'nextMovie.releaseYear'\n\nconst picker = deepicker.simplePicker(include, exclude)\n```\n\nAs you see, our `include` and `exclude` vars are simple strings with fields separated by `,` and using `.` to going into objects. Always consider root element to build this string.\n\n##### deepicker.xpathPicker([includeStr], [excludeStr])\n\nThis option handle include and exclude string with a \"xpath like\" format, e.g.:\n\n```javascript\nconst include = 'nextMovie/releaseYear,characters(name,actor)'\nconst exclude = 'previousMovie/characters/name'\n\nconst picker = deepicker.xpathPicker(include, exclude)\n```\n\nAs you see, it uses `/` to going deep into fields object and `,` to separate options. The great advantage to use this way is to save \"bytes\" with complex objects. In our example, using `characters(name,actor)` we instruct picker to get `name` and `actor` fields inside `characters` key. In other example, we can do something like this: `nextMovie/characters/bornDate(month,year)` to get just `month` and `year` of `bornDate` object inside `characters` from `nextMovie`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falissonperez%2Fdeepicker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falissonperez%2Fdeepicker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falissonperez%2Fdeepicker/lists"}