{"action":"created","issue":{"url":"https://api.github.com/repos/amzn/style-dictionary/issues/199","repository_url":"https://api.github.com/repos/amzn/style-dictionary","labels_url":"https://api.github.com/repos/amzn/style-dictionary/issues/199/labels{/name}","comments_url":"https://api.github.com/repos/amzn/style-dictionary/issues/199/comments","events_url":"https://api.github.com/repos/amzn/style-dictionary/issues/199/events","html_url":"https://github.com/amzn/style-dictionary/issues/199","id":381859841,"node_id":"MDU6SXNzdWUzODE4NTk4NDE=","number":199,"title":"Allow \"filter\" option in config file to support array of objects","user":{"login":"didoo","id":686239,"node_id":"MDQ6VXNlcjY4NjIzOQ==","avatar_url":"https://avatars1.githubusercontent.com/u/686239?v=4","gravatar_id":"","url":"https://api.github.com/users/didoo","html_url":"https://github.com/didoo","followers_url":"https://api.github.com/users/didoo/followers","following_url":"https://api.github.com/users/didoo/following{/other_user}","gists_url":"https://api.github.com/users/didoo/gists{/gist_id}","starred_url":"https://api.github.com/users/didoo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/didoo/subscriptions","organizations_url":"https://api.github.com/users/didoo/orgs","repos_url":"https://api.github.com/users/didoo/repos","events_url":"https://api.github.com/users/didoo/events{/privacy}","received_events_url":"https://api.github.com/users/didoo/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":7,"created_at":"2018-11-17T12:43:47Z","updated_at":"2018-11-24T09:43:05Z","closed_at":null,"author_association":"CONTRIBUTOR","body":"Calling in @elliotdickison here, since you worked on #101.\r\nIn the documentation we say that: \r\n\r\n>  platform.file.filter | Function/Object (optional) | A function or object used to filter the properties that will be included in the file. If a function is provided, each property will be passed to the function and the result (true or false) will determine whether the property is included. If an object is provided, each property will be matched against the object using a partial deep comparison to determine whether the property is included.\r\n\r\nBut if the config is a JSON file, there is no way to pass a function to the `filter` property (maybe we should update the documentation?), so the only way to apply a filter is via an object:\r\n```\r\n\"filter\": {\r\n    \"attributes\": {\r\n      \"category\": \"color\"\r\n    }\r\n}\r\n```\r\nwhich in the code is transformed to a matching filter function via the Lodash `matches` method:\r\n```\r\nconst filterFunc = _.isFunction(filter) ? filter : _.matches(filter)\r\n```\r\nThis also means we can filter **only** for one CTI property (eg. color, or size) at the time. In reality often is useful to have a filter that can work with multiple CTI properties (eg. \"give me all the color and size properties\") but as is now is not possible.\r\n\r\nWhat I am proposing here is to extend a little bit the capabilities of the filter, and accept an array of objects. Something like this:\r\n```\r\n\"filter\": [{\r\n    \"attributes\": {\r\n      \"category\": \"size\"\r\n    }\r\n},{\r\n    \"attributes\": {\r\n      \"category\": \"color\"\r\n    }\r\n}]\r\n```\r\nwhere the `filterProperties` function would look something like this (notice: the array filter function is probably wrong, I have to investigate what is the correct way to write it, but it gives you a gist of what I mean):\r\n\r\n```\r\nfunction filterProperties(dictionary, filter) {\r\n  if (!filter) {\r\n    return dictionary\r\n  } else {\r\n    let filterFunc;\r\n    if (_.isFunction(filter)) {\r\n        filterFunc = filter;\r\n    } else if (_.isArray(filter) && filter.every(_.isObject(filter))) {\r\n        filterFunc = function (filter) {\r\n            return filter.some(function(obj) { return _.matches(filter); });\r\n        };\r\n    } else if (_.isObject(filter)) {\r\n        filterFunc = _.matches(filter);\r\n    } else {\r\n        // maybe throw an error here?\r\n    }\r\n    return _.assign({}, dictionary, {\r\n      allProperties: filterPropertyArray(dictionary.allProperties, filterFunc),\r\n      properties: filterPropertyObject(dictionary.properties, filterFunc)\r\n    })\r\n  }\r\n}\r\n```\r\n\r\nWhat do you think of this? Adding too much complexity?\r\n(pinging @dbanksdesign + @chazzmoney if they have some ideas/comments) "},"comment":{"url":"https://api.github.com/repos/amzn/style-dictionary/issues/comments/441355541","html_url":"https://github.com/amzn/style-dictionary/issues/199#issuecomment-441355541","issue_url":"https://api.github.com/repos/amzn/style-dictionary/issues/199","id":441355541,"node_id":"MDEyOklzc3VlQ29tbWVudDQ0MTM1NTU0MQ==","user":{"login":"didoo","id":686239,"node_id":"MDQ6VXNlcjY4NjIzOQ==","avatar_url":"https://avatars1.githubusercontent.com/u/686239?v=4","gravatar_id":"","url":"https://api.github.com/users/didoo","html_url":"https://github.com/didoo","followers_url":"https://api.github.com/users/didoo/followers","following_url":"https://api.github.com/users/didoo/following{/other_user}","gists_url":"https://api.github.com/users/didoo/gists{/gist_id}","starred_url":"https://api.github.com/users/didoo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/didoo/subscriptions","organizations_url":"https://api.github.com/users/didoo/orgs","repos_url":"https://api.github.com/users/didoo/repos","events_url":"https://api.github.com/users/didoo/events{/privacy}","received_events_url":"https://api.github.com/users/didoo/received_events","type":"User","site_admin":false},"created_at":"2018-11-24T09:43:05Z","updated_at":"2018-11-24T09:43:05Z","author_association":"CONTRIBUTOR","body":"Looks like this is getting complex (the multiple options, the negation, the OR vs AND). The risk is to take something that works and it's \"easy\" to use and convert it to something too complex and unpredictable. What do you think if instead we define a new `registerFilter` method in Style Dictionary (similar to what we have with `registerFormat`, `registerTemplate`, `registerAction`) so that we can do:\r\n\r\n```\r\n\"filter\": \"name_of_the_filter\"\r\n```\r\n\r\n(in the same way as we do `\"template\": \"name_of_template\"` or `\"format\": \"name_of_template\"`).\r\n\r\nThen in the `filterProperties` function declaration we can easily detect if the filter is a \"custom\" filter by the fact that is a string."}}
{"actor":{"display_login":"didoo"}}