{"id":28533825,"url":"https://github.com/esri/arcgoose","last_synced_at":"2025-07-07T20:30:36.005Z","repository":{"id":33837455,"uuid":"153627642","full_name":"Esri/arcgoose","owner":"Esri","description":"Mongoose-style bindings for the ArcGIS REST API","archived":false,"fork":false,"pushed_at":"2023-07-08T12:40:03.000Z","size":1770,"stargazers_count":4,"open_issues_count":23,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-09T17:09:44.847Z","etag":null,"topics":["arcgis-rest-api","rest-api","schemas","web"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Esri.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":"CODEOWNERS","security":null,"support":null}},"created_at":"2018-10-18T13:23:59.000Z","updated_at":"2023-03-08T13:23:36.000Z","dependencies_parsed_at":"2023-01-15T02:52:37.543Z","dependency_job_id":null,"html_url":"https://github.com/Esri/arcgoose","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Esri/arcgoose","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Esri%2Farcgoose","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Esri%2Farcgoose/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Esri%2Farcgoose/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Esri%2Farcgoose/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Esri","download_url":"https://codeload.github.com/Esri/arcgoose/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Esri%2Farcgoose/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264142500,"owners_count":23563506,"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":["arcgis-rest-api","rest-api","schemas","web"],"created_at":"2025-06-09T17:08:49.694Z","updated_at":"2025-07-07T20:30:35.999Z","avatar_url":"https://github.com/Esri.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Arcgoose\n\nLet's face it, writing ArcGIS REST API validation, casting and business logic boilerplate is a drag.\nThat's why we wrote Arcgoose.\n\n```javascript\nconst connection = await arcgoose.connect({ url });\nconst Cat = await arcgoose.model(connection.layers.Cats, { name: String });\n\nconst cat = await Cat.findOne({ name: 'Grumpy' }).exec();\n```\n\nArcgoose provides a straight-forward, schema-based solution to model your application data. It\nincludes built-in type casting, validation, query building, business logic hooks and more,\nout of the box.\\*\n\n\\* Arcgoose is a work in progress.\n\n\\* Arcgoose is loosely based on the [Mongoose](https://mongoosejs.com) syntax.\n\n## Installing\n\n```\n$ npm install --save arcgoose\n```\n\nThen, just import to your service or module:\n\n```jsx\nimport arcgoose from 'arcgoose';\n```\n\n## Instructions\n\n### Connecting to ArcGIS Feature Server\n\nUsing the feature server URL:\n\n```javascript\nconst connection = await arcgoose.connect({ url });\n```\n\nUsing the hosted feature layer item id:\n\n```javascript\nconst connection = await arcgoose.connect({ portalUrl, portalItemId });\n```\n\nStructure of the `connection` JSON object:\n\n```javascript\n{\n  url,\n  capabilities: { create, query, update, delete, editing },\n  layers: {\n    Cats: { id, url, fields, objectIdField },\n    Dogs: { id, url, fields, objectIdField },\n  },\n  tables: {\n    Rabbits: { id, url, fields, objectIdField },\n  },\n}\n```\n\n### Schemas\n\nArcgoose uses schemas for validation and casting of types that are not Esri-supported (e.g., arrays,\nobjects, ...). Arcgoose uses the JSON Schema standard, and uses the\n[Ajv](https://github.com/epoberezkin/ajv#api) library for validation.\n\n```javascript\nconst catSchema = {\n  type: 'object', // type should always be object\n  required: ['GlobalID', 'name']\n  properties: {\n    GlobalID: {\n      type: 'string',\n    },\n    name: {\n      type: 'string',\n      minLength: 3,\n      maxLength: 100,\n    },\n    details: {\n      type: 'object', // 'details' will be casted from a string to a javascript object\n      properties: {\n        color: {\n          type: 'string',\n          pattern: '^#(([0-9a-fA-F]{2}){3}|([0-9a-fA-F]){3})$', // reg exp to match HEX color code\n        },\n        age: {\n          type: 'integer',\n          minimum: 0,\n        }\n      }\n    }\n    friends: {\n      type: 'array', // 'friends' will be casted from a string to a javascript array\n      items: {\n        type: 'string',\n      }\n    }\n  }\n};\n```\n\n### Models\n\nModels are fancy constructors compiled from `Schema` definitions. Instances of models are used\nto query and update layers and tables on the feature server.\n\n```javascript\nconst schema = {\n  type: 'object',\n  properties: {\n    name: { type: 'string' }\n  }\n};\n\nconst Cat = await arcgoose.model(connection.layers.Cats, schema);\n\nconst cat = await Cat.findOne({ name: 'Grumpy' }).exec();\n```\n\n### Queries\n\nQueries can be executed using the `find()` or `findOne()` methods. You can pass one or more\nobject fields to be matched.\n\n```javascript\nconst cat = await Cat\n  .find({ name: 'Grumpy' })\n  .exec();\n```\n\nAdditional query methods can be chained after the `find()` method.\n\n```javascript\nconst cat = await Cat\n  .find({ name: 'Grumpy' })\n  .populate(['name', 'dateOfBirth'])\n  .returnGeometry()\n  .exec();\n```\n\nHere is a list of additional query methods:\n\n```javascript\n.filter(additionalSQLWhereClause) // chain as many as you like\n```\n\n```javascript\n.populate(outFields) // otherwise all fields from the schema will be populated\n```\n\n```javascript\n.geometry(geometry, geometryType).intersects() // spatial query\n```\n\n```javascript\n.geometry(geometry, geometryType).contains()  // spatial query\n```\n\n```javascript\n.returnGeometry()\n```\n\n```javascript\n.returnCentroid()\n```\n\n```javascript\n.outSpatialReference(wkid)\n```\n\n```javascript\n.sort(sortOrder)\n```\n\n```javascript\n.offset(amount)\n```\n\n```javascript\n.limit(amount)\n```\n\n```javascript\n.offset(amount)\n```\n\n```javascript\n.outStatistics(outStatistics, groupByFieldsForStatistics)\n```\n\nIf the query indicates, that the transfer limit was exceeded, more paged queries are executed until all the data has been received.\n```javascript\n.ignoreServiceLimits()\n```\n\n```javascript\n.returnCountOnly()\n```\n\n### Edits\n\nEdits can be applied using the `applyEdits()` method.\n\n```javascript\nconst cat = await Cat\n  .applyEdits()\n  .add({ name: 'Grumpy' })\n  .exec();\n```\n\nThe following edits are possible:\n\n```javascript\n.add(features)\n```\n\n```javascript\n.update(features)\n```\n\n```javascript\n.delete(idArray)\n```\n\n```javascript\n.useGlobalIds() // default\n```\n\n```javascript\n.useObjectIds()\n```\n\n### Multi-layer Edits\n\nYou can also collect updates across multiple layers and execute them in a single REST call.\n\n```javascript\nconst schema = { name: String };\nconst Cat = await arcgoose.model(connection.layers.Cats, schema);\nconst Mouse = await arcgoose.model(connection.layers.Mice, schema);\n\nconst catHandle = Cat.applyEdits().add({ name: 'Tom' }).handle();\nconst mouseHandle = Mouse.applyEdits().add({ name: 'Jerry' }).handle();\n\narcgoose.execAll([catHandle, mouseHandle]);\n```\n\n## Authentication\n\nArcgoose is compatible with [@esri/arcgis-rest-auth](https://github.com/Esri/arcgis-rest-js/blob/master/packages/arcgis-rest-auth).\n\n```javascript\nimport { UserSession } from '@esri/arcgis-rest-auth';\n\nconst session = new UserSession({\n  username: \"casey\",\n  password: \"123456\"\n});\n\nconst connection = await arcgoose.connect({ url, authentication: session });\nconst Cat = await arcgoose.model(connection.layers.Cats, { name: String });\n\nconst cat = await Cat.findOne({ name: 'Grumpy' }).exec();\n```\n\n## Issues\n\nFind a bug or want to request a new feature?  Please let us know by submitting an issue.\n\n## Contributing\n\nEsri welcomes contributions from anyone and everyone. Please see our [guidelines for contributing](https://github.com/esri/contributing).\n\n## Licensing\nCopyright 2018 Esri\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nA copy of the license is available in the repository's [license.txt](/license.txt) file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fesri%2Farcgoose","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fesri%2Farcgoose","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fesri%2Farcgoose/lists"}