diff --git a/docs/assets/css/main.css b/docs/assets/css/main.css new file mode 100644 index 00000000..1ffd2a30 --- /dev/null +++ b/docs/assets/css/main.css @@ -0,0 +1,2679 @@ +/*! normalize.css v1.1.3 | MIT License | git.io/normalize */ +/* ========================================================================== + * * HTML5 display definitions + * * ========================================================================== */ +/** + * * Correct `block` display not defined in IE 6/7/8/9 and Firefox 3. */ +article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary { + display: block; +} + +/** + * * Correct `inline-block` display not defined in IE 6/7/8/9 and Firefox 3. */ +audio, canvas, video { + display: inline-block; + *display: inline; + *zoom: 1; +} + +/** + * * Prevent modern browsers from displaying `audio` without controls. + * * Remove excess height in iOS 5 devices. */ +audio:not([controls]) { + display: none; + height: 0; +} + +/** + * * Address styling not present in IE 7/8/9, Firefox 3, and Safari 4. + * * Known issue: no IE 6 support. */ +[hidden] { + display: none; +} + +/* ========================================================================== + * * Base + * * ========================================================================== */ +/** + * * 1. Correct text resizing oddly in IE 6/7 when body `font-size` is set using + * * `em` units. + * * 2. Prevent iOS text size adjust after orientation change, without disabling + * * user zoom. */ +html { + font-size: 100%; + /* 1 */ + -ms-text-size-adjust: 100%; + /* 2 */ + -webkit-text-size-adjust: 100%; + /* 2 */ + font-family: sans-serif; +} + +/** + * * Address `font-family` inconsistency between `textarea` and other form + * * elements. */ +button, input, select, textarea { + font-family: sans-serif; +} + +/** + * * Address margins handled incorrectly in IE 6/7. */ +body { + margin: 0; +} + +/* ========================================================================== + * * Links + * * ========================================================================== */ +/** + * * Address `outline` inconsistency between Chrome and other browsers. */ +a:focus { + outline: thin dotted; +} +a:active, a:hover { + outline: 0; +} + +/** + * * Improve readability when focused and also mouse hovered in all browsers. */ +/* ========================================================================== + * * Typography + * * ========================================================================== */ +/** + * * Address font sizes and margins set differently in IE 6/7. + * * Address font sizes within `section` and `article` in Firefox 4+, Safari 5, + * * and Chrome. */ +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +h2 { + font-size: 1.5em; + margin: 0.83em 0; +} + +h3 { + font-size: 1.17em; + margin: 1em 0; +} + +h4, .tsd-index-panel h3 { + font-size: 1em; + margin: 1.33em 0; +} + +h5 { + font-size: 0.83em; + margin: 1.67em 0; +} + +h6 { + font-size: 0.67em; + margin: 2.33em 0; +} + +/** + * * Address styling not present in IE 7/8/9, Safari 5, and Chrome. */ +abbr[title] { + border-bottom: 1px dotted; +} + +/** + * * Address style set to `bolder` in Firefox 3+, Safari 4/5, and Chrome. */ +b, strong { + font-weight: bold; +} + +blockquote { + margin: 1em 40px; +} + +/** + * * Address styling not present in Safari 5 and Chrome. */ +dfn { + font-style: italic; +} + +/** + * * Address differences between Firefox and other browsers. + * * Known issue: no IE 6/7 normalization. */ +hr { + box-sizing: content-box; + height: 0; +} + +/** + * * Address styling not present in IE 6/7/8/9. */ +mark { + background: #ff0; + color: #000; +} + +/** + * * Address margins set differently in IE 6/7. */ +p, pre { + margin: 1em 0; +} + +/** + * * Correct font family set oddly in IE 6, Safari 4/5, and Chrome. */ +code, kbd, pre, samp { + font-family: monospace, serif; + _font-family: "courier new", monospace; + font-size: 1em; +} + +/** + * * Improve readability of pre-formatted text in all browsers. */ +pre { + white-space: pre; + white-space: pre-wrap; + word-wrap: break-word; +} + +/** + * * Address CSS quotes not supported in IE 6/7. */ +q { + quotes: none; +} +q:before, q:after { + content: ""; + content: none; +} + +/** + * * Address `quotes` property not supported in Safari 4. */ +/** + * * Address inconsistent and variable font size in all browsers. */ +small { + font-size: 80%; +} + +/** + * * Prevent `sub` and `sup` affecting `line-height` in all browsers. */ +sub { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* ========================================================================== + * * Lists + * * ========================================================================== */ +/** + * * Address margins set differently in IE 6/7. */ +dl, menu, ol, ul { + margin: 1em 0; +} + +dd { + margin: 0 0 0 40px; +} + +/** + * * Address paddings set differently in IE 6/7. */ +menu, ol, ul { + padding: 0 0 0 40px; +} + +/** + * * Correct list images handled incorrectly in IE 7. */ +nav ul, nav ol { + list-style: none; + list-style-image: none; +} + +/* ========================================================================== + * * Embedded content + * * ========================================================================== */ +/** + * * 1. Remove border when inside `a` element in IE 6/7/8/9 and Firefox 3. + * * 2. Improve image quality when scaled in IE 7. */ +img { + border: 0; + /* 1 */ + -ms-interpolation-mode: bicubic; +} + +/* 2 */ +/** + * * Correct overflow displayed oddly in IE 9. */ +svg:not(:root) { + overflow: hidden; +} + +/* ========================================================================== + * * Figures + * * ========================================================================== */ +/** + * * Address margin not present in IE 6/7/8/9, Safari 5, and Opera 11. */ +figure, form { + margin: 0; +} + +/* ========================================================================== + * * Forms + * * ========================================================================== */ +/** + * * Correct margin displayed oddly in IE 6/7. */ +/** + * * Define consistent border, margin, and padding. */ +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/** + * * 1. Correct color not being inherited in IE 6/7/8/9. + * * 2. Correct text not wrapping in Firefox 3. + * * 3. Correct alignment displayed oddly in IE 6/7. */ +legend { + border: 0; + /* 1 */ + padding: 0; + white-space: normal; + /* 2 */ + *margin-left: -7px; +} + +/* 3 */ +/** + * * 1. Correct font size not being inherited in all browsers. + * * 2. Address margins set differently in IE 6/7, Firefox 3+, Safari 5, + * * and Chrome. + * * 3. Improve appearance and consistency in all browsers. */ +button, input, select, textarea { + font-size: 100%; + /* 1 */ + margin: 0; + /* 2 */ + vertical-align: baseline; + /* 3 */ + *vertical-align: middle; +} + +/* 3 */ +/** + * * Address Firefox 3+ setting `line-height` on `input` using `!important` in + * * the UA stylesheet. */ +button, input { + line-height: normal; +} + +/** + * * Address inconsistent `text-transform` inheritance for `button` and `select`. + * * All other form control elements do not inherit `text-transform` values. + * * Correct `button` style inheritance in Chrome, Safari 5+, and IE 6+. + * * Correct `select` style inheritance in Firefox 4+ and Opera. */ +button, select { + text-transform: none; +} + +/** + * * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * * and `video` controls. + * * 2. Correct inability to style clickable `input` types in iOS. + * * 3. Improve usability and consistency of cursor style between image-type + * * `input` and others. + * * 4. Remove inner spacing in IE 7 without affecting normal text inputs. + * * Known issue: inner spacing remains in IE 6. */ +button, html input[type=button] { + -webkit-appearance: button; + /* 2 */ + cursor: pointer; + /* 3 */ + *overflow: visible; +} + +/* 4 */ +input[type=reset], input[type=submit] { + -webkit-appearance: button; + /* 2 */ + cursor: pointer; + /* 3 */ + *overflow: visible; +} + +/* 4 */ +/** + * * Re-set default cursor for disabled elements. */ +button[disabled], html input[disabled] { + cursor: default; +} + +/** + * * 1. Address box sizing set to content-box in IE 8/9. + * * 2. Remove excess padding in IE 8/9. + * * 3. Remove excess padding in IE 7. + * * Known issue: excess padding remains in IE 6. */ +input { + /* 3 */ +} +input[type=checkbox], input[type=radio] { + box-sizing: border-box; + /* 1 */ + padding: 0; + /* 2 */ + *height: 13px; + /* 3 */ + *width: 13px; +} +input[type=search] { + -webkit-appearance: textfield; + /* 1 */ + /* 2 */ + box-sizing: content-box; +} +input[type=search]::-webkit-search-cancel-button, input[type=search]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. + * * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome + * * (include `-moz` to future-proof). */ +/** + * * Remove inner padding and search cancel button in Safari 5 and Chrome + * * on OS X. */ +/** + * * Remove inner padding and border in Firefox 3+. */ +button::-moz-focus-inner, input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/** + * * 1. Remove default vertical scrollbar in IE 6/7/8/9. + * * 2. Improve readability and alignment in all browsers. */ +textarea { + overflow: auto; + /* 1 */ + vertical-align: top; +} + +/* 2 */ +/* ========================================================================== + * * Tables + * * ========================================================================== */ +/** + * * Remove most spacing between table cells. */ +table { + border-collapse: collapse; + border-spacing: 0; +} + +/* * + * *Visual Studio-like style based on original C# coloring by Jason Diamond */ +.hljs { + display: inline-block; + padding: 0.5em; + background: white; + color: black; +} + +.hljs-comment, .hljs-annotation, .hljs-template_comment, .diff .hljs-header, .hljs-chunk, .apache .hljs-cbracket { + color: #008000; +} + +.hljs-keyword, .hljs-id, .hljs-built_in, .css .smalltalk .hljs-class, .hljs-winutils, .bash .hljs-variable, .tex .hljs-command, .hljs-request, .hljs-status, .nginx .hljs-title { + color: #00f; +} + +.xml .hljs-tag { + color: #00f; +} +.xml .hljs-tag .hljs-value { + color: #00f; +} + +.hljs-string, .hljs-title, .hljs-parent, .hljs-tag .hljs-value, .hljs-rules .hljs-value { + color: #a31515; +} + +.ruby .hljs-symbol { + color: #a31515; +} +.ruby .hljs-symbol .hljs-string { + color: #a31515; +} + +.hljs-template_tag, .django .hljs-variable, .hljs-addition, .hljs-flow, .hljs-stream, .apache .hljs-tag, .hljs-date, .tex .hljs-formula, .coffeescript .hljs-attribute { + color: #a31515; +} + +.ruby .hljs-string, .hljs-decorator, .hljs-filter .hljs-argument, .hljs-localvars, .hljs-array, .hljs-attr_selector, .hljs-pseudo, .hljs-pi, .hljs-doctype, .hljs-deletion, .hljs-envvar, .hljs-shebang, .hljs-preprocessor, .hljs-pragma, .userType, .apache .hljs-sqbracket, .nginx .hljs-built_in, .tex .hljs-special, .hljs-prompt { + color: #2b91af; +} + +.hljs-phpdoc, .hljs-javadoc, .hljs-xmlDocTag { + color: #808080; +} + +.vhdl .hljs-typename { + font-weight: bold; +} +.vhdl .hljs-string { + color: #666666; +} +.vhdl .hljs-literal { + color: #a31515; +} +.vhdl .hljs-attribute { + color: #00b0e8; +} + +.xml .hljs-attribute { + color: #f00; +} + +ul.tsd-descriptions > li > :first-child, .tsd-panel > :first-child, .col > :first-child, .col-11 > :first-child, .col-10 > :first-child, .col-9 > :first-child, .col-8 > :first-child, .col-7 > :first-child, .col-6 > :first-child, .col-5 > :first-child, .col-4 > :first-child, .col-3 > :first-child, .col-2 > :first-child, .col-1 > :first-child, +ul.tsd-descriptions > li > :first-child > :first-child, +.tsd-panel > :first-child > :first-child, +.col > :first-child > :first-child, +.col-11 > :first-child > :first-child, +.col-10 > :first-child > :first-child, +.col-9 > :first-child > :first-child, +.col-8 > :first-child > :first-child, +.col-7 > :first-child > :first-child, +.col-6 > :first-child > :first-child, +.col-5 > :first-child > :first-child, +.col-4 > :first-child > :first-child, +.col-3 > :first-child > :first-child, +.col-2 > :first-child > :first-child, +.col-1 > :first-child > :first-child, +ul.tsd-descriptions > li > :first-child > :first-child > :first-child, +.tsd-panel > :first-child > :first-child > :first-child, +.col > :first-child > :first-child > :first-child, +.col-11 > :first-child > :first-child > :first-child, +.col-10 > :first-child > :first-child > :first-child, +.col-9 > :first-child > :first-child > :first-child, +.col-8 > :first-child > :first-child > :first-child, +.col-7 > :first-child > :first-child > :first-child, +.col-6 > :first-child > :first-child > :first-child, +.col-5 > :first-child > :first-child > :first-child, +.col-4 > :first-child > :first-child > :first-child, +.col-3 > :first-child > :first-child > :first-child, +.col-2 > :first-child > :first-child > :first-child, +.col-1 > :first-child > :first-child > :first-child { + margin-top: 0; +} +ul.tsd-descriptions > li > :last-child, .tsd-panel > :last-child, .col > :last-child, .col-11 > :last-child, .col-10 > :last-child, .col-9 > :last-child, .col-8 > :last-child, .col-7 > :last-child, .col-6 > :last-child, .col-5 > :last-child, .col-4 > :last-child, .col-3 > :last-child, .col-2 > :last-child, .col-1 > :last-child, +ul.tsd-descriptions > li > :last-child > :last-child, +.tsd-panel > :last-child > :last-child, +.col > :last-child > :last-child, +.col-11 > :last-child > :last-child, +.col-10 > :last-child > :last-child, +.col-9 > :last-child > :last-child, +.col-8 > :last-child > :last-child, +.col-7 > :last-child > :last-child, +.col-6 > :last-child > :last-child, +.col-5 > :last-child > :last-child, +.col-4 > :last-child > :last-child, +.col-3 > :last-child > :last-child, +.col-2 > :last-child > :last-child, +.col-1 > :last-child > :last-child, +ul.tsd-descriptions > li > :last-child > :last-child > :last-child, +.tsd-panel > :last-child > :last-child > :last-child, +.col > :last-child > :last-child > :last-child, +.col-11 > :last-child > :last-child > :last-child, +.col-10 > :last-child > :last-child > :last-child, +.col-9 > :last-child > :last-child > :last-child, +.col-8 > :last-child > :last-child > :last-child, +.col-7 > :last-child > :last-child > :last-child, +.col-6 > :last-child > :last-child > :last-child, +.col-5 > :last-child > :last-child > :last-child, +.col-4 > :last-child > :last-child > :last-child, +.col-3 > :last-child > :last-child > :last-child, +.col-2 > :last-child > :last-child > :last-child, +.col-1 > :last-child > :last-child > :last-child { + margin-bottom: 0; +} + +.container { + max-width: 1200px; + margin: 0 auto; + padding: 0 40px; +} +@media (max-width: 640px) { + .container { + padding: 0 20px; + } +} + +.container-main { + padding-bottom: 200px; +} + +.row { + display: -ms-flexbox; + display: flex; + position: relative; + margin: 0 -10px; +} +.row:after { + visibility: hidden; + display: block; + content: ""; + clear: both; + height: 0; +} + +.col, .col-11, .col-10, .col-9, .col-8, .col-7, .col-6, .col-5, .col-4, .col-3, .col-2, .col-1 { + box-sizing: border-box; + float: left; + padding: 0 10px; +} + +.col-1 { + width: 8.3333333333%; +} + +.offset-1 { + margin-left: 8.3333333333%; +} + +.col-2 { + width: 16.6666666667%; +} + +.offset-2 { + margin-left: 16.6666666667%; +} + +.col-3 { + width: 25%; +} + +.offset-3 { + margin-left: 25%; +} + +.col-4 { + width: 33.3333333333%; +} + +.offset-4 { + margin-left: 33.3333333333%; +} + +.col-5 { + width: 41.6666666667%; +} + +.offset-5 { + margin-left: 41.6666666667%; +} + +.col-6 { + width: 50%; +} + +.offset-6 { + margin-left: 50%; +} + +.col-7 { + width: 58.3333333333%; +} + +.offset-7 { + margin-left: 58.3333333333%; +} + +.col-8 { + width: 66.6666666667%; +} + +.offset-8 { + margin-left: 66.6666666667%; +} + +.col-9 { + width: 75%; +} + +.offset-9 { + margin-left: 75%; +} + +.col-10 { + width: 83.3333333333%; +} + +.offset-10 { + margin-left: 83.3333333333%; +} + +.col-11 { + width: 91.6666666667%; +} + +.offset-11 { + margin-left: 91.6666666667%; +} + +.tsd-kind-icon { + display: block; + position: relative; + padding-left: 20px; + text-indent: -20px; +} +.tsd-kind-icon:before { + content: ""; + display: inline-block; + vertical-align: middle; + width: 17px; + height: 17px; + margin: 0 3px 2px 0; + background-image: url(../images/icons.png); +} +@media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { + .tsd-kind-icon:before { + background-image: url(../images/icons@2x.png); + background-size: 238px 204px; + } +} + +.tsd-signature.tsd-kind-icon:before { + background-position: 0 -153px; +} + +.tsd-kind-object-literal > .tsd-kind-icon:before { + background-position: 0px -17px; +} +.tsd-kind-object-literal.tsd-is-protected > .tsd-kind-icon:before { + background-position: -17px -17px; +} +.tsd-kind-object-literal.tsd-is-private > .tsd-kind-icon:before { + background-position: -34px -17px; +} + +.tsd-kind-class > .tsd-kind-icon:before { + background-position: 0px -34px; +} +.tsd-kind-class.tsd-is-protected > .tsd-kind-icon:before { + background-position: -17px -34px; +} +.tsd-kind-class.tsd-is-private > .tsd-kind-icon:before { + background-position: -34px -34px; +} + +.tsd-kind-class.tsd-has-type-parameter > .tsd-kind-icon:before { + background-position: 0px -51px; +} +.tsd-kind-class.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before { + background-position: -17px -51px; +} +.tsd-kind-class.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { + background-position: -34px -51px; +} + +.tsd-kind-interface > .tsd-kind-icon:before { + background-position: 0px -68px; +} +.tsd-kind-interface.tsd-is-protected > .tsd-kind-icon:before { + background-position: -17px -68px; +} +.tsd-kind-interface.tsd-is-private > .tsd-kind-icon:before { + background-position: -34px -68px; +} + +.tsd-kind-interface.tsd-has-type-parameter > .tsd-kind-icon:before { + background-position: 0px -85px; +} +.tsd-kind-interface.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before { + background-position: -17px -85px; +} +.tsd-kind-interface.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { + background-position: -34px -85px; +} + +.tsd-kind-namespace > .tsd-kind-icon:before { + background-position: 0px -102px; +} +.tsd-kind-namespace.tsd-is-protected > .tsd-kind-icon:before { + background-position: -17px -102px; +} +.tsd-kind-namespace.tsd-is-private > .tsd-kind-icon:before { + background-position: -34px -102px; +} + +.tsd-kind-module > .tsd-kind-icon:before { + background-position: 0px -102px; +} +.tsd-kind-module.tsd-is-protected > .tsd-kind-icon:before { + background-position: -17px -102px; +} +.tsd-kind-module.tsd-is-private > .tsd-kind-icon:before { + background-position: -34px -102px; +} + +.tsd-kind-enum > .tsd-kind-icon:before { + background-position: 0px -119px; +} +.tsd-kind-enum.tsd-is-protected > .tsd-kind-icon:before { + background-position: -17px -119px; +} +.tsd-kind-enum.tsd-is-private > .tsd-kind-icon:before { + background-position: -34px -119px; +} + +.tsd-kind-enum-member > .tsd-kind-icon:before { + background-position: 0px -136px; +} +.tsd-kind-enum-member.tsd-is-protected > .tsd-kind-icon:before { + background-position: -17px -136px; +} +.tsd-kind-enum-member.tsd-is-private > .tsd-kind-icon:before { + background-position: -34px -136px; +} + +.tsd-kind-signature > .tsd-kind-icon:before { + background-position: 0px -153px; +} +.tsd-kind-signature.tsd-is-protected > .tsd-kind-icon:before { + background-position: -17px -153px; +} +.tsd-kind-signature.tsd-is-private > .tsd-kind-icon:before { + background-position: -34px -153px; +} + +.tsd-kind-type-alias > .tsd-kind-icon:before { + background-position: 0px -170px; +} +.tsd-kind-type-alias.tsd-is-protected > .tsd-kind-icon:before { + background-position: -17px -170px; +} +.tsd-kind-type-alias.tsd-is-private > .tsd-kind-icon:before { + background-position: -34px -170px; +} + +.tsd-kind-type-alias.tsd-has-type-parameter > .tsd-kind-icon:before { + background-position: 0px -187px; +} +.tsd-kind-type-alias.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before { + background-position: -17px -187px; +} +.tsd-kind-type-alias.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { + background-position: -34px -187px; +} + +.tsd-kind-variable > .tsd-kind-icon:before { + background-position: -136px -0px; +} +.tsd-kind-variable.tsd-is-protected > .tsd-kind-icon:before { + background-position: -153px -0px; +} +.tsd-kind-variable.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -0px; +} +.tsd-kind-variable.tsd-parent-kind-class > .tsd-kind-icon:before { + background-position: -51px -0px; +} +.tsd-kind-variable.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -68px -0px; +} +.tsd-kind-variable.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { + background-position: -85px -0px; +} +.tsd-kind-variable.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -102px -0px; +} +.tsd-kind-variable.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -0px; +} +.tsd-kind-variable.tsd-parent-kind-enum > .tsd-kind-icon:before { + background-position: -170px -0px; +} +.tsd-kind-variable.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { + background-position: -187px -0px; +} +.tsd-kind-variable.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -0px; +} +.tsd-kind-variable.tsd-parent-kind-interface > .tsd-kind-icon:before { + background-position: -204px -0px; +} +.tsd-kind-variable.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -221px -0px; +} + +.tsd-kind-property > .tsd-kind-icon:before { + background-position: -136px -0px; +} +.tsd-kind-property.tsd-is-protected > .tsd-kind-icon:before { + background-position: -153px -0px; +} +.tsd-kind-property.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -0px; +} +.tsd-kind-property.tsd-parent-kind-class > .tsd-kind-icon:before { + background-position: -51px -0px; +} +.tsd-kind-property.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -68px -0px; +} +.tsd-kind-property.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { + background-position: -85px -0px; +} +.tsd-kind-property.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -102px -0px; +} +.tsd-kind-property.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -0px; +} +.tsd-kind-property.tsd-parent-kind-enum > .tsd-kind-icon:before { + background-position: -170px -0px; +} +.tsd-kind-property.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { + background-position: -187px -0px; +} +.tsd-kind-property.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -0px; +} +.tsd-kind-property.tsd-parent-kind-interface > .tsd-kind-icon:before { + background-position: -204px -0px; +} +.tsd-kind-property.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -221px -0px; +} + +.tsd-kind-get-signature > .tsd-kind-icon:before { + background-position: -136px -17px; +} +.tsd-kind-get-signature.tsd-is-protected > .tsd-kind-icon:before { + background-position: -153px -17px; +} +.tsd-kind-get-signature.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -17px; +} +.tsd-kind-get-signature.tsd-parent-kind-class > .tsd-kind-icon:before { + background-position: -51px -17px; +} +.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -68px -17px; +} +.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { + background-position: -85px -17px; +} +.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -102px -17px; +} +.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -17px; +} +.tsd-kind-get-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { + background-position: -170px -17px; +} +.tsd-kind-get-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { + background-position: -187px -17px; +} +.tsd-kind-get-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -17px; +} +.tsd-kind-get-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { + background-position: -204px -17px; +} +.tsd-kind-get-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -221px -17px; +} + +.tsd-kind-set-signature > .tsd-kind-icon:before { + background-position: -136px -34px; +} +.tsd-kind-set-signature.tsd-is-protected > .tsd-kind-icon:before { + background-position: -153px -34px; +} +.tsd-kind-set-signature.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -34px; +} +.tsd-kind-set-signature.tsd-parent-kind-class > .tsd-kind-icon:before { + background-position: -51px -34px; +} +.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -68px -34px; +} +.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { + background-position: -85px -34px; +} +.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -102px -34px; +} +.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -34px; +} +.tsd-kind-set-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { + background-position: -170px -34px; +} +.tsd-kind-set-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { + background-position: -187px -34px; +} +.tsd-kind-set-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -34px; +} +.tsd-kind-set-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { + background-position: -204px -34px; +} +.tsd-kind-set-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -221px -34px; +} + +.tsd-kind-accessor > .tsd-kind-icon:before { + background-position: -136px -51px; +} +.tsd-kind-accessor.tsd-is-protected > .tsd-kind-icon:before { + background-position: -153px -51px; +} +.tsd-kind-accessor.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -51px; +} +.tsd-kind-accessor.tsd-parent-kind-class > .tsd-kind-icon:before { + background-position: -51px -51px; +} +.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -68px -51px; +} +.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { + background-position: -85px -51px; +} +.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -102px -51px; +} +.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -51px; +} +.tsd-kind-accessor.tsd-parent-kind-enum > .tsd-kind-icon:before { + background-position: -170px -51px; +} +.tsd-kind-accessor.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { + background-position: -187px -51px; +} +.tsd-kind-accessor.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -51px; +} +.tsd-kind-accessor.tsd-parent-kind-interface > .tsd-kind-icon:before { + background-position: -204px -51px; +} +.tsd-kind-accessor.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -221px -51px; +} + +.tsd-kind-function > .tsd-kind-icon:before { + background-position: -136px -68px; +} +.tsd-kind-function.tsd-is-protected > .tsd-kind-icon:before { + background-position: -153px -68px; +} +.tsd-kind-function.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -68px; +} +.tsd-kind-function.tsd-parent-kind-class > .tsd-kind-icon:before { + background-position: -51px -68px; +} +.tsd-kind-function.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -68px -68px; +} +.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { + background-position: -85px -68px; +} +.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -102px -68px; +} +.tsd-kind-function.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -68px; +} +.tsd-kind-function.tsd-parent-kind-enum > .tsd-kind-icon:before { + background-position: -170px -68px; +} +.tsd-kind-function.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { + background-position: -187px -68px; +} +.tsd-kind-function.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -68px; +} +.tsd-kind-function.tsd-parent-kind-interface > .tsd-kind-icon:before { + background-position: -204px -68px; +} +.tsd-kind-function.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -221px -68px; +} + +.tsd-kind-method > .tsd-kind-icon:before { + background-position: -136px -68px; +} +.tsd-kind-method.tsd-is-protected > .tsd-kind-icon:before { + background-position: -153px -68px; +} +.tsd-kind-method.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -68px; +} +.tsd-kind-method.tsd-parent-kind-class > .tsd-kind-icon:before { + background-position: -51px -68px; +} +.tsd-kind-method.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -68px -68px; +} +.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { + background-position: -85px -68px; +} +.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -102px -68px; +} +.tsd-kind-method.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -68px; +} +.tsd-kind-method.tsd-parent-kind-enum > .tsd-kind-icon:before { + background-position: -170px -68px; +} +.tsd-kind-method.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { + background-position: -187px -68px; +} +.tsd-kind-method.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -68px; +} +.tsd-kind-method.tsd-parent-kind-interface > .tsd-kind-icon:before { + background-position: -204px -68px; +} +.tsd-kind-method.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -221px -68px; +} + +.tsd-kind-call-signature > .tsd-kind-icon:before { + background-position: -136px -68px; +} +.tsd-kind-call-signature.tsd-is-protected > .tsd-kind-icon:before { + background-position: -153px -68px; +} +.tsd-kind-call-signature.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -68px; +} +.tsd-kind-call-signature.tsd-parent-kind-class > .tsd-kind-icon:before { + background-position: -51px -68px; +} +.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -68px -68px; +} +.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { + background-position: -85px -68px; +} +.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -102px -68px; +} +.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -68px; +} +.tsd-kind-call-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { + background-position: -170px -68px; +} +.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { + background-position: -187px -68px; +} +.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -68px; +} +.tsd-kind-call-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { + background-position: -204px -68px; +} +.tsd-kind-call-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -221px -68px; +} + +.tsd-kind-function.tsd-has-type-parameter > .tsd-kind-icon:before { + background-position: -136px -85px; +} +.tsd-kind-function.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before { + background-position: -153px -85px; +} +.tsd-kind-function.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -85px; +} +.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class > .tsd-kind-icon:before { + background-position: -51px -85px; +} +.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -68px -85px; +} +.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { + background-position: -85px -85px; +} +.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -102px -85px; +} +.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -85px; +} +.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum > .tsd-kind-icon:before { + background-position: -170px -85px; +} +.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { + background-position: -187px -85px; +} +.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -85px; +} +.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-interface > .tsd-kind-icon:before { + background-position: -204px -85px; +} +.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -221px -85px; +} + +.tsd-kind-method.tsd-has-type-parameter > .tsd-kind-icon:before { + background-position: -136px -85px; +} +.tsd-kind-method.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before { + background-position: -153px -85px; +} +.tsd-kind-method.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -85px; +} +.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class > .tsd-kind-icon:before { + background-position: -51px -85px; +} +.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -68px -85px; +} +.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { + background-position: -85px -85px; +} +.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -102px -85px; +} +.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -85px; +} +.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum > .tsd-kind-icon:before { + background-position: -170px -85px; +} +.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { + background-position: -187px -85px; +} +.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -85px; +} +.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-interface > .tsd-kind-icon:before { + background-position: -204px -85px; +} +.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -221px -85px; +} + +.tsd-kind-constructor > .tsd-kind-icon:before { + background-position: -136px -102px; +} +.tsd-kind-constructor.tsd-is-protected > .tsd-kind-icon:before { + background-position: -153px -102px; +} +.tsd-kind-constructor.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -102px; +} +.tsd-kind-constructor.tsd-parent-kind-class > .tsd-kind-icon:before { + background-position: -51px -102px; +} +.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -68px -102px; +} +.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { + background-position: -85px -102px; +} +.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -102px -102px; +} +.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -102px; +} +.tsd-kind-constructor.tsd-parent-kind-enum > .tsd-kind-icon:before { + background-position: -170px -102px; +} +.tsd-kind-constructor.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { + background-position: -187px -102px; +} +.tsd-kind-constructor.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -102px; +} +.tsd-kind-constructor.tsd-parent-kind-interface > .tsd-kind-icon:before { + background-position: -204px -102px; +} +.tsd-kind-constructor.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -221px -102px; +} + +.tsd-kind-constructor-signature > .tsd-kind-icon:before { + background-position: -136px -102px; +} +.tsd-kind-constructor-signature.tsd-is-protected > .tsd-kind-icon:before { + background-position: -153px -102px; +} +.tsd-kind-constructor-signature.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -102px; +} +.tsd-kind-constructor-signature.tsd-parent-kind-class > .tsd-kind-icon:before { + background-position: -51px -102px; +} +.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -68px -102px; +} +.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { + background-position: -85px -102px; +} +.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -102px -102px; +} +.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -102px; +} +.tsd-kind-constructor-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { + background-position: -170px -102px; +} +.tsd-kind-constructor-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { + background-position: -187px -102px; +} +.tsd-kind-constructor-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -102px; +} +.tsd-kind-constructor-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { + background-position: -204px -102px; +} +.tsd-kind-constructor-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -221px -102px; +} + +.tsd-kind-index-signature > .tsd-kind-icon:before { + background-position: -136px -119px; +} +.tsd-kind-index-signature.tsd-is-protected > .tsd-kind-icon:before { + background-position: -153px -119px; +} +.tsd-kind-index-signature.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -119px; +} +.tsd-kind-index-signature.tsd-parent-kind-class > .tsd-kind-icon:before { + background-position: -51px -119px; +} +.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -68px -119px; +} +.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { + background-position: -85px -119px; +} +.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -102px -119px; +} +.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -119px; +} +.tsd-kind-index-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { + background-position: -170px -119px; +} +.tsd-kind-index-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { + background-position: -187px -119px; +} +.tsd-kind-index-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -119px; +} +.tsd-kind-index-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { + background-position: -204px -119px; +} +.tsd-kind-index-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -221px -119px; +} + +.tsd-kind-event > .tsd-kind-icon:before { + background-position: -136px -136px; +} +.tsd-kind-event.tsd-is-protected > .tsd-kind-icon:before { + background-position: -153px -136px; +} +.tsd-kind-event.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -136px; +} +.tsd-kind-event.tsd-parent-kind-class > .tsd-kind-icon:before { + background-position: -51px -136px; +} +.tsd-kind-event.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -68px -136px; +} +.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { + background-position: -85px -136px; +} +.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -102px -136px; +} +.tsd-kind-event.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -136px; +} +.tsd-kind-event.tsd-parent-kind-enum > .tsd-kind-icon:before { + background-position: -170px -136px; +} +.tsd-kind-event.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { + background-position: -187px -136px; +} +.tsd-kind-event.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -136px; +} +.tsd-kind-event.tsd-parent-kind-interface > .tsd-kind-icon:before { + background-position: -204px -136px; +} +.tsd-kind-event.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -221px -136px; +} + +.tsd-is-static > .tsd-kind-icon:before { + background-position: -136px -153px; +} +.tsd-is-static.tsd-is-protected > .tsd-kind-icon:before { + background-position: -153px -153px; +} +.tsd-is-static.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -153px; +} +.tsd-is-static.tsd-parent-kind-class > .tsd-kind-icon:before { + background-position: -51px -153px; +} +.tsd-is-static.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -68px -153px; +} +.tsd-is-static.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { + background-position: -85px -153px; +} +.tsd-is-static.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -102px -153px; +} +.tsd-is-static.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -153px; +} +.tsd-is-static.tsd-parent-kind-enum > .tsd-kind-icon:before { + background-position: -170px -153px; +} +.tsd-is-static.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { + background-position: -187px -153px; +} +.tsd-is-static.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -153px; +} +.tsd-is-static.tsd-parent-kind-interface > .tsd-kind-icon:before { + background-position: -204px -153px; +} +.tsd-is-static.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -221px -153px; +} + +.tsd-is-static.tsd-kind-function > .tsd-kind-icon:before { + background-position: -136px -170px; +} +.tsd-is-static.tsd-kind-function.tsd-is-protected > .tsd-kind-icon:before { + background-position: -153px -170px; +} +.tsd-is-static.tsd-kind-function.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -170px; +} +.tsd-is-static.tsd-kind-function.tsd-parent-kind-class > .tsd-kind-icon:before { + background-position: -51px -170px; +} +.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -68px -170px; +} +.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { + background-position: -85px -170px; +} +.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -102px -170px; +} +.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -170px; +} +.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum > .tsd-kind-icon:before { + background-position: -170px -170px; +} +.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { + background-position: -187px -170px; +} +.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -170px; +} +.tsd-is-static.tsd-kind-function.tsd-parent-kind-interface > .tsd-kind-icon:before { + background-position: -204px -170px; +} +.tsd-is-static.tsd-kind-function.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -221px -170px; +} + +.tsd-is-static.tsd-kind-method > .tsd-kind-icon:before { + background-position: -136px -170px; +} +.tsd-is-static.tsd-kind-method.tsd-is-protected > .tsd-kind-icon:before { + background-position: -153px -170px; +} +.tsd-is-static.tsd-kind-method.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -170px; +} +.tsd-is-static.tsd-kind-method.tsd-parent-kind-class > .tsd-kind-icon:before { + background-position: -51px -170px; +} +.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -68px -170px; +} +.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { + background-position: -85px -170px; +} +.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -102px -170px; +} +.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -170px; +} +.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum > .tsd-kind-icon:before { + background-position: -170px -170px; +} +.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { + background-position: -187px -170px; +} +.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -170px; +} +.tsd-is-static.tsd-kind-method.tsd-parent-kind-interface > .tsd-kind-icon:before { + background-position: -204px -170px; +} +.tsd-is-static.tsd-kind-method.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -221px -170px; +} + +.tsd-is-static.tsd-kind-call-signature > .tsd-kind-icon:before { + background-position: -136px -170px; +} +.tsd-is-static.tsd-kind-call-signature.tsd-is-protected > .tsd-kind-icon:before { + background-position: -153px -170px; +} +.tsd-is-static.tsd-kind-call-signature.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -170px; +} +.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class > .tsd-kind-icon:before { + background-position: -51px -170px; +} +.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -68px -170px; +} +.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { + background-position: -85px -170px; +} +.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -102px -170px; +} +.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -170px; +} +.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { + background-position: -170px -170px; +} +.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { + background-position: -187px -170px; +} +.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -170px; +} +.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { + background-position: -204px -170px; +} +.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -221px -170px; +} + +.tsd-is-static.tsd-kind-event > .tsd-kind-icon:before { + background-position: -136px -187px; +} +.tsd-is-static.tsd-kind-event.tsd-is-protected > .tsd-kind-icon:before { + background-position: -153px -187px; +} +.tsd-is-static.tsd-kind-event.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -187px; +} +.tsd-is-static.tsd-kind-event.tsd-parent-kind-class > .tsd-kind-icon:before { + background-position: -51px -187px; +} +.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -68px -187px; +} +.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { + background-position: -85px -187px; +} +.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -102px -187px; +} +.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -187px; +} +.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum > .tsd-kind-icon:before { + background-position: -170px -187px; +} +.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { + background-position: -187px -187px; +} +.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { + background-position: -119px -187px; +} +.tsd-is-static.tsd-kind-event.tsd-parent-kind-interface > .tsd-kind-icon:before { + background-position: -204px -187px; +} +.tsd-is-static.tsd-kind-event.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { + background-position: -221px -187px; +} + +@keyframes fade-in { + from { + opacity: 0; + } + to { + opacity: 1; + } +} +@keyframes fade-out { + from { + opacity: 1; + visibility: visible; + } + to { + opacity: 0; + } +} +@keyframes fade-in-delayed { + 0% { + opacity: 0; + } + 33% { + opacity: 0; + } + 100% { + opacity: 1; + } +} +@keyframes fade-out-delayed { + 0% { + opacity: 1; + visibility: visible; + } + 66% { + opacity: 0; + } + 100% { + opacity: 0; + } +} +@keyframes shift-to-left { + from { + transform: translate(0, 0); + } + to { + transform: translate(-25%, 0); + } +} +@keyframes unshift-to-left { + from { + transform: translate(-25%, 0); + } + to { + transform: translate(0, 0); + } +} +@keyframes pop-in-from-right { + from { + transform: translate(100%, 0); + } + to { + transform: translate(0, 0); + } +} +@keyframes pop-out-to-right { + from { + transform: translate(0, 0); + visibility: visible; + } + to { + transform: translate(100%, 0); + } +} +body { + background: #fdfdfd; + font-family: "Segoe UI", sans-serif; + font-size: 16px; + color: #222; +} + +a { + color: #4da6ff; + text-decoration: none; +} +a:hover { + text-decoration: underline; +} + +code, pre { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; + padding: 0.2em; + margin: 0; + font-size: 14px; + background-color: rgba(0, 0, 0, 0.04); +} + +pre { + padding: 10px; +} +pre code { + padding: 0; + font-size: 100%; + background-color: transparent; +} + +.tsd-typography { + line-height: 1.333em; +} +.tsd-typography ul { + list-style: square; + padding: 0 0 0 20px; + margin: 0; +} +.tsd-typography h4, .tsd-typography .tsd-index-panel h3, .tsd-index-panel .tsd-typography h3, .tsd-typography h5, .tsd-typography h6 { + font-size: 1em; + margin: 0; +} +.tsd-typography h5, .tsd-typography h6 { + font-weight: normal; +} +.tsd-typography p, .tsd-typography ul, .tsd-typography ol { + margin: 1em 0; +} + +@media (min-width: 901px) and (max-width: 1024px) { + html.default .col-content { + width: 72%; + } + html.default .col-menu { + width: 28%; + } + html.default .tsd-navigation { + padding-left: 10px; + } +} +@media (max-width: 900px) { + html.default .col-content { + float: none; + width: 100%; + } + html.default .col-menu { + position: fixed !important; + overflow: auto; + -webkit-overflow-scrolling: touch; + z-index: 1024; + top: 0 !important; + bottom: 0 !important; + left: auto !important; + right: 0 !important; + width: 100%; + padding: 20px 20px 0 0; + max-width: 450px; + visibility: hidden; + background-color: #fff; + transform: translate(100%, 0); + } + html.default .col-menu > *:last-child { + padding-bottom: 20px; + } + html.default .overlay { + content: ""; + display: block; + position: fixed; + z-index: 1023; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.75); + visibility: hidden; + } + html.default.to-has-menu .overlay { + animation: fade-in 0.4s; + } + html.default.to-has-menu header, +html.default.to-has-menu footer, +html.default.to-has-menu .col-content { + animation: shift-to-left 0.4s; + } + html.default.to-has-menu .col-menu { + animation: pop-in-from-right 0.4s; + } + html.default.from-has-menu .overlay { + animation: fade-out 0.4s; + } + html.default.from-has-menu header, +html.default.from-has-menu footer, +html.default.from-has-menu .col-content { + animation: unshift-to-left 0.4s; + } + html.default.from-has-menu .col-menu { + animation: pop-out-to-right 0.4s; + } + html.default.has-menu body { + overflow: hidden; + } + html.default.has-menu .overlay { + visibility: visible; + } + html.default.has-menu header, +html.default.has-menu footer, +html.default.has-menu .col-content { + transform: translate(-25%, 0); + } + html.default.has-menu .col-menu { + visibility: visible; + transform: translate(0, 0); + } +} + +.tsd-page-title { + padding: 70px 0 20px 0; + margin: 0 0 40px 0; + background: #fff; + box-shadow: 0 0 5px rgba(0, 0, 0, 0.35); +} +.tsd-page-title h1 { + margin: 0; +} + +.tsd-breadcrumb { + margin: 0; + padding: 0; + color: #808080; +} +.tsd-breadcrumb a { + color: #808080; + text-decoration: none; +} +.tsd-breadcrumb a:hover { + text-decoration: underline; +} +.tsd-breadcrumb li { + display: inline; +} +.tsd-breadcrumb li:after { + content: " / "; +} + +html.minimal .container { + margin: 0; +} +html.minimal .container-main { + padding-top: 50px; + padding-bottom: 0; +} +html.minimal .content-wrap { + padding-left: 300px; +} +html.minimal .tsd-navigation { + position: fixed !important; + overflow: auto; + -webkit-overflow-scrolling: touch; + box-sizing: border-box; + z-index: 1; + left: 0; + top: 40px; + bottom: 0; + width: 300px; + padding: 20px; + margin: 0; +} +html.minimal .tsd-member .tsd-member { + margin-left: 0; +} +html.minimal .tsd-page-toolbar { + position: fixed; + z-index: 2; +} +html.minimal #tsd-filter .tsd-filter-group { + right: 0; + transform: none; +} +html.minimal footer { + background-color: transparent; +} +html.minimal footer .container { + padding: 0; +} +html.minimal .tsd-generator { + padding: 0; +} +@media (max-width: 900px) { + html.minimal .tsd-navigation { + display: none; + } + html.minimal .content-wrap { + padding-left: 0; + } +} + +dl.tsd-comment-tags { + overflow: hidden; +} +dl.tsd-comment-tags dt { + float: left; + padding: 1px 5px; + margin: 0 10px 0 0; + border-radius: 4px; + border: 1px solid #808080; + color: #808080; + font-size: 0.8em; + font-weight: normal; +} +dl.tsd-comment-tags dd { + margin: 0 0 10px 0; +} +dl.tsd-comment-tags dd:before, dl.tsd-comment-tags dd:after { + display: table; + content: " "; +} +dl.tsd-comment-tags dd pre, dl.tsd-comment-tags dd:after { + clear: both; +} +dl.tsd-comment-tags p { + margin: 0; +} + +.tsd-panel.tsd-comment .lead { + font-size: 1.1em; + line-height: 1.333em; + margin-bottom: 2em; +} +.tsd-panel.tsd-comment .lead:last-child { + margin-bottom: 0; +} + +.toggle-protected .tsd-is-private { + display: none; +} + +.toggle-public .tsd-is-private, +.toggle-public .tsd-is-protected, +.toggle-public .tsd-is-private-protected { + display: none; +} + +.toggle-inherited .tsd-is-inherited { + display: none; +} + +.toggle-only-exported .tsd-is-not-exported { + display: none; +} + +.toggle-externals .tsd-is-external { + display: none; +} + +#tsd-filter { + position: relative; + display: inline-block; + height: 40px; + vertical-align: bottom; +} +.no-filter #tsd-filter { + display: none; +} +#tsd-filter .tsd-filter-group { + display: inline-block; + height: 40px; + vertical-align: bottom; + white-space: nowrap; +} +#tsd-filter input { + display: none; +} +@media (max-width: 900px) { + #tsd-filter .tsd-filter-group { + display: block; + position: absolute; + top: 40px; + right: 20px; + height: auto; + background-color: #fff; + visibility: hidden; + transform: translate(50%, 0); + box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); + } + .has-options #tsd-filter .tsd-filter-group { + visibility: visible; + } + .to-has-options #tsd-filter .tsd-filter-group { + animation: fade-in 0.2s; + } + .from-has-options #tsd-filter .tsd-filter-group { + animation: fade-out 0.2s; + } + #tsd-filter label, +#tsd-filter .tsd-select { + display: block; + padding-right: 20px; + } +} + +footer { + border-top: 1px solid #eee; + background-color: #fff; +} +footer.with-border-bottom { + border-bottom: 1px solid #eee; +} +footer .tsd-legend-group { + font-size: 0; +} +footer .tsd-legend { + display: inline-block; + width: 25%; + padding: 0; + font-size: 16px; + list-style: none; + line-height: 1.333em; + vertical-align: top; +} +@media (max-width: 900px) { + footer .tsd-legend { + width: 50%; + } +} + +.tsd-hierarchy { + list-style: square; + padding: 0 0 0 20px; + margin: 0; +} +.tsd-hierarchy .target { + font-weight: bold; +} + +.tsd-index-panel .tsd-index-content { + margin-bottom: -30px !important; +} +.tsd-index-panel .tsd-index-section { + margin-bottom: 30px !important; +} +.tsd-index-panel h3 { + margin: 0 -20px 10px -20px; + padding: 0 20px 10px 20px; + border-bottom: 1px solid #eee; +} +.tsd-index-panel ul.tsd-index-list { + -moz-column-count: 3; + -ms-column-count: 3; + -o-column-count: 3; + column-count: 3; + -moz-column-gap: 20px; + -ms-column-gap: 20px; + -o-column-gap: 20px; + column-gap: 20px; + padding: 0; + list-style: none; + line-height: 1.333em; +} +@media (max-width: 900px) { + .tsd-index-panel ul.tsd-index-list { + -moz-column-count: 1; + -ms-column-count: 1; + -o-column-count: 1; + column-count: 1; + } +} +@media (min-width: 901px) and (max-width: 1024px) { + .tsd-index-panel ul.tsd-index-list { + -moz-column-count: 2; + -ms-column-count: 2; + -o-column-count: 2; + column-count: 2; + } +} +.tsd-index-panel ul.tsd-index-list li { + -webkit-page-break-inside: avoid; + -moz-page-break-inside: avoid; + -ms-page-break-inside: avoid; + -o-page-break-inside: avoid; + page-break-inside: avoid; +} +.tsd-index-panel a, +.tsd-index-panel .tsd-parent-kind-module a { + color: #9600ff; +} +.tsd-index-panel .tsd-parent-kind-interface a { + color: #7da01f; +} +.tsd-index-panel .tsd-parent-kind-enum a { + color: #cc9900; +} +.tsd-index-panel .tsd-parent-kind-class a { + color: #4da6ff; +} +.tsd-index-panel .tsd-kind-module a { + color: #9600ff; +} +.tsd-index-panel .tsd-kind-interface a { + color: #7da01f; +} +.tsd-index-panel .tsd-kind-enum a { + color: #cc9900; +} +.tsd-index-panel .tsd-kind-class a { + color: #4da6ff; +} +.tsd-index-panel .tsd-is-private a { + color: #808080; +} + +.tsd-flag { + display: inline-block; + padding: 1px 5px; + border-radius: 4px; + color: #fff; + background-color: #808080; + text-indent: 0; + font-size: 14px; + font-weight: normal; +} + +.tsd-anchor { + position: absolute; + top: -100px; +} + +.tsd-member { + position: relative; +} +.tsd-member .tsd-anchor + h3 { + margin-top: 0; + margin-bottom: 0; + border-bottom: none; +} + +.tsd-navigation { + margin: 0 0 0 40px; +} +.tsd-navigation a { + display: block; + padding-top: 2px; + padding-bottom: 2px; + border-left: 2px solid transparent; + color: #222; + text-decoration: none; + transition: border-left-color 0.1s; +} +.tsd-navigation a:hover { + text-decoration: underline; +} +.tsd-navigation ul { + margin: 0; + padding: 0; + list-style: none; +} +.tsd-navigation li { + padding: 0; +} + +.tsd-navigation.primary { + padding-bottom: 40px; +} +.tsd-navigation.primary a { + display: block; + padding-top: 6px; + padding-bottom: 6px; +} +.tsd-navigation.primary ul li a { + padding-left: 5px; +} +.tsd-navigation.primary ul li li a { + padding-left: 25px; +} +.tsd-navigation.primary ul li li li a { + padding-left: 45px; +} +.tsd-navigation.primary ul li li li li a { + padding-left: 65px; +} +.tsd-navigation.primary ul li li li li li a { + padding-left: 85px; +} +.tsd-navigation.primary ul li li li li li li a { + padding-left: 105px; +} +.tsd-navigation.primary > ul { + border-bottom: 1px solid #eee; +} +.tsd-navigation.primary li { + border-top: 1px solid #eee; +} +.tsd-navigation.primary li.current > a { + font-weight: bold; +} +.tsd-navigation.primary li.label span { + display: block; + padding: 20px 0 6px 5px; + color: #808080; +} +.tsd-navigation.primary li.globals + li > span, .tsd-navigation.primary li.globals + li > a { + padding-top: 20px; +} + +.tsd-navigation.secondary { + max-height: calc(100vh - 1rem - 40px); + overflow: auto; + position: -webkit-sticky; + position: sticky; + top: calc(.5rem + 40px); + transition: 0.3s; +} +.tsd-navigation.secondary.tsd-navigation--toolbar-hide { + max-height: calc(100vh - 1rem); + top: 0.5rem; +} +.tsd-navigation.secondary ul { + transition: opacity 0.2s; +} +.tsd-navigation.secondary ul li a { + padding-left: 25px; +} +.tsd-navigation.secondary ul li li a { + padding-left: 45px; +} +.tsd-navigation.secondary ul li li li a { + padding-left: 65px; +} +.tsd-navigation.secondary ul li li li li a { + padding-left: 85px; +} +.tsd-navigation.secondary ul li li li li li a { + padding-left: 105px; +} +.tsd-navigation.secondary ul li li li li li li a { + padding-left: 125px; +} +.tsd-navigation.secondary ul.current a { + border-left-color: #eee; +} +.tsd-navigation.secondary li.focus > a, +.tsd-navigation.secondary ul.current li.focus > a { + border-left-color: #000; +} +.tsd-navigation.secondary li.current { + margin-top: 20px; + margin-bottom: 20px; + border-left-color: #eee; +} +.tsd-navigation.secondary li.current > a { + font-weight: bold; +} + +@media (min-width: 901px) { + .menu-sticky-wrap { + position: static; + } +} + +.tsd-panel { + margin: 20px 0; + padding: 20px; + background-color: #fff; + box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); +} +.tsd-panel:empty { + display: none; +} +.tsd-panel > h1, .tsd-panel > h2, .tsd-panel > h3 { + margin: 1.5em -20px 10px -20px; + padding: 0 20px 10px 20px; + border-bottom: 1px solid #eee; +} +.tsd-panel > h1.tsd-before-signature, .tsd-panel > h2.tsd-before-signature, .tsd-panel > h3.tsd-before-signature { + margin-bottom: 0; + border-bottom: 0; +} +.tsd-panel table { + display: block; + width: 100%; + overflow: auto; + margin-top: 10px; + word-break: normal; + word-break: keep-all; +} +.tsd-panel table th { + font-weight: bold; +} +.tsd-panel table th, .tsd-panel table td { + padding: 6px 13px; + border: 1px solid #ddd; +} +.tsd-panel table tr { + background-color: #fff; + border-top: 1px solid #ccc; +} +.tsd-panel table tr:nth-child(2n) { + background-color: #f8f8f8; +} + +.tsd-panel-group { + margin: 60px 0; +} +.tsd-panel-group > h1, .tsd-panel-group > h2, .tsd-panel-group > h3 { + padding-left: 20px; + padding-right: 20px; +} + +#tsd-search { + transition: background-color 0.2s; +} +#tsd-search .title { + position: relative; + z-index: 2; +} +#tsd-search .field { + position: absolute; + left: 0; + top: 0; + right: 40px; + height: 40px; +} +#tsd-search .field input { + box-sizing: border-box; + position: relative; + top: -50px; + z-index: 1; + width: 100%; + padding: 0 10px; + opacity: 0; + outline: 0; + border: 0; + background: transparent; + color: #222; +} +#tsd-search .field label { + position: absolute; + overflow: hidden; + right: -40px; +} +#tsd-search .field input, +#tsd-search .title { + transition: opacity 0.2s; +} +#tsd-search .results { + position: absolute; + visibility: hidden; + top: 40px; + width: 100%; + margin: 0; + padding: 0; + list-style: none; + box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); +} +#tsd-search .results li { + padding: 0 10px; + background-color: #fdfdfd; +} +#tsd-search .results li:nth-child(even) { + background-color: #fff; +} +#tsd-search .results li.state { + display: none; +} +#tsd-search .results li.current, +#tsd-search .results li:hover { + background-color: #eee; +} +#tsd-search .results a { + display: block; +} +#tsd-search .results a:before { + top: 10px; +} +#tsd-search .results span.parent { + color: #808080; + font-weight: normal; +} +#tsd-search.has-focus { + background-color: #eee; +} +#tsd-search.has-focus .field input { + top: 0; + opacity: 1; +} +#tsd-search.has-focus .title { + z-index: 0; + opacity: 0; +} +#tsd-search.has-focus .results { + visibility: visible; +} +#tsd-search.loading .results li.state.loading { + display: block; +} +#tsd-search.failure .results li.state.failure { + display: block; +} + +.tsd-signature { + margin: 0 0 1em 0; + padding: 10px; + border: 1px solid #eee; + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; + font-size: 14px; + overflow-x: auto; +} +.tsd-signature.tsd-kind-icon { + padding-left: 30px; +} +.tsd-signature.tsd-kind-icon:before { + top: 10px; + left: 10px; +} +.tsd-panel > .tsd-signature { + margin-left: -20px; + margin-right: -20px; + border-width: 1px 0; +} +.tsd-panel > .tsd-signature.tsd-kind-icon { + padding-left: 40px; +} +.tsd-panel > .tsd-signature.tsd-kind-icon:before { + left: 20px; +} + +.tsd-signature-symbol { + color: #808080; + font-weight: normal; +} + +.tsd-signature-type { + font-style: italic; + font-weight: normal; +} + +.tsd-signatures { + padding: 0; + margin: 0 0 1em 0; + border: 1px solid #eee; +} +.tsd-signatures .tsd-signature { + margin: 0; + border-width: 1px 0 0 0; + transition: background-color 0.1s; +} +.tsd-signatures .tsd-signature:first-child { + border-top-width: 0; +} +.tsd-signatures .tsd-signature.current { + background-color: #eee; +} +.tsd-signatures.active > .tsd-signature { + cursor: pointer; +} +.tsd-panel > .tsd-signatures { + margin-left: -20px; + margin-right: -20px; + border-width: 1px 0; +} +.tsd-panel > .tsd-signatures .tsd-signature.tsd-kind-icon { + padding-left: 40px; +} +.tsd-panel > .tsd-signatures .tsd-signature.tsd-kind-icon:before { + left: 20px; +} +.tsd-panel > a.anchor + .tsd-signatures { + border-top-width: 0; + margin-top: -20px; +} + +ul.tsd-descriptions { + position: relative; + overflow: hidden; + padding: 0; + list-style: none; +} +ul.tsd-descriptions.active > .tsd-description { + display: none; +} +ul.tsd-descriptions.active > .tsd-description.current { + display: block; +} +ul.tsd-descriptions.active > .tsd-description.fade-in { + animation: fade-in-delayed 0.3s; +} +ul.tsd-descriptions.active > .tsd-description.fade-out { + animation: fade-out-delayed 0.3s; + position: absolute; + display: block; + top: 0; + left: 0; + right: 0; + opacity: 0; + visibility: hidden; +} +ul.tsd-descriptions h4, ul.tsd-descriptions .tsd-index-panel h3, .tsd-index-panel ul.tsd-descriptions h3 { + font-size: 16px; + margin: 1em 0 0.5em 0; +} + +ul.tsd-parameters, +ul.tsd-type-parameters { + list-style: square; + margin: 0; + padding-left: 20px; +} +ul.tsd-parameters > li.tsd-parameter-signature, +ul.tsd-type-parameters > li.tsd-parameter-signature { + list-style: none; + margin-left: -20px; +} +ul.tsd-parameters h5, +ul.tsd-type-parameters h5 { + font-size: 16px; + margin: 1em 0 0.5em 0; +} +ul.tsd-parameters .tsd-comment, +ul.tsd-type-parameters .tsd-comment { + margin-top: -0.5em; +} + +.tsd-sources { + font-size: 14px; + color: #808080; + margin: 0 0 1em 0; +} +.tsd-sources a { + color: #808080; + text-decoration: underline; +} +.tsd-sources ul, .tsd-sources p { + margin: 0 !important; +} +.tsd-sources ul { + list-style: none; + padding: 0; +} + +.tsd-page-toolbar { + position: fixed; + z-index: 1; + top: 0; + left: 0; + width: 100%; + height: 40px; + color: #333; + background: #fff; + border-bottom: 1px solid #eee; + transition: transform 0.3s linear; +} +.tsd-page-toolbar a { + color: #333; + text-decoration: none; +} +.tsd-page-toolbar a.title { + font-weight: bold; +} +.tsd-page-toolbar a.title:hover { + text-decoration: underline; +} +.tsd-page-toolbar .table-wrap { + display: table; + width: 100%; + height: 40px; +} +.tsd-page-toolbar .table-cell { + display: table-cell; + position: relative; + white-space: nowrap; + line-height: 40px; +} +.tsd-page-toolbar .table-cell:first-child { + width: 100%; +} + +.tsd-page-toolbar--hide { + transform: translateY(-100%); +} + +.tsd-select .tsd-select-list li:before, .tsd-select .tsd-select-label:before, .tsd-widget:before { + content: ""; + display: inline-block; + width: 40px; + height: 40px; + margin: 0 -8px 0 0; + background-image: url(../images/widgets.png); + background-repeat: no-repeat; + text-indent: -1024px; + vertical-align: bottom; +} +@media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { + .tsd-select .tsd-select-list li:before, .tsd-select .tsd-select-label:before, .tsd-widget:before { + background-image: url(../images/widgets@2x.png); + background-size: 320px 40px; + } +} + +.tsd-widget { + display: inline-block; + overflow: hidden; + opacity: 0.6; + height: 40px; + transition: opacity 0.1s, background-color 0.2s; + vertical-align: bottom; + cursor: pointer; +} +.tsd-widget:hover { + opacity: 0.8; +} +.tsd-widget.active { + opacity: 1; + background-color: #eee; +} +.tsd-widget.no-caption { + width: 40px; +} +.tsd-widget.no-caption:before { + margin: 0; +} +.tsd-widget.search:before { + background-position: 0 0; +} +.tsd-widget.menu:before { + background-position: -40px 0; +} +.tsd-widget.options:before { + background-position: -80px 0; +} +.tsd-widget.options, .tsd-widget.menu { + display: none; +} +@media (max-width: 900px) { + .tsd-widget.options, .tsd-widget.menu { + display: inline-block; + } +} +input[type=checkbox] + .tsd-widget:before { + background-position: -120px 0; +} +input[type=checkbox]:checked + .tsd-widget:before { + background-position: -160px 0; +} + +.tsd-select { + position: relative; + display: inline-block; + height: 40px; + transition: opacity 0.1s, background-color 0.2s; + vertical-align: bottom; + cursor: pointer; +} +.tsd-select .tsd-select-label { + opacity: 0.6; + transition: opacity 0.2s; +} +.tsd-select .tsd-select-label:before { + background-position: -240px 0; +} +.tsd-select.active .tsd-select-label { + opacity: 0.8; +} +.tsd-select.active .tsd-select-list { + visibility: visible; + opacity: 1; + transition-delay: 0s; +} +.tsd-select .tsd-select-list { + position: absolute; + visibility: hidden; + top: 40px; + left: 0; + margin: 0; + padding: 0; + opacity: 0; + list-style: none; + box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); + transition: visibility 0s 0.2s, opacity 0.2s; +} +.tsd-select .tsd-select-list li { + padding: 0 20px 0 0; + background-color: #fdfdfd; +} +.tsd-select .tsd-select-list li:before { + background-position: 40px 0; +} +.tsd-select .tsd-select-list li:nth-child(even) { + background-color: #fff; +} +.tsd-select .tsd-select-list li:hover { + background-color: #eee; +} +.tsd-select .tsd-select-list li.selected:before { + background-position: -200px 0; +} +@media (max-width: 900px) { + .tsd-select .tsd-select-list { + top: 0; + left: auto; + right: 100%; + margin-right: -5px; + } + .tsd-select .tsd-select-label:before { + background-position: -280px 0; + } +} + +img { + max-width: 100%; +} \ No newline at end of file diff --git a/docs/assets/css/pages.css b/docs/assets/css/pages.css new file mode 100644 index 00000000..0bb4aa3d --- /dev/null +++ b/docs/assets/css/pages.css @@ -0,0 +1,64 @@ +h2 code { + font-size: 1em; +} + +h3 code { + font-size: 1em; +} + +.tsd-navigation.primary ul { + border-bottom: none; +} + +.tsd-navigation.primary li { + border-top: none; +} + +.tsd-navigation li.label.pp-nav.pp-group:first-child span { + padding-top: 0; +} + +.tsd-navigation li.label.pp-nav.pp-group { + font-weight: 700; + border-bottom: 1px solid #eee; +} + +.tsd-navigation li.label.pp-nav.pp-group span { + color: #222; +} + +.tsd-navigation li.pp-nav.pp-page.current { + background-color: #f8f8f8; + border-left: 2px solid #222; +} + +.tsd-navigation li.pp-nav.pp-page.current a { + color: #222; +} + +.tsd-navigation li.pp-nav.pp-page.pp-parent.pp-active { + border-left: 2px solid #eee; +} + +.tsd-navigation li.pp-nav.pp-page.pp-child { + border-left: 2px solid #eee; + padding-left: 15px; +} + +.tsd-navigation li.pp-nav.pp-page.pp-child.current { + border-left: 2px solid #222; +} + +.tsd-kind-page .tsd-kind-icon:before { + display: inline-block; + vertical-align: middle; + height: 16px; + width: 16px; + content: ""; + background-image: url("../images/page-icon.svg"); + background-size: 16px 16px; +} + +#tsd-search .results span.parent { + color: #b3b2b2 !important; +} \ No newline at end of file diff --git a/docs/assets/images/icons.png b/docs/assets/images/icons.png new file mode 100644 index 00000000..3836d5fe Binary files /dev/null and b/docs/assets/images/icons.png differ diff --git a/docs/assets/images/icons@2x.png b/docs/assets/images/icons@2x.png new file mode 100644 index 00000000..5a209e2f Binary files /dev/null and b/docs/assets/images/icons@2x.png differ diff --git a/docs/assets/images/page-icon.svg b/docs/assets/images/page-icon.svg new file mode 100644 index 00000000..4fe78d91 --- /dev/null +++ b/docs/assets/images/page-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/assets/images/widgets.png b/docs/assets/images/widgets.png new file mode 100644 index 00000000..c7380532 Binary files /dev/null and b/docs/assets/images/widgets.png differ diff --git a/docs/assets/images/widgets@2x.png b/docs/assets/images/widgets@2x.png new file mode 100644 index 00000000..4bbbd572 Binary files /dev/null and b/docs/assets/images/widgets@2x.png differ diff --git a/docs/assets/js/main.js b/docs/assets/js/main.js new file mode 100644 index 00000000..1cc4dd86 --- /dev/null +++ b/docs/assets/js/main.js @@ -0,0 +1 @@ +!function(){var e=function(t){var r=new e.Builder;return r.pipeline.add(e.trimmer,e.stopWordFilter,e.stemmer),r.searchPipeline.add(e.stemmer),t.call(r,r),r.build()};e.version="2.3.7",e.utils={},e.utils.warn=function(e){return function(t){e.console&&console.warn&&console.warn(t)}}(this),e.utils.asString=function(e){return null==e?"":e.toString()},e.utils.clone=function(e){if(null==e)return e;for(var t=Object.create(null),r=Object.keys(e),i=0;i=this.length)return e.QueryLexer.EOS;var t=this.str.charAt(this.pos);return this.pos+=1,t},e.QueryLexer.prototype.width=function(){return this.pos-this.start},e.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},e.QueryLexer.prototype.backup=function(){this.pos-=1},e.QueryLexer.prototype.acceptDigitRun=function(){for(var t,r;47<(r=(t=this.next()).charCodeAt(0))&&r<58;);t!=e.QueryLexer.EOS&&this.backup()},e.QueryLexer.prototype.more=function(){return this.pos=this.scrollTop||0===this.scrollTop,isShown!==this.showToolbar&&(this.toolbar.classList.toggle("tsd-page-toolbar--hide"),this.secondaryNav.classList.toggle("tsd-navigation--toolbar-hide")),this.lastY=this.scrollTop},Viewport}(typedoc.EventTarget);typedoc.Viewport=Viewport,typedoc.registerService(Viewport,"viewport")}(typedoc||(typedoc={})),function(typedoc){function Component(options){this.el=options.el}typedoc.Component=Component}(typedoc||(typedoc={})),function(typedoc){typedoc.pointerDown="mousedown",typedoc.pointerMove="mousemove",typedoc.pointerUp="mouseup",typedoc.pointerDownPosition={x:0,y:0},typedoc.preventNextClick=!1,typedoc.isPointerDown=!1,typedoc.isPointerTouch=!1,typedoc.hasPointerMoved=!1,typedoc.isMobile=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),document.documentElement.classList.add(typedoc.isMobile?"is-mobile":"not-mobile"),typedoc.isMobile&&"ontouchstart"in document.documentElement&&(typedoc.isPointerTouch=!0,typedoc.pointerDown="touchstart",typedoc.pointerMove="touchmove",typedoc.pointerUp="touchend"),document.addEventListener(typedoc.pointerDown,function(e){typedoc.isPointerDown=!0,typedoc.hasPointerMoved=!1;var t="touchstart"==typedoc.pointerDown?e.targetTouches[0]:e;typedoc.pointerDownPosition.y=t.pageY||0,typedoc.pointerDownPosition.x=t.pageX||0}),document.addEventListener(typedoc.pointerMove,function(e){if(typedoc.isPointerDown&&!typedoc.hasPointerMoved){var t="touchstart"==typedoc.pointerDown?e.targetTouches[0]:e,x=typedoc.pointerDownPosition.x-(t.pageX||0),y=typedoc.pointerDownPosition.y-(t.pageY||0);typedoc.hasPointerMoved=10scrollTop;)index-=1;for(;index"+match+""}),parent=row.parent||"";(parent=parent.replace(new RegExp(this.query,"i"),function(match){return""+match+""}))&&(name=''+parent+"."+name);var item=document.createElement("li");item.classList.value=row.classes,item.innerHTML='\n '+name+"\n ",this.results.appendChild(item)}}},Search.prototype.setLoadingState=function(value){this.loadingState!=value&&(this.el.classList.remove(SearchLoadingState[this.loadingState].toLowerCase()),this.loadingState=value,this.el.classList.add(SearchLoadingState[this.loadingState].toLowerCase()),this.updateResults())},Search.prototype.setHasFocus=function(value){this.hasFocus!=value&&(this.hasFocus=value,this.el.classList.toggle("has-focus"),value?(this.setQuery(""),this.field.value=""):this.field.value=this.query)},Search.prototype.setQuery=function(value){this.query=value.trim(),this.updateResults()},Search.prototype.setCurrentResult=function(dir){var current=this.results.querySelector(".current");if(current){var rel=1==dir?current.nextElementSibling:current.previousElementSibling;rel&&(current.classList.remove("current"),rel.classList.add("current"))}else(current=this.results.querySelector(1==dir?"li:first-child":"li:last-child"))&¤t.classList.add("current")},Search.prototype.gotoCurrentResult=function(){var current=this.results.querySelector(".current");if(current||(current=this.results.querySelector("li:first-child")),current){var link=current.querySelector("a");link&&(window.location.href=link.href),this.field.blur()}},Search.prototype.bindEvents=function(){var _this=this;this.results.addEventListener("mousedown",function(){_this.resultClicked=!0}),this.results.addEventListener("mouseup",function(){_this.resultClicked=!1,_this.setHasFocus(!1)}),this.field.addEventListener("focusin",function(){_this.setHasFocus(!0),_this.loadIndex()}),this.field.addEventListener("focusout",function(){_this.resultClicked?_this.resultClicked=!1:setTimeout(function(){return _this.setHasFocus(!1)},100)}),this.field.addEventListener("input",function(){_this.setQuery(_this.field.value)}),this.field.addEventListener("keydown",function(e){13==e.keyCode||27==e.keyCode||38==e.keyCode||40==e.keyCode?(_this.preventPress=!0,e.preventDefault(),13==e.keyCode?_this.gotoCurrentResult():27==e.keyCode?_this.field.blur():38==e.keyCode?_this.setCurrentResult(-1):40==e.keyCode&&_this.setCurrentResult(1)):_this.preventPress=!1}),this.field.addEventListener("keypress",function(e){_this.preventPress&&e.preventDefault()}),document.body.addEventListener("keydown",function(e){e.altKey||e.ctrlKey||e.metaKey||!_this.hasFocus&&47this.groups.length-1&&(index=this.groups.length-1),this.index!=index){var to=this.groups[index];if(-1 This module is compatible with `nestjs@^8.0.0`.\n\n# Setup & configuration\n\nFirst, install the module:\n\n```bash\nnpm install @scitizen/nest-casl\n```\n\nThen, declare a provider that generate a CASL Ability from the current request.\n\n{@codeblock test/basic-use.e2e-spec.ts#AbilityFactory | src/ability-factory.service.ts}\n\nImport the {@link CaslModule `CaslModule`} in your `AppModule`, and configure it to use your ability factory.\n\n{@codeblock test/basic-use.e2e-spec.ts#AppModule | src/app.module.ts}\n\nYou can now start using policy decorators ({@link Policy `Policy`} and {@link PoliciesMask `PoliciesMask`}) in your controllers !\n\n# Basic usage\n\nYou can protect all methods of your controller using the {@link Policy `Policy`} class decorator.\n\n{@codeblock test/basic-use.e2e-spec.ts#CatOwnerController | src/cat-owner.controller.ts}\n\nThis decorator can also be used to protect individual methods.\n\n{@codeblock test/basic-use.e2e-spec.ts#CatCareController | src/cat-care.controller.ts}\n\nIf you want to group various policies in the same decorator at the controller level, use the {@link PoliciesMask `PoliciesMask`} decorator.\n\n{@codeblock test/basic-use.e2e-spec.ts#CatController | src/cat.controller.ts}\n\nCheck the tests !\n\n{@codeblock folded test/basic-use.e2e-spec.ts#Test | test/cats.e2e-spec.ts}\n\n# What next ?\n\n{@page Use with guards}","pagesPluginParent":"Guides / "},{"id":25,"kind":1,"name":"Use with guards","url":"pages/Guides/use-with-guards.html","classes":"tsd-kind-page","pagesPluginContent":"Most of the times, you want to execute some guards before checking CASL policies, to extract some user informations before generating its abilities.\n\nThis page will show you the various way to do.\n\nLet's assume you have the following {@link CaslAbilityFactory `CaslAbilityFactory`}:\n\n{@codeblock test/use-with-guards/ability-factory.service.ts | src/ability-factory.service.ts}\n\n# The naïve approach\n\n> This method is **not recommanded**. You might skip directly to the [recommended approach](#the-recommended-approach)\n\n## Without any more dependencies\n\nThis method does not require any external dependency, and is as close to NestJS as possible.\n\n{@codeblock folded test/use-with-guards/naive.guard.ts | src/guards/naive.guard.ts}\n\nAssuming the guard does the following (see above for an example implementation):\n* Users without an `Authorization` header will see an `Unauthorized` exception.\n* Users with an invalid `Authorization` header will see a `Forbidden` exception.\n* Users with a valid `Authorization` header will be allowed to continue, and the property `user` is set on the `request`.\n\n> Yeah, I'm aware that in an ideal world, a [`Middleware`](https://docs.nestjs.com/middleware) or an [`Interceptor`](https://docs.nestjs.com/interceptors) should take care of setting the `user` property on the `Request`. But fact is that [`@nestjs/passport`](https://www.npmjs.com/package/@nestjs/passport) does it [in a guard](https://github.com/nestjs/passport/blob/6aef921c7566766d0eb9e79d2c8235177c539863/lib/auth.guard.ts#L58)\n\n{@codeblock test/use-with-guards/naive.controller.ts | src/controllers/naive.controller.ts}\n\nNow,\n* Users without an `Authorization` header will see an `Unauthorized` exception (from the `NaiveGuard`).\n* Users with an invalid `Authorization` header will see a `Forbidden` exception (from the `NaiveGuard`).\n* Users with an `Authorization` header that does not give them access to the ressource will see a `Forbidden` exception (from the {@link PoliciesGuard `PoliciesGuard`}).\n* Users with an `Authorization` header that give them access to the ressource will succeed.\n\n## Using [`@nestjs/passport`](https://www.npmjs.com/package/@nestjs/passport)\n\nIf you're using `passport`, you can delegate the user retrieval. Let's say you have a JWT `passport` strategy.\n\n{@codeblock folded test/use-with-guards/jwt-passport.strategy.ts | src/strategies/jwt-passport.strategy.ts}\n\nStill using the naive approach, you can then declare the controller like this:\n\n{@codeblock test/use-with-guards/passport-naive.controller.ts | src/controllers/passport-naive.controller.ts}\n\n## The tests\n\nWanna see the behavior as tests ? Here you are !\n\n{@codeblock folded test/use-with-guards/naive-test.e2e-spec.ts}\n\n# The recommended approach\n\nWhat's the problem about the naïve approach above ? Well, there are 2.\n1. *The readability*: The `UseGuards` decorator is placed **below** the {@link Policy `Policy`} decorator, but is ran **before** it.\n2. *The reusability*: If you're using multiple authentication strategies in the same app, you might have to apply guards **and** the policies on each method depending on the context. Moreover, if you want to type-check your policies, you might prefer to have abilities presets.\n\n## About readability\n\nYou can use {@link Policy.usingGuard `Policy.usingGuard`} or {@link PoliciesMask.usingGuard `PoliciesMask.usingGuard`} to prepended guards to the decorator factory. Those calls are cumulative, and you can do multiple subsequent calls to join guards using an `and` condition. If you provide an array of guards, they be evaluated using an `or` condition.\n\n{@codeblock test/use-with-guards/recommended.controller.ts#Recommended simple controller | src/controllers/recommended.controller.ts}\n\n## About reusability\n\nYou can even prepare a policy decorator with guards or {@link PolicyDescriptor `PolicyDescriptor`}:\n\n{@codeblock test/use-with-guards/recommended.controller.ts#Recommended bound | src/policies.ts}\n\nThen, use those presets in your controller:\n\n{@codeblock test/use-with-guards/recommended.controller.ts#Recommended bound controller | src/recommended-bound.controller.ts}\n\nNow, both `method1` and `method2` will run if\n* the user is authenticated through `jwt` strategy\n* it passes either `ExtraGuard1` or `ExtraGuard2`\n* and he has admin role.\n\n> Note that you can use {@link bindPolicyDecorators `bindPolicyDecorators`} to bind *both* {@link Policy `Policy`} and {@link PoliciesMask `PoliciesMask`}\n\n## The tests\n\nThis is tested, of course. Just see by yourself.\n\n{@codeblock folded test/use-with-guards/recommended-test.e2e-spec.ts}\n\n# What next ?\n\n{@page Better type constraints}","pagesPluginParent":"Guides / "},{"id":26,"kind":1,"name":"Better type constraints","url":"pages/Guides/better-type-constraints.html","classes":"tsd-kind-page","pagesPluginContent":"So far, we were able to configure your policies. But we can't yet check that our `action`s or `subject`s are actually matching what we declared.\n\n# Define the ability type\n\nLet's configure our ability types:\n\n{@codeblock test/better-types/ability.ts}\n\nUsing `MyAbility`, we can't pass anything to `can` or `cannot`: types are constrained.\n\n{@codeblock test/better-types/ability.typecheck.e2e-spec.ts}\n\nThat's great. This will greatly reduce our chances of typos. Moreover, your IDE might now suggest `action`s & `subject`s for you.\n\n# Use the ability type\n\n## With the {@link CaslAbilityFactory `CaslAbilityFactory`}\n\nLet's now use this type in your {@link CaslAbilityFactory `CaslAbilityFactory`}:\n\n{@codeblock test/better-types/ability-factory.service.ts | src/ability-factory.service.ts}\n\n## With decorators\n\nYou can pass your ability as a type parameter to your decorators to constraint your `action`s and `subject`s:\n\n{@codeblock test/better-types/test.controller.ts | src/test.controller.ts}\n\nBut the boring part here is that you have to pass your ability type to **every** decorator in order to constrain them. Hopefully, you can solve this:\n\n{@codeblock test/better-types/my-policies.ts | src/my-policies.ts}\n\nThen, simply enjoy type contraints !\n\n{@codeblock test/better-types/test-bound.controller.ts | src/test-bound.controller.ts}\n","pagesPluginParent":"Guides / "},{"id":27,"kind":1,"name":"Changelog","url":"pages/Changelog/CHANGELOG.html","classes":"tsd-kind-page","pagesPluginContent":"# Changelog\n\nAll notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.\n\n### 0.0.1 (2021-10-06)\n\nInitial release\n","pagesPluginParent":"Changelog / "}],"index":{"version":"2.3.9","fields":["pagesPluginContent","name","parent"],"fieldVectors":[["pagesPluginContent/0",[]],["name/0",[0,31.575]],["parent/0",[]],["pagesPluginContent/1",[]],["name/1",[1,15.943]],["parent/1",[]],["pagesPluginContent/2",[]],["name/2",[1,15.943]],["parent/2",[]],["pagesPluginContent/3",[]],["name/3",[2,26.13]],["parent/3",[1,0.861]],["pagesPluginContent/4",[]],["name/4",[3,15.943]],["parent/4",[]],["pagesPluginContent/5",[]],["name/5",[3,15.943]],["parent/5",[]],["pagesPluginContent/6",[]],["name/6",[2,26.13]],["parent/6",[3,0.861]],["pagesPluginContent/7",[]],["name/7",[4,26.13]],["parent/7",[]],["pagesPluginContent/8",[]],["name/8",[5,26.13]],["parent/8",[]],["pagesPluginContent/9",[]],["name/9",[6,31.575]],["parent/9",[5,1.412]],["pagesPluginContent/10",[]],["name/10",[1,15.943]],["parent/10",[7,1.412]],["pagesPluginContent/11",[]],["name/11",[3,15.943]],["parent/11",[7,1.412]],["pagesPluginContent/12",[]],["name/12",[8,19.863]],["parent/12",[]],["pagesPluginContent/13",[]],["name/13",[9,31.575]],["parent/13",[8,1.073]],["pagesPluginContent/14",[]],["name/14",[10,31.575]],["parent/14",[8,1.073]],["pagesPluginContent/15",[]],["name/15",[11,26.13]],["parent/15",[]],["pagesPluginContent/16",[]],["name/16",[12,31.575]],["parent/16",[11,1.412]],["pagesPluginContent/17",[]],["name/17",[13,26.13]],["parent/17",[]],["pagesPluginContent/18",[]],["name/18",[14,31.575]],["parent/18",[]],["pagesPluginContent/19",[]],["name/19",[15,26.13]],["parent/19",[]],["pagesPluginContent/20",[]],["name/20",[16,31.575]],["parent/20",[15,1.412]],["pagesPluginContent/21",[]],["name/21",[17,31.575]],["parent/21",[]],["pagesPluginContent/22",[]],["name/22",[18,19.863]],["parent/22",[]],["pagesPluginContent/23",[]],["name/23",[19,31.575]],["parent/23",[18,1.073]],["pagesPluginContent/24",[1,25.372,3,22.624,8,18.284,20,46.756,21,18.284,22,29.065,23,12.187,24,17.071,25,18.284,26,17.071,27,17.071,28,17.071,29,17.071,30,29.065,31,43.867,32,17.071,33,17.071,34,17.071,35,24.052,36,12.187,37,14.127,38,20.75,39,17.071,40,12.187,41,17.071,42,24.052,43,14.127,44,17.071,45,14.127,46,39.035,47,54.677,48,54.677,49,17.071,50,12.187,51,12.187,52,17.071,53,35.874,54,23.876,55,31.988,56,17.071,57,20.75,58,14.127,59,14.127,60,23.876,61,23.876,62,14.127,63,17.071,64,17.071,65,27.097,66,27.097,67,12.187,68,17.071,69,20.75,70,14.127,71,17.071,72,17.071,73,17.071,74,29.065,75,14.127,76,29.065,77,12.187,78,24.052,79,17.071,80,31.988,81,17.071,82,29.065,83,17.071,84,17.071,85,12.187,86,17.071,87,17.071,88,17.071,89,17.071,90,14.127,91,14.127,92,17.071,93,14.127,94,12.187,95,14.127,96,17.071,97,17.071,98,17.071,99,17.071,100,12.187,101,14.127,102,14.127,103,17.071,104,17.071,105,12.187,106,12.187,107,14.127,108,14.127,109,12.187]],["name/24",[110,23.047,111,23.047]],["parent/24",[]],["pagesPluginContent/25",[1,11.914,3,5.573,4,9.133,13,9.133,18,6.943,20,42.053,21,14.843,23,23.543,25,31.023,31,47.725,35,4.84,36,7.88,37,4.84,38,23.543,40,16.846,43,12.968,45,9.133,46,27.139,50,4.176,51,7.88,53,25.414,54,12.477,55,7.88,57,23.543,59,12.968,60,30.031,61,9.858,62,4.84,65,35.207,66,19.284,67,7.88,69,19.284,77,14.16,78,16.413,80,14.16,85,7.88,90,19.526,91,9.133,93,4.84,94,11.188,95,4.84,100,4.176,101,12.968,102,16.413,105,7.88,106,4.176,107,4.84,108,9.133,109,19.284,112,5.849,113,5.849,114,5.849,115,11.037,116,15.671,117,5.849,118,5.849,119,23.596,120,5.849,121,5.849,122,5.849,123,11.037,124,25.414,125,5.849,126,5.849,127,11.037,128,9.133,129,5.849,130,16.413,131,11.037,132,38.014,133,5.849,134,11.037,135,23.596,136,15.671,137,15.671,138,5.849,139,12.968,140,5.849,141,5.849,142,15.671,143,5.849,144,15.671,145,11.037,146,5.849,147,5.849,148,19.834,149,5.849,150,5.849,151,5.849,152,12.968,153,5.849,154,5.849,155,5.849,156,5.849,157,5.849,158,5.849,159,5.849,160,27.289,161,11.037,162,4.176,163,46.055,164,5.849,165,5.849,166,30.125,167,30.125,168,30.125,169,11.037,170,23.596,171,11.037,172,15.671,173,5.849,174,5.849,175,5.849,176,11.037,177,5.849,178,19.834,179,5.849,180,5.849,181,5.849,182,5.849,183,5.849,184,5.849,185,19.526,186,5.849,187,5.849,188,5.849,189,5.849,190,5.849,191,9.133,192,5.849,193,11.037,194,5.849,195,5.849,196,5.849,197,11.037,198,11.037,199,9.133,200,11.037,201,11.037,202,11.037,203,5.849,204,11.037,205,11.037,206,5.849,207,5.849,208,5.849,209,11.037,210,11.037,211,5.849,212,11.037,213,5.849,214,5.849,215,5.849,216,5.849,217,5.849,218,11.037,219,5.849,220,5.849,221,5.849,222,4.84,223,12.968,224,5.849,225,11.037,226,5.849,227,5.849,228,15.671,229,5.849,230,5.849,231,11.037,232,5.849,233,11.037,234,5.849,235,5.849,236,5.849,237,5.849,238,11.037,239,11.037,240,5.849,241,5.849,242,5.849,243,5.849,244,5.849,245,5.849,246,5.849,247,4.84,248,7.88,249,5.849,250,11.037,251,11.037,252,11.037,253,5.849,254,11.037,255,11.037,256,5.849,257,5.849,258,5.849,259,11.037,260,5.849,261,5.849,262,5.849,263,5.849,264,15.671,265,5.849,266,5.849,267,5.849,268,5.849,269,11.037,270,5.849,271,5.849,272,4.84,273,11.037,274,5.849,275,5.849,276,5.849,277,5.849,278,5.849,279,5.849,280,5.849,281,5.849,282,5.849,283,5.849,284,5.849,285,5.849,286,5.849,287,5.849,288,5.849,289,5.849,290,5.849,291,5.849,292,5.849,293,5.849,294,5.849,295,4.84,296,4.84]],["name/25",[25,11.415,61,11.415,109,12.955]],["parent/25",[]],["pagesPluginContent/26",[18,27.61,20,41.244,21,23.326,23,11.811,25,17.802,31,31.334,36,11.811,38,11.811,40,20.203,42,40.818,46,38.383,50,11.811,51,20.203,53,20.203,54,17.802,55,41.02,57,11.811,58,23.418,60,36.145,61,17.802,65,31.334,66,26.472,67,20.203,69,11.811,70,23.418,77,11.811,80,11.811,94,11.811,100,11.811,105,11.811,106,11.811,124,11.811,128,23.418,130,13.691,139,13.691,152,13.691,162,11.811,185,23.418,191,23.418,199,13.691,222,13.691,223,23.418,247,13.691,248,38.383,272,23.418,297,16.544,298,16.544,299,43.89,300,16.544,301,16.544,302,28.298,303,16.544,304,37.08,305,37.08,306,37.08,307,16.544,308,16.544,309,16.544,310,16.544,311,28.298,312,53.763,313,16.544,314,16.544,315,37.08,316,16.544,317,16.544,318,16.544,319,16.544,320,16.544,321,16.544,322,16.544,323,16.544,324,16.544,325,16.544,326,16.544,327,16.544,328,16.544,329,16.544,330,16.544,331,16.544,332,16.544,333,16.544,334,16.544,335,16.544,336,16.544,337,16.544,338,16.544,339,16.544,340,16.544,341,28.298,342,16.544,343,16.544,344,16.544,345,16.544,346,16.544,347,16.544]],["name/26",[248,12.955,295,15.016,296,15.016]],["parent/26",[]],["pagesPluginContent/27",[20,40.253,21,40.253,54,29.921,60,29.921,75,39.36,85,33.957,124,33.957,160,39.36,162,33.957,348,39.36,349,47.563,350,47.563,351,47.563,352,47.563,353,47.563,354,47.563,355,47.563,356,47.563,357,47.563,358,47.563,359,47.563,360,47.563,361,47.563,362,47.563,363,47.563,364,47.563,365,47.563]],["name/27",[348,26.13]],["parent/27",[]]],"invertedIndex":[["",{"_index":20,"pagesPluginContent":{"24":{},"25":{},"26":{},"27":{}},"name":{},"parent":{}}],["0.0.1",{"_index":360,"pagesPluginContent":{"27":{}},"name":{},"parent":{}}],["06",{"_index":363,"pagesPluginContent":{"27":{}},"name":{},"parent":{}}],["1",{"_index":232,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["10",{"_index":362,"pagesPluginContent":{"27":{}},"name":{},"parent":{}}],["2",{"_index":231,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["2021",{"_index":361,"pagesPluginContent":{"27":{}},"name":{},"parent":{}}],["__type",{"_index":6,"pagesPluginContent":{},"name":{"9":{}},"parent":{}}],["a",{"_index":38,"pagesPluginContent":{"24":{},"25":{},"26":{}},"name":{},"parent":{}}],["abilities",{"_index":123,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["ability",{"_index":42,"pagesPluginContent":{"24":{},"26":{}},"name":{},"parent":{}}],["abilityfactory",{"_index":12,"pagesPluginContent":{},"name":{"16":{}},"parent":{}}],["able",{"_index":301,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["about",{"_index":228,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["above",{"_index":161,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["access",{"_index":200,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["action`s",{"_index":305,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["actually",{"_index":307,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["admin",{"_index":285,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["all",{"_index":75,"pagesPluginContent":{"24":{},"27":{}},"name":{},"parent":{}}],["allowed",{"_index":174,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["also",{"_index":84,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["an",{"_index":163,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["and",{"_index":57,"pagesPluginContent":{"24":{},"25":{},"26":{}},"name":{},"parent":{}}],["any",{"_index":145,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["anything",{"_index":316,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["app",{"_index":242,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["apply",{"_index":243,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["appmodule",{"_index":56,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["approach",{"_index":135,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["approach](#the",{"_index":143,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["are",{"_index":223,"pagesPluginContent":{"25":{},"26":{}},"name":{},"parent":{}}],["array",{"_index":261,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["as",{"_index":152,"pagesPluginContent":{"25":{},"26":{}},"name":{},"parent":{}}],["assume",{"_index":129,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["assuming",{"_index":158,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["at",{"_index":96,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["authenticated",{"_index":277,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["authentication",{"_index":240,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["authorization",{"_index":167,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["aware",{"_index":181,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["bash",{"_index":32,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["basic",{"_index":72,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["be",{"_index":85,"pagesPluginContent":{"24":{},"25":{},"27":{}},"name":{},"parent":{}}],["before",{"_index":116,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["behavior",{"_index":221,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["below",{"_index":236,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["better",{"_index":295,"pagesPluginContent":{"25":{}},"name":{"26":{}},"parent":{}}],["bind",{"_index":288,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["bindpolicydecorators",{"_index":4,"pagesPluginContent":{"25":{}},"name":{"7":{}},"parent":{}}],["boring",{"_index":333,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["both",{"_index":273,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["bound",{"_index":269,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["bound.controller.ts",{"_index":272,"pagesPluginContent":{"25":{},"26":{}},"name":{},"parent":{}}],["boundpolicydecorators",{"_index":5,"pagesPluginContent":{},"name":{"8":{}},"parent":{"9":{}}}],["boundpolicydecorators.__type",{"_index":7,"pagesPluginContent":{},"name":{},"parent":{"10":{},"11":{}}}],["but",{"_index":191,"pagesPluginContent":{"25":{},"26":{}},"name":{},"parent":{}}],["by",{"_index":292,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["calls",{"_index":255,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["can",{"_index":66,"pagesPluginContent":{"24":{},"25":{},"26":{}},"name":{},"parent":{}}],["can't",{"_index":302,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["cannot",{"_index":317,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["care",{"_index":189,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["care.controller.ts",{"_index":89,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["casl",{"_index":35,"pagesPluginContent":{"24":{},"25":{}},"name":{},"parent":{}}],["caslabilityfactory",{"_index":18,"pagesPluginContent":{"25":{},"26":{}},"name":{"22":{}},"parent":{"23":{}}}],["caslmodule",{"_index":8,"pagesPluginContent":{"24":{}},"name":{"12":{}},"parent":{"13":{},"14":{}}}],["chances",{"_index":324,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["changelog",{"_index":348,"pagesPluginContent":{"27":{}},"name":{"27":{}},"parent":{}}],["changelog/standard",{"_index":356,"pagesPluginContent":{"27":{}},"name":{},"parent":{}}],["changes",{"_index":350,"pagesPluginContent":{"27":{}},"name":{},"parent":{}}],["check",{"_index":100,"pagesPluginContent":{"24":{},"25":{},"26":{}},"name":{},"parent":{}}],["checking",{"_index":117,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["class",{"_index":79,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["close",{"_index":153,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["codeblock",{"_index":46,"pagesPluginContent":{"24":{},"25":{},"26":{}},"name":{},"parent":{}}],["commit",{"_index":358,"pagesPluginContent":{"27":{}},"name":{},"parent":{}}],["compatible",{"_index":24,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["condition",{"_index":259,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["configuration",{"_index":28,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["configure",{"_index":58,"pagesPluginContent":{"24":{},"26":{}},"name":{},"parent":{}}],["constrain",{"_index":337,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["constrained",{"_index":318,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["constraint",{"_index":330,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["constraints",{"_index":296,"pagesPluginContent":{"25":{}},"name":{"26":{}},"parent":{}}],["constructor",{"_index":10,"pagesPluginContent":{},"name":{"14":{}},"parent":{}}],["context",{"_index":246,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["continue",{"_index":175,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["contraints",{"_index":345,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["controller",{"_index":78,"pagesPluginContent":{"24":{},"25":{}},"name":{},"parent":{}}],["controllers",{"_index":71,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["course",{"_index":290,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["createfromrequest",{"_index":19,"pagesPluginContent":{},"name":{"23":{}},"parent":{}}],["cumulative",{"_index":256,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["current",{"_index":44,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["declare",{"_index":37,"pagesPluginContent":{"24":{},"25":{}},"name":{},"parent":{}}],["declared",{"_index":309,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["decorator",{"_index":80,"pagesPluginContent":{"24":{},"25":{},"26":{}},"name":{},"parent":{}}],["decorators",{"_index":70,"pagesPluginContent":{"24":{},"26":{}},"name":{},"parent":{}}],["define",{"_index":310,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["delegate",{"_index":206,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["dependencies",{"_index":147,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["dependency",{"_index":151,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["depending",{"_index":245,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["directly",{"_index":141,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["do",{"_index":127,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["documented",{"_index":352,"pagesPluginContent":{"27":{}},"name":{},"parent":{}}],["does",{"_index":148,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["each",{"_index":244,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["either",{"_index":280,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["enjoy",{"_index":344,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["evaluated",{"_index":263,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["even",{"_index":267,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["every",{"_index":335,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["example",{"_index":164,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["exception",{"_index":170,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["execute",{"_index":114,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["external",{"_index":150,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["extract",{"_index":118,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["extraguard1",{"_index":281,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["extraguard2",{"_index":282,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["fact",{"_index":192,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["factory",{"_index":62,"pagesPluginContent":{"24":{},"25":{}},"name":{},"parent":{}}],["factory.service.ts",{"_index":51,"pagesPluginContent":{"24":{},"25":{},"26":{}},"name":{},"parent":{}}],["far",{"_index":298,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["file",{"_index":353,"pagesPluginContent":{"27":{}},"name":{},"parent":{}}],["first",{"_index":29,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["folded",{"_index":102,"pagesPluginContent":{"24":{},"25":{}},"name":{},"parent":{}}],["following",{"_index":131,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["for",{"_index":162,"pagesPluginContent":{"25":{},"26":{},"27":{}},"name":{},"parent":{}}],["forbidden",{"_index":172,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["from",{"_index":43,"pagesPluginContent":{"24":{},"25":{}},"name":{},"parent":{}}],["generate",{"_index":41,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["generating",{"_index":121,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["getting",{"_index":110,"pagesPluginContent":{},"name":{"24":{}},"parent":{}}],["give",{"_index":198,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["great",{"_index":321,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["greatly",{"_index":322,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["group",{"_index":92,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["guard",{"_index":159,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["guard](https://github.com/nestjs/passport/blob/6aef921c7566766d0eb9e79d2c8235177c539863/lib/auth.guard.ts#l58",{"_index":194,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["guards",{"_index":109,"pagesPluginContent":{"24":{},"25":{}},"name":{"25":{}},"parent":{}}],["guards/ability",{"_index":133,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["guards/jwt",{"_index":211,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["guards/naive",{"_index":224,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["guards/naive.controller.ts",{"_index":195,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["guards/naive.guard.ts",{"_index":156,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["guards/passport",{"_index":217,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["guards/recommended",{"_index":294,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["guards/recommended.controller.ts#recommended",{"_index":264,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["guidelines",{"_index":359,"pagesPluginContent":{"27":{}},"name":{},"parent":{}}],["handle",{"_index":16,"pagesPluginContent":{},"name":{"20":{}},"parent":{}}],["has",{"_index":284,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["have",{"_index":130,"pagesPluginContent":{"25":{},"26":{}},"name":{},"parent":{}}],["he",{"_index":283,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["header",{"_index":168,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["here",{"_index":222,"pagesPluginContent":{"25":{},"26":{}},"name":{},"parent":{}}],["hopefully",{"_index":338,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["i'm",{"_index":180,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["icaslrootconfig",{"_index":11,"pagesPluginContent":{},"name":{"15":{}},"parent":{"16":{}}}],["ide",{"_index":326,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["ideal",{"_index":182,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["if",{"_index":90,"pagesPluginContent":{"24":{},"25":{}},"name":{},"parent":{}}],["implementation",{"_index":165,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["import",{"_index":52,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["in",{"_index":54,"pagesPluginContent":{"24":{},"25":{},"26":{},"27":{}},"name":{},"parent":{}}],["individual",{"_index":87,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["informations",{"_index":120,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["initial",{"_index":364,"pagesPluginContent":{"27":{}},"name":{},"parent":{}}],["injectability",{"_index":0,"pagesPluginContent":{},"name":{"0":{}},"parent":{}}],["install",{"_index":30,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["interceptor`](https://docs.nestjs.com/interceptors",{"_index":186,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["invalid",{"_index":171,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["ipolicy",{"_index":15,"pagesPluginContent":{},"name":{"19":{}},"parent":{"20":{}}}],["is",{"_index":23,"pagesPluginContent":{"24":{},"25":{},"26":{}},"name":{},"parent":{}}],["it",{"_index":59,"pagesPluginContent":{"24":{},"25":{}},"name":{},"parent":{}}],["its",{"_index":122,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["join",{"_index":258,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["just",{"_index":291,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["jwt",{"_index":209,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["let's",{"_index":128,"pagesPluginContent":{"25":{},"26":{}},"name":{},"parent":{}}],["level",{"_index":97,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["like",{"_index":216,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["link",{"_index":53,"pagesPluginContent":{"24":{},"25":{},"26":{}},"name":{},"parent":{}}],["matching",{"_index":308,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["method",{"_index":136,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["method1",{"_index":274,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["method2",{"_index":275,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["methods",{"_index":76,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["middleware`](https://docs.nestjs.com/middleware",{"_index":184,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["might",{"_index":139,"pagesPluginContent":{"25":{},"26":{}},"name":{},"parent":{}}],["module",{"_index":22,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["more",{"_index":146,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["moreover",{"_index":247,"pagesPluginContent":{"25":{},"26":{}},"name":{},"parent":{}}],["most",{"_index":112,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["multiple",{"_index":239,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["myability",{"_index":314,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["naive",{"_index":215,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["naive.controller.ts",{"_index":218,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["naiveguard",{"_index":197,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["naïve",{"_index":134,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["nestjs",{"_index":154,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["nestjs/passport`](https://www.npmjs.com/package/@nestjs/passport",{"_index":193,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["nestjs@^8.0.0",{"_index":26,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["next",{"_index":107,"pagesPluginContent":{"24":{},"25":{}},"name":{},"parent":{}}],["not",{"_index":137,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["notable",{"_index":349,"pagesPluginContent":{"27":{}},"name":{},"parent":{}}],["note",{"_index":287,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["now",{"_index":67,"pagesPluginContent":{"24":{},"25":{},"26":{}},"name":{},"parent":{}}],["npm",{"_index":33,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["of",{"_index":77,"pagesPluginContent":{"24":{},"25":{},"26":{}},"name":{},"parent":{}}],["on",{"_index":178,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["or",{"_index":185,"pagesPluginContent":{"25":{},"26":{}},"name":{},"parent":{}}],["order",{"_index":336,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["our",{"_index":304,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["owner.controller.ts",{"_index":83,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["page",{"_index":108,"pagesPluginContent":{"24":{},"25":{}},"name":{},"parent":{}}],["parameter",{"_index":329,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["part",{"_index":334,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["pass",{"_index":315,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["passes",{"_index":279,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["passport",{"_index":205,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["passport.strategy.ts",{"_index":212,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["placed",{"_index":235,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["policies",{"_index":94,"pagesPluginContent":{"24":{},"25":{},"26":{}},"name":{},"parent":{}}],["policies.ts",{"_index":341,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["policiesguard",{"_index":202,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["policiesmask",{"_index":3,"pagesPluginContent":{"24":{},"25":{}},"name":{"4":{},"5":{},"11":{}},"parent":{"6":{}}}],["policiesmask.usingguard",{"_index":252,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["policy",{"_index":1,"pagesPluginContent":{"24":{},"25":{}},"name":{"1":{},"2":{},"10":{}},"parent":{"3":{}}}],["policy.usingguard",{"_index":251,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["policydescriptor",{"_index":13,"pagesPluginContent":{"25":{}},"name":{"17":{}},"parent":{}}],["policydescriptormask",{"_index":14,"pagesPluginContent":{},"name":{"18":{}},"parent":{}}],["possible",{"_index":155,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["prefer",{"_index":249,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["prepare",{"_index":268,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["prepended",{"_index":253,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["presets",{"_index":250,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["problem",{"_index":227,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["project",{"_index":351,"pagesPluginContent":{"27":{}},"name":{},"parent":{}}],["property",{"_index":176,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["protect",{"_index":74,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["provide",{"_index":260,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["provider",{"_index":39,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["ran",{"_index":237,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["readability",{"_index":233,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["recommanded",{"_index":138,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["recommended",{"_index":142,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["reduce",{"_index":323,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["release",{"_index":365,"pagesPluginContent":{"27":{}},"name":{},"parent":{}}],["request",{"_index":45,"pagesPluginContent":{"24":{},"25":{}},"name":{},"parent":{}}],["require",{"_index":149,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["ressource",{"_index":201,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["retrieval",{"_index":207,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["reusability",{"_index":238,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["role",{"_index":286,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["run",{"_index":276,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["same",{"_index":95,"pagesPluginContent":{"24":{},"25":{}},"name":{},"parent":{}}],["say",{"_index":208,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["scitizen/nest",{"_index":34,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["see",{"_index":160,"pagesPluginContent":{"25":{},"27":{}},"name":{},"parent":{}}],["set",{"_index":177,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["setting",{"_index":190,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["setup",{"_index":27,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["should",{"_index":187,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["show",{"_index":125,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["simple",{"_index":265,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["simplepolicy",{"_index":17,"pagesPluginContent":{},"name":{"21":{}},"parent":{}}],["simply",{"_index":343,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["skip",{"_index":140,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["so",{"_index":297,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["solve",{"_index":339,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["some",{"_index":115,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["spec.ts",{"_index":105,"pagesPluginContent":{"24":{},"25":{},"26":{}},"name":{},"parent":{}}],["spec.ts#abilityfactory",{"_index":49,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["spec.ts#appmodule",{"_index":63,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["spec.ts#catcarecontroller",{"_index":88,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["spec.ts#catcontroller",{"_index":98,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["spec.ts#catownercontroller",{"_index":81,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["spec.ts#test",{"_index":103,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["src/ability",{"_index":50,"pagesPluginContent":{"24":{},"25":{},"26":{}},"name":{},"parent":{}}],["src/app.module.ts",{"_index":64,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["src/cat",{"_index":82,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["src/cat.controller.ts",{"_index":99,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["src/controllers/naive.controller.ts",{"_index":196,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["src/controllers/passport",{"_index":219,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["src/controllers/recommended.controller.ts",{"_index":266,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["src/guards/naive.guard.ts",{"_index":157,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["src/my",{"_index":342,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["src/policies.ts",{"_index":270,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["src/recommended",{"_index":271,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["src/strategies/jwt",{"_index":213,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["src/test",{"_index":347,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["src/test.controller.ts",{"_index":332,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["standard",{"_index":354,"pagesPluginContent":{"27":{}},"name":{},"parent":{}}],["start",{"_index":68,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["started",{"_index":111,"pagesPluginContent":{},"name":{"24":{}},"parent":{}}],["still",{"_index":214,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["strategies",{"_index":241,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["strategy",{"_index":210,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["subject`s",{"_index":306,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["subsequent",{"_index":257,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["succeed",{"_index":203,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["suggest",{"_index":327,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["take",{"_index":188,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["test.e2e",{"_index":225,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["test/basic",{"_index":47,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["test/better",{"_index":312,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["test/cats.e2e",{"_index":104,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["test/use",{"_index":132,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["tested",{"_index":289,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["tests",{"_index":101,"pagesPluginContent":{"24":{},"25":{}},"name":{},"parent":{}}],["that",{"_index":40,"pagesPluginContent":{"24":{},"25":{},"26":{}},"name":{},"parent":{}}],["that's",{"_index":320,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["the",{"_index":31,"pagesPluginContent":{"24":{},"25":{},"26":{}},"name":{},"parent":{}}],["them",{"_index":199,"pagesPluginContent":{"25":{},"26":{}},"name":{},"parent":{}}],["then",{"_index":36,"pagesPluginContent":{"24":{},"25":{},"26":{}},"name":{},"parent":{}}],["there",{"_index":230,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["they",{"_index":262,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["this",{"_index":21,"pagesPluginContent":{"24":{},"25":{},"26":{},"27":{}},"name":{},"parent":{}}],["those",{"_index":254,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["through",{"_index":278,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["times",{"_index":113,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["to",{"_index":60,"pagesPluginContent":{"24":{},"25":{},"26":{},"27":{}},"name":{},"parent":{}}],["type",{"_index":248,"pagesPluginContent":{"25":{},"26":{}},"name":{"26":{}},"parent":{}}],["types",{"_index":311,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["types/ability",{"_index":328,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["types/ability.ts",{"_index":313,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["types/ability.typecheck.e2e",{"_index":319,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["types/my",{"_index":340,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["types/test",{"_index":346,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["types/test.controller.ts",{"_index":331,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["typos",{"_index":325,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["unauthorized",{"_index":169,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["usage",{"_index":73,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["use",{"_index":61,"pagesPluginContent":{"24":{},"25":{},"26":{}},"name":{"25":{}},"parent":{}}],["use.e2e",{"_index":48,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["used",{"_index":86,"pagesPluginContent":{"24":{}},"name":{},"parent":{}}],["useguards",{"_index":234,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["user",{"_index":119,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["users",{"_index":166,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["using",{"_index":69,"pagesPluginContent":{"24":{},"25":{},"26":{}},"name":{},"parent":{}}],["usingguard",{"_index":2,"pagesPluginContent":{},"name":{"3":{},"6":{}},"parent":{}}],["valid",{"_index":173,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["various",{"_index":93,"pagesPluginContent":{"24":{},"25":{}},"name":{},"parent":{}}],["version",{"_index":357,"pagesPluginContent":{"27":{}},"name":{},"parent":{}}],["version](https://github.com/conventional",{"_index":355,"pagesPluginContent":{"27":{}},"name":{},"parent":{}}],["wanna",{"_index":220,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["want",{"_index":91,"pagesPluginContent":{"24":{},"25":{}},"name":{},"parent":{}}],["way",{"_index":126,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["we",{"_index":299,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["well",{"_index":229,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["were",{"_index":300,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["what",{"_index":106,"pagesPluginContent":{"24":{},"25":{},"26":{}},"name":{},"parent":{}}],["what's",{"_index":226,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["will",{"_index":124,"pagesPluginContent":{"25":{},"26":{},"27":{}},"name":{},"parent":{}}],["with",{"_index":25,"pagesPluginContent":{"24":{},"25":{},"26":{}},"name":{"25":{}},"parent":{}}],["withconfig",{"_index":9,"pagesPluginContent":{},"name":{"13":{}},"parent":{}}],["without",{"_index":144,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["world",{"_index":183,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["yeah",{"_index":179,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["yet",{"_index":303,"pagesPluginContent":{"26":{}},"name":{},"parent":{}}],["you",{"_index":65,"pagesPluginContent":{"24":{},"25":{},"26":{}},"name":{},"parent":{}}],["you're",{"_index":204,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}],["your",{"_index":55,"pagesPluginContent":{"24":{},"25":{},"26":{}},"name":{},"parent":{}}],["yourself",{"_index":293,"pagesPluginContent":{"25":{}},"name":{},"parent":{}}]],"pipeline":[]}} \ No newline at end of file diff --git a/docs/classes/CaslModule.html b/docs/classes/CaslModule.html new file mode 100644 index 00000000..d1a94c4d --- /dev/null +++ b/docs/classes/CaslModule.html @@ -0,0 +1,255 @@ + + + + + + CaslModule | @scitizen/nest-casl + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+
+ +

Class CaslModule

+
+
+
+
+
+
+
+

Hierarchy

+
    +
  • + CaslModule +
  • +
+
+
+

Index

+
+
+
+

Constructors

+ +
+
+

Methods

+ +
+
+
+
+
+

Constructors

+
+ +

constructor

+ + +
+
+
+

Methods

+
+ +

Static withConfig

+ +
    +
  • + +
    +
    +

    Configure the CaslModule using the provided configuration.

    +
    +
    +

    Parameters

    +
      +
    • +
      config: ICaslRootConfig<any>
      +
      +

      The module configuration to use.

      +
      +
    • +
    +

    Returns DynamicModule

    +

    the configured CaslModule

    +
  • +
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Property
  • +
  • Method
  • +
+
    +
  • Constructor
  • +
+
    +
  • Static method
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + + \ No newline at end of file diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 00000000..15a5abac --- /dev/null +++ b/docs/index.html @@ -0,0 +1,271 @@ + + + + + + @scitizen/nest-casl + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+
+ +

Project @scitizen/nest-casl

+
+
+
+
+
+
+
+ +

@scitizen/nest-casl

+
+

+ Nest Logo +  +  + CASL Logo +

+

A simple decorator-based way to check CASL abilities on NestJS controllers.

+

+ GitHub issues + NPM Version + Package License + NPM Downloads + CircleCI + + +

+ +

Description

+
+

Use decorators everywhere to protect your controller methods.

+ + +

Installation

+
+
npm install --save @scitizen/nest-casl
+
+ +

In a nutshell

+
+

Declare a new service that converts the user of your request to a CASL ability:

+
import { Injectable } from '@nestjs/common';
+import { AbilityBuilder, PureAbility } from '@casl/ability';
+import { CaslAbilityFactory } from '@scitizen/nest-casl';
+
+@Injectable()
+export class AbilityFactory implements CaslAbilityFactory {
+    // Here, `request` is the express or fastify request. You might get infos from it.
+    public createFromRequest( _request: unknown ): PureAbility {
+        const abilityBuilder = new AbilityBuilder( PureAbility );
+        abilityBuilder.can( 'feed', 'cat' );
+        abilityBuilder.can( 'hug', 'cat' );
+        abilityBuilder.can( 'pet', 'cat' );
+        abilityBuilder.cannot( 'rename', 'cat' );
+        return abilityBuilder.build();
+    }
+}
+
+

Import the module:

+
import { Module } from '@nestjs/common';
+import { CaslModule } from '@scitizen/nest-casl';
+
+@Module( {
+    imports: [
+        CaslModule.withConfig( ( { abilityFactory: AbilityFactory } ) ),
+        // ....
+    ],
+} )
+export class AppModule {}
+
+

Use decorators in your controller:

+
import { AbilityBuilder, PureAbility } from '@casl/ability';
+import { Controller, Get } from '@nestjs/common';
+import { InjectAbility, PoliciesMask, Policy } from '@scitizen/nest-casl';
+
+@Controller( '/cat/care' )
+@PoliciesMask({
+    'pet': { action: 'pet', subject: 'cat' }
+})
+export class CatCareController {
+    // Okay, you can feed.
+    @Get( 'feed' )
+    @Policy( { action: 'feed', subject: 'cat' } )
+    public feed(){
+        // ...
+    }
+
+    // Well, I guess he won't bite.
+    @Get( 'hug' )
+    @Policy( { action: 'hug', subject: 'cat' } )
+    public hug(){
+        // ...
+    }
+
+    @Get( 'pet' )
+    public pet( @InjectAbility() ability: PureAbility ){
+        // ...
+    }
+}
+
+

For more details and usage with guards, please refer to the guide.

+ +

License

+
+

@scitizen/nest-casl is MIT licensed.

+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Property
  • +
  • Method
  • +
+
    +
  • Constructor
  • +
+
    +
  • Static method
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + + \ No newline at end of file diff --git a/docs/interfaces/CaslAbilityFactory.html b/docs/interfaces/CaslAbilityFactory.html new file mode 100644 index 00000000..137b4201 --- /dev/null +++ b/docs/interfaces/CaslAbilityFactory.html @@ -0,0 +1,244 @@ + + + + + + CaslAbilityFactory | @scitizen/nest-casl + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+
+ +

Interface CaslAbilityFactory<TAbility>

+
+
+
+
+
+
+
+
+
+

A class interface that generate the CASL ability from the request.

+
+
+
+
+

Type parameters

+
    +
  • +

    TAbility: AnyAbilityLike

    +
  • +
+
+
+

Hierarchy

+
    +
  • + CaslAbilityFactory +
  • +
+
+
+

Index

+
+
+
+

Methods

+ +
+
+
+
+
+

Methods

+
+ +

createFromRequest

+
    +
  • createFromRequest(request: unknown): TAbility
  • +
+
    +
  • + +
    +
    +

    Extract the ability from the HTTP request.

    +
    +
    +

    Parameters

    +
      +
    • +
      request: unknown
      +
      +

      The HTTP request, usually from express or fastify depending on your HTTP adapter.

      +
      +
    • +
    +

    Returns TAbility

    +

    the ability for the user.

    +
  • +
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Property
  • +
  • Method
  • +
+
    +
  • Constructor
  • +
+
    +
  • Static method
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + + \ No newline at end of file diff --git a/docs/interfaces/ICaslRootConfig.html b/docs/interfaces/ICaslRootConfig.html new file mode 100644 index 00000000..9356b530 --- /dev/null +++ b/docs/interfaces/ICaslRootConfig.html @@ -0,0 +1,215 @@ + + + + + + ICaslRootConfig | @scitizen/nest-casl + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+
+ +

Interface ICaslRootConfig<TAbility>

+
+
+
+
+
+
+
+

Type parameters

+
    +
  • +

    TAbility: AnyAbilityLike

    +
  • +
+
+
+

Hierarchy

+
    +
  • + ICaslRootConfig +
  • +
+
+
+

Index

+
+
+
+

Properties

+ +
+
+
+
+
+

Properties

+
+ +

abilityFactory

+
abilityFactory: Type<CaslAbilityFactory<TAbility>>
+ +
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Property
  • +
  • Method
  • +
+
    +
  • Constructor
  • +
+
    +
  • Static method
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + + \ No newline at end of file diff --git a/docs/interfaces/IPolicy.html b/docs/interfaces/IPolicy.html new file mode 100644 index 00000000..16dbfc78 --- /dev/null +++ b/docs/interfaces/IPolicy.html @@ -0,0 +1,244 @@ + + + + + + IPolicy | @scitizen/nest-casl + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+
+ +

Interface IPolicy<TAbility>

+
+
+
+
+
+
+
+
+
+

This interface specify a class or object that can do dynamic and complex checks about the current user abilities.

+
+
+
+
+

Type parameters

+
    +
  • +

    TAbility: AnyAbilityLike

    +
  • +
+
+
+

Hierarchy

+
    +
  • + IPolicy +
  • +
+
+
+

Index

+
+
+
+

Methods

+ +
+
+
+
+
+

Methods

+
+ +

handle

+
    +
  • handle(ability: TAbility): boolean
  • +
+
    +
  • + +
    +
    +

    Check if the ability is allowed.

    +
    +
    +

    Parameters

    +
      +
    • +
      ability: TAbility
      +
      +

      The request's ability.

      +
      +
    • +
    +

    Returns boolean

    +

    true if allowed, false otherwise.

    +
  • +
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Property
  • +
  • Method
  • +
+
    +
  • Constructor
  • +
+
    +
  • Static method
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + + \ No newline at end of file diff --git a/docs/modules.html b/docs/modules.html new file mode 100644 index 00000000..4a966e4b --- /dev/null +++ b/docs/modules.html @@ -0,0 +1,499 @@ + + + + + + @scitizen/nest-casl + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+
+ +

Project @scitizen/nest-casl

+
+
+
+
+
+
+
+

Index

+
+
+
+

Namespaces

+ +
+
+

Classes

+ +
+
+

Interfaces

+ +
+
+

Type aliases

+ +
+
+

Decorators Functions

+ +

Other Functions

+ +
+
+
+
+
+

Type aliases

+
+ +

BoundPolicyDecorators

+
BoundPolicyDecorators<TAbility>: { PoliciesMask: PoliciesMask<TAbility>; Policy: Policy<TAbility> }
+ +

Type parameters

+
    +
  • +

    TAbility: AnyAbilityLike

    +
  • +
+
+

Type declaration

+
    +
  • + + +
  • +
  • +
    PoliciesMask: PoliciesMask<TAbility>
    +
  • +
  • +
    Policy: Policy<TAbility>
    +
  • +
+
+
+
+ +

PolicyDescriptor

+
PolicyDescriptor<TAbility>: Type<IPolicy<TAbility>> | IPolicy<TAbility> | ((ability: TAbility) => boolean) | SimplePolicy<TAbility> | boolean
+ +
+
+

Any type of policy that can be handled. It can either be

+
    +
  • an object or an injectable class implementing IPolicy
  • +
  • a simple function that takes the ability and return a boolean
  • +
  • a SimplePolicy defining the action and subject
  • +
  • or a static boolean.
  • +
+
+

Note that in some cases, static boolean are handled in a special way.

+
+
todo
+

Docs page about special case.

+
+
+
+

Type parameters

+
    +
  • +

    TAbility: AnyAbilityLike

    +
  • +
+
+
+ +

PolicyDescriptorMask

+
PolicyDescriptorMask<TAbility>: Record<string, PolicyDescriptor<TAbility>>
+ +
+
+

A dictionary of policies to apply on a class. All properties must be methods of the class it is applied on, except *.

+
+

The * key is a special fallback case.

+
+
todo
+

Docs page about special case.

+
+
+
+

Type parameters

+
    +
  • +

    TAbility: AnyAbilityLike

    +
  • +
+
+
+ +

SimplePolicy

+
SimplePolicy<TAbility>: TAbility extends Ability<infer TAbilityTuple> ? TAbilityTuple extends any ? { action: TAbilityTuple[0]; subject: TAbilityTuple[1] } : never : { action: string; subject: string }
+ +
+
+

A simple policy defined by an action and a subject.

+
+
+
see
+

https://casl.js.org/v5/en/guide/intro#basics

+
+
+
+

Type parameters

+
    +
  • +

    TAbility: AnyAbilityLike

    +
  • +
+
+
+
+

Decorators Functions

+
+ +

Const InjectAbility

+
    +
  • InjectAbility(required?: boolean): ParameterDecorator
  • +
+
    +
  • + +
    +
    +

    A parameter decorator factory that retrieve the ability of the current request.

    +
    +
    +

    Parameters

    +
      +
    • +
      Optional required: boolean
      +
      +

      Set to false to not throw if no ability was found for the request. Defaults to true.

      +
      +
    • +
    +

    Returns ParameterDecorator

    +

    a parameter decorator that will set the parameter value to the ability. If not {@link required} and none is found, a new empty ability will be created.

    +
  • +
+
+
+ +

PoliciesMask

+
    +
  • PoliciesMask<TMask, TAbility>(mask: TMask): BoundPoliciesMask<TMask, TAbility>
  • +
+ +
+
+ +

Policy

+
    +
  • Policy<TAbility>(policy: PolicyDescriptor<TAbility>): BoundPolicy<TAbility>
  • +
+ +
+
+
+

Other Functions

+
+ +

Const bindPolicyDecorators

+ +
    +
  • + +

    Type parameters

    +
      +
    • +

      TAbility: AnyAbilityLike

      +
    • +
    +

    Parameters

    +
      +
    • +
      Rest ...guards: GuardsList
      +
    • +
    +

    Returns BoundPolicyDecorators<TAbility>

    +
  • +
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Property
  • +
  • Method
  • +
+
    +
  • Constructor
  • +
+
    +
  • Static method
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + + \ No newline at end of file diff --git a/docs/modules/PoliciesMask.html b/docs/modules/PoliciesMask.html new file mode 100644 index 00000000..fe961ef3 --- /dev/null +++ b/docs/modules/PoliciesMask.html @@ -0,0 +1,188 @@ + + + + + + PoliciesMask | @scitizen/nest-casl + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+
+ +

Namespace PoliciesMask

+
+
+
+
+
+
+
+

Index

+
+
+
+

Functions

+ +
+
+
+
+
+

Functions

+
+ +

usingGuard

+
    +
  • usingGuard(...guards: GuardsList): PoliciesMask<AnyAbilityLike>
  • +
+
    +
  • + +
    +
    +

    Create a new PoliciesMask decorator factory that will always use the given {@link guards} before checking.

    +
    +
    +

    Parameters

    +
      +
    • +
      Rest ...guards: GuardsList
      +
      +

      The list of guards to use.

      +
      +
    • +
    +

    Returns PoliciesMask<AnyAbilityLike>

    +

    a new PoliciesMask decorator factory.

    +
  • +
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Property
  • +
  • Method
  • +
+
    +
  • Constructor
  • +
+
    +
  • Static method
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + + \ No newline at end of file diff --git a/docs/modules/Policy.html b/docs/modules/Policy.html new file mode 100644 index 00000000..c740c27e --- /dev/null +++ b/docs/modules/Policy.html @@ -0,0 +1,188 @@ + + + + + + Policy | @scitizen/nest-casl + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+
+ +

Namespace Policy

+
+
+
+
+
+
+
+

Index

+
+
+
+

Functions

+ +
+
+
+
+
+

Functions

+
+ +

usingGuard

+
    +
  • usingGuard(...guards: GuardsList): typeof Policy
  • +
+
    +
  • + +
    +
    +

    Create a new Policy decorator factory that will always use the given {@link guards} before checking.

    +
    +
    +

    Parameters

    +
      +
    • +
      Rest ...guards: GuardsList
      +
      +

      The list of guards to use.

      +
      +
    • +
    +

    Returns typeof Policy

    +

    a new Policy decorator factory.

    +
  • +
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Property
  • +
  • Method
  • +
+
    +
  • Constructor
  • +
+
    +
  • Static method
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + + \ No newline at end of file diff --git a/docs/pages/Changelog/CHANGELOG.html b/docs/pages/Changelog/CHANGELOG.html new file mode 100644 index 00000000..a76fc1ca --- /dev/null +++ b/docs/pages/Changelog/CHANGELOG.html @@ -0,0 +1,150 @@ + + + + + + Changelog | @scitizen/nest-casl + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+
+ +

Changelog

+
+
+
+
+
+
+
+ +

Changelog

+
+

All notable changes to this project will be documented in this file. See standard-version for commit guidelines.

+ +

0.0.1 (2021-10-06)

+
+

Initial release

+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Property
  • +
  • Method
  • +
+
    +
  • Constructor
  • +
+
    +
  • Static method
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + + \ No newline at end of file diff --git a/docs/pages/Guides/better-type-constraints.html b/docs/pages/Guides/better-type-constraints.html new file mode 100644 index 00000000..22a0c2e4 --- /dev/null +++ b/docs/pages/Guides/better-type-constraints.html @@ -0,0 +1,292 @@ + + + + + + Better type constraints | @scitizen/nest-casl + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+
+ +

Better type constraints

+
+
+
+
+
+
+
+

So far, we were able to configure your policies. But we can't yet check that our actions or subjects are actually matching what we declared.

+ +

Define the ability type

+
+

Let's configure our ability types:

+

From ./test/demo/better-types/ability.ts#1~6

+
import { Ability } from '@casl/ability';
+
+export type MyAbilities =
+	| ['admin', 'ImportantData']
+	| ['create' | 'read' | 'update' | 'delete', 'PublicData' ];
+export type MyAbility = Ability<MyAbilities>;
+
+

+

Using MyAbility, we can't pass anything to can or cannot: types are constrained.

+

From ./test/demo/better-types/ability.typecheck.e2e-spec.ts#1~12

+
import { expectTypeOf } from 'expect-type';
+
+import { MyAbility } from './ability';
+
+it( 'ability should have correct typings', () => {
+	expectTypeOf<['read', 'PublicData']>().toMatchTypeOf<Parameters<MyAbility['can']>>();
+	expectTypeOf<['create', 'PublicData']>().toMatchTypeOf<Parameters<MyAbility['can']>>();
+	expectTypeOf<['admin', 'ImportantData']>().toMatchTypeOf<Parameters<MyAbility['can']>>();
+
+	expectTypeOf<['admin', 'PublicData']>().not.toMatchTypeOf<Parameters<MyAbility['can']>>();
+	expectTypeOf<['read', 'ImportantData']>().not.toMatchTypeOf<Parameters<MyAbility['can']>>();
+} );
+
+

+

That's great. This will greatly reduce our chances of typos. Moreover, your IDE might now suggest actions & subjects for you.

+ +

Use the ability type

+
+ +

With the CaslAbilityFactory

+ +

Let's now use this type in your CaslAbilityFactory:

+

From ./src/ability-factory.service.ts

+
import { AbilityBuilder, PureAbility } from '@casl/ability';
+import { Injectable } from '@nestjs/common';
+
+import { CaslAbilityFactory } from '@scitizen/nest-casl';
+
+import { MyAbility } from './ability';
+
+@Injectable()
+export class AbilityFactory implements CaslAbilityFactory<MyAbility> {
+	// Here, `request` is the express or fastify request. You might get infos from it.
+	public createFromRequest( _request: unknown ): MyAbility {
+		const { user } = ( _request as any );
+		const abilityBuilder = new AbilityBuilder<MyAbility>( PureAbility );
+		if( user?.role === 'admin' ) {
+			abilityBuilder.can( 'admin', 'ImportantData' );
+		}
+		return abilityBuilder.build();
+	}
+}
+
+

+ +

With decorators

+
+

You can pass your ability as a type parameter to your decorators to constraint your actions and subjects:

+

From ./src/test.controller.ts

+
import { Controller, Get } from '@nestjs/common';
+
+import { Policy } from '@scitizen/nest-casl';
+
+import { MyAbility } from './ability';
+
+@Controller()
+// @ts-expect-error -- `something` is not a valid subject
+@Policy<MyAbility>( { action: 'admin', subject: 'something' } )
+// @ts-expect-error -- `rick-roll` is not a valid action
+@Policy<MyAbility>( { action: 'rick-roll', subject: 'ImportantData' } )
+// @ts-expect-error -- `read` is not a valid action on `ImportantData`
+@Policy<MyAbility>( { action: 'read', subject: 'ImportantData' } )
+@Policy<MyAbility>( { action: 'read', subject: 'PublicData' } )
+// ...
+export class TestController {
+	@Get()
+	public method(){
+		// ...
+	}
+}
+
+

+

But the boring part here is that you have to pass your ability type to every decorator in order to constrain them. Hopefully, you can solve this:

+

From ./src/my-policies.ts

+
import { bindPolicyDecorators } from '@scitizen/nest-casl';
+
+import { MyAbility } from './ability';
+
+export const MyPolicies = bindPolicyDecorators<MyAbility>( /* you can even pass some guards here ! */ );
+
+

+

Then, simply enjoy type contraints !

+

From ./src/test-bound.controller.ts

+
import { Controller, Get } from '@nestjs/common';
+
+import { MyPolicies } from './my-policies';
+
+@Controller()
+@MyPolicies.PoliciesMask( {
+	'*': { action: 'admin', subject: 'ImportantData' },
+	'read': { action: 'read', subject: 'PublicData' },
+	'create': { action: 'create', subject: 'PublicData' },
+} )
+export class TestController {
+	@Get()
+	@MyPolicies.Policy( { handle: ability => ability.can( 'read', 'PublicData' ) } )
+	public create(){
+		// ...
+	}
+	@Get()
+	public read(){
+		// ...
+	}
+
+	@Get()
+	public admin(){
+		// ...
+	}
+}
+
+

+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Property
  • +
  • Method
  • +
+
    +
  • Constructor
  • +
+
    +
  • Static method
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + + \ No newline at end of file diff --git a/docs/pages/Guides/getting-started.html b/docs/pages/Guides/getting-started.html new file mode 100644 index 00000000..2a3c454f --- /dev/null +++ b/docs/pages/Guides/getting-started.html @@ -0,0 +1,311 @@ + + + + + + Getting started | @scitizen/nest-casl + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+
+ +

Getting started

+
+
+
+
+
+
+
+
+

This module is compatible with nestjs@^8.0.0.

+
+ +

Setup & configuration

+
+

First, install the module:

+
npm install @scitizen/nest-casl
+
+

Then, declare a provider that generate a CASL Ability from the current request.

+

From ./src/ability-factory.service.ts

+
@Injectable()
+export class AbilityFactory implements CaslAbilityFactory {
+	// Here, `request` is the express or fastify request. You might get infos from it.
+	public createFromRequest( _request: unknown ): PureAbility {
+		const abilityBuilder = new AbilityBuilder( PureAbility );
+		abilityBuilder.can( 'feed', 'cat' );
+		abilityBuilder.can( 'hug', 'cat' );
+		abilityBuilder.cannot( 'rename', 'cat' );
+		return abilityBuilder.build();
+	}
+}
+
+

+

Import the CaslModule in your AppModule, and configure it to use your ability factory.

+

From ./src/app.module.ts

+
@Module( {
+	imports: [
+		CaslModule.withConfig( ( { abilityFactory: AbilityFactory } ) ),
+		// ....
+	],
+} )
+export class AppModule {}
+
+

+

You can now start using policy decorators (Policy and PoliciesMask) in your controllers !

+ +

Basic usage

+
+

You can protect all methods of your controller using the Policy class decorator.

+

From ./src/cat-owner.controller.ts

+
@Controller( '/cat/owner' )
+@Policy( { action: 'rename', subject: 'cat' } )
+export class CatOwnerController {
+	// Given the ability builder above, this method will always reject.
+	@Post( 'rename' )
+	public rename( @Body() _name: string ){
+		// ...
+	}
+}
+
+

+

This decorator can also be used to protect individual methods.

+

From ./src/cat-care.controller.ts

+
@Controller( '/cat/care' )
+export class CatCareController {
+	// Okay, you can feed.
+	@Get( 'feed' )
+	@Policy( { action: 'feed', subject: 'cat' } )
+	public feed(){
+		// ...
+	}
+
+	// Well, I guess he won't bite.
+	@Get( 'hug' )
+	@Policy( { action: 'hug', subject: 'cat' } )
+	public hug(){
+		// ...
+	}
+}
+
+

+

If you want to group various policies in the same decorator at the controller level, use the PoliciesMask decorator.

+

From ./src/cat.controller.ts

+
@Controller( '/cat' )
+@PoliciesMask( {
+	feed: { action: 'feed', subject: 'cat' },
+	hug: { action: 'hug', subject: 'cat' },
+	rename: { action: 'rename', subject: 'cat' },
+} )
+export class CatController {
+	@Get( 'feed' )
+	public feed(){
+		// ...
+	}
+
+	@Get( 'hug' )
+	public hug(){
+		// ...
+	}
+
+	@Post( 'rename' )
+	public rename( @Body() _name: string ){
+		// ...
+	}
+}
+
+

+

Check the tests !

+

From ./test/cats.e2e-spec.ts

+
describe( 'Basic usage', () => {
+	let app: INestApplication;
+
+	beforeAll( async () => {
+		const moduleRef = await Test.createTestingModule( {
+			imports: [ CaslModule.withConfig( { abilityFactory: AbilityFactory } ) ],
+			controllers: [
+				CatOwnerController, CatCareController, CatController,
+			],
+		} ).compile();
+
+		app = moduleRef.createNestApplication();
+		await app.init();
+	} );
+
+	describe( 'CatOwnerController', () => {
+		it( 'should not be able to rename a cat', () => request( app.getHttpServer() )
+			.post( '/cat/owner/rename' )
+			.expect( HttpStatus.FORBIDDEN ) );
+	} );
+	describe( 'CatCareController', () => {
+		it( 'should be able to feed the cat', () => request( app.getHttpServer() )
+			.get( '/cat/care/feed' )
+			.expect( HttpStatus.OK ) );
+		it( 'should be able to hug the cat', () => request( app.getHttpServer() )
+			.get( '/cat/care/hug' )
+			.expect( HttpStatus.OK ) );
+	} );
+	describe( 'PoliciesMask', () => {
+		it( 'should not be able to rename a cat', () => request( app.getHttpServer() )
+			.post( '/cat/rename' )
+			.expect( HttpStatus.FORBIDDEN ) );
+		it( 'should be able to feed the cat', () => request( app.getHttpServer() )
+			.get( '/cat/feed' )
+			.expect( HttpStatus.OK ) );
+		it( 'should be able to hug the cat', () => request( app.getHttpServer() )
+			.get( '/cat/hug' )
+			.expect( HttpStatus.OK ) );
+	} );
+} );
+
+

+ +

What next ?

+
+

Use with guards

+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Property
  • +
  • Method
  • +
+
    +
  • Constructor
  • +
+
    +
  • Static method
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + + \ No newline at end of file diff --git a/docs/pages/Guides/use-with-guards.html b/docs/pages/Guides/use-with-guards.html new file mode 100644 index 00000000..cdf93e07 --- /dev/null +++ b/docs/pages/Guides/use-with-guards.html @@ -0,0 +1,572 @@ + + + + + + Use with guards | @scitizen/nest-casl + + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+
+ +

Use with guards

+
+
+
+
+
+
+
+

Most of the times, you want to execute some guards before checking CASL policies, to extract some user informations before generating its abilities.

+

This page will show you the various way to do.

+

Let's assume you have the following CaslAbilityFactory:

+

From ./src/ability-factory.service.ts

+
import { AbilityBuilder, PureAbility } from '@casl/ability';
+import { Injectable } from '@nestjs/common';
+
+import { CaslAbilityFactory } from '@scitizen/nest-casl';
+
+@Injectable()
+export class AbilityFactory implements CaslAbilityFactory {
+	// Here, `request` is the express or fastify request. You might get infos from it.
+	public createFromRequest( _request: unknown ): PureAbility {
+		const { user } = ( _request as any );
+		const abilityBuilder = new AbilityBuilder( PureAbility );
+		if( user?.role === 'admin' ) {
+			abilityBuilder.can( 'admin', 'something' );
+		}
+		return abilityBuilder.build();
+	}
+}
+
+

+ +

The naïve approach

+
+
+

This method is not recommanded. You might skip directly to the recommended approach

+
+ +

Without any more dependencies

+
+

This method does not require any external dependency, and is as close to NestJS as possible.

+

From ./src/guards/naive.guard.ts

+
import { CanActivate, ExecutionContext, UnauthorizedException } from '@nestjs/common';
+import { Request } from 'express';
+
+export class NaiveGuard implements CanActivate {
+	public canActivate( context: ExecutionContext ): boolean {
+		const request = context.switchToHttp().getRequest<Request>();
+		const authorization = request.header( 'Authorization' );
+		if( !authorization ){
+			// **BEWARE**: if the guard returns `false`, Nest will throw a `ForbiddenException` which is semantically incorrect here.
+			// The user is not *missing the right to do*, it is *not authenticated at all*.
+			throw new UnauthorizedException( 'Missing authorization header' );
+		}
+		const user = this._getUserFromAuthorization( authorization );
+		if( !user ){
+			return false;
+		}
+		( request as any ).user = user;
+		return true;
+	}
+
+	private _getUserFromAuthorization( authorization?: string ){
+		if( authorization === 'admin' ){
+			return { role: 'admin' };
+		} else if( authorization === 'user' ){
+			return { role: 'user' };
+		} else {
+			return undefined;
+		}
+	}
+}
+
+

+

Assuming the guard does the following (see above for an example implementation):

+
    +
  • Users without an Authorization header will see an Unauthorized exception.
  • +
  • Users with an invalid Authorization header will see a Forbidden exception.
  • +
  • Users with a valid Authorization header will be allowed to continue, and the property user is set on the request.
  • +
+
+

Yeah, I'm aware that in an ideal world, a Middleware or an Interceptor should take care of setting the user property on the Request. But fact is that @nestjs/passport does it in a guard

+
+

From ./src/controllers/naive.controller.ts

+
import { Controller, Get, UseGuards } from '@nestjs/common';
+
+import { Policy } from '@scitizen/nest-casl';
+
+import { NaiveGuard } from './naive.guard';
+
+@Controller( '/naive' )
+@Policy( { action: 'admin', subject: 'something' } ) // **MUST** be above the guard extracting infos from your request.
+@UseGuards( NaiveGuard )
+export class NaiveTestController {
+	@Get()
+	public method(){
+		// ...
+	}
+}
+
+

+

Now,

+
    +
  • Users without an Authorization header will see an Unauthorized exception (from the NaiveGuard).
  • +
  • Users with an invalid Authorization header will see a Forbidden exception (from the NaiveGuard).
  • +
  • Users with an Authorization header that does not give them access to the ressource will see a Forbidden exception (from the {@link PoliciesGuard PoliciesGuard}).
  • +
  • Users with an Authorization header that give them access to the ressource will succeed.
  • +
+ +

Using @nestjs/passport

+ +

If you're using passport, you can delegate the user retrieval. Let's say you have a JWT passport strategy.

+

From ./src/strategies/jwt-passport.strategy.ts

+
import { Injectable } from '@nestjs/common';
+import { PassportStrategy } from '@nestjs/passport';
+import { ExtractJwt, Strategy, StrategyOptions } from 'passport-jwt';
+
+@Injectable()
+export class JwtPassportStrategy extends PassportStrategy( Strategy, 'jwt' ) {
+	public static readonly KEY = 'this-is-a-secret';
+	public constructor(){
+		super( {
+			jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
+			secretOrKey: JwtPassportStrategy.KEY,
+		} as StrategyOptions );
+	}
+
+	public validate( user: any ){
+		return user;
+	}
+}
+
+

+

Still using the naive approach, you can then declare the controller like this:

+

From ./src/controllers/passport-naive.controller.ts

+
import { Controller, Get, UseGuards } from '@nestjs/common';
+import { AuthGuard } from '@nestjs/passport';
+
+import { Policy } from '@scitizen/nest-casl';
+
+@Controller( '/passport/naive' )
+@Policy( { action: 'admin', subject: 'something' } ) // **MUST** be above the guard extracting infos from your request.
+@UseGuards( AuthGuard( 'jwt' ) )
+export class PassportNaiveTestController {
+	@Get()
+	public method(){
+		// ...
+	}
+}
+
+

+ +

The tests

+
+

Wanna see the behavior as tests ? Here you are !

+

From ./test/demo/use-with-guards/naive-test.e2e-spec.ts#1~77

+
import { HttpStatus, INestApplication } from '@nestjs/common';
+import { JwtModule, JwtService } from '@nestjs/jwt';
+import { Test } from '@nestjs/testing';
+import request from 'supertest';
+
+import { CaslModule } from '@scitizen/nest-casl';
+
+import { AbilityFactory } from './ability-factory.service';
+import { JwtPassportStrategy } from './jwt-passport.strategy';
+import { NaiveTestController } from './naive.controller';
+import { PassportNaiveTestController } from './passport-naive.controller';
+
+describe( 'Use with guards (naive)', () => {
+	let app: INestApplication;
+
+	describe( 'NaiveTestController', () => {
+		beforeAll( async () => {
+			const moduleRef = await Test.createTestingModule( {
+				imports: [
+					CaslModule.withConfig( ( { abilityFactory: AbilityFactory } ) ),
+				],
+				controllers: [ NaiveTestController ],
+			} ).compile();
+
+			app = moduleRef.createNestApplication();
+			await app.init();
+		} );
+
+		it( 'should send an UNAUTHORIZED error if no authorization set', () => request( app.getHttpServer() )
+			.get( '/naive' )
+			.expect( HttpStatus.UNAUTHORIZED )
+			.expect( { statusCode: HttpStatus.UNAUTHORIZED, message: 'Missing authorization header', error: 'Unauthorized' } ) );
+		it( 'should send a FORBIDDEN error if invalid authorization', () => request( app.getHttpServer() )
+			.get( '/naive' )
+			.set( 'Authorization', 'invalid' )
+			.expect( HttpStatus.FORBIDDEN )
+			.expect( { statusCode: HttpStatus.FORBIDDEN, message: 'Forbidden resource', error: 'Forbidden' } ) );
+		it( 'should send a FORBIDDEN error if invalid capabilities', () => request( app.getHttpServer() )
+			.get( '/naive' )
+			.set( 'Authorization', 'user' )
+			.expect( HttpStatus.FORBIDDEN )
+			.expect( { statusCode: HttpStatus.FORBIDDEN, message: 'Invalid authorizations: Can\'t "admin" on "something"', error: 'Forbidden' } ) );
+		it( 'should work', () => request( app.getHttpServer() )
+			.get( '/naive' )
+			.set( 'Authorization', 'admin' )
+			.expect( HttpStatus.OK ) );
+	} );
+	describe( 'PassportNaiveTestController', () => {
+		beforeAll( async () => {
+			const moduleRef = await Test.createTestingModule( {
+				imports: [
+					CaslModule.withConfig( ( { abilityFactory: AbilityFactory } ) ),
+					JwtModule.register( { secret: JwtPassportStrategy.KEY } ),
+				],
+				providers: [ JwtPassportStrategy ],
+				controllers: [ PassportNaiveTestController ],
+			} ).compile();
+
+			app = moduleRef.createNestApplication();
+			await app.init();
+		} );
+
+		it( 'should send an UNAUTHORIZED error if no authorization set', () => request( app.getHttpServer() )
+			.get( '/passport/naive' )
+			.expect( HttpStatus.UNAUTHORIZED )
+			.expect( { statusCode: HttpStatus.UNAUTHORIZED, message: 'Unauthorized' } ) );
+		it( 'should send a FORBIDDEN error if invalid capabilities', () => request( app.getHttpServer() )
+			.get( '/passport/naive' )
+			.set( 'Authorization', `Bearer ${app.get( JwtService ).sign( { role: 'user' } )}` )
+			.expect( HttpStatus.FORBIDDEN )
+			.expect( { statusCode: HttpStatus.FORBIDDEN, message: 'Invalid authorizations: Can\'t "admin" on "something"', error: 'Forbidden' } ) );
+		it( 'should work', () => request( app.getHttpServer() )
+			.get( '/passport/naive' )
+			.set( 'Authorization', `Bearer ${app.get( JwtService ).sign( { role: 'admin' } )}` )
+			.expect( HttpStatus.OK ) );
+	} );
+} );
+
+

+ +

The recommended approach

+
+

What's the problem about the naïve approach above ? Well, there are 2.

+
    +
  1. The readability: The UseGuards decorator is placed below the Policy decorator, but is ran before it.
  2. +
  3. The reusability: If you're using multiple authentication strategies in the same app, you might have to apply guards and the policies on each method depending on the context. Moreover, if you want to type-check your policies, you might prefer to have abilities presets.
  4. +
+ +

About readability

+
+

You can use Policy.usingGuard or PoliciesMask.usingGuard to prepended guards to the decorator factory. Those calls are cumulative, and you can do multiple subsequent calls to join guards using an and condition. If you provide an array of guards, they be evaluated using an or condition.

+

From ./src/controllers/recommended.controller.ts

+
@Controller( '/recommended' )
+@Policy( { action: 'admin', subject: 'something' } )
+	.usingGuard( AuthGuard( 'jwt' ) ) // The policy will run the guard before doing its own checks.
+export class RecommendedTestController {
+	@Get()
+	public method(){
+		// ...
+	}
+}
+
+

+ +

About reusability

+
+

You can even prepare a policy decorator with guards or PolicyDescriptor:

+

From ./src/policies.ts

+
export const AdminViaJwtPolicy = Policy( { action: 'admin', subject: 'something' } )
+	.usingGuard( AuthGuard( 'jwt' ) );
+export const ViaJwtPolicy = Policy.usingGuard( AuthGuard( 'jwt' ) );
+
+

+

Then, use those presets in your controller:

+

From ./src/recommended-bound.controller.ts

+
@Injectable()
+export class ExtraGuard1 implements CanActivate {
+	public canActivate( context: ExecutionContext ): boolean {
+		if( !context.switchToHttp().getRequest().user.allowed1 ){
+			throw new BadRequestException( 'Not allowed from ExtraGuard1' );
+		}
+		return true;
+	}
+}
+@Injectable()
+export class ExtraGuard2 implements CanActivate {
+	public canActivate( context: ExecutionContext ): boolean {
+		return context.switchToHttp().getRequest().user.allowed2 ?? false;
+	}
+}
+
+@Controller( '/recommended/bound' )
+export class RecommendedBoundTestController {
+	@Get( 'method1' )
+	@AdminViaJwtPolicy
+		.usingGuard( [ ExtraGuard1, ExtraGuard2 ] ) // Add guards. When passed as an array, if either one can activate, it will continue
+	public method1(){
+		// ...
+	}
+
+	@Get( 'method2' )
+	@ViaJwtPolicy( { action: 'admin', subject: 'something' } )
+		.usingGuard( [ ExtraGuard1, ExtraGuard2 ] ) // Add guards. When passed as an array, if either one can activate, it will continue
+	public method2(){
+		// ...
+	}
+}
+
+

+

Now, both method1 and method2 will run if

+
    +
  • the user is authenticated through jwt strategy
  • +
  • it passes either ExtraGuard1 or ExtraGuard2
  • +
  • and he has admin role.
  • +
+
+

Note that you can use bindPolicyDecorators to bind both Policy and PoliciesMask

+
+ +

The tests

+
+

This is tested, of course. Just see by yourself.

+

From ./test/demo/use-with-guards/recommended-test.e2e-spec.ts#1~90

+
import { HttpStatus, INestApplication } from '@nestjs/common';
+import { JwtModule, JwtService } from '@nestjs/jwt';
+import { Test } from '@nestjs/testing';
+import request from 'supertest';
+
+import { CaslModule } from '@scitizen/nest-casl';
+
+import { AbilityFactory } from './ability-factory.service';
+import { JwtPassportStrategy } from './jwt-passport.strategy';
+import { ExtraGuard1, ExtraGuard2, RecommendedBoundTestController, RecommendedTestController } from './recommended.controller';
+
+describe( 'Use with guards (recommended)', () => {
+	let app: INestApplication;
+
+	describe( 'RecommendedTestController', () => {
+		beforeAll( async () => {
+			const moduleRef = await Test.createTestingModule( {
+				imports: [
+					CaslModule.withConfig( ( { abilityFactory: AbilityFactory } ) ),
+					JwtModule.register( { secret: JwtPassportStrategy.KEY } ),
+				],
+				providers: [ JwtPassportStrategy ],
+				controllers: [ RecommendedTestController ],
+			} ).compile();
+
+			app = moduleRef.createNestApplication();
+			await app.init();
+		} );
+
+		it( 'should send an UNAUTHORIZED error if no authorization set', () => request( app.getHttpServer() )
+			.get( '/recommended' )
+			.expect( HttpStatus.UNAUTHORIZED )
+			.expect( { statusCode: HttpStatus.UNAUTHORIZED, message: 'Unauthorized' } ) );
+		it( 'should send a FORBIDDEN error if invalid capabilities', () => request( app.getHttpServer() )
+			.get( '/recommended' )
+			.set( 'Authorization', `Bearer ${app.get( JwtService ).sign( { role: 'user' } )}` )
+			.expect( HttpStatus.FORBIDDEN )
+			.expect( { statusCode: HttpStatus.FORBIDDEN, message: 'Invalid authorizations: Can\'t "admin" on "something"', error: 'Forbidden' } ) );
+		it( 'should work', () => request( app.getHttpServer() )
+			.get( '/recommended' )
+			.set( 'Authorization', `Bearer ${app.get( JwtService ).sign( { role: 'admin' } )}` )
+			.expect( HttpStatus.OK ) );
+	} );
+	describe( 'RecommendedBoundTestController', () => {
+		beforeAll( async () => {
+			const moduleRef = await Test.createTestingModule( {
+				imports: [
+					CaslModule.withConfig( ( { abilityFactory: AbilityFactory } ) ),
+					JwtModule.register( { secret: JwtPassportStrategy.KEY } ),
+				],
+				providers: [ JwtPassportStrategy, ExtraGuard1, ExtraGuard2 ],
+				controllers: [ RecommendedBoundTestController ],
+			} ).compile();
+
+			app = moduleRef.createNestApplication();
+			await app.init();
+		} );
+
+		describe.each( [ 'method1', 'method2' ] )( 'On method %s', method => {
+			const endpoint = `/recommended/bound/${method}`;
+			it( 'should send an UNAUTHORIZED error if no authorization set', () => request( app.getHttpServer() )
+				.get( endpoint )
+				.expect( HttpStatus.UNAUTHORIZED )
+				.expect( { statusCode: HttpStatus.UNAUTHORIZED, message: 'Unauthorized' } ) );
+			it( 'should send a FORBIDDEN error if passing neither guard 1 nor 2, and throw error from guard 1', () => request( app.getHttpServer() )
+				.get( endpoint )
+				.set( 'Authorization', `Bearer ${app.get( JwtService ).sign( { role: 'user', allowed1: false, allowed2: false } )}` )
+				.expect( HttpStatus.BAD_REQUEST )
+				.expect( { statusCode: HttpStatus.BAD_REQUEST, message: 'Not allowed from ExtraGuard1', error: 'Bad Request' } ) );
+			it( 'should send a FORBIDDEN error if passing guard 1 invalid capabilities', () => request( app.getHttpServer() )
+				.get( endpoint )
+				.set( 'Authorization', `Bearer ${app.get( JwtService ).sign( { role: 'user', allowed1: true } )}` )
+				.expect( HttpStatus.FORBIDDEN )
+				.expect( { statusCode: HttpStatus.FORBIDDEN, message: 'Invalid authorizations: Can\'t "admin" on "something"', error: 'Forbidden' } ) );
+			it( 'should send a FORBIDDEN error if passing guard 2 invalid capabilities', () => request( app.getHttpServer() )
+				.get( endpoint )
+				.set( 'Authorization', `Bearer ${app.get( JwtService ).sign( { role: 'user', allowed2: true } )}` )
+				.expect( HttpStatus.FORBIDDEN )
+				.expect( { statusCode: HttpStatus.FORBIDDEN, message: 'Invalid authorizations: Can\'t "admin" on "something"', error: 'Forbidden' } ) );
+			it( 'should work via guard 1', () => request( app.getHttpServer() )
+				.get( endpoint )
+				.set( 'Authorization', `Bearer ${app.get( JwtService ).sign( { role: 'admin', allowed1: true } )}` )
+				.expect( HttpStatus.OK ) );
+			it( 'should work via guard 2', () => request( app.getHttpServer() )
+				.get( endpoint )
+				.set( 'Authorization', `Bearer ${app.get( JwtService ).sign( { role: 'admin', allowed2: true } )}` )
+				.expect( HttpStatus.OK ) );
+		} );
+	} );
+} );
+
+

+ +

What next ?

+
+

Better type constraints

+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Property
  • +
  • Method
  • +
+
    +
  • Constructor
  • +
+
    +
  • Static method
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + + \ No newline at end of file