{"id":21401451,"url":"https://github.com/spoonx/sails-hook-wetland","last_synced_at":"2025-06-26T10:35:19.156Z","repository":{"id":44795451,"uuid":"77231322","full_name":"SpoonX/sails-hook-wetland","owner":"SpoonX","description":"A sails hook that enables the use of wetland ORM.","archived":false,"fork":false,"pushed_at":"2018-02-04T11:04:14.000Z","size":61,"stargazers_count":8,"open_issues_count":3,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-10T14:47:23.167Z","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/SpoonX.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":"2016-12-23T14:43:31.000Z","updated_at":"2025-03-29T12:34:26.000Z","dependencies_parsed_at":"2022-09-08T02:37:19.684Z","dependency_job_id":null,"html_url":"https://github.com/SpoonX/sails-hook-wetland","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/SpoonX/sails-hook-wetland","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SpoonX%2Fsails-hook-wetland","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SpoonX%2Fsails-hook-wetland/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SpoonX%2Fsails-hook-wetland/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SpoonX%2Fsails-hook-wetland/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SpoonX","download_url":"https://codeload.github.com/SpoonX/sails-hook-wetland/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SpoonX%2Fsails-hook-wetland/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262049077,"owners_count":23250676,"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-22T15:27:52.567Z","updated_at":"2025-06-26T10:35:19.103Z","avatar_url":"https://github.com/SpoonX.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# sails-hook-wetland\n\nA sails hook that enables the use of [wetland ORM](https://wetland.spoonx.org/). It might be useful to take a look at the [quick start of wetland](https://wetland.spoonx.org/quick-start.html).\n\nMore documentation and examples will follow.\n\n## Features\n\n* All default sails blueprints.\n* **NEW:** Custom count blueprint\n* **NEW:** Blueprint options\n* Nested populates.\n* Migrations.\n* Runs side-by-side with waterline.\n* Unit of work (transactions).\n* Dirty checking (optimized).\n* Lower memory footprint.\n* Performance.\n* And the rest of the wetland features.\n\n## Installation\n\n1. `sails new myapplication`\n2. `cd $_`\n3. `npm i sails-hook-wetland --save`\n4. Choose an adapter (list below) `npm i --save sqlite3`\n5. `mkdir api/entity`\n\n## Configuration\n\nOut of the box, wetland works with sqlite3, so there's no need to configure anything.\nYou do however need to install sqlite3 if that's what you want to use, and create the `config/wetland.js` and `wetland.js` files.\n\nHere are two code snippets that will do everything for you, assuming the `sqlite3` default as an adapter.\nYou can read how to configure other adapters further down the readme.\n\n* `npm i sqlite3`\n* `mkdir api/entity`\n* `echo \"module.exports.wetland = {};\" \u003e config/wetland.js`\n* `echo \"module.exports = require('./config/wetland').wetland;\" \u003e wetland.js`\n\nAn extensive list with config options and explanation can be found in [the wetland documentation](https://wetland.spoonx.org/configuration.html).\n\n### Example config\n\nThe simplest configuration _(which will be what's used 9/10 times)_ is as follows:\n\n**config/wetland.js**\n\n```js\nconst path = require('path');\n\nmodule.exports.wetland = {\n  entityPath: path.resolve(process.cwd(), 'api', 'entity'),\n  stores    : {\n    defaultStore: {\n      client    : 'mysql',\n      connection: {\n\t    host    : '127.0.0.1',\n\t    user    : 'your_database_user',\n\t    password: 'your_database_password',\n\t    database: 'myapp_test'\n      }\n    }\n  }\n};\n```\n\nWetland supports master/slave setups and pooling.\nDocumentation for these features will be added in the nearby future.\n\n## Blueprints\n\nThis hook comes with all the default blueprints, and a count blueprint. It also adds some features for the current blueprints.\n\n### New: Additional config options\n\nSails-hook-wetland offers additional options for blueprints.\n\n```js\nmodule.exports.blueprints = {\n\n  // Enabling this options will include the total count for the current query in the results using the value as header key.\n  // For instance, using 'X-Total-Count' as a value, will return the total count in the headers with every find request.\n  countInResponse: false,\n\n  // This option allows you to nest the response deeper.\n  // So, you could use 'data' as a value here, and all responses will be wrapped.\n  dataProperty: false\n};\n```\n\n### Create and update\n\nCode speaks. Take a look at this:\n\n```js\nconst createAction = require('sails-hook-wetland/blueprints/create');\nconst updateAction = require('sails-hook-wetland/blueprints/update');\nconst My           = require('../Entity/My');\n\nconst MyController = {\n  update (req, res) {\n    return updateAction(req, res, MyController.getDetailed(req, actionUtil.requirePk(req), true), true);\n  },\n\n  create (req, res) {\n    return createAction(req, res, true);\n  },\n\n  getDetailed(req, pk, update) {\n    let options = {\n      populate: [{'something': 's'}, 's.somethingElse', 's.anotherThing', 'whatever']\n    };\n\n    return req.getRepository(My).findOne((pk || actionUtil.requirePk(req)), options);\n  },\n};\n```\n\nThis example shows how you can support nested creates, as well as nested updates based on your own provided base data.\n\nThe latter is useful when you want to apply nested updates. Wetland diffs and only pushes what is needed.\nThis gives you a chance to supply the base to use for the diff.\n\n### Count\n\nOn top of the default blueprint, this hook also adds a `count` blueprint which, you guessed it, allows you to fetch a count.\n\nAll you need to do to add this is add a route:\n\n```js\nmodule.exports.routes = {\n  'GET /my/count': {blueprint: 'count'}\n};\n```\n\nAnd it's ready to be used:\n\n```js\n$ curl http://127.0.0.1:1337/my/count\n{\n  \"count\": 8\n}\n```\n\n### Wetland CLI\n\nTo be able to use the [wetland CLI](https://github.com/SpoonX/wetland-cli), a `wetland.js` or `wetland.json` file must be present in the root directory of your project.\nThe wetland cli allows you to run \u0026 create migrations, manage your schema and work with snapshots.\nIt also helps you [generate entities](https://github.com/SpoonX/wetland-generator-entity).\n\nThe easiest way to do this is by creating a file called wetland.js in the root of your directory with the following contents:\n\n```js\nmodule.exports = require('./config/wetland').wetland;\n```\n\n#### Installing the CLI\n\nIn order to use the CLI, you'll have to install it first. You can do this by running `npm i -g wetland`.\nYou can verify installation worked by running `wetland --version`.\n\n### Adapters\n\n| Adapter | Command |\n| ------------- | ------------- |\n| mysql | `npm i mysql --save` |\n| mysql2 | `npm i mysql2 --save` |\n| pg | `npm i pg --save` |\n| sqlite3 | `npm i sqlite3 --save` |\n| mariasql | `npm i mariasql --save` |\n| strong-oracle | `npm i strong-oracle --save` |\n| oracle | `npm i oracle --save` |\n| mssql | `npm i mssql --save` |\n\n## Differences with waterline\n\nThe differences are minimal out of the box when working with blueprints.\nOnce you start writing custom code, the differences become more clear.\n\n### No validation\n\nValidation is a precious feature, that does not belong in an ORM.\nBecause wetland entities are simple classes, you can apply your own validation easily.\n\nA good library for this is [joi](https://github.com/hapijs/joi), which is a joy to work with.\n\nIn the future there will be an opinionated validation plugin for wetland.\nIf there's enough demand, this will be bumped up on the priority list.\n\n### Unit of work\n\nTo be able to guarantee data safety, wetland uses transactions for all queries. These queries are calculated once you _flush the changes_.\n\nFlushing will trigger the unit of work to calculate changes you made (new, changed, removed and linked entities).\n\n### No entity methods\n\nWetland doesn't have model methods. It separates logic and state using Entities and [Repositories](http://martinfowler.com/eaaCatalog/repository.html).\n\nInstead, you'll be using repositories to fetch data from the database. Each entity can have its own repository, so it's possible to create your own repository and have it contain custom queries (using the query builder, or native).\n\n### Migrations\n\nWetland supports migrations, including creating, running and auto-running (dev migrations) them.\n\n[Read more here](https://wetland.spoonx.org/Tutorial/snapshots.html)\n\n### IDs on entities\n\nOut of the box, entities are exactly as you define them. No magical PK, no autoUpdatedAt or autoCreatedAt. All of these are up to you to implement. Because entities are just classes, you can create a base class and extend it.\n\n### Entity definition\n\nThe way you specify the _mappings_ for your entities is different.\n\n## Usage\n\nIn api, create a directory called `entity`. This is where wetland will look for your entities (comparable to models for waterline).\n\n## Req methods\n\n### req.getRepository([Entity])\n\nGet the repository for provided Entity.\nIf none was supplied, the Entity for the current blueprint will be used instead.\n\n**See also: [EntityRepository](https://wetland.spoonx.org/API/entity-repository.html).**\n\n### req.getManager()\n\nUse this method to get a new EntityManager scope.\nThis is used to call persist on, for instance. Check the wetland docs for more info.\n\n### req.wetland\n\nA convenience property pointing to the wetland instance.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspoonx%2Fsails-hook-wetland","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspoonx%2Fsails-hook-wetland","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspoonx%2Fsails-hook-wetland/lists"}