{"id":18401212,"url":"https://github.com/guillotinaweb/grange","last_synced_at":"2026-04-10T10:02:31.992Z","repository":{"id":54873726,"uuid":"216386499","full_name":"guillotinaweb/grange","owner":"guillotinaweb","description":"The Guillotina REST API aNGular Environment","archived":false,"fork":false,"pushed_at":"2021-01-23T09:09:06.000Z","size":1243,"stargazers_count":1,"open_issues_count":2,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-12-22T08:48:09.220Z","etag":null,"topics":["angular","grange","guillotina","pastanaga"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/guillotinaweb.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2019-10-20T15:47:59.000Z","updated_at":"2021-01-23T09:08:03.000Z","dependencies_parsed_at":"2022-08-14T05:20:43.253Z","dependency_job_id":null,"html_url":"https://github.com/guillotinaweb/grange","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/guillotinaweb/grange","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guillotinaweb%2Fgrange","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guillotinaweb%2Fgrange/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guillotinaweb%2Fgrange/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guillotinaweb%2Fgrange/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/guillotinaweb","download_url":"https://codeload.github.com/guillotinaweb/grange/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guillotinaweb%2Fgrange/sbom","scorecard":{"id":448836,"data":{"date":"2025-08-11","repo":{"name":"github.com/guillotinaweb/grange","commit":"54eb85f970c1901b261757f5eda6ed4ebe386d71"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.3,"checks":[{"name":"Code-Review","score":1,"reason":"Found 1/10 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Warn: no topLevel permission defined: .github/workflows/deploy.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:9: update your workflow using https://app.stepsecurity.io/secureworkflow/guillotinaweb/grange/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/guillotinaweb/grange/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/deploy.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/guillotinaweb/grange/deploy.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/deploy.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/guillotinaweb/grange/deploy.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/deploy.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/guillotinaweb/grange/deploy.yml/master?enable=pin","Warn: npmCommand not pinned by hash: .github/workflows/ci.yml:13","Warn: npmCommand not pinned by hash: .github/workflows/deploy.yml:17","Info:   0 out of   4 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   0 out of   2 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":0,"reason":"license file not detected","details":["Warn: project does not have a license file"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 26 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"125 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-hxwm-x553-x359","Warn: Project is vulnerable to: GHSA-6chw-6frg-f759","Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-whgm-jr23-g3j9","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-fwr7-v2mv-hh25","Warn: Project is vulnerable to: GHSA-qwcr-r2fm-qrc7","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-x9w5-v3q2-3rhw","Warn: Project is vulnerable to: GHSA-w8qv-6jwh-64r5","Warn: Project is vulnerable to: GHSA-257v-vj4p-3w2h","Warn: Project is vulnerable to: GHSA-pxg6-pf52-xh8x","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-3wcq-x3mq-6r9p","Warn: Project is vulnerable to: GHSA-r9p9-mrjm-926w","Warn: Project is vulnerable to: GHSA-434g-2637-qmqr","Warn: Project is vulnerable to: GHSA-49q7-c7j4-3p7m","Warn: Project is vulnerable to: GHSA-977x-g7h5-7qgw","Warn: Project is vulnerable to: GHSA-f7q4-pwc6-w24p","Warn: Project is vulnerable to: GHSA-fc9h-whq2-v747","Warn: Project is vulnerable to: GHSA-vjh7-7g9h-fjfh","Warn: Project is vulnerable to: GHSA-4gmj-3p3h-gm8h","Warn: Project is vulnerable to: GHSA-6h5x-7c5m-7cr7","Warn: Project is vulnerable to: GHSA-rv95-896h-c2vc","Warn: Project is vulnerable to: GHSA-qw6h-vgh9-j6wx","Warn: Project is vulnerable to: GHSA-74fj-2j2h-c42q","Warn: Project is vulnerable to: GHSA-pw2r-vq6v-hr8c","Warn: Project is vulnerable to: GHSA-jchw-25xp-jwwc","Warn: Project is vulnerable to: GHSA-cxjh-pqwp-8mfp","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-8r6j-v8pm-fqw3","Warn: Project is vulnerable to: MAL-2023-462","Warn: Project is vulnerable to: GHSA-ww39-953v-wcq6","Warn: Project is vulnerable to: GHSA-62gr-4qp9-h98f","Warn: Project is vulnerable to: GHSA-f52g-6jhx-586p","Warn: Project is vulnerable to: GHSA-2cf5-4w76-r9qv","Warn: Project is vulnerable to: GHSA-3cqr-58rm-57f8","Warn: Project is vulnerable to: GHSA-g9r4-xpmj-mj65","Warn: Project is vulnerable to: GHSA-q2c6-c6pm-g3gh","Warn: Project is vulnerable to: GHSA-765h-qjxv-5f44","Warn: Project is vulnerable to: GHSA-f2jv-r9rf-7988","Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj","Warn: Project is vulnerable to: GHSA-rc47-6667-2j5j","Warn: Project is vulnerable to: GHSA-c7qv-q95q-8v27","Warn: Project is vulnerable to: GHSA-qqgx-2p2h-9c37","Warn: Project is vulnerable to: GHSA-78xj-cgh5-2h22","Warn: Project is vulnerable to: GHSA-2p57-rm9w-gvfp","Warn: Project is vulnerable to: GHSA-7r28-3m3f-r2pr","Warn: Project is vulnerable to: GHSA-r8j5-h5cx-65gg","Warn: Project is vulnerable to: GHSA-896r-f27r-55mw","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-jg8v-48h5-wgxg","Warn: Project is vulnerable to: GHSA-36fh-84j7-cv5h","Warn: Project is vulnerable to: GHSA-6c8f-qphg-qjgp","Warn: Project is vulnerable to: GHSA-76p3-8jx3-jpfq","Warn: Project is vulnerable to: GHSA-3rfm-jhwj-7488","Warn: Project is vulnerable to: GHSA-hhq3-ff78-jv3g","Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-qrpm-p2h7-hrv2","Warn: Project is vulnerable to: GHSA-mwcw-c2x4-8c55","Warn: Project is vulnerable to: GHSA-5rrq-pxf6-6jx5","Warn: Project is vulnerable to: GHSA-8fr3-hfg3-gpgp","Warn: Project is vulnerable to: GHSA-gf8q-jrpm-jvxq","Warn: Project is vulnerable to: GHSA-2r2c-g63r-vccr","Warn: Project is vulnerable to: GHSA-cfm4-qjh2-4765","Warn: Project is vulnerable to: GHSA-x4jg-mjrx-434g","Warn: Project is vulnerable to: GHSA-5fw9-fq32-wv5p","Warn: Project is vulnerable to: GHSA-rp65-9cf3-cjxr","Warn: Project is vulnerable to: GHSA-76c9-3jph-rj3q","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j","Warn: Project is vulnerable to: GHSA-rhx6-c78j-4q9w","Warn: Project is vulnerable to: GHSA-h7cp-r72f-jxh6","Warn: Project is vulnerable to: GHSA-v62p-rq8g-8h59","Warn: Project is vulnerable to: GHSA-566m-qj78-rww5","Warn: Project is vulnerable to: GHSA-hwj9-h5mp-3pm3","Warn: Project is vulnerable to: GHSA-7fh5-64p2-3v2j","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-m6fv-jmcg-4jfg","Warn: Project is vulnerable to: GHSA-cm22-4g7w-348p","Warn: Project is vulnerable to: GHSA-3f95-r44v-8mrg","Warn: Project is vulnerable to: GHSA-28xr-mwxg-3qc8","Warn: Project is vulnerable to: GHSA-9p95-fxvg-qgq2","Warn: Project is vulnerable to: GHSA-9w5j-4mwv-2wj8","Warn: Project is vulnerable to: GHSA-vx3p-948g-6vhq","Warn: Project is vulnerable to: GHSA-3jfq-g458-7qm9","Warn: Project is vulnerable to: GHSA-r628-mhmh-qjhw","Warn: Project is vulnerable to: GHSA-9r2w-394v-53qc","Warn: Project is vulnerable to: GHSA-5955-9wpr-37jh","Warn: Project is vulnerable to: GHSA-qq89-hq3f-393p","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-4wf5-vphf-c2xc","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-jgrx-mgxx-jf9v","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-9m6j-fcg5-2442","Warn: Project is vulnerable to: GHSA-hh27-ffr2-f2jc","Warn: Project is vulnerable to: GHSA-rqff-837h-mm52","Warn: Project is vulnerable to: GHSA-8v38-pw62-9cw2","Warn: Project is vulnerable to: GHSA-hgjh-723h-mx2j","Warn: Project is vulnerable to: GHSA-jf5r-8hm2-f872","Warn: Project is vulnerable to: GHSA-qgmg-gppg-76g5","Warn: Project is vulnerable to: GHSA-xx4c-jj58-r7x6","Warn: Project is vulnerable to: GHSA-wr3j-pwj9-hqq6","Warn: Project is vulnerable to: GHSA-4v9v-hfq4-rm2v","Warn: Project is vulnerable to: GHSA-9jgg-88mc-972h","Warn: Project is vulnerable to: GHSA-6fc8-4gx4-v693","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q","Warn: Project is vulnerable to: GHSA-776f-qx25-q3cc","Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh","Warn: Project is vulnerable to: GHSA-p9pc-299p-vxgp"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-19T07:37:53.215Z","repository_id":54873726,"created_at":"2025-08-19T07:37:53.216Z","updated_at":"2025-08-19T07:37:53.216Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31637748,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-10T07:40:12.752Z","status":"ssl_error","status_checked_at":"2026-04-10T07:40:11.664Z","response_time":98,"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":["angular","grange","guillotina","pastanaga"],"created_at":"2024-11-06T02:38:08.335Z","updated_at":"2026-04-10T10:02:31.968Z","avatar_url":"https://github.com/guillotinaweb.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Grange\n\n[![Build Status](https://github.com/guillotinaweb/grange/workflows/CI/badge.svg)](https://github.com/guillotinaweb/grange/actions?query=workflow%3ACI)\n\nThe Guillotina REST API aNGular Environment.\n\nThe Grange is a rich extensible development toolkit.\n\nIt provides ready-to-use components and features (like login form, rich UI library, form generator, breadcrumbs, etc.).\n\nIt offers support for standard CRUD use-cases, allowing to build simple applications very rapidly.\n\nComplex applications are supported too as the Grange is highly extensible and all the default views can be overridden.\n\n## Principles\n\nA Grange app is able to render any object served by the Guillotina backend.\n\nIt will use the path requested on the frontend to call the corresponding Guillotina object, like `http://localhost:4200/shoes/pink-boots` will produce a call to `https://my-guillotina-server/db/app1/shoes/pink-boots` (assuming our Guillotina container supporting our app is named `app1`).\n\nLet's assume the `pink-boots` object belongs to the `Shoes` type (a custom type defined in `app1`), it will be rendered using the default view (named `view`).\n\nThis view will be the generic `view` view unless we override the generic view with a custom one in order to make a specific rendering for shoes:\n\n```typescript\nthis.grange.traverser.addView('view', 'Shoes', MyCustomShoesView);\n```\n\nIf we try to access `http://localhost:4200/shoes/pink-boots/@@edit`, then the app will use the `edit` view (assuming the current user is allowed to modify the `pink-boots` object).\n\nWe can also define custom views, like:\n\n```typescript\nthis.grange.traverser.addView('buy', 'Shoes', BuyShoesView);\n```\n\nIt will make `http://localhost:4200/shoes/pink-boots/@@buy` a valid path.\n\nWhen creating a custom view, we can use ready-to-use components (like breadcrumbs, form generator for editing, etc.) directly in the template, and we can use the Grange service to implement custom features in the TypeScript component.\n\nThe good thing about a Grange app is it is totally neutral about the Guillotina backend. It does not assume any hierarchical structure (like our shoes are not meant to be in `/shoes` folder, if we have some shoes object in `/autumn/new-shoes/red-sleepers`, the app can render it). It does not even assume what are the content types, we could make our Shoe type folderish and make an addable type to display shoes pictures named ShoesPicture, the app will offer the Add button in the actions components, the create form will work for ShoesPicture, etc. (we probably want to implement some custom views for our ShoesPicture type, nevertheless the basic CRUD scenario would be working without any change).\n\n## Building a basic Grange app\n\n### Init a Grange project\n\nIf you don't have one already, create an angular project:\n\n```\nng new my-project\n```\n\nIn your Angular project, install Grange:\n\n```\nnpm install @guillotinaweb/grange-schematic\nng add @guillotinaweb/grange-schematic\n```\n\nRun Guillotina (it requires Docker):\n\n```\nnpm run guillotina\n```\n\nImport in the `app.module.ts` the Grange module plus a minimal NgRx store, and provide the Guillotina backend URL to our container:\n\n```typescript\nimport { GrangeRootModule } from '@guillotinaweb/grange';\nimport { TraversalModule } from 'angular-traversal';\nimport { StoreModule } from '@ngrx/store';\n\n...\n    imports: [\n        ...\n        GrangeRootModule.forRoot(),\n        StoreModule.forRoot(\n            {},\n            {\n                runtimeChecks: {\n                    strictStateImmutability: false,\n                    strictActionImmutability: false,\n                },\n            }\n        ),\n        TraversalModule,\n    ],\n    providers: [\n        {\n            provide: 'CONFIGURATION',\n            useValue: {\n                BACKEND_URL: 'http://127.0.0.1:8081/db/site',\n                CLIENT_TIMEOUT: 5000,\n            },\n        },\n    ],\n```\n\nInitialize the default views in `app.component.ts`:\n\n```typescript\nexport class AppComponent {\n    constructor(private views: GrangeViews) {\n        this.views.initialize();\n    }\n}\n```\n\nSet the `traverser-outlet` in `app.component.html`:\n\n```html\n\u003ctraverser-outlet\u003e\u003c/traverser-outlet\u003e\n```\n\nRun the application:\n\n```\nnpm start\n```\n\nOur Angular app is now offering all Grange standard views (login, content creation, view, etc.).\nWe can login as root/root. By clicking on the \"Plus\" button, we get the available content types and we can a new content.\nOnce created we can delete it or edit it. The edit form is automatically generated based on the content type schema provided by Guillotina.\n\nSee [Grange tutorial](https://github.com/guillotinaweb/grange/blob/master/docs/TUTORAL.md) for more advanced examples.\n\n## Reference\n\n### Grange views\n\n#### `view`\n\nIt is the default view for a non-folderish object. It just displays the title and description of the current context object.\n\nIt also contains the CRUD actions component (add/edit/delete).\n\n#### `add`\n\nThe `add` view will either open a creation form for the type passed as parameter, either presents the list of addable contents in the current context.\n\nBy selecting one, we are redirected to `./@@add?type=\u003cthe-type\u003e`.\n\n#### `edit`\n\nThe `edit` view displays a form allowing to modify the current object.\n\nThe form is dynamically generated according the current object schema provided by Guillotina.\n\n#### `folder`\n\nIt is the default view for a folderish object. It displays the title and description of the current context object and links to its items.\n\nIt also contains the CRUD actions component (add/edit/delete).\n\n#### `login`\n\nThe `login` view displays a login form and redirects to `view` if login is successful.\n\n### Grange components\n\n#### CRUD actions\n\nThe `\u003cgrange-actions\u003e\u003c/grange-actions\u003e` component allows to display the Add / Edit / Delete buttons.\n\n#### Breadcrumbs\n\nThe `\u003cgrange-breadcrumbs\u003e\u003c/grange-breadcrumbs\u003e` component display the current breadcrumbs.\n\n#### Toasters\n\nBy adding the `\u003cgrange-toast-container\u003e\u003c/grange-toast-container\u003e` component in our main `app.component.html` template, we can use the toaster service to display toast messages:\n\n```typescript\nimport { Grange } from 'grange';\n...\n\n    constructor(private grange: Grange) {}\n\n    notify() {\n        this.grange.ui.toaster.open('Hello', 'Close');\n    }\n```\n\n### Services\n\nAll the services are accessible through the global `Grange` service\n\n```typescript\nimport { Grange } from 'grange';\n...\n\n    constructor(private grange: Grange) {}\n```\n\n### The Grange service itself\n\nThe `grange` service provides handy methods for the most common needs.\n\n`getContext()`: returns an Observable with the current traversed context.\n\n`updateContext(changes)`: update the current context with the provided changes.\nThe update will be performed in the state immediately, and the corresponding PATCH will be done on the backend.\nIf the backend call fails, a GET call is done to update the state with the actual value.\n\n#### The Traverser service\n\n`this.grange.traverser`\n\nIt allows to declare new views. For example to add a custome view to edit the player type:\n\n```typescript\nthis.grange.traverser.addView('edit', 'Player', EditPlayerPreferencesComponent);\n```\n\nIt allows to navigate to a given path:\n\n```typescript\nthis.grange.traverser.navigate(this.currentPlayer.team);\n```\n\n```typescript\nthis.grange.traverser.navigate(this.currentPlayer['@id'] + '/@@score');\n```\n\nIt also allows to load the context for a tile:\n\n```typescript\nthis.grange.traverser.loadTile('details', this.currentPlayer.team);\n```\n\nMore details in the [Angular traversal documentation](https://github.com/guillotinaweb/angular-traversal).\n\n#### Grange core\n\n`this.grange.core`\n\nThe core service provides access to:\n\n-   the authentication service, to login, logout, get the current username;\n-   the resource service to interact with the Guillotina resources (get, create, modify, delete, find, share, get children, get navigation links, breadcrumbs, etc.);\n-   the API service to handle all the low-level communications with the Guillotina backend: regular HTTP verbs or file downloading.\n\n#### Redux store\n\n`this.grange.store`\n\nIt allows to select state information or to dispatch actions. See below the \"State\" section.\n\n#### Grange UI\n\n`this.grange.ui`\n\nIt gives access to the main Pastanaga services: calendar, dialog, popup, sidebar, toaster and translate.\n\nSee \"Pastanaga UI library\" section below.\n\n### State\n\nGrange comes with a NgRx store.\n\nTO BE COMPLETED\n\n### Form generator\n\nThe Guillotina RESTAPI supports the JSON Schema standard.\n\nGrange uses ngx-schema-form to render any JSON Schema as a dynamic form. The form widgets use the Pastanaga library.\n\n```html\n\u003csf-form [schema]=\"schema\" [(model)]=\"editModel\"\u003e\u003c/sf-form\u003e\n```\n\n### Pastanaga UI library\n\nTO BE COMPLETED\n\n## Guillotina\n\nUseful Guillotina operations:\n\n-   create an app container for a new project\n\n```\ncurl -XPOST --user root:root http://127.0.0.1:8081/db -d '{\n  \"@type\": \"Container\",\n  \"id\": \"my-app\"\n}'\n```\n\n-   create a user\n\n```\ncurl -XPOST --user root:root http://127.0.0.1:8081/db/site/users -d '{\n    \"@type\": \"User\",\n    \"id\": \"inewton\",\n    \"username\": \"inewton\",\n    \"name\": \"Isaac Newton\",\n    \"email\": \"isaac@newton.org\",\n    \"password\": \"inewton\",\n    \"user_roles\": [\"guillotina.Member\"]\n}'\n```\n\n-   give reader access to a user\n\n```\ncurl -XPOST --user root:root http://127.0.0.1:8081/db/site/@sharing -d '{\n    \"prinrole\": [\n        {\n            \"principal\": \"inewton\",\n            \"role\": \"guillotina.Reader\",\n            \"setting\": \"Allow\"\n        }\n    ]\n}'\n```\n\n## Developers\n\nIf we want to run Grange into an Anugular project using the GitHub master branches of all the dependencies, we need to use mrs-developer:\n\n```\nnpm install mrs-developer\n```\n\nThen create the `mrs.developer.json`:\n\n```json\n{\n    \"angular-traversal\": {\n        \"path\": \"/projects/traversal/src/lib\",\n        \"url\": \"git@github.com:guillotinaweb/angular-traversal.git\",\n        \"https\": \"https://github.com/guillotinaweb/angular-traversal.git\",\n        \"branch\": \"master\"\n    },\n    \"grange\": {\n        \"url\": \"git@github.com:guillotinaweb/grange.git\",\n        \"https\": \"https://github.com/guillotinaweb/grange.git\",\n        \"path\": \"/projects/grange/src\",\n        \"branch\": \"master\"\n    },\n    \"grange-core\": {\n        \"url\": \"git@github.com:guillotinaweb/grange-core.git\",\n        \"https\": \"https://github.com/guillotinaweb/grange-core.git\",\n        \"path\": \"/projects/grange-core/src\",\n        \"branch\": \"master\"\n    },\n    \"grange-form\": {\n        \"path\": \"/projects/grange-form/src/lib\",\n        \"url\": \"git@github.com:guillotinaweb/grange-form.git\",\n        \"https\": \"https://github.com/guillotinaweb/grange-form.git\",\n        \"branch\": \"master\"\n    },\n    \"ngx-schema-form\": {\n        \"path\": \"/projects/schema-form/src/lib\",\n        \"url\": \"git@github.com:guillotinaweb/ngx-schema-form.git\",\n        \"https\": \"https://github.com/guillotinaweb/ngx-schema-form.git\",\n        \"branch\": \"master\"\n    },\n    \"ngx-state-traverser\": {\n        \"path\": \"/projects/ngx-state-traverser/src\",\n        \"url\": \"git@github.com:guillotinaweb/ngx-state-traverser.git\",\n        \"https\": \"https://github.com/guillotinaweb/ngx-state-traverser.git\",\n        \"branch\": \"master\"\n    }\n}\n```\n\n## Running Guillotina locally\n\n```\nnpm run guillotina\n```\n\nIt comes with few content types example, they can be easily adapted and extended by editing `g-api/config.yaml`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguillotinaweb%2Fgrange","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fguillotinaweb%2Fgrange","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguillotinaweb%2Fgrange/lists"}