{"id":13745209,"url":"https://github.com/jonnyreeves/as3-vanilla","last_synced_at":"2026-02-12T00:31:27.802Z","repository":{"id":66198507,"uuid":"2086194","full_name":"jonnyreeves/as3-vanilla","owner":"jonnyreeves","description":"Extract strongly typed Objects from dynamic objects without writing a single line of code!","archived":false,"fork":false,"pushed_at":"2014-12-18T07:48:51.000Z","size":4071,"stargazers_count":81,"open_issues_count":6,"forks_count":15,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-09-02T14:49:08.916Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://www.jonnyreeves.co.uk/2011/08/getting-started-with-vanilla/","language":"ActionScript","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/jonnyreeves.png","metadata":{"files":{"readme":"README.mkd","changelog":"CHANGELOG","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2011-07-21T23:04:58.000Z","updated_at":"2021-12-17T15:32:56.000Z","dependencies_parsed_at":"2023-02-20T00:15:34.022Z","dependency_job_id":null,"html_url":"https://github.com/jonnyreeves/as3-vanilla","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/jonnyreeves/as3-vanilla","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonnyreeves%2Fas3-vanilla","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonnyreeves%2Fas3-vanilla/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonnyreeves%2Fas3-vanilla/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonnyreeves%2Fas3-vanilla/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jonnyreeves","download_url":"https://codeload.github.com/jonnyreeves/as3-vanilla/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonnyreeves%2Fas3-vanilla/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29350897,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-11T20:11:40.865Z","status":"ssl_error","status_checked_at":"2026-02-11T20:10:41.637Z","response_time":97,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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-08-03T05:01:24.948Z","updated_at":"2026-02-12T00:31:27.783Z","avatar_url":"https://github.com/jonnyreeves.png","language":"ActionScript","funding_links":[],"categories":["Unsorted"],"sub_categories":["Other API"],"readme":"AS3 Vanilla\n===========\n\n[![Build Status](https://travis-ci.org/jonnyreeves/as3-vanilla.svg?branch=master)](https://travis-ci.org/jonnyreeves/as3-vanilla)\n\nA lightweight library which enables a developer to extract a strongly typed Model Object from a untyped dynamic object \nwithout having to write a single line of parsing or marshalling code.  An example use case would be turning data \nreturned from a JSON endpoint into a Model, if you've ever written the following code, then you can benefit from this \nlibrary:\n\n```actionscript\n// Use a JSON library to convert a JSON String into an AS3 Object.\nvar jsonObject : Object = JSON.decode('{\"name\":\"Jonny\", \"age\": 28, \"music\":[\"nin\",\"mew\"]}');\n\n// Copy all the data into a new PersonVO so the rest of the system can use it.\nvar myPerson : PersonVO = new PersonVO();\nmyPerson.name = jsonObject[\"name\"];\nmyPerson.age = jsonObject[\"age\"];\nmyPerson.music = jsonObject[\"music\"];\n\ntrace(myPerson.name) // Jonny.\n```\n\nUsing the Vanilla library, you can turn the above code into this:\n\n```actionscript\n// Use a JSON library to convert a JSON String into an AS3 Object.\nvar jsonObject : Object = JSON.decode('{\"name\":\"Jonny\", \"age\": 28, \"music\":[\"nin\",\"mew\"]}');\n\n// Use Vanilla to convert it into a PersonVO.\nvar myPerson : PersonVO = new Vanilla().extract(jsonObject, PersonVO);\n\ntrace(myPerson.name);  // \"Jonny\"\n```\n\nThings get even easier when you make use of the `extract` convenience method:\n\n```actionscript\nvar jsonObject : Object = JSON.decode('{\"name\":\"Jonny\", \"age\": 28, \"music\":[\"nin\",\"mew\"]}');\nvar myPerson : PersonVO = extract(jsonObject, PersonVO);\n```\n\nGot a complex object graph?  Well that's where Vanilla really shines, making light work of parsing and \nmarshalling nested objects, for example:\n\n```actionscript\n// The PersonVO Model contains an 'address' field which is a complex datatype (AddressVO).\npackage app.model {\n\tclass PersonVO {\n\t\tpublic var name : String;\n\t\tpublic var address : AddressVO;\n\t}\n}\n\n// Here's the class definition for AddressVO.\npackage app.model {\n\tclass AddressVO {\n\t\tpublic var line1 : String;\n\t\tpublic var line2 : String;\n\t\tpublic var city : String;\n\t}\n}\n\nvar jsonObject : Object = JSON.decode('{\"name\":\"Jonny\",\"address\":{\"line1\":\"My House\",\"line2\":\"My Road\",\"city\":\"London\"}}');\nvar myPerson : PersonVO = extract(jsonObject, PersonVO);\n\ntrace(myPerson.address.city);\t// \"London\"\n```\n\nAlthough Vanilla library does make use of Metadata, it is by no means required - the goal of this library\nis to make the marshalling as transparent and painless as possible; if the source Object's fields maps perfectly to\nthe fields of your Model object (as in the example above) then everything should 'just work'(tm).\n\n\nMapping Fields\n--------------\nSometimes the fields on your Model object don't quite match up to the fields in your source object; not a problem, \nyou can use Metadata to define the mappings in your Model object:\n\n```actionscript\npackage app.model {\n\tpublic class PersonVO {\n\t\tpublic var name : String;\n\t\tpublic var age : uint;\n\t\t[Marshall(field=\"music\")] public var musicTastes : Array;\n\t}\n}\n```\n\n\nMapping to Constructor Arguments\n--------------------------------\nIf you're a fan of immutable models then you will want to define some Metadata to map the fields in your source object\nto the constructor arguments of your Model object:\n\n```actionscript\npackage app.model {\n\t// Don't forget, constructor metadata is annotated to the class, not the constructor method!\n\t[Marshall(field=\"name\", field=\"age\", field=\"music\")]\n\tpublic class PersonModel {\n\t\tprivate var _name : String;\n\t\tprivate var _age : uint;\n\t\tprivate var _musicTastes : Array;\n\t\n    \tpublic function PersonModel(name, age, music : Array) {\n    \t\t_name = name;\n    \t\t_age = age;\n    \t\t_music = music;\n    \t}\n    }\n}\n```\n\n\nMapping to Methods / Mutators\n-----------------------------\nYou can map the fields of your source object to a setter method in your Model object:\n\n```actionscript\npackage app.model {\n\tpublic class PersonModel {\n\t\tprivate var _name : String;\n\t\tprivate var _age : uint;\n\t\tprivate var _music : Array;\n\t\t\n\t\t[Marshall(field=\"name\", field=\"age\")]\n\t\tpublic function init(name : String, age : uint) : void {\n\t\t\t_name = name;\n\t\t\t_age = age;\n\t\t}\n\t\t\n\t\t[Marshall(field=\"music\")]\n\t\tpublic function setMusic(value : Array) : void {\n\t\t\t_music = value;\n    }\n}\n```\n\n\nIgnoring fields\n-----------------------------\nYou can ignore fields by using [Transient] metadata:\n\n```actionscript\npackage app.model {\n\tpublic class PersonModel {\n\t\t[Transient]\n\t\tpublic var name : String;\n\t\tpublic var age : uint;\n\t}\n}\n```\nThe name field is ignored from the mapping but the age is not.\n\n\nAutomatic Coercion\n------------------\nVanilla will automatically coerce Arrays found in your source object into Vectors defined in your target Model\nClass, take the following example:\n\n```actionscript\n// The Target Model Class Definition.\nclass app.model {\n\tpublic class ColourList {\n\t\tpublic var colours : Vector.\u003cString\u003e;\n\t}\n}\n\nvar source : Object = { colours: [ \"red\", \"white\", \"blue\" ] };\nvar result : ColourList = extract(source, ColourList); \n\ntrace(result.colours);\t// \"red\",\"white\",\"blue\"\ntrace(getQualifiedClassName(result.colours));\t// __AS3__.vec::Vector.\u003cString\u003e\n```\n\nIf you aren't using Vectors in your project, then you will have to give Vanilla a hand and provide it with a type hint\nas to what the Array is expected to contain, for example:\n\n```actionscript\n// The Target Model Class Definition.\nclass app.model {\n\tpublic class Contact {\n\t\tpublic var name : String;\n\t\t\n\t\t[Marshall (type=\"app.model.PhoneNumber\")]\n\t\tpublic var phoneNumbers : Array;\n\t}\n}\n\n// A DTO which the Contact class makes use of.\nclass app.model {\n\tpublic class PhoneNumber {\n\t\tpublic var number : Number;\n\t\tpublic var type : String;\n\t}\n}\n\n// Let's extract this JSON representation into a instance of the Contact model.\nvar source : Object = { \n\tname: \"Jonny\", \n\tphoneNumbers: [ \n\t\t{ number: 114752471, type: \"home\" }, \n\t\t{ number: 12344122, type: \"mobile\" } \n\t] \n};\n\nvar result : Contact = extract(source, Contact); \ntrace(result.phoneNumbers); // [object PhoneNumber],[object PhoneNumber]\ntrace((result.phoneNumbers[0] as PhoneNumber).type)\t// \"home\".\n```\n\n\n\nDependencies\n------------\n`as3commons-reflect` is used for all reflection; in order to use as3-vanilla you will need to download and add\nthe following SWCs to your project's libs folder.\n\n* [ascommons-reflect-1.4.1](http://projects.yoolab.org/maven/content/repositories/releases/org/as3commons/as3commons-reflect/1.4.1/as3commons-reflect-1.4.1.swc)\n* [as3commons-lang-0.3.4](http://projects.yoolab.org/maven/content/repositories/releases/org/as3commons/as3commons-lang/0.3.4/as3commons-lang-0.3.4.swc)\n* [as3commons-logging-2.0](http://projects.yoolab.org/maven/content/repositories/releases/org/as3commons/as3commons-logging/2.0/as3commons-logging-2.0.swc)\n\n\nFuture Features / Wish List\n---------------------------\n* The user should be able to define mapping rules without having to use Metadata.\n* Java style mutators (eg: `setFoo()`) could be mapped automatically.\n* By using `as3commons-bytecode` we could perform ByteCode reflection to retrieve the names of parameters; this would \nwould remove the need for constructor marshalling metadata.\n* Possibly move away from as3commons-reflect (It has too many dependencies).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonnyreeves%2Fas3-vanilla","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjonnyreeves%2Fas3-vanilla","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonnyreeves%2Fas3-vanilla/lists"}