{"id":21893329,"url":"https://github.com/norjs/models","last_synced_at":"2025-10-29T12:04:51.770Z","repository":{"id":48024392,"uuid":"167687900","full_name":"norjs/models","owner":"norjs","description":"NorJS models","archived":false,"fork":false,"pushed_at":"2023-01-03T16:10:36.000Z","size":260,"stargazers_count":0,"open_issues_count":6,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-26T07:24:09.595Z","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":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/norjs.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2019-01-26T12:46:19.000Z","updated_at":"2019-10-28T06:05:30.000Z","dependencies_parsed_at":"2023-02-01T07:30:34.438Z","dependency_job_id":null,"html_url":"https://github.com/norjs/models","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/norjs/models","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/norjs%2Fmodels","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/norjs%2Fmodels/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/norjs%2Fmodels/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/norjs%2Fmodels/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/norjs","download_url":"https://codeload.github.com/norjs/models/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/norjs%2Fmodels/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261193127,"owners_count":23122909,"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-11-28T13:13:27.360Z","updated_at":"2025-10-29T12:04:51.757Z","avatar_url":"https://github.com/norjs.png","language":"JavaScript","readme":"# Models for NorJS\n\nAbstracts, factories and utils for implementing classes in ES6 \nJavaScript.\n\nAlso includes some NorJS concrete model classes, which are also examples\nof usage.\n\n--------------------------------------------------------------------------------\n\n## Package usage\n\n### Requirements \n\n * Babel 7 with ES6 support (building)\n * Lodash\n * Support for symbols\n\n### Install in your project\n\n```\nnpm i --save-dev @norjs/models\n```\n\n### Import\n\nFor eg. `DataModel`, use:\n\n```js\nimport { DataModel } from \"@norjs/models\";\n```\n\n### Run tests\n\n```\nnpm test\n```\n\n--------------------------------------------------------------------------------\n\n## `DataModel`\n\nThe abstract base class for models.\n\nAs an abstract class it does not work unless you extend from it and define \nmissing abstract methods, or use one of our ready to use classes. \n\nSee also:\n\n  * [`InternalDataModel`](#InternalDataModel),\n  * [`PlainDataModel`](#PlainDataModel),\n  * [`ShallowCowDataModel`](#ShallowCowDataModel),\n  * [`DataModel.create(model)`](#datamodelcreatemodel)\n  * [`DataModel.deleteProperty(model, key)`](#datamodeldeletepropertyobj-key),\n  * [`Invoice`](#Invoice),\n  * [`InvoiceRow`](#InvoiceRow)\n\nYou can also compose your own classes a bit by bit using our factory functions:\n\n  * [`InternalDataModelFactory`](#InternalDataModelFactory),\n  * [`PlainDataModelFactory`](#PlainDataModelFactory),\n  * [`ShallowCowDataModelFactory`](#ShallowCowDataModelFactory)\n  * [`InvoiceFactory`](#InvoiceFactory)\n  * [`InvoiceRowFactory`](#InvoiceRowFactory)\n\nThese factory functions make it possible to swap parts of the implementation,\n or use your own instead.\n\n--------------------------------------------------------------------------------\n\n### `DataModel.create(model)`\n\nStatic, public.\n\nThis is a static method which you can use to create a freezed instance of your \nmodel. \n\nYou need to call it from your own class, of course.\n\nEg. if your class is `MyData extends DataModel`, you'll call it as \n`const model = MyData.create(...)`\n\n--------------------------------------------------------------------------------\n\n### `DataModel.deleteProperty(obj, key)`\n\nStatic, public.\n\nDelete a property inside the model by a keyword.\n\n**Note!** It is *recommended* to save your keywords as static constants into \nyour model class, so user's don't need to use your internal keyword strings or \nsymbols to delete properties.\n\n--------------------------------------------------------------------------------\n\n### `DataModel#valueOf()`\n\nPublic.\n\nReturns the internal value for the model. Usually it is an object.\n\n--------------------------------------------------------------------------------\n\n### `DataModel#getId()`\n\nAbstract, Public.\n\nReturns the unique identifier value for this model instance. (Eg. the primary \nkey in a database table.)\n\n--------------------------------------------------------------------------------\n\n### `DataModel#setId(value)`\n\nAbstract, Public.\n\nSets the unique identifier value for this model instance. (Eg. the primary \nkey in a database table.)\n\n--------------------------------------------------------------------------------\n\n### `DataModel#constructor(value)`\n\nProtected.\n\nThe constructor, which is declared as protected to disable using `new DataModel\n()` \nstyle.\n\n--------------------------------------------------------------------------------\n\n### `DataModel#_getInternal()`\n\nReturns the internal value for the model. Usually it is an object.\n\nAbstract, protected.\n\n--------------------------------------------------------------------------------\n\n### `DataModel#_setInternal(value)`\n\nAbstract, Protected.\n\nSets the internal value of the model. Usually it's an object.\n\n--------------------------------------------------------------------------------\n\n### `DataModel#_has(key)`\n\nAbstract, Protected.\n\nReturns `true` or `false` depending if a keyword is defined in the model's \ninternal value.\n\nSee `DataModel#_get(key)` for more information for the keyword format.\n\n--------------------------------------------------------------------------------\n\n### `DataModel#_get(key)`\n\nAbstract, Protected.\n\nReturns the value for a property from the model's internal value.\n\nThe `key` can be:\n \n * a `symbol` for the value, eg `FOO` for `.valueOf()[FOO]`\n * a `string` with a path to the property, eg. `\"foo.bar\"` for `.valueOf().foo.bar`\n * an `array` of symbol or string values, eg. `[\"foo\", \"bar\"]` for `.valueOf().foo.bar`\n\n--------------------------------------------------------------------------------\n\n### `DataModel#_set(key, value)`\n\nAbstract, Protected.\n\nSets a value for a property in the model's internal value.\n\nSee `DataModel#_get(key)` for more information for the keyword format.\n\n--------------------------------------------------------------------------------\n\n### `DataModel#_delete(key)`\n\nAbstract, Protected.\n\nDelete a value for a property in the model's internal value.\n\nSee `DataModel#_get(key)` for more information for the keyword format.\n\n--------------------------------------------------------------------------------\n\n## InternalDataModel\n\nThis is an abstract class extended from `DataModel` which has implemented \ninterface to get and set an internal model value as a plain object.\n\nIt implements: \n\n * `DataModel#constructor(value = {})` using `DataModel#_setInternal(value)`\n * `DataModel#_getInternal()`\n * `DataModel#_setInternal(value)`.\n\nIt *does not* implement:\n\n * `DataModel#_has(key)`\n * `DataModel#_get(key)`\n * `DataModel#_set(key, value)`\n * `DataModel#_delete(key)`\n * `DataModel#getId()`\n * `DataModel#setId(value)`\n \n--------------------------------------------------------------------------------\n\n## InternalDataModelFactory\n\nThis is a factory function which returns a class extending to the \nprovided DataModel class and implementing `DataModel#_getInternal()` and \n`DataModel#_setInternal(value)` using a private member variable.\n\n```js\nclass MyData extends InternalDataModelFactory(DataModel) {\n\t// ...\n}\n```\n\nYou'll need to implement other abstract methods.\n\nSee also [InternalDataModel](#InternalDataModel).\n\n--------------------------------------------------------------------------------\n\n## PlainDataModel\n\nThis is an abstract class extended from `InternalDataModel` which has \nimplemented interface to get and set an internal model value as a plain object.\n\nIt implements:\n\n * `DataModel#_has(key)`\n * `DataModel#_get(key)`\n * `DataModel#_set(key, value)`\n * `DataModel#_delete(key)`\n\nIt also implements: \n\n * `DataModel#_getInternal()` (from [InternalDataModel](#InternalDataModel))\n * `DataModel#_setInternal(value)` (from [InternalDataModel]\n (#InternalDataModel))\n\nIt *does not* implement:\n\n * `DataModel#getId()`\n * `DataModel#setId(value)`\n\n--------------------------------------------------------------------------------\n\n## PlainDataModelFactory\n\nThis is a factory function which returns a class extended from the provided \nmodel class implementing `DataModel#_has(key)`, `DataModel#_get(key)`, \n`DataModel#_set(key, value)` and `DataModel#_delete(key)`.\n\nIt implements them using `DataModel#_getInternal()` and \n`DataModel#_setInternal(value)`, which must be implemented in the provided model\n or \nlater in your own class.\n\n```js\nclass MyData extends PlainDataModelFactory(DataModel) {\n\t// ...\n}\n```\n\nSee also [PlainDataModel](#PlainDataModel) and \n[ShallowCowDataModel](#ShallowCowDataModel) for ready to use abstract classes.\n\n--------------------------------------------------------------------------------\n\n## ShallowCowDataModel\n\nThis is a class extended from `PlainDataModel` which implements \nabstract shallow copy on write model class implementation.\n\nThe shallow copy will be made only when there is a write operation and only \nto the parent objects of the modified property.\n\nYou can trust that the internal object returned from a call to `#valueOf()` will \nnot be modified later (by the model class implementation). It also will not be \ndeep copied when returned since this *is* a *copy on* ***write***, not \n*copy on read* implementation.\n\nLater call to `#valueOf()` may return a different object, but only if it was \nmodified, and only modified inner objects (and their parents) will point to new \ncopies. Eg. a change in a property of `\"foo.bar\"` does not modify a reference of\nan object in `\"bar.foo\"`.\n\nIt re-implements:\n \n * `DataModel#_set(key, value)`\n * `DataModel#_delete(key)`\n\nIt also implements: \n\n * `DataModel#_has(key)` (from [PlainDataModel](#PlainDataModel))\n * `DataModel#_get(key)`  (from [PlainDataModel](#PlainDataModel))\n * `DataModel#_getInternal()` (from [InternalDataModel](#InternalDataModel))\n * `DataModel#_setInternal(value)` (from [InternalDataModel]\n (#InternalDataModel))\n\nIt *does not* implement:\n\n * `DataModel#getId()`\n * `DataModel#setId(value)`\n \n--------------------------------------------------------------------------------\n\n## ShallowCowDataModelFactory\n\nThis is a factory function which returns a class extended from the provided \nmodel class implementing `DataModel#_set(key, value)` and `DataModel#_delete(key)`.\n\nIt implements them using abstract `DataModel#_setInternal(value)`, which you need\n to implement.\n\n```js\nclass MyData extends ShallowCowDataModelFactory(DataModel) {\n\t// ...\n}\n```\n\nIt does not implement: \n\n * `DataModel#_has(key)`\n * `DataModel#_get(key)`\n * `DataModel#_getInternal()`\n * `DataModel#_setInternal(value)`\n * `DataModel#getId()`\n * `DataModel#setId(value)`\n\nSee also [ShallowCowDataModel](#ShallowCowDataModel) for ready to use abstract \nclass.\n\n--------------------------------------------------------------------------------\n\n## Invoice\n\nThis is our invoice model class. See \n[the source code](./src/concretes/Invoice.js) \nfor updated inline documentation.\n\n## InvoiceFactory\n\nThis is our invoice model factory function. See \n[the source code](./src/factories/InvoiceFactory.js) \nfor updated inline documentation.\n\n--------------------------------------------------------------------------------\n\n## InvoiceRow\n\nThis is our invoice row model class. See \n[the source code](./src/concretes/InvoiceRow.js) \nfor updated inline documentation.\n\n## InvoiceRowFactory\n\nThis is our invoice row model factory function. See \n[the source code](./src/factories/InvoiceRowFactory.js) \nfor updated inline documentation.\n\n--------------------------------------------------------------------------------\n\n## DataModelUtils\n\n--------------------------------------------------------------------------------\n\n### `DataModelUtils.getPathToProperty(model, key)`\n\nReturns a readable and writable interface to a property inside the model object.\n\n--------------------------------------------------------------------------------\n\n### `DataModelUtils.shallowCopyByPath(model, path)`\n\nReturns a new model object with the path shallow copied to the property.\n\n--------------------------------------------------------------------------------\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnorjs%2Fmodels","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnorjs%2Fmodels","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnorjs%2Fmodels/lists"}