{"id":24411434,"url":"https://github.com/5310/assignplus","last_synced_at":"2026-04-24T17:32:11.752Z","repository":{"id":34554886,"uuid":"38500085","full_name":"5310/assignplus","owner":"5310","description":"A custom Object.assign-like function that can be overridden with symbolic annotations for advanced functionality.","archived":false,"fork":false,"pushed_at":"2015-07-04T06:09:34.000Z","size":128,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-27T02:54:39.552Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/5310.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-07-03T15:47:45.000Z","updated_at":"2015-07-03T15:48:13.000Z","dependencies_parsed_at":"2022-09-08T15:00:44.248Z","dependency_job_id":null,"html_url":"https://github.com/5310/assignplus","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/5310/assignplus","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/5310%2Fassignplus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/5310%2Fassignplus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/5310%2Fassignplus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/5310%2Fassignplus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/5310","download_url":"https://codeload.github.com/5310/assignplus/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/5310%2Fassignplus/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32234577,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-24T13:21:15.438Z","status":"ssl_error","status_checked_at":"2026-04-24T13:21:15.005Z","response_time":64,"last_error":"SSL_read: 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":"2025-01-20T06:36:13.590Z","updated_at":"2026-04-24T17:32:11.733Z","avatar_url":"https://github.com/5310.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# assignPlus\n\n[![ecmascript-2015](https://img.shields.io/badge/es-2015-green.svg?style=flat)](http://www.ecma-international.org/publications/standards/Ecma-262.htm)\n[![js-standard-style](https://img.shields.io/badge/code%20style-standard-green.svg?style=flat)](https://github.com/feross/standard)\n[![License](http://img.shields.io/badge/license-mit-green.svg?style=flat)](https://github.com/lahuan/lahuanjs-com-events/blob/master/LICENSE)\n[![Dependency Status](https://david-dm.org/5310/assignplus.svg)](https://david-dm.org/5310/assignplus)\n[![Build](http://img.shields.io/travis/5310/assignplus.svg?style=flat)](https://travis-ci.org/5310/assignplus)\n[![Release](http://img.shields.io/badge/release-v1.0.0-blue.svg?style=flat)](https://github.com/5310/assignplus/releases)\n[![jspm](https://img.shields.io/badge/jspm-github:5310/assignplus-blue.svg?style=flat)](http://jspm.io)\n[![jspm](https://img.shields.io/badge/npm-5310/assignplus-blue.svg?style=flat)](https://docs.npmjs.com/cli/install)\n\n`assignPlus` is a custom `Object.assign`-like function that can be overridden with symbolic annotations for advanced functionality.\n\nWith it you can not only do what `Object.assign` can, copy first-level enumerable own-properties of a object to another, but also merge property objects, whether by an object-by-object basis or recursively, and fully define properties on the target, or remove a property entirely. All with symbolic annotations defining the assignment behaviors.\n\nThis is written as an ES2015 module, and transpiled with Babel upon installation for NPM.\n\n## Usage\n\n- `assignPlus(target, source)`\n  - The source objects properties will be assigned to the target object.\n  - Without annotation, behaves just like `Object.assign`.\n  - Invalid behavior annotations will be ignored.\n\n- Behaviors:\n  - Default\n    - Without any annotation, by default a source sub-object's properties are merely copied over to the equivalent property on the target.\n    - Sub-objects nested inside a default object _will not_ be checked for annotation!\n  - `merge`\n    - Copies all enumerable own properties over to the target object.\n    - If a nested sub-object has this annotation, it does not overwrite the equivalent property on the target.\n      - But does throw an exception if the equivalent target property is not an object itself.\n    - Overwrites properties if they collide.\n    - Sub-objects nested immediately inside a merge object _will_ be checked for further annotation.\n  - `deep`\n    - Recursively or \"deeply\" merges all objects from this annotated level and lower.\n    - Can be an annotation on the root, deeply merging the entire source object.\n    - Sub-objects nested inside a deep object will be assumed to be annotated with deep merge.\n  - `overwrite`\n    - Used to break out of a deep merge.\n    - It is functionally equivalent to the default behavior.\n  - `define`\n    - A nested sub-object with this annotation will invoke `Object.defineProperty`!\n      - The property will be defined on the equivalent level on the target.\n      - The name of the object will become the name of the property being defined.\n      - The annotated object itself will be passed to `Object.defineProperty` as configuration.\n  - `remove`\n    - A nested object with this annotation will delete the equivalent property on the target.\n  - Arbitrary handler\n    - If the behavior annotation is a function, it will be treated as an arbitrary handler.\n    - It will be passed the current level's target and source sub-objects respectively, and whatever it returns will be ran through the process again in place of the source sub-object.\n    - Can be an annotation on the root, replacing the entire source object with the returned value.\n      - If this value isn't an object, the process will fail, as expected.\n\n## Example\n```\nimport assignPlus, {symbols} from './assignplus'\nimport assert from 'assert'\n\nlet x = {\n  name: '',\n  health: {\n    max: 10,\n    current: 10\n  },\n  twod: {\n    position: {\n      x: 0,\n      y: 0,\n      velocity: {\n        dx: 0,\n        dy: 0\n      }\n    },\n    rotation: 0\n  },\n  enemy: {\n    type: 'melee',\n    rank: 2\n  }\n}\n\nassignPlus(x, {\n  name: 'random injured guy',\n  health: {\n    [symbols.behavior]: symbols.behaviors.merge,\n    current: 5\n  },\n  twod: {\n    [symbols.behavior]: symbols.behaviors.deep,\n    position: {\n      x: 100,\n      y: 100,\n      velocity: {\n        [symbols.behavior]: symbols.behaviors.overwrite,\n        x: 0,\n        y: 0\n      }\n    }\n  },\n  enemy: { [symbols.behavior]: symbols.behaviors.remove },\n  id: {\n    [symbols.behavior]: symbols.behaviors.define,\n    get: () =\u003e 123,\n    enumerable: true\n  },\n  random: { [symbols.behavior]: (target, source) =\u003e 4 }\n  // chosen by a fair dice roll, guaranteed to be random\n})\n\nassert.deepEqual(x, {\n  name: 'random injured guy',\n  health: {\n    max: 10,\n    current: 5\n  },\n  twod: {\n    position: {\n      x: 100,\n      y: 100,\n      velocity: {\n        x: 0,\n        y: 0\n      }\n    },\n    rotation: 0\n  },\n  id: 123,\n  random: 4\n})\n```\nLook at the `test.js` file for even more examples of the behaviors.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F5310%2Fassignplus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F5310%2Fassignplus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F5310%2Fassignplus/lists"}