diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 79d6276b..00000000 --- a/.eslintrc.js +++ /dev/null @@ -1,28 +0,0 @@ -module.exports = { - root: true, - env: { - browser: true, - node: true - }, - parserOptions: { - parser: "babel-eslint" - }, - extends: [ - "eslint:recommended", - "prettier", - // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention - // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules. - "plugin:vue/recommended" - // "plugin:prettier/recommended" - ], - // required to lint *.vue files - plugins: ["vue"], - // add your custom rules here - "vue/attributes-hyphenation": "never", - rules: { - semi: [2, "always"], - "no-console": "off", - "vue/max-attributes-per-line": "off", - "prettier/prettier": ["error", { semi: true }] - } -}; diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..b18fd293 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: 'github-actions' + directory: '/' + schedule: + interval: 'weekly' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..a321cd42 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,25 @@ +name: Test + +on: + push: + branches: [master] + pull_request: + branches: [master] + +permissions: + contents: read + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v6 + - uses: pnpm/action-setup@v5 + - name: Use Node.js + uses: actions/setup-node@v6 + with: + node-version: 22 + cache: 'pnpm' + - run: pnpm install --frozen-lockfile + - run: pnpm test diff --git a/.gitignore b/.gitignore index 31b0ec82..4a794b93 100644 --- a/.gitignore +++ b/.gitignore @@ -68,11 +68,12 @@ typings/ # nuxt.js build output .nuxt -# Nuxt generate +# Build output dist -# vuepress build output -.vuepress/dist +# vitepress build output +dist +.vitepress/cache # Serverless directories .serverless diff --git a/.nvmrc b/.nvmrc index 832d3850..8e350348 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -16.14.0 +24.14.1 diff --git a/.oxfmtrc.json b/.oxfmtrc.json new file mode 100644 index 00000000..b945198b --- /dev/null +++ b/.oxfmtrc.json @@ -0,0 +1,25 @@ +{ + "$schema": "./node_modules/oxfmt/configuration_schema.json", + "singleQuote": true, + "printWidth": 120, + "sortPackageJson": false, + "sortImports": { + "groups": [ + "builtin", + "external", + ["internal", "parent", "sibling", "index"], + "type-builtin", + "type-external", + ["type-internal", "type-parent", "type-sibling", "type-index"] + ] + }, + "ignorePatterns": [], + "overrides": [ + { + "files": ["generated/**"], + "options": { + "printWidth": 80 + } + } + ] +} diff --git a/.oxlintrc.json b/.oxlintrc.json new file mode 100644 index 00000000..698338e8 --- /dev/null +++ b/.oxlintrc.json @@ -0,0 +1,38 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": ["typescript", "unicorn", "vue"], + "env": { + "node": true, + "browser": true + }, + "categories": { + "correctness": "error", + "perf": "error", + "suspicious": "error", + "pedantic": "warn", + "style": "warn", + "nursery": "warn" + }, + "globals": { + "defineProps": "readonly", + "defineModel": "readonly" + }, + "rules": { + "id-length": "off", + "init-declarations": "off", + "max-depth": "off", + "max-lines-per-function": "off", + "max-params": "off", + "max-statements": "off", + "no-await-in-loop": "off", + "no-duplicate-imports": ["error", { "allowSeparateTypeImports": true }], + "no-magic-numbers": "off", + "no-ternary": "off", + "prefer-global-this": "off", + "sort-imports": "off", + "typescript/consistent-type-imports": ["error", { "prefer": "type-imports", "fixStyle": "separate-type-imports" }], + "unicorn/filename-case": "off", + "unicorn/no-null": "off", + "unicorn/prefer-node-protocol": "error" + } +} diff --git a/.vitepress/config.ts b/.vitepress/config.ts new file mode 100644 index 00000000..04439154 --- /dev/null +++ b/.vitepress/config.ts @@ -0,0 +1,206 @@ +import { defineConfig } from 'vitepress'; +import { groupIconMdPlugin, groupIconVitePlugin } from 'vitepress-plugin-group-icons'; + +import modulesData from '../generated/metadata/modules.json' with { type: 'json' }; +import hapiInfo from '../generated/modules/hapi/info.json' with { type: 'json' }; +import pluginsData from '../src/plugins.json' with { type: 'json' }; +import { formatVersion } from './utils.js'; + +const modulesItems = Object.keys(modulesData) + .filter((name) => name !== 'hapi') + .map((name) => ({ + link: `/module/${name}/api/${modulesData[name as keyof typeof modulesData].latestVersion}`, + text: name, + })); + +const getModuleSidebar = (moduleName: string) => { + const moduleData = modulesData[moduleName as keyof typeof modulesData]; + + const items: { link: string; text: string; items?: { link: string; text: string }[] }[] = [ + { + items: [...moduleData.versions].toReversed().map((version) => ({ + link: `/module/${moduleName}/api/${formatVersion(version.name)}`, + text: formatVersion(version.name), + })), + link: `/module/${moduleName}/api/${moduleData.latestVersion}`, + text: 'API', + }, + { link: `/module/${moduleName}/changelog`, text: 'Changelog' }, + ]; + + if (moduleName === 'bell') { + items.push({ link: '/module/bell/examples', text: 'Examples' }); + items.push({ link: '/module/bell/providers', text: 'Providers' }); + } + + return [ + { + items, + text: moduleName, + }, + { + collapsed: true, + items: [{ link: '/module/', text: 'All Modules' }, ...modulesItems], + text: 'Other Modules', + }, + ]; +}; + +const moduleSidebars = Object.fromEntries( + Object.keys(modulesData) + .filter((name) => name !== 'hapi') + .map((name) => [`/module/${name}/`, getModuleSidebar(name)]), +); + +const tutorialItems = [ + { slug: 'getting-started', text: 'Getting Started' }, + { slug: 'auth', text: 'Authentication' }, + { slug: 'caching', text: 'Caching' }, + { slug: 'cookies', text: 'Cookies' }, + { slug: 'logging', text: 'Logging' }, + { slug: 'plugins', text: 'Plugins' }, + { slug: 'routing', text: 'Routing' }, + { slug: 'server-methods', text: 'Server Methods' }, + { slug: 'serving-files', text: 'Serving Files' }, + { slug: 'testing', text: 'Testing' }, + { slug: 'validation', text: 'Validation' }, + { slug: 'views', text: 'Views' }, + { slug: 'community', text: 'Community' }, + { slug: 'express-to-hapi', text: 'Express to hapi' }, +]; + +const getTutorialSidebar = (locale: string) => [ + { + items: tutorialItems.map((t) => ({ + link: `/tutorials/${locale}/${t.slug}`, + text: t.text, + })), + text: 'Tutorials', + }, +]; + +export default defineConfig({ + appearance: true, + cleanUrls: true, + description: 'The Simple, Secure Framework Developers Trust', + head: [['link', { href: '/favicon.png', rel: 'icon', type: 'image/png' }]], + ignoreDeadLinks: true, + markdown: { + config(md) { + md.use(groupIconMdPlugin); + }, + lineNumbers: true, + theme: { + dark: 'vitesse-dark', + light: 'vitesse-light', + }, + }, + outDir: 'dist', + srcDir: 'docs', + themeConfig: { + docFooter: { + next: false, + prev: false, + }, + footer: { + copyright: 'Copyright © 2012-present hapi.js team', + message: + 'Deploys by Netlify', + }, + logo: '/img/hapi.svg', + nav: [ + { link: '/', text: 'Home' }, + { activeMatch: '^/api/', link: `/api/${formatVersion(hapiInfo.versions.at(-1)!.name)}`, text: 'API' }, + { activeMatch: '^/tutorials/', link: '/tutorials/en_US/getting-started', text: 'Tutorials' }, + { activeMatch: '^/plugins', link: '/plugins', text: 'Plugins' }, + { + activeMatch: '^/resources/', + link: '/resources/changelog', + text: 'Resources', + }, + { activeMatch: '^/module/', link: '/module/', text: 'Modules' }, + { activeMatch: '^/policies/', link: '/policies/coc', text: 'Policies' }, + { link: '/support', text: 'Support' }, + { link: 'https://hapi.threadless.com', target: '_blank', text: 'Shop' }, + ], + outline: { + label: 'On this page', + level: 'deep', + }, + sidebar: { + '/api/': [ + { + items: [ + { + items: [...hapiInfo.versions].toReversed().map((version) => ({ + link: `/api/${formatVersion(version.name)}`, + text: formatVersion(version.name), + })), + link: `/api/${formatVersion(hapiInfo.versions.at(-1)!.name)}`, + text: 'API', + }, + ], + text: '@hapi/hapi', + }, + ], + '/module/': [ + { + items: [{ link: '/module/', text: 'All Modules' }, ...modulesItems], + text: 'Modules', + }, + ], + '/plugins': [ + { + items: pluginsData.map((category) => ({ + link: `/plugins#${category.anchor}`, + text: category.name, + })), + text: 'Plugins', + }, + ], + '/policies/': [ + { + items: [ + { link: '/policies/coc', text: 'Code of Conduct' }, + { link: '/policies/contributing', text: 'Contributing' }, + { link: '/policies/license', text: 'License' }, + { link: '/policies/security', text: 'Security' }, + { link: '/policies/sponsors', text: 'Sponsors' }, + { link: '/policies/styleguide', text: 'Style Guide' }, + { link: '/policies/support', text: 'Support' }, + ], + text: 'Policies', + }, + ], + '/resources/': [ + { + items: [ + { link: '/resources/changelog', text: 'Changelog' }, + { link: '/resources/status', text: 'Module Status' }, + { link: '/resources/list#books', text: 'Books' }, + { link: '/resources/list#boilerplates', text: 'Boilerplates' }, + { link: '/resources/list#projects', text: 'Projects' }, + { link: '/resources/list#videos', text: 'Videos' }, + ], + text: 'Resources', + }, + ], + '/tutorials/en_US/': getTutorialSidebar('en_US'), + '/tutorials/ko_KR/': getTutorialSidebar('ko_KR'), + '/tutorials/pt_BR/': getTutorialSidebar('pt_BR'), + '/tutorials/tr_TR/': getTutorialSidebar('tr_TR'), + '/tutorials/zh_CN/': getTutorialSidebar('zh_CN'), + ...moduleSidebars, + }, + socialLinks: [ + { icon: 'github', link: 'https://github.com/hapijs/hapi' }, + { icon: 'slack', link: 'https://join.slack.com/t/hapihour/shared_invite/zt-g5ortpsk-ErlnRA2rUcPIWES21oXBOg' }, + { icon: 'discord', link: 'https://discord.gg/YYxZhpKKvu' }, + ], + }, + title: 'hapi.dev', + titleTemplate: 'hapi.dev - :title', + vite: { + plugins: [groupIconVitePlugin()], + }, +}); diff --git a/.vitepress/theme/fonts/IBMPlexMono-Regular.ttf b/.vitepress/theme/fonts/IBMPlexMono-Regular.ttf new file mode 100644 index 00000000..601ae945 Binary files /dev/null and b/.vitepress/theme/fonts/IBMPlexMono-Regular.ttf differ diff --git a/.vitepress/theme/fonts/IBMPlexMono-SemiBold.ttf b/.vitepress/theme/fonts/IBMPlexMono-SemiBold.ttf new file mode 100644 index 00000000..5e0b41df Binary files /dev/null and b/.vitepress/theme/fonts/IBMPlexMono-SemiBold.ttf differ diff --git a/.vitepress/theme/fonts/IBMPlexSans-Bold.ttf b/.vitepress/theme/fonts/IBMPlexSans-Bold.ttf new file mode 100644 index 00000000..258c10a9 Binary files /dev/null and b/.vitepress/theme/fonts/IBMPlexSans-Bold.ttf differ diff --git a/.vitepress/theme/fonts/IBMPlexSans-BoldItalic.ttf b/.vitepress/theme/fonts/IBMPlexSans-BoldItalic.ttf new file mode 100644 index 00000000..fabdca04 Binary files /dev/null and b/.vitepress/theme/fonts/IBMPlexSans-BoldItalic.ttf differ diff --git a/.vitepress/theme/fonts/IBMPlexSans-Italic.ttf b/.vitepress/theme/fonts/IBMPlexSans-Italic.ttf new file mode 100644 index 00000000..bf439563 Binary files /dev/null and b/.vitepress/theme/fonts/IBMPlexSans-Italic.ttf differ diff --git a/.vitepress/theme/fonts/IBMPlexSans-Medium.ttf b/.vitepress/theme/fonts/IBMPlexSans-Medium.ttf new file mode 100644 index 00000000..fb75072d Binary files /dev/null and b/.vitepress/theme/fonts/IBMPlexSans-Medium.ttf differ diff --git a/.vitepress/theme/fonts/IBMPlexSans-MediumItalic.ttf b/.vitepress/theme/fonts/IBMPlexSans-MediumItalic.ttf new file mode 100644 index 00000000..1b059beb Binary files /dev/null and b/.vitepress/theme/fonts/IBMPlexSans-MediumItalic.ttf differ diff --git a/.vitepress/theme/fonts/IBMPlexSans-Regular.ttf b/.vitepress/theme/fonts/IBMPlexSans-Regular.ttf new file mode 100644 index 00000000..5387ad48 Binary files /dev/null and b/.vitepress/theme/fonts/IBMPlexSans-Regular.ttf differ diff --git a/.vitepress/theme/fonts/IBMPlexSans-SemiBold.ttf b/.vitepress/theme/fonts/IBMPlexSans-SemiBold.ttf new file mode 100644 index 00000000..a63f1c56 Binary files /dev/null and b/.vitepress/theme/fonts/IBMPlexSans-SemiBold.ttf differ diff --git a/.vitepress/theme/fonts/IBMPlexSans-SemiBoldItalic.ttf b/.vitepress/theme/fonts/IBMPlexSans-SemiBoldItalic.ttf new file mode 100644 index 00000000..981d5142 Binary files /dev/null and b/.vitepress/theme/fonts/IBMPlexSans-SemiBoldItalic.ttf differ diff --git a/.vitepress/theme/index.ts b/.vitepress/theme/index.ts new file mode 100644 index 00000000..55578287 --- /dev/null +++ b/.vitepress/theme/index.ts @@ -0,0 +1,49 @@ +import DefaultTheme from 'vitepress/theme'; +import { defineAsyncComponent, h } from 'vue'; + +import './variables.css'; +import './main.css'; +import 'virtual:group-icons.css'; +import { getRedirectPath } from './redirect.js'; + +import type { Theme } from 'vitepress'; + +const ApiOutline = defineAsyncComponent(() => import('../../components/ApiOutline.vue')); +const CarbonAds = defineAsyncComponent(() => import('../../components/CarbonAds.vue')); +const HomeContent = defineAsyncComponent(() => import('../../components/HomeContent.vue')); +const ModuleIndex = defineAsyncComponent(() => import('../../components/ModuleIndex.vue')); +const PluginsDirectory = defineAsyncComponent(() => import('../../components/PluginsDirectory.vue')); +const StatusContent = defineAsyncComponent(() => import('../../components/StatusContent.vue')); +const TutorialLang = defineAsyncComponent(() => import('../../components/TutorialLang.vue')); + +export default { + Layout() { + return h(DefaultTheme.Layout, null, { + 'sidebar-nav-after': () => h(CarbonAds), + }); + }, + enhanceApp({ app, router }) { + app.component('ApiOutline', ApiOutline); + app.component('HomeContent', HomeContent); + app.component('ModuleIndex', ModuleIndex); + app.component('PluginsDirectory', PluginsDirectory); + app.component('StatusContent', StatusContent); + app.component('TutorialLang', TutorialLang); + + if (typeof window !== 'undefined') { + router.onBeforeRouteChange = (to) => { + const target = getRedirectPath(to); + if (target) { + router.go(target); + return false; + } + }; + + const initialTarget = getRedirectPath(window.location.pathname); + if (initialTarget) { + router.go(initialTarget); + } + } + }, + extends: DefaultTheme, +} satisfies Theme; diff --git a/.vitepress/theme/main.css b/.vitepress/theme/main.css new file mode 100644 index 00000000..eec770c6 --- /dev/null +++ b/.vitepress/theme/main.css @@ -0,0 +1,423 @@ +/* ---------- Fonts ---------- */ +@font-face { + font-family: 'IBM Plex Sans'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url('./fonts/IBMPlexSans-Regular.ttf') format('truetype'); +} +@font-face { + font-family: 'IBM Plex Sans'; + font-style: italic; + font-weight: 400; + font-display: swap; + src: url('./fonts/IBMPlexSans-Italic.ttf') format('truetype'); +} +@font-face { + font-family: 'IBM Plex Sans'; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url('./fonts/IBMPlexSans-Medium.ttf') format('truetype'); +} +@font-face { + font-family: 'IBM Plex Sans'; + font-style: italic; + font-weight: 500; + font-display: swap; + src: url('./fonts/IBMPlexSans-MediumItalic.ttf') format('truetype'); +} +@font-face { + font-family: 'IBM Plex Sans'; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url('./fonts/IBMPlexSans-SemiBold.ttf') format('truetype'); +} +@font-face { + font-family: 'IBM Plex Sans'; + font-style: italic; + font-weight: 600; + font-display: swap; + src: url('./fonts/IBMPlexSans-SemiBoldItalic.ttf') format('truetype'); +} +@font-face { + font-family: 'IBM Plex Sans'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url('./fonts/IBMPlexSans-Bold.ttf') format('truetype'); +} +@font-face { + font-family: 'IBM Plex Sans'; + font-style: italic; + font-weight: 700; + font-display: swap; + src: url('./fonts/IBMPlexSans-BoldItalic.ttf') format('truetype'); +} +@font-face { + font-family: 'IBM Plex Mono'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url('./fonts/IBMPlexMono-Regular.ttf') format('truetype'); +} +@font-face { + font-family: 'IBM Plex Mono'; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url('./fonts/IBMPlexMono-SemiBold.ttf') format('truetype'); +} + +:root { + --vp-font-family-base: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + --vp-font-family-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; +} + +/* ---------- Shared card ---------- */ +.card { + position: relative; + border: 1px solid var(--vp-c-divider); + border-radius: 14px; + padding: 22px 20px; + background: var(--vp-c-bg-soft); + box-shadow: var(--shadow-card); + transition: + transform 0.2s ease, + border-color 0.2s ease, + box-shadow 0.2s ease; + overflow: hidden; +} + +.card::after { + content: ''; + position: absolute; + inset: 0; + background: radial-gradient(circle at 50% 50%, var(--vp-c-brand-soft), transparent 70%); + opacity: 0; + transition: opacity 0.3s ease; + pointer-events: none; +} + +.card:hover::after { + opacity: 1; +} + +.card > * { + position: relative; + z-index: 1; +} + +.card:hover { + transform: translateY(-2px); + border-color: var(--vp-c-brand-1); + box-shadow: var(--shadow-card-hover); +} + +/* ---------- Shared form controls ---------- */ +.form-control { + padding: 12px 16px; + border: 1px solid var(--vp-c-divider); + border-radius: 10px; + background: var(--vp-c-bg-soft); + font-family: var(--vp-font-family-base); + font-size: 0.95em; + color: var(--vp-c-text-1); + transition: + border-color 0.15s ease, + box-shadow 0.15s ease; +} + +.form-control:focus { + outline: none; + border-color: var(--vp-c-brand-1); + box-shadow: 0 0 0 3px var(--vp-c-brand-soft); +} + +/* Selects: appearance:none + custom chevron fixes native popup mispositioning + on Chromium when selects carry custom padding/font. */ +select.form-control { + appearance: none; + -webkit-appearance: none; + padding-right: 40px; + background-image: url("data:image/svg+xml;utf8,"); + background-repeat: no-repeat; + background-position: right 14px center; + cursor: pointer; +} + +/* ---------- Shared buttons ---------- + * Two styles used site-wide: .btn.btn-primary (gradient) and .btn.btn-ghost. + */ +.btn { + display: inline-block; + border-radius: 10px; + padding: 12px 24px; + font-size: 0.95em; + font-weight: 700; + text-decoration: none; + border: 2px solid transparent; + cursor: pointer; + transition: + transform 0.15s ease, + box-shadow 0.2s ease, + border-color 0.2s ease, + color 0.2s ease; +} + +.btn-primary { + background: linear-gradient(135deg, var(--vp-c-brand-1), var(--vp-c-brand-2)); + color: #fff; + box-shadow: 0 8px 24px var(--vp-c-brand-soft); +} + +.btn-primary:hover { + transform: translateY(-2px); + box-shadow: 0 12px 28px var(--vp-c-brand-soft); + color: #fff; +} + +.btn-ghost { + background: var(--vp-c-bg-soft); + border-color: var(--vp-c-divider); + color: var(--vp-c-text-1); +} + +.btn-ghost:hover { + border-color: var(--vp-c-brand-1); + color: var(--vp-c-brand-1); +} + +/* ---------- Doc typography ---------- + * Minimal overrides on top of vitepress defaults: + * - more breathing room on p / li / headings + * - inline recolored via CSS vars (neutral by default, brand in links) + * - links un-underlined + * - h4-h6 uppercased + */ +:root { + --vp-code-color: var(--vp-c-text-1); + --vp-code-bg: var(--vp-c-bg-soft); + --vp-code-link-color: var(--vp-c-brand-1); +} + +.vp-doc p { + line-height: 1.75; + margin: 20px 0; +} +.vp-doc ul, +.vp-doc ol { + margin: 20px 0; +} +.vp-doc li + li, +.vp-doc li > ol, +.vp-doc li > ul { + margin-top: 16px; +} +.vp-doc h2 { + margin-top: 64px; +} +.vp-doc h3 { + margin-top: 40px; +} +.vp-doc h4, +.vp-doc h5, +.vp-doc h6 { + margin-top: 32px; + text-transform: uppercase; + letter-spacing: 0.06em; +} +.vp-doc h4 { + font-size: 15px; +} +.vp-doc h5 { + font-size: 13px; +} +.vp-doc h6 { + font-size: 12px; + color: var(--vp-c-text-2); +} + +.vp-doc a { + text-decoration: none; +} +.vp-doc a:hover { + text-decoration: underline; +} +.vp-doc :not(pre) > code { + border: 1px solid color-mix(in srgb, var(--vp-code-color) 7%, transparent); +} +.vp-doc a > code { + background: var(--vp-c-brand-soft); + border-color: color-mix(in srgb, var(--vp-code-link-color) 7%, transparent); +} + +.vp-doc pre { + max-width: 100%; + overflow-x: auto; +} + +/* ---------- Doc tables ---------- + * Rounded card aesthetic applied globally so markdown tables look polished + * without per-component overrides. + */ +.vp-doc table { + display: table; + width: 100%; + max-width: 100%; + border-collapse: separate; + border-spacing: 0; + margin: 20px 0; + border: 1px solid var(--vp-c-divider); + border-radius: 12px; + overflow: hidden; + background: var(--vp-c-bg); +} +.vp-doc thead { + background: var(--vp-c-bg-soft); +} +.vp-doc th { + padding: 10px 14px; + text-align: left; + font-size: 0.72em; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.08em; + color: var(--vp-c-text-2); + border: none; + border-bottom: 1px solid var(--vp-c-divider); + background: var(--vp-c-bg-soft); +} +.vp-doc tr { + background: transparent; + border: none; +} +.vp-doc tr:nth-child(2n) { + background: transparent; +} +.vp-doc td { + padding: 10px 14px; + border: none; + border-bottom: 1px solid var(--vp-c-divider); + font-size: 0.95em; +} +.vp-doc tbody tr:last-child td { + border-bottom: none; +} + +.VPSidebar > .nav { + display: flex; + flex-direction: column; + min-height: calc(100vh - var(--vp-nav-height) - 128px); +} + +.breaking-badge { + display: inline-flex; + align-items: center; + padding: 0 6px; + font-size: 11px; + font-weight: 600; + height: 18px; + line-height: 18px; + border-radius: 4px; + background-color: var(--vp-c-brand-1); + color: var(--vp-c-white); + text-transform: uppercase; + vertical-align: middle; + margin-left: 8px; + box-sizing: border-box; +} + +.breaking-badge::after { + content: 'breaking changes'; +} + +.release-notes-link { + display: inline-flex; + align-items: center; + padding: 0 6px; + font-size: 11px; + font-weight: 600; + height: 18px; + line-height: 18px; + border-radius: 4px; + background-color: var(--release-notes-bg); + color: var(--vp-c-black) !important; + text-transform: uppercase; + vertical-align: middle; + margin-left: 8px; + text-decoration: none !important; + box-sizing: border-box; +} + +.release-notes-link::after { + content: 'release notes'; + margin-left: 10px; +} + +.release-notes-link span { + margin-left: 10px; +} + +.release-notes-link:hover { + opacity: 0.8; +} + +.release-notes-img { + width: 12px; + height: 12px; +} + +.atom-link { + display: inline-flex; + align-items: center; + vertical-align: middle; + color: var(--vp-c-text-2); + transition: color 0.2s; + text-decoration: none !important; + margin-left: 12px; +} + +.atom-link:hover { + color: var(--vp-c-orange) !important; +} + +.atom-icon { + width: 24px; + height: 24px; + fill: currentColor; +} + +.sponsors-page ul { + columns: 3; + list-style: none; + padding-left: 0; +} + +.sponsors-page ul li { + border-left: 3px solid var(--vp-c-brand-1); + padding-left: 15px; + margin-bottom: 8px; + break-inside: avoid; +} + +@media screen and (max-width: 900px) { + .sponsors-page ul { + columns: 2; + } +} + +@media screen and (max-width: 500px) { + .sponsors-page ul { + columns: 1; + } +} + +.vp-doc img.resources-book { + float: right; + height: 160px; + max-width: none; + border: 1px solid var(--vp-c-divider); + margin: 0 0 0 20px; +} diff --git a/.vitepress/theme/redirect.ts b/.vitepress/theme/redirect.ts new file mode 100644 index 00000000..1d7c2d03 --- /dev/null +++ b/.vitepress/theme/redirect.ts @@ -0,0 +1,117 @@ +import Semver from 'semver'; + +import modulesData from '../../generated/metadata/modules.json' with { type: 'json' }; +import hapiInfo from '../../generated/modules/hapi/info.json' with { type: 'json' }; +import { formatVersion } from '../utils.js'; + +const tutorialRenames: Record = { + expresstohapi: 'express-to-hapi', + gettingstarted: 'getting-started', + servermethods: 'server-methods', + servingfiles: 'serving-files', +}; + +export const getRedirectPath = (toPath: string) => { + const [urlPath, hash] = toPath.split('#'); + const path = urlPath.replace(/\/$/, '').replace(/\.html$/, '') || '/'; + const suffix = hash ? `#${hash}` : ''; + + // Handle /api with optional version + const apiMatch = path.match(/^\/api(?:\/([^/]+))?$/); + if (apiMatch) { + return resolveHapiVersion(apiMatch.at(1), 'api', suffix); + } + + // Handle /family/{name} -> /module/{name}/api/{version} + const familyMatch = path.match(/^\/family\/([^/]+)(?:\/(.*))?$/); + if (familyMatch) { + const [, name, rest] = familyMatch; + if (rest === 'api') { + return `/module/${name}/api${suffix}`; + } + if (rest) { + return `/module/${name}/${rest}${suffix}`; + } + return resolveModuleLatest(name, suffix); + } + + // Handle /module/{name} without subpath -> /module/{name}/api/{version} + const moduleMatch = path.match(/^\/module\/([^/]+)$/); + if (moduleMatch) { + return resolveModuleLatest(moduleMatch[1], suffix); + } + + // Handle /module/{name}/install -> /module/{name}/api/{version} + const installMatch = path.match(/^\/module\/([^/]+)\/install$/); + if (installMatch) { + return resolveModuleLatest(installMatch[1], suffix); + } + + // Handle old tutorial URLs -> new /tutorials/{locale}/{slug} format + const tutorialMatch = path.match(/^\/tutorials\/([^/]+)$/); + if (tutorialMatch) { + const oldName = tutorialMatch.at(1)!; + // If it's a locale code, skip (it's a directory) + if (['en_US', 'ko_KR', 'pt_BR', 'tr_TR', 'zh_CN'].includes(oldName)) { + return null; + } + const newName = tutorialRenames[oldName] ?? oldName; + return `/tutorials/en_US/${newName}${suffix}`; + } + + // Handle /resources -> /resources/changelog + if (path === '/resources') { + return `/resources/changelog${suffix}`; + } + + // Handle /policies -> /policies/coc + if (path === '/policies') { + return `/policies/coc${suffix}`; + } + + return null; +}; + +const resolveModuleLatest = (name: string, suffix: string) => { + const mod = modulesData[name as keyof typeof modulesData]; + if (!mod) { + return null; + } + return `/module/${name}/api/${mod.latestVersion}${suffix}`; +}; + +const resolveHapiVersion = (version: string | undefined, type: string, suffix: string) => { + const [latestVersion] = hapiInfo.versionsArray; + const latestMasked = formatVersion(latestVersion); + + if (!version) { + return `/${type}/${latestMasked}${suffix}`; + } + + const maskedVersions = hapiInfo.versionsArray.map(formatVersion); + if (maskedVersions.includes(version)) { + return null; + } + + let targetVersion = latestVersion; + try { + const coerced = Semver.coerce(version); + if (coerced) { + const major = Semver.major(coerced); + const sameMajor = hapiInfo.versionsArray.find((v) => Semver.major(v) === major); + if (sameMajor) { + targetVersion = sameMajor; + } + } + } catch { + // Keep targetVersion as latest if coercion fails + } + + const finalTarget = formatVersion(targetVersion); + + if (finalTarget === version) { + return null; + } + + return `/${type}/${finalTarget}${suffix}`; +}; diff --git a/.vitepress/theme/variables.css b/.vitepress/theme/variables.css new file mode 100644 index 00000000..6a54a153 --- /dev/null +++ b/.vitepress/theme/variables.css @@ -0,0 +1,18 @@ +:root { + /* Brand Colors - hapi orange */ + --vp-c-brand-1: #ed7d31; + --vp-c-brand-2: #d06a20; + --vp-c-brand-3: #b85a15; + --vp-c-brand-soft: rgba(237, 125, 49, 0.14); + + /* Release Notes Badge */ + --release-notes-bg: #fad8c7; + + /* Shadows */ + --shadow-card: 0 6px 20px rgba(0, 0, 0, 0.04); + --shadow-card-hover: 0 14px 30px rgba(0, 0, 0, 0.08); + --shadow-elevated: 0 8px 24px rgba(0, 0, 0, 0.06); + + /* Atom Icon */ + --vp-c-orange: #f26522; +} diff --git a/.vitepress/utils.ts b/.vitepress/utils.ts new file mode 100644 index 00000000..0c481df7 --- /dev/null +++ b/.vitepress/utils.ts @@ -0,0 +1,4 @@ +export const formatVersion = (version: string) => { + const [major] = version.split('.'); + return `${major}.x.x`; +}; diff --git a/DEPLOY.md b/DEPLOY.md deleted file mode 100644 index 96e6880f..00000000 --- a/DEPLOY.md +++ /dev/null @@ -1,47 +0,0 @@ - - -# @hapi/hapi.dev deployment process - -This documentation is aimed for maintainers of the website to deploy a new version. The site is hosted on [Netlify](https://www.netlify.com/). - -## Testing the release - -Prior to deploying the new website version it is best to test it on your local machine. You need to: - -1. Make the changes you need to the codebase. -2. Run `npm run generate` which will build the static dist folder. -3. Run `npm run static` to view the website with the static dist folder you generated on the previous step. - -At this point if everything looks good and you don't notice any regression, you can proceed to the next step. - -## Deploying - -You need to go to [Netlify's login page](https://app.netlify.com/). Once logged in make sure you are on the hapi team account and not your personal one: -
hapi team account switch
- -Pick the **hapi.dev** from the list of sites available either from the dashboard or the "sites" tab: -
hapi site select
- -Activate the automatic builds for that site: -
enable hapi.dev automatic build button
- -We don't keep the automatic build enabled so we don't build the website on every commit push to the repo. This is intended to decrease the build minutes consumption on our account otherwise 💸. - -Trigger a deployment: -
trigger hapi.dev deployment link
- -After the deployment process is done, you can preview the result to make sure everything's working fine from the deployment details page: -
hapi.dev deployment preview button
- -If the deployment is ready to be published you can just click the "publish deploy" button: -
hapi.dev publish deploy button
- -The new version of the website is now live. Congrats! 🎉🎊 - -Just one more step and you're good to go, we need to disable the automatic builds once we're done publishing. For that you need to go the "site settings" page either from the top tab or the dashboard: -
hapi.dev site settings section for automatic builds
- -Just click that "Stop builds" radio button and hit save: -
hapi.dev site setting to disable automatic builds
- -Good job! diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index e8f6be11..00000000 --- a/Dockerfile +++ /dev/null @@ -1,16 +0,0 @@ -FROM node:16.14.0-alpine - -# Add curl for readiness check and git for version information. -RUN apk --no-cache add curl git - -RUN mkdir -p /usr/src/app -WORKDIR /usr/src/app -COPY ./server /usr/src/app/server -COPY ./dist /usr/src/app/dist -RUN npm install @hapi/hapi @hapi/inert --no-save - -ENV NODE_ENV production -ENV HOST 0.0.0.0 -ENV PORT 3000 - -CMD [ "node", "server/static.js" ] diff --git a/README.md b/README.md index f799932c..a9529278 100644 --- a/README.md +++ b/README.md @@ -4,44 +4,99 @@ The home of the [hapi.dev](http://hapi.dev) developer portal. -## Running/developing +Built with [VitePress](https://vitepress.dev), Vue 3, and TypeScript. -* First, clone or download the repo and run ```npm install```. +## Prerequisites -* Next, you need to make an .env file in the root directory. +- [Node.js](https://nodejs.org/) v22+ +- [pnpm](https://pnpm.io/) -* Obtain a token from GitHub [here](https://github.com/settings/tokens/new) and select checked scopes only (only two) +## Setup - - [ ] **repo** : *Full control of private repositories* - - [x] **repo status** : *Access commit status* - - [ ] **repo_deployment** : *Access deployment status* - - [x] **public_repo** : *Access public repositories* - - [ ] **repo:invite** : *Access repository invitations* +Clone the repo and install dependencies: -* Copy your GitHub token and place it in your .env file by entering: -```GITHUB_TOKEN = "YOUR TOKEN"``` +```bash +pnpm install +``` -* Run ```npm run dev``` and go to ```http://localhost:3000``` to view the site. The dev server hot loads, which will automatically show your changes without having to restart the server. -* Run ```npm run static``` and go to ```http://localhost:3000``` to view the site with the actual resulting /dist folder. +Create a `.env` file in the root directory with a GitHub token: -* After you make your changes, simply open a pull request. +``` +GITHUB_TOKEN="YOUR_TOKEN" +``` -## Add a translation for the tutorials -In the directory `static/lib/tutorials` we have some directories with the name of the languages translated, to add a new translation, simply add a new folder in the `static/lib/tutorials` with your translation. -An Example, if you translate the tutorials, to Brazilian Portuguese, you must use the `pt_BR` as the name of the directory. -Inside the directory `pt_BR`, you need to follow the same struture we use in `en_US`, with all tutorials separated in markdown files and an `index.js` file that's export the tutorials and the titles. -After finish the translations, you also need add your translation in the `index.js` file inside `static/lib/tutorials`. +You can obtain a token from [GitHub Settings](https://github.com/settings/tokens/new). The token needs these scopes: + +- [x] **repo:status** — Access commit status +- [x] **public_repo** — Access public repositories + +## Development + +Fetch module data from GitHub and npm: + +```bash +pnpm fetch-data +``` + +Start the dev server: + +```bash +pnpm dev +``` + +The site will be available at `http://localhost:5173` with hot reload. + +## Building + +Build the full site (fetch data + static generation): + +```bash +pnpm generate +``` + +Preview the built site: + +```bash +pnpm preview +``` + +## Project structure + +``` +cli/ # TypeScript CLI for fetching module data from GitHub/npm +components/ # Vue 3 components +docs/ # VitePress markdown pages and static assets + ├── api/ # hapi core API docs (dynamic routes) + ├── module/ # Module pages (install, API, changelog) + ├── tutorials/ # Tutorials in 5 languages (en_US, ko_KR, pt_BR, tr_TR, zh_CN) + ├── policies/ # Policy pages + ├── resources/ # Resources (changelog, status, books, etc.) + └── public/ # Static assets (images, plugins.json) +generated/ # Auto-generated data (from pnpm fetch-data) + ├── metadata/ # modules.json central registry + ├── modules/ # Per-module info and changelog JSON + └── markdown/ # Raw API docs, changelogs, policies +.vitepress/ # VitePress config and theme +``` + +## Tutorials + +Tutorials live in `docs/tutorials/{locale}/` with one markdown file per tutorial. Available locales: `en_US`, `ko_KR`, `pt_BR`, `tr_TR`, `zh_CN`. + +To add a new translation, create a directory under `docs/tutorials/` with the locale code (e.g. `fr_FR`) and add markdown files matching the English tutorial filenames. ## Plugins -hapijs.com maintains a list of community-created plugins [here](http://hapi.dev/plugins). If there are any plugins you have created or one you use often that isn't listed please send a [pull request](https://github.com/hapijs/hapi.dev/blob/master/static/lib/plugins.json). Please note the existing categories, but if your plugin does not fit one feel free to create your own. Please keep the plugins in alphabetical order to be fair to all contributors. -## Building the docker image - - npm install (installs dependencies in order to run the generate) - - npm run generate (builds the static dist folder) - - npm run docker-build (creates hapi.dev image with just static content) +hapi.dev maintains a list of community-created plugins at [hapi.dev/plugins](http://hapi.dev/plugins). The plugin data lives in `docs/public/lib/plugins.json`. To add a plugin, send a [pull request](https://github.com/hapijs/hapi.dev/blob/master/docs/public/lib/plugins.json) with your addition. Please keep plugins in alphabetical order within their category. + +## Linting and formatting -This builds a static docker image without any secrets. It relies on the dist folder being created from the npm run generate step. +```bash +pnpm lint # Run oxlint +pnpm fmt # Check formatting with oxfmt +pnpm test # Run lint + fmt + TypeScript check +``` -## Deployment process +## Deployment -See [DEPLOY.md](DEPLOY.md) +The site is deployed to [Netlify](https://www.netlify.com). See `netlify.toml` for the build configuration. The build command is `pnpm generate` which fetches data and builds the static site to `dist/`. diff --git a/app/router.scrollBehavior.js b/app/router.scrollBehavior.js deleted file mode 100644 index 406baadf..00000000 --- a/app/router.scrollBehavior.js +++ /dev/null @@ -1,16 +0,0 @@ -export default function(to, from, savedPosition) { - if (savedPosition) { - return savedPosition; - } else { - let position = {}; - if (to.matched.length < 2) { - position = { x: 0, y: 0 }; - } else if (to.matched.some(r => r.components.default.options.scrollToTop)) { - position = { x: 0, y: 0 }; - } - if (to.hash) { - position = { selector: to.hash }; - } - return position; - } -} diff --git a/assets/js/getModuleInfo.js b/assets/js/getModuleInfo.js deleted file mode 100644 index f95694c2..00000000 --- a/assets/js/getModuleInfo.js +++ /dev/null @@ -1,462 +0,0 @@ -let axios = require("axios"); -let Semver = require("semver"); -let fs = require("fs"); -let Toc = require("markdown-toc"); -require("dotenv").config(); - -// hard code to avoid github api calls -const apiRepos = [ - "accept", - "ammo", - "b64", - "basic", - "bell", - "boom", - "bossy", - "bounce", - "bourne", - "call", - "catbox", - "catbox-memcached", - "catbox-memory", - "catbox-object", - "catbox-redis", - "code", - "content", - "cookie", - "crumb", - "cryptiles", - "eslint-plugin", - "file", - "glue", - "hapi", - "h2o2", - "hoek", - "inert", - "iron", - "jwt", - "lab", - "log", - "mimos", - "nes", - "oppsy", - "podium", - "scooter", - "shot", - "subtext", - "topo", - "vision", - "wreck", - "yar" -]; - -// hard code to avoid github api calls -const hapiPlugins = [ - "basic", - "bell", - "catbox-redis", - "cookie", - "crumb", - "h2o2", - "inert", - "jwt", - "log", - "nes", - "ratrace", - "scooter", - "vision", - "yar" -]; - -// include only these modules -const includedModules = [ - "accept", - "ammo", - "b64", - "basic", - "bell", - "boom", - "bossy", - "bounce", - "bourne", - "call", - "catbox", - "catbox-memcached", - "catbox-memory", - "catbox-object", - "catbox-redis", - "code", - "content", - "cookie", - "crumb", - "cryptiles", - "eslint-plugin", - "file", - "glue", - "h2o2", - "hapi", - "heavy", - "hoek", - "inert", - "iron", - "jwt", - "lab", - "log", - "mimos", - "nes", - "nigel", - "oppsy", - "pez", - "podium", - "scooter", - "shot", - "somever", - "statehood", - "subtext", - "teamwork", - "topo", - "vise", - "vision", - "wreck", - "yar", -]; - -getInfo(); - -async function getInfo() { - let repos = {}; - let newRepos = {}; - let hapiRepo = {}; - let intro = ""; - let example = ""; - let usage = ""; - let faq = ""; - let advance = ""; - let finalHtmlDisplay = ""; - let finalMenu = ""; - const options = { - headers: { - accept: "application/vnd.github.v3.raw+json", - authorization: "token " + process.env.GITHUB_TOKEN - } - }; - let repositoriesPromise = axios.get( - "https://api.github.com/orgs/hapijs/repos?per_page=100", - options - ); - - const nodeVersionsSchedulePromise = axios.get( - "https://api.github.com/repos/nodejs/Release/contents/schedule.json", - options - ); - const hapiPackageJsonPromise = axios.get( - "https://api.github.com/repos/hapijs/hapi/contents/package.json", - options - ); - - const [repositories, nodeVersionsScheduleResponse, hapiPackageJsonResponse] = - await Promise.all([ - repositoriesPromise, - nodeVersionsSchedulePromise, - hapiPackageJsonPromise, - ]); - - if (nodeVersionsScheduleResponse.status !== 200 || !nodeVersionsScheduleResponse.data) { - throw new Error("Cannot fetch list of nodejs versions"); - } else if (hapiPackageJsonResponse.status !== 200 || !hapiPackageJsonResponse.data) { - throw new Error("Cannot fetch @hapi/hapi package.json"); - } - - let nodeGlobalVersions = getSupportedNodeLtsVersions(nodeVersionsScheduleResponse.data, hapiPackageJsonResponse.data); - - repositories.data.sort((a, b) => a.name.localeCompare(b.name)); - - for (let r = 0; r < repositories.data.length; ++r) { - if (!includedModules.includes(repositories.data[r].name)) { - continue; - } - finalHtmlDisplay = ""; - finalMenu = ""; - let branches = await axios.get( - "https://api.github.com/repos/hapijs/" + - repositories.data[r].name + - "/branches", - options - ); - console.log('Processing repo: ' + repositories.data[r].name); - branches = branches.data.sort((a, b) => (a.name > b.name) ? 1 : -1) - repos[repositories.data[r].name] = { - name: repositories.data[r].name, - versions: [], - versionsArray: [], - api: false - }; - for (let branch of branches) { - intro = ""; - example = ""; - usage = ""; - faq = ""; - advance = ""; - // skip commercial branches except for hapi - if (branch.name.match(/commercial$/g) && repositories.data[r].name != 'hapi') { - continue; - } - // due to supporting commercial hapi on the site - // hard code versions so we can reduce github api calls - if (branch.name.match(/commercial$/g) && repositories.data[r].name == 'hapi') { - if (branch.name == "v19-commercial") { - nodeVersions = ["12", "14"]; - } else if (branch.name == "v18-commercial") { - nodeVersions = ["8", "10", "12"]; - } else if (branch.name == "v17-commercial") { - nodeVersions = ["8", "10", "12"]; - } else if (branch.name == "v16-commercial") { - nodeVersions = ["6", "8", "10", "12"]; - } - } else { - nodeVersions = nodeGlobalVersions; - } - if (hapiPlugins.includes(repositories.data[r].name)) { - repos[repositories.data[r].name].isPlugin = true; - } else { - repos[repositories.data[r].name].isPlugin = false; - } - if (branch.name.match(/^v+[0-9]+|\bmaster\b/g)) { - const gitHubVersion = await axios.get( - "https://api.github.com/repos/hapijs/" + - repositories.data[r].name + - "/contents/package.json?ref=" + - branch.name, - options - ); - //Get API - try { - if (apiRepos.includes(repositories.data[r].name)) { - const api = await axios.get( - "https://api.github.com/repos/hapijs/" + - repositories.data[r].name + - "/contents/API.md?ref=" + - branch.name, - options - ); - repos[repositories.data[r].name].api = true; - let rawString = await api.data.toString(); - - if (branch.name === "master") { - let intros = await rawString.match( - /(?=#.*Intro)([\s\S]*?)(?=\n#)/ - ); - if (intros) { - rawString = await rawString.replace( - /(?=#.*Intro)([\s\S]*?)(?=\n#)/, - "" - ); - intro = intros[0]; - } - let usages = await rawString.match( - /(?=#.*Usage)([\s\S]*?)(?=\n#)/ - ); - if (usages) { - rawString = await rawString.replace( - /(?=#.*Usage)([\s\S]*?)(?=\n#)/, - "" - ); - usage = usages[0]; - } - let advanced = await rawString.match( - /(?=#.*Advanced\W\W)([\s\S]*?)(?=\n#)/ - ); - if (advanced) { - rawString = await rawString.replace( - /(?=#.*Advanced\W\W)([\s\S]*?)(?=\n#)/, - "" - ); - advance = advanced[0]; - } - let examples = await rawString.match( - /(?=#.*Example\s\s)([\s\S]*?)(?=\n#)/ - ); - if (examples && repositories.data[r].name !== "bell") { - rawString = await rawString.replace( - /(?=#.*Example)([\s\S]*?)(?=\n#)/, - "" - ); - example = examples[0]; - } - rawString = (await rawString) + "#"; - let faqs = await rawString.match( - /(?=#.*F.A.Q.)([\s\S]*?)(?=\n#)/ - ); - if (faqs) { - rawString = await rawString.replace( - /(?=#.*F.A.Q.)([\s\S]*?)(?=\n#)/, - "" - ); - faq = faqs[0]; - } - } - - rawString = rawString.substring(0, rawString.length - 1); - - //Auto generate TOC - let apiTocString = ""; - let apiTocArray = await rawString.match(/\n#.+/g); - let pattern = "####"; - - for (let i = 0; i < apiTocArray.length; ++i) { - let testPattern = apiTocArray[i].match(/(?=#)(.*)(?=\s)/); - if (testPattern == null) { - continue; - } - if (testPattern[0].length < pattern.length) { - pattern = testPattern[0]; - } - apiTocString = apiTocString + apiTocArray[i]; - } - finalMenu = Toc(apiTocString, { bullets: "-" }).content; - - //Generate API and Menu HTML - let finalDisplay = await rawString.replace(/\/>/g, ">"); - finalMenu = await finalMenu.replace(/Boom\./g, ""); - finalMenu = await finalMenu.replace(/\(([^#*]+)\)/g, "()"); - const apiHTML = await axios.post( - "https://api.github.com/markdown", - { - text: finalDisplay, - mode: "markdown" - }, - { - headers: { - authorization: "token " + process.env.GITHUB_TOKEN - } - } - ); - let apiString = await apiHTML.data.toString(); - // add note that tsc does not support commercial for hapi - if (branch.name.match(/commercial$/g)) { - apiString = "\n**Note**
This is a commercial API version and is not officially supported by the TSC.
\n" + apiString; - } - finalHtmlDisplay = await apiString.replace(/user-content-/g, ""); - } - } catch (err) { - console.log(err); - continue; - } - if (repos[repositories.data[r].name].versionsArray.indexOf(gitHubVersion.data.version) === -1) { - if (!Semver.valid(gitHubVersion.data.version)) { - continue; - } - repos[repositories.data[r].name].versionsArray.push( - gitHubVersion.data.version - ); - repos[repositories.data[r].name].versions.push({ - name: gitHubVersion.data.version, - branch: branch.name, - license: gitHubVersion.data.name.includes("commercial") - ? "Commercial" - : "BSD", - node: nodeVersions.join(", ").replace("node,", "") - }); - repos[repositories.data[r].name][gitHubVersion.data.version] = { - menu: finalMenu, - api: await finalHtmlDisplay, - intro: intro, - example: example, - usage: usage, - faq: faq, - advanced: advance, - license: gitHubVersion.data.name.includes("commercial") - ? "Commercial" - : "BSD" - }; - } - await repos[repositories.data[r].name].versions.sort(function(a, b) { - return Semver.compare(b.name, a.name); - }); - } - } - - let readme = await axios.get( - "https://api.github.com/repos/hapijs/" + - repositories.data[r].name + - "/contents/README.md", - options - ); - let forks = await axios.get( - "https://api.github.com/repos/hapijs/" + repositories.data[r].name, - options - ); - let slogan = - (await readme.data.match(/####(.*)/gm)) !== null - ? await readme.data.match(/####(.*)/gm)[0].substring(5) - : "Description coming soon..."; - let date = await new Date(forks.data.pushed_at); - (repos[repositories.data[r].name].slogan = await slogan), - (repos[repositories.data[r].name].forks = await Number( - forks.data.forks_count - )), - (repos[repositories.data[r].name].stars = await Number( - forks.data.stargazers_count - )), - (repos[repositories.data[r].name].date = await forks.data.pushed_at), - (repos[repositories.data[r].name].updated = await date.toDateString()), - (repos[repositories.data[r].name].link = - "https://github.com/hapijs/" + repositories.data[r].name); - - for (let key of Object.keys(repos)) { - if (repos[key].versions.length > 1) { - if ( - repos[key].versions[0].name === repos[key].versions[1].name && - repos[key].versions[0].license === "Commercial" - ) { - let temp = repos[key].versions[0]; - repos[key].versions[0] = repos[key].versions[1]; - repos[key].versions[1] = temp; - } - } - } - - const orderedRepos = {}; - await Object.keys(repos) - .sort() - .forEach(function(key) { - orderedRepos[key] = repos[key]; - }); - - hapiRepo = orderedRepos.hapi; - - delete orderedRepos.hapi; - - newRepos = orderedRepos; - } - fs.writeFile( - "./static/lib/moduleInfo.json", - JSON.stringify(newRepos, null, 2), - function(err) { - if (err) throw err; - } - ); - fs.writeFile( - "./static/lib/hapiInfo.json", - JSON.stringify(hapiRepo, null, 2), - function(err) { - if (err) throw err; - } - ); -} - -function getSupportedNodeLtsVersions(nodeVersionsSchedule, hapiPackageJson) { - const now = Date.now(); - - const ltsVersions = Object.entries(nodeVersionsSchedule) - .filter( - ([, versionData]) => - Boolean(versionData.lts) && new Date(versionData.lts).getTime() < now - ) - .map(([readableVersion]) => Semver.coerce(readableVersion)); - - return ltsVersions - .filter((lts) => Semver.satisfies(lts, hapiPackageJson.engines.node)) - .map((supportedLts) => supportedLts.major) - .sort(); -} diff --git a/assets/styles/api.scss b/assets/styles/api.scss deleted file mode 100644 index 7cf3b422..00000000 --- a/assets/styles/api.scss +++ /dev/null @@ -1,82 +0,0 @@ -@import "./assets/styles/variables.scss"; - -h5 { - font-size: 1.1rem; -} - -h2, -h3, -h4, -h5 { - margin-top: 35px; -} - -.api-main-doc-header, -.api-main-doc-header code { - font-weight: 700; -} - -.api-top-doc-header, -.api-top-doc-header code { - padding-top: 0; - margin-top: 1em; -} - -h2 code, -h3 .api-nav-code, -h4 .api-nav-code, -h3 code, -h4 code { - background: $white; - font-family: "Open Sans", sans-serif; - font-size: 1.55rem; - color: $black; - font-weight: 400; - -webkit-font-smoothing: antialiased; - padding: 5px 0; - margin: 0; -} - -// h2 code, h3 code, h4 code, h5 code { -// margin-right: -5px; -// } - -h5 code { - background: $white; - font-family: "Open Sans", sans-serif; - font-size: 1.3rem; - color: $black; - font-weight: 400; - -webkit-font-smoothing: antialiased; - padding: 5px 0; -} - -h6 code { - background: $white; - font-family: "Open Sans", sans-serif; - font-size: 1.2rem; - color: $black; - font-weight: 400; - -webkit-font-smoothing: antialiased; - padding: 5px 0; -} - -@media (prefers-color-scheme: dark) { - h2 code, - h3 .api-nav-code, - h4 .api-nav-code, - h3 code, - h4 code { - background: $blacker; - color: $white; - } - h5 code { - background: $blacker; - color: $white; - } - h6 code { - background: $blacker; - color: $white; - } - -} \ No newline at end of file diff --git a/assets/styles/main.scss b/assets/styles/main.scss deleted file mode 100644 index c8c33ff0..00000000 --- a/assets/styles/main.scss +++ /dev/null @@ -1,234 +0,0 @@ -@import "./assets/styles/variables.scss"; - -html, -body { - position: relative; - margin: 0; - padding: 0; - font-size: 16px; - height: auto; - min-height: calc(100vh - 116px); - font-family: "Lato", sans-serif; - color: $black; - text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.004); -} - -.container { - position: relative; - width: 100%; - margin: 96px 0 0 0; - display: flex; - justify-content: space-between; -} - -.tutorial-markdown-window { - position: relative; - width: 100%; - max-width: calc(100% - 370px); - padding: 0 20px; - box-sizing: border-box; - margin: 0; -} - -.page-wrapper { - max-width: 1260px; - width: 100%; - margin: 0 auto 50px auto; - padding: 0 60px; -} - -.bold { - font-weight: 900; -} - -.hide { - display: none; -} - -.hapi-header { - margin: 10px 0; - border-top: none; - width: auto; - font-weight: 700; - font-size: 2.3rem; -} - -.hapi-family-header { - margin: 30px 0 10px 100px; - border-top: none; - width: auto; - display: inline-block; - font-weight: 700; - font-size: 2rem; - display: block; -} - -.nav-display { - display: block !important; -} - -code + .copy-clipboard { - margin-left: 0; -} - -.copy-clipboard { - position: relative; - top: 5px; - right: 5px; - display: inline-block; - width: 17px; - height: 17px; - margin: 0 0 0 5px; - background-image: url("/img/clipboard.png"); - background-size: contain; - opacity: 0.3; - cursor: pointer; - transition: all 0.2s; - - &-absolute { - position: absolute; - } - - &:hover { - opacity: 0.7; - } - - &-checked { - background-image: url("/img/clipboardCheck.png"); - opacity: 0.7; - } -} - -.spacer { - display: block; - width: 100%; -} - -.highlight-source-js { - position: relative; -} - -.api-clipboardCheck { - position: relative; - display: inline-block; - width: 17px; - height: 17px; - margin: 0 0 0 5px; - opacity: 0.7; - background: url("/img/clipboardCheck.png"); - background-size: contain; - transition: all 0.2s; -} - -.api-clipboard { - position: relative; - display: inline-block; - width: 17px; - height: 17px; - margin: 0 0 0 5px; - background: url("/img/clipboard.png"); - background-size: contain; - opacity: 0.3; - cursor: pointer; - transition: all 0.2s; -} - -.api-clipboard:hover { - opacity: 0.7; -} - -.api-version-span { - font-weight: 400; - font-size: 1.4rem; -} - -.landing-hr { - position: relative; - left: -30px; - height: 1px; - background-color: $dark-white; - width: calc(100% - 10px); - margin: 0; -} - -.preload { - display: none; -} -@media screen and (max-width: 1500px) { - .hapi-family-header { - margin-left: 40px; - } -} - -@media screen and (min-width: 1088px) { - .container { - max-width: 100%; - } -} - -@media screen and (max-width: 900px) { - html, - body { - font-size: 14px; - overflow-x: hidden; - -webkit-overflow-scrolling: touch; - height: 100%; - } - - :root { - font-size: 14px; - } - - .container { - display: flex; - flex-direction: column; - margin-top: 50px; - } - - .tutorial-markdown-window { - max-width: 100%; - word-wrap: break-word; - } - - .page-wrapper { - padding: 0 20px; - } - - .hapi-header { - font-size: 2rem; - } - - .hapi-family-header { - margin-top: 10px; - margin-left: 10px; - } -} - -@media print { - .container { - margin: 0; - display: block; - } - .tutorial-markdown-window { - max-width: 100%; - } -} - - -@media (prefers-color-scheme: dark) { - - html, - body { - color: $off-white; - background: $black; - z-index: -1; - } - - .landing-hr { - background-color: $blacker; - } - - strong, b { - color: $off-white; - } -} \ No newline at end of file diff --git a/assets/styles/markdown.scss b/assets/styles/markdown.scss deleted file mode 100644 index e9d6f004..00000000 --- a/assets/styles/markdown.scss +++ /dev/null @@ -1,235 +0,0 @@ -@import "./assets/styles/variables.scss"; - -.markdown-wrapper { - position: relative; - width: 100%; - box-sizing: border-box; - margin: 0; - padding: 20px 100px 10px 100px; - word-wrap: break-all; -} - -.family-markdown-wrapper { - position: relative; - width: 100%; - box-sizing: border-box; - margin: 0; - padding: 0 100px 10px 100px; - word-wrap: break-all; -} - -h1 { - font-size: 2rem; -} - -h2 { - font-size: 1.75rem; -} - -h3 { - font-size: 1.55rem; -} - -h4 { - font-size: 1.3rem; -} - -h5 { - font-size: 1.25rem; -} - -h2 a, -h3 a, -h4 a, -h5 a { - display: block; - position: relative; - top: -116px; - visibility: hidden; -} - -a:focus { - outline: none; -} - -h2 a, -h3 a { - color: $black; - cursor: auto; -} - -code, -.code { - font-family: "inconsolata", menlo, consolas, monospace; - padding: 0.2rem 0.33rem; - font-size: 1rem; - color: $gray; - background-color: $off-white; - // border: 1px solid $dark-white; -} - -.tutorial-markdown-window section { - height: 100%; -} - -a { - cursor: pointer; - color: $orange; - text-decoration: none; -} - -a:hover { - color: $orange; - text-decoration: underline; -} - -p { - display: block; - margin-block-start: 1em; - margin-block-end: 1em; - margin-inline-start: 0px; - margin-inline-end: 0px; - color: $black; - line-height: 1.7rem; -} - -p code, -li code { - font-family: "inconsolata", menlo, consolas, monospace; - padding: 0.2rem 0.33rem; - color: $gray; - background-color: $quote-gray; - border: 1px solid $dark-white; -} - -pre { - font-family: "inconsolata", menlo, consolas, monospace; - font-size: 1rem; -} - -pre p code, -pre pre { - border: none; -} - -li { - margin-bottom: 20px; - line-height: 1.7rem; - list-style-type: disc; -} - -ul { - margin: 15px 0 15px 20px; - padding: 0; -} - -pre { - border: 1px solid $dark-white; - white-space: pre-wrap; /* Since CSS 2.1 */ - white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ - white-space: -pre-wrap; /* Opera 4-6 */ - white-space: -o-pre-wrap; /* Opera 7 */ - word-wrap: break-word; /* Internet Explorer 5.5+ */ -} - -.hljs-keyword, -.pl-k { - color: #d73a49; -} - -.hljs-built_in, -.pl-c1 { - color: #009bdc; -} - -.pl-c { - color: #aaa; -} - -.hljs-attr, -.pl-en { - color: #6f42c1; -} - -@media screen and (max-width: 1500px) { - .markdown-wrapper { - padding: 20px 40px; - } - - .family-markdown-wrapper { - padding: 0 40px 10px 40px; - } -} - -@media screen and (max-width: 900px) { - h2 a, - h3 a, - h4 a, - h5 a { - top: -60px; - } - - p, - li { - line-height: 2rem; - font-size: 16px; - } - - pre { - font-size: 15.25px; - } - - .markdown-wrapper, - .family-markdown-wrapper { - padding: 5px 0; - } -} - -@media print { - .markdown-wrapper, - .family-markdown-wrapper { - padding: 0; - } -} - - -@media (prefers-color-scheme: dark) { - - pre { - background: $blackest; - border-color: #000 !important; - color: $ash; - } - - h2 a, - h3 a { - color: $white; - } - - code, - .code { - color: $light-gray; - background-color: $blacker !important; - border: 1px solid #000 !important; - } - - p { - color: $off-white; - } - - p code, - li code { - color: $light-gray; - background-color: $quote-gray-dark; - } - - a:hover { - color: $gray; - } - - .hljs-attr, - .pl-en { - color: lighten(#6f42c1, 20%); - } - -} \ No newline at end of file diff --git a/assets/styles/sideNav.scss b/assets/styles/sideNav.scss deleted file mode 100644 index 8ecba552..00000000 --- a/assets/styles/sideNav.scss +++ /dev/null @@ -1,296 +0,0 @@ -@import "./assets/styles/variables.scss"; - -.side-nav-window { - position: -webkit-sticky; - position: sticky; - top: 96px; - bottom: 0; - width: 370px; - min-width: 370px; - max-height: calc(100vh - 96px); - min-height: calc(100vh - 96px); - overflow-x: hidden; - overflow-y: auto; - padding: 20px 20px 5px; - margin: 0; - -webkit-font-smoothing: auto; - -moz-osx-font-smoothing: auto; - display: flex; - flex-direction: column; - justify-content: flex-start; - align-items: flex-start; - background: #f8f8f8; - border-right: 1px solid $dark-white; -} - -.api-nav-window { - position: sticky; - top: 96px; - bottom: 0; - width: 370px; - min-width: 370px; - max-height: calc(100vh - 96px); - min-height: calc(100vh - 96px); - overflow-y: auto; - overflow-x: hidden; - -webkit-font-smoothing: auto; - -moz-osx-font-smoothing: auto; - padding: 0 0 5px 0; - margin: 0; - display: flex; - flex-direction: column; - justify-content: flex-start; - align-items: flex-start; - background: $off-white; - border-right: 1px solid $dark-white; -} - -.api-nav-wrapper { - display: flex; - flex-direction: column; - justify-content: space-between; - position: relative; - width: 100%; - height: auto; - min-height: calc(100vh - 122px); -} - -.api-nav-inner-wrapper { - display: flex; - flex: 0 0 auto; - flex-direction: column; - align-items: flex-start; - margin: 0; - // overflow-x: hidden; - position: relative; -} - -.api-nav-select-wrapper ul { - margin-left: 0; -} - -.api-nav-select-wrapper { - margin: 0; - font-size: 1.1em; - color: $orange; - line-height: 30px; - width: 100%; - overflow-x: hidden; -} - -.side-nav-wrapper { - display: flex; - flex-direction: column; - justify-content: space-between; - position: relative; - width: 100%; - height: auto; - min-height: calc(100vh - 122px); -} - -.side-nav-inner-wrapper { - display: flex; - flex: 0 0 auto; - flex-direction: column; - align-items: flex-start; - margin: 0; -} - -.side-nav-title { - font-size: 1.5rem; - color: $black; - margin: 0; -} - -.lang-wrapper { - display: flex; - justify-content: flex-start; - align-items: center; - margin: 20px 0 0 0; - width: 100%; -} - -.lang-text { - margin: 0 33px 0 0; - font-size: 1.1em; -} - -.family-span { - font-size: 1rem; - color: #333; - font-weight: 400; -} - -.family-version-select { - width: 70px; - padding: 0px 5px 0px 5px; - border: none; - height: 30px; - font-size: 1em; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - background: url(/img/down.png) 96% / 15% no-repeat $off-white; - cursor: pointer; -} - -select { - width: 100px; - padding: 0px 5px 0px 5px; - border: 1px solid $dark-white; - height: 30px; - font-size: 0.9em; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - background: url(/img/down.png) 96% / 15% no-repeat $white; - cursor: pointer; -} - -select:focus { - outline: none; -} - -.api-side-nav-select-wrapper { - font-size: 1.1em; - color: $orange; - line-height: 30px; - width: 100%; - padding: 0 20px; -} - -.side-nav-select-wrapper { - margin: 20px 0 0 0; - font-size: 1.1em; - color: #ed7d31; - line-height: 30px; - width: 100%; - overflow-x: hidden; -} - -.family-nav-no-margin { - margin: 0; -} - -.side-nav-select-list { - margin: 0; - display: flex; - flex-direction: column; -} - -.family-nav-select-list { - margin-left: 30px; -} - -.side-nav-select-link { - cursor: pointer; - margin: 0 auto 0 0; - list-style-type: none; -} - -.side-nav-select-link:hover { - color: $orange; - text-decoration: underline; -} - -.side-nav-active { - font-weight: 900; -} - -.ads-wrapper { - width: 319px; - height: 142px; -} - -@media screen and (max-width: 900px) { - .side-nav-window, - .api-nav-window, - .tutorial-nav-window { - flex-direction: row; - align-items: center; - position: relative; - top: 0; - padding: 10px 20px; - min-height: auto; - max-height: auto; - border-right: none; - border-bottom: 1px solid $dark-white; - width: 100%; - } - - .side-nav-inner-wrapper { - margin: 0; - } - - #carbonads { - max-width: none; - } - - .ads-wrapper { - margin: 0; - } - - .side-nav-wrapper { - min-height: auto; - } - - .side-nav-select-list { - display: inline-block; - } - - .side-nav-select-link { - display: inline-block; - } - - .side-nav-select-wrapper, - .api-nav-select-wrapper { - display: none; - } -} - -@media print { - .side-nav-window { - display: none; - } -} - -@media (prefers-color-scheme: dark) { - - .side-nav-window, - .api-nav-window { - background: $blacker !important; - border-color: $blackest !important; - } - .side-nav-title { - color: $white; - } - .family-span { - color: $white; - } - .family-version-select, select { - background: url(/img/down.png) 96% / 15% no-repeat $blackest; - color: $ash; - border-color: black; - } - .api-nav-window { - background: $blacker; - } - - .family-version-select, - .family-search-box, - .api-search-box { - background-color: $blackest !important; - border-color: $blackest !important; - color: $light-gray !important; - } - - .family-top-wrapper, - .family-search-button, - .family-search-img, - .api-search-img { - background-color: $blackest !important;; - border-color: $blackest !important; - color: $light-gray; - } - -} diff --git a/assets/styles/statusTable.scss b/assets/styles/statusTable.scss deleted file mode 100644 index e8ee2b15..00000000 --- a/assets/styles/statusTable.scss +++ /dev/null @@ -1,262 +0,0 @@ -@import "./assets/styles/variables.scss"; -@import "../../assets/styles/markdown.scss"; - -.module-status-wrapper { - display: flex; - flex-direction: column; - justify-content: flex-start; - align-items: flex-start; - padding: 20px 100px; - margin: 0; - width: 100%; -} - -.module-status-table-wrapper { - margin: 0; - width: 100%; -} - -.status-table { - width: 100%; - margin-top: 16px; - min-width: 800px; - position: relative; -} - -.dependencies-header, -.ci-header, -.license-header, -.node-header { - width: 10.546875%; - text-align: center; - font-weight: 900; -} - -.version-header { - width: 18.75%; - text-align: center !important; - font-weight: 900; -} - -.header-module { - text-align: center; -} - -.header-row { - position: relative; - z-index: 1; -} - -.module-name { - width: 25%; - border-right: 1px solid $dark-white; - text-align: center; - vertical-align: middle; - font-size: 1.15em; - font-weight: 700; -} - -.module-row { - border-bottom: 3px solid $dark-white; - background-color: $white; -} - -.module-name { - position: relative; -} - -.module-name-link { - display: block; - position: absolute; - content: ""; - visibility: hidden; - top: -150px; - z-index: -5; -} - -.module-row:nth-child(odd) { - background-color: $off-white; -} - -.nested-table { - width: 100%; -} - -.nested-table td { - width: 14.0625%; - text-align: center; -} - -.module-license { - width: 18.75%; -} - -.module-version { - width: 25% !important; -} - -.status-table th { - padding: 10px; - font-size: 1.15em; - position: sticky; - top: 90px; - background-color: $white; - z-index: 1; -} - -.status-table th:after { - content: ""; - position: absolute; - left: 0; - bottom: -1px; - width: 100%; - border-bottom: 1px solid $dark-white; - z-index: 1; -} - -.status-table td { - padding: 10px; -} - -.status-table tbody { - border: 3px solid $dark-white; -} - -.nested-tbody { - border: none !important; -} - -.nested-tbody td { - vertical-align: middle; -} - -.nested-td { - box-sizing: border-box; - padding: 0 !important; -} - -.nested-tbody tr:not(:last-child) { - border-bottom: 1px solid $dark-white; -} - -.module-version-wrapper, -.module-version-wrapper a { - display: flex; - justify-content: center; - align-items: center; -} - -.version-name { - color: $orange; - font-weight: 700; -} - -.module-version-wrapper * { - margin: 0; -} - -.version-helmet { - padding: 0 20px; -} - -.version-img { - width: 20px; - min-width: 20px; -} - -.status-link { - font-weight: 700; -} - -.status-passing { - width: 12px; - height: 12px; - border-radius: 50%; - background: #1dd022; -} - -.status-nonMaster { - width: 12px; - height: 12px; - border-radius: 50%; - background: #10872a; -} - -.status-failing { - width: 12px; - height: 12px; - border-radius: 50%; - background: #e80013; -} - -.status-unknown { - width: 12px; - height: 12px; - border-radius: 50%; - background: #797979; -} - -.hide { - display: hidden; -} - -@media screen and (max-width: 1500px) { - .module-status-wrapper { - padding: 20px 40px; - } - - .status-table th { - font-size: 14px; - padding: 10px 0px; - } - - .module-name { - font-size: 16px; - } - - .status-table td { - padding: 10px 5px; - } -} - -@media screen and (max-width: 900px) { - .module-status-wrapper { - padding: 10px 10px 0 10px; - overflow-x: auto; - } - - .status-table { - margin-right: 10px; - } - - .status-table th { - padding: 0; - font-size: 12px; - } -} - - -@media (prefers-color-scheme: dark) { - - .module-row { - background-color: $black; - } - .module-row:nth-child(odd) { - background-color: $blacker; - } - .status-table th { - background-color: $black; - } - - .module-name, - .module-row, - .status-table th:after, - .status-table tbody, - .nested-tbody tr:not(:last-child) { - border-color: $blackest !important; - } - - table thead tr th { - color: $gray !important; - } -} diff --git a/assets/styles/variables.scss b/assets/styles/variables.scss deleted file mode 100644 index f260721f..00000000 --- a/assets/styles/variables.scss +++ /dev/null @@ -1,14 +0,0 @@ -/* Colors */ -$orange: #ed7d31; -$black: #333; -$blacker: #222; -$blackest: #111; -$off-white: #f8f8f8; -$dark-white: #ddd; -$light-gray: #ccc; -$ash: #aaa; -$quote-gray: #f3f3f3; -$quote-gray-dark: #3a3a3a; -$gray: #6f6f6f; -$gray-light: lighten($gray, 35%); -$white: #ffffff; \ No newline at end of file diff --git a/cli/generateChangelog.ts b/cli/generateChangelog.ts new file mode 100644 index 00000000..a46d5edf --- /dev/null +++ b/cli/generateChangelog.ts @@ -0,0 +1,178 @@ +import fs from 'node:fs/promises'; +import path from 'node:path'; + +import { Semaphore } from 'es-toolkit'; +import { Feed } from 'feed'; +import Semver from 'semver'; + +import { getMilestoneIssues, getMilestones } from './gh.js'; +import { modules } from './modules.js'; +import { getExisting, getModuleChangelogPath, getModuleMarkdownChangelogPath, PUBLIC_ATOM_DIR } from './paths.js'; + +import type { ChangelogItem } from './types.js'; + +export const generateChangelog = async (moduleName: string) => { + let foundNewMilestones = false; + + const filePath = getModuleChangelogPath(moduleName); + const existing = await getExisting(filePath); + const existingMap = new Map(existing?.map((c) => [c.version, c])); + + console.info(`[changelog] Generating for ${moduleName}`); + + const milestones = await getMilestones(moduleName); + + const changelog: ChangelogItem[] = []; + + const limit = new Semaphore(10); + const tasks = milestones.map(async (milestone) => { + if (existingMap.has(milestone.title)) { + console.info(`[changelog] Skipping ${moduleName}@${milestone.title}`); + return existingMap.get(milestone.title)!; + } + + await limit.acquire(); + try { + console.info(`[changelog] Getting issues for ${moduleName}@${milestone.title}`); + + const issues = await getMilestoneIssues(moduleName, milestone.number); + + foundNewMilestones = true; + + return { + date: milestone.closed_at, + id: milestone.id, + issues: issues.map((issue) => ({ + id: issue.id, + labels: issue.labels.map((label) => label.name), + number: issue.number, + title: issue.title, + url: issue.html_url, + })), + number: milestone.number, + url: milestone.html_url, + version: milestone.title, + }; + } finally { + limit.release(); + } + }); + + changelog.push(...(await Promise.all(tasks))); + + const sortedChangelog = changelog.toSorted((a, b) => { + const aCoerced = Semver.coerce(a.version); + const bCoerced = Semver.coerce(b.version); + if (aCoerced && bCoerced) { + return Semver.compare(bCoerced, aCoerced); + } + return b.version.localeCompare(a.version); + }); + + if (foundNewMilestones) { + await fs.writeFile(filePath, JSON.stringify(sortedChangelog, null, 2)); + } + + await generateModuleMarkdownChangelog(moduleName, sortedChangelog); + await generateModuleAtom(moduleName, sortedChangelog); +}; + +const generateModuleAtom = async (moduleName: string, sortedChangelog: ChangelogItem[]) => { + const isHapi = moduleName === 'hapi'; + const spec = modules[moduleName]; + const fullModuleName = spec?.package ?? moduleName; + const baseLink = isHapi ? 'https://hapi.dev' : `https://hapi.dev/module/${moduleName}`; + const changelogLink = isHapi + ? 'https://hapi.dev/resources/changelog' + : `https://hapi.dev/module/${moduleName}/changelog`; + + const feed = new Feed({ + favicon: 'https://hapi.dev/favicon.png', + id: baseLink, + image: 'https://hapi.dev/img/logo.png', + language: 'en', + link: baseLink, + title: `${fullModuleName} changelog`, + updated: new Date(sortedChangelog[0]?.date ?? Date.now()), + }); + + const items = sortedChangelog.slice(0, 50); + + for (const item of items) { + const title = `${fullModuleName} v${item.version}`; + const link = `${changelogLink}#${item.version}`; + const date = new Date(item.date); + + let content = '
    '; + for (const issue of item.issues) { + content += `
  • [#${issue.number}] ${escapeHtml(issue.title)}
  • `; + } + content += '
'; + + feed.addItem({ + content, + date, + description: title, + id: item.url, + link, + title, + }); + } + + const atomPath = path.join(PUBLIC_ATOM_DIR, `${moduleName}.atom`); + await fs.mkdir(path.dirname(atomPath), { recursive: true }); + await fs.writeFile(atomPath, feed.atom1()); +}; + +const generateModuleMarkdownChangelog = async (moduleName: string, sortedChangelog: ChangelogItem[]) => { + const majorVersions = new Set(); + sortedChangelog.forEach((m) => { + const [major] = m.version.split('.'); + if (major) { + majorVersions.add(major); + } + }); + + const changelogPath = getModuleMarkdownChangelogPath(moduleName); + await fs.mkdir(path.dirname(changelogPath), { recursive: true }); + let content = ''; + + const sortedMajors = [...majorVersions].toSorted((a, b) => parseInt(b, 10) - parseInt(a, 10)); + + for (const major of sortedMajors) { + content += `## Version ${major} {#v${major}}\n\n`; + + const milestones = sortedChangelog.filter((m) => m.version.startsWith(`${major}.`)); + + for (const milestone of milestones) { + const hasBreaking = milestone.issues.some((issue) => issue.labels.some((label) => label === 'breaking changes')); + + const releaseNotesIssue = milestone.issues.find((issue) => + issue.labels.some((label) => label === 'release notes'), + ); + + content += `### [${milestone.version}](${milestone.url}) `; + + if (releaseNotesIssue) { + content += ` `; + } + + if (hasBreaking) { + content += ` `; + } + + content += `{#${milestone.version}} `; + + content += `\n\n`; + + for (const issue of milestone.issues) { + content += `- [#${issue.number}](${issue.url}) ${escapeHtml(issue.title)}\n`; + } + content += '\n'; + } + } + + await fs.writeFile(changelogPath, content); +}; + +const escapeHtml = (text: string) => text.replaceAll('<', '<').replaceAll('>', '>'); diff --git a/cli/getModuleInfo.ts b/cli/getModuleInfo.ts new file mode 100644 index 00000000..87e03a5e --- /dev/null +++ b/cli/getModuleInfo.ts @@ -0,0 +1,285 @@ +import { execFileSync } from 'node:child_process'; +import fs from 'node:fs/promises'; +import path from 'node:path'; + +import { Semaphore, uniq } from 'es-toolkit'; +import Semver from 'semver'; +import { createMarkdownRenderer } from 'vitepress'; + +import { generateChangelog } from './generateChangelog.js'; +import { getDirectoryListing, getRawContent, getRepoInfo } from './gh.js'; +import { modules } from './modules.js'; +import { + API_DIR, + MARKDOWN_DIR, + METADATA_DIR, + POLICIES_GENERATED_DIR, + getExisting, + getModuleInfoPath, + getModuleMarkdownPath, + getModuleStoragePath, +} from './paths.js'; + +import type { ModuleInfo, ModuleSpec, VersionInfo } from './types.js'; + +const getFilteredVersions = (specs: ModuleSpec, versions: string[]): VersionInfo[] => { + const compatibilityVersions = Object.keys(specs.compatibility); + const minVersion = Math.min(...compatibilityVersions.map((v) => parseInt(v, 10))); + const prefilteredVersions = versions.filter((v) => Semver.satisfies(v, `>=${minVersion}`)); + const publishedMajorVersions = uniq(prefilteredVersions.map((v) => Semver.major(v))); + const semveredMajors = compatibilityVersions.map((v) => `${v}.0.0`); + + return publishedMajorVersions.map((major) => { + const closestMatchingVersion = Semver.maxSatisfying(semveredMajors, `<= ${major}`); + return { + fullVersion: Semver.maxSatisfying(prefilteredVersions, `^${major}`)!, + major, + nodeVersion: closestMatchingVersion ? specs.compatibility[Semver.major(closestMatchingVersion)] : '', + }; + }); +}; + +const md = await createMarkdownRenderer('.'); + +const repos: Record> = {}; + +const limit = new Semaphore(4); + +const processModule = async (moduleName: string, specs: ModuleSpec) => { + console.info(`Processing ${moduleName}`); + + await fs.mkdir(getModuleStoragePath(moduleName), { + recursive: true, + }); + + const filePath = getModuleInfoPath(moduleName); + + const existing = await getExisting(filePath); + + // Get published versions from npm + const versions = JSON.parse( + execFileSync('npm', ['view', specs.package, 'versions', '--json'], { + encoding: 'utf8', + }), + ) as string[]; + + const currentModule: ModuleInfo = { + api: false, + forks: 0, + isPlugin: specs.isPlugin ?? false, + latestVersion: '', + link: '', + name: moduleName, + package: specs.package, + slogan: '', + sloganHtml: '', + stars: 0, + updated: '', + versions: [], + versionsArray: [], + }; + repos[moduleName] = currentModule; + + // Keep only latest versions from majors listed in specs + const filteredVersions = getFilteredVersions(specs, versions); + + currentModule.versionsArray = filteredVersions.map((v) => v.fullVersion).toSorted((a, b) => Semver.compare(b, a)); + currentModule.latestVersion = `${currentModule.versionsArray[0].split('.')[0]}.x.x`; + + const versionLimit = new Semaphore(10); + const versionTasks = filteredVersions.map(async ({ nodeVersion, fullVersion, major }) => { + const hasApi = specs.hasApi ?? false; + + if (!hasApi) { + return { + apiExists: false, + branch: `v${fullVersion}`, + license: 'BSD', + name: fullVersion, + node: nodeVersion, + }; + } + + const apiPath = getModuleMarkdownPath(moduleName, major); + const apiExists = await fs + .access(apiPath) + .then(() => true) + .catch(() => false); + + const existingVersion = existing?.versions.find((v) => v.name === fullVersion); + + if (existingVersion && apiExists) { + console.info(`[docs] Skipping ${moduleName}@${major}`); + return { + apiExists: true, + branch: existingVersion.branch, + license: existingVersion.license, + name: existingVersion.name, + node: existingVersion.node, + }; + } + + await versionLimit.acquire(); + try { + console.info(`[docs] Processing ${moduleName}@${fullVersion}`); + const tagName = `v${fullVersion}`; + + const api = await getRawContent(moduleName, 'API.md', tagName); + + await fs.mkdir(path.dirname(apiPath), { recursive: true }); + + await fs.writeFile(apiPath, api.data); + console.info(`[docs] Wrote ${apiPath}`); + + return { + apiExists: true, + branch: tagName, + license: 'BSD', + name: fullVersion, + node: nodeVersion, + }; + } finally { + versionLimit.release(); + } + }); + + const versionResults = await Promise.all(versionTasks); + for (const result of versionResults) { + currentModule.versions.push({ + branch: result.branch, + license: result.license, + name: result.name, + node: result.node, + }); + if (result.apiExists) { + currentModule.api = true; + } + } + + currentModule.versions.sort((a, b) => Semver.compare(a.name, b.name)); + + const [readme, repoInfo] = await Promise.all([ + existing ? Promise.resolve({ data: '' }) : getRawContent(moduleName, 'README.md'), + getRepoInfo(moduleName), + ]); + + const readmeMatch = readme.data.match(/####(.*)/gm); + const rawSlogan = readmeMatch === null ? (existing?.slogan ?? 'Description coming soon...') : readmeMatch[0].slice(5); + + currentModule.slogan = rawSlogan.trim(); + currentModule.sloganHtml = md.renderInline(currentModule.slogan); + currentModule.forks = repoInfo.data.forks_count; + currentModule.stars = repoInfo.data.stargazers_count; + currentModule.updated = repoInfo.data.pushed_at; + currentModule.link = repoInfo.data.html_url; + + const moduleDir = getModuleStoragePath(moduleName); + await fs.mkdir(moduleDir, { recursive: true }); + + await fs.writeFile(filePath, JSON.stringify(currentModule, null, 2)); + + if (moduleName === 'hapi') { + await fs.mkdir(API_DIR, { recursive: true }); + } + + await generateChangelog(moduleName); + + await fs.writeFile(filePath, JSON.stringify(currentModule, null, 2)); + + repos[moduleName] = { + forks: currentModule.forks, + isPlugin: currentModule.isPlugin, + latestVersion: currentModule.latestVersion, + link: currentModule.link, + package: currentModule.package, + slogan: currentModule.slogan, + sloganHtml: currentModule.sloganHtml, + stars: currentModule.stars, + updated: currentModule.updated, + versions: currentModule.versions, + versionsArray: currentModule.versionsArray, + }; +}; + +const moduleTasks = Object.entries(modules).map(async ([moduleName, specs]) => { + await limit.acquire(); + try { + await processModule(moduleName, specs); + } finally { + limit.release(); + } +}); + +await Promise.all(moduleTasks); + +const sortedRepos = Object.fromEntries(Object.keys(modules).map((name) => [name, repos[name]])); + +const policies: [string, string, string?][] = [ + ['coc', 'CODE_OF_CONDUCT'], + ['contributing', 'CONTRIBUTING'], + ['license', 'LICENSE'], + ['security', 'SECURITY'], + ['sponsors', 'SPONSORS'], + ['styleguide', 'STYLE', 'assets'], + ['support', 'SUPPORT'], +]; + +await fs.mkdir(POLICIES_GENERATED_DIR, { recursive: true }); +await Promise.all( + policies.map(async ([policy, fileName, repo]) => { + const policyPath = path.join(POLICIES_GENERATED_DIR, `${policy}.md`); + const existingPolicy = await fs.readFile(policyPath, 'utf8').catch(() => null); + if (existingPolicy) { + console.info(`[policy] Skipping ${policy}`); + return; + } + const { data } = await getRawContent(repo ?? '.github', `${fileName}.md`, 'master'); + await fs.writeFile(policyPath, data); + }), +); + +// Fetch bell-specific content (examples and providers) +const bellMarkdownDir = path.join(MARKDOWN_DIR, 'bell'); +await fs.mkdir(bellMarkdownDir, { recursive: true }); + +const bellProvidersPath = path.join(bellMarkdownDir, 'providers.md'); +const existingProviders = await fs.readFile(bellProvidersPath, 'utf8').catch(() => null); +if (existingProviders) { + console.info('[bell] Skipping Providers.md'); +} else { + console.info('[bell] Fetching Providers.md'); + const { data: providersData } = await getRawContent('bell', 'Providers.md', 'master'); + await fs.writeFile(bellProvidersPath, providersData); +} + +const bellExamplesPath = path.join(bellMarkdownDir, 'examples.md'); +const existingExamples = await fs.readFile(bellExamplesPath, 'utf8').catch(() => null); +if (existingExamples) { + console.info('[bell] Skipping examples'); +} else { + console.info('[bell] Fetching examples'); + const { data: exampleFiles } = await getDirectoryListing('bell', 'examples', 'master'); + let examplesContent = ''; + for (const file of exampleFiles) { + if (file.type === 'file' && file.name.endsWith('.js')) { + const name = file.name.replace(/\.js$/, ''); + const label = name.charAt(0).toUpperCase() + name.slice(1); + const { data: code } = await getRawContent('bell', file.path, 'master'); + examplesContent += `## ${label}\n\n\`\`\`js\n${code}\n\`\`\`\n\n`; + } + } + await fs.writeFile(bellExamplesPath, examplesContent); +} + +await fs.mkdir(METADATA_DIR, { recursive: true }); +await fs.writeFile(path.join(METADATA_DIR, 'modules.json'), JSON.stringify(sortedRepos, null, 2)); + +console.info('Running oxfmt...'); +try { + execFileSync('oxfmt', ['./generated'], { stdio: 'inherit' }); + + // Apparently oxfmt sometimes needs a 2nd pass + execFileSync('oxfmt', ['./generated'], { stdio: 'inherit' }); +} catch (error: unknown) { + console.error('Failed to run oxfmt:', error instanceof Error ? error.message : error); +} diff --git a/cli/gh.ts b/cli/gh.ts new file mode 100644 index 00000000..b22ab81d --- /dev/null +++ b/cli/gh.ts @@ -0,0 +1,85 @@ +import { throttling } from '@octokit/plugin-throttling'; +import { Octokit } from '@octokit/rest'; +import Semver from 'semver'; + +import type { Issue, Milestone } from './types.js'; + +const MyOctokit = Octokit.plugin(throttling); + +const gh = new MyOctokit({ + auth: process.env.GITHUB_TOKEN, + throttle: { + onRateLimit: (retryAfter, options, octokit, retryCount) => { + octokit.log.warn(`Request quota exhausted for request ${options.method} ${options.url}`); + + if (retryCount < 1) { + // Only retries once + octokit.log.info(`Retrying after ${retryAfter} seconds!`); + return true; + } + }, + onSecondaryRateLimit: (retryAfter, options, octokit) => { + // Does not retry, only logs a warning + octokit.log.warn(`Secondary quota exhausted for request ${options.method} ${options.url}`); + }, + }, +}); + +export const getRawContent = async (repoName: string, filePath: string, tagName?: string) => + (await gh.repos.getContent({ + mediaType: { + format: 'raw', + }, + owner: 'hapijs', + path: filePath, + ref: tagName, + repo: repoName, + })) as unknown as { data: string }; + +export const getDirectoryListing = async (repoName: string, dirPath: string, ref?: string) => + (await gh.repos.getContent({ + owner: 'hapijs', + path: dirPath, + ref, + repo: repoName, + })) as unknown as { data: { name: string; path: string; type: string }[] }; + +export const getRepoInfo = async (moduleName: string) => + await gh.repos.get({ + owner: 'hapijs', + repo: moduleName, + }); + +export const getMilestones = async (moduleName: string) => { + const milestones: Milestone[] = []; + for await (const response of gh.paginate.iterator(gh.issues.listMilestones, { + owner: 'hapijs', + per_page: 100, + repo: moduleName, + state: 'closed', + })) { + milestones.push(...(response.data as Milestone[])); + } + return milestones.toSorted((a, b) => { + const aCoerced = Semver.coerce(a.title); + const bCoerced = Semver.coerce(b.title); + if (aCoerced && bCoerced) { + return Semver.compare(aCoerced, bCoerced); + } + return a.title.localeCompare(b.title); + }); +}; + +export const getMilestoneIssues = async (moduleName: string, milestoneNumber: number) => { + const issues: Issue[] = []; + for await (const response of gh.paginate.iterator(gh.issues.listForRepo, { + milestone: milestoneNumber.toString(), + owner: 'hapijs', + per_page: 100, + repo: moduleName, + state: 'closed', + })) { + issues.push(...(response.data as Issue[])); + } + return issues; +}; diff --git a/cli/modules.ts b/cli/modules.ts new file mode 100644 index 00000000..23b8ef7e --- /dev/null +++ b/cli/modules.ts @@ -0,0 +1,262 @@ +import type { ModuleSpec } from './types.js'; + +export const modules: Record = { + accept: { + compatibility: { 6: '>= 16' }, + hasApi: true, + package: '@hapi/accept', + }, + ammo: { + compatibility: { 6: '>= 16' }, + hasApi: true, + package: '@hapi/ammo', + }, + b64: { + compatibility: { 6: '>= 16' }, + hasApi: true, + package: '@hapi/b64', + }, + basic: { + compatibility: { 7: '>= 16' }, + hasApi: true, + isPlugin: true, + package: '@hapi/basic', + }, + bell: { + compatibility: { 13: '>= 16' }, + hasApi: true, + isPlugin: true, + package: '@hapi/bell', + }, + boom: { + compatibility: { 10: '>= 16' }, + hasApi: true, + package: '@hapi/boom', + }, + bossy: { + compatibility: { 5: '>= 16' }, + hasApi: true, + package: '@hapi/bossy', + }, + bounce: { + compatibility: { 3: '>= 16' }, + hasApi: true, + package: '@hapi/bounce', + }, + bourne: { + compatibility: { 3: '>= 16' }, + hasApi: true, + package: '@hapi/bourne', + }, + call: { + compatibility: { 9: '>= 16' }, + hasApi: true, + package: '@hapi/call', + }, + catbox: { + compatibility: { 12: '>= 16' }, + hasApi: true, + package: '@hapi/catbox', + }, + 'catbox-memcached': { + compatibility: { 4: '>= 16' }, + hasApi: true, + package: '@hapi/catbox-memcached', + }, + 'catbox-memory': { + compatibility: { 6: '>= 16' }, + hasApi: true, + package: '@hapi/catbox-memory', + }, + 'catbox-object': { + compatibility: { 3: '>= 16' }, + hasApi: true, + package: '@hapi/catbox-object', + }, + 'catbox-redis': { + compatibility: { 7: '>= 16' }, + hasApi: true, + isPlugin: true, + package: '@hapi/catbox-redis', + }, + code: { + compatibility: { 9: '>= 16' }, + hasApi: true, + package: '@hapi/code', + }, + content: { + compatibility: { 6: '>= 16' }, + hasApi: true, + package: '@hapi/content', + }, + cookie: { + compatibility: { 12: '>= 16' }, + hasApi: true, + isPlugin: true, + package: '@hapi/cookie', + }, + crumb: { + compatibility: { 9: '>= 16' }, + hasApi: true, + isPlugin: true, + package: '@hapi/crumb', + }, + cryptiles: { + compatibility: { 6: '>= 16' }, + hasApi: true, + package: '@hapi/cryptiles', + }, + 'eslint-plugin': { + compatibility: { 6: '>= 16' }, + hasApi: true, + package: '@hapi/eslint-plugin', + }, + file: { + compatibility: { 3: '>= 16' }, + hasApi: true, + package: '@hapi/file', + }, + glue: { + compatibility: { 9: '>= 16' }, + hasApi: true, + package: '@hapi/glue', + }, + h2o2: { + compatibility: { 10: '>= 16' }, + hasApi: true, + isPlugin: true, + package: '@hapi/h2o2', + }, + hapi: { + compatibility: { 20: '>= 16', 21: '>= 16' }, + hasApi: true, + package: '@hapi/hapi', + }, + heavy: { + compatibility: { 8: '>= 16' }, + hasApi: true, + package: '@hapi/heavy', + }, + hoek: { + compatibility: { 11: '>= 16' }, + hasApi: true, + package: '@hapi/hoek', + }, + inert: { + compatibility: { 7: '>= 16' }, + hasApi: true, + isPlugin: true, + package: '@hapi/inert', + }, + iron: { + compatibility: { 7: '>= 16' }, + hasApi: true, + package: '@hapi/iron', + }, + jwt: { + compatibility: { 3: '>= 16' }, + hasApi: true, + isPlugin: true, + package: '@hapi/jwt', + }, + lab: { + compatibility: { 25: '>= 16' }, + hasApi: true, + package: '@hapi/lab', + }, + log: { + compatibility: { 2: '>= 16' }, + hasApi: true, + isPlugin: true, + package: '@hapi/log', + }, + mimos: { + compatibility: { 7: '>= 16' }, + hasApi: true, + package: '@hapi/mimos', + }, + nes: { + compatibility: { 13: '>= 16' }, + hasApi: true, + isPlugin: true, + package: '@hapi/nes', + }, + nigel: { + compatibility: { 5: '>= 16' }, + package: '@hapi/nigel', + }, + oppsy: { + compatibility: { 3: '>= 16' }, + hasApi: true, + package: '@hapi/oppsy', + }, + pez: { + compatibility: { 6: '>= 16' }, + package: '@hapi/pez', + }, + podium: { + compatibility: { 5: '>= 16' }, + hasApi: true, + package: '@hapi/podium', + }, + scooter: { + compatibility: { 7: '>= 16' }, + hasApi: true, + isPlugin: true, + package: '@hapi/scooter', + }, + shot: { + compatibility: { 6: '>= 16' }, + hasApi: true, + package: '@hapi/shot', + }, + somever: { + compatibility: { 4: '>= 16' }, + package: '@hapi/somever', + }, + sse: { + compatibility: { 1: '>= 22' }, + hasApi: true, + isPlugin: true, + package: '@hapi/sse', + }, + statehood: { + compatibility: { 8: '>= 16' }, + package: '@hapi/statehood', + }, + subtext: { + compatibility: { 8: '>= 16' }, + hasApi: true, + package: '@hapi/subtext', + }, + teamwork: { + compatibility: { 6: '>= 16' }, + package: '@hapi/teamwork', + }, + topo: { + compatibility: { 6: '>= 16' }, + hasApi: true, + package: '@hapi/topo', + }, + vise: { + compatibility: { 5: '>= 16' }, + package: '@hapi/vise', + }, + vision: { + compatibility: { 7: '>= 16' }, + hasApi: true, + isPlugin: true, + package: '@hapi/vision', + }, + wreck: { + compatibility: { 18: '>= 16' }, + hasApi: true, + package: '@hapi/wreck', + }, + yar: { + compatibility: { 11: '>= 16' }, + hasApi: true, + isPlugin: true, + package: '@hapi/yar', + }, +}; diff --git a/cli/paths.ts b/cli/paths.ts new file mode 100644 index 00000000..269aa258 --- /dev/null +++ b/cli/paths.ts @@ -0,0 +1,32 @@ +import fs from 'node:fs/promises'; +import path from 'node:path'; + +export const GENERATED_DIR = path.join(import.meta.dirname, '../generated'); +export const API_DIR = path.join(import.meta.dirname, '../docs/api'); +export const MARKDOWN_DIR = path.join(GENERATED_DIR, 'markdown'); +export const POLICIES_GENERATED_DIR = path.join(MARKDOWN_DIR, 'policies'); +export const METADATA_DIR = path.join(GENERATED_DIR, 'metadata'); +export const MODULES_DIR = path.join(GENERATED_DIR, 'modules'); +export const PUBLIC_ATOM_DIR = path.join(import.meta.dirname, '../docs/public/atom'); + +export const getModuleMarkdownPath = (moduleName: string, major: string | number) => + path.join(MARKDOWN_DIR, moduleName, major.toString(), 'api.md'); + +export const getModuleMarkdownChangelogPath = (moduleName: string) => + path.join(MARKDOWN_DIR, moduleName, 'changelog.md'); + +export const getModuleStoragePath = (moduleName: string) => path.join(MODULES_DIR, moduleName); + +export const getModuleInfoPath = (moduleName: string) => path.join(getModuleStoragePath(moduleName), 'info.json'); + +export const getModuleChangelogPath = (moduleName: string) => + path.join(getModuleStoragePath(moduleName), 'changelog.json'); + +export const getExisting = async (filePath: string): Promise => { + try { + const content = await fs.readFile(filePath, 'utf8'); + return JSON.parse(content) as T; + } catch { + // Ignore error + } +}; diff --git a/cli/types.ts b/cli/types.ts new file mode 100644 index 00000000..ee2738e6 --- /dev/null +++ b/cli/types.ts @@ -0,0 +1,83 @@ +export interface ChangelogItem { + id: number; + number: number; + version: string; + date: string; + url: string; + issues: { + id: number; + number: number; + title: string; + url: string; + labels: string[]; + }[]; +} + +export interface Milestone { + id: number; + number: number; + title: string; + closed_at: string; + html_url: string; +} + +export interface Issue { + id: number; + number: number; + title: string; + html_url: string; + labels: { name: string }[]; +} + +export interface VersionInfo { + nodeVersion: string; + fullVersion: string; + major: number; +} + +export interface ModuleInfo { + name: string; + slogan: string; + sloganHtml: string; + forks: number; + stars: number; + updated: string; + link: string; + versions: { + name: string; + branch: string; + license: string; + node: string; + }[]; + versionsArray: string[]; + latestVersion: string; + api: boolean; + isPlugin: boolean; + package: string; +} + +export interface ModuleMetadata { + slogan: string; + sloganHtml: string; + link: string; + stars: number; + forks: number; + updated: string; + versionsArray: string[]; + latestVersion: string; + versions: { + name: string; + branch: string; + license: string; + node: string; + }[]; + isPlugin: boolean; + package: string; +} + +export interface ModuleSpec { + package: string; + compatibility: Record; + isPlugin?: boolean; + hasApi?: boolean; +} diff --git a/components/Ads.vue b/components/Ads.vue deleted file mode 100644 index 13568fa5..00000000 --- a/components/Ads.vue +++ /dev/null @@ -1,105 +0,0 @@ - - - - - diff --git a/components/ApiOutline.vue b/components/ApiOutline.vue new file mode 100644 index 00000000..3b929344 --- /dev/null +++ b/components/ApiOutline.vue @@ -0,0 +1,78 @@ + + + + + diff --git a/components/CarbonAds.vue b/components/CarbonAds.vue new file mode 100644 index 00000000..27d75f40 --- /dev/null +++ b/components/CarbonAds.vue @@ -0,0 +1,107 @@ + + + + + diff --git a/components/Footers/Footer.vue b/components/Footers/Footer.vue deleted file mode 100644 index 435afd22..00000000 --- a/components/Footers/Footer.vue +++ /dev/null @@ -1,145 +0,0 @@ - - - - - diff --git a/components/Footers/SideFooter.vue b/components/Footers/SideFooter.vue deleted file mode 100644 index b7725683..00000000 --- a/components/Footers/SideFooter.vue +++ /dev/null @@ -1,123 +0,0 @@ - - - - - diff --git a/components/HTML.vue b/components/HTML.vue deleted file mode 100644 index e8157022..00000000 --- a/components/HTML.vue +++ /dev/null @@ -1,17 +0,0 @@ - - - - - \ No newline at end of file diff --git a/components/HomeContent.vue b/components/HomeContent.vue new file mode 100644 index 00000000..b3fb457f --- /dev/null +++ b/components/HomeContent.vue @@ -0,0 +1,661 @@ + + + + + diff --git a/components/Markdown.vue b/components/Markdown.vue deleted file mode 100644 index d180ca1a..00000000 --- a/components/Markdown.vue +++ /dev/null @@ -1,22 +0,0 @@ - - - - - \ No newline at end of file diff --git a/components/ModuleIndex.vue b/components/ModuleIndex.vue new file mode 100644 index 00000000..17035b6e --- /dev/null +++ b/components/ModuleIndex.vue @@ -0,0 +1,145 @@ + + + + + diff --git a/components/Navs/MobileNav.vue b/components/Navs/MobileNav.vue deleted file mode 100644 index 3021c86a..00000000 --- a/components/Navs/MobileNav.vue +++ /dev/null @@ -1,464 +0,0 @@ - - - - - diff --git a/components/Navs/Nav.vue b/components/Navs/Nav.vue deleted file mode 100644 index a6bbe348..00000000 --- a/components/Navs/Nav.vue +++ /dev/null @@ -1,393 +0,0 @@ - - - - - diff --git a/components/PillarCard.vue b/components/PillarCard.vue new file mode 100644 index 00000000..9336fd48 --- /dev/null +++ b/components/PillarCard.vue @@ -0,0 +1,90 @@ + + + + + diff --git a/components/PluginsDirectory.vue b/components/PluginsDirectory.vue new file mode 100644 index 00000000..5fe74ab6 --- /dev/null +++ b/components/PluginsDirectory.vue @@ -0,0 +1,198 @@ + + + + + diff --git a/components/QuoteBlock.vue b/components/QuoteBlock.vue new file mode 100644 index 00000000..0e69163e --- /dev/null +++ b/components/QuoteBlock.vue @@ -0,0 +1,125 @@ + + + + + diff --git a/components/SectionHead.vue b/components/SectionHead.vue new file mode 100644 index 00000000..7a495780 --- /dev/null +++ b/components/SectionHead.vue @@ -0,0 +1,72 @@ + + + + + diff --git a/components/StatusContent.vue b/components/StatusContent.vue new file mode 100644 index 00000000..e816c7cc --- /dev/null +++ b/components/StatusContent.vue @@ -0,0 +1,102 @@ + + + + + diff --git a/components/TutorialLang.vue b/components/TutorialLang.vue new file mode 100644 index 00000000..4da95c71 --- /dev/null +++ b/components/TutorialLang.vue @@ -0,0 +1,108 @@ + + + + + diff --git a/components/api/ApiNav.vue b/components/api/ApiNav.vue deleted file mode 100644 index 9c266901..00000000 --- a/components/api/ApiNav.vue +++ /dev/null @@ -1,719 +0,0 @@ - - - - - diff --git a/components/family/FamilyDisplay.vue b/components/family/FamilyDisplay.vue deleted file mode 100644 index 73884957..00000000 --- a/components/family/FamilyDisplay.vue +++ /dev/null @@ -1,17 +0,0 @@ - - - - - \ No newline at end of file diff --git a/components/family/FamilyIndexNav.vue b/components/family/FamilyIndexNav.vue deleted file mode 100644 index 49e16e65..00000000 --- a/components/family/FamilyIndexNav.vue +++ /dev/null @@ -1,167 +0,0 @@ - - - - - diff --git a/components/family/FamilyNav.vue b/components/family/FamilyNav.vue deleted file mode 100644 index 2c8d8a47..00000000 --- a/components/family/FamilyNav.vue +++ /dev/null @@ -1,305 +0,0 @@ - - - - - diff --git a/components/family/FamilyNavItem.vue b/components/family/FamilyNavItem.vue deleted file mode 100644 index 27ff2241..00000000 --- a/components/family/FamilyNavItem.vue +++ /dev/null @@ -1,69 +0,0 @@ - - - - - diff --git a/components/family/Install.vue b/components/family/Install.vue deleted file mode 100644 index 9c843e54..00000000 --- a/components/family/Install.vue +++ /dev/null @@ -1,63 +0,0 @@ - - - - - \ No newline at end of file diff --git a/components/family/LandingNav.vue b/components/family/LandingNav.vue deleted file mode 100644 index 6fa45dee..00000000 --- a/components/family/LandingNav.vue +++ /dev/null @@ -1,596 +0,0 @@ - - - - - diff --git a/components/family/LandingTable.vue b/components/family/LandingTable.vue deleted file mode 100644 index dc10fc32..00000000 --- a/components/family/LandingTable.vue +++ /dev/null @@ -1,202 +0,0 @@ - - - - - diff --git a/components/home/DevelopersFirst.vue b/components/home/DevelopersFirst.vue deleted file mode 100644 index 14576567..00000000 --- a/components/home/DevelopersFirst.vue +++ /dev/null @@ -1,92 +0,0 @@ - - - - - \ No newline at end of file diff --git a/components/home/Extensibility.vue b/components/home/Extensibility.vue deleted file mode 100644 index 2c2887ed..00000000 --- a/components/home/Extensibility.vue +++ /dev/null @@ -1,108 +0,0 @@ - - - - - diff --git a/components/home/Predictability.vue b/components/home/Predictability.vue deleted file mode 100644 index 0ce9f801..00000000 --- a/components/home/Predictability.vue +++ /dev/null @@ -1,79 +0,0 @@ - - - - - \ No newline at end of file diff --git a/components/home/Quality.vue b/components/home/Quality.vue deleted file mode 100644 index dc426fc3..00000000 --- a/components/home/Quality.vue +++ /dev/null @@ -1,88 +0,0 @@ - - - - - diff --git a/components/home/Security.vue b/components/home/Security.vue deleted file mode 100644 index d581d301..00000000 --- a/components/home/Security.vue +++ /dev/null @@ -1,105 +0,0 @@ - - - - - \ No newline at end of file diff --git a/components/plugins/Plugins.vue b/components/plugins/Plugins.vue deleted file mode 100644 index bc45f863..00000000 --- a/components/plugins/Plugins.vue +++ /dev/null @@ -1,19 +0,0 @@ - - - - - \ No newline at end of file diff --git a/components/plugins/PluginsNav.vue b/components/plugins/PluginsNav.vue deleted file mode 100644 index 9b87bfc2..00000000 --- a/components/plugins/PluginsNav.vue +++ /dev/null @@ -1,108 +0,0 @@ - - - - - diff --git a/components/policies/PoliciesNav.vue b/components/policies/PoliciesNav.vue deleted file mode 100644 index da0c28d4..00000000 --- a/components/policies/PoliciesNav.vue +++ /dev/null @@ -1,150 +0,0 @@ - - - - - diff --git a/components/resources/Changelog.vue b/components/resources/Changelog.vue deleted file mode 100644 index e8024825..00000000 --- a/components/resources/Changelog.vue +++ /dev/null @@ -1,51 +0,0 @@ - - - - - diff --git a/components/resources/ChangelogText.vue b/components/resources/ChangelogText.vue deleted file mode 100644 index 9b4bde97..00000000 --- a/components/resources/ChangelogText.vue +++ /dev/null @@ -1,28 +0,0 @@ - - - - - \ No newline at end of file diff --git a/components/resources/ChangelogVersion.vue b/components/resources/ChangelogVersion.vue deleted file mode 100644 index 5172fabb..00000000 --- a/components/resources/ChangelogVersion.vue +++ /dev/null @@ -1,189 +0,0 @@ - - - - - diff --git a/components/resources/Resources.vue b/components/resources/Resources.vue deleted file mode 100644 index 7c5b35bf..00000000 --- a/components/resources/Resources.vue +++ /dev/null @@ -1,15 +0,0 @@ - - - \ No newline at end of file diff --git a/components/resources/ResourcesNav.vue b/components/resources/ResourcesNav.vue deleted file mode 100644 index cd05c90f..00000000 --- a/components/resources/ResourcesNav.vue +++ /dev/null @@ -1,191 +0,0 @@ - - - - - diff --git a/components/support/howToHelp.vue b/components/support/howToHelp.vue deleted file mode 100644 index a5797333..00000000 --- a/components/support/howToHelp.vue +++ /dev/null @@ -1,90 +0,0 @@ - - - - - diff --git a/components/tutorials/Tutorial.vue b/components/tutorials/Tutorial.vue deleted file mode 100644 index 0aa6cd82..00000000 --- a/components/tutorials/Tutorial.vue +++ /dev/null @@ -1,20 +0,0 @@ - - - - - diff --git a/components/tutorials/TutorialNav.vue b/components/tutorials/TutorialNav.vue deleted file mode 100644 index be8e73ea..00000000 --- a/components/tutorials/TutorialNav.vue +++ /dev/null @@ -1,660 +0,0 @@ - - - - - diff --git a/components/tutorials/TutorialNavItem.vue b/components/tutorials/TutorialNavItem.vue deleted file mode 100644 index deab1f04..00000000 --- a/components/tutorials/TutorialNavItem.vue +++ /dev/null @@ -1,66 +0,0 @@ - - - - - diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index bebd0366..00000000 --- a/docker-compose.yml +++ /dev/null @@ -1,7 +0,0 @@ -version: '3.7' -services: - hapi.dev: - image: hapi.dev - container_name: hapi.dev - ports: - - 3000:3000 diff --git a/docs/api/[version].md b/docs/api/[version].md new file mode 100644 index 00000000..6f556a57 --- /dev/null +++ b/docs/api/[version].md @@ -0,0 +1,31 @@ +--- +title: API +--- + + + +# @hapi/hapi API v{{ $params.fullVersion }} + +### Installation + +::: code-group + +```console-vue [npm] +npm install @hapi/hapi@{{ $params.fullVersion }} +``` + +```console-vue [yarn] +yarn add @hapi/hapi@{{ $params.fullVersion }} +``` + +```console-vue [pnpm] +pnpm add @hapi/hapi@{{ $params.fullVersion }} +``` + +::: + +::: v-pre + + + +::: diff --git a/docs/api/[version].paths.ts b/docs/api/[version].paths.ts new file mode 100644 index 00000000..d1b2df9e --- /dev/null +++ b/docs/api/[version].paths.ts @@ -0,0 +1,31 @@ +import fs from 'node:fs'; +import path from 'node:path'; + +import { defineRoutes } from 'vitepress'; + +import hapiInfo from '../../generated/modules/hapi/info.json' with { type: 'json' }; + +import type { ModuleInfo } from '../../cli/types.js'; + +export default defineRoutes({ + paths() { + const info = hapiInfo as ModuleInfo; + + return info.versions.flatMap((versionInfo) => { + const major = parseInt(versionInfo.name.split('.')[0], 10); + const version = `${major}.x.x`; + const apiPath = path.resolve(`generated/markdown/hapi/${major}/api.md`); + if (!fs.existsSync(apiPath)) { + return []; + } + let content = fs.readFileSync(apiPath, 'utf8'); + content = content.replaceAll('{{', '{{').replaceAll('}}', '}}'); + return [ + { + content, + params: { fullVersion: versionInfo.name, version }, + }, + ]; + }); + }, +}); diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 00000000..cd5ffbc1 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,6 @@ +--- +layout: page +title: Home +--- + + diff --git a/docs/module/[name]/api/[version].md b/docs/module/[name]/api/[version].md new file mode 100644 index 00000000..371328b3 --- /dev/null +++ b/docs/module/[name]/api/[version].md @@ -0,0 +1,29 @@ +--- +title: Module +--- + + + +# {{ $params.package }} v{{ $params.fullVersion }} + +::: code-group + +```console-vue [npm] +npm install {{ $params.package }}@{{ $params.fullVersion }} +``` + +```console-vue [yarn] +yarn add {{ $params.package }}@{{ $params.fullVersion }} +``` + +```console-vue [pnpm] +pnpm add {{ $params.package }}@{{ $params.fullVersion }} +``` + +::: + +::: v-pre + + + +::: diff --git a/docs/module/[name]/api/[version].paths.ts b/docs/module/[name]/api/[version].paths.ts new file mode 100644 index 00000000..285cf8fc --- /dev/null +++ b/docs/module/[name]/api/[version].paths.ts @@ -0,0 +1,61 @@ +import fs from 'node:fs'; +import path from 'node:path'; + +import { defineRoutes } from 'vitepress'; + +import { modules } from '../../../../cli/modules.js'; +import modulesData from '../../../../generated/metadata/modules.json' with { type: 'json' }; + +import type { ModuleMetadata } from '../../../../cli/types.js'; + +const renderCompatibility = (info: ModuleMetadata) => { + let content = ` +### Compatibility + +| Major version | License | Node.js | +| ------------- | ------- | ------- | +`; + + const versions = [...info.versions].toReversed(); + for (const v of versions) { + const [major] = v.name.split('.'); + content += `| ${major} | ${v.license} | ${v.node} |\n`; + } + + return content; +}; + +export default defineRoutes({ + paths() { + const data = modulesData as Record; + return Object.keys(data) + .filter((name) => name !== 'hapi') + .flatMap((name: string) => { + const info = data[name]; + const hasApi = modules[name]?.hasApi ?? false; + + return info.versions.flatMap((versionInfo) => { + const major = parseInt(versionInfo.name.split('.')[0], 10); + const version = `${major}.x.x`; + + let content = `${info.slogan}\n${renderCompatibility(info)}`; + + if (hasApi) { + const apiPath = path.resolve(`generated/markdown/${name}/${major}/api.md`); + if (fs.existsSync(apiPath)) { + let apiContent = fs.readFileSync(apiPath, 'utf8'); + apiContent = apiContent.replaceAll('{{', '{{').replaceAll('}}', '}}'); + content += `\n${apiContent}`; + } + } + + return [ + { + content, + params: { fullVersion: versionInfo.name, name, package: info.package, version }, + }, + ]; + }); + }); + }, +}); diff --git a/docs/module/[name]/changelog.md b/docs/module/[name]/changelog.md new file mode 100644 index 00000000..568df898 --- /dev/null +++ b/docs/module/[name]/changelog.md @@ -0,0 +1,13 @@ +--- +title: Module changelog +--- + + + +# Changelog + +::: v-pre + + + +::: diff --git a/docs/module/[name]/changelog.paths.ts b/docs/module/[name]/changelog.paths.ts new file mode 100644 index 00000000..f94e2c2b --- /dev/null +++ b/docs/module/[name]/changelog.paths.ts @@ -0,0 +1,26 @@ +import fs from 'node:fs'; +import path from 'node:path'; + +import { defineRoutes } from 'vitepress'; + +import modulesData from '../../../generated/metadata/modules.json' with { type: 'json' }; + +import type { ModuleMetadata } from '../../../cli/types.js'; + +export default defineRoutes({ + paths() { + return Object.keys(modulesData as Record) + .filter((name) => name !== 'hapi') + .filter((name) => { + const changelogPath = path.resolve(`generated/markdown/${name}/changelog.md`); + return fs.existsSync(changelogPath); + }) + .map((name: string) => { + const content = fs.readFileSync(path.resolve(`generated/markdown/${name}/changelog.md`), 'utf8'); + return { + content, + params: { name }, + }; + }); + }, +}); diff --git a/docs/module/bell/examples.md b/docs/module/bell/examples.md new file mode 100644 index 00000000..676b6220 --- /dev/null +++ b/docs/module/bell/examples.md @@ -0,0 +1,11 @@ +--- +title: Bell Examples +--- + +# Bell Examples + +::: v-pre + + + +::: diff --git a/docs/module/bell/providers.md b/docs/module/bell/providers.md new file mode 100644 index 00000000..8ec273f3 --- /dev/null +++ b/docs/module/bell/providers.md @@ -0,0 +1,11 @@ +--- +title: Bell Providers +--- + +# Bell Providers + +::: v-pre + + + +::: diff --git a/docs/module/index.md b/docs/module/index.md new file mode 100644 index 00000000..99a9c25b --- /dev/null +++ b/docs/module/index.md @@ -0,0 +1,9 @@ +--- +aside: false +--- + +# Modules + +The hapi ecosystem consists of several modules. + + diff --git a/docs/plugins.md b/docs/plugins.md new file mode 100644 index 00000000..a4f3c1e1 --- /dev/null +++ b/docs/plugins.md @@ -0,0 +1,7 @@ +--- +aside: false +--- + +# Community Plugins + + diff --git a/docs/policies/coc.md b/docs/policies/coc.md new file mode 100644 index 00000000..c2e4e3ff --- /dev/null +++ b/docs/policies/coc.md @@ -0,0 +1,9 @@ +--- +title: Code of Conduct +--- + +:::: v-pre + + + +:::: diff --git a/docs/policies/contributing.md b/docs/policies/contributing.md new file mode 100644 index 00000000..412cef46 --- /dev/null +++ b/docs/policies/contributing.md @@ -0,0 +1,9 @@ +--- +title: Contributing +--- + +:::: v-pre + + + +:::: diff --git a/docs/policies/license.md b/docs/policies/license.md new file mode 100644 index 00000000..808e3fd3 --- /dev/null +++ b/docs/policies/license.md @@ -0,0 +1,9 @@ +--- +title: License +--- + +:::: v-pre + + + +:::: diff --git a/docs/policies/security.md b/docs/policies/security.md new file mode 100644 index 00000000..ef31bbeb --- /dev/null +++ b/docs/policies/security.md @@ -0,0 +1,9 @@ +--- +title: Security +--- + +:::: v-pre + + + +:::: diff --git a/docs/policies/sponsors.md b/docs/policies/sponsors.md new file mode 100644 index 00000000..7d125b1e --- /dev/null +++ b/docs/policies/sponsors.md @@ -0,0 +1,13 @@ +--- +title: Sponsors +--- + +
+ +::: v-pre + + + +::: + +
diff --git a/docs/policies/styleguide.md b/docs/policies/styleguide.md new file mode 100644 index 00000000..84623929 --- /dev/null +++ b/docs/policies/styleguide.md @@ -0,0 +1,9 @@ +--- +title: Style Guide +--- + +:::: v-pre + + + +:::: diff --git a/docs/policies/support.md b/docs/policies/support.md new file mode 100644 index 00000000..d1e2e5c1 --- /dev/null +++ b/docs/policies/support.md @@ -0,0 +1,9 @@ +--- +title: Support +--- + +:::: v-pre + + + +:::: diff --git a/docs/public/atom/accept.atom b/docs/public/atom/accept.atom new file mode 100644 index 00000000..23a493b5 --- /dev/null +++ b/docs/public/atom/accept.atom @@ -0,0 +1,242 @@ + + + https://hapi.dev/module/accept + @hapi/accept changelog + 2023-10-10T08:20:42.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/accept v6.0.3]]> + https://github.com/hapijs/accept/milestone/33 + + 2023-10-10T08:20:42.000Z + +
  • [#73] allow readonly arrays to be used as preferences
  • ]]>
    +
    + + <![CDATA[@hapi/accept v6.0.2]]> + https://github.com/hapijs/accept/milestone/32 + + 2023-07-18T13:38:21.000Z + +
  • [#72] update typing of mediaTypes to match actual implementation
  • ]]>
    +
    + + <![CDATA[@hapi/accept v6.0.1]]> + https://github.com/hapijs/accept/milestone/31 + + 2023-02-11T19:46:22.000Z + +
  • [#71] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/accept v6.0.0]]> + https://github.com/hapijs/accept/milestone/30 + + 2023-02-11T19:46:21.000Z + +
  • [#70] Support node v18 and drop node v12
  • ]]>
    +
    + + <![CDATA[@hapi/accept v5.0.2]]> + https://github.com/hapijs/accept/milestone/28 + + 2021-02-05T05:40:23.000Z + +
  • [#65] Enable prefix matching for language tags
  • [#63] Accept.language does not match more specific language tag
  • [#59] update lab and typescript now needs to be added as a devdependency
  • ]]>
    +
    + + <![CDATA[@hapi/accept v5.0.1]]> + https://github.com/hapijs/accept/milestone/26 + + 2020-02-13T06:32:55.000Z + +
  • [#53] Use maps
  • ]]>
    +
    + + <![CDATA[@hapi/accept v5.0.0]]> + https://github.com/hapijs/accept/milestone/25 + + 2020-01-04T20:55:47.000Z + +
  • [#51] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/accept v4.0.1]]> + https://github.com/hapijs/accept/milestone/24 + + 2020-02-13T06:32:33.000Z + +
  • [#54] Backport #53
  • ]]>
    +
    + + <![CDATA[@hapi/accept v4.0.0]]> + https://github.com/hapijs/accept/milestone/23 + + 2019-10-05T22:08:55.000Z + +
  • [#48] Drop node 8
  • [#47] Add types
  • ]]>
    +
    + + <![CDATA[@hapi/accept v3.2.4]]> + https://github.com/hapijs/accept/milestone/22 + + 2020-02-13T06:32:53.000Z + +
  • [#55] Backport #53
  • ]]>
    +
    + + <![CDATA[@hapi/accept v3.2.3]]> + https://github.com/hapijs/accept/milestone/21 + + 2019-08-13T20:43:13.000Z + +
  • [#42] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/accept v3.2.2]]> + https://github.com/hapijs/accept/milestone/20 + + 2019-04-02T22:53:28.000Z + +
  • [#41] Missing bias for server preferences among equal q values
  • ]]>
    +
    + + <![CDATA[@hapi/accept v3.2.1]]> + https://github.com/hapijs/accept/milestone/19 + + 2019-03-30T00:05:54.000Z + +
  • [#40] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/accept v3.2.0]]> + https://github.com/hapijs/accept/milestone/14 + + 2019-03-29T17:17:57.000Z + +
  • [#39] Change module namespace
  • [#34] headerType() '*' logic is incorrect.
  • ]]>
    +
    + + <![CDATA[@hapi/accept v3.1.3]]> + https://github.com/hapijs/accept/milestone/13 + + 2018-11-03T00:14:00.000Z + +
  • [#32] Remove engines
  • ]]>
    +
    + + <![CDATA[@hapi/accept v3.1.2]]> + https://github.com/hapijs/accept/milestone/12 + + 2018-11-01T07:20:19.000Z + +
  • [#31] Update hoek v6
  • ]]>
    +
    + + <![CDATA[@hapi/accept v3.1.1]]> + https://github.com/hapijs/accept/milestone/11 + + 2018-10-30T08:12:03.000Z + +
  • [#30] Fix node 11 sort
  • ]]>
    +
    + + <![CDATA[@hapi/accept v3.1.0]]> + https://github.com/hapijs/accept/milestone/10 + + 2018-10-30T04:00:21.000Z + +
  • [#28] add mediaType method
  • ]]>
    +
    + + <![CDATA[@hapi/accept v3.0.2]]> + https://github.com/hapijs/accept/milestone/9 + + 2017-11-03T06:41:46.000Z + +
  • [#22] Update boom
  • ]]>
    +
    + + <![CDATA[@hapi/accept v3.0.1]]> + https://github.com/hapijs/accept/milestone/8 + + 2017-09-26T09:04:11.000Z + +
  • [#21] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/accept v3.0.0]]> + https://github.com/hapijs/accept/milestone/7 + + 2017-09-25T23:59:24.000Z + +
  • [#20] Throw all errors
  • ]]>
    +
    + + <![CDATA[@hapi/accept v2.2.2]]> + https://github.com/hapijs/accept/milestone/17 + + 2019-03-22T00:14:24.000Z + +
  • [#38] Node 11 (language)
  • ]]>
    +
    + + <![CDATA[@hapi/accept v2.2.1]]> + https://github.com/hapijs/accept/milestone/16 + + 2019-03-22T00:08:43.000Z + +
  • [#37] Fix node 11
  • ]]>
    +
    + + <![CDATA[@hapi/accept v2.2.0]]> + https://github.com/hapijs/accept/milestone/15 + + 2019-03-21T23:58:24.000Z + +
  • [#36] Commercial version of v2 branch
  • ]]>
    +
    + + <![CDATA[@hapi/accept v2.1.4]]> + https://github.com/hapijs/accept/milestone/6 + + 2017-05-28T05:52:16.000Z + +
  • [#18] Update deps.
  • ]]>
    +
    + + <![CDATA[@hapi/accept v2.1.2]]> + https://github.com/hapijs/accept/milestone/5 + + 2016-07-27T18:28:57.000Z + +
  • [#17] Update lab
  • ]]>
    +
    + + <![CDATA[@hapi/accept v2.1.0]]> + https://github.com/hapijs/accept/milestone/4 + + 2016-07-27T18:28:21.000Z + +
  • [#14] Mediatypes
  • ]]>
    +
    + + <![CDATA[@hapi/accept v2.0.0]]> + https://github.com/hapijs/accept/milestone/2 + + 2015-11-01T18:52:39.000Z + +
  • [#15] ES6 style changes and node v4
  • [#13] Update docs to use API.md
  • [#11] add language() and languages()
  • ]]>
    +
    + + <![CDATA[@hapi/accept v1.1.0]]> + https://github.com/hapijs/accept/milestone/1 + + 2015-07-13T16:56:12.000Z + +
  • [#9] Charset
  • [#2] Update to Lab 5.x.x and Code 1.x.x
  • [#1] Update .travis.yml
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/ammo.atom b/docs/public/atom/ammo.atom new file mode 100644 index 00000000..8f41bb97 --- /dev/null +++ b/docs/public/atom/ammo.atom @@ -0,0 +1,178 @@ + + + https://hapi.dev/module/ammo + @hapi/ammo changelog + 2023-02-11T19:39:49.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/ammo v6.0.1]]> + https://github.com/hapijs/ammo/milestone/22 + + 2023-02-11T19:39:49.000Z + +
  • [#54] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/ammo v6.0.0]]> + https://github.com/hapijs/ammo/milestone/21 + + 2023-02-11T19:39:47.000Z + +
  • [#53] Support node v18 and drop node v12
  • ]]>
    +
    + + <![CDATA[@hapi/ammo v5.0.1]]> + https://github.com/hapijs/ammo/milestone/19 + + 2020-02-13T05:14:49.000Z + +
  • [#37] Strict parsing
  • ]]>
    +
    + + <![CDATA[@hapi/ammo v5.0.0]]> + https://github.com/hapijs/ammo/milestone/18 + + 2020-01-04T21:08:13.000Z + +
  • [#35] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/ammo v4.0.1]]> + https://github.com/hapijs/ammo/milestone/17 + + 2020-02-13T05:36:22.000Z + +
  • [#38] Backport #37
  • ]]>
    +
    + + <![CDATA[@hapi/ammo v4.0.0]]> + https://github.com/hapijs/ammo/milestone/16 + + 2019-10-15T00:23:26.000Z + +
  • [#32] Add types
  • [#31] Drop node 8
  • [#16] Stream early exit
  • ]]>
    +
    + + <![CDATA[@hapi/ammo v3.1.2]]> + https://github.com/hapijs/ammo/milestone/15 + + 2020-02-13T05:36:20.000Z + +
  • [#39] Backport #37
  • ]]>
    +
    + + <![CDATA[@hapi/ammo v3.1.1]]> + https://github.com/hapijs/ammo/milestone/14 + + 2019-08-13T20:47:40.000Z + +
  • [#25] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/ammo v3.1.0]]> + https://github.com/hapijs/ammo/milestone/11 + + 2019-03-30T07:47:40.000Z + +
  • [#23] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/ammo v3.0.3]]> + https://github.com/hapijs/ammo/milestone/10 + + 2018-11-03T00:14:46.000Z + +
  • [#20] Remove engines
  • ]]>
    +
    + + <![CDATA[@hapi/ammo v3.0.2]]> + https://github.com/hapijs/ammo/milestone/9 + + 2018-11-01T07:22:13.000Z + +
  • [#19] Update hoek v6
  • ]]>
    +
    + + <![CDATA[@hapi/ammo v3.0.1]]> + https://github.com/hapijs/ammo/milestone/8 + + 2018-04-29T18:17:38.000Z + +
  • [#18] Improve error handling
  • ]]>
    +
    + + <![CDATA[@hapi/ammo v3.0.0]]> + https://github.com/hapijs/ammo/milestone/7 + + 2017-09-26T05:47:37.000Z + +
  • [#17] Node 8
  • ]]>
    +
    + + <![CDATA[@hapi/ammo v2.1.1]]> + https://github.com/hapijs/ammo/milestone/13 + + 2020-02-13T05:36:18.000Z + +
  • [#40] Backport #37
  • ]]>
    +
    + + <![CDATA[@hapi/ammo v2.1.0]]> + https://github.com/hapijs/ammo/milestone/12 + + 2019-03-22T05:49:25.000Z + +
  • [#22] Commercial version of v2 branch
  • ]]>
    +
    + + <![CDATA[@hapi/ammo v2.0.4]]> + https://github.com/hapijs/ammo/milestone/6 + + 2017-05-28T05:55:23.000Z + +
  • [#15] Update deps.
  • ]]>
    +
    + + <![CDATA[@hapi/ammo v2.0.3]]> + https://github.com/hapijs/ammo/milestone/5 + + 2016-11-29T01:46:45.000Z + +
  • [#14] Update deps
  • [#10] dependency update
  • ]]>
    +
    + + <![CDATA[@hapi/ammo v2.0.2]]> + https://github.com/hapijs/ammo/milestone/4 + + 2016-07-27T19:25:24.000Z + +
  • [#8] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/ammo v2.0.1]]> + https://github.com/hapijs/ammo/milestone/3 + + 2016-05-19T18:00:33.000Z + +
  • [#6] Test on node v6, update dependencies
  • ]]>
    +
    + + <![CDATA[@hapi/ammo v2.0.0]]> + https://github.com/hapijs/ammo/milestone/2 + + 2016-05-19T17:31:59.000Z + +
  • [#4] ES6 style changes and node v4
  • ]]>
    +
    + + <![CDATA[@hapi/ammo v1.0.1]]> + https://github.com/hapijs/ammo/milestone/1 + + 2015-06-28T02:26:21.000Z + +
  • [#3] Apply hapi project style
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/b64.atom b/docs/public/atom/b64.atom new file mode 100644 index 00000000..9308fb8a --- /dev/null +++ b/docs/public/atom/b64.atom @@ -0,0 +1,146 @@ + + + https://hapi.dev/module/b64 + @hapi/b64 changelog + 2023-02-11T17:55:46.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/b64 v6.0.1]]> + https://github.com/hapijs/b64/milestone/18 + + 2023-02-11T17:55:46.000Z + +
  • [#41] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/b64 v6.0.0]]> + https://github.com/hapijs/b64/milestone/17 + + 2023-02-11T17:55:48.000Z + +
  • [#40] Support node v18 and drop node v12
  • ]]>
    +
    + + <![CDATA[@hapi/b64 v5.0.0]]> + https://github.com/hapijs/b64/milestone/15 + + 2020-01-04T22:10:05.000Z + +
  • [#33] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/b64 v4.2.2]]> + https://github.com/hapijs/b64/milestone/14 + + 2020-09-26T18:12:20.000Z + + ]]> + + + <![CDATA[@hapi/b64 v4.2.1]]> + https://github.com/hapijs/b64/milestone/13 + + 2019-08-13T20:49:32.000Z + +
  • [#26] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/b64 v4.2.0]]> + https://github.com/hapijs/b64/milestone/10 + + 2019-04-02T06:29:59.000Z + +
  • [#25] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/b64 v4.1.2]]> + https://github.com/hapijs/b64/milestone/9 + + 2018-11-03T00:15:44.000Z + +
  • [#22] Remove engines
  • ]]>
    +
    + + <![CDATA[@hapi/b64 v4.1.1]]> + https://github.com/hapijs/b64/milestone/8 + + 2018-11-01T07:24:53.000Z + +
  • [#21] Update hoek v6
  • ]]>
    +
    + + <![CDATA[@hapi/b64 v4.1.0]]> + https://github.com/hapijs/b64/milestone/7 + + 2018-10-31T01:14:32.000Z + +
  • [#20] Move base64 methods from hoek
  • ]]>
    +
    + + <![CDATA[@hapi/b64 v4.0.0]]> + https://github.com/hapijs/b64/milestone/6 + + 2017-09-26T05:55:20.000Z + +
  • [#18] Node 8
  • ]]>
    +
    + + <![CDATA[@hapi/b64 v3.1.1]]> + https://github.com/hapijs/b64/milestone/12 + + 2020-09-26T18:12:22.000Z + + ]]> + + + <![CDATA[@hapi/b64 v3.1.0]]> + https://github.com/hapijs/b64/milestone/11 + + 2019-03-25T18:23:05.000Z + +
  • [#24] Commercial version of v3 branch
  • ]]>
    +
    + + <![CDATA[@hapi/b64 v3.0.3]]> + https://github.com/hapijs/b64/milestone/5 + + 2017-07-31T15:29:44.000Z + +
  • [#17] 3.0.3 Release notes
  • [#16] Remove deprecated buffer usage
  • [#15] Pending deprecation for new Buffer()
  • ]]>
    +
    + + <![CDATA[@hapi/b64 v3.0.2]]> + https://github.com/hapijs/b64/milestone/4 + + 2016-07-28T19:40:33.000Z + +
  • [#14] Update deps
  • [#13] Document API
  • [#12] Separate decode/encode modules
  • [#10] Document API
  • ]]>
    +
    + + <![CDATA[@hapi/b64 v3.0.1]]> + https://github.com/hapijs/b64/milestone/3 + + 2016-05-19T18:02:58.000Z + +
  • [#11] update hoek to 4.x.x
  • [#9] Update lab and travis node version
  • ]]>
    +
    + + <![CDATA[@hapi/b64 v3.0.0]]> + https://github.com/hapijs/b64/milestone/2 + + 2015-10-31T20:07:20.000Z + +
  • [#8] es6. Closes #7
  • [#7] ES6 style, node v4
  • ]]>
    +
    + + <![CDATA[@hapi/b64 v2.0.1]]> + https://github.com/hapijs/b64/milestone/1 + + 2015-06-28T01:56:43.000Z + +
  • [#5] Update to Lab 5.x.x and Code 1.x.x
  • [#4] Update .travis.yml
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/basic.atom b/docs/public/atom/basic.atom new file mode 100644 index 00000000..e040d434 --- /dev/null +++ b/docs/public/atom/basic.atom @@ -0,0 +1,138 @@ + + + https://hapi.dev/module/basic + @hapi/basic changelog + 2023-02-11T19:54:09.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/basic v7.0.1]]> + https://github.com/hapijs/basic/milestone/19 + + 2023-02-11T19:54:09.000Z + +
  • [#91] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/basic v7.0.0]]> + https://github.com/hapijs/basic/milestone/18 + + 2022-07-23T19:16:19.000Z + +
  • [#90] Support node v18 and hapi v21, drop node v12 and hapi v18/19
  • [#83] upgrade lab to v24
  • ]]>
    +
    + + <![CDATA[@hapi/basic v6.0.0]]> + https://github.com/hapijs/basic/milestone/17 + + 2020-01-10T04:37:00.000Z + +
  • [#78] Change plugin name to @hapi/basic
  • [#77] Drop hapi 17
  • [#76] Only support node 12
  • ]]>
    +
    + + <![CDATA[@hapi/basic v5.1.1]]> + https://github.com/hapijs/basic/milestone/15 + + 2019-08-13T21:57:19.000Z + +
  • [#70] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/basic v5.1.0]]> + https://github.com/hapijs/basic/milestone/14 + + 2019-04-18T05:07:08.000Z + +
  • [#69] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/basic v5.0.0]]> + https://github.com/hapijs/basic/milestone/13 + + 2019-04-18T04:36:08.000Z + +
  • [#61] Update for hapi 17.x.x
  • ]]>
    +
    + + <![CDATA[@hapi/basic v4.2.0]]> + https://github.com/hapijs/basic/milestone/12 + + 2019-04-18T04:36:07.000Z + +
  • [#51] Test on node v6, update dependencies
  • [#48] Documentation update
  • ]]>
    +
    + + <![CDATA[@hapi/basic v4.1.0]]> + https://github.com/hapijs/basic/milestone/11 + + 2015-11-17T07:08:32.000Z + +
  • [#46] add option to pass attributes to unauthorized replies
  • ]]>
    +
    + + <![CDATA[@hapi/basic v4.0.0]]> + https://github.com/hapijs/basic/milestone/10 + + 2015-11-04T12:32:06.000Z + +
  • [#44] Node 4+, Hapi 10+, ES6 changes. Closes #42
  • [#42] Node >= 4 / es2015 updates
  • [#41] Update devDependencies. Closes #40
  • ]]>
    +
    + + <![CDATA[@hapi/basic v3.0.0]]> + https://github.com/hapijs/basic/milestone/8 + + 2015-07-04T22:04:08.000Z + +
  • [#34] Added request object as the first argument in validateFunc
  • ]]>
    +
    + + <![CDATA[@hapi/basic v2.0.0]]> + https://github.com/hapijs/basic/milestone/7 + + 2014-12-10T22:55:16.000Z + +
  • [#22] hapi 8.0 API
  • ]]>
    +
    + + <![CDATA[@hapi/basic v1.1.2]]> + https://github.com/hapijs/basic/milestone/6 + + 2014-11-12T07:34:45.000Z + +
  • [#21] Update dev deps. Closes #20
  • [#20] Test deps
  • ]]>
    +
    + + <![CDATA[@hapi/basic v1.1.1]]> + https://github.com/hapijs/basic/milestone/5 + + 2014-08-04T08:44:26.000Z + +
  • [#11] Authentication fails when password contains one or more colons
  • [#10] issue passing errors to validateFunc
  • ]]>
    +
    + + <![CDATA[@hapi/basic v1.1.0]]> + https://github.com/hapijs/basic/milestone/4 + + 2014-06-12T20:21:41.000Z + +
  • [#7] Updated to Hapi 6.0
  • [#6] Prepare for hapi v6.0
  • ]]>
    +
    + + <![CDATA[@hapi/basic v1.0.2]]> + https://github.com/hapijs/basic/milestone/2 + + 2014-05-20T22:33:26.000Z + +
  • [#5] Bring coverage back to 100%
  • ]]>
    +
    + + <![CDATA[@hapi/basic v1.0.1]]> + https://github.com/hapijs/basic/milestone/1 + + 2014-03-21T20:19:05.000Z + +
  • [#2] update peerDependency
  • [#1] change hapi peer dependency to 3.0.0
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/bell.atom b/docs/public/atom/bell.atom new file mode 100644 index 00000000..b0def1ac --- /dev/null +++ b/docs/public/atom/bell.atom @@ -0,0 +1,410 @@ + + + https://hapi.dev/module/bell + @hapi/bell changelog + 2025-03-12T12:11:47.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/bell v13.1.0]]> + https://github.com/hapijs/bell/milestone/91 + + 2025-03-12T12:11:47.000Z + +
  • [#497] Add tokenParams option
  • [#496] chore: remove mixer provider
  • [#485] remove the bit about google plus
  • ]]>
    +
    + + <![CDATA[@hapi/bell v13.0.2]]> + https://github.com/hapijs/bell/milestone/90 + + 2024-03-19T15:01:00.000Z + +
  • [#493] feat: 🎸 add types
  • ]]>
    +
    + + <![CDATA[@hapi/bell v13.0.1]]> + https://github.com/hapijs/bell/milestone/89 + + 2023-02-11T19:53:36.000Z + +
  • [#490] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/bell v13.0.0]]> + https://github.com/hapijs/bell/milestone/88 + + 2022-10-10T12:22:30.000Z + +
  • [#488] Support hapi v21 and node v18, drop hapi v19 and node v12, test ESM support
  • ]]>
    +
    + + <![CDATA[@hapi/bell v12.3.0]]> + https://github.com/hapijs/bell/milestone/86 + + 2021-08-26T05:07:21.000Z + +
  • [#481] Support OAuth1 client wreck options
  • ]]>
    +
    + + <![CDATA[@hapi/bell v12.2.0]]> + https://github.com/hapijs/bell/milestone/85 + + 2021-03-15T08:08:24.000Z + +
  • [#476] Add support for providing clientSecret as a function
  • ]]>
    +
    + + <![CDATA[@hapi/bell v12.1.1]]> + https://github.com/hapijs/bell/milestone/84 + + 2020-09-27T00:04:14.000Z + +
  • [#473] upgrade lab to v24
  • [#470] migrate to new travis format
  • [#469] [Bugfix] Okta example code
  • [#467] update to hapi 20
  • [#466] upgrade bell to use just regular joi package and update teamwork as well
  • ]]>
    +
    + + <![CDATA[@hapi/bell v12.1.0]]> + https://github.com/hapijs/bell/milestone/83 + + 2020-08-20T20:22:45.000Z + +
  • [#450] Support Okta custom authorization server
  • ]]>
    +
    + + <![CDATA[@hapi/bell v12.0.1]]> + https://github.com/hapijs/bell/milestone/82 + + 2020-05-15T20:29:49.000Z + +
  • [#458] Issue with the meetup provider
  • ]]>
    +
    + + <![CDATA[@hapi/bell v12.0.0]]> + https://github.com/hapijs/bell/milestone/81 + + 2020-01-10T05:54:33.000Z + +
  • [#449] Change plugin name to @hapi/bell
  • [#448] Require hapi 19
  • [#447] Only node 12
  • [#445] Use actual package name for plugin name
  • ]]>
    +
    + + <![CDATA[@hapi/bell v11.1.0]]> + https://github.com/hapijs/bell/milestone/80 + + 2019-09-20T05:16:48.000Z + +
  • [#432] Return azureAD provider
  • ]]>
    +
    + + <![CDATA[@hapi/bell v11.0.0]]> + https://github.com/hapijs/bell/milestone/79 + + 2019-09-13T07:05:49.000Z + +
  • [#428] Make dropbox-v2 the only provider
  • [#427] Replace office365, azuread with updated azure provider
  • [#426] Update joi
  • [#420] Add support for PKCE
  • [#418] New Twitch API oAuth & profile
  • [#416] Update github login example
  • [#411] [Bell-410] Add AWS Cognito provider
  • [#410] Add provider for AWS Cognito
  • [#409] RFC 7636: Proof Key for Code Exchange
  • [#404] Add Azure Oauth2 v2 provider
  • [#403] Correctly utilize JWT tokens instead of normal accessTokens for AzureAD
  • [#376] Update Office365 / Microsoft provider
  • ]]>
    +
    + + <![CDATA[@hapi/bell v10.1.1]]> + https://github.com/hapijs/bell/milestone/77 + + 2019-08-14T04:48:02.000Z + +
  • [#421] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/bell v10.1.0]]> + https://github.com/hapijs/bell/milestone/76 + + 2019-04-20T19:54:13.000Z + +
  • [#405] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/bell v10.0.0]]> + https://github.com/hapijs/bell/milestone/75 + + 2019-03-05T20:39:59.000Z + +
  • [#400] 10.0.0 Release Notes
  • [#397] Add support for hapi 18
  • [#394] Google auth redirect loop with hapi v18
  • [#391] Update LinkedIn to use new lite profile
  • [#390] Upgrade LinkedIn to support new 'Lite Profile'
  • ]]>
    +
    + + <![CDATA[@hapi/bell v9.6.0]]> + https://github.com/hapijs/bell/milestone/78 + + 2019-04-20T22:20:42.000Z + +
  • [#406] Change module namespace for v9 branch
  • ]]>
    +
    + + <![CDATA[@hapi/bell v9.5.0]]> + https://github.com/hapijs/bell/milestone/74 + + 2019-02-27T18:28:00.000Z + +
  • [#396] Allow isSameSite customization
  • [#395] Safari isSameSite
  • [#389] Add changelog.md
  • ]]>
    +
    + + <![CDATA[@hapi/bell v9.4.0]]> + https://github.com/hapijs/bell/milestone/73 + + 2018-11-10T22:28:07.000Z + +
  • [#386] Cleanup
  • [#381] FB custom scope + upgrade api version
  • [#374] Ensure Auth0 profile is availabe in all cases
  • [#373] Use Stripe Express
  • [#372] Add config 'fields' to vk provider
  • ]]>
    +
    + + <![CDATA[@hapi/bell v9.3.1]]> + https://github.com/hapijs/bell/milestone/71 + + 2018-05-29T19:00:33.000Z + +
  • [#358] Use OIDC compliant profile from Auth0
  • ]]>
    +
    + + <![CDATA[@hapi/bell v9.3.0]]> + https://github.com/hapijs/bell/milestone/70 + + 2018-04-03T08:01:17.000Z + +
  • [#356] fix(package): update Boom and fix trying to create an instance of .internal
  • [#355] Set SameSite=Strict for improved security
  • ]]>
    +
    + + <![CDATA[@hapi/bell v9.2.0]]> + https://github.com/hapijs/bell/milestone/68 + + 2018-04-02T19:10:36.000Z + +
  • [#354] Remove new Buffer usage
  • [#350] Picture object included in the profile object for facebook oauth
  • [#349] Fix problem with not exist required param 'v' last versitons today 5.…
  • [#348] VK auth dev error: 'v' is required
  • [#347] facebook picture field added to get profile picture
  • ]]>
    +
    + + <![CDATA[@hapi/bell v9.1.0]]> + https://github.com/hapijs/bell/milestone/67 + + 2018-02-26T06:51:41.000Z + +
  • [#295] Expose query in spite of errors
  • [#288] Remove or more comprehensively document provider.version
  • ]]>
    +
    + + <![CDATA[@hapi/bell v9.0.0]]> + https://github.com/hapijs/bell/milestone/63 + + 2018-02-26T04:20:11.000Z + +
  • [#345] 9.0.0 Release Notes
  • [#332] [WIP] Hapi 17 Support
  • [#330] hapi v17 support
  • ]]>
    +
    + + <![CDATA[@hapi/bell v8.9.0]]> + https://github.com/hapijs/bell/milestone/66 + + 2017-11-19T16:41:43.000Z + +
  • [#325] Changed the discord providers image url prefix
  • [#321] Add trakt.tv provider
  • [#286] Added custom OAuth2 client authentication
  • ]]>
    +
    + + <![CDATA[@hapi/bell v8.8.0]]> + https://github.com/hapijs/bell/milestone/65 + + 2017-09-24T21:05:07.000Z + +
  • [#319] Allowing the location option to be a function
  • [#318] Add Mixer as a new provider
  • [#316] Add Stripe as a new provider
  • [#315] Add `fields` option to Facebook provider
  • [#244] New dropbox-v2 provider which uses Dropbox V2 API
  • ]]>
    +
    + + <![CDATA[@hapi/bell v8.7.0]]> + https://github.com/hapijs/bell/milestone/64 + + 2017-05-09T03:28:13.000Z + +
  • [#312] add DigitalOcean provider
  • [#311] Updates Facebook API to v2.9
  • [#308] Add `'profile'` to list of default scopes for Okta
  • [#303] Facebook
  • [#252] [Update] Updates Facebook provider to v2.7
  • ]]>
    +
    + + <![CDATA[@hapi/bell v8.6.0]]> + https://github.com/hapijs/bell/milestone/62 + + 2017-03-24T20:22:14.000Z + +
  • [#299] Add support for authentication with Okta
  • [#298] added spotify
  • [#273] Fixes #261 expose OAUTH2 token response as request.auth.artifacts
  • ]]>
    +
    + + <![CDATA[@hapi/bell v8.5.1]]> + https://github.com/hapijs/bell/milestone/61 + + 2017-03-24T20:22:22.000Z + +
  • [#289] AzureAD: Support email, when userPrincipalName (upn) is not available
  • ]]>
    +
    + + <![CDATA[@hapi/bell v8.5.0]]> + https://github.com/hapijs/bell/milestone/54 + + 2017-01-24T02:39:32.000Z + +
  • [#291] Medium provider
  • ]]>
    +
    + + <![CDATA[@hapi/bell v8.4.0]]> + https://github.com/hapijs/bell/milestone/60 + + 2016-12-01T03:29:08.000Z + +
  • [#280] hapi 16
  • [#266] Implement Azure Active Directory authentication for enterprise AD logins
  • ]]>
    +
    + + <![CDATA[@hapi/bell v8.3.0]]> + https://github.com/hapijs/bell/milestone/59 + + 2016-10-04T14:36:45.000Z + +
  • [#267] Fixes #266 Implements azure active directory as bell azuread module
  • ]]>
    +
    + + <![CDATA[@hapi/bell v8.2.1]]> + https://github.com/hapijs/bell/milestone/58 + + 2016-09-21T14:49:02.000Z + +
  • [#265] Set isSameSite to false and add code to support Hapi 13.5+
  • [#264] Bell is not compatible with Hapi 15 due to same-site: strict for cookie
  • ]]>
    +
    + + <![CDATA[@hapi/bell v8.2.0]]> + https://github.com/hapijs/bell/milestone/57 + + 2016-09-07T14:41:01.000Z + +
  • [#259] Support Hapi 15 & upgrade boom + wreck dependencies
  • [#256] allow for leading whitespace in JSON
  • [#248] Add discord as a new provider
  • ]]>
    +
    + + <![CDATA[@hapi/bell v8.1.1]]> + https://github.com/hapijs/bell/milestone/56 + + 2016-09-07T14:32:01.000Z + +
  • [#254] fix mapping of google profile fixes #251
  • [#251] Google user info
  • ]]>
    +
    + + <![CDATA[@hapi/bell v8.1.0]]> + https://github.com/hapijs/bell/milestone/55 + + 2016-08-20T21:39:28.000Z + +
  • [#249] Twitter additional GET parameters on extended profile request
  • ]]>
    +
    + + <![CDATA[@hapi/bell v8.0.1]]> + https://github.com/hapijs/bell/milestone/52 + + 2016-07-29T20:27:10.000Z + +
  • [#247] Allow hapi 14
  • ]]>
    +
    + + <![CDATA[@hapi/bell v8.0.0]]> + https://github.com/hapijs/bell/milestone/34 + + 2016-07-17T20:22:49.000Z + +
  • [#243] Bell 8.0.0 Release Notes
  • [#242] Upgrade Joi dependence to 9.x.x
  • [#240] Fitbit provider
  • [#235] Separate Google into two providers. #228
  • [#233] Allow providerParams to be a method invoked with the request
  • [#228] Remove dependency on Google Plus APIs
  • ]]>
    +
    + + <![CDATA[@hapi/bell v7.9.3]]> + https://github.com/hapijs/bell/milestone/51 + + 2016-07-16T10:31:18.000Z + +
  • [#239] [Fix] Fixes email address field in LinkedIn
  • ]]>
    +
    + + <![CDATA[@hapi/bell v7.9.1]]> + https://github.com/hapijs/bell/milestone/50 + + 2016-06-22T23:36:12.000Z + +
  • [#237] Profiles are broken when used directly
  • ]]>
    +
    + + <![CDATA[@hapi/bell v7.9.0]]> + https://github.com/hapijs/bell/milestone/49 + + 2016-06-19T20:04:09.000Z + +
  • [#236] Aphuang2013 patch 1
  • [#232] Update dependencies
  • [#231] Only publish root and lib directory in npm. #230
  • [#230] Only publish root and lib directory in npm
  • [#227] Implemented RSA-SHA1 signatures for OAuth v1
  • [#226] OAuth v1: How to handle RSA-SHA1 signing?
  • ]]>
    +
    + + <![CDATA[@hapi/bell v7.8.0]]> + https://github.com/hapijs/bell/milestone/47 + + 2016-06-02T05:44:27.000Z + +
  • [#221] getMethod option
  • ]]>
    +
    + + <![CDATA[@hapi/bell v7.7.3]]> + https://github.com/hapijs/bell/milestone/48 + + 2016-06-02T05:43:01.000Z + +
  • [#225] Fix markup to quote URL correctly to avoid infinite redirect
  • ]]>
    +
    + + <![CDATA[@hapi/bell v7.7.2]]> + https://github.com/hapijs/bell/milestone/45 + + 2016-06-02T05:37:53.000Z + +
  • [#224] Apply the same html redirection logic to oauth v1. Closes #223
  • [#223] OAuth 1.0 missing HTML redirection workaround
  • ]]>
    +
    + + <![CDATA[@hapi/bell v7.7.1]]> + https://github.com/hapijs/bell/milestone/46 + + 2016-05-23T22:48:19.000Z + +
  • [#222] Upgrade to code 3.x.x
  • [#210] Test with Node 6
  • ]]>
    +
    + + <![CDATA[@hapi/bell v7.7.0]]> + https://github.com/hapijs/bell/milestone/44 + + 2016-05-23T22:39:29.000Z + +
  • [#216] Consistently return node req object in oauth v1 client. Closes #215
  • [#215] Fails to always return the node req object from wreck
  • [#213] Add Pinterest provider
  • ]]>
    +
    + + <![CDATA[@hapi/bell v7.6.1]]> + https://github.com/hapijs/bell/milestone/42 + + 2016-04-30T23:30:36.000Z + +
  • [#208] Fix Safari CORS with Facebook & potentially other providers
  • [#206] Fix weird error happening when logging in through Facebook on safari …
  • [#191] Can not login with Facebook on Safari
  • ]]>
    +
    + + <![CDATA[@hapi/bell v7.6.0]]> + https://github.com/hapijs/bell/milestone/43 + + 2016-04-23T15:13:15.000Z + +
  • [#207] Add GitLab provider
  • ]]>
    +
    + + <![CDATA[@hapi/bell v7.5.1]]> + https://github.com/hapijs/bell/milestone/38 + + 2016-04-17T21:38:46.000Z + +
  • [#205] Added appsecret_proof to wordpress provider
  • ]]>
    +
    + + <![CDATA[@hapi/bell v7.5.0]]> + https://github.com/hapijs/bell/milestone/41 + + 2016-04-16T15:22:07.000Z + +
  • [#204] WordPress Provider
  • ]]>
    +
    + + <![CDATA[@hapi/bell v7.4.0]]> + https://github.com/hapijs/bell/milestone/40 + + 2016-04-10T03:33:48.000Z + +
  • [#202] Office365 provider
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/boom.atom b/docs/public/atom/boom.atom new file mode 100644 index 00000000..0308a031 --- /dev/null +++ b/docs/public/atom/boom.atom @@ -0,0 +1,410 @@ + + + https://hapi.dev/module/boom + @hapi/boom changelog + 2023-02-11T17:44:33.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/boom v10.0.1]]> + https://github.com/hapijs/boom/milestone/69 + + 2023-02-11T17:44:33.000Z + +
  • [#299] chore: bump hoek and lab
  • [#297] Document 1st arg can be an Error
  • ]]>
    +
    + + <![CDATA[@hapi/boom v10.0.0]]> + https://github.com/hapijs/boom/milestone/68 + + 2022-05-02T02:47:27.000Z + +
  • [#295] Support node v18, drop node v12
  • ]]>
    +
    + + <![CDATA[@hapi/boom v9.1.4]]> + https://github.com/hapijs/boom/milestone/66 + + 2021-08-23T22:23:19.000Z + +
  • [#289] fix: make reformat configurable in initialize
  • ]]>
    +
    + + <![CDATA[@hapi/boom v9.1.3]]> + https://github.com/hapijs/boom/milestone/64 + + 2021-07-02T03:23:36.000Z + +
  • [#286] Don't mess with instanceof checks called on subclasses
  • [#285] Extending Boom and unexpected instanceof behavior
  • ]]>
    +
    + + <![CDATA[@hapi/boom v9.1.2]]> + https://github.com/hapijs/boom/milestone/63 + + 2021-03-16T02:10:26.000Z + +
  • [#281] Add proper index type to headers property
  • ]]>
    +
    + + <![CDATA[@hapi/boom v9.1.1]]> + https://github.com/hapijs/boom/milestone/62 + + 2020-12-16T15:48:27.000Z + +
  • [#279] TypeScript: Allow custom properties on output.payload
  • [#278] Clean up d.ts comments
  • [#277] output.payload.attributes is not exposed in the .d.ts file
  • [#275] Make isBoom type definition laxer
  • [#273] upgrade lab to v24 and devDependency of typescript
  • ]]>
    +
    + + <![CDATA[@hapi/boom v9.1.0]]> + https://github.com/hapijs/boom/milestone/61 + + 2020-03-12T03:12:39.000Z + +
  • [#266] Add optional statusCode parameter to Boom.isBoom
  • [#265] Optional second param for Boom.isBoom() to verify status code
  • ]]>
    +
    + + <![CDATA[@hapi/boom v9.0.0]]> + https://github.com/hapijs/boom/milestone/60 + + 2020-01-04T00:06:35.000Z + +
  • [#262] Support only node 12
  • [#261] Add HTTP code 425 Too Early
  • [#260] boom.unathorized adds extra space to string value scheme in WWW-Authenticate header
  • ]]>
    +
    + + <![CDATA[@hapi/boom v8.0.1]]> + https://github.com/hapijs/boom/milestone/58 + + 2019-09-28T05:13:21.000Z + +
  • [#253] change new Boom() to new Boom.Boom()
  • [#252] Drop support for node 8
  • [#251] Add types
  • [#246] boom doesn't consider message not set directly on error object when deciding whether it is a compatible error
  • ]]>
    +
    + + <![CDATA[@hapi/boom v7.4.12]]> + https://github.com/hapijs/boom/milestone/65 + + 2021-04-21T23:09:44.000Z + +
  • [#282] Latest v7-commercial release (v7.4.11) is broken
  • ]]>
    +
    + + <![CDATA[@hapi/boom v7.4.11]]> + https://github.com/hapijs/boom/milestone/56 + + 2019-09-27T18:55:27.000Z + +
  • [#248] Error TS2709: Cannot use namespace 'Boom' as a type.
  • ]]>
    +
    + + <![CDATA[@hapi/boom v7.4.10]]> + https://github.com/hapijs/boom/milestone/55 + + 2019-09-23T20:34:29.000Z + +
  • [#245] Fix default export. Fixes #244.
  • [#244] Typescript - can't extend Boom
  • ]]>
    +
    + + <![CDATA[@hapi/boom v7.4.9]]> + https://github.com/hapijs/boom/milestone/54 + + 2019-09-21T00:10:43.000Z + +
  • [#243] Improve types
  • ]]>
    +
    + + <![CDATA[@hapi/boom v7.4.8]]> + https://github.com/hapijs/boom/milestone/53 + + 2019-09-20T23:24:43.000Z + +
  • [#242] Typescript definitions missing internal()
  • [#241] Ts fix
  • [#240] Fix types: Update static isBoom to be a type guard.
  • ]]>
    +
    + + <![CDATA[@hapi/boom v7.4.7]]> + https://github.com/hapijs/boom/milestone/52 + + 2019-09-20T04:15:14.000Z + +
  • [#239] Missing error properties
  • ]]>
    +
    + + <![CDATA[@hapi/boom v7.4.6]]> + https://github.com/hapijs/boom/milestone/51 + + 2019-09-20T00:24:55.000Z + +
  • [#238] Fix types: serviceUnavailable -> serverUnavailable.
  • [#237] Types have typo: serverUnavailable -> serviceUnavailable
  • ]]>
    +
    + + <![CDATA[@hapi/boom v7.4.5]]> + https://github.com/hapijs/boom/milestone/50 + + 2019-09-19T21:24:20.000Z + +
  • [#216] Handle case of message property with getter-only
  • [#215] `typeof` and `reformat` should not be enumerable
  • ]]>
    +
    + + <![CDATA[@hapi/boom v7.4.4]]> + https://github.com/hapijs/boom/milestone/49 + + 2019-09-19T20:06:00.000Z + +
  • [#233] Added TS declarations
  • ]]>
    +
    + + <![CDATA[@hapi/boom v7.4.3]]> + https://github.com/hapijs/boom/milestone/48 + + 2019-08-14T04:54:27.000Z + +
  • [#229] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/boom v7.4.2]]> + https://github.com/hapijs/boom/milestone/47 + + 2019-03-29T22:31:08.000Z + +
  • [#221] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/boom v7.4.1]]> + https://github.com/hapijs/boom/milestone/46 + + 2019-03-29T21:48:57.000Z + +
  • [#220] Fix dependency
  • ]]>
    +
    + + <![CDATA[@hapi/boom v7.4.0]]> + https://github.com/hapijs/boom/milestone/42 + + 2019-03-27T00:50:55.000Z + +
  • [#219] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/boom v7.3.0]]> + https://github.com/hapijs/boom/milestone/41 + + 2018-11-28T20:33:01.000Z + +
  • [#211] add debug mode to reformat()
  • ]]>
    +
    + + <![CDATA[@hapi/boom v7.2.2]]> + https://github.com/hapijs/boom/milestone/40 + + 2018-11-03T00:16:50.000Z + +
  • [#208] Remove engines
  • ]]>
    +
    + + <![CDATA[@hapi/boom v7.2.1]]> + https://github.com/hapijs/boom/milestone/39 + + 2018-11-01T07:28:14.000Z + +
  • [#206] Update hoek v6
  • ]]>
    +
    + + <![CDATA[@hapi/boom v7.2.0]]> + https://github.com/hapijs/boom/milestone/38 + + 2018-02-28T17:43:37.000Z + +
  • [#188] 424 Failed dependency implementation
  • ]]>
    +
    + + <![CDATA[@hapi/boom v7.1.1]]> + https://github.com/hapijs/boom/milestone/37 + + 2017-11-03T18:05:01.000Z + +
  • [#173] Support instanceof
  • ]]>
    +
    + + <![CDATA[@hapi/boom v7.1.0]]> + https://github.com/hapijs/boom/milestone/36 + + 2017-11-03T07:24:07.000Z + +
  • [#172] Add decorate option
  • ]]>
    +
    + + <![CDATA[@hapi/boom v7.0.0]]> + https://github.com/hapijs/boom/milestone/35 + + 2017-11-03T07:24:09.000Z + +
  • [#171] Remove wrap() and create()
  • ]]>
    +
    + + <![CDATA[@hapi/boom v6.0.0]]> + https://github.com/hapijs/boom/milestone/34 + + 2017-09-26T05:23:53.000Z + +
  • [#165] Node v8
  • ]]>
    +
    + + <![CDATA[@hapi/boom v5.3.1]]> + https://github.com/hapijs/boom/milestone/44 + + 2019-03-21T23:55:56.000Z + +
  • [#218] Load the commercial version of hoek
  • ]]>
    +
    + + <![CDATA[@hapi/boom v5.3.0]]> + https://github.com/hapijs/boom/milestone/43 + + 2019-03-21T23:30:56.000Z + +
  • [#217] Commercial version of v5 branch
  • ]]>
    +
    + + <![CDATA[@hapi/boom v5.2.0]]> + https://github.com/hapijs/boom/milestone/33 + + 2017-07-18T23:45:09.000Z + +
  • [#160] Allow decorating a boom error
  • ]]>
    +
    + + <![CDATA[@hapi/boom v5.1.0]]> + https://github.com/hapijs/boom/milestone/32 + + 2017-05-28T21:50:42.000Z + +
  • [#157] Hide message on 500 when error is provided as data
  • [#156] Added typeOf functionality
  • ]]>
    +
    + + <![CDATA[@hapi/boom v5.0.0]]> + https://github.com/hapijs/boom/milestone/31 + + 2017-05-25T07:53:06.000Z + +
  • [#154] Boom.wrap with a provided message doesn't format the payload
  • [#152] Boom.badGateway( string, Boom.anything() )
  • ]]>
    +
    + + <![CDATA[@hapi/boom v4.3.1]]> + https://github.com/hapijs/boom/milestone/30 + + 2017-05-25T07:25:15.000Z + +
  • [#149] fix #148 when Boom supplied to wrapper
  • [#148] Remove line from wrap function
  • ]]>
    +
    + + <![CDATA[@hapi/boom v4.3.0]]> + https://github.com/hapijs/boom/milestone/29 + + 2017-03-21T07:17:29.000Z + +
  • [#147] Unauthorized extension for #146
  • [#146] Unauthorized
  • [#142] Boom.wrap never sends custom message to client
  • [#139] Adds support for `Boom.someMethod(err)`, closes #138
  • [#138] Preservation of `err.name` via `Boom.create` or `Boom[someMethod]`
  • [#78] Add Boom.teapot() method with documentation and tests
  • ]]>
    +
    + + <![CDATA[@hapi/boom v4.2.0]]> + https://github.com/hapijs/boom/milestone/28 + + 2016-10-13T16:46:10.000Z + +
  • [#133] Add 'allow' parameter to methodNotAllowed for setting 'Allow' header
  • [#132] 405 Method Not Allowed should provide an argument for specifying "Allow" header
  • ]]>
    +
    + + <![CDATA[@hapi/boom v4.1.0]]> + https://github.com/hapijs/boom/milestone/27 + + 2016-09-27T13:12:32.000Z + +
  • [#130] Add 402 payment required
  • [#129] Add Boom.internal() to API docs fixes #127
  • ]]>
    +
    + + <![CDATA[@hapi/boom v4.0.0]]> + https://github.com/hapijs/boom/milestone/26 + + 2016-08-26T13:43:49.000Z + +
  • [#125] Remove deprecated serverTimeout
  • [#118] Remove serverTimeout()
  • ]]>
    +
    + + <![CDATA[@hapi/boom v3.2.2]]> + https://github.com/hapijs/boom/milestone/25 + + 2016-06-21T14:29:48.000Z + +
  • [#121] Added .npmignore file.
  • [#119] Rename serverTimeout to serverUnavailable
  • [#117] serverTimeout() should be aliased to serverUnavailable()
  • [#108] Create .npmignore
  • ]]>
    +
    + + <![CDATA[@hapi/boom v3.2.1]]> + https://github.com/hapijs/boom/milestone/24 + + 2016-05-22T19:58:32.000Z + +
  • [#113] Updated to code 3.
  • ]]>
    +
    + + <![CDATA[@hapi/boom v3.2.0]]> + https://github.com/hapijs/boom/milestone/23 + + 2016-05-20T18:05:04.000Z + +
  • [#112] Added HTTP code 423 Locked
  • [#111] HTTP Error 423 (Locked)
  • ]]>
    +
    + + <![CDATA[@hapi/boom v3.1.3]]> + https://github.com/hapijs/boom/milestone/22 + + 2016-05-06T14:51:15.000Z + +
  • [#110] Added node 6.
  • ]]>
    +
    + + <![CDATA[@hapi/boom v3.1.2]]> + https://github.com/hapijs/boom/milestone/21 + + 2016-01-22T15:06:12.000Z + +
  • [#97] Use quotes instead of backticks
  • ]]>
    +
    + + <![CDATA[@hapi/boom v3.1.1]]> + https://github.com/hapijs/boom/milestone/20 + + 2015-12-23T16:54:26.000Z + +
  • [#95] Changed prototype logic.
  • ]]>
    +
    + + <![CDATA[@hapi/boom v3.1.0]]> + https://github.com/hapijs/boom/milestone/19 + + 2015-12-23T16:33:16.000Z + +
  • [#94] Cleanup for 254593fd1d09e79049692675a4f9b7b5108b36d8
  • [#93] Document Illegal
  • [#92] Status Code Hash
  • [#91] Add new 451 Unavailable For Legal Reasons
  • ]]>
    +
    + + <![CDATA[@hapi/boom v3.0.0]]> + https://github.com/hapijs/boom/milestone/18 + + 2015-10-31T17:24:27.000Z + +
  • [#83] es6 style. Closes #77
  • [#77] Node 4 Updates
  • ]]>
    +
    + + <![CDATA[@hapi/boom v2.10.1]]> + https://github.com/hapijs/boom/milestone/17 + + 2015-10-30T19:16:41.000Z + +
  • [#81] Upgrade to lab 7.x.x
  • [#80] Fix ctor passing in serverError helper
  • [#79] Stack trace filtering not working for serverError constructors
  • ]]>
    +
    + + <![CDATA[@hapi/boom v2.10.0]]> + https://github.com/hapijs/boom/milestone/16 + + 2015-10-26T13:28:25.000Z + +
  • [#75] Support Precondition Required
  • [#74] Precondition required is not supported
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/bossy.atom b/docs/public/atom/bossy.atom new file mode 100644 index 00000000..a3756d08 --- /dev/null +++ b/docs/public/atom/bossy.atom @@ -0,0 +1,210 @@ + + + https://hapi.dev/module/bossy + @hapi/bossy changelog + 2023-02-11T19:12:41.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/bossy v6.0.1]]> + https://github.com/hapijs/bossy/milestone/25 + + 2023-02-11T19:12:41.000Z + +
  • [#83] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/bossy v6.0.0]]> + https://github.com/hapijs/bossy/milestone/24 + + 2023-02-11T19:12:39.000Z + +
  • [#82] Support node v18 and drop node v12
  • ]]>
    +
    + + <![CDATA[@hapi/bossy v5.1.1]]> + https://github.com/hapijs/bossy/milestone/23 + + 2022-05-05T01:38:12.000Z + +
  • [#78] Fix display of defaults for json args and zero
  • ]]>
    +
    + + <![CDATA[@hapi/bossy v5.1.0]]> + https://github.com/hapijs/bossy/milestone/22 + + 2021-02-12T03:46:19.000Z + +
  • [#77] Implement object argument type
  • [#76] Implement negation of boolean arguments
  • ]]>
    +
    + + <![CDATA[@hapi/bossy v5.0.1]]> + https://github.com/hapijs/bossy/milestone/21 + + 2021-02-12T03:46:45.000Z + +
  • [#74] upgrade lab to v24
  • ]]>
    +
    + + <![CDATA[@hapi/bossy v5.0.0]]> + https://github.com/hapijs/bossy/milestone/20 + + 2020-01-04T09:20:18.000Z + +
  • [#70] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/bossy v4.1.3]]> + https://github.com/hapijs/bossy/milestone/19 + + 2019-09-12T23:32:18.000Z + +
  • [#66] Update joi
  • ]]>
    +
    + + <![CDATA[@hapi/bossy v4.1.2]]> + https://github.com/hapijs/bossy/milestone/18 + + 2019-08-07T19:25:08.000Z + +
  • [#63] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/bossy v4.1.1]]> + https://github.com/hapijs/bossy/milestone/17 + + 2019-04-09T06:33:09.000Z + +
  • [#62] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/bossy v4.1.0]]> + https://github.com/hapijs/bossy/milestone/16 + + 2019-03-29T20:31:05.000Z + +
  • [#61] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/bossy v4.0.3]]> + https://github.com/hapijs/bossy/milestone/15 + + 2018-11-01T07:31:08.000Z + +
  • [#58] Update hoek v6
  • ]]>
    +
    + + <![CDATA[@hapi/bossy v4.0.2]]> + https://github.com/hapijs/bossy/milestone/14 + + 2018-11-01T07:29:44.000Z + +
  • [#57] Cleanup
  • ]]>
    +
    + + <![CDATA[@hapi/bossy v4.0.1]]> + https://github.com/hapijs/bossy/milestone/13 + + 2017-11-03T06:46:40.000Z + +
  • [#55] Use Boom for errors
  • ]]>
    +
    + + <![CDATA[@hapi/bossy v4.0.0]]> + https://github.com/hapijs/bossy/milestone/12 + + 2017-10-23T19:41:21.000Z + +
  • [#54] Node v8
  • ]]>
    +
    + + <![CDATA[@hapi/bossy v3.0.3]]> + https://github.com/hapijs/bossy/milestone/11 + + 2016-12-01T03:42:08.000Z + +
  • [#52] node 7
  • ]]>
    +
    + + <![CDATA[@hapi/bossy v3.0.2]]> + https://github.com/hapijs/bossy/milestone/10 + + 2016-12-01T03:40:57.000Z + + ]]> + + + <![CDATA[@hapi/bossy v3.0.1]]> + https://github.com/hapijs/bossy/milestone/9 + + 2016-07-29T19:12:34.000Z + +
  • [#49] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/bossy v3.0.0]]> + https://github.com/hapijs/bossy/milestone/8 + + 2016-07-28T23:42:25.000Z + +
  • [#47] Upgrade to current hapi.js standards
  • [#46] Upgrade to current hapi.js standards
  • [#43] Show default value when printing options
  • ]]>
    +
    + + <![CDATA[@hapi/bossy v2.0.0]]> + https://github.com/hapijs/bossy/milestone/7 + + 2015-07-05T20:56:06.000Z + +
  • [#41] Add `multiple` option parameter
  • [#40] update project style
  • [#39] Update project style
  • [#37] Enable multiple values to be passed in
  • [#36] Support multiple values for an option
  • [#35] Validate input arguments using Joi
  • [#24] Cleanup
  • ]]>
    +
    + + <![CDATA[@hapi/bossy v1.0.3]]> + https://github.com/hapijs/bossy/milestone/6 + + 2015-06-28T01:09:51.000Z + +
  • [#32] Update to Lab 5.x.x and Code 1.x.x
  • [#31] Update .travis.yml
  • [#29] fix minor lint
  • [#28] Allow numeric arguments to be passed in without spaces
  • [#27] Bossy should support numeric arguments without spaces
  • [#26] Add help type
  • [#23] Slice
  • ]]>
    +
    + + <![CDATA[@hapi/bossy v1.0.2]]> + https://github.com/hapijs/bossy/milestone/5 + + 2014-09-15T19:01:49.000Z + +
  • [#20] Populate all aliases.
  • [#18] Alias keys should be assigned argument value
  • ]]>
    +
    + + <![CDATA[@hapi/bossy v1.0.1]]> + https://github.com/hapijs/bossy/milestone/4 + + 2014-09-12T15:45:37.000Z + +
  • [#17] Format unknown option error message
  • [#16] Unhelpful message for unknown argument
  • ]]>
    +
    + + <![CDATA[@hapi/bossy v1.0.0]]> + https://github.com/hapijs/bossy/milestone/3 + + 2014-09-12T14:41:57.000Z + +
  • [#15] Support colorizing usage information
  • [#14] Add valid definition option for arguments
  • [#13] Orders usage message with -shortname, --longname
  • [#12] Add `valid` property to definition objects
  • [#11] Order alias and full name correctly on usage
  • [#10] Colorize the usage/help output
  • ]]>
    +
    + + <![CDATA[@hapi/bossy v0.0.2]]> + https://github.com/hapijs/bossy/milestone/2 + + 2014-09-11T02:31:57.000Z + +
  • [#9] Can override argv
  • [#8] Support null defaults for boolean
  • [#7] Allow boolean to be defaulted to null
  • [#6] Support argv being passed in options to parse
  • ]]>
    +
    + + <![CDATA[@hapi/bossy v0.0.1]]> + https://github.com/hapijs/bossy/milestone/1 + + 2014-09-10T18:26:07.000Z + +
  • [#4] Adding help formatting
  • [#2] Implement function for displaying usage
  • [#1] Lab 4, defaults, and require
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/bounce.atom b/docs/public/atom/bounce.atom new file mode 100644 index 00000000..77ba9dab --- /dev/null +++ b/docs/public/atom/bounce.atom @@ -0,0 +1,130 @@ + + + https://hapi.dev/module/bounce + @hapi/bounce changelog + 2024-10-23T15:48:17.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/bounce v3.0.2]]> + https://github.com/hapijs/bounce/milestone/17 + + 2024-10-23T15:48:17.000Z + +
  • [#38] Fix background() missing return option support
  • ]]>
    +
    + + <![CDATA[@hapi/bounce v3.0.1]]> + https://github.com/hapijs/bounce/milestone/16 + + 2023-02-11T17:54:18.000Z + +
  • [#35] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/bounce v3.0.0]]> + https://github.com/hapijs/bounce/milestone/15 + + 2023-02-11T17:47:09.000Z + +
  • [#33] Support node v18 and drop node v12
  • ]]>
    +
    + + <![CDATA[@hapi/bounce v2.0.0]]> + https://github.com/hapijs/bounce/milestone/13 + + 2020-01-04T22:28:38.000Z + +
  • [#23] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/bounce v1.3.2]]> + https://github.com/hapijs/bounce/milestone/11 + + 2019-10-15T06:45:47.000Z + +
  • [#21] Fix hoek contain bug
  • ]]>
    +
    + + <![CDATA[@hapi/bounce v1.3.1]]> + https://github.com/hapijs/bounce/milestone/10 + + 2019-06-26T17:24:58.000Z + +
  • [#16] Treat hoek assertion as system
  • ]]>
    +
    + + <![CDATA[@hapi/bounce v1.3.0]]> + https://github.com/hapijs/bounce/milestone/9 + + 2019-03-30T20:27:28.000Z + +
  • [#15] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/bounce v1.2.3]]> + https://github.com/hapijs/bounce/milestone/8 + + 2018-11-11T02:10:06.000Z + +
  • [#13] Fix contain() options
  • ]]>
    +
    + + <![CDATA[@hapi/bounce v1.2.2]]> + https://github.com/hapijs/bounce/milestone/7 + + 2018-11-03T00:17:57.000Z + +
  • [#12] Remove engines
  • ]]>
    +
    + + <![CDATA[@hapi/bounce v1.2.1]]> + https://github.com/hapijs/bounce/milestone/6 + + 2018-11-01T07:32:37.000Z + +
  • [#10] Update hoek v6
  • ]]>
    +
    + + <![CDATA[@hapi/bounce v1.2.0]]> + https://github.com/hapijs/bounce/milestone/5 + + 2017-11-06T09:36:32.000Z + +
  • [#6] Support background functions
  • ]]>
    +
    + + <![CDATA[@hapi/bounce v1.1.0]]> + https://github.com/hapijs/bounce/milestone/4 + + 2017-11-06T07:23:16.000Z + +
  • [#5] Background processing with error protection
  • ]]>
    +
    + + <![CDATA[@hapi/bounce v1.0.3]]> + https://github.com/hapijs/bounce/milestone/3 + + 2017-11-03T09:41:02.000Z + +
  • [#4] Ignore boomified system errors
  • ]]>
    +
    + + <![CDATA[@hapi/bounce v1.0.2]]> + https://github.com/hapijs/bounce/milestone/2 + + 2017-11-03T06:49:25.000Z + +
  • [#3] Update boom
  • ]]>
    +
    + + <![CDATA[@hapi/bounce v1.0.1]]> + https://github.com/hapijs/bounce/milestone/1 + + 2017-11-02T17:57:26.000Z + +
  • [#2] Hoek missing from dependencies
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/bourne.atom b/docs/public/atom/bourne.atom new file mode 100644 index 00000000..62a6b59c --- /dev/null +++ b/docs/public/atom/bourne.atom @@ -0,0 +1,74 @@ + + + https://hapi.dev/module/bourne + @hapi/bourne changelog + 2022-04-08T15:01:04.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/bourne v2.1.0]]> + https://github.com/hapijs/bourne/milestone/9 + + 2022-04-08T15:01:04.000Z + +
  • [#26] Add Typescript types
  • [#22] upgrade lab to v24
  • ]]>
    +
    + + <![CDATA[@hapi/bourne v2.0.0]]> + https://github.com/hapijs/bourne/milestone/8 + + 2020-01-04T09:10:54.000Z + +
  • [#17] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/bourne v1.3.2]]> + https://github.com/hapijs/bourne/milestone/6 + + 2019-04-28T19:07:05.000Z + +
  • [#10] Fix uppercase hex strings validating as safe
  • ]]>
    +
    + + <![CDATA[@hapi/bourne v1.3.0]]> + https://github.com/hapijs/bourne/milestone/5 + + 2019-04-27T19:39:27.000Z + +
  • [#9] Add safeParse()
  • ]]>
    +
    + + <![CDATA[@hapi/bourne v1.2.0]]> + https://github.com/hapijs/bourne/milestone/4 + + 2019-04-27T19:38:20.000Z + +
  • [#8] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/bourne v1.1.2]]> + https://github.com/hapijs/bourne/milestone/3 + + 2019-03-25T16:54:21.000Z + +
  • [#7] Don't assume `hasOwnProperty` is safe
  • ]]>
    +
    + + <![CDATA[@hapi/bourne v1.1.1]]> + https://github.com/hapijs/bourne/milestone/2 + + 2019-02-04T21:26:15.000Z + +
  • [#5] Use syntax available down to Node 4.
  • [#4] Improve regex to only flag keys
  • ]]>
    +
    + + <![CDATA[@hapi/bourne v1.1.0]]> + https://github.com/hapijs/bourne/milestone/1 + + 2019-02-01T22:41:40.000Z + +
  • [#3] Handle escaped unicode characters
  • [#2] Expose validation logic
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/call.atom b/docs/public/atom/call.atom new file mode 100644 index 00000000..9057e43d --- /dev/null +++ b/docs/public/atom/call.atom @@ -0,0 +1,226 @@ + + + https://hapi.dev/module/call + @hapi/call changelog + 2020-11-18T03:40:51.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/call v8.0.1]]> + https://github.com/hapijs/call/milestone/28 + + 2020-11-18T03:40:51.000Z + +
  • [#62] upgrade lab to v24
  • ]]>
    +
    + + <![CDATA[@hapi/call v8.0.0]]> + https://github.com/hapijs/call/milestone/27 + + 2020-02-10T08:57:02.000Z + +
  • [#56] Switch tables to maps
  • ]]>
    +
    + + <![CDATA[@hapi/call v7.0.1]]> + https://github.com/hapijs/call/milestone/26 + + 2020-02-10T05:41:04.000Z + +
  • [#55] Switch to use maps
  • ]]>
    +
    + + <![CDATA[@hapi/call v7.0.0]]> + https://github.com/hapijs/call/milestone/25 + + 2020-01-04T22:38:39.000Z + +
  • [#54] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/call v6.0.1]]> + https://github.com/hapijs/call/milestone/23 + + 2019-11-01T22:12:31.000Z + +
  • [#52] Special case '/'
  • ]]>
    +
    + + <![CDATA[@hapi/call v6.0.0]]> + https://github.com/hapijs/call/milestone/22 + + 2019-10-30T23:54:22.000Z + +
  • [#51] Improve performance
  • [#50] Drop node 8
  • ]]>
    +
    + + <![CDATA[@hapi/call v5.1.3]]> + https://github.com/hapijs/call/milestone/21 + + 2020-02-13T19:45:13.000Z + +
  • [#57] Check method exists
  • ]]>
    +
    + + <![CDATA[@hapi/call v5.1.2]]> + https://github.com/hapijs/call/milestone/20 + + 2019-10-30T23:48:27.000Z + +
  • [#49] Fix typo: wilcard -> wildcard
  • ]]>
    +
    + + <![CDATA[@hapi/call v5.1.1]]> + https://github.com/hapijs/call/milestone/19 + + 2019-08-14T05:02:31.000Z + +
  • [#42] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/call v5.1.0]]> + https://github.com/hapijs/call/milestone/16 + + 2019-03-30T20:46:45.000Z + +
  • [#41] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/call v5.0.3]]> + https://github.com/hapijs/call/milestone/15 + + 2018-11-03T00:18:57.000Z + +
  • [#37] Remove engines
  • ]]>
    +
    + + <![CDATA[@hapi/call v5.0.2]]> + https://github.com/hapijs/call/milestone/14 + + 2018-11-01T07:48:36.000Z + +
  • [#36] Update hoek v6
  • ]]>
    +
    + + <![CDATA[@hapi/call v5.0.1]]> + https://github.com/hapijs/call/milestone/13 + + 2017-11-03T06:52:08.000Z + +
  • [#34] Update boom
  • ]]>
    +
    + + <![CDATA[@hapi/call v5.0.0]]> + https://github.com/hapijs/call/milestone/12 + + 2017-09-26T06:13:48.000Z + +
  • [#33] Node 8
  • ]]>
    +
    + + <![CDATA[@hapi/call v4.1.1]]> + https://github.com/hapijs/call/milestone/18 + + 2020-02-13T19:49:15.000Z + +
  • [#58] Check method exists
  • ]]>
    +
    + + <![CDATA[@hapi/call v4.1.0]]> + https://github.com/hapijs/call/milestone/17 + + 2019-03-22T06:11:06.000Z + +
  • [#40] Commercial version of v4 branch
  • ]]>
    +
    + + <![CDATA[@hapi/call v4.0.2]]> + https://github.com/hapijs/call/milestone/11 + + 2017-05-28T05:58:30.000Z + +
  • [#32] Update deps.
  • ]]>
    +
    + + <![CDATA[@hapi/call v4.0.1]]> + https://github.com/hapijs/call/milestone/10 + + 2017-03-20T20:44:53.000Z + +
  • [#29] Apply path segment normalization
  • [#28] No "Path Segment Normalization"?
  • ]]>
    +
    + + <![CDATA[@hapi/call v4.0.0]]> + https://github.com/hapijs/call/milestone/9 + + 2016-11-29T23:41:49.000Z + +
  • [#24] {path*} segments disappear when empty
  • ]]>
    +
    + + <![CDATA[@hapi/call v3.0.4]]> + https://github.com/hapijs/call/milestone/8 + + 2016-11-29T01:51:02.000Z + +
  • [#26] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/call v3.0.3]]> + https://github.com/hapijs/call/milestone/7 + + 2016-07-27T19:27:19.000Z + +
  • [#23] npmignore
  • ]]>
    +
    + + <![CDATA[@hapi/call v3.0.2]]> + https://github.com/hapijs/call/milestone/6 + + 2016-07-04T04:14:46.000Z + +
  • [#21] Fix empty segment bug
  • ]]>
    +
    + + <![CDATA[@hapi/call v3.0.1]]> + https://github.com/hapijs/call/milestone/5 + + 2016-05-19T18:07:15.000Z + +
  • [#20] Test on node v6, update dependencies
  • [#16] fix TypeError if path /constructor/foo is accessed
  • ]]>
    +
    + + <![CDATA[@hapi/call v3.0.0]]> + https://github.com/hapijs/call/milestone/4 + + 2015-11-01T19:45:59.000Z + +
  • [#17] ES6 style changes and node v4
  • ]]>
    +
    + + <![CDATA[@hapi/call v2.0.2]]> + https://github.com/hapijs/call/milestone/3 + + 2015-06-28T03:31:29.000Z + +
  • [#14] Update project style
  • ]]>
    +
    + + <![CDATA[@hapi/call v2.0.1]]> + https://github.com/hapijs/call/milestone/2 + + 2014-11-23T08:42:01.000Z + +
  • [#11] Performance tweaks
  • ]]>
    +
    + + <![CDATA[@hapi/call v2.0.0]]> + https://github.com/hapijs/call/milestone/1 + + 2014-11-23T08:41:31.000Z + +
  • [#10] Support route id
  • [#9] /a/{p}/{p*} conflicts with /a/{p*} (which is not reachable)
  • [#8] '/a/b/{p*}' is more specific than '/{p*5}'
  • [#7] /a/b/{p*} is more specific than /a/{b}/{c}
  • [#6] '/a/{b*}' is less specific than '/a/{b}/{c*}'
  • [#3] Support for flexible routes
  • [#2] Match case-insensitive paths with no params
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/catbox-memcached.atom b/docs/public/atom/catbox-memcached.atom new file mode 100644 index 00000000..f71ae285 --- /dev/null +++ b/docs/public/atom/catbox-memcached.atom @@ -0,0 +1,66 @@ + + + https://hapi.dev/module/catbox-memcached + @hapi/catbox-memcached changelog + 2020-01-04T23:47:47.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/catbox-memcached v3.0.0]]> + https://github.com/hapijs/catbox-memcached/milestone/8 + + 2020-01-04T23:47:47.000Z + +
  • [#44] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memcached v2.1.1]]> + https://github.com/hapijs/catbox-memcached/milestone/6 + + 2019-08-14T05:13:21.000Z + +
  • [#38] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memcached v2.1.0]]> + https://github.com/hapijs/catbox-memcached/milestone/5 + + 2019-04-22T05:34:34.000Z + +
  • [#35] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memcached v2.0.5]]> + https://github.com/hapijs/catbox-memcached/milestone/4 + + 2018-11-11T01:57:52.000Z + +
  • [#21] Remove test connections
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memcached v1.1.1]]> + https://github.com/hapijs/catbox-memcached/milestone/3 + + 2018-11-11T01:50:38.000Z + +
  • [#17] upgrade to lab 6 minor fixes license fix
  • [#9] Using catbox-memcache with yar, response body is replaced with `true`
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memcached v1.0.3]]> + https://github.com/hapijs/catbox-memcached/milestone/2 + + 2014-11-20T10:53:48.000Z + +
  • [#5] Hapi hangs if the memcached server is down
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memcached v1.0.2]]> + https://github.com/hapijs/catbox-memcached/milestone/1 + + 2014-08-03T06:32:01.000Z + +
  • [#4] Rename spumko to hapijs
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/catbox-memory.atom b/docs/public/atom/catbox-memory.atom new file mode 100644 index 00000000..04f9eea8 --- /dev/null +++ b/docs/public/atom/catbox-memory.atom @@ -0,0 +1,234 @@ + + + https://hapi.dev/module/catbox-memory + @hapi/catbox-memory changelog + 2024-06-12T07:47:17.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/catbox-memory v6.0.2]]> + https://github.com/hapijs/catbox-memory/milestone/31 + + 2024-06-12T07:47:17.000Z + +
  • [#90] feat: 🎸 bring in typings from DT
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memory v6.0.1]]> + https://github.com/hapijs/catbox-memory/milestone/30 + + 2023-02-11T20:53:06.000Z + +
  • [#87] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memory v6.0.0]]> + https://github.com/hapijs/catbox-memory/milestone/29 + + 2023-02-11T20:53:04.000Z + +
  • [#86] Support node v18 and drop node v12, make exports ESM-friendly
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memory v5.0.1]]> + https://github.com/hapijs/catbox-memory/milestone/27 + + 2021-04-09T14:32:33.000Z + +
  • [#83] fix: make class extendable
  • [#81] upgrade lab to v24
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memory v5.0.0]]> + https://github.com/hapijs/catbox-memory/milestone/26 + + 2020-01-04T23:51:40.000Z + +
  • [#77] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memory v4.1.1]]> + https://github.com/hapijs/catbox-memory/milestone/22 + + 2019-08-14T05:16:56.000Z + +
  • [#69] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memory v4.1.0]]> + https://github.com/hapijs/catbox-memory/milestone/19 + + 2019-04-02T04:16:28.000Z + +
  • [#66] Remove allowMixedContent option
  • [#65] Change module namespace
  • [#64] Typo _timeDue vs _timerDue
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memory v4.0.1]]> + https://github.com/hapijs/catbox-memory/milestone/16 + + 2018-11-03T00:22:37.000Z + +
  • [#61] Remove engines
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memory v4.0.0]]> + https://github.com/hapijs/catbox-memory/milestone/15 + + 2018-11-01T07:55:29.000Z + +
  • [#57] Update hoek v6
  • [#55] Buffers can change while in cache
  • [#8] Large overhead from expires times when highly populated
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memory v3.2.2]]> + https://github.com/hapijs/catbox-memory/milestone/24 + + 2020-07-04T19:49:13.000Z + + ]]> + + + <![CDATA[@hapi/catbox-memory v3.2.0]]> + https://github.com/hapijs/catbox-memory/milestone/23 + + 2019-04-10T20:02:31.000Z + +
  • [#67] Change module namespace v3
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memory v3.1.4]]> + https://github.com/hapijs/catbox-memory/milestone/18 + + 2018-11-03T00:22:38.000Z + +
  • [#60] Remove engines
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memory v3.1.3]]> + https://github.com/hapijs/catbox-memory/milestone/17 + + 2018-11-02T23:51:52.000Z + +
  • [#58] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memory v3.1.2]]> + https://github.com/hapijs/catbox-memory/milestone/14 + + 2018-03-31T00:21:48.000Z + +
  • [#56] Remove new Buffer usage
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memory v3.1.1]]> + https://github.com/hapijs/catbox-memory/milestone/13 + + 2017-11-03T18:21:08.000Z + +
  • [#54] Fix new Boom
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memory v3.1.0]]> + https://github.com/hapijs/catbox-memory/milestone/12 + + 2017-11-03T06:30:54.000Z + +
  • [#53] Replace hash with Map
  • [#52] Sync client for catbox 10
  • [#48] Use big-time for long timeout support
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memory v3.0.0]]> + https://github.com/hapijs/catbox-memory/milestone/11 + + 2017-09-26T08:32:25.000Z + +
  • [#47] Node 8
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memory v2.1.0]]> + https://github.com/hapijs/catbox-memory/milestone/20 + + 2019-03-24T23:41:01.000Z + +
  • [#63] Commercial version of v2 branch
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memory v2.0.4]]> + https://github.com/hapijs/catbox-memory/milestone/10 + + 2016-10-26T00:31:03.000Z + +
  • [#43] Update deps
  • [#42] fix: cancel timeouts on drop
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memory v2.0.3]]> + https://github.com/hapijs/catbox-memory/milestone/9 + + 2016-06-07T13:53:12.000Z + +
  • [#38] Add .npmignore
  • [#37] add note to readme about the limitation of ttl
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memory v2.0.1]]> + https://github.com/hapijs/catbox-memory/milestone/8 + + 2015-11-02T14:04:07.000Z + +
  • [#33] Update hapijs/catbox to 7.0.0
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memory v1.1.2]]> + https://github.com/hapijs/catbox-memory/milestone/7 + + 2015-08-18T19:31:47.000Z + +
  • [#32] v1.1.2
  • [#27] Clean up timers when the cache is stopped.
  • [#26] Remove Makefile in favor of npm scripts and enable linting
  • [#24] add node 0.11 to travis file
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memory v1.1.1]]> + https://github.com/hapijs/catbox-memory/milestone/6 + + 2014-10-30T14:33:24.000Z + +
  • [#23] version 1.1.1. update to catbox 4 and lab 5 (replace chai with code)
  • [#22] Update to Lab 5
  • [#21] Update to catbox 4
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memory v1.1.0]]> + https://github.com/hapijs/catbox-memory/milestone/5 + + 2014-09-11T17:31:19.000Z + +
  • [#17] Bump version to 1.1.0
  • [#16] Release 1.1.0
  • [#15] Add support for Buffers
  • [#14] Add build status to README
  • [#13] Add build status to readme
  • [#12] Update owner
  • [#5] Option to store buffer data
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memory v1.0.5]]> + https://github.com/hapijs/catbox-memory/milestone/4 + + 2014-08-15T17:30:16.000Z + +
  • [#11] Up version and use lab 4
  • [#10] Fix total byteSize tracking in connection
  • [#9] Create named classes for cache objects
  • [#7] Memory limit does not restrict data size properly
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memory v1.0.4]]> + https://github.com/hapijs/catbox-memory/milestone/3 + + 2014-08-03T05:31:39.000Z + +
  • [#6] Rename spumko to hapijs
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memory v1.0.3]]> + https://github.com/hapijs/catbox-memory/milestone/2 + + 2014-06-11T05:49:27.000Z + +
  • [#4] Move large ttl (over 32bit) check from catbox
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-memory v1.0.2]]> + https://github.com/hapijs/catbox-memory/milestone/1 + + 2014-05-20T21:31:46.000Z + +
  • [#2] Bring coverage back to 100%
  • [#1] why peer depend instead of verify in parent
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/catbox-object.atom b/docs/public/atom/catbox-object.atom new file mode 100644 index 00000000..035f7b40 --- /dev/null +++ b/docs/public/atom/catbox-object.atom @@ -0,0 +1,42 @@ + + + https://hapi.dev/module/catbox-object + @hapi/catbox-object changelog + 2023-02-11T20:43:44.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/catbox-object v3.0.1]]> + https://github.com/hapijs/catbox-object/milestone/5 + + 2023-02-11T20:43:44.000Z + +
  • [#14] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-object v3.0.0]]> + https://github.com/hapijs/catbox-object/milestone/4 + + 2022-07-19T01:07:18.000Z + +
  • [#13] Support for node v18, change default export, ESM tests
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-object v2.0.0]]> + https://github.com/hapijs/catbox-object/milestone/2 + + 2020-01-04T23:56:03.000Z + +
  • [#6] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-object v1.0.1]]> + https://github.com/hapijs/catbox-object/milestone/1 + + 2019-08-14T05:23:12.000Z + +
  • [#1] Update deps
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/catbox-redis.atom b/docs/public/atom/catbox-redis.atom new file mode 100644 index 00000000..f12d49fa --- /dev/null +++ b/docs/public/atom/catbox-redis.atom @@ -0,0 +1,258 @@ + + + https://hapi.dev/module/catbox-redis + @hapi/catbox-redis changelog + 2023-08-04T14:08:43.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/catbox-redis v7.0.2]]> + https://github.com/hapijs/catbox-redis/milestone/33 + + 2023-08-04T14:08:43.000Z + +
  • [#128] chore: enable lab type tests
  • [#126] feat: 🎸 add and improve typings from DT
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis v7.0.1]]> + https://github.com/hapijs/catbox-redis/milestone/32 + + 2023-02-11T20:47:35.000Z + +
  • [#125] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis v7.0.0]]> + https://github.com/hapijs/catbox-redis/milestone/31 + + 2022-10-29T20:22:54.000Z + +
  • [#123] Support for node v18, ESM tests, upgrade ioredis
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis v6.0.2]]> + https://github.com/hapijs/catbox-redis/milestone/29 + + 2020-09-26T17:17:28.000Z + +
  • [#117] update deps and use travis templates
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis v6.0.1]]> + https://github.com/hapijs/catbox-redis/milestone/28 + + 2020-07-10T03:45:28.000Z + +
  • [#115] Redis Configuration Options
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis v6.0.0]]> + https://github.com/hapijs/catbox-redis/milestone/27 + + 2020-01-05T00:09:14.000Z + +
  • [#112] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis v5.0.5]]> + https://github.com/hapijs/catbox-redis/milestone/26 + + 2019-10-05T16:44:57.000Z + +
  • [#109] Use PSETEX instead of SET and PEXP
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis v5.0.4]]> + https://github.com/hapijs/catbox-redis/milestone/25 + + 2019-09-12T23:28:30.000Z + +
  • [#107] Update joi
  • [#103] Example "db" parameter error
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis v5.0.3]]> + https://github.com/hapijs/catbox-redis/milestone/24 + + 2019-09-12T23:19:33.000Z + +
  • [#106] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis v5.0.2]]> + https://github.com/hapijs/catbox-redis/milestone/23 + + 2019-05-19T17:35:25.000Z + +
  • [#102] Allowing empty password
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis v5.0.1]]> + https://github.com/hapijs/catbox-redis/milestone/22 + + 2019-04-25T17:09:05.000Z + +
  • [#100] hotfix: redis tls opt is an object, not boolean
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis v5.0.0]]> + https://github.com/hapijs/catbox-redis/milestone/21 + + 2019-04-21T21:08:14.000Z + +
  • [#98] Switch to use Redis pexpire
  • [#97] Refactor options
  • [#96] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis vv4.1.0]]> + https://github.com/hapijs/catbox-redis/milestone/20 + + 2019-04-20T22:53:16.000Z + +
  • [#79] Don't mess with provided clients
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis vv4.0.1]]> + https://github.com/hapijs/catbox-redis/milestone/18 + + 2019-04-20T22:53:17.000Z + +
  • [#69] added support for dropSegment
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis vv4.0.0]]> + https://github.com/hapijs/catbox-redis/milestone/15 + + 2017-11-23T13:08:20.000Z + +
  • [#77] Update to work with Catbox 10 (Hapi 17)
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis vv3.2.0]]> + https://github.com/hapijs/catbox-redis/milestone/16 + + 2017-11-23T13:08:13.000Z + + ]]> + + + <![CDATA[@hapi/catbox-redis vv3.1.1]]> + https://github.com/hapijs/catbox-redis/milestone/17 + + 2017-11-23T13:08:10.000Z + +
  • [#74] Ensure the client really is ready
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis vv3.1.0]]> + https://github.com/hapijs/catbox-redis/milestone/14 + + 2017-09-18T10:32:27.000Z + +
  • [#72] Upgrade `ioredis` to `3.x.x`
  • [#71] chore(package): update ioredis to v3
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis vv3.0.3]]> + https://github.com/hapijs/catbox-redis/milestone/13 + + 2017-09-18T10:32:22.000Z + + ]]> + + + <![CDATA[@hapi/catbox-redis vv3.0.0]]> + https://github.com/hapijs/catbox-redis/milestone/12 + + 2017-03-28T15:36:28.000Z + +
  • [#62] update dependencies
  • [#53] Move to `ioredis`
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis vv2.0.3]]> + https://github.com/hapijs/catbox-redis/milestone/11 + + 2017-03-28T15:36:26.000Z + +
  • [#52] upgrade code@3 and lab@11
  • [#51] Add option to ignore startup failures
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis vv2.0.2]]> + https://github.com/hapijs/catbox-redis/milestone/10 + + 2017-03-28T15:36:30.000Z + +
  • [#49] Use `false` parameter to `client.end` in order to fail silently
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis vv2.0.1]]> + https://github.com/hapijs/catbox-redis/milestone/9 + + 2016-06-14T09:23:43.000Z + +
  • [#47] Adding flush parameter when calling client.end
  • [#45] Test on node v6, update dependencies
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis vv1.1.0]]> + https://github.com/hapijs/catbox-redis/milestone/7 + + 2016-06-14T09:16:49.000Z + +
  • [#36] Ignore partition if not defined
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis vv1.0.9]]> + https://github.com/hapijs/catbox-redis/milestone/8 + + 2016-06-14T09:16:51.000Z + +
  • [#40] Allow passing a ready Redis client
  • [#39] Drop node 0.10 support
  • [#30] Add unix socket support
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis vv1.0.8]]> + https://github.com/hapijs/catbox-redis/milestone/6 + + 2016-03-15T11:05:10.000Z + +
  • [#38] Cleanup tests
  • [#37] Wait redis client to be ready in order to make sure that authentication has been done
  • [#31] Loosen dependency to redis 2.x.x to allow 2.3.0 to match
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis vv1.0.6]]> + https://github.com/hapijs/catbox-redis/milestone/5 + + 2016-01-15T10:13:54.000Z + +
  • [#27] Upgrade outdated node-redis dependency
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis v1.0.4]]> + https://github.com/hapijs/catbox-redis/milestone/4 + + 2014-08-03T05:36:05.000Z + +
  • [#8] Rename spumko to hapijs
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis v1.0.3]]> + https://github.com/hapijs/catbox-redis/milestone/3 + + 2014-06-12T06:23:22.000Z + +
  • [#7] Remove large ttl test
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis v1.0.2]]> + https://github.com/hapijs/catbox-redis/milestone/2 + + 2014-05-20T21:41:20.000Z + +
  • [#5] Bring coverage back to 100%
  • ]]>
    +
    + + <![CDATA[@hapi/catbox-redis v1.0.1]]> + https://github.com/hapijs/catbox-redis/milestone/1 + + 2014-03-08T23:18:40.000Z + +
  • [#3] Add example
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/catbox.atom b/docs/public/atom/catbox.atom new file mode 100644 index 00000000..be79ea01 --- /dev/null +++ b/docs/public/atom/catbox.atom @@ -0,0 +1,410 @@ + + + https://hapi.dev/module/catbox + @hapi/catbox changelog + 2023-02-11T20:38:22.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/catbox v12.1.1]]> + https://github.com/hapijs/catbox/milestone/58 + + 2023-02-11T20:38:22.000Z + +
  • [#243] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v12.1.0]]> + https://github.com/hapijs/catbox/milestone/57 + + 2022-11-17T23:30:25.000Z + +
  • [#242] Add typescript types
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v12.0.1]]> + https://github.com/hapijs/catbox/milestone/56 + + 2022-11-17T23:09:04.000Z + +
  • [#240] Validate engines to detect legacy adaptor modules
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v12.0.0]]> + https://github.com/hapijs/catbox/milestone/55 + + 2022-11-17T23:09:02.000Z + +
  • [#239] Support node v18 and drop node v12
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v11.1.1]]> + https://github.com/hapijs/catbox/milestone/54 + + 2022-05-08T21:31:43.000Z + +
  • [#231] Replace joi with validate
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v11.1.0]]> + https://github.com/hapijs/catbox/milestone/53 + + 2020-03-14T21:26:04.000Z + +
  • [#229] Expose cache client in policy
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v11.0.1]]> + https://github.com/hapijs/catbox/milestone/52 + + 2020-01-20T08:48:04.000Z + +
  • [#228] pendingGenerateTimeout causes weird timing situation
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v11.0.0]]> + https://github.com/hapijs/catbox/milestone/51 + + 2020-01-04T23:25:30.000Z + +
  • [#227] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v10.2.3]]> + https://github.com/hapijs/catbox/milestone/49 + + 2019-09-12T22:36:08.000Z + +
  • [#220] Update joi
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v10.2.2]]> + https://github.com/hapijs/catbox/milestone/48 + + 2019-08-14T05:08:49.000Z + +
  • [#217] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v10.2.1]]> + https://github.com/hapijs/catbox/milestone/47 + + 2019-04-02T05:01:00.000Z + +
  • [#216] Update joi dep
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v10.2.0]]> + https://github.com/hapijs/catbox/milestone/46 + + 2019-04-01T21:26:47.000Z + +
  • [#215] Old pendingGenerateTimeout can clear new one
  • [#210] If generate takes longer than staleTimeout, errors get swallowed
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v10.1.0]]> + https://github.com/hapijs/catbox/milestone/43 + + 2019-03-30T21:13:47.000Z + +
  • [#214] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v10.0.6]]> + https://github.com/hapijs/catbox/milestone/42 + + 2018-12-18T15:38:45.000Z + +
  • [#208] Add changelog.md
  • [#206] Support ioredis client option for catbox-redis
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v10.0.5]]> + https://github.com/hapijs/catbox/milestone/41 + + 2018-11-03T00:19:51.000Z + +
  • [#205] Remove engines
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v10.0.4]]> + https://github.com/hapijs/catbox/milestone/40 + + 2018-11-01T07:51:26.000Z + +
  • [#204] Update hoek v6
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v10.0.3]]> + https://github.com/hapijs/catbox/milestone/39 + + 2018-09-17T17:07:12.000Z + +
  • [#201] Update lab
  • [#200] Unhandled rejection on get() errors
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v10.0.2]]> + https://github.com/hapijs/catbox/milestone/38 + + 2017-11-03T20:29:31.000Z + +
  • [#194] Add bounce protection
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v10.0.1]]> + https://github.com/hapijs/catbox/milestone/37 + + 2017-11-03T06:39:14.000Z + +
  • [#193] Update boom
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v10.0.0]]> + https://github.com/hapijs/catbox/milestone/36 + + 2017-11-03T06:34:43.000Z + +
  • [#192] Require clients to be async
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v9.0.0]]> + https://github.com/hapijs/catbox/milestone/35 + + 2017-10-17T20:01:05.000Z + +
  • [#191] Change policy.get() return value to plain (with override option)
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v8.0.1]]> + https://github.com/hapijs/catbox/milestone/34 + + 2017-09-27T10:09:09.000Z + + ]]> + + + <![CDATA[@hapi/catbox v8.0.0]]> + https://github.com/hapijs/catbox/milestone/33 + + 2017-09-26T06:47:58.000Z + +
  • [#190] Migrate to async/await
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v7.2.0]]> + https://github.com/hapijs/catbox/milestone/44 + + 2019-03-30T21:02:21.000Z + +
  • [#213] Commercial version of v7 branch
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v7.1.5]]> + https://github.com/hapijs/catbox/milestone/32 + + 2017-07-14T11:52:26.000Z + +
  • [#185] Fix pendingGenerateTimeout timeout issue
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v7.1.4]]> + https://github.com/hapijs/catbox/milestone/31 + + 2017-05-28T00:06:13.000Z + +
  • [#178] Ensure generate timeout is triggered when staleTimeout > ttl
  • [#166] Can we remove the max() from staleIn?
  • [#165] Can't drop method without arguments
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v7.1.3]]> + https://github.com/hapijs/catbox/milestone/30 + + 2016-11-29T01:57:59.000Z + +
  • [#176] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v7.1.2]]> + https://github.com/hapijs/catbox/milestone/29 + + 2016-07-27T19:31:34.000Z + +
  • [#168] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v7.1.1]]> + https://github.com/hapijs/catbox/milestone/28 + + 2016-05-19T18:04:58.000Z + +
  • [#162] Test on node v6, update dependencies
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v7.1.0]]> + https://github.com/hapijs/catbox/milestone/27 + + 2016-01-04T22:21:59.000Z + +
  • [#152] Adding pendingGenerateTimeout
  • [#149] Proposal: Stale while revalidate - prevent multiple generate calls
  • [#147] Update drop function to allow for object keys
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v7.0.0]]> + https://github.com/hapijs/catbox/milestone/26 + + 2015-11-02T00:22:12.000Z + +
  • [#146] ES6 style changes and node v4
  • [#145] Fixed this.constructor issue
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v6.0.0]]> + https://github.com/hapijs/catbox/milestone/25 + + 2015-08-12T06:25:43.000Z + +
  • [#140] Replace generate cache error handing options
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v5.0.0]]> + https://github.com/hapijs/catbox/milestone/24 + + 2015-08-10T00:11:31.000Z + +
  • [#137] Add generateOnGetError option
  • [#136] Pass cache set() errors when generating value on get()
  • [#134] Require generateTimeout with generateFunc.
  • [#128] Explicitly binding process.domain to the callback
  • [#127] callbacks are called with wrong process.domain
  • [#115] get() can get stuck when first request never returns
  • [#70] No way to monitor cache error rates
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v4.3.0]]> + https://github.com/hapijs/catbox/milestone/23 + + 2015-06-06T16:49:09.000Z + +
  • [#114] Expose cache engine connection isReady as public method
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v4.2.2]]> + https://github.com/hapijs/catbox/milestone/22 + + 2015-03-11T22:18:29.000Z + +
  • [#120] Upgrade to Joi 6
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v4.2.1]]> + https://github.com/hapijs/catbox/milestone/21 + + 2015-01-22T20:40:43.000Z + +
  • [#116] Prefix keys with a `'+'` when using object as a hash
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v4.2.0]]> + https://github.com/hapijs/catbox/milestone/20 + + 2014-11-19T23:06:29.000Z + +
  • [#113] Allow empty keys
  • [#109] Return cached on error when dropOnError is false
  • [#105] StaleIn can be function.
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v4.1.0]]> + https://github.com/hapijs/catbox/milestone/19 + + 2014-11-05T02:57:07.000Z + +
  • [#111] Allow changing policy rules after construction
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v4.0.3]]> + https://github.com/hapijs/catbox/milestone/18 + + 2014-10-09T07:59:02.000Z + +
  • [#104] Fix tests
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v4.0.2]]> + https://github.com/hapijs/catbox/milestone/17 + + 2014-10-09T07:44:23.000Z + +
  • [#103] Explicitly allow hapi keys in policy instead of allowUnknown
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v4.0.1]]> + https://github.com/hapijs/catbox/milestone/16 + + 2014-10-09T07:28:57.000Z + +
  • [#102] Use joi for validating policy rules
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v4.0.0]]> + https://github.com/hapijs/catbox/milestone/15 + + 2014-10-09T07:03:44.000Z + +
  • [#101] Change policy.get() callback to use a consistent signature regardless of generateFunc
  • [#100] Require generateFunc options for staleIn, staleTimeout, and generateTimeout
  • [#99] Remove getOrGenerate()
  • [#98] Adding ability to retain a stale value when generate function fails
  • [#97] Retain stale on error
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v3.4.3]]> + https://github.com/hapijs/catbox/milestone/14 + + 2014-10-08T23:49:36.000Z + +
  • [#95] Leftover background timeouts can interlace with new requests
  • [#93] Rarely cache can serve old value having slower backend
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v3.4.2]]> + https://github.com/hapijs/catbox/milestone/13 + + 2014-09-16T21:14:22.000Z + +
  • [#86] Fix concurrent getOrGenerate bug. Closes #85
  • [#85] Problems with concurrent invocation of getOrGenerate.
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v3.4.1]]> + https://github.com/hapijs/catbox/milestone/12 + + 2014-09-09T21:14:01.000Z + +
  • [#84] null or undefined expiresIn/At break compile
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v3.4.0]]> + https://github.com/hapijs/catbox/milestone/11 + + 2014-09-09T21:14:02.000Z + +
  • [#83] Errors thrown in get() block pending queue
  • [#82] Allow setting cache with default expiresIn 0 (no cache)
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v3.3.0]]> + https://github.com/hapijs/catbox/milestone/10 + + 2014-09-08T19:10:15.000Z + +
  • [#80] Allow setting policy without expiration when server side disabled
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v3.2.0]]> + https://github.com/hapijs/catbox/milestone/9 + + 2014-09-08T15:15:32.000Z + +
  • [#79] Queue get requests
  • [#78] Incomplete coverage when testing at 23:00
  • [#77] expiredAt fails to zero milliseconds
  • [#76] expiredAt returns negative ttl on created < expired < now
  • [#75] Move generate method to policy config
  • [#73] Chain concurrent gets
  • [#71] Update to Lab 4
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v3.1.0]]> + https://github.com/hapijs/catbox/milestone/8 + + 2014-08-03T04:35:51.000Z + +
  • [#69] Error fails to clear cache is error arrives before stale timeout
  • [#68] staleTimeout for first request should returns null if no data at timeout time
  • ]]>
    +
    + + <![CDATA[@hapi/catbox v3.0.0]]> + https://github.com/hapijs/catbox/milestone/6 + + 2014-06-11T05:43:03.000Z + +
  • [#67] Remove internal require() call
  • [#66] Remove large ttl check
  • [#65] Move 32bit ttl restriction to catbox-memory
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/code.atom b/docs/public/atom/code.atom new file mode 100644 index 00000000..72d645ba --- /dev/null +++ b/docs/public/atom/code.atom @@ -0,0 +1,330 @@ + + + https://hapi.dev/module/code + @hapi/code changelog + 2023-02-11T18:01:54.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/code v9.0.3]]> + https://github.com/hapijs/code/milestone/41 + + 2023-02-11T18:01:54.000Z + +
  • [#179] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/code v9.0.2]]> + https://github.com/hapijs/code/milestone/40 + + 2022-11-29T08:49:48.000Z + +
  • [#178] Fix typo and add missing type
  • ]]>
    +
    + + <![CDATA[@hapi/code v9.0.1]]> + https://github.com/hapijs/code/milestone/39 + + 2022-06-14T15:40:06.000Z + +
  • [#177] Fix `reject()` types
  • ]]>
    +
    + + <![CDATA[@hapi/code v9.0.0]]> + https://github.com/hapijs/code/milestone/38 + + 2022-06-14T15:39:02.000Z + +
  • [#175] Drop node v12, support node v18
  • ]]>
    +
    + + <![CDATA[@hapi/code v8.0.8]]> + https://github.com/hapijs/code/milestone/37 + + 2022-04-25T13:55:13.000Z + + ]]> + + + <![CDATA[@hapi/code v8.0.7]]> + https://github.com/hapijs/code/milestone/36 + + 2022-02-08T07:04:40.000Z + +
  • [#174] Fix equal() type
  • ]]>
    +
    + + <![CDATA[@hapi/code v8.0.6]]> + https://github.com/hapijs/code/milestone/35 + + 2022-01-24T14:51:35.000Z + +
  • [#173] Fix equal() types
  • [#172] equal(value: T) type should be Loosely<T> when options ignore symbols or properties
  • [#171] Fix typings for throw() and reject()
  • ]]>
    +
    + + <![CDATA[@hapi/code v8.0.5]]> + https://github.com/hapijs/code/milestone/34 + + 2021-11-20T04:14:28.000Z + +
  • [#168] Don't narrow generic on type specific assertions
  • [#167] compilation errors for primitive type assertions
  • ]]>
    +
    + + <![CDATA[@hapi/code v8.0.4]]> + https://github.com/hapijs/code/milestone/33 + + 2021-11-05T14:23:06.000Z + +
  • [#165] Fix aliases for reject()
  • [#163] Improve typings
  • ]]>
    +
    + + <![CDATA[@hapi/code v8.0.3]]> + https://github.com/hapijs/code/milestone/32 + + 2021-03-15T18:59:37.000Z + +
  • [#161] Fix reject(s) return type
  • [#160] The type `.rejects` returns should return a Promise
  • ]]>
    +
    + + <![CDATA[@hapi/code v8.0.2]]> + https://github.com/hapijs/code/milestone/31 + + 2021-03-15T18:56:29.000Z + +
  • [#158] upgrade lab to v24 and devDependency of typescript
  • ]]>
    +
    + + <![CDATA[@hapi/code v8.0.1]]> + https://github.com/hapijs/code/milestone/30 + + 2020-01-03T23:26:48.000Z + +
  • [#155] Fix function string in node 13
  • [#154] Update hoek
  • ]]>
    +
    + + <![CDATA[@hapi/code v8.0.0]]> + https://github.com/hapijs/code/milestone/29 + + 2020-01-03T23:00:17.000Z + +
  • [#153] Support only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/code v7.0.0]]> + https://github.com/hapijs/code/milestone/27 + + 2019-10-13T01:12:53.000Z + +
  • [#151] Add types
  • [#150] Drop node 8
  • ]]>
    +
    + + <![CDATA[@hapi/code v6.0.0]]> + https://github.com/hapijs/code/milestone/26 + + 2019-07-24T18:08:54.000Z + +
  • [#142] Deep comparison includes symbols
  • [#141] Support deep comparison key skipping
  • [#140] Use deepFunction flag for deep comparison
  • ]]>
    +
    + + <![CDATA[@hapi/code v5.3.1]]> + https://github.com/hapijs/code/milestone/25 + + 2019-03-29T23:11:53.000Z + +
  • [#136] Better handling of thrown stack parsing
  • ]]>
    +
    + + <![CDATA[@hapi/code v5.3.0]]> + https://github.com/hapijs/code/milestone/24 + + 2019-03-29T22:05:13.000Z + +
  • [#135] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/code v5.2.3]]> + https://github.com/hapijs/code/milestone/23 + + 2018-11-02T23:38:42.000Z + +
  • [#130] Remove engines
  • ]]>
    +
    + + <![CDATA[@hapi/code v5.2.2]]> + https://github.com/hapijs/code/milestone/22 + + 2018-11-01T07:16:43.000Z + +
  • [#129] Update hoek v6
  • ]]>
    +
    + + <![CDATA[@hapi/code v5.2.0]]> + https://github.com/hapijs/code/milestone/21 + + 2018-02-09T23:15:42.000Z + +
  • [#124] Return error when asserting for thrown. Closes #123
  • [#123] Assertions on error properties
  • [#121] Invalidates rejection with wrong type or message arguments
  • [#119] reject does not fail if argument is of the wrong type
  • ]]>
    +
    + + <![CDATA[@hapi/code v5.1.2]]> + https://github.com/hapijs/code/milestone/20 + + 2017-11-03T07:01:44.000Z + +
  • [#117] Update dependencies
  • ]]>
    +
    + + <![CDATA[@hapi/code v5.1.1]]> + https://github.com/hapijs/code/milestone/19 + + 2017-11-03T07:01:00.000Z + +
  • [#116] Fix broken API.md anchor
  • [#111] fix(length): throw decent error on length check of `null`
  • [#110] Cannot read property 'length' of null
  • ]]>
    +
    + + <![CDATA[@hapi/code v5.1.0]]> + https://github.com/hapijs/code/milestone/18 + + 2017-09-17T20:23:14.000Z + +
  • [#106] Allow custom validation function for reject
  • ]]>
    +
    + + <![CDATA[@hapi/code v5.0.0]]> + https://github.com/hapijs/code/milestone/17 + + 2017-09-17T17:44:30.000Z + +
  • [#105] Add promises rejection support
  • [#104] Add test for async functions
  • [#103] Expected async function to be a function
  • ]]>
    +
    + + <![CDATA[@hapi/code v4.1.0]]> + https://github.com/hapijs/code/milestone/16 + + 2017-06-08T16:27:08.000Z + +
  • [#102] please publish new version
  • [#101] print expected value on equals assertion
  • [#94] Reference value NaN assertion.
  • ]]>
    +
    + + <![CDATA[@hapi/code v4.0.0]]> + https://github.com/hapijs/code/milestone/15 + + 2016-09-21T23:41:19.000Z + +
  • [#91] New release?
  • [#89] Docs: Modified match API documentation
  • [#87] fix tests for Node v6.5.0
  • [#86] Tests failing on node 6.5.0
  • [#84] Enhancement: Added validation to `include`
  • [#83] Include should validate number of arguments
  • [#82] fix broken test from Node v6.4.0 update
  • [#81] Fix broken test
  • [#77] Invalidate array of objects with only a partial object value
  • ]]>
    +
    + + <![CDATA[@hapi/code v3.0.1]]> + https://github.com/hapijs/code/milestone/14 + + 2016-06-07T13:16:52.000Z + +
  • [#75] Add .npmignore file
  • ]]>
    +
    + + <![CDATA[@hapi/code v3.0.0]]> + https://github.com/hapijs/code/milestone/13 + + 2016-05-21T01:35:27.000Z + +
  • [#73] change default comparison behavior
  • [#72] Fix link to hoek documentation
  • [#68] Default to deep copy
  • ]]>
    +
    + + <![CDATA[@hapi/code v2.3.0]]> + https://github.com/hapijs/code/milestone/12 + + 2016-05-06T19:25:15.000Z + +
  • [#71] Fix at location information. Closes #70
  • [#70] expect(err).to.not.exist() reports wrong 'at' information
  • ]]>
    +
    + + <![CDATA[@hapi/code v2.2.0]]> + https://github.com/hapijs/code/milestone/11 + + 2016-04-06T13:55:11.000Z + +
  • [#64] Add documentation to error() (fixes #63)
  • [#63] Document new error() method
  • [#62] Add error type (fixes #61)
  • [#61] Proposal: error type
  • ]]>
    +
    + + <![CDATA[@hapi/code v2.1.1]]> + https://github.com/hapijs/code/milestone/10 + + 2016-04-06T13:19:32.000Z + +
  • [#58] handle errors without proper stacks
  • [#57] Problem with internals.at
  • [#56] minor typo fix
  • [#55] Update dep format for markdown-toc
  • [#54] Readme tweaks
  • ]]>
    +
    + + <![CDATA[@hapi/code v2.1.0]]> + https://github.com/hapijs/code/milestone/9 + + 2015-12-30T15:50:42.000Z + +
  • [#51] add fail method
  • [#48] customize error message for once flag
  • [#47] once flag should change error message
  • ]]>
    +
    + + <![CDATA[@hapi/code v2.0.1]]> + https://github.com/hapijs/code/milestone/8 + + 2015-10-30T19:43:24.000Z + +
  • [#45] Update hapijs/hoek to 3.0.0 from 2.16.3
  • ]]>
    +
    + + <![CDATA[@hapi/code v2.0.0]]> + https://github.com/hapijs/code/milestone/7 + + 2015-10-30T19:43:21.000Z + +
  • [#44] es6 style. Closes #43
  • [#43] node v4, es6
  • [#38] markdown fixes
  • [#37] fixed markdown link for equal
  • ]]>
    +
    + + <![CDATA[@hapi/code v1.5.0]]> + https://github.com/hapijs/code/milestone/6 + + 2015-07-29T23:49:49.000Z + +
  • [#36] Display error when should not exist. Closes #35
  • [#35] Throw original error when not.exist(err) is asserted
  • [#32] Added new global setting to ignore prototypes.
  • ]]>
    +
    + + <![CDATA[@hapi/code v1.4.1]]> + https://github.com/hapijs/code/milestone/5 + + 2015-06-16T19:02:31.000Z + +
  • [#31] Handle multi-line errors
  • [#30] `settings.truncateMessages = false` causes issues with deep object comparisons
  • [#29] Fixed the description for the empty() assertion in README.md
  • ]]>
    +
    + + <![CDATA[@hapi/code v1.4.0]]> + https://github.com/hapijs/code/milestone/4 + + 2015-03-27T08:20:56.000Z + +
  • [#28] Release code 1.4.0
  • [#27] Add documentation for global settings
  • [#26] Add configuration settings, including disabling message truncating
  • [#25] Allow prototypes to be ignored in deep.equal()
  • [#24] Allow prototypes to be ignored in deep comparisons
  • [#23] readme typo and better message
  • [#18] Remove Makefile in favor of npm scripts
  • [#17] Verify deep.equal() functionality after changes to Hoek.deepEqual()
  • [#15] .to.deep.equal() performs unexpectedly with empty object
  • [#14] do not truncate values in assertions
  • ]]>
    +
    + + <![CDATA[@hapi/code v1.3.0]]> + https://github.com/hapijs/code/milestone/3 + + 2015-01-21T19:05:41.000Z + +
  • [#13] code 1.3.0
  • [#11] Object [object Object] has no method 'startWith'
  • [#10] Reset flags after each assertion
  • [#6] Add startsWith and endsWith for URLs.
  • ]]>
    +
    + + <![CDATA[@hapi/code v1.2.1]]> + https://github.com/hapijs/code/milestone/2 + + 2014-11-02T18:59:41.000Z + +
  • [#5] throw('') matches any message
  • ]]>
    +
    + + <![CDATA[@hapi/code v1.2.0]]> + https://github.com/hapijs/code/milestone/1 + + 2014-10-22T06:14:51.000Z + +
  • [#2] between()
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/content.atom b/docs/public/atom/content.atom new file mode 100644 index 00000000..3b06a33d --- /dev/null +++ b/docs/public/atom/content.atom @@ -0,0 +1,130 @@ + + + https://hapi.dev/module/content + @hapi/content changelog + 2022-05-24T01:54:39.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/content v6.0.0]]> + https://github.com/hapijs/content/milestone/16 + + 2022-05-24T01:54:39.000Z + +
  • [#35] Support node v18 and drop node v12
  • [#34] support parsing charset
  • ]]>
    +
    + + <![CDATA[@hapi/content v5.0.2]]> + https://github.com/hapijs/content/milestone/14 + + 2020-02-13T08:07:57.000Z + +
  • [#22] Block __proto__ name
  • ]]>
    +
    + + <![CDATA[@hapi/content v5.0.1]]> + https://github.com/hapijs/content/milestone/13 + + 2020-02-13T07:23:14.000Z + +
  • [#21] Explicitly handle __proto__
  • ]]>
    +
    + + <![CDATA[@hapi/content v5.0.0]]> + https://github.com/hapijs/content/milestone/12 + + 2020-01-05T01:02:33.000Z + +
  • [#20] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/content v4.1.1]]> + https://github.com/hapijs/content/milestone/11 + + 2020-02-13T08:22:05.000Z + +
  • [#24] Backport #21, #22
  • ]]>
    +
    + + <![CDATA[@hapi/content v4.1.0]]> + https://github.com/hapijs/content/milestone/8 + + 2019-04-02T17:54:24.000Z + +
  • [#13] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/content v4.0.6]]> + https://github.com/hapijs/content/milestone/7 + + 2018-11-03T00:24:12.000Z + +
  • [#9] Remove engines
  • ]]>
    +
    + + <![CDATA[@hapi/content v4.0.5]]> + https://github.com/hapijs/content/milestone/6 + + 2018-03-31T00:02:31.000Z + +
  • [#7] Throw on .type() if header is completely missing
  • ]]>
    +
    + + <![CDATA[@hapi/content v4.0.4]]> + https://github.com/hapijs/content/milestone/5 + + 2018-03-01T09:19:33.000Z + +
  • [#5] Skip processing parameters when content type is not multipart
  • ]]>
    +
    + + <![CDATA[@hapi/content v4.0.3]]> + https://github.com/hapijs/content/milestone/4 + + 2017-11-03T20:02:55.000Z + +
  • [#4] Throw directly from header processing
  • ]]>
    +
    + + <![CDATA[@hapi/content v4.0.2]]> + https://github.com/hapijs/content/milestone/3 + + 2017-11-03T20:02:21.000Z + +
  • [#3] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/content v4.0.1]]> + https://github.com/hapijs/content/milestone/2 + + 2017-09-26T09:07:07.000Z + +
  • [#2] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/content v4.0.0]]> + https://github.com/hapijs/content/milestone/1 + + 2017-09-26T00:11:17.000Z + +
  • [#1] Throw errors
  • ]]>
    +
    + + <![CDATA[@hapi/content v3.1.1]]> + https://github.com/hapijs/content/milestone/10 + + 2020-02-13T08:16:30.000Z + +
  • [#23] Backport #21, #22
  • ]]>
    +
    + + <![CDATA[@hapi/content v3.1.0]]> + https://github.com/hapijs/content/milestone/9 + + 2019-03-25T18:02:27.000Z + +
  • [#12] Commercial version of v3 branch
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/cookie.atom b/docs/public/atom/cookie.atom new file mode 100644 index 00000000..0ab79fc7 --- /dev/null +++ b/docs/public/atom/cookie.atom @@ -0,0 +1,298 @@ + + + https://hapi.dev/module/cookie + @hapi/cookie changelog + 2023-02-11T19:30:47.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/cookie v12.0.1]]> + https://github.com/hapijs/cookie/milestone/37 + + 2023-02-11T19:30:47.000Z + +
  • [#248] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v12.0.0]]> + https://github.com/hapijs/cookie/milestone/36 + + 2022-10-17T19:51:45.000Z + +
  • [#246] Support for hapi v21, node v18, ESM tests
  • [#244] Drop support for node v12 and hapi v18
  • [#236] Rename plugin options to be consistent across the hapi ecosystem
  • [#235] Remove old repository name
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v11.0.2]]> + https://github.com/hapijs/cookie/milestone/34 + + 2020-09-26T16:59:56.000Z + +
  • [#232] update to hapi v20
  • [#231] migrate to new travis format
  • [#229] change joi to validate and update lab
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v11.0.1]]> + https://github.com/hapijs/cookie/milestone/33 + + 2020-03-13T19:26:59.000Z + +
  • [#228] Non system error in validateFunc will be swallowed
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v11.0.0]]> + https://github.com/hapijs/cookie/milestone/32 + + 2020-01-10T07:21:58.000Z + +
  • [#227] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v10.1.2]]> + https://github.com/hapijs/cookie/milestone/31 + + 2019-09-12T17:45:35.000Z + +
  • [#222] Update joi
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v10.1.1]]> + https://github.com/hapijs/cookie/milestone/30 + + 2019-08-14T22:39:58.000Z + +
  • [#221] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v10.1.0]]> + https://github.com/hapijs/cookie/milestone/29 + + 2019-04-19T21:19:30.000Z + +
  • [#213] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v10.0.0]]> + https://github.com/hapijs/cookie/milestone/28 + + 2019-04-19T21:10:37.000Z + +
  • [#210] Move all cookie settings to `cookie`
  • [#209] 10.0.0 Release notes
  • [#208] Remove ignoreIfDecorated
  • [#207] No override of default cookie settings
  • [#205] Upgrade to hapi 18
  • [#204] Update for hapi 18
  • [#193] Support password rotation
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v9.1.0]]> + https://github.com/hapijs/cookie/milestone/27 + + 2018-11-24T05:12:17.000Z + +
  • [#196] referenced the raw request when setting next
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v9.0.0]]> + https://github.com/hapijs/cookie/milestone/24 + + 2018-05-27T23:39:04.000Z + +
  • [#186] Respect auth mode for redirects
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v8.1.0]]> + https://github.com/hapijs/cookie/milestone/23 + + 2018-02-08T21:14:21.000Z + +
  • [#176] Use options key for route configuration
  • [#164] Issue 163
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v8.0.1]]> + https://github.com/hapijs/cookie/milestone/25 + + 2018-02-08T09:43:49.000Z + +
  • [#183] Fix redirectTo function w/ blank to behave like blank redirectTo (fix)
  • [#170] Drop session from cache in examples
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v8.0.0]]> + https://github.com/hapijs/cookie/milestone/22 + + 2017-12-10T20:05:55.000Z + +
  • [#179] Update lead maintainer
  • [#174] Upgraded module to hapi v17
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v7.1.0]]> + https://github.com/hapijs/cookie/milestone/26 + + 2018-05-27T23:38:05.000Z + +
  • [#151] referenced the raw request when setting next
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v7.0.0]]> + https://github.com/hapijs/cookie/milestone/21 + + 2017-03-28T16:53:54.000Z + +
  • [#152] Do not redecorate the request object if already decorated
  • [#148] Allow redirectTo to be a function
  • [#142] Add isSameSite to schema
  • [#138] Options aren't required
  • [#134] add note to readme about the 'ttl' option
  • [#130] Test on node v6, update dependencies
  • [#127] fix typo in readme
  • [#124] Allow null to be passed for the ttl
  • [#115] update readme with information/warning about cookie length
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v6.1.1]]> + https://github.com/hapijs/cookie/milestone/20 + + 2017-03-28T16:47:45.000Z + +
  • [#118] decorator fix
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v6.1.0]]> + https://github.com/hapijs/cookie/milestone/19 + + 2016-02-22T13:43:36.000Z + +
  • [#114] support many strategies
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v6.0.0]]> + https://github.com/hapijs/cookie/milestone/18 + + 2016-01-29T13:31:05.000Z + +
  • [#107] Use server.decorate
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v5.0]]> + https://github.com/hapijs/cookie/milestone/17 + + 2016-01-05T17:37:49.000Z + +
  • [#103] move away from request.auth.session
  • [#101] Switch to use a request decoration instead of request.auth.session
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v4.0.0]]> + https://github.com/hapijs/cookie/milestone/16 + + 2016-01-05T16:26:41.000Z + +
  • [#102] node 4 update
  • [#93] Node >= 4 / es6 updates
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v3.1.0]]> + https://github.com/hapijs/cookie/milestone/15 + + 2015-08-17T12:33:41.000Z + +
  • [#83] allow buffer as password
  • [#80] Buffer type should be allowed for "password" option
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v3.0.0]]> + https://github.com/hapijs/cookie/milestone/14 + + 2015-06-13T13:23:09.000Z + +
  • [#75] validateFunc according to signature function
  • [#74] Updated docs
  • [#72] Pass request object to validation function
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v2.2.0]]> + https://github.com/hapijs/cookie/milestone/13 + + 2015-05-04T19:53:09.000Z + +
  • [#69] 2.2.0 update
  • [#68] Fix support for custom appendNext param
  • [#67] `appendNext` no longer accepts a string
  • [#65] allow null setting for domain
  • [#64] domain is now required as a string, and null does not pass validation
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v2.1.0]]> + https://github.com/hapijs/cookie/milestone/12 + + 2015-04-22T17:02:08.000Z + +
  • [#63] Version 2.1.0
  • [#62] Allow environment variables to configure cookie scheme
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v2.0.0]]> + https://github.com/hapijs/cookie/milestone/10 + + 2014-12-11T06:59:31.000Z + +
  • [#45] Version 2.0.0
  • [#43] Use request.route.settings.plugin
  • [#40] Invalid cookie should still return 401
  • [#39] hapi 8.0 API
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v1.4.2]]> + https://github.com/hapijs/cookie/milestone/11 + + 2014-12-04T17:36:52.000Z + +
  • [#42] Invalid cookie blocks scheme from redirecting
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v1.4.1]]> + https://github.com/hapijs/cookie/milestone/9 + + 2014-11-20T05:02:27.000Z + +
  • [#37] Fix clearInvalid (for issue #34)
  • [#34] Bad cookie value even with clearInvalid true
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v1.4.0]]> + https://github.com/hapijs/cookie/milestone/8 + + 2014-11-12T22:55:45.000Z + +
  • [#35] Session keepAlive and ttl override
  • [#30] add set/clear key for cookie
  • [#29] Fix for handling multiple strategies
  • [#26] Update key in auth.credentials
  • [#22] Exposed path option for session cookie
  • [#21] Expose 'path' in cookieOptions
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v1.3.2]]> + https://github.com/hapijs/cookie/milestone/7 + + 2014-08-04T08:50:12.000Z + +
  • [#20] Update LICENSE
  • [#19] Update License
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v1.3.1]]> + https://github.com/hapijs/cookie/milestone/6 + + 2014-07-17T12:35:49.000Z + +
  • [#16] Fix hapi dev dep
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v1.3.0]]> + https://github.com/hapijs/cookie/milestone/5 + + 2014-07-17T12:29:47.000Z + +
  • [#15] Skip redirection on try
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v1.2.0]]> + https://github.com/hapijs/cookie/milestone/4 + + 2014-06-13T19:16:21.000Z + +
  • [#11] No way to use with 'try' mode if 'redirectTo' is set
  • [#10] validateFunc credentials override session
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v1.1.0]]> + https://github.com/hapijs/cookie/milestone/3 + + 2014-06-12T19:47:21.000Z + +
  • [#9] hapi 6.0
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v1.0.3]]> + https://github.com/hapijs/cookie/milestone/2 + + 2014-05-21T02:18:17.000Z + +
  • [#6] Bring coverage back to 100%
  • ]]>
    +
    + + <![CDATA[@hapi/cookie v1.0.2]]> + https://github.com/hapijs/cookie/milestone/1 + + 2014-03-21T20:29:24.000Z + +
  • [#5] Bring coverage back to 100% after lab fix
  • [#4] fix peerDependencies for hapi
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/crumb.atom b/docs/public/atom/crumb.atom new file mode 100644 index 00000000..8fd547f9 --- /dev/null +++ b/docs/public/atom/crumb.atom @@ -0,0 +1,178 @@ + + + https://hapi.dev/module/crumb + @hapi/crumb changelog + 2023-02-11T19:29:58.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/crumb v9.0.1]]> + https://github.com/hapijs/crumb/milestone/22 + + 2023-02-11T19:29:58.000Z + +
  • [#163] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/crumb v9.0.0]]> + https://github.com/hapijs/crumb/milestone/21 + + 2022-10-29T20:21:00.000Z + +
  • [#162] Support for hapi v21, node v18, ESM tests
  • ]]>
    +
    + + <![CDATA[@hapi/crumb v8.0.1]]> + https://github.com/hapijs/crumb/milestone/19 + + 2020-09-26T23:19:23.000Z + +
  • [#153] upgrade lab to v24
  • [#150] update dependencies
  • [#149] migrate to new travis format
  • [#147] upgrade to use the latest lab and joi to validate
  • ]]>
    +
    + + <![CDATA[@hapi/crumb v8.0.0]]> + https://github.com/hapijs/crumb/milestone/18 + + 2020-01-10T07:36:50.000Z + +
  • [#144] Drop hapi v17 and v18
  • [#143] Change plugin name to @hapi/crubm
  • [#142] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/crumb v7.3.2]]> + https://github.com/hapijs/crumb/milestone/17 + + 2019-09-12T22:53:52.000Z + +
  • [#135] Update joi
  • [#131] validate crumb when autoGenerate is false and crumb not defined on route
  • ]]>
    +
    + + <![CDATA[@hapi/crumb v7.3.1]]> + https://github.com/hapijs/crumb/milestone/16 + + 2019-08-14T22:36:04.000Z + +
  • [#134] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/crumb v7.3.0]]> + https://github.com/hapijs/crumb/milestone/15 + + 2019-08-14T21:10:22.000Z + +
  • [#129] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/crumb v7.1.1]]> + https://github.com/hapijs/crumb/milestone/14 + + 2018-11-13T18:43:24.000Z + + ]]> + + + <![CDATA[@hapi/crumb v7.1.0]]> + https://github.com/hapijs/crumb/milestone/13 + + 2018-04-23T15:22:25.000Z + +
  • [#112] adds logUnauthorized option - addresses #56
  • [#111] Remove new Buffer usage
  • [#103] Add an option to specify the CSRF header name
  • [#56] Provide more relevant feedback
  • ]]>
    +
    + + <![CDATA[@hapi/crumb v7.0.0]]> + https://github.com/hapijs/crumb/milestone/12 + + 2017-11-29T22:08:48.000Z + +
  • [#107] Update contact details/maintainer
  • [#106] Upgrade Crumb to Hapi 17
  • [#105] hapi v17 support
  • [#101] Enable Crumb for specific routes only
  • [#99] Add sentence to README about how to disable the plugin for a particular route.
  • [#98] Make both examples runnable with a package.json and proper dependencies
  • [#97] Example won't launch: `Server.views is not a function`
  • [#93] Documentation Improvement
  • ]]>
    +
    + + <![CDATA[@hapi/crumb v6.0.3]]> + https://github.com/hapijs/crumb/milestone/11 + + 2016-08-15T14:50:45.000Z + +
  • [#91] Cors origin
  • [#90] Generate function never called when Vision route has CORS enabled
  • [#89] Generate is running a second time and 500-ing hapi
  • [#87] remove arrow function to fix context
  • [#54] Getting 403 forbidden because token has changed
  • ]]>
    +
    + + <![CDATA[@hapi/crumb v6.0.2]]> + https://github.com/hapijs/crumb/milestone/10 + + 2016-06-30T04:58:45.000Z + +
  • [#84] #80: fixes crumb route settings bug
  • [#82] Test on node v6, update dependencies
  • [#80] 6.0.1 update breaks route-restful option
  • ]]>
    +
    + + <![CDATA[@hapi/crumb v6.0.1]]> + https://github.com/hapijs/crumb/milestone/9 + + 2016-05-12T20:17:54.000Z + +
  • [#79] Fixes #74 -- restful configured through routes is not superceded by global config
  • [#78] Purpose readme contribution
  • [#69] Update restful example to respond with JSON. Closes #64
  • ]]>
    +
    + + <![CDATA[@hapi/crumb v6.0.0]]> + https://github.com/hapijs/crumb/milestone/8 + + 2016-05-12T20:03:30.000Z + +
  • [#70] Hapi12
  • [#68] Heroku disallows host binding but Crumb requires it
  • [#67] ES6 style changes and node v4
  • [#61] Ignore CORS
  • ]]>
    +
    + + <![CDATA[@hapi/crumb v5.0.0]]> + https://github.com/hapijs/crumb/milestone/7 + + 2016-01-15T19:10:59.000Z + +
  • [#63] Update 9
  • [#58] update to hapi 9/10
  • [#51] crumb request.plugins.crumb: undefined
  • ]]>
    +
    + + <![CDATA[@hapi/crumb v4.04]]> + https://github.com/hapijs/crumb/milestone/6 + + 2016-01-15T19:11:02.000Z + +
  • [#53] correct linting issues
  • [#52] Updated joi to 6.x.x
  • ]]>
    +
    + + <![CDATA[@hapi/crumb v4.0.3]]> + https://github.com/hapijs/crumb/milestone/5 + + 2015-06-05T14:00:44.000Z + +
  • [#49] Return error during plugin registration for invalid options.
  • ]]>
    +
    + + <![CDATA[@hapi/crumb v4.0.2]]> + https://github.com/hapijs/crumb/milestone/4 + + 2015-02-26T14:24:19.000Z + +
  • [#46] fix internals.originParser + tests to add protocol in all origin/allowOrigins values
  • ]]>
    +
    + + <![CDATA[@hapi/crumb v4.0.1]]> + https://github.com/hapijs/crumb/milestone/3 + + 2015-02-13T04:56:16.000Z + +
  • [#34] Host header cannot include URI scheme
  • ]]>
    +
    + + <![CDATA[@hapi/crumb v4.0.0]]> + https://github.com/hapijs/crumb/milestone/2 + + 2015-02-04T21:14:02.000Z + +
  • [#37] hapi8. Closes #35. internals bug. Closes #33
  • [#35] hapi 8.0 API
  • [#33] Don't use internals for plugin state
  • ]]>
    +
    + + <![CDATA[@hapi/crumb v1.1.2]]> + https://github.com/hapijs/crumb/milestone/1 + + 2014-03-21T00:42:56.000Z + +
  • [#11] Support hapi 3.0
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/cryptiles.atom b/docs/public/atom/cryptiles.atom new file mode 100644 index 00000000..df84fea7 --- /dev/null +++ b/docs/public/atom/cryptiles.atom @@ -0,0 +1,234 @@ + + + https://hapi.dev/module/cryptiles + @hapi/cryptiles changelog + 2025-12-09T17:04:51.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/cryptiles v6.0.2]]> + https://github.com/hapijs/cryptiles/milestone/31 + + 2025-12-09T17:04:51.000Z + +
  • [#63] fix: 🐛 Add timing-safe comparison tests and update API docs
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v6.0.1]]> + https://github.com/hapijs/cryptiles/milestone/30 + + 2023-02-11T18:56:26.000Z + +
  • [#60] chore: bump packages
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v6.0.0]]> + https://github.com/hapijs/cryptiles/milestone/29 + + 2022-05-07T22:43:55.000Z + +
  • [#58] Support node v18 and drop node v12
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v5.1.0]]> + https://github.com/hapijs/cryptiles/milestone/27 + + 2020-05-15T20:25:04.000Z + +
  • [#51] Add randomAlphanumString()
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v5.0.0]]> + https://github.com/hapijs/cryptiles/milestone/26 + + 2020-01-05T01:06:58.000Z + +
  • [#50] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v4.2.1]]> + https://github.com/hapijs/cryptiles/milestone/24 + + 2019-09-19T18:16:57.000Z + +
  • [#45] Added TS declarations
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v4.2.0]]> + https://github.com/hapijs/cryptiles/milestone/20 + + 2019-04-02T06:15:55.000Z + +
  • [#40] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v4.1.3]]> + https://github.com/hapijs/cryptiles/milestone/18 + + 2018-11-03T00:26:25.000Z + +
  • [#36] Remove engines
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v4.1.2]]> + https://github.com/hapijs/cryptiles/milestone/17 + + 2018-06-24T04:07:49.000Z + +
  • [#34] randomDigits() generates biased random digits
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v4.1.1]]> + https://github.com/hapijs/cryptiles/milestone/16 + + 2017-11-10T20:15:19.000Z + +
  • [#33] fix(fixedTimeComparison): use Buffer.from
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v4.1.0]]> + https://github.com/hapijs/cryptiles/milestone/15 + + 2017-11-03T20:46:13.000Z + +
  • [#32] Add fixedTimeComparison()
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v4.0.2]]> + https://github.com/hapijs/cryptiles/milestone/14 + + 2017-11-03T20:45:19.000Z + +
  • [#31] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v4.0.1]]> + https://github.com/hapijs/cryptiles/milestone/13 + + 2017-09-26T09:08:43.000Z + +
  • [#28] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v4.0.0]]> + https://github.com/hapijs/cryptiles/milestone/12 + + 2017-09-24T21:26:52.000Z + +
  • [#27] Throw errors
  • [#24] Use crypto.timingSafeEqual for fixedTimeComparison
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v3.2.0]]> + https://github.com/hapijs/cryptiles/milestone/22 + + 2019-04-02T06:12:23.000Z + +
  • [#39] Commercial version of v3 branch
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v3.1.4]]> + https://github.com/hapijs/cryptiles/milestone/21 + + 2018-11-05T22:45:49.000Z + +
  • [#37] Remove engines
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v3.1.3]]> + https://github.com/hapijs/cryptiles/milestone/19 + + 2018-11-02T21:48:07.000Z + +
  • [#35] randomDigits() generates biased random digits
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v3.1.2]]> + https://github.com/hapijs/cryptiles/milestone/11 + + 2017-05-28T06:24:36.000Z + +
  • [#26] Update deps.
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v3.1.1]]> + https://github.com/hapijs/cryptiles/milestone/10 + + 2016-09-05T22:10:42.000Z + +
  • [#23] Support node 4
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v3.1.0]]> + https://github.com/hapijs/cryptiles/milestone/9 + + 2016-09-05T22:01:59.000Z + +
  • [#22] Generate random digits
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v3.0.2]]> + https://github.com/hapijs/cryptiles/milestone/8 + + 2016-07-27T19:50:53.000Z + +
  • [#21] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v3.0.1]]> + https://github.com/hapijs/cryptiles/milestone/7 + + 2016-05-19T18:00:07.000Z + +
  • [#19] Test on node v6, update dependencies
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v3.0.0]]> + https://github.com/hapijs/cryptiles/milestone/6 + + 2015-11-02T03:43:40.000Z + +
  • [#18] es6. Closes #17
  • [#17] ES6 style changes and node v4
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v2.0.5]]> + https://github.com/hapijs/cryptiles/milestone/5 + + 2015-09-09T06:09:59.000Z + +
  • [#16] Update hapi style
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v2.0.4]]> + https://github.com/hapijs/cryptiles/milestone/4 + + 2014-09-15T22:11:54.000Z + +
  • [#10] Move to hapijs
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v2.0.3]]> + https://github.com/hapijs/cryptiles/milestone/3 + + 2014-09-05T19:43:02.000Z + +
  • [#9] lab 4.0
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v2.0.2]]> + https://github.com/hapijs/cryptiles/milestone/2 + + 2014-08-02T07:22:12.000Z + +
  • [#8] Update contact
  • ]]>
    +
    + + <![CDATA[@hapi/cryptiles v2.0.1]]> + https://github.com/hapijs/cryptiles/milestone/1 + + 2014-04-08T07:41:09.000Z + +
  • [#5] Bring coverage back to 100% after lab partial condition result coverage
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/eslint-plugin.atom b/docs/public/atom/eslint-plugin.atom new file mode 100644 index 00000000..da4a1c04 --- /dev/null +++ b/docs/public/atom/eslint-plugin.atom @@ -0,0 +1,106 @@ + + + https://hapi.dev/module/eslint-plugin + @hapi/eslint-plugin changelog + 2024-10-22T13:42:11.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/eslint-plugin v7.0.0]]> + https://github.com/hapijs/eslint-plugin/milestone/14 + + 2024-10-22T13:42:11.000Z + +
  • [#33] feat: target ESLint v9
  • ]]>
    +
    + + <![CDATA[@hapi/eslint-plugin v6.0.0]]> + https://github.com/hapijs/eslint-plugin/milestone/12 + + 2024-10-22T13:42:03.000Z + +
  • [#31] Drop support for node v12, support node v18, upgrade eslint
  • ]]>
    +
    + + <![CDATA[@hapi/eslint-plugin v5.1.0]]> + https://github.com/hapijs/eslint-plugin/milestone/10 + + 2021-05-21T17:30:07.000Z + +
  • [#27] Migrate lab internal eslint config
  • [#26] Update to @babel/eslint-parser
  • [#24] upgrade lab to v24
  • ]]>
    +
    + + <![CDATA[@hapi/eslint-plugin v5.0.0]]> + https://github.com/hapijs/eslint-plugin/milestone/9 + + 2020-09-15T00:06:00.000Z + +
  • [#23] Rename to eslint-plugin
  • [#21] Change package name to @hapi/eslint-plugin
  • ]]>
    +
    + + <![CDATA[@hapi/eslint-plugin v4.3.6]]> + https://github.com/hapijs/eslint-plugin/milestone/8 + + 2020-09-13T14:51:39.000Z + +
  • [#22] Update rules for modern eslint
  • [#20] Merge eslint-config-hapi and rules
  • [#19] update to travis templates and test on node 14
  • [#17] Create API.md
  • [#16] Update README.md
  • [#15] fix(package.json): repository url
  • ]]>
    +
    + + <![CDATA[@hapi/eslint-plugin v4.3.5]]> + https://github.com/hapijs/eslint-plugin/milestone/7 + + 2020-01-05T01:14:59.000Z + +
  • [#14] Cleanup
  • ]]>
    +
    + + <![CDATA[@hapi/eslint-plugin v4.3.4]]> + https://github.com/hapijs/eslint-plugin/milestone/6 + + 2019-08-07T20:19:01.000Z + +
  • [#11] eslint 6 support
  • ]]>
    +
    + + <![CDATA[@hapi/eslint-plugin v4.3.3]]> + https://github.com/hapijs/eslint-plugin/milestone/5 + + 2019-04-23T16:20:53.000Z + +
  • [#10] Fix names
  • ]]>
    +
    + + <![CDATA[@hapi/eslint-plugin v4.2.0]]> + https://github.com/hapijs/eslint-plugin/milestone/4 + + 2019-04-23T07:02:53.000Z + +
  • [#9] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/eslint-plugin v3.0.0]]> + https://github.com/hapijs/eslint-plugin/milestone/3 + + 2015-11-04T18:29:10.000Z + +
  • [#6] Remove no-shadow-relaxed
  • ]]>
    +
    + + <![CDATA[@hapi/eslint-plugin vv2.0.0]]> + https://github.com/hapijs/eslint-plugin/milestone/2 + + 2015-10-30T20:35:59.000Z + +
  • [#5] Add rule no-arrowception
  • [#4] Update to hapi-scope-start@2.0.0
  • ]]>
    +
    + + <![CDATA[@hapi/eslint-plugin vv1.2.0]]> + https://github.com/hapijs/eslint-plugin/milestone/1 + + 2015-06-25T14:52:50.000Z + +
  • [#3] Add no-shadow-relaxed rule to plugin
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/file.atom b/docs/public/atom/file.atom new file mode 100644 index 00000000..72db70dd --- /dev/null +++ b/docs/public/atom/file.atom @@ -0,0 +1,26 @@ + + + https://hapi.dev/module/file + @hapi/file changelog + 2022-05-30T23:07:31.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/file v3.0.0]]> + https://github.com/hapijs/file/milestone/3 + + 2022-05-30T23:07:31.000Z + +
  • [#14] Support node v18 and drop node v12
  • ]]>
    +
    + + <![CDATA[@hapi/file v2.0.0]]> + https://github.com/hapijs/file/milestone/1 + + 2020-01-05T05:01:42.000Z + +
  • [#4] Only node 12
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/glue.atom b/docs/public/atom/glue.atom new file mode 100644 index 00000000..141be239 --- /dev/null +++ b/docs/public/atom/glue.atom @@ -0,0 +1,210 @@ + + + https://hapi.dev/module/glue + @hapi/glue changelog + 2023-02-11T20:18:12.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/glue v9.0.1]]> + https://github.com/hapijs/glue/milestone/29 + + 2023-02-11T20:18:12.000Z + +
  • [#149] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/glue v9.0.0]]> + https://github.com/hapijs/glue/milestone/28 + + 2022-10-29T20:20:06.000Z + +
  • [#148] Support for node v18 and hapi v21, ESM support
  • ]]>
    +
    + + <![CDATA[@hapi/glue v8.0.0]]> + https://github.com/hapijs/glue/milestone/26 + + 2020-08-13T22:48:26.000Z + +
  • [#142] fix: 🐛 bump hapi 20 dependency
  • ]]>
    +
    + + <![CDATA[@hapi/glue v7.0.0]]> + https://github.com/hapijs/glue/milestone/25 + + 2020-01-12T04:47:15.000Z + +
  • [#138] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/glue v6.2.0]]> + https://github.com/hapijs/glue/milestone/23 + + 2019-09-12T22:29:28.000Z + +
  • [#133] Update joi
  • [#129] #128 Add support for constructor property and additional options in server cache configuration
  • [#128] Server cache options in hapi 18 cannot be passed
  • ]]>
    +
    + + <![CDATA[@hapi/glue v6.1.1]]> + https://github.com/hapijs/glue/milestone/20 + + 2019-08-14T22:32:56.000Z + +
  • [#132] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/glue v6.1.0]]> + https://github.com/hapijs/glue/milestone/19 + + 2019-04-14T00:17:39.000Z + +
  • [#126] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/glue v6.0.0]]> + https://github.com/hapijs/glue/milestone/18 + + 2019-01-22T14:06:45.000Z + +
  • [#124] Updates to hapi 18; refactors cache.engine to cache.provider
  • [#121] Updating package dependencies.
  • ]]>
    +
    + + <![CDATA[@hapi/glue v5.1.0]]> + https://github.com/hapijs/glue/milestone/21 + + 2019-04-16T05:03:21.000Z + +
  • [#127] Change module namespace for v5 branch
  • ]]>
    +
    + + <![CDATA[@hapi/glue v5.0.0]]> + https://github.com/hapijs/glue/milestone/17 + + 2017-11-06T00:14:32.000Z + +
  • [#104] Update to hapi v17.
  • [#102] Hapi 17
  • ]]>
    +
    + + <![CDATA[@hapi/glue v4.2.1]]> + https://github.com/hapijs/glue/milestone/16 + + 2017-10-28T22:57:30.000Z + +
  • [#98] Promises aren't quite right
  • ]]>
    +
    + + <![CDATA[@hapi/glue v4.2.0]]> + https://github.com/hapijs/glue/milestone/15 + + 2017-07-28T05:56:49.000Z + +
  • [#95] This is for issue #89
  • [#89] Plugin as function
  • ]]>
    +
    + + <![CDATA[@hapi/glue v4.1.0]]> + https://github.com/hapijs/glue/milestone/14 + + 2016-12-23T05:23:13.000Z + +
  • [#85] Hapi v16
  • [#84] Refactors Joi.array() to utilize .items()
  • [#83] Joi.array() does not accept arguments
  • [#82] Add Hapi 16 support
  • ]]>
    +
    + + <![CDATA[@hapi/glue v4.0.0]]> + https://github.com/hapijs/glue/milestone/13 + + 2016-08-27T20:24:40.000Z + +
  • [#74] Support hapi 15
  • [#72] Make compose callback always execute async
  • ]]>
    +
    + + <![CDATA[@hapi/glue v3.4.0]]> + https://github.com/hapijs/glue/milestone/12 + + 2016-08-17T16:38:35.000Z + +
  • [#73] Add Hapi 14.x.x to dependencies
  • [#71] using Hoek.clone makes some plugins stop working
  • ]]>
    +
    + + <![CDATA[@hapi/glue v3.3.0]]> + https://github.com/hapijs/glue/milestone/11 + + 2016-06-04T15:48:15.000Z + +
  • [#64] add plugin-specific registration options to schema
  • ]]>
    +
    + + <![CDATA[@hapi/glue v3.2.1]]> + https://github.com/hapijs/glue/milestone/10 + + 2016-05-20T15:08:17.000Z + +
  • [#68] Test on node v6, update dependencies
  • ]]>
    +
    + + <![CDATA[@hapi/glue v3.2.0]]> + https://github.com/hapijs/glue/milestone/9 + + 2016-05-20T15:07:13.000Z + +
  • [#62] Support hapi 13
  • ]]>
    +
    + + <![CDATA[@hapi/glue v3.1.0]]> + https://github.com/hapijs/glue/milestone/8 + + 2016-01-15T06:05:54.000Z + +
  • [#57] Remove boom dependency
  • [#54] compose() returns a Promise if no callback is provided
  • [#53] Support hapi v12
  • [#52] Support promises
  • ]]>
    +
    + + <![CDATA[@hapi/glue v3.0.0]]> + https://github.com/hapijs/glue/milestone/7 + + 2015-12-28T16:30:17.000Z + +
  • [#47] when is glue 3.x going to be completed?
  • [#44] Don't force object for plugin options
  • [#42] update to es6 based hapi style guide and lab 7 + Dependencies update
  • [#41] update to es6 based hapi style guide and lab 7
  • [#40] Breaking changes on 2.3.0 and 2.4.0
  • [#31] Prefix is passed only when plugin in manifest is an array
  • ]]>
    +
    + + <![CDATA[@hapi/glue v2.3.0]]> + https://github.com/hapijs/glue/milestone/5 + + 2015-09-14T15:29:23.000Z + +
  • [#32] Support Hapi 10
  • ]]>
    +
    + + <![CDATA[@hapi/glue v2.2.0]]> + https://github.com/hapijs/glue/milestone/4 + + 2015-08-18T20:08:36.000Z + +
  • [#28] README: Use the svg Travis image
  • [#26] Fix typos in docs
  • ]]>
    +
    + + <![CDATA[@hapi/glue v2.1.1]]> + https://github.com/hapijs/glue/milestone/3 + + 2015-07-24T21:55:42.000Z + +
  • [#25] Linting update
  • ]]>
    +
    + + <![CDATA[@hapi/glue v2.1.0]]> + https://github.com/hapijs/glue/milestone/2 + + 2015-06-17T23:14:07.000Z + +
  • [#22] Add usage section to README file.
  • [#20] Added ability to pass array of plugins
  • ]]>
    +
    + + <![CDATA[@hapi/glue v2.0.0]]> + https://github.com/hapijs/glue/milestone/1 + + 2015-03-02T19:47:30.000Z + +
  • [#8] Update Hapi dependency
  • [#7] Publish 2.0.0
  • [#6] revamp test code to only test functionality relevant to glue
  • [#5] Improve validation and documentation of manifest plugins entry
  • [#4] Update to hapi@8.0.0-rc7
  • [#3] add support for preConnection and preRegister options handlers
  • [#2] manifest limitation on server options
  • [#1] hapi 8.0 API
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/h2o2.atom b/docs/public/atom/h2o2.atom new file mode 100644 index 00000000..fb3d1176 --- /dev/null +++ b/docs/public/atom/h2o2.atom @@ -0,0 +1,186 @@ + + + https://hapi.dev/module/h2o2 + @hapi/h2o2 changelog + 2023-08-10T16:31:37.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/h2o2 v10.0.3]]> + https://github.com/hapijs/h2o2/milestone/23 + + 2023-08-10T16:31:37.000Z + +
  • [#137] Fix mapUri type definition
  • ]]>
    +
    + + <![CDATA[@hapi/h2o2 v10.0.2]]> + https://github.com/hapijs/h2o2/milestone/22 + + 2023-06-09T14:37:02.000Z + +
  • [#136] chore: add typings from DT
  • ]]>
    +
    + + <![CDATA[@hapi/h2o2 v10.0.1]]> + https://github.com/hapijs/h2o2/milestone/21 + + 2023-02-11T20:03:42.000Z + +
  • [#135] chore: bump hoek
  • [#133] Support delete payload forwarding
  • ]]>
    +
    + + <![CDATA[@hapi/h2o2 v10.0.0]]> + https://github.com/hapijs/h2o2/milestone/20 + + 2022-09-26T19:58:27.000Z + +
  • [#132] Support for hapi v21, node v18, ESM tests
  • [#131] add dispatcher and use shared config
  • [#128] Add querystring support for uri mapping
  • ]]>
    +
    + + <![CDATA[@hapi/h2o2 v9.1.0]]> + https://github.com/hapijs/h2o2/milestone/18 + + 2022-09-12T20:29:37.000Z + +
  • [#125] propagate request abortion to upstream server
  • ]]>
    +
    + + <![CDATA[@hapi/h2o2 v9.0.2]]> + https://github.com/hapijs/h2o2/milestone/17 + + 2020-09-26T16:42:17.000Z + +
  • [#121] migrate to new travis format
  • [#120] upgrade to hapi 20
  • [#119] update lab and switch joi to validate
  • [#117] Update onResponse for Wreck's async/await syntax
  • ]]>
    +
    + + <![CDATA[@hapi/h2o2 v9.0.1]]> + https://github.com/hapijs/h2o2/milestone/16 + + 2020-01-12T08:18:44.000Z + +
  • [#113] Require hapi 19
  • ]]>
    +
    + + <![CDATA[@hapi/h2o2 v9.0.0]]> + https://github.com/hapijs/h2o2/milestone/15 + + 2020-01-12T06:20:03.000Z + +
  • [#112] Change plugin name to @hapi/h2o2
  • [#111] Drop hapi v17
  • [#110] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/h2o2 v8.3.2]]> + https://github.com/hapijs/h2o2/milestone/14 + + 2019-09-13T06:06:35.000Z + +
  • [#102] Update joi
  • ]]>
    +
    + + <![CDATA[@hapi/h2o2 v8.3.1]]> + https://github.com/hapijs/h2o2/milestone/13 + + 2019-08-14T22:25:47.000Z + +
  • [#101] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/h2o2 v8.3.0]]> + https://github.com/hapijs/h2o2/milestone/12 + + 2019-04-13T22:24:28.000Z + +
  • [#95] Move agents from internals to server
  • [#94] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/h2o2 v5.3.0]]> + https://github.com/hapijs/h2o2/milestone/11 + + 2018-11-13T18:43:54.000Z + +
  • [#45] Fix the `uri` vs. `address` variable usage for multiple replacements
  • [#44] Allow request.params variable replacement in the uri template
  • ]]>
    +
    + + <![CDATA[@hapi/h2o2 v5.2.0]]> + https://github.com/hapijs/h2o2/milestone/10 + + 2018-11-13T18:43:58.000Z + +
  • [#42] Added X-Forwarded-Host to forward headers
  • [#41] X-Forwarded-Proto being set to upstream protocol
  • ]]>
    +
    + + <![CDATA[@hapi/h2o2 v5.1]]> + https://github.com/hapijs/h2o2/milestone/9 + + 2018-11-13T18:43:59.000Z + +
  • [#24] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/h2o2 v5.0.0]]> + https://github.com/hapijs/h2o2/milestone/8 + + 2018-11-13T18:44:01.000Z + +
  • [#20] Migrate to new versions of modules and ES6.
  • ]]>
    +
    + + <![CDATA[@hapi/h2o2 v4.0.2]]> + https://github.com/hapijs/h2o2/milestone/7 + + 2018-11-13T18:44:03.000Z + +
  • [#18] Update Wreck dependency
  • ]]>
    +
    + + <![CDATA[@hapi/h2o2 v4.0.1]]> + https://github.com/hapijs/h2o2/milestone/6 + + 2015-05-29T05:51:41.000Z + +
  • [#11] Bump Joi to v6.x.x
  • ]]>
    +
    + + <![CDATA[@hapi/h2o2 v4.0.0]]> + https://github.com/hapijs/h2o2/milestone/5 + + 2014-12-09T22:42:28.000Z + +
  • [#8] passThrough changes
  • ]]>
    +
    + + <![CDATA[@hapi/h2o2 v3.0.0]]> + https://github.com/hapijs/h2o2/milestone/4 + + 2014-10-31T00:33:45.000Z + +
  • [#7] Move maxSockets to a handler config instead of server
  • [#6] Replace server maxSockets settings with per handler configuration
  • ]]>
    +
    + + <![CDATA[@hapi/h2o2 v2.0.1]]> + https://github.com/hapijs/h2o2/milestone/3 + + 2014-10-09T20:53:16.000Z + +
  • [#4] Change localStatePassThrough default to true
  • ]]>
    +
    + + <![CDATA[@hapi/h2o2 v2.0.0]]> + https://github.com/hapijs/h2o2/milestone/2 + + 2014-10-09T18:17:15.000Z + +
  • [#3] Change handler function to hapi 7.0 API
  • ]]>
    +
    + + <![CDATA[@hapi/h2o2 v1.0.1]]> + https://github.com/hapijs/h2o2/milestone/1 + + 2014-09-20T07:57:45.000Z + +
  • [#1] Use joi.assert()
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/hapi.atom b/docs/public/atom/hapi.atom new file mode 100644 index 00000000..26c7466f --- /dev/null +++ b/docs/public/atom/hapi.atom @@ -0,0 +1,410 @@ + + + https://hapi.dev + @hapi/hapi changelog + 2026-04-02T08:29:10.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/hapi v21.4.8]]> + https://github.com/hapijs/hapi/milestone/329 + + 2026-04-02T08:29:10.000Z + +
  • [#4568] chore: bump deps
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v21.4.7]]> + https://github.com/hapijs/hapi/milestone/328 + + 2026-03-06T15:06:47.000Z + +
  • [#4559] fix: 🐛 request.url getter fails when using IPv6 and HTTP2 [#4560]
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v21.4.6]]> + https://github.com/hapijs/hapi/milestone/327 + + 2026-02-19T15:27:38.000Z + +
  • [#4564] Fix invalid hostname parsing for ipv6 formatted host header
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v21.4.5]]> + https://github.com/hapijs/hapi/milestone/326 + + 2026-02-18T09:16:35.000Z + +
  • [#4562] fix: auth typings and reduced type ambiguity
  • [#4561] Possible typing regression between v21.3.12 and v21.4.4
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v21.4.4]]> + https://github.com/hapijs/hapi/milestone/325 + + 2025-11-06T09:44:01.000Z + +
  • [#4557] chore: update deps
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v21.4.3]]> + https://github.com/hapijs/hapi/milestone/324 + + 2025-08-13T22:38:47.000Z + +
  • [#4553] chore: bump dependencies
  • [#4552] Handle stream.destroy() called before stream end
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v21.4.2]]> + https://github.com/hapijs/hapi/milestone/323 + + 2025-08-04T21:03:50.000Z + +
  • [#4550] Correct type for state object
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v21.4.1]]> + https://github.com/hapijs/hapi/milestone/322 + + 2025-08-04T21:03:47.000Z + + ]]> + + + <![CDATA[@hapi/hapi v21.4.0]]> + https://github.com/hapijs/hapi/milestone/321 + + 2025-03-01T09:19:22.000Z + +
  • [#4545] feat: add support for cookie partition
  • [#4543] Update event tags in documentation
  • [#4542] `request` `closed` `error` tags
  • [#4540] fix: 🐛 less ambigious plugin types
  • [#4538] fix: 🐛 typings around server.decorate
  • [#4523] fix: 🐛 accurate auth typings
  • [#4515] fix: 🐛 allow typed server methods access cache methods
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v21.3.12]]> + https://github.com/hapijs/hapi/milestone/320 + + 2024-10-24T22:12:20.000Z + +
  • [#4533] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v21.3.11]]> + https://github.com/hapijs/hapi/milestone/319 + + 2024-10-24T10:20:18.000Z + +
  • [#4532] chore: bump all modules to their latest compatible version
  • [#4531] Asserts (and probably other Bounce.isSystem) loose stack trace
  • [#4530] Don't destroy incoming requests during the stopping phase
  • [#4488] Improve expect 100-continue handling
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v21.3.10]]> + https://github.com/hapijs/hapi/milestone/318 + + 2024-10-24T10:00:52.000Z + +
  • [#4507] fix: 🐛 route payload options missing types
  • [#4501] Missing maxParts type in route.d.ts
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v21.3.9]]> + https://github.com/hapijs/hapi/milestone/317 + + 2024-04-09T14:38:28.000Z + +
  • [#4496] types: allow server.match to receive lowercased methods
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v21.3.8]]> + https://github.com/hapijs/hapi/milestone/316 + + 2024-04-03T20:56:12.000Z + +
  • [#4493] Cleanup http methods typings
  • [#4492] HTTP_METHODS_PARTIAL_LOWERCASE is missing `head`
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v21.3.7]]> + https://github.com/hapijs/hapi/milestone/315 + + 2024-03-19T21:21:08.000Z + +
  • [#4490] Make content encoder and options explicitly typed and extensible
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v21.3.6]]> + https://github.com/hapijs/hapi/milestone/314 + + 2024-03-13T19:06:46.000Z + +
  • [#4486] Revert "fix(types): enhance reusability of pres"
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v21.3.5]]> + https://github.com/hapijs/hapi/milestone/313 + + 2024-03-13T14:43:47.000Z + +
  • [#4471] Don't return error response when clientError is a pipelined HPE_INVALID_METHOD
  • [#4363] Server crash: Error: Unknown error
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v21.3.4]]> + https://github.com/hapijs/hapi/milestone/312 + + 2024-03-13T14:12:21.000Z + +
  • [#4470] fix(types): enhance reusability of pres
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v21.3.3]]> + https://github.com/hapijs/hapi/milestone/311 + + 2024-01-29T15:50:24.000Z + +
  • [#4473] Node 20 fixes
  • [#4460] FIX add compressed to ResponseObject type
  • [#4446] failAction loses stacktrace context
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v21.3.2]]> + https://github.com/hapijs/hapi/milestone/310 + + 2023-04-24T22:12:03.000Z + +
  • [#4449] chore: use new statehood types
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v21.3.1]]> + https://github.com/hapijs/hapi/milestone/309 + + 2023-04-24T22:12:01.000Z + +
  • [#4413] Pass ServerApplicationState to server extensions
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v21.3.0]]> + https://github.com/hapijs/hapi/milestone/308 + + 2023-02-14T15:13:19.000Z + +
  • [#4425] Add option to limit maxParts in multipart payloads
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v21.2.2]]> + https://github.com/hapijs/hapi/milestone/306 + + 2023-02-11T21:16:25.000Z + +
  • [#4417] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v21.2.1]]> + https://github.com/hapijs/hapi/milestone/304 + + 2023-01-30T03:18:04.000Z + +
  • [#4422] Update README.md
  • [#4421] adding colin to tsc members
  • [#4415] Correct the ResponseObject type
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v21.2.0]]> + https://github.com/hapijs/hapi/milestone/303 + + 2023-01-30T03:17:24.000Z + +
  • [#4407] Add type for preflight status code in cors options
  • [#4402] Updates to TypeScript definitions
  • [#4401] update types for xss
  • [#4400] Enhance plugin types
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v21.1.0]]> + https://github.com/hapijs/hapi/milestone/302 + + 2022-12-01T03:25:20.000Z + +
  • [#4398] Move TypeScript definition from DT (as-is)
  • [#4396] Fix handling of no remoteAddress available
  • [#4391] Fix node version requirement
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v21.0.0]]> + https://github.com/hapijs/hapi/milestone/300 + + 2022-11-07T15:13:45.000Z + +
  • [#4386] 21.0.0 Release Notes
  • [#4366] Allow matching prereleases when validating plugin version requirements
  • [#4361] Upgrade production deps for hapi v21 and node v18
  • [#4357] Change default host to be IPv6-friendly
  • [#4352] Change XSS header default to '0'
  • [#4351] Change default CORS preflight status code w/ configuration
  • [#4350] Make default error available in validation failAction
  • [#4349] Enforce that response streams are always Stream.Readable
  • [#4348] Ignore return value from generateResponse() prepare method
  • [#4346] Drop node v12 support
  • [#4288] Add support for event loop utilization based load limit
  • [#4271] Remove JSONP support
  • [#4229] failAction: detailedError to log, defaultError to response
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v20.3.0]]> + https://github.com/hapijs/hapi/milestone/307 + + 2023-02-14T15:13:24.000Z + + ]]> + + + <![CDATA[@hapi/hapi v20.2.2]]> + https://github.com/hapijs/hapi/milestone/299 + + 2022-04-20T02:52:44.000Z + +
  • [#4347] Update hapijs/statehood to 7.0.4 from 7.0.3
  • [#4345] Fix memory leaks from teamwork long standing notes
  • [#4314] Fix tests for node v17
  • [#4302] Soft deprecate returning a new object from generateResponse()
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v20.2.1]]> + https://github.com/hapijs/hapi/milestone/298 + + 2021-10-09T01:03:48.000Z + +
  • [#4295] Revised request / inject abort handling
  • [#4294] Server crashes if a requested aborted during sending a response.
  • [#4289] Update server load default options on documentation
  • [#4286] Initialize server settings defaults
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v20.2.0]]> + https://github.com/hapijs/hapi/milestone/297 + + 2021-09-21T07:06:30.000Z + +
  • [#4283] Fix tests for node@16 error format change
  • [#4281] Fix handling of auth scheme/strategy realms
  • [#4274] Add optional payload authentication skip on credentials injection
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v20.1.5]]> + https://github.com/hapijs/hapi/milestone/296 + + 2021-06-28T22:01:30.000Z + +
  • [#4264] Fix req end during response transmission
  • [#4262] Streaming uploads cause truncated responses in node 16
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v20.1.4]]> + https://github.com/hapijs/hapi/milestone/295 + + 2021-06-10T13:17:41.000Z + +
  • [#4257] Add response lifecycle tracking and checks
  • [#4256] inert + hapi may be leaking file descriptors
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v20.1.3]]> + https://github.com/hapijs/hapi/milestone/294 + + 2021-05-10T14:52:40.000Z + +
  • [#4250] Update to mimos v6
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v20.1.2]]> + https://github.com/hapijs/hapi/milestone/293 + + 2021-03-20T22:46:32.000Z + +
  • [#4239] Fix abort test timing to be consistent from node v12 through v16
  • [#4231] Update dependencies version range
  • [#4225] Future-proof hapi for node v16, rely on res close rather than req
  • [#4095] Rely on stream.destroy() whenever available
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v20.1.1]]> + https://github.com/hapijs/hapi/milestone/291 + + 2021-03-16T02:11:37.000Z + +
  • [#4234] Allow for res to have already closed during transmission
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v20.1.0]]> + https://github.com/hapijs/hapi/milestone/290 + + 2021-01-25T23:56:24.000Z + +
  • [#4221] Fix tests for citgm
  • [#4219] Add policy event
  • [#4203] Add closing event
  • [#4194] Add a 'closing' event
  • [#4104] Track cache policies
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v20.0.3]]> + https://github.com/hapijs/hapi/milestone/289 + + 2020-11-23T20:58:34.000Z + +
  • [#4191] Preserve original response status on error after write, fix status message
  • [#4182] server.inject does not reflect actual HTTP response in case of stream error
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v20.0.2]]> + https://github.com/hapijs/hapi/milestone/288 + + 2020-11-11T03:44:29.000Z + +
  • [#4167] upgrade to labv24
  • [#4089] [default-scope] Accept default scope as a valid route scope
  • [#4083] Default auth scope not compatible with route auth scope
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v20.0.1]]> + https://github.com/hapijs/hapi/milestone/287 + + 2020-09-24T02:24:20.000Z + +
  • [#4162] Use response instead of request when marshalling
  • [#4161] fix: check if _isPayloadSupported is set
  • [#4156] update handlebars dependency version
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v20.0.0]]> + https://github.com/hapijs/hapi/milestone/286 + + 2020-08-11T19:57:02.000Z + +
  • [#4140] update to travis templates
  • [#4139] update most out of date dependencies
  • [#4138] 20.0.0 Release Notes
  • [#4134] headers: avoid sending null content-type
  • [#4133] Content-type header is null when empty response is returned
  • [#4132] README needs this change to parse the slogan for site
  • [#4130] fixed teamwork version
  • [#4123] Removing the route timeout validation
  • [#4122] Payload timeout must be shorter than socket timeout
  • [#4117] Implement `isInjected` read-only request property to indicate request…
  • [#4116] Improved injected request detection
  • [#4115] Replace joi with validate
  • [#4113] The future of the hapi project
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v19.2.0]]> + https://github.com/hapijs/hapi/milestone/278 + + 2020-07-17T19:34:46.000Z + +
  • [#4077] Decorate response object
  • [#4073] Add new ext onPostResponse
  • [#4072] Response Event For Aborted Requests Has Status Code Of 200
  • [#4051] Expose (likely?) Content-Type on response object
  • [#4041] How to access catbox client instances through the framework?
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v19.1.1]]> + https://github.com/hapijs/hapi/milestone/277 + + 2020-02-13T19:15:37.000Z + +
  • [#4043] Update deps
  • [#4027] Problem with settings global request.payload.multipart to true in Hapi v19
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v19.1.0]]> + https://github.com/hapijs/hapi/milestone/276 + + 2020-02-03T21:33:54.000Z + +
  • [#4034] request.info.remoteAddress / request.info.remotePort undefined after connection closed (request aborted)
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v19.0.5]]> + https://github.com/hapijs/hapi/milestone/275 + + 2020-01-16T10:18:43.000Z + +
  • [#4026] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v19.0.4]]> + https://github.com/hapijs/hapi/milestone/274 + + 2020-01-13T11:42:05.000Z + +
  • [#4022] Revert #4021
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v19.0.3]]> + https://github.com/hapijs/hapi/milestone/273 + + 2020-01-13T02:32:28.000Z + +
  • [#4021] Retain '' result in inject in 204 response
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v19.0.2]]> + https://github.com/hapijs/hapi/milestone/272 + + 2020-01-10T17:57:52.000Z + +
  • [#4020] support JSON.stringify() of request.info
  • [#4019] Feature request: custom toJSON() method for request.info
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v19.0.1]]> + https://github.com/hapijs/hapi/milestone/271 + + 2020-01-10T07:18:36.000Z + +
  • [#4018] Override request.url in setUrl()
  • ]]>
    +
    + + <![CDATA[@hapi/hapi v19.0.0]]> + https://github.com/hapijs/hapi/milestone/254 + + 2020-01-10T04:22:19.000Z + +
  • [#4017] 19.0.0 Release Notes
  • [#4015] Do not override request.payload if set manually in onRequest
  • [#4013] Use private class fields
  • [#4012] Drop node 10
  • [#4011] Change scoped plugins name handling
  • [#4006] server.validator()
  • [#4002] fix(auth): properly populate request.auth on failed auth
  • [#4000] auth scheme artifacts are dropped when mode is not 'try'
  • [#3996] Decorate requests with symbols with apply=true
  • [#3995] Fix ? in fragment part
  • [#3987] Support SameSite=None for cookies
  • [#3977] Remove request queue (options.load.concurrent)
  • [#3976] Update hapijs/joi to 16.0.1 from 15.1.1
  • [#3920] Change routes.payload.multipart to false by default
  • [#3919] Change emptyStatusCode to 204 by default
  • [#3910] Drop support for node v8
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/heavy.atom b/docs/public/atom/heavy.atom new file mode 100644 index 00000000..38ab8eae --- /dev/null +++ b/docs/public/atom/heavy.atom @@ -0,0 +1,194 @@ + + + https://hapi.dev/module/heavy + @hapi/heavy changelog + 2023-02-11T19:36:41.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/heavy v8.0.1]]> + https://github.com/hapijs/heavy/milestone/26 + + 2023-02-11T19:36:41.000Z + +
  • [#51] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/heavy v8.0.0]]> + https://github.com/hapijs/heavy/milestone/25 + + 2023-02-11T19:36:39.000Z + +
  • [#50] Support node v18 and drop node v12
  • [#48] Add event loop utilization support
  • ]]>
    +
    + + <![CDATA[@hapi/heavy v7.0.1]]> + https://github.com/hapijs/heavy/milestone/23 + + 2021-09-24T13:10:43.000Z + +
  • [#44] upgrade lab to v24
  • ]]>
    +
    + + <![CDATA[@hapi/heavy v7.0.0]]> + https://github.com/hapijs/heavy/milestone/22 + + 2020-01-05T04:47:21.000Z + +
  • [#36] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/heavy v6.2.2]]> + https://github.com/hapijs/heavy/milestone/20 + + 2019-09-12T20:46:24.000Z + +
  • [#32] Update joi
  • ]]>
    +
    + + <![CDATA[@hapi/heavy v6.2.1]]> + https://github.com/hapijs/heavy/milestone/19 + + 2019-08-15T06:53:01.000Z + +
  • [#31] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/heavy v6.2.0]]> + https://github.com/hapijs/heavy/milestone/16 + + 2019-04-02T05:31:29.000Z + +
  • [#29] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/heavy v6.1.2]]> + https://github.com/hapijs/heavy/milestone/15 + + 2018-11-03T00:27:19.000Z + +
  • [#26] Remove engines
  • ]]>
    +
    + + <![CDATA[@hapi/heavy v6.1.1]]> + https://github.com/hapijs/heavy/milestone/14 + + 2018-11-01T07:59:30.000Z + +
  • [#25] Update hoek v6
  • ]]>
    +
    + + <![CDATA[@hapi/heavy v6.1.0]]> + https://github.com/hapijs/heavy/milestone/13 + + 2017-12-19T23:59:29.000Z + +
  • [#23] Allow unknown config keys
  • ]]>
    +
    + + <![CDATA[@hapi/heavy v6.0.0]]> + https://github.com/hapijs/heavy/milestone/12 + + 2017-11-03T07:43:26.000Z + +
  • [#22] Throw in check()
  • ]]>
    +
    + + <![CDATA[@hapi/heavy v5.0.2]]> + https://github.com/hapijs/heavy/milestone/11 + + 2017-10-22T08:27:20.000Z + +
  • [#21] Update joi
  • ]]>
    +
    + + <![CDATA[@hapi/heavy v5.0.1]]> + https://github.com/hapijs/heavy/milestone/10 + + 2017-09-26T17:51:39.000Z + +
  • [#20] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/heavy v5.0.0]]> + https://github.com/hapijs/heavy/milestone/9 + + 2017-09-26T17:50:38.000Z + +
  • [#18] Refactor for single connection
  • ]]>
    +
    + + <![CDATA[@hapi/heavy v4.1.0]]> + https://github.com/hapijs/heavy/milestone/17 + + 2019-03-25T00:06:30.000Z + +
  • [#28] Commercial version of v4 branch
  • ]]>
    +
    + + <![CDATA[@hapi/heavy v4.0.4]]> + https://github.com/hapijs/heavy/milestone/8 + + 2017-09-14T22:40:58.000Z + +
  • [#16] Update deps.
  • ]]>
    +
    + + <![CDATA[@hapi/heavy v4.0.3]]> + https://github.com/hapijs/heavy/milestone/7 + + 2016-11-29T02:01:25.000Z + +
  • [#15] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/heavy v4.0.2]]> + https://github.com/hapijs/heavy/milestone/6 + + 2016-07-27T19:53:58.000Z + +
  • [#13] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/heavy v4.0.1]]> + https://github.com/hapijs/heavy/milestone/5 + + 2016-05-05T17:04:54.000Z + +
  • [#11] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/heavy v4.0.0]]> + https://github.com/hapijs/heavy/milestone/4 + + 2015-11-02T04:02:09.000Z + +
  • [#10] ES6 style changes and node v4
  • ]]>
    +
    + + <![CDATA[@hapi/heavy v3.0.1]]> + https://github.com/hapijs/heavy/milestone/3 + + 2015-11-02T03:55:36.000Z + +
  • [#8] Closes #6, Closes #7
  • [#7] bring heavy up to date with standards
  • [#6] upgrade joi
  • [#4] Update .travis.yml
  • ]]>
    +
    + + <![CDATA[@hapi/heavy v3.0.0]]> + https://github.com/hapijs/heavy/milestone/1 + + 2014-12-09T22:49:22.000Z + +
  • [#2] Update check() to return reason why
  • ]]>
    +
    + + <![CDATA[@hapi/heavy v2.0.0]]> + https://github.com/hapijs/heavy/milestone/2 + + 2014-10-31T02:18:38.000Z + +
  • [#1] Split sampling from policy
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/hoek.atom b/docs/public/atom/hoek.atom new file mode 100644 index 00000000..75d75158 --- /dev/null +++ b/docs/public/atom/hoek.atom @@ -0,0 +1,410 @@ + + + https://hapi.dev/module/hoek + @hapi/hoek changelog + 2024-11-14T15:55:17.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/hoek v11.0.7]]> + https://github.com/hapijs/hoek/milestone/108 + + 2024-11-14T15:55:17.000Z + +
  • [#402] Fix cloning Util.inherit() subclassed errors. Backports #401
  • [#401] Fix cloning Util.inherit() subclassed errors
  • [#400] Hoek.clone drop an error with axios errors in version @hapi/hoek 11.0.6+
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v11.0.6]]> + https://github.com/hapijs/hoek/milestone/107 + + 2024-10-24T22:05:42.000Z + +
  • [#399] Fix Error clone() when structuredClone uses bad prototype
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v11.0.5]]> + https://github.com/hapijs/hoek/milestone/106 + + 2024-10-24T22:03:04.000Z + +
  • [#398] fix: missing stack starting from node 21+
  • [#396] Fix default values for `merge.Options` interface
  • [#395] Incorrect default documented for `mergeArrays` option
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v11.0.4]]> + https://github.com/hapijs/hoek/milestone/105 + + 2023-12-05T10:49:28.000Z + +
  • [#389] fix: provide reference to TS types for export map
  • [#385] Missing types in typescript with module resolution nodenext
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v11.0.3]]> + https://github.com/hapijs/hoek/milestone/104 + + 2023-12-05T08:08:59.000Z + +
  • [#392] Support the URL type
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v11.0.2]]> + https://github.com/hapijs/hoek/milestone/102 + + 2023-02-18T18:52:59.000Z + +
  • [#384] chore: add individual module types
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v11.0.1]]> + https://github.com/hapijs/hoek/milestone/101 + + 2022-12-13T19:33:59.000Z + +
  • [#380] Explicitly export modules
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v11.0.0]]> + https://github.com/hapijs/hoek/milestone/100 + + 2022-12-13T08:05:19.000Z + +
  • [#382] Refactor AssertError
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v10.0.1]]> + https://github.com/hapijs/hoek/milestone/98 + + 2022-07-23T18:31:42.000Z + +
  • [#383] Updates assert() type to declare condition to be true
  • [#379] Fix version range
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v10.0.0]]> + https://github.com/hapijs/hoek/milestone/97 + + 2022-05-01T18:02:50.000Z + +
  • [#377] Support node v18 and drop node v12
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v9.3.0]]> + https://github.com/hapijs/hoek/milestone/96 + + 2022-05-01T18:00:57.000Z + +
  • [#373] Handle very long timeouts in Hoek.wait()
  • [#372] Cleanup
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v9.2.1]]> + https://github.com/hapijs/hoek/milestone/94 + + 2021-09-27T20:57:03.000Z + +
  • [#371] Fix reachTemplate() regex timing
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v9.2.0]]> + https://github.com/hapijs/hoek/milestone/93 + + 2021-04-17T21:10:59.000Z + +
  • [#368] Support named imports when using node esm loader
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v9.1.1]]> + https://github.com/hapijs/hoek/milestone/92 + + 2020-12-27T17:02:12.000Z + +
  • [#367] applyToDefaults: respect nullOverride when shallow is used
  • [#365] Fix applyToDefaults to work better with non-object source values
  • [#361] upgrade lab to v24 and devDependency of typescript
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v9.1.0]]> + https://github.com/hapijs/hoek/milestone/91 + + 2020-09-02T01:38:07.000Z + +
  • [#360] Always call base class methods to inspect Map and Set
  • [#359] Add returnValue option to wait()
  • [#357] deepEqual() can fail on subclassed map
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v9.0.4]]> + https://github.com/hapijs/hoek/milestone/90 + + 2020-03-12T05:11:19.000Z + +
  • [#351] Fix 'compare is not a function'
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v9.0.3]]> + https://github.com/hapijs/hoek/milestone/88 + + 2020-02-08T06:59:41.000Z + +
  • [#352] Prevent prototype poisoning in clone()
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v9.0.2]]> + https://github.com/hapijs/hoek/milestone/87 + + 2020-01-09T18:26:01.000Z + +
  • [#350] Clone fails to copy override array prototype
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v9.0.1]]> + https://github.com/hapijs/hoek/milestone/86 + + 2020-01-09T06:17:18.000Z + +
  • [#349] Fix shallow defaults clone
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v9.0.0]]> + https://github.com/hapijs/hoek/milestone/85 + + 2020-01-03T23:06:49.000Z + +
  • [#347] Support only node 12
  • [#343] Safer and faster shallow handling
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v8.5.1]]> + https://github.com/hapijs/hoek/milestone/84 + + 2020-02-08T06:59:43.000Z + +
  • [#353] Prevent prototype poisoning in clone() (v8)
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v8.5.0]]> + https://github.com/hapijs/hoek/milestone/83 + + 2019-10-31T00:37:26.000Z + +
  • [#346] Add isPromise()
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v8.4.0]]> + https://github.com/hapijs/hoek/milestone/82 + + 2019-10-30T06:35:08.000Z + +
  • [#345] Add ts.XOR<>
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v8.3.2]]> + https://github.com/hapijs/hoek/milestone/81 + + 2019-10-17T20:54:08.000Z + +
  • [#344] Improve clone() performance
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v8.3.1]]> + https://github.com/hapijs/hoek/milestone/80 + + 2019-10-15T06:28:04.000Z + +
  • [#342] contain() part option allows no matches
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v8.3.0]]> + https://github.com/hapijs/hoek/milestone/79 + + 2019-10-05T03:18:40.000Z + +
  • [#341] Block once in contain() when subject is an object
  • [#340] Error.captureStackTrace can't be used in Joi's browser build
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v8.2.5]]> + https://github.com/hapijs/hoek/milestone/78 + + 2019-09-28T07:13:14.000Z + +
  • [#338] Export interfaces
  • [#337] deepEqual with skip seems to ignore missing properties
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v8.2.4]]> + https://github.com/hapijs/hoek/milestone/77 + + 2019-09-09T06:18:56.000Z + +
  • [#330] Remove deep limit on contain with object
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v8.2.3]]> + https://github.com/hapijs/hoek/milestone/76 + + 2019-09-08T19:10:33.000Z + +
  • [#329] deepEqual() fails to compare errors when prototype is false
  • [#327] contain() passes with extra values with only and not once
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v8.2.2]]> + https://github.com/hapijs/hoek/milestone/73 + + 2019-09-08T19:10:08.000Z + + ]]> + + + <![CDATA[@hapi/hoek v8.2.1]]> + https://github.com/hapijs/hoek/milestone/72 + + 2019-08-12T19:48:25.000Z + +
  • [#324] Fix empty ref bug in contain when only is true
  • [#323] contain() is always true for empty ref with only and not once
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v8.2.0]]> + https://github.com/hapijs/hoek/milestone/71 + + 2019-08-07T21:35:23.000Z + +
  • [#322] Break methods for deep require
  • [#321] Handle no Buffer support
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v8.1.0]]> + https://github.com/hapijs/hoek/milestone/70 + + 2019-07-24T17:41:28.000Z + +
  • [#319] skip and deepFunction options for deepEqual()
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v8.0.2]]> + https://github.com/hapijs/hoek/milestone/69 + + 2019-07-01T16:54:08.000Z + +
  • [#317] Restore ability to assert with pre-made error
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v8.0.1]]> + https://github.com/hapijs/hoek/milestone/68 + + 2019-06-26T17:18:20.000Z + +
  • [#316] Make assert() generate a named Error so bounce can identify
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v8.0.0]]> + https://github.com/hapijs/hoek/milestone/67 + + 2019-06-26T05:57:21.000Z + +
  • [#315] v8.0.0 Release Notes
  • [#314] Change assert() AssertionError to Error
  • [#313] Remove uniqueFilename()
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v7.2.1]]> + https://github.com/hapijs/hoek/milestone/66 + + 2019-06-23T04:10:44.000Z + +
  • [#312] Minor performance
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v7.2.0]]> + https://github.com/hapijs/hoek/milestone/65 + + 2019-06-22T03:50:14.000Z + +
  • [#311] Support reach into Set and Map objects
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v7.1.0]]> + https://github.com/hapijs/hoek/milestone/64 + + 2019-06-01T17:49:13.000Z + +
  • [#308] Shallow clone of entire object
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v7.0.0]]> + https://github.com/hapijs/hoek/milestone/63 + + 2019-05-31T21:38:24.000Z + +
  • [#306] v7.0.0 Release Notes
  • [#305] Support symbols in merge()
  • [#304] Replace applyToDefaultsWithShallow() with applyToDefaults(..., { shallow })
  • [#303] Replace cloneWithShallow() with clone(value, { shallow })
  • [#285] Change all individual option arguments to { options } object
  • [#284] Default handling of symbols to true by default
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v6.2.6]]> + https://github.com/hapijs/hoek/milestone/74 + + 2019-09-01T07:35:48.000Z + +
  • [#328] deepEqual() skip fails when number of keys is diff
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v6.2.4]]> + https://github.com/hapijs/hoek/milestone/62 + + 2019-05-27T00:44:26.000Z + +
  • [#302] Fix clone of subclassed Set and Map
  • [#301] Fix: Add map and set to seen map
  • [#300] Stack overflow in clone in v6.2.3
  • [#298] Typescript enhancements
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v6.2.3]]> + https://github.com/hapijs/hoek/milestone/61 + + 2019-05-17T20:15:56.000Z + +
  • [#299] Set deepEqual() prototype option to true by default, not just when no options are passed
  • [#297] Clone Map and Set
  • [#228] Hoek.clone() issues
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v6.2.2]]> + https://github.com/hapijs/hoek/milestone/60 + + 2019-05-17T20:11:07.000Z + +
  • [#295] Bootstrap types from @types
  • [#294] Handle promises in deepEqual()
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v6.2.1]]> + https://github.com/hapijs/hoek/milestone/58 + + 2019-03-29T22:27:48.000Z + +
  • [#291] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v6.2.0]]> + https://github.com/hapijs/hoek/milestone/55 + + 2019-03-27T00:22:51.000Z + +
  • [#289] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v6.1.3]]> + https://github.com/hapijs/hoek/milestone/59 + + 2019-03-27T00:32:39.000Z + +
  • [#290] Fix clone without prototype
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v6.1.2]]> + https://github.com/hapijs/hoek/milestone/54 + + 2018-12-01T08:36:56.000Z + +
  • [#283] Revert cloning of symbols to false by default
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v6.1.1]]> + https://github.com/hapijs/hoek/milestone/53 + + 2018-11-28T22:32:05.000Z + +
  • [#282] Ignore symbols by default in deepEqual()
  • [#281] Symbol support
  • ]]>
    +
    + + <![CDATA[@hapi/hoek v6.0.4]]> + https://github.com/hapijs/hoek/milestone/52 + + 2018-11-24T12:40:20.000Z + +
  • [#278] Hoek.clone() defineProperty issue
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/inert.atom b/docs/public/atom/inert.atom new file mode 100644 index 00000000..cd87589e --- /dev/null +++ b/docs/public/atom/inert.atom @@ -0,0 +1,346 @@ + + + https://hapi.dev/module/inert + @hapi/inert changelog + 2023-03-13T15:42:42.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/inert v7.1.0]]> + https://github.com/hapijs/inert/milestone/43 + + 2023-03-13T15:42:42.000Z + +
  • [#169] feat: import DT types
  • ]]>
    +
    + + <![CDATA[@hapi/inert v7.0.1]]> + https://github.com/hapijs/inert/milestone/42 + + 2023-02-11T20:54:07.000Z + +
  • [#167] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/inert v7.0.0]]> + https://github.com/hapijs/inert/milestone/41 + + 2022-07-17T21:08:06.000Z + +
  • [#164] Support node v18 and hapi v21, drop node v12 and hapi v19
  • ]]>
    +
    + + <![CDATA[@hapi/inert v6.0.5]]> + https://github.com/hapijs/inert/milestone/39 + + 2022-01-16T20:12:16.000Z + +
  • [#162] fix: return 404 for ENOTDIR
  • ]]>
    +
    + + <![CDATA[@hapi/inert v6.0.4]]> + https://github.com/hapijs/inert/milestone/38 + + 2021-08-30T20:44:28.000Z + +
  • [#160] Disallow serving absolute paths from directory handler
  • ]]>
    +
    + + <![CDATA[@hapi/inert v6.0.3]]> + https://github.com/hapijs/inert/milestone/37 + + 2020-09-26T18:03:51.000Z + +
  • [#152] migrate to new travis format
  • [#151] Cleanup & update lru-cache
  • [#150] Fix travis to test hapi v20 and on node v14
  • [#149] upgrade to hapi 20
  • ]]>
    +
    + + <![CDATA[@hapi/inert v6.0.2]]> + https://github.com/hapijs/inert/milestone/36 + + 2020-09-26T18:03:47.000Z + +
  • [#148] update lab and switch joi to validate
  • [#144] Update LICENSE.md
  • [#142] Correct default value for etagsCacheMaxSize
  • ]]>
    +
    + + <![CDATA[@hapi/inert v6.0.1]]> + https://github.com/hapijs/inert/milestone/35 + + 2020-09-26T18:03:43.000Z + +
  • [#140] Change plugin name to @hapi/inert
  • [#139] Require hapi 19
  • [#138] Update deps for hapi v19
  • ]]>
    +
    + + <![CDATA[@hapi/inert v6.0.0]]> + https://github.com/hapijs/inert/milestone/34 + + 2020-01-05T05:07:35.000Z + +
  • [#137] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/inert v5.2.3]]> + https://github.com/hapijs/inert/milestone/33 + + 2020-09-26T17:44:22.000Z + + ]]> + + + <![CDATA[@hapi/inert v5.2.2]]> + https://github.com/hapijs/inert/milestone/32 + + 2019-09-12T23:10:52.000Z + +
  • [#130] Update joi
  • [#124] Directory listing has broken links
  • ]]>
    +
    + + <![CDATA[@hapi/inert v5.2.1]]> + https://github.com/hapijs/inert/milestone/31 + + 2019-06-26T05:59:26.000Z + +
  • [#127] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/inert v5.2.0]]> + https://github.com/hapijs/inert/milestone/30 + + 2019-04-10T22:08:53.000Z + +
  • [#126] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/inert v5.1.3]]> + https://github.com/hapijs/inert/milestone/29 + + 2019-04-02T21:42:23.000Z + +
  • [#125] Directory routes doesn't work with relative files.relativeTo
  • [#119] Directory listing has broken links, missing a slash between file and directory
  • ]]>
    +
    + + <![CDATA[@hapi/inert v5.1.2]]> + https://github.com/hapijs/inert/milestone/28 + + 2018-11-07T07:34:05.000Z + +
  • [#122] Use new requirements config
  • ]]>
    +
    + + <![CDATA[@hapi/inert v5.1.1]]> + https://github.com/hapijs/inert/milestone/27 + + 2018-11-01T08:07:59.000Z + +
  • [#121] Update deps.
  • ]]>
    +
    + + <![CDATA[@hapi/inert v5.1.0]]> + https://github.com/hapijs/inert/milestone/26 + + 2018-11-01T08:07:58.000Z + +
  • [#111] Add failing path to errors
  • ]]>
    +
    + + <![CDATA[@hapi/inert v5.0.1]]> + https://github.com/hapijs/inert/milestone/25 + + 2017-11-04T00:00:19.000Z + +
  • [#103] Rethrow developer errors
  • ]]>
    +
    + + <![CDATA[@hapi/inert v5.0.0]]> + https://github.com/hapijs/inert/milestone/24 + + 2017-11-03T23:59:33.000Z + +
  • [#102] Update deps
  • [#100] 5.0.0 Release Notes
  • [#99] Move etagsCacheMaxSize to server option
  • [#97] Internal rewrite to async / await
  • ]]>
    +
    + + <![CDATA[@hapi/inert v4.2.1]]> + https://github.com/hapijs/inert/milestone/23 + + 2017-09-19T22:28:14.000Z + +
  • [#93] Limit "node" tests to only try configured hapi release
  • ]]>
    +
    + + <![CDATA[@hapi/inert v4.2.0]]> + https://github.com/hapijs/inert/milestone/22 + + 2017-04-03T11:37:14.000Z + +
  • [#87] Add start end option to file handler
  • ]]>
    +
    + + <![CDATA[@hapi/inert v4.1.0]]> + https://github.com/hapijs/inert/milestone/21 + + 2016-12-27T20:34:04.000Z + +
  • [#71] Add lookupMap option
  • ]]>
    +
    + + <![CDATA[@hapi/inert v4.0.4]]> + https://github.com/hapijs/inert/milestone/20 + + 2016-12-22T00:00:45.000Z + +
  • [#79] Manually extract last param name from path
  • ]]>
    +
    + + <![CDATA[@hapi/inert v4.0.3]]> + https://github.com/hapijs/inert/milestone/19 + + 2016-11-29T02:54:57.000Z + +
  • [#76] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/inert v4.0.2]]> + https://github.com/hapijs/inert/milestone/18 + + 2016-08-23T11:43:18.000Z + +
  • [#70] Errors on old hapi releases
  • ]]>
    +
    + + <![CDATA[@hapi/inert v4.0.1]]> + https://github.com/hapijs/inert/milestone/17 + + 2016-08-23T11:40:12.000Z + +
  • [#68] Update code to v3
  • [#67] The hapi response.ranges option is not respected
  • [#63] Test on node v6
  • ]]>
    +
    + + <![CDATA[@hapi/inert v4.0.0]]> + https://github.com/hapijs/inert/milestone/16 + + 2016-05-09T10:44:30.000Z + +
  • [#62] 4.0.0 Release Notes
  • [#60] Hapijs directory route not being scrapped by facebook behind cloudfront
  • [#59] remove hoek.isAbsolutePath for path.isAbsolute
  • [#56] Clarify bad path for directory handler message
  • [#53] Update lru-cache
  • [#51] Update dependencies. Update codebase to ES6/Node4
  • [#49] ES6 style changes and node v4
  • [#47] Add confine option that confines file responses
  • ]]>
    +
    + + <![CDATA[@hapi/inert v3.2.0]]> + https://github.com/hapijs/inert/milestone/12 + + 2015-10-24T12:09:28.000Z + +
  • [#30] Add new etaging options
  • [#29] New ETag generation method
  • ]]>
    +
    + + <![CDATA[@hapi/inert v3.1.0]]> + https://github.com/hapijs/inert/milestone/15 + + 2015-10-06T10:46:06.000Z + +
  • [#44] Test using hapi@10.x
  • [#43] Add new attributes: connections: false, once: true
  • ]]>
    +
    + + <![CDATA[@hapi/inert v3.0.2]]> + https://github.com/hapijs/inert/milestone/14 + + 2015-10-04T10:30:12.000Z + +
  • [#42] Avoid re-opening files when serving from a directory
  • ]]>
    +
    + + <![CDATA[@hapi/inert v3.0.1]]> + https://github.com/hapijs/inert/milestone/13 + + 2015-08-12T12:52:03.000Z + +
  • [#36] Respect the new connection compression option
  • [#32] Move hapi security tests here
  • ]]>
    +
    + + <![CDATA[@hapi/inert v3.0.0]]> + https://github.com/hapijs/inert/milestone/11 + + 2015-08-08T00:42:44.000Z + +
  • [#35] Move config to plugin options from hapi server. Closes #34
  • [#34] Move etags caching config to plugin options
  • ]]>
    +
    + + <![CDATA[@hapi/inert v2.1.6]]> + https://github.com/hapijs/inert/milestone/10 + + 2015-07-06T11:48:06.000Z + +
  • [#28] Never store ETags computed on partial data
  • [#27] ETag generation can miss data
  • ]]>
    +
    + + <![CDATA[@hapi/inert v2.1.5]]> + https://github.com/hapijs/inert/milestone/9 + + 2015-05-21T17:07:33.000Z + +
  • [#26] Misc. Closes #25
  • ]]>
    +
    + + <![CDATA[@hapi/inert v2.1.4]]> + https://github.com/hapijs/inert/milestone/8 + + 2015-03-10T07:21:09.000Z + +
  • [#23] Upgrade to joi 6.0
  • ]]>
    +
    + + <![CDATA[@hapi/inert v2.1.3]]> + https://github.com/hapijs/inert/milestone/7 + + 2015-03-10T06:48:30.000Z + +
  • [#22] Add io.js support
  • [#21] Return 404 for path string with a null byte
  • ]]>
    +
    + + <![CDATA[@hapi/inert v2.1.2]]> + https://github.com/hapijs/inert/milestone/6 + + 2015-01-26T17:47:40.000Z + +
  • [#19] Fix directory handler regressions in 2.1.1
  • ]]>
    +
    + + <![CDATA[@hapi/inert v2.1.1]]> + https://github.com/hapijs/inert/milestone/5 + + 2015-01-23T09:26:15.000Z + +
  • [#18] Replace 404 response with 403 and 500 when appropriate
  • ]]>
    +
    + + <![CDATA[@hapi/inert v2.1.0]]> + https://github.com/hapijs/inert/milestone/4 + + 2015-01-12T09:53:24.000Z + +
  • [#17] Handle Range requests explicitly
  • [#10] more flexible 'index' option for directory handler
  • ]]>
    +
    + + <![CDATA[@hapi/inert v2.0.0]]> + https://github.com/hapijs/inert/milestone/2 + + 2014-12-09T22:53:07.000Z + +
  • [#16] Fix option parsing to match hapi documentation
  • [#14] Use .single() option for directory settings schema
  • [#12] Don't allow files in hidden directories to be served
  • [#9] Fix tests on windows
  • [#8] Use open file descriptors to retain file between prepare and marshal phases
  • [#7] Invalid ETag for lookupCompressed responses
  • [#4] Potentially incorrect file responses when file is changed
  • ]]>
    +
    + + <![CDATA[@hapi/inert v1.1.1]]> + https://github.com/hapijs/inert/milestone/3 + + 2014-12-10T13:41:55.000Z + +
  • [#15] Don't allow files in hidden directories to be served
  • [#13] Don't allow files in hidden directories to be served (backported)
  • ]]>
    +
    + + <![CDATA[@hapi/inert v1.1.0]]> + https://github.com/hapijs/inert/milestone/1 + + 2014-10-22T08:08:12.000Z + +
  • [#3] Move lru-cache over from hapi
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/iron.atom b/docs/public/atom/iron.atom new file mode 100644 index 00000000..b9d7b9fc --- /dev/null +++ b/docs/public/atom/iron.atom @@ -0,0 +1,242 @@ + + + https://hapi.dev/module/iron + @hapi/iron changelog + 2023-02-11T19:03:10.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/iron v7.0.1]]> + https://github.com/hapijs/iron/milestone/33 + + 2023-02-11T19:03:10.000Z + +
  • [#104] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/iron v7.0.0]]> + https://github.com/hapijs/iron/milestone/32 + + 2022-05-23T03:59:38.000Z + +
  • [#103] Support node v18 and drop node v12
  • ]]>
    +
    + + <![CDATA[@hapi/iron v6.0.0]]> + https://github.com/hapijs/iron/milestone/30 + + 2020-01-05T06:00:59.000Z + +
  • [#90] Fix iv type definition
  • [#89] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/iron v5.1.3]]> + https://github.com/hapijs/iron/milestone/28 + + 2019-09-20T23:05:48.000Z + +
  • [#84] Fix types and sync with previous TS until hapi is updated
  • [#83] Fixes #81: Replace defaults with SealOptions
  • ]]>
    +
    + + <![CDATA[@hapi/iron v5.1.2]]> + https://github.com/hapijs/iron/milestone/27 + + 2019-09-20T00:20:45.000Z + +
  • [#78] Added TS declarations
  • ]]>
    +
    + + <![CDATA[@hapi/iron v5.1.1]]> + https://github.com/hapijs/iron/milestone/26 + + 2019-08-14T22:18:12.000Z + +
  • [#77] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/iron v5.1.0]]> + https://github.com/hapijs/iron/milestone/23 + + 2019-04-02T06:38:05.000Z + +
  • [#74] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/iron v5.0.6]]> + https://github.com/hapijs/iron/milestone/22 + + 2018-11-03T00:43:10.000Z + +
  • [#72] Remove engines
  • ]]>
    +
    + + <![CDATA[@hapi/iron v5.0.5]]> + https://github.com/hapijs/iron/milestone/21 + + 2018-11-01T19:11:49.000Z + +
  • [#71] Update deps
  • [#70] seal() options is not guarded against mutation
  • ]]>
    +
    + + <![CDATA[@hapi/iron v5.0.4]]> + https://github.com/hapijs/iron/milestone/20 + + 2017-11-03T20:54:01.000Z + +
  • [#63] Use Cryptiles.fixedTimeComparison()
  • ]]>
    +
    + + <![CDATA[@hapi/iron v5.0.3]]> + https://github.com/hapijs/iron/milestone/19 + + 2017-11-03T18:28:45.000Z + +
  • [#62] Fix new Boom
  • ]]>
    +
    + + <![CDATA[@hapi/iron v5.0.2]]> + https://github.com/hapijs/iron/milestone/18 + + 2017-11-03T18:26:40.000Z + +
  • [#61] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/iron v5.0.1]]> + https://github.com/hapijs/iron/milestone/17 + + 2017-09-26T09:11:53.000Z + +
  • [#59] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/iron v5.0.0]]> + https://github.com/hapijs/iron/milestone/16 + + 2017-09-25T00:40:39.000Z + +
  • [#58] Migrate to async interface
  • ]]>
    +
    + + <![CDATA[@hapi/iron v4.1.0]]> + https://github.com/hapijs/iron/milestone/24 + + 2019-03-25T06:16:57.000Z + +
  • [#73] Commercial version of v4 branch
  • ]]>
    +
    + + <![CDATA[@hapi/iron v4.0.5]]> + https://github.com/hapijs/iron/milestone/15 + + 2017-05-28T06:40:56.000Z + +
  • [#53] Update deps.
  • ]]>
    +
    + + <![CDATA[@hapi/iron v4.0.4]]> + https://github.com/hapijs/iron/milestone/14 + + 2016-09-08T21:27:32.000Z + +
  • [#50] Always return boom errors
  • ]]>
    +
    + + <![CDATA[@hapi/iron v4.0.3]]> + https://github.com/hapijs/iron/milestone/13 + + 2016-08-26T07:33:15.000Z + +
  • [#45] Catch and report possible `JSON.stringify` errors in `Iron.seal`
  • ]]>
    +
    + + <![CDATA[@hapi/iron v4.0.2]]> + https://github.com/hapijs/iron/milestone/12 + + 2016-08-26T07:27:24.000Z + +
  • [#46] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/iron v4.0.1]]> + https://github.com/hapijs/iron/milestone/11 + + 2016-05-09T17:14:45.000Z + +
  • [#44] made exception message assertion less strict to account for different node 6 error message
  • [#43] added digest argument to crypto.pbkdf2
  • ]]>
    +
    + + <![CDATA[@hapi/iron v4.0.0]]> + https://github.com/hapijs/iron/milestone/10 + + 2016-02-01T07:27:09.000Z + +
  • [#39] Require min of n characters for passwords
  • ]]>
    +
    + + <![CDATA[@hapi/iron v3.0.1]]> + https://github.com/hapijs/iron/milestone/9 + + 2015-11-02T04:38:07.000Z + +
  • [#36] ES6 style changes and node v4
  • ]]>
    +
    + + <![CDATA[@hapi/iron v3.0.0]]> + https://github.com/hapijs/iron/milestone/5 + + 2014-08-18T20:24:59.000Z + + ]]> + + + <![CDATA[@hapi/iron v2.1.3]]> + https://github.com/hapijs/iron/milestone/8 + + 2015-08-12T04:51:03.000Z + + ]]> + + + <![CDATA[@hapi/iron v2.1.2]]> + https://github.com/hapijs/iron/milestone/7 + + 2015-08-12T04:51:01.000Z + +
  • [#24] Revert 3.0 changes. Back to 2.x
  • ]]>
    +
    + + <![CDATA[@hapi/iron v2.1.1]]> + https://github.com/hapijs/iron/milestone/4 + + 2014-08-02T07:34:52.000Z + +
  • [#19] Update contact
  • ]]>
    +
    + + <![CDATA[@hapi/iron v2.1.0]]> + https://github.com/hapijs/iron/milestone/2 + + 2014-05-20T21:00:48.000Z + +
  • [#17] Expanding on the password object format so that it becomes possible to s...
  • ]]>
    +
    + + <![CDATA[@hapi/iron v2.0.2]]> + https://github.com/hapijs/iron/milestone/3 + + 2014-04-27T05:01:46.000Z + +
  • [#15] Bring coverage back to 100%
  • ]]>
    +
    + + <![CDATA[@hapi/iron v2.0.1]]> + https://github.com/hapijs/iron/milestone/1 + + 2014-02-25T21:29:07.000Z + +
  • [#14] Support node 0.11
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/jwt.atom b/docs/public/atom/jwt.atom new file mode 100644 index 00000000..7c4d829a --- /dev/null +++ b/docs/public/atom/jwt.atom @@ -0,0 +1,130 @@ + + + https://hapi.dev/module/jwt + @hapi/jwt changelog + 2025-12-09T17:13:05.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/jwt v3.2.2]]> + https://github.com/hapijs/jwt/milestone/18 + + 2025-12-09T17:13:05.000Z + +
  • [#60] Fix: jwt constant time fixed time
  • ]]>
    +
    + + <![CDATA[@hapi/jwt v3.2.1]]> + https://github.com/hapijs/jwt/milestone/17 + + 2025-12-09T17:13:04.000Z + +
  • [#59] chore: improve keys typings
  • ]]>
    +
    + + <![CDATA[@hapi/jwt v3.2.0]]> + https://github.com/hapijs/jwt/milestone/16 + + 2025-09-02T13:15:25.000Z + +
  • [#54] feat: add local typings
  • ]]>
    +
    + + <![CDATA[@hapi/jwt v3.1.0]]> + https://github.com/hapijs/jwt/milestone/15 + + 2023-02-04T10:17:46.000Z + +
  • [#53] feat: EdDSA
  • [#48] EdDSA (ed25519, ed448) support
  • ]]>
    +
    + + <![CDATA[@hapi/jwt v3.0.0]]> + https://github.com/hapijs/jwt/milestone/11 + + 2022-08-29T20:07:09.000Z + +
  • [#47] Support hapi v21, drop hapi v19, test ESM support
  • [#39] use utf-8 encoding, closes #21
  • [#21] Utils.b64stringify() is called wrong
  • ]]>
    +
    + + <![CDATA[@hapi/jwt v2.2.0]]> + https://github.com/hapijs/jwt/milestone/14 + + 2022-08-29T19:33:07.000Z + +
  • [#43] add support for reading token from cookie
  • [#28] Load the JWT from an arbitrary location in the request
  • ]]>
    +
    + + <![CDATA[@hapi/jwt v2.1.1]]> + https://github.com/hapijs/jwt/milestone/9 + + 2022-03-24T23:48:31.000Z + +
  • [#46] fix: make compliant with jwt spec
  • ]]>
    +
    + + <![CDATA[@hapi/jwt v2.1.0]]> + https://github.com/hapijs/jwt/milestone/8 + + 2021-08-17T02:41:27.000Z + +
  • [#37] headless support.
  • [#34] Fix serialNumber and remove workarounds
  • [#29] allow typ in header to be optional.
  • [#23] Improvements to the API.md
  • ]]>
    +
    + + <![CDATA[@hapi/jwt v2.0.1]]> + https://github.com/hapijs/jwt/milestone/7 + + 2020-12-01T22:01:25.000Z + +
  • [#20] Changes to README.md to align with other modules in the family
  • [#18] Bump node-forge from 0.9.2 to 0.10.0
  • [#14] Update dependencies and travis
  • [#12] Add API.md
  • ]]>
    +
    + + <![CDATA[@hapi/jwt v2.0.0]]> + https://github.com/hapijs/jwt/milestone/6 + + 2020-01-22T08:29:33.000Z + +
  • [#11] Require hapi 19 or newer
  • [#10] Change plugin name to @commercial/jwt
  • [#9] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/jwt v1.1.2]]> + https://github.com/hapijs/jwt/milestone/5 + + 2019-09-12T22:41:01.000Z + +
  • [#6] Update joi
  • ]]>
    +
    + + <![CDATA[@hapi/jwt v1.1.1]]> + https://github.com/hapijs/jwt/milestone/4 + + 2019-08-15T06:35:17.000Z + +
  • [#5] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/jwt v1.1.0]]> + https://github.com/hapijs/jwt/milestone/3 + + 2019-05-01T05:47:12.000Z + +
  • [#3] Support ttlSec on generate()
  • ]]>
    +
    + + <![CDATA[@hapi/jwt v1.0.2]]> + https://github.com/hapijs/jwt/milestone/2 + + 2019-05-01T00:43:01.000Z + +
  • [#2] Expire token on exp, not just after
  • ]]>
    +
    + + <![CDATA[@hapi/jwt v1.0.1]]> + https://github.com/hapijs/jwt/milestone/1 + + 2019-04-30T23:41:11.000Z + +
  • [#1] Verify payload once, not per key
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/lab.atom b/docs/public/atom/lab.atom new file mode 100644 index 00000000..b9ebc035 --- /dev/null +++ b/docs/public/atom/lab.atom @@ -0,0 +1,410 @@ + + + https://hapi.dev/module/lab + @hapi/lab changelog + 2026-03-26T19:26:11.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/lab v26.0.1]]> + https://github.com/hapijs/lab/milestone/202 + + 2026-03-26T19:26:11.000Z + +
  • [#1087] fix: guard parent access in `addTsEsmHook` for ESM-to-CJS sub-dependency resolution
  • [#1086] `@hapi/lab` crashes when TypeScript tests depend on ESM packages
  • ]]>
    +
    + + <![CDATA[@hapi/lab v26.0.0]]> + https://github.com/hapijs/lab/milestone/201 + + 2024-10-24T08:05:55.000Z + +
  • [#1081] chore: report node 18+ support
  • [#1080] 26.0.0 Release Notes
  • [#1079] chore: next version
  • [#1076] feat: target ESLint v9
  • [#1071] Tighten type checking config
  • ]]>
    +
    + + <![CDATA[@hapi/lab v25.3.2]]> + https://github.com/hapijs/lab/milestone/200 + + 2024-10-22T13:15:46.000Z + +
  • [#1078] Ignore new TypeScript global leak
  • ]]>
    +
    + + <![CDATA[@hapi/lab v25.3.1]]> + https://github.com/hapijs/lab/milestone/199 + + 2024-10-17T13:15:31.000Z + +
  • [#1075] fix: coverage for arrow functions returning literals
  • [#1074] fix: lint typescript files
  • ]]>
    +
    + + <![CDATA[@hapi/lab v25.3.0]]> + https://github.com/hapijs/lab/milestone/198 + + 2024-07-26T06:32:57.000Z + +
  • [#1073] feat: add explicit extension support when using Typescript and ESM
  • ]]>
    +
    + + <![CDATA[@hapi/lab v25.2.0]]> + https://github.com/hapijs/lab/milestone/197 + + 2024-01-15T13:14:31.000Z + +
  • [#1069] Always lint .ts
  • [#1065] Add `.ts` to the default `extensions` for `--lint`
  • ]]>
    +
    + + <![CDATA[@hapi/lab v25.1.4]]> + https://github.com/hapijs/lab/milestone/196 + + 2024-01-15T13:10:57.000Z + +
  • [#1070] Make report an allow list
  • ]]>
    +
    + + <![CDATA[@hapi/lab v25.1.2]]> + https://github.com/hapijs/lab/milestone/195 + + 2023-02-11T18:20:06.000Z + +
  • [#1061] Fix: add more typescript leaks
  • ]]>
    +
    + + <![CDATA[@hapi/lab v25.1.1]]> + https://github.com/hapijs/lab/milestone/194 + + 2023-02-11T18:18:28.000Z + +
  • [#1060] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/lab v25.1.0]]> + https://github.com/hapijs/lab/milestone/193 + + 2023-02-11T18:18:30.000Z + +
  • [#1059] Bump @types/node
  • [#1058] Deal with `Symbol(undici.globalDispatcher.1)` in Node.js 18+
  • [#1057] Enable linting of *.cjs and *.mjs files
  • [#1052] Add missing space after colon
  • ]]>
    +
    + + <![CDATA[@hapi/lab v25.0.1]]> + https://github.com/hapijs/lab/milestone/192 + + 2022-05-08T00:32:23.000Z + +
  • [#1051] Add check for TS error 2820
  • ]]>
    +
    + + <![CDATA[@hapi/lab v25.0.0]]> + https://github.com/hapijs/lab/milestone/190 + + 2022-05-07T22:58:25.000Z + +
  • [#1050] Upgrade dependences
  • [#1048] Update target to ES2020 to match node 14+
  • [#1045] Support node v18
  • [#1037] Remove undocumented --coverage-module option
  • [#1035] Upgrade to eslint v8
  • [#1034] Drop support for node v12
  • [#1021] Update linter to work with ESLint 8
  • ]]>
    +
    + + <![CDATA[@hapi/lab v24.7.0]]> + https://github.com/hapijs/lab/milestone/189 + + 2022-04-30T23:33:18.000Z + +
  • [#1044] Revise leak detection to use fresh node globals
  • [#1043] New --coverage-predicates option
  • [#1042] Remove node 8 compat fix
  • [#1041] feat: 🎸 depedencies cli option
  • [#1038] Update sindresorhus deps to pre ESM versions
  • [#1036] Coverage for nullish coalescing operator
  • [#1033] tsconfig paths alias
  • ]]>
    +
    + + <![CDATA[@hapi/lab v24.6.0]]> + https://github.com/hapijs/lab/milestone/188 + + 2022-04-02T22:20:53.000Z + +
  • [#1032] add Node.js 18 globals
  • [#1031] Support for ES modules
  • ]]>
    +
    + + <![CDATA[@hapi/lab v24.5.1]]> + https://github.com/hapijs/lab/milestone/187 + + 2022-01-19T18:48:34.000Z + +
  • [#1029] Add inline typescript sources to transformed output
  • [#1028] Skip coverage on non-mapped transpiled code
  • [#1018] Add @hapi/eslint-plugin as peer dependency
  • [#1017] Using the coverage reporter requires "@hapi/eslint-plugin" to be installed, even if it’s not used.
  • [#1002] Code coverage reports on transpiled JavaScript, instead of TypeScript source
  • [#972] Original files in HTML reporter
  • ]]>
    +
    + + <![CDATA[@hapi/lab v24.5.0]]> + https://github.com/hapijs/lab/milestone/186 + + 2021-12-31T07:46:14.000Z + +
  • [#1026] Add TypeScript support. Closes #1025
  • [#1001] Introduce an upper limit to how much actual vs. expected is diffed
  • ]]>
    +
    + + <![CDATA[@hapi/lab vv24.4.0]]> + https://github.com/hapijs/lab/milestone/185 + + 2021-11-09T05:10:49.000Z + +
  • [#1023] Cleanup flaky tests, lint CLI scripts
  • [#1020] Add DOMException and structuredClone globals to leaks module
  • [#1019] DOMException will be a global in Node.js 17+
  • ]]>
    +
    + + <![CDATA[@hapi/lab vv24.3.2]]> + https://github.com/hapijs/lab/milestone/184 + + 2021-07-16T12:59:22.000Z + +
  • [#1016] fix: never instrument eslint configs for coverage
  • ]]>
    +
    + + <![CDATA[@hapi/lab vv24.3.1]]> + https://github.com/hapijs/lab/milestone/183 + + 2021-07-16T12:58:49.000Z + +
  • [#1015] fix: correct semver range for @hapi/eslint-plugin
  • ]]>
    +
    + + <![CDATA[@hapi/lab vv24.3.0]]> + https://github.com/hapijs/lab/milestone/182 + + 2021-07-09T07:45:45.000Z + +
  • [#1014] Add eslint configuration
  • [#1013] Add eslint-plugin module config to lint/coverage feature
  • [#1012] Use the new module ESLint configuration
  • ]]>
    +
    + + <![CDATA[@hapi/lab v24.2.1]]> + https://github.com/hapijs/lab/milestone/181 + + 2021-06-29T17:25:40.000Z + +
  • [#1007] Report on private/protected class type errors
  • [#1006] Incorrect type error detection
  • ]]>
    +
    + + <![CDATA[@hapi/lab v24.2.0]]> + https://github.com/hapijs/lab/milestone/180 + + 2021-04-23T03:31:51.000Z + +
  • [#1004] Add new globals for node v16
  • ]]>
    +
    + + <![CDATA[@hapi/lab v24.1.1]]> + https://github.com/hapijs/lab/milestone/178 + + 2021-02-21T16:24:55.000Z + +
  • [#1000] Fix retrying of passing tests
  • ]]>
    +
    + + <![CDATA[@hapi/lab v24.1.0]]> + https://github.com/hapijs/lab/milestone/177 + + 2020-10-22T15:59:02.000Z + +
  • [#997] lib: add new globals from Node.js 15.x
  • ]]>
    +
    + + <![CDATA[@hapi/lab v24.0.0]]> + https://github.com/hapijs/lab/milestone/176 + + 2020-09-23T02:29:34.000Z + +
  • [#996] 24.0.0 Release Notes
  • [#995] Wait for pending ticks started by test
  • [#993] Shallow clone context
  • [#992] Allow typescript to be updated by clients
  • [#990] Use eslint-plugin-hapi embedded config
  • [#987] throw error if an async experiment function is provided
  • ]]>
    +
    + + <![CDATA[@hapi/lab v22.0.4]]> + https://github.com/hapijs/lab/milestone/175 + + 2020-03-12T17:10:15.000Z + +
  • [#975] Replace mkdirp with Fs.mkdirSync with recursive: true
  • [#974] Vulnerability in a dep of mkdirp
  • ]]>
    +
    + + <![CDATA[@hapi/lab v22.0.3]]> + https://github.com/hapijs/lab/milestone/174 + + 2020-01-04T09:24:50.000Z + +
  • [#968] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/lab v22.0.2]]> + https://github.com/hapijs/lab/milestone/173 + + 2019-12-28T17:25:00.000Z + +
  • [#963] Record retries
  • [#962] Replace Espree with babel-eslint
  • ]]>
    +
    + + <![CDATA[@hapi/lab v22.0.1]]> + https://github.com/hapijs/lab/milestone/172 + + 2019-12-28T07:27:49.000Z + +
  • [#961] Update es lint version
  • ]]>
    +
    + + <![CDATA[@hapi/lab v22.0.0]]> + https://github.com/hapijs/lab/milestone/171 + + 2019-12-28T07:09:49.000Z + +
  • [#960] Drop node 10
  • [#959] Update lint rules
  • [#957] update test assertion for node core changes
  • [#955] TS: String object type -> string literal type
  • [#954] TS: Uses an inferred generic on flags.mustCall
  • ]]>
    +
    + + <![CDATA[@hapi/lab v21.0.0]]> + https://github.com/hapijs/lab/milestone/170 + + 2019-10-14T07:47:36.000Z + +
  • [#950] Update types
  • [#949] Drop node 8
  • ]]>
    +
    + + <![CDATA[@hapi/lab v20.4.0]]> + https://github.com/hapijs/lab/milestone/169 + + 2019-10-05T02:51:10.000Z + +
  • [#948] Tags to skip types test line execution
  • [#945] coverage-all option triggers TypeError: Cannot set property 'source' of undefined
  • ]]>
    +
    + + <![CDATA[@hapi/lab v20.3.2]]> + https://github.com/hapijs/lab/milestone/168 + + 2019-09-23T19:23:35.000Z + +
  • [#943] Fails to load npm modules in ts tests
  • ]]>
    +
    + + <![CDATA[@hapi/lab v20.3.1]]> + https://github.com/hapijs/lab/milestone/167 + + 2019-09-23T07:09:07.000Z + +
  • [#942] Support types test execution on windows
  • ]]>
    +
    + + <![CDATA[@hapi/lab v20.3.0]]> + https://github.com/hapijs/lab/milestone/166 + + 2019-09-23T04:52:06.000Z + +
  • [#941] External modules coverage fails on windows due to path
  • [#940] Run TS tests, not just validate them
  • [#924] New diff is broken
  • [#856] coverage analysis modifies a function return
  • ]]>
    +
    + + <![CDATA[@hapi/lab v20.2.2]]> + https://github.com/hapijs/lab/milestone/165 + + 2019-09-01T07:31:52.000Z + +
  • [#938] Stupid typescript
  • ]]>
    +
    + + <![CDATA[@hapi/lab v20.2.1]]> + https://github.com/hapijs/lab/milestone/164 + + 2019-08-24T00:55:35.000Z + +
  • [#937] Support coverage of external modules with own coverage reports
  • ]]>
    +
    + + <![CDATA[@hapi/lab v20.1.0]]> + https://github.com/hapijs/lab/milestone/162 + + 2019-08-15T23:22:50.000Z + +
  • [#936] Ignore symbol leaks
  • ]]>
    +
    + + <![CDATA[@hapi/lab v20.0.0]]> + https://github.com/hapijs/lab/milestone/163 + + 2019-08-07T20:02:18.000Z + +
  • [#933] Update to eslint 6
  • [#932] Single line coverage ignore
  • ]]>
    +
    + + <![CDATA[@hapi/lab v19.1.0]]> + https://github.com/hapijs/lab/milestone/161 + + 2019-06-14T20:35:58.000Z + +
  • [#926] Implement coverage bypass stack
  • [#923] Support multiple "only" flags
  • [#922] Support for multiple "only"
  • [#904] Add affordance for coverage flag stack
  • ]]>
    +
    + + <![CDATA[@hapi/lab v19.0.1]]> + https://github.com/hapijs/lab/milestone/160 + + 2019-05-17T18:16:26.000Z + +
  • [#921] Handle ts "Cannot find name" error when expected
  • ]]>
    +
    + + <![CDATA[@hapi/lab v19.0.0]]> + https://github.com/hapijs/lab/milestone/159 + + 2019-05-16T07:43:32.000Z + +
  • [#920] 19.0.0 Release Notes
  • [#919] Change console reporter labels
  • [#918] Typescript test support
  • [#917] Remove debug-brk
  • [#916] Global leak detector skips Symbol() properties
  • [#915] Use util.inspect() for console reporter
  • [#914] "console" reporter crashes if object contains a BigInt
  • [#572] No mismatch highlighted on -0 !== 0 deep equality mismatch
  • ]]>
    +
    + + <![CDATA[@hapi/lab v18.1.2]]> + https://github.com/hapijs/lab/milestone/158 + + 2019-04-23T16:54:23.000Z + +
  • [#913] Update lint rules modules
  • [#912] Add globalThis to symbols
  • ]]>
    +
    + + <![CDATA[@hapi/lab v18.1.1]]> + https://github.com/hapijs/lab/milestone/157 + + 2019-04-23T16:45:14.000Z + +
  • [#911] Update code
  • ]]>
    +
    + + <![CDATA[@hapi/lab v18.1.0]]> + https://github.com/hapijs/lab/milestone/156 + + 2019-03-29T21:40:22.000Z + +
  • [#910] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/lab v18.0.2]]> + https://github.com/hapijs/lab/milestone/155 + + 2019-02-12T01:05:36.000Z + +
  • [#905] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/lab v18.0.1]]> + https://github.com/hapijs/lab/milestone/154 + + 2018-12-17T23:01:47.000Z + +
  • [#898] Switch back to Hoek.clone from lodash.deepClone.
  • [#895] Fix coverage with sourcemaps inlined via Transform API.
  • ]]>
    +
    + + <![CDATA[@hapi/lab v18.0.0]]> + https://github.com/hapijs/lab/milestone/152 + + 2018-11-13T22:46:35.000Z + +
  • [#894] Have correct exit code with multiple reporters
  • [#893] Properly propagate term sig to child lab process
  • [#892] Add note about how to get a tests ID
  • [#891] Update eslint version
  • [#890] Remove deprecated espree option
  • [#889] Remove docs about custom linter option
  • [#888] Compare coverage pattern to canonical path
  • [#885] Centralize espree options
  • [#884] Remove old parallel flag from test
  • [#883] Use correct gray color code
  • [#882] Add missing coverage and remove unnecessary checks
  • [#878] Fix false-positive coverage of if statements (REDUCES REPORTED COVERAGE!)
  • [#855] Update linter configuration?
  • [#852] Console reporter: "gray" is actually light green
  • [#842] Coverage fails for multiple conditionals on same line (logical operators)
  • [#788] Documentation on using --id
  • [#762] Request to consolidate parsers
  • [#758] CLI failure test doesn't appear to test what it claims
  • ]]>
    +
    + + <![CDATA[@hapi/lab v17.3.0]]> + https://github.com/hapijs/lab/milestone/153 + + 2018-11-05T15:17:31.000Z + +
  • [#881] Add coverage-pattern option
  • [#880] Remove engines
  • [#853] Coverage being analized on the test file
  • ]]>
    +
    + + <![CDATA[@hapi/lab v17.2.0]]> + https://github.com/hapijs/lab/milestone/151 + + 2018-11-02T21:30:05.000Z + +
  • [#879] Check file pattern on coverage traversal
  • [#877] Add --coverage-all option
  • [#710] setting coverage-path doesn't include all code in path
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/log.atom b/docs/public/atom/log.atom new file mode 100644 index 00000000..48fceb25 --- /dev/null +++ b/docs/public/atom/log.atom @@ -0,0 +1,42 @@ + + + https://hapi.dev/module/log + @hapi/log changelog + 2023-02-11T20:20:25.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/log v2.0.1]]> + https://github.com/hapijs/log/milestone/5 + + 2023-02-11T20:20:25.000Z + +
  • [#28] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/log v2.0.0]]> + https://github.com/hapijs/log/milestone/4 + + 2022-08-29T03:28:55.000Z + +
  • [#26] Support hapi v21, drop hapi v19, test ESM support
  • [#25] Drop node v12 support
  • ]]>
    +
    + + <![CDATA[@hapi/log v1.0.0-beta]]> + https://github.com/hapijs/log/milestone/1 + + 2021-05-24T00:23:44.000Z + +
  • [#20] Add pino logger and minor fixes
  • ]]>
    +
    + + <![CDATA[@hapi/log v1.0.0]]> + https://github.com/hapijs/log/milestone/2 + + 2021-07-19T02:54:59.000Z + +
  • [#21] Support changing log level after server start
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/mimos.atom b/docs/public/atom/mimos.atom new file mode 100644 index 00000000..0b0757fb --- /dev/null +++ b/docs/public/atom/mimos.atom @@ -0,0 +1,154 @@ + + + https://hapi.dev/module/mimos + @hapi/mimos changelog + 2023-02-11T20:23:57.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/mimos v7.0.1]]> + https://github.com/hapijs/mimos/milestone/21 + + 2023-02-11T20:23:57.000Z + +
  • [#42] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/mimos v7.0.0]]> + https://github.com/hapijs/mimos/milestone/20 + + 2022-05-23T03:59:56.000Z + +
  • [#41] Support node v18 and drop node v12
  • ]]>
    +
    + + <![CDATA[@hapi/mimos v6.0.0]]> + https://github.com/hapijs/mimos/milestone/19 + + 2022-05-09T03:24:11.000Z + +
  • [#37] Add Typescript typings + rework
  • ]]>
    +
    + + <![CDATA[@hapi/mimos v5.0.0]]> + https://github.com/hapijs/mimos/milestone/17 + + 2020-01-05T06:11:22.000Z + +
  • [#32] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/mimos v4.1.1]]> + https://github.com/hapijs/mimos/milestone/15 + + 2019-08-15T06:16:25.000Z + +
  • [#27] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/mimos v4.1.0]]> + https://github.com/hapijs/mimos/milestone/12 + + 2019-04-02T05:49:06.000Z + +
  • [#25] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/mimos v4.0.2]]> + https://github.com/hapijs/mimos/milestone/11 + + 2018-11-03T00:32:56.000Z + +
  • [#22] Remove engines
  • ]]>
    +
    + + <![CDATA[@hapi/mimos v4.0.1]]> + https://github.com/hapijs/mimos/milestone/10 + + 2018-11-01T18:36:01.000Z + +
  • [#21] Update deps.
  • ]]>
    +
    + + <![CDATA[@hapi/mimos v4.0.0]]> + https://github.com/hapijs/mimos/milestone/9 + + 2017-09-26T08:37:52.000Z + +
  • [#20] node 8
  • ]]>
    +
    + + <![CDATA[@hapi/mimos v3.1.0]]> + https://github.com/hapijs/mimos/milestone/13 + + 2019-04-02T05:36:51.000Z + +
  • [#24] Commercial version of v3 branch
  • ]]>
    +
    + + <![CDATA[@hapi/mimos v3.0.3]]> + https://github.com/hapijs/mimos/milestone/8 + + 2016-07-28T19:02:41.000Z + +
  • [#19] npmignore
  • ]]>
    +
    + + <![CDATA[@hapi/mimos v3.0.2]]> + https://github.com/hapijs/mimos/milestone/7 + + 2016-05-24T21:04:51.000Z + +
  • [#18] Code3
  • ]]>
    +
    + + <![CDATA[@hapi/mimos v3.0.1]]> + https://github.com/hapijs/mimos/milestone/6 + + 2016-05-09T18:30:05.000Z + +
  • [#17] Node-6 updates. Closes #16.
  • [#16] Node 6
  • ]]>
    +
    + + <![CDATA[@hapi/mimos v3.0.0]]> + https://github.com/hapijs/mimos/milestone/5 + + 2015-11-02T05:26:41.000Z + +
  • [#13] ES6 style changes and node v4
  • [#11] Update to Lab 5.x.x
  • [#10] Update .travis.yml
  • ]]>
    +
    + + <![CDATA[@hapi/mimos v2.0.2]]> + https://github.com/hapijs/mimos/milestone/4 + + 2014-11-18T19:33:43.000Z + +
  • [#8] Change source from hapi to mimos
  • ]]>
    +
    + + <![CDATA[@hapi/mimos v2.0.1]]> + https://github.com/hapijs/mimos/milestone/3 + + 2014-11-18T19:21:37.000Z + +
  • [#7] Improve performance for testing
  • ]]>
    +
    + + <![CDATA[@hapi/mimos v2.0.0]]> + https://github.com/hapijs/mimos/milestone/2 + + 2014-11-18T18:57:58.000Z + +
  • [#6] Added ability to override entries in the mime database.
  • ]]>
    +
    + + <![CDATA[@hapi/mimos v1.0.1]]> + https://github.com/hapijs/mimos/milestone/1 + + 2014-11-07T03:50:51.000Z + +
  • [#5] Transform extension to lower case before searching MIME type
  • [#4] Uppercase extension causes to return undefined MIME type
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/nes.atom b/docs/public/atom/nes.atom new file mode 100644 index 00000000..01e6dbc7 --- /dev/null +++ b/docs/public/atom/nes.atom @@ -0,0 +1,410 @@ + + + https://hapi.dev/module/nes + @hapi/nes changelog + 2025-01-08T21:42:26.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/nes v14.0.1]]> + https://github.com/hapijs/nes/milestone/86 + + 2025-01-08T21:42:26.000Z + +
  • [#338] Declare correct `ws` options type
  • ]]>
    +
    + + <![CDATA[@hapi/nes v14.0.0]]> + https://github.com/hapijs/nes/milestone/85 + + 2024-08-28T09:24:27.000Z + +
  • [#335] v14.0.0 Release Notes
  • [#334] Release next version as 14.0.0
  • [#333] chore: set min node version
  • [#330] chore: 🤖 import and improve outdate typings from DT
  • [#329] Upgrade to ws@8.x
  • [#327] chore: change CI target for next
  • ]]>
    +
    + + <![CDATA[@hapi/nes v13.0.1]]> + https://github.com/hapijs/nes/milestone/84 + + 2024-07-24T18:06:52.000Z + +
  • [#325] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/nes v13.0.0]]> + https://github.com/hapijs/nes/milestone/82 + + 2022-08-08T02:36:32.000Z + +
  • [#322] Support node v18 and hapi v21, drop node v12 and hapi v18/19
  • ]]>
    +
    + + <![CDATA[@hapi/nes v12.0.5]]> + https://github.com/hapijs/nes/milestone/83 + + 2022-08-08T02:36:34.000Z + +
  • [#323] Fix client reconnect retry attempts
  • [#318] client - _reconnect update, single reconnection timer
  • ]]>
    +
    + + <![CDATA[@hapi/nes v12.0.4]]> + https://github.com/hapijs/nes/milestone/81 + + 2020-09-26T16:25:03.000Z + +
  • [#313] migrate to new travis format
  • [#312] upgrade to hapi 20
  • [#311] switch to validate and other package updates
  • ]]>
    +
    + + <![CDATA[@hapi/nes v12.0.3]]> + https://github.com/hapijs/nes/milestone/80 + + 2020-07-10T03:31:35.000Z + +
  • [#307] Upgrade deprecated `@hapi/call@6.x.x`
  • [#306] fix: pass remoteAddress when injecting request
  • [#305] request.info.remoteAddress is always 127.0.0.1 in request handler
  • ]]>
    +
    + + <![CDATA[@hapi/nes v12.0.2]]> + https://github.com/hapijs/nes/milestone/79 + + 2020-03-17T03:17:04.000Z + +
  • [#304] Prevent beat timeout from disconnecting newly connecting sockets
  • ]]>
    +
    + + <![CDATA[@hapi/nes v12.0.1]]> + https://github.com/hapijs/nes/milestone/78 + + 2020-03-17T03:14:41.000Z + +
  • [#303] Remove unused dep
  • ]]>
    +
    + + <![CDATA[@hapi/nes v12.0.0]]> + https://github.com/hapijs/nes/milestone/77 + + 2020-01-13T12:13:27.000Z + +
  • [#301] Change plugin name to @hapi/nes
  • [#300] Require hapi 19
  • [#299] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/nes v11.2.2]]> + https://github.com/hapijs/nes/milestone/76 + + 2019-09-12T20:30:28.000Z + +
  • [#285] Unknown authentication strategy
  • ]]>
    +
    + + <![CDATA[@hapi/nes v11.2.1]]> + https://github.com/hapijs/nes/milestone/75 + + 2019-08-15T01:20:56.000Z + +
  • [#289] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/nes v11.2.0]]> + https://github.com/hapijs/nes/milestone/74 + + 2019-05-30T22:29:29.000Z + +
  • [#284] Add ability to revoke a socket ignoring if it is already closed
  • [#283] cleanup called twice if there is an onUnsubscribe handler
  • ]]>
    +
    + + <![CDATA[@hapi/nes v11.1.0]]> + https://github.com/hapijs/nes/milestone/73 + + 2019-04-25T16:40:58.000Z + +
  • [#278] Passing remoteAddress and x-forwarded-for is in whitelist when connect
  • ]]>
    +
    + + <![CDATA[@hapi/nes v11.0.1]]> + https://github.com/hapijs/nes/milestone/72 + + 2019-04-24T23:56:20.000Z + +
  • [#279] Fix name
  • ]]>
    +
    + + <![CDATA[@hapi/nes v11.0.0]]> + https://github.com/hapijs/nes/milestone/71 + + 2019-04-18T17:06:25.000Z + +
  • [#276] Remove client dist
  • [#248] eachSocket behaves as synchronous without filter, but async with filter
  • ]]>
    +
    + + <![CDATA[@hapi/nes v10.1.0]]> + https://github.com/hapijs/nes/milestone/70 + + 2019-04-18T04:32:31.000Z + +
  • [#275] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/nes v10.0.2]]> + https://github.com/hapijs/nes/milestone/69 + + 2019-03-05T17:10:57.000Z + +
  • [#270] Error in the browser with 10.0.1
  • ]]>
    +
    + + <![CDATA[@hapi/nes v10.0.1]]> + https://github.com/hapijs/nes/milestone/68 + + 2019-03-04T19:10:51.000Z + +
  • [#269] Update dependencies
  • ]]>
    +
    + + <![CDATA[@hapi/nes v10.0.0]]> + https://github.com/hapijs/nes/milestone/67 + + 2019-01-18T23:38:51.000Z + +
  • [#265] hapi v18
  • ]]>
    +
    + + <![CDATA[@hapi/nes v9.1.0]]> + https://github.com/hapijs/nes/milestone/66 + + 2018-11-24T03:54:05.000Z + +
  • [#263] Document minAuthVerifyInterval and make it less restrictive
  • [#262] Close the socket when authentication verification fails
  • [#260] Close the socket when authentication expires
  • ]]>
    +
    + + <![CDATA[@hapi/nes v9.0.2]]> + https://github.com/hapijs/nes/milestone/65 + + 2018-11-11T08:10:42.000Z + +
  • [#256] Cleanup
  • ]]>
    +
    + + <![CDATA[@hapi/nes v9.0.1]]> + https://github.com/hapijs/nes/milestone/64 + + 2018-11-11T08:06:30.000Z + +
  • [#247] Reconnect on error
  • ]]>
    +
    + + <![CDATA[@hapi/nes v8.1.0]]> + https://github.com/hapijs/nes/milestone/63 + + 2018-11-11T08:06:31.000Z + +
  • [#243] Add client.onHeartbeatTimeout hook
  • ]]>
    +
    + + <![CDATA[@hapi/nes v8.0.0]]> + https://github.com/hapijs/nes/milestone/62 + + 2018-11-11T08:06:32.000Z + +
  • [#229] Update ws to 5.x.x
  • ]]>
    +
    + + <![CDATA[@hapi/nes v7.2.0]]> + https://github.com/hapijs/nes/milestone/61 + + 2018-11-11T08:06:33.000Z + +
  • [#228] Mark NesErrors as coming from nes
  • ]]>
    +
    + + <![CDATA[@hapi/nes v7.1.0]]> + https://github.com/hapijs/nes/milestone/60 + + 2018-11-11T08:06:34.000Z + +
  • [#224] Add socket.info object
  • [#223] Delay heartbeats until server is started
  • [#222] Allow isSameSite cookie option to be passed
  • ]]>
    +
    + + <![CDATA[@hapi/nes v7.0.4]]> + https://github.com/hapijs/nes/milestone/59 + + 2018-03-11T09:37:21.000Z + +
  • [#221] Update hapijs/call to 5.x.x
  • [#220] Ignore node network errors after opening client socket
  • ]]>
    +
    + + <![CDATA[@hapi/nes v7.0.3]]> + https://github.com/hapijs/nes/milestone/58 + + 2018-03-07T02:32:25.000Z + +
  • [#214] Do not replace message for all sockets with override from filter
  • ]]>
    +
    + + <![CDATA[@hapi/nes v7.0.2]]> + https://github.com/hapijs/nes/milestone/55 + + 2017-12-18T21:57:19.000Z + +
  • [#206] Handle ws socket error events
  • ]]>
    +
    + + <![CDATA[@hapi/nes v7.0.1]]> + https://github.com/hapijs/nes/milestone/54 + + 2017-11-03T23:51:47.000Z + +
  • [#198] Better error handling
  • ]]>
    +
    + + <![CDATA[@hapi/nes v7.0.0]]> + https://github.com/hapijs/nes/milestone/53 + + 2017-10-31T09:39:57.000Z + +
  • [#196] hapi v17
  • [#195] Update ws
  • [#194] Update babel script
  • ]]>
    +
    + + <![CDATA[@hapi/nes v6.5.1]]> + https://github.com/hapijs/nes/milestone/57 + + 2017-11-13T20:51:44.000Z + +
  • [#202] Fix test
  • ]]>
    +
    + + <![CDATA[@hapi/nes v6.5.0]]> + https://github.com/hapijs/nes/milestone/56 + + 2017-11-13T20:49:18.000Z + +
  • [#201] Update ws
  • ]]>
    +
    + + <![CDATA[@hapi/nes v6.4.3]]> + https://github.com/hapijs/nes/milestone/52 + + 2017-07-18T19:40:26.000Z + +
  • [#179] `maximum call stack exceeded` if web socket gets disconnected while nes is sending packets
  • ]]>
    +
    + + <![CDATA[@hapi/nes v6.4.2]]> + https://github.com/hapijs/nes/milestone/51 + + 2017-03-20T19:55:03.000Z + +
  • [#156] Handle undefined payloads from server in client
  • ]]>
    +
    + + <![CDATA[@hapi/nes v6.4.1]]> + https://github.com/hapijs/nes/milestone/50 + + 2017-03-20T19:50:47.000Z + +
  • [#171] server falls with bad cookie header
  • ]]>
    +
    + + <![CDATA[@hapi/nes v6.4.0]]> + https://github.com/hapijs/nes/milestone/49 + + 2016-12-12T08:24:42.000Z + +
  • [#169] Expose server and connection on socket
  • ]]>
    +
    + + <![CDATA[@hapi/nes v6.3.2]]> + https://github.com/hapijs/nes/milestone/48 + + 2016-12-01T06:20:16.000Z + +
  • [#168] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/nes v6.3.1]]> + https://github.com/hapijs/nes/milestone/47 + + 2016-08-27T01:10:07.000Z + +
  • [#145] Disable inject() validate
  • ]]>
    +
    + + <![CDATA[@hapi/nes v6.3.0]]> + https://github.com/hapijs/nes/milestone/46 + + 2016-08-25T22:44:32.000Z + +
  • [#144] Verify request Origin
  • ]]>
    +
    + + <![CDATA[@hapi/nes v6.2.5]]> + https://github.com/hapijs/nes/milestone/45 + + 2016-08-02T18:36:56.000Z + +
  • [#142] Reconnection timeout conflicts
  • ]]>
    +
    + + <![CDATA[@hapi/nes v6.2.4]]> + https://github.com/hapijs/nes/milestone/44 + + 2016-07-29T17:47:00.000Z + +
  • [#141] Add client.js and dist/ to npm tarball -Closes #140
  • [#140] Missing root client.js and dist
  • ]]>
    +
    + + <![CDATA[@hapi/nes v6.2.3]]> + https://github.com/hapijs/nes/milestone/43 + + 2016-07-28T23:36:27.000Z + +
  • [#139] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/nes v6.2.2]]> + https://github.com/hapijs/nes/milestone/42 + + 2016-07-19T22:47:16.000Z + +
  • [#138] Always call onConnection before onSubscribe
  • ]]>
    +
    + + <![CDATA[@hapi/nes v6.2.1]]> + https://github.com/hapijs/nes/milestone/41 + + 2016-06-16T22:31:28.000Z + +
  • [#136] Reuse pre-stringified hapi response
  • ]]>
    +
    + + <![CDATA[@hapi/nes v6.2.0]]> + https://github.com/hapijs/nes/milestone/40 + + 2016-06-15T02:35:26.000Z + +
  • [#135] Cookie auth fails to register socket
  • [#134] Per user connection limit
  • [#133] Timeout sockets if hello takes too long
  • ]]>
    +
    + + <![CDATA[@hapi/nes v6.1.2]]> + https://github.com/hapijs/nes/milestone/39 + + 2016-05-28T01:01:18.000Z + +
  • [#132] Client indicates wasRequested when calling disconnect() on dead socket
  • ]]>
    +
    + + <![CDATA[@hapi/nes v6.1.1]]> + https://github.com/hapijs/nes/milestone/38 + + 2016-05-25T19:57:18.000Z + +
  • [#131] Incorrectly reports wasRequested when internally disconnects
  • ]]>
    +
    + + <![CDATA[@hapi/nes v6.1.0]]> + https://github.com/hapijs/nes/milestone/37 + + 2016-05-21T00:14:49.000Z + +
  • [#129] Include reason disconnected in log object
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/nigel.atom b/docs/public/atom/nigel.atom new file mode 100644 index 00000000..a0ec7eaa --- /dev/null +++ b/docs/public/atom/nigel.atom @@ -0,0 +1,146 @@ + + + https://hapi.dev/module/nigel + @hapi/nigel changelog + 2023-02-11T18:06:10.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/nigel v5.0.1]]> + https://github.com/hapijs/nigel/milestone/20 + + 2023-02-11T18:06:10.000Z + +
  • [#33] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/nigel v5.0.0]]> + https://github.com/hapijs/nigel/milestone/19 + + 2022-05-24T02:49:20.000Z + +
  • [#32] Support node v18 and drop node v12
  • ]]>
    +
    + + <![CDATA[@hapi/nigel v4.0.2]]> + https://github.com/hapijs/nigel/milestone/17 + + 2020-07-05T05:26:03.000Z + +
  • [#26] fix duplicate 'close' events
  • ]]>
    +
    + + <![CDATA[@hapi/nigel v4.0.1]]> + https://github.com/hapijs/nigel/milestone/16 + + 2020-06-29T06:16:25.000Z + +
  • [#25] close event emitted twice
  • ]]>
    +
    + + <![CDATA[@hapi/nigel v4.0.0]]> + https://github.com/hapijs/nigel/milestone/15 + + 2020-01-05T06:36:12.000Z + +
  • [#23] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/nigel v3.1.1]]> + https://github.com/hapijs/nigel/milestone/13 + + 2019-08-15T01:19:30.000Z + +
  • [#21] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/nigel v3.1.0]]> + https://github.com/hapijs/nigel/milestone/10 + + 2019-04-02T17:45:18.000Z + +
  • [#19] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/nigel v3.0.4]]> + https://github.com/hapijs/nigel/milestone/9 + + 2018-11-03T00:33:51.000Z + +
  • [#16] Remove engines
  • ]]>
    +
    + + <![CDATA[@hapi/nigel v3.0.3]]> + https://github.com/hapijs/nigel/milestone/8 + + 2018-11-01T18:37:34.000Z + +
  • [#15] Update hoek v6
  • ]]>
    +
    + + <![CDATA[@hapi/nigel v3.0.2]]> + https://github.com/hapijs/nigel/milestone/7 + + 2018-10-31T05:49:54.000Z + +
  • [#14] Cleanup
  • ]]>
    +
    + + <![CDATA[@hapi/nigel v3.0.1]]> + https://github.com/hapijs/nigel/milestone/6 + + 2018-03-31T00:18:14.000Z + +
  • [#13] Remove new Buffer usage
  • [#12] Remove `noAssert` argument from buffer functions
  • ]]>
    +
    + + <![CDATA[@hapi/nigel v3.0.0]]> + https://github.com/hapijs/nigel/milestone/5 + + 2017-09-26T08:56:40.000Z + +
  • [#11] Node 8
  • ]]>
    +
    + + <![CDATA[@hapi/nigel v2.1.0]]> + https://github.com/hapijs/nigel/milestone/11 + + 2019-03-25T18:40:22.000Z + +
  • [#18] Commercial version of v2 branch
  • ]]>
    +
    + + <![CDATA[@hapi/nigel v2.0.2]]> + https://github.com/hapijs/nigel/milestone/4 + + 2016-07-28T19:43:23.000Z + +
  • [#10] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/nigel v2.0.1]]> + https://github.com/hapijs/nigel/milestone/3 + + 2016-05-19T18:11:22.000Z + +
  • [#9] Update hoek & lab
  • ]]>
    +
    + + <![CDATA[@hapi/nigel v2.0.0]]> + https://github.com/hapijs/nigel/milestone/2 + + 2015-11-03T04:29:49.000Z + +
  • [#5] ES6 style changes and node v4
  • [#4] Adjust whitespace after semicolons to fix tests
  • [#3] Update to Lab 5.x.x and Code 1.x.x
  • [#2] Update .travis.yml
  • ]]>
    +
    + + <![CDATA[@hapi/nigel v1.0.1]]> + https://github.com/hapijs/nigel/milestone/1 + + 2014-10-02T18:18:49.000Z + +
  • [#1] Performance tweaks
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/oppsy.atom b/docs/public/atom/oppsy.atom new file mode 100644 index 00000000..0b9cc403 --- /dev/null +++ b/docs/public/atom/oppsy.atom @@ -0,0 +1,90 @@ + + + https://hapi.dev/module/oppsy + @hapi/oppsy changelog + 2020-01-12T04:57:36.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/oppsy v3.0.0]]> + https://github.com/hapijs/oppsy/milestone/10 + + 2020-01-12T04:57:36.000Z + +
  • [#27] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/oppsy v2.1.2]]> + https://github.com/hapijs/oppsy/milestone/9 + + 2019-08-15T01:17:58.000Z + +
  • [#23] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/oppsy v2.1.1]]> + https://github.com/hapijs/oppsy/milestone/8 + + 2019-04-25T16:17:47.000Z + +
  • [#21] Add missing namespace to hoek dependency
  • ]]>
    +
    + + <![CDATA[@hapi/oppsy v2.1.0]]> + https://github.com/hapijs/oppsy/milestone/7 + + 2019-04-22T00:18:44.000Z + +
  • [#20] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/oppsy v2.0.1]]> + https://github.com/hapijs/oppsy/milestone/6 + + 2019-04-22T00:17:12.000Z + +
  • [#19] Update Hoek and dev dependencies
  • ]]>
    +
    + + <![CDATA[@hapi/oppsy v2.0.0]]> + https://github.com/hapijs/oppsy/milestone/5 + + 2017-12-06T13:07:39.000Z + +
  • [#13] Add cpu process information. Closes #7
  • [#12] Migrate to node 8 and async/await
  • ]]>
    +
    + + <![CDATA[@hapi/oppsy v1.0.3]]> + https://github.com/hapijs/oppsy/milestone/4 + + 2017-12-05T17:48:51.000Z + +
  • [#6] Fix httpAgent reference assignment
  • ]]>
    +
    + + <![CDATA[@hapi/oppsy v1.0.2]]> + https://github.com/hapijs/oppsy/milestone/3 + + 2016-08-09T18:07:47.000Z + +
  • [#5] Test on node v6, update dependencies
  • ]]>
    +
    + + <![CDATA[@hapi/oppsy v1.0.1]]> + https://github.com/hapijs/oppsy/milestone/2 + + 2015-11-18T16:51:02.000Z + +
  • [#4] Fixes #2.
  • [#3] Bind networkMonitor to _tasks.
  • [#2] TypeError: Cannot read property 'connections' of undefined
  • ]]>
    +
    + + <![CDATA[@hapi/oppsy v1.0.0]]> + https://github.com/hapijs/oppsy/milestone/1 + + 2015-11-18T02:04:13.000Z + +
  • [#1] Implementation
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/pez.atom b/docs/public/atom/pez.atom new file mode 100644 index 00000000..9aff4161 --- /dev/null +++ b/docs/public/atom/pez.atom @@ -0,0 +1,258 @@ + + + https://hapi.dev/module/pez + @hapi/pez changelog + 2026-04-02T08:16:07.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/pez v6.1.1]]> + https://github.com/hapijs/pez/milestone/32 + + 2026-04-02T08:16:07.000Z + +
  • [#54] chore: bump dependencies
  • ]]>
    +
    + + <![CDATA[@hapi/pez v6.1.0]]> + https://github.com/hapijs/pez/milestone/31 + + 2026-04-02T08:11:20.000Z + +
  • [#50] Support maxParts to limit multipart payloads
  • ]]>
    +
    + + <![CDATA[@hapi/pez v6.0.1]]> + https://github.com/hapijs/pez/milestone/29 + + 2023-02-14T15:17:22.000Z + +
  • [#49] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/pez v6.0.0]]> + https://github.com/hapijs/pez/milestone/28 + + 2023-02-14T15:17:21.000Z + +
  • [#48] Support node v18 and drop node v12
  • ]]>
    +
    + + <![CDATA[@hapi/pez v5.1.0]]> + https://github.com/hapijs/pez/milestone/30 + + 2026-04-02T08:11:59.000Z + + ]]> + + + <![CDATA[@hapi/pez v5.0.3]]> + https://github.com/hapijs/pez/milestone/24 + + 2020-07-17T18:54:10.000Z + +
  • [#39] node 14. Closes #38
  • [#38] Support node 14
  • ]]>
    +
    + + <![CDATA[@hapi/pez v5.0.2]]> + https://github.com/hapijs/pez/milestone/23 + + 2020-02-13T17:46:26.000Z + +
  • [#35] Update dep
  • ]]>
    +
    + + <![CDATA[@hapi/pez v5.0.1]]> + https://github.com/hapijs/pez/milestone/22 + + 2020-02-13T07:57:00.000Z + +
  • [#34] Explicitly handle __proto__ header
  • ]]>
    +
    + + <![CDATA[@hapi/pez v5.0.0]]> + https://github.com/hapijs/pez/milestone/21 + + 2020-01-05T06:47:51.000Z + +
  • [#32] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/pez v4.1.3]]> + https://github.com/hapijs/pez/milestone/25 + + 2020-07-17T07:28:08.000Z + + ]]> + + + <![CDATA[@hapi/pez v4.1.2]]> + https://github.com/hapijs/pez/milestone/20 + + 2020-02-13T17:51:38.000Z + +
  • [#36] Backport #34
  • ]]>
    +
    + + <![CDATA[@hapi/pez v4.1.1]]> + https://github.com/hapijs/pez/milestone/19 + + 2019-08-15T01:16:24.000Z + +
  • [#30] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/pez v4.1.0]]> + https://github.com/hapijs/pez/milestone/16 + + 2019-04-02T18:02:23.000Z + +
  • [#28] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/pez v4.0.5]]> + https://github.com/hapijs/pez/milestone/15 + + 2018-11-03T00:34:40.000Z + +
  • [#24] Remove engines
  • ]]>
    +
    + + <![CDATA[@hapi/pez v4.0.4]]> + https://github.com/hapijs/pez/milestone/14 + + 2018-11-01T18:42:55.000Z + +
  • [#23] Update hoek v6
  • ]]>
    +
    + + <![CDATA[@hapi/pez v4.0.3]]> + https://github.com/hapijs/pez/milestone/13 + + 2018-10-31T04:21:53.000Z + +
  • [#21] Convert to class
  • ]]>
    +
    + + <![CDATA[@hapi/pez v4.0.2]]> + https://github.com/hapijs/pez/milestone/12 + + 2018-03-21T14:09:49.000Z + +
  • [#20] Remove new Buffer usage
  • ]]>
    +
    + + <![CDATA[@hapi/pez v4.0.1]]> + https://github.com/hapijs/pez/milestone/11 + + 2017-11-03T08:24:18.000Z + +
  • [#19] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/pez v4.0.0]]> + https://github.com/hapijs/pez/milestone/10 + + 2017-11-03T08:21:19.000Z + +
  • [#18] Return 413 on maxBytes error
  • ]]>
    +
    + + <![CDATA[@hapi/pez v3.0.1]]> + https://github.com/hapijs/pez/milestone/9 + + 2017-09-28T05:43:53.000Z + +
  • [#17] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/pez v2.2.2]]> + https://github.com/hapijs/pez/milestone/26 + + 2020-07-17T07:28:06.000Z + + ]]> + + + <![CDATA[@hapi/pez v2.2.1]]> + https://github.com/hapijs/pez/milestone/18 + + 2020-02-13T18:02:24.000Z + +
  • [#37] Backport #34
  • ]]>
    +
    + + <![CDATA[@hapi/pez v2.2.0]]> + https://github.com/hapijs/pez/milestone/17 + + 2019-03-25T18:46:10.000Z + +
  • [#27] Commercial version of v2 branch
  • ]]>
    +
    + + <![CDATA[@hapi/pez v2.1.5]]> + https://github.com/hapijs/pez/milestone/8 + + 2017-05-28T06:49:47.000Z + +
  • [#16] Update deps.
  • ]]>
    +
    + + <![CDATA[@hapi/pez v2.1.4]]> + https://github.com/hapijs/pez/milestone/7 + + 2016-11-29T01:02:52.000Z + + ]]> + + + <![CDATA[@hapi/pez v2.1.3]]> + https://github.com/hapijs/pez/milestone/6 + + 2016-10-05T13:57:51.000Z + +
  • [#14] update dependencies + lint updates
  • ]]>
    +
    + + <![CDATA[@hapi/pez v2.1.2]]> + https://github.com/hapijs/pez/milestone/5 + + 2016-06-07T14:03:19.000Z + +
  • [#12] Update dependencies for v2.1.2 release
  • [#11] Add .npmignore file
  • ]]>
    +
    + + <![CDATA[@hapi/pez v2.1.1]]> + https://github.com/hapijs/pez/milestone/4 + + 2016-05-18T13:26:10.000Z + +
  • [#10] Github / npm hoek version mismatch
  • ]]>
    +
    + + <![CDATA[@hapi/pez v2.1.0]]> + https://github.com/hapijs/pez/milestone/3 + + 2016-04-06T12:40:00.000Z + +
  • [#9] add maxBytes setting to detect oversized payloads
  • ]]>
    +
    + + <![CDATA[@hapi/pez v2.0.1]]> + https://github.com/hapijs/pez/milestone/2 + + 2015-11-03T05:42:09.000Z + +
  • [#8] ES6 deps
  • ]]>
    +
    + + <![CDATA[@hapi/pez v2.0.0]]> + https://github.com/hapijs/pez/milestone/1 + + 2015-10-31T03:43:58.000Z + +
  • [#6] Repo cleanup
  • [#5] Update to Lab 5.x.x and Code 1.x.x
  • [#4] Update .travis.yml
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/podium.atom b/docs/public/atom/podium.atom new file mode 100644 index 00000000..189f4310 --- /dev/null +++ b/docs/public/atom/podium.atom @@ -0,0 +1,290 @@ + + + https://hapi.dev/module/podium + @hapi/podium changelog + 2025-01-07T22:49:01.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/podium v5.0.2]]> + https://github.com/hapijs/podium/milestone/38 + + 2025-01-07T22:49:01.000Z + +
  • [#84] fix: typescript exactOptionalPropertyTypes issue
  • ]]>
    +
    + + <![CDATA[@hapi/podium v5.0.1]]> + https://github.com/hapijs/podium/milestone/37 + + 2025-01-07T22:48:24.000Z + +
  • [#82] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/podium v5.0.0]]> + https://github.com/hapijs/podium/milestone/36 + + 2022-05-08T19:54:56.000Z + +
  • [#80] Upgrade deps for node v14+
  • [#79] Support podium.gauge() method
  • [#76] Prepare a breaking build
  • [#75] Drop node 12 support
  • [#74] Prepare for ESM
  • [#73] Don't return promise from emit()
  • [#65] Remove "podium" event source
  • [#64] A thrown error in a handler can prevent other handlers from being called
  • ]]>
    +
    + + <![CDATA[@hapi/podium v4.1.3]]> + https://github.com/hapijs/podium/milestone/34 + + 2021-04-12T15:37:39.000Z + +
  • [#70] Fix typings to accomodate spread flag
  • ]]>
    +
    + + <![CDATA[@hapi/podium v4.1.2]]> + https://github.com/hapijs/podium/milestone/33 + + 2021-03-29T21:15:10.000Z + +
  • [#67] Clone the data array before using it as args
  • ]]>
    +
    + + <![CDATA[@hapi/podium v4.1.1]]> + https://github.com/hapijs/podium/milestone/32 + + 2021-03-29T21:15:19.000Z + +
  • [#62] upgrade lab to v24
  • ]]>
    +
    + + <![CDATA[@hapi/podium v4.1.0]]> + https://github.com/hapijs/podium/milestone/31 + + 2020-02-21T07:29:54.000Z + +
  • [#58] few()
  • ]]>
    +
    + + <![CDATA[@hapi/podium v4.0.0]]> + https://github.com/hapijs/podium/milestone/30 + + 2020-01-04T23:23:32.000Z + +
  • [#57] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/podium v3.4.3]]> + https://github.com/hapijs/podium/milestone/28 + + 2019-11-01T22:37:43.000Z + +
  • [#55] Optimize emit()
  • ]]>
    +
    + + <![CDATA[@hapi/podium v3.4.2]]> + https://github.com/hapijs/podium/milestone/27 + + 2019-09-12T22:43:26.000Z + +
  • [#49] Update joi
  • ]]>
    +
    + + <![CDATA[@hapi/podium v3.4.1]]> + https://github.com/hapijs/podium/milestone/26 + + 2019-08-15T01:15:03.000Z + +
  • [#48] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/podium v3.4.0]]> + https://github.com/hapijs/podium/milestone/25 + + 2019-04-02T05:03:10.000Z + +
  • [#43] Update joi dep
  • ]]>
    +
    + + <![CDATA[@hapi/podium v3.3.0]]> + https://github.com/hapijs/podium/milestone/22 + + 2019-04-01T19:59:59.000Z + +
  • [#42] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/podium v3.2.0]]> + https://github.com/hapijs/podium/milestone/21 + + 2018-11-11T05:00:05.000Z + + ]]> + + + <![CDATA[@hapi/podium v3.1.5]]> + https://github.com/hapijs/podium/milestone/20 + + 2018-11-03T00:35:37.000Z + +
  • [#39] Remove engines
  • ]]>
    +
    + + <![CDATA[@hapi/podium v3.1.4]]> + https://github.com/hapijs/podium/milestone/19 + + 2018-11-01T18:49:51.000Z + +
  • [#38] Update hoek v6
  • ]]>
    +
    + + <![CDATA[@hapi/podium v3.1.3]]> + https://github.com/hapijs/podium/milestone/18 + + 2018-10-31T22:53:27.000Z + +
  • [#37] Cleanup and node 11
  • ]]>
    +
    + + <![CDATA[@hapi/podium v3.1.2]]> + https://github.com/hapijs/podium/milestone/17 + + 2017-10-20T22:12:19.000Z + +
  • [#34] Only remove once handler if actually called
  • [#33] Do not modify criteria objects
  • ]]>
    +
    + + <![CDATA[@hapi/podium v3.1.1]]> + https://github.com/hapijs/podium/milestone/16 + + 2017-10-03T20:39:45.000Z + +
  • [#32] Remove emit() return values
  • ]]>
    +
    + + <![CDATA[@hapi/podium v3.1.0]]> + https://github.com/hapijs/podium/milestone/15 + + 2017-10-03T20:02:39.000Z + +
  • [#31] Return consistent results from the emit function
  • ]]>
    +
    + + <![CDATA[@hapi/podium v3.0.0]]> + https://github.com/hapijs/podium/milestone/14 + + 2017-09-28T19:13:12.000Z + +
  • [#30] Remove block option
  • [#29] emit() no longer waits for previous emits to complete
  • [#28] Remove error handler
  • ]]>
    +
    + + <![CDATA[@hapi/podium v2.1.0]]> + https://github.com/hapijs/podium/milestone/13 + + 2017-09-28T00:58:02.000Z + +
  • [#27] Expose events validation method
  • ]]>
    +
    + + <![CDATA[@hapi/podium v2.0.3]]> + https://github.com/hapijs/podium/milestone/12 + + 2017-09-26T19:15:44.000Z + +
  • [#26] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/podium v2.0.2]]> + https://github.com/hapijs/podium/milestone/11 + + 2017-09-17T22:15:26.000Z + +
  • [#25] Return consistent result on once()
  • ]]>
    +
    + + <![CDATA[@hapi/podium v2.0.1]]> + https://github.com/hapijs/podium/milestone/10 + + 2017-09-16T08:14:26.000Z + +
  • [#24] Cleanup emit()
  • ]]>
    +
    + + <![CDATA[@hapi/podium v2.0.0]]> + https://github.com/hapijs/podium/milestone/9 + + 2017-09-16T07:08:55.000Z + +
  • [#23] Convert emit() to async function
  • ]]>
    +
    + + <![CDATA[@hapi/podium v1.4.0]]> + https://github.com/hapijs/podium/milestone/23 + + 2019-03-25T07:02:20.000Z + +
  • [#41] Commercial version of v1 branch
  • ]]>
    +
    + + <![CDATA[@hapi/podium v1.3.0]]> + https://github.com/hapijs/podium/milestone/8 + + 2017-07-18T07:06:24.000Z + +
  • [#22] Method to create new emitters based on existing configuration
  • [#18] throwing inside an event breaks new events from emitting
  • ]]>
    +
    + + <![CDATA[@hapi/podium v1.2.5]]> + https://github.com/hapijs/podium/milestone/7 + + 2016-11-29T21:17:46.000Z + +
  • [#17] Defer using process.nextTick
  • ]]>
    +
    + + <![CDATA[@hapi/podium v1.2.4]]> + https://github.com/hapijs/podium/milestone/6 + + 2016-11-29T01:43:27.000Z + +
  • [#16] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/podium v1.2.3]]> + https://github.com/hapijs/podium/milestone/5 + + 2016-09-01T00:04:21.000Z + +
  • [#10] Generate data once across podiums
  • ]]>
    +
    + + <![CDATA[@hapi/podium v1.2.2]]> + https://github.com/hapijs/podium/milestone/4 + + 2016-08-31T19:50:50.000Z + +
  • [#9] emit() callback not called on next tick
  • ]]>
    +
    + + <![CDATA[@hapi/podium v1.2.1]]> + https://github.com/hapijs/podium/milestone/3 + + 2016-08-23T06:02:55.000Z + +
  • [#8] Function data not allowed with spread
  • ]]>
    +
    + + <![CDATA[@hapi/podium v1.2.0]]> + https://github.com/hapijs/podium/milestone/2 + + 2016-08-22T23:49:29.000Z + +
  • [#7] Support function data to generate data once
  • ]]>
    +
    + + <![CDATA[@hapi/podium v1.1.0]]> + https://github.com/hapijs/podium/milestone/1 + + 2016-08-21T07:48:30.000Z + +
  • [#5] Allow emit() to be overridden
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/scooter.atom b/docs/public/atom/scooter.atom new file mode 100644 index 00000000..8d039307 --- /dev/null +++ b/docs/public/atom/scooter.atom @@ -0,0 +1,90 @@ + + + https://hapi.dev/module/scooter + @hapi/scooter changelog + 2022-10-29T20:19:56.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/scooter v7.0.0]]> + https://github.com/hapijs/scooter/milestone/11 + + 2022-10-29T20:19:56.000Z + +
  • [#63] Support for hapi v21, node v18, ESM tests, multiple registration
  • ]]>
    +
    + + <![CDATA[@hapi/scooter v6.0.1]]> + https://github.com/hapijs/scooter/milestone/8 + + 2020-09-26T15:49:42.000Z + +
  • [#58] migrate to new travis format
  • [#57] update to hapi 20
  • [#56] upgrade semver and lab
  • ]]>
    +
    + + <![CDATA[@hapi/scooter v6.0.0]]> + https://github.com/hapijs/scooter/milestone/9 + + 2020-01-13T12:25:45.000Z + +
  • [#55] Only node 12
  • [#54] Require hapi 18
  • ]]>
    +
    + + <![CDATA[@hapi/scooter v5.1.1]]> + https://github.com/hapijs/scooter/milestone/7 + + 2019-09-15T05:28:07.000Z + +
  • [#49] Re-fix issue #44 which was reverted in changeset da33ea7
  • ]]>
    +
    + + <![CDATA[@hapi/scooter v4.1.0]]> + https://github.com/hapijs/scooter/milestone/6 + + 2019-04-21T22:30:47.000Z + +
  • [#48] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/scooter v4.0.1]]> + https://github.com/hapijs/scooter/milestone/5 + + 2018-11-11T06:54:34.000Z + +
  • [#39] Cleanup
  • ]]>
    +
    + + <![CDATA[@hapi/scooter v3.0.0]]> + https://github.com/hapijs/scooter/milestone/4 + + 2018-11-11T06:53:47.000Z + +
  • [#30] Update to follow node > 4 style standards
  • ]]>
    +
    + + <![CDATA[@hapi/scooter v2.0.0]]> + https://github.com/hapijs/scooter/milestone/3 + + 2016-05-24T03:08:10.000Z + +
  • [#22] hapi8. Closes #21
  • [#21] hapi 8.0 API
  • ]]>
    +
    + + <![CDATA[@hapi/scooter v1.2.1]]> + https://github.com/hapijs/scooter/milestone/2 + + 2014-08-18T21:39:19.000Z + +
  • [#16] lab 4.0
  • [#15] Rename spumko to hapijs
  • ]]>
    +
    + + <![CDATA[@hapi/scooter v1.0.1]]> + https://github.com/hapijs/scooter/milestone/1 + + 2014-03-20T08:59:55.000Z + +
  • [#2] hapi 3.0
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/shot.atom b/docs/public/atom/shot.atom new file mode 100644 index 00000000..1173dd1d --- /dev/null +++ b/docs/public/atom/shot.atom @@ -0,0 +1,410 @@ + + + https://hapi.dev/module/shot + @hapi/shot changelog + 2025-08-13T22:35:10.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/shot v6.0.2]]> + https://github.com/hapijs/shot/milestone/55 + + 2025-08-13T22:35:10.000Z + +
  • [#151] Improve argument validation and messaging
  • [#150] Support handlers calling res.destroy() to abort sending a response
  • ]]>
    +
    + + <![CDATA[@hapi/shot v6.0.1]]> + https://github.com/hapijs/shot/milestone/54 + + 2023-02-11T20:29:00.000Z + +
  • [#147] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/shot v6.0.0]]> + https://github.com/hapijs/shot/milestone/53 + + 2022-05-09T04:05:08.000Z + +
  • [#145] More realistic request socket interface
  • [#144] Drop node v12 support
  • [#140] Add initial typescript support
  • ]]>
    +
    + + <![CDATA[@hapi/shot v5.0.5]]> + https://github.com/hapijs/shot/milestone/51 + + 2021-01-23T07:04:19.000Z + +
  • [#139] When simulating close, ensure res emits close.
  • [#137] remove unused lib/schema.js
  • [#134] upgrade lab to v24
  • ]]>
    +
    + + <![CDATA[@hapi/shot v5.0.4]]> + https://github.com/hapijs/shot/milestone/50 + + 2020-09-26T19:26:01.000Z + +
  • [#133] Another attempt at #129
  • [#132] fix: do not auto destroy request stream
  • ]]>
    +
    + + <![CDATA[@hapi/shot v5.0.3]]> + https://github.com/hapijs/shot/milestone/49 + + 2020-08-25T22:53:38.000Z + +
  • [#130] Revert "Fix cleanup to be consistent across node releases"
  • ]]>
    +
    + + <![CDATA[@hapi/shot v5.0.2]]> + https://github.com/hapijs/shot/milestone/48 + + 2020-08-25T15:26:23.000Z + +
  • [#129] Fix cleanup to be consistent across node releases
  • ]]>
    +
    + + <![CDATA[@hapi/shot v5.0.1]]> + https://github.com/hapijs/shot/milestone/47 + + 2020-08-25T15:25:45.000Z + +
  • [#127] test on node 14
  • [#124] Replace joi with validate
  • ]]>
    +
    + + <![CDATA[@hapi/shot v5.0.0]]> + https://github.com/hapijs/shot/milestone/46 + + 2020-01-08T21:17:23.000Z + +
  • [#120] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/shot v4.1.2]]> + https://github.com/hapijs/shot/milestone/44 + + 2019-09-12T23:17:38.000Z + +
  • [#112] Update joi
  • ]]>
    +
    + + <![CDATA[@hapi/shot v4.1.1]]> + https://github.com/hapijs/shot/milestone/43 + + 2019-09-12T23:17:21.000Z + +
  • [#109] work around Node's DEP0066
  • ]]>
    +
    + + <![CDATA[@hapi/shot v4.1.0]]> + https://github.com/hapijs/shot/milestone/40 + + 2019-04-02T05:57:58.000Z + +
  • [#108] Node V12 deprecation warning [DEP0066] OutgoingMessage.prototype._headers is deprecated
  • [#106] Change module name
  • ]]>
    +
    + + <![CDATA[@hapi/shot v4.0.7]]> + https://github.com/hapijs/shot/milestone/39 + + 2018-11-03T00:36:49.000Z + +
  • [#101] Remove engines
  • ]]>
    +
    + + <![CDATA[@hapi/shot v4.0.6]]> + https://github.com/hapijs/shot/milestone/38 + + 2018-11-01T19:01:21.000Z + +
  • [#100] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/shot v4.0.5]]> + https://github.com/hapijs/shot/milestone/37 + + 2018-11-01T19:00:52.000Z + +
  • [#99] Updated lab to v17 to pass on Node v11
  • [#92] skip not covered lines on node master
  • ]]>
    +
    + + <![CDATA[@hapi/shot v4.0.4]]> + https://github.com/hapijs/shot/milestone/36 + + 2017-11-14T22:30:34.000Z + + ]]> + + + <![CDATA[@hapi/shot v4.0.3]]> + https://github.com/hapijs/shot/milestone/35 + + 2017-10-22T08:34:58.000Z + +
  • [#90] Update joi
  • ]]>
    +
    + + <![CDATA[@hapi/shot v4.0.2]]> + https://github.com/hapijs/shot/milestone/34 + + 2017-10-04T07:47:43.000Z + +
  • [#89] Replace instanceof with symbol
  • ]]>
    +
    + + <![CDATA[@hapi/shot v4.0.1]]> + https://github.com/hapijs/shot/milestone/33 + + 2017-09-28T06:15:19.000Z + +
  • [#88] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/shot v4.0.0]]> + https://github.com/hapijs/shot/milestone/32 + + 2017-09-28T06:15:21.000Z + + ]]> + + + <![CDATA[@hapi/shot v3.5.1]]> + https://github.com/hapijs/shot/milestone/42 + + 2020-06-29T20:53:35.000Z + +
  • [#122] Support node 12
  • ]]>
    +
    + + <![CDATA[@hapi/shot v3.5.0]]> + https://github.com/hapijs/shot/milestone/41 + + 2019-03-25T16:19:48.000Z + +
  • [#105] Commercial version of v3 branch
  • ]]>
    +
    + + <![CDATA[@hapi/shot v3.4.2]]> + https://github.com/hapijs/shot/milestone/31 + + 2017-09-23T10:00:11.000Z + +
  • [#85] Fix for node 8
  • ]]>
    +
    + + <![CDATA[@hapi/shot v3.4.1]]> + https://github.com/hapijs/shot/milestone/30 + + 2017-09-23T10:00:12.000Z + +
  • [#84] Fix node 8 issues
  • ]]>
    +
    + + <![CDATA[@hapi/shot v3.4.0]]> + https://github.com/hapijs/shot/milestone/29 + + 2016-11-29T01:41:05.000Z + +
  • [#83] Update deps
  • [#81] Handle streams of utf8 encoded strings
  • [#79] Remove custom output parsing and buffer payload chunks via write()
  • [#76] Updated API docs to reflect new validate flag
  • ]]>
    +
    + + <![CDATA[@hapi/shot v3.3.1]]> + https://github.com/hapijs/shot/milestone/28 + + 2016-08-26T21:46:09.000Z + + ]]> + + + <![CDATA[@hapi/shot v3.3.0]]> + https://github.com/hapijs/shot/milestone/27 + + 2016-08-26T21:37:05.000Z + +
  • [#75] Cleanup validation and make it optional
  • ]]>
    +
    + + <![CDATA[@hapi/shot v3.2.1]]> + https://github.com/hapijs/shot/milestone/26 + + 2016-08-26T08:42:55.000Z + +
  • [#73] Add status message to response object
  • [#71] add validation schema to shot
  • ]]>
    +
    + + <![CDATA[@hapi/shot v3.2.0]]> + https://github.com/hapijs/shot/milestone/25 + + 2016-08-23T05:19:50.000Z + +
  • [#74] Include statusMessage
  • ]]>
    +
    + + <![CDATA[@hapi/shot v3.1.1]]> + https://github.com/hapijs/shot/milestone/24 + + 2016-08-22T08:58:35.000Z + +
  • [#72] npmignore
  • ]]>
    +
    + + <![CDATA[@hapi/shot v3.1.0]]> + https://github.com/hapijs/shot/milestone/23 + + 2016-07-28T19:11:47.000Z + +
  • [#69] Update code to 3.x.x
  • [#68] Test on node 6, update lab and fix tests
  • [#67] Support stream payloads
  • [#65] Adds quotes around node versions in travis file
  • ]]>
    +
    + + <![CDATA[@hapi/shot v3.0.1]]> + https://github.com/hapijs/shot/milestone/22 + + 2016-02-09T17:13:27.000Z + +
  • [#63] Add default port to host header when no port specified. Fixes #62
  • [#61] Reduce function generation
  • [#60] Refactor index.js into separate files
  • ]]>
    +
    + + <![CDATA[@hapi/shot v3.0.0]]> + https://github.com/hapijs/shot/milestone/21 + + 2015-12-30T08:55:07.000Z + +
  • [#59] Update README with ES6 styles
  • [#58] Updated README for ES6 styles closes #59
  • [#57] Set trailers in res.trailers rather than res.headers. Fixes #56
  • [#56] Trailers should be added to res.trailers, not res.headers
  • ]]>
    +
    + + <![CDATA[@hapi/shot v2.0.1]]> + https://github.com/hapijs/shot/milestone/20 + + 2015-11-02T18:15:08.000Z + +
  • [#55] Fix broken tests
  • ]]>
    +
    + + <![CDATA[@hapi/shot v2.0.0]]> + https://github.com/hapijs/shot/milestone/19 + + 2015-11-02T18:10:02.000Z + +
  • [#52] Node >= 4 / es2015 updates
  • [#51] Upgrade lab to 7.x.x. Closes #50
  • ]]>
    +
    + + <![CDATA[@hapi/shot v1.7.0]]> + https://github.com/hapijs/shot/milestone/17 + + 2015-10-05T22:31:29.000Z + +
  • [#47] Add authority option. Closes #46
  • [#46] Add authority option for overriding default host header
  • ]]>
    +
    + + <![CDATA[@hapi/shot v1.6.1]]> + https://github.com/hapijs/shot/milestone/16 + + 2015-09-24T22:04:22.000Z + +
  • [#44] Always include a host header. Closes #43
  • [#43] host header is not always set
  • ]]>
    +
    + + <![CDATA[@hapi/shot v1.6.0]]> + https://github.com/hapijs/shot/milestone/15 + + 2015-08-04T07:33:25.000Z + +
  • [#36] Inject request with specified the remote client IP address
  • [#35] Client IP address
  • ]]>
    +
    + + <![CDATA[@hapi/shot v1.5.4]]> + https://github.com/hapijs/shot/milestone/14 + + 2015-08-04T07:33:46.000Z + + ]]> + + + <![CDATA[@hapi/shot v1.5.3]]> + https://github.com/hapijs/shot/milestone/13 + + 2015-06-05T11:39:29.000Z + +
  • [#33] Inconsistent assignment of rawPayload
  • ]]>
    +
    + + <![CDATA[@hapi/shot v1.5.2]]> + https://github.com/hapijs/shot/milestone/12 + + 2015-06-05T11:13:13.000Z + +
  • [#32] use rawPayload, convert to UTF8 after the whole buffer is available
  • ]]>
    +
    + + <![CDATA[@hapi/shot v1.5.1]]> + https://github.com/hapijs/shot/milestone/11 + + 2015-06-04T15:41:11.000Z + +
  • [#30] fix #7
  • [#7] deprecated encoding 'binary' is used
  • ]]>
    +
    + + <![CDATA[@hapi/shot v1.5.0]]> + https://github.com/hapijs/shot/milestone/10 + + 2015-04-14T20:32:04.000Z + +
  • [#28] Add 'content-length' header matching payload length if none set
  • ]]>
    +
    + + <![CDATA[@hapi/shot v1.4.2]]> + https://github.com/hapijs/shot/milestone/9 + + 2015-04-14T20:25:17.000Z + +
  • [#27] add -L to test and test-cov
  • ]]>
    +
    + + <![CDATA[@hapi/shot v1.4.1]]> + https://github.com/hapijs/shot/milestone/8 + + 2015-02-19T23:40:14.000Z + +
  • [#24] Added Hoek.applyToDefaults.
  • [#23] Use Hoek to assign defaults to options passed to inject. Fixes #22
  • [#22] Use hoek to assign defaults to options passed to inject
  • ]]>
    +
    + + <![CDATA[@hapi/shot v1.4.0]]> + https://github.com/hapijs/shot/milestone/7 + + 2015-02-19T23:40:13.000Z + +
  • [#19] optionally accept an object as the `url`
  • ]]>
    +
    + + <![CDATA[@hapi/shot v1.3.5]]> + https://github.com/hapijs/shot/milestone/6 + + 2014-09-05T21:22:55.000Z + +
  • [#14] lab 4.0
  • ]]>
    +
    + + <![CDATA[@hapi/shot v1.3.4]]> + https://github.com/hapijs/shot/milestone/4 + + 2014-08-02T07:42:34.000Z + +
  • [#12] Remove repeated assignment
  • ]]>
    +
    + + <![CDATA[@hapi/shot v1.3.3]]> + https://github.com/hapijs/shot/milestone/5 + + 2014-05-01T21:10:24.000Z + +
  • [#11] Bring coverage back to 100%
  • ]]>
    +
    + + <![CDATA[@hapi/shot v1.3.2]]> + https://github.com/hapijs/shot/milestone/3 + + 2014-03-08T19:47:41.000Z + +
  • [#10] Bring coverage back to 100% after lab fix
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/somever.atom b/docs/public/atom/somever.atom new file mode 100644 index 00000000..687a33e0 --- /dev/null +++ b/docs/public/atom/somever.atom @@ -0,0 +1,90 @@ + + + https://hapi.dev/module/somever + @hapi/somever changelog + 2023-02-11T20:26:26.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/somever v4.1.1]]> + https://github.com/hapijs/somever/milestone/12 + + 2023-02-11T20:26:26.000Z + +
  • [#23] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/somever v4.1.0]]> + https://github.com/hapijs/somever/milestone/11 + + 2023-02-11T20:26:24.000Z + +
  • [#22] Support includePrerelease option to permit prereleases when matching ranges
  • ]]>
    +
    + + <![CDATA[@hapi/somever v4.0.0]]> + https://github.com/hapijs/somever/milestone/9 + + 2022-07-11T04:05:02.000Z + +
  • [#21] Support node v18 and drop node v12
  • ]]>
    +
    + + <![CDATA[@hapi/somever v3.0.1]]> + https://github.com/hapijs/somever/milestone/7 + + 2021-05-05T18:32:18.000Z + +
  • [#17] fix: use pre-release number for comparison
  • [#15] upgrade lab to v24
  • ]]>
    +
    + + <![CDATA[@hapi/somever v3.0.0]]> + https://github.com/hapijs/somever/milestone/6 + + 2020-01-09T00:16:23.000Z + +
  • [#8] Expose Somever.compare()
  • [#7] Expose a public Somever.compare()
  • ]]>
    +
    + + <![CDATA[@hapi/somever v2.1.2]]> + https://github.com/hapijs/somever/milestone/5 + + 2020-07-17T07:49:35.000Z + + ]]> + + + <![CDATA[@hapi/somever v2.1.1]]> + https://github.com/hapijs/somever/milestone/4 + + 2019-08-15T01:03:51.000Z + +
  • [#5] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/somever v2.1.0]]> + https://github.com/hapijs/somever/milestone/3 + + 2019-04-02T06:06:06.000Z + +
  • [#3] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/somever v1.1.1]]> + https://github.com/hapijs/somever/milestone/2 + + 2020-07-17T07:49:37.000Z + + ]]> + + + <![CDATA[@hapi/somever v1.1.0]]> + https://github.com/hapijs/somever/milestone/1 + + 2019-03-25T16:35:59.000Z + +
  • [#2] Commercial version of v1 branch
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/sse.atom b/docs/public/atom/sse.atom new file mode 100644 index 00000000..6dd54c61 --- /dev/null +++ b/docs/public/atom/sse.atom @@ -0,0 +1,18 @@ + + + https://hapi.dev/module/sse + @hapi/sse changelog + 2026-04-07T22:13:58.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/sse v1.0.0]]> + https://github.com/hapijs/sse/milestone/1 + + 2026-04-07T22:13:58.000Z + +
  • [#3] Initial release
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/statehood.atom b/docs/public/atom/statehood.atom new file mode 100644 index 00000000..51caa361 --- /dev/null +++ b/docs/public/atom/statehood.atom @@ -0,0 +1,346 @@ + + + https://hapi.dev/module/statehood + @hapi/statehood changelog + 2025-11-06T09:39:52.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/statehood v8.2.1]]> + https://github.com/hapijs/statehood/milestone/45 + + 2025-11-06T09:39:52.000Z + +
  • [#89] chore: optimize regexps
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v8.2.0]]> + https://github.com/hapijs/statehood/milestone/44 + + 2025-02-28T23:50:15.000Z + +
  • [#88] Add support to cookie partition
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v8.1.1]]> + https://github.com/hapijs/statehood/milestone/43 + + 2023-04-24T21:49:37.000Z + +
  • [#86] fix: missing types on exclude
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v8.1.0]]> + https://github.com/hapijs/statehood/milestone/42 + + 2023-04-24T21:49:35.000Z + +
  • [#85] feat: add typescript types
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v8.0.1]]> + https://github.com/hapijs/statehood/milestone/41 + + 2023-02-11T19:06:55.000Z + +
  • [#84] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v8.0.0]]> + https://github.com/hapijs/statehood/milestone/40 + + 2022-05-23T04:21:52.000Z + +
  • [#82] Support node v18, drop node v12
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v7.0.4]]> + https://github.com/hapijs/statehood/milestone/38 + + 2022-04-20T02:52:24.000Z + +
  • [#81] Parse cookie pairs without a regex
  • [#77] upgrade lab to v24
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v7.0.3]]> + https://github.com/hapijs/statehood/milestone/37 + + 2020-09-26T19:29:40.000Z + + ]]> + + + <![CDATA[@hapi/statehood v7.0.2]]> + https://github.com/hapijs/statehood/milestone/36 + + 2020-02-13T08:43:03.000Z + +
  • [#71] Explicitly block __proto__ cookie name
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v7.0.1]]> + https://github.com/hapijs/statehood/milestone/35 + + 2020-01-09T00:23:17.000Z + +
  • [#69] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v7.0.0]]> + https://github.com/hapijs/statehood/milestone/33 + + 2019-12-28T05:08:28.000Z + +
  • [#67] Drop node 10
  • [#66] Drop node 8
  • [#65] Support custom properties via function
  • [#64] Support SameSite=None
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v6.1.2]]> + https://github.com/hapijs/statehood/milestone/32 + + 2019-09-12T22:31:29.000Z + +
  • [#62] Update joi
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v6.1.1]]> + https://github.com/hapijs/statehood/milestone/31 + + 2019-08-15T01:02:09.000Z + +
  • [#61] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v6.1.0]]> + https://github.com/hapijs/statehood/milestone/28 + + 2019-04-02T06:42:28.000Z + +
  • [#59] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v6.0.9]]> + https://github.com/hapijs/statehood/milestone/26 + + 2019-01-31T19:46:46.000Z + +
  • [#55] Protect against JSON.parse() prototype poisoning
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v6.0.8]]> + https://github.com/hapijs/statehood/milestone/25 + + 2018-11-03T00:38:01.000Z + +
  • [#47] Remove engines
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v6.0.7]]> + https://github.com/hapijs/statehood/milestone/23 + + 2018-11-01T19:21:36.000Z + +
  • [#46] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v6.0.6]]> + https://github.com/hapijs/statehood/milestone/22 + + 2018-03-31T00:10:43.000Z + +
  • [#41] Fix a typo
  • [#40] Remove new Buffer usage
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v6.0.5]]> + https://github.com/hapijs/statehood/milestone/24 + + 2018-03-31T00:12:06.000Z + +
  • [#38] Use Cryptiles.fixedTimeComparison()
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v6.0.4]]> + https://github.com/hapijs/statehood/milestone/21 + + 2017-11-03T20:25:01.000Z + +
  • [#37] Add bounce
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v6.0.3]]> + https://github.com/hapijs/statehood/milestone/20 + + 2017-11-03T08:42:25.000Z + +
  • [#36] Update dep
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v6.0.2]]> + https://github.com/hapijs/statehood/milestone/19 + + 2017-10-22T08:39:17.000Z + +
  • [#35] Update joi
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v6.0.1]]> + https://github.com/hapijs/statehood/milestone/18 + + 2017-09-28T06:18:50.000Z + +
  • [#34] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v6.0.0]]> + https://github.com/hapijs/statehood/milestone/17 + + 2017-09-25T05:54:06.000Z + +
  • [#33] Migrate to async interface
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v5.1.0]]> + https://github.com/hapijs/statehood/milestone/29 + + 2019-03-25T17:44:33.000Z + +
  • [#58] Commercial version of v5 branch
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v5.0.4]]> + https://github.com/hapijs/statehood/milestone/27 + + 2019-01-31T19:45:49.000Z + +
  • [#56] Protect against JSON.parse() prototype poisoning
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v5.0.3]]> + https://github.com/hapijs/statehood/milestone/16 + + 2017-07-20T08:32:47.000Z + +
  • [#32] Ignore partial header structure errors when ignoreErrors
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v5.0.2]]> + https://github.com/hapijs/statehood/milestone/15 + + 2017-05-27T22:27:43.000Z + +
  • [#31] Update deps.
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v5.0.1]]> + https://github.com/hapijs/statehood/milestone/14 + + 2016-11-29T00:19:07.000Z + +
  • [#29] Fix parse when iron is used with invalid and valid values
  • [#28] Cookies with the same name are ignored if only one is invalid
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v5.0.0]]> + https://github.com/hapijs/statehood/milestone/13 + + 2016-08-26T20:39:23.000Z + +
  • [#26] Change Secure, HttpOnly, and SameSite to true by default
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v4.1.0]]> + https://github.com/hapijs/statehood/milestone/12 + + 2016-08-26T08:22:20.000Z + +
  • [#23] Assert when input is not a string
  • [#21] Support SameSite attribute
  • [#17] Assert when input is not a string
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v4.0.3]]> + https://github.com/hapijs/statehood/milestone/11 + + 2016-07-28T20:14:07.000Z + +
  • [#25] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v4.0.2]]> + https://github.com/hapijs/statehood/milestone/10 + + 2016-07-28T19:20:14.000Z + +
  • [#24] npmignore
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v4.0.1]]> + https://github.com/hapijs/statehood/milestone/9 + + 2016-05-21T03:48:29.000Z + +
  • [#19] Test on node v6, update dependencies
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v4.0.0]]> + https://github.com/hapijs/statehood/milestone/8 + + 2016-02-01T08:08:03.000Z + +
  • [#16] Update hueniverse/iron from 3.x.x to 4.x.x
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v3.1.0]]> + https://github.com/hapijs/statehood/milestone/7 + + 2016-01-02T18:19:47.000Z + +
  • [#15] Allow empty names in loose mode
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v3.0.0]]> + https://github.com/hapijs/statehood/milestone/6 + + 2015-11-03T03:29:42.000Z + +
  • [#14] ES6 style changes and node v4
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v2.1.1]]> + https://github.com/hapijs/statehood/milestone/5 + + 2015-06-04T14:15:26.000Z + +
  • [#13] Update hapijs/joi to 6.4.3 from 4.9.0
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v2.1.0]]> + https://github.com/hapijs/statehood/milestone/4 + + 2015-06-04T14:09:36.000Z + +
  • [#12] Support isNullOverride in applyToDefaults
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v2.0.0]]> + https://github.com/hapijs/statehood/milestone/3 + + 2014-12-09T22:42:09.000Z + +
  • [#9] Move passThrough exclude logic from h2o2
  • [#8] Change parse and format to prototype
  • [#7] Replace globals with per cookie defaults
  • [#6] Ignored errors do not stop processing current cookie
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v1.2.0]]> + https://github.com/hapijs/statehood/milestone/2 + + 2014-09-08T03:00:10.000Z + +
  • [#3] exclude()
  • [#2] Remove support for comma separator
  • ]]>
    +
    + + <![CDATA[@hapi/statehood v1.1.0]]> + https://github.com/hapijs/statehood/milestone/1 + + 2014-09-07T22:33:45.000Z + +
  • [#1] Add list of cookie names
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/subtext.atom b/docs/public/atom/subtext.atom new file mode 100644 index 00000000..564059f7 --- /dev/null +++ b/docs/public/atom/subtext.atom @@ -0,0 +1,410 @@ + + + https://hapi.dev/module/subtext + @hapi/subtext changelog + 2026-04-02T08:19:32.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/subtext v8.1.2]]> + https://github.com/hapijs/subtext/milestone/58 + + 2026-04-02T08:19:32.000Z + +
  • [#105] chore: bump deps
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v8.1.1]]> + https://github.com/hapijs/subtext/milestone/57 + + 2025-08-06T10:02:02.000Z + +
  • [#104] Fix cleanup test on windows
  • [#102] Fix late write error on aborted streams
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v8.1.0]]> + https://github.com/hapijs/subtext/milestone/55 + + 2023-02-14T15:18:38.000Z + +
  • [#99] Support multipart payload maxParts, clean-up files on error
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v8.0.1]]> + https://github.com/hapijs/subtext/milestone/54 + + 2023-02-14T15:13:34.000Z + +
  • [#98] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v8.0.0]]> + https://github.com/hapijs/subtext/milestone/53 + + 2022-06-20T20:14:00.000Z + +
  • [#97] Support node v18 and drop node v12
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v7.1.0]]> + https://github.com/hapijs/subtext/milestone/56 + + 2023-02-14T15:18:39.000Z + + ]]> + + + <![CDATA[@hapi/subtext v7.0.4]]> + https://github.com/hapijs/subtext/milestone/52 + + 2022-06-20T20:13:59.000Z + +
  • [#96] Fix stream error propagation for node v16+
  • [#94] add dispatcher and use shared config
  • [#87] upgrade lab to v24
  • [#84] Test on node 14
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v7.0.3]]> + https://github.com/hapijs/subtext/milestone/49 + + 2020-02-13T19:12:44.000Z + +
  • [#83] Allow options.multipart to be true
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v7.0.2]]> + https://github.com/hapijs/subtext/milestone/48 + + 2020-02-13T18:20:46.000Z + +
  • [#80] Add tests for deps changes
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v7.0.1]]> + https://github.com/hapijs/subtext/milestone/47 + + 2020-01-16T10:13:43.000Z + +
  • [#79] Update hoek
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v7.0.0]]> + https://github.com/hapijs/subtext/milestone/46 + + 2020-01-09T00:26:33.000Z + +
  • [#78] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v6.1.3]]> + https://github.com/hapijs/subtext/milestone/44 + + 2020-02-13T18:20:43.000Z + +
  • [#82] Add tests
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v6.1.2]]> + https://github.com/hapijs/subtext/milestone/43 + + 2019-09-13T19:24:35.000Z + +
  • [#72] Fix maxBytes in file output
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v6.1.1]]> + https://github.com/hapijs/subtext/milestone/42 + + 2019-06-26T06:18:38.000Z + +
  • [#70] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v6.1.0]]> + https://github.com/hapijs/subtext/milestone/39 + + 2019-04-02T18:18:02.000Z + +
  • [#69] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v6.0.12]]> + https://github.com/hapijs/subtext/milestone/37 + + 2019-01-31T19:38:22.000Z + +
  • [#66] Protect against JSON.parse() prototype poisoning
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v6.0.11]]> + https://github.com/hapijs/subtext/milestone/36 + + 2018-11-03T00:38:56.000Z + +
  • [#63] Remove engines
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v6.0.10]]> + https://github.com/hapijs/subtext/milestone/35 + + 2018-11-02T17:51:11.000Z + +
  • [#62] Only include file headers on multipart
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v6.0.9]]> + https://github.com/hapijs/subtext/milestone/34 + + 2018-11-01T19:24:28.000Z + +
  • [#61] Update hoek v6
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v6.0.8]]> + https://github.com/hapijs/subtext/milestone/33 + + 2018-10-31T21:00:02.000Z + +
  • [#60] Handle PromiseRejectionHandledWarning
  • [#58] Cleanup
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v6.0.7]]> + https://github.com/hapijs/subtext/milestone/32 + + 2017-11-03T20:19:27.000Z + +
  • [#56] Cleaner throw
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v6.0.6]]> + https://github.com/hapijs/subtext/milestone/31 + + 2017-11-03T08:46:14.000Z + +
  • [#55] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v6.0.5]]> + https://github.com/hapijs/subtext/milestone/30 + + 2017-10-22T08:46:03.000Z + +
  • [#54] Update wreck
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v6.0.4]]> + https://github.com/hapijs/subtext/milestone/29 + + 2017-10-19T17:52:32.000Z + +
  • [#53] Update pez dependency
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v6.0.3]]> + https://github.com/hapijs/subtext/milestone/28 + + 2017-09-28T06:29:17.000Z + + ]]> + + + <![CDATA[@hapi/subtext v6.0.2]]> + https://github.com/hapijs/subtext/milestone/27 + + 2017-09-28T06:21:32.000Z + +
  • [#52] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v6.0.1]]> + https://github.com/hapijs/subtext/milestone/26 + + 2017-09-26T00:28:54.000Z + +
  • [#51] Update content
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v6.0.0]]> + https://github.com/hapijs/subtext/milestone/25 + + 2017-09-18T22:40:20.000Z + +
  • [#50] Async interface
  • [#49] Migrate to async interface
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v5.1.2]]> + https://github.com/hapijs/subtext/milestone/45 + + 2020-02-13T18:20:45.000Z + +
  • [#81] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v5.1.1]]> + https://github.com/hapijs/subtext/milestone/41 + + 2019-09-13T19:42:13.000Z + +
  • [#73] maxBytes file output
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v5.1.0]]> + https://github.com/hapijs/subtext/milestone/40 + + 2019-03-25T18:53:49.000Z + +
  • [#68] Commercial version of v5 branch
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v5.0.1]]> + https://github.com/hapijs/subtext/milestone/38 + + 2019-01-31T19:38:18.000Z + +
  • [#67] Protect against JSON.parse() prototype poisoning
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v5.0.0]]> + https://github.com/hapijs/subtext/milestone/24 + + 2017-07-02T18:35:21.000Z + +
  • [#48] Return 413 when payload too large.
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v4.4.1]]> + https://github.com/hapijs/subtext/milestone/22 + + 2017-05-28T06:55:07.000Z + +
  • [#47] Update deps.
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v4.4.0]]> + https://github.com/hapijs/subtext/milestone/21 + + 2017-03-21T06:49:19.000Z + +
  • [#45] Allow specifying custom query string parser
  • [#44] Retain raw payload when parsing fails
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v4.3.0]]> + https://github.com/hapijs/subtext/milestone/19 + + 2016-10-19T08:50:16.000Z + +
  • [#41] Support multipart override
  • [#40] Support multipart override output
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v4.2.2]]> + https://github.com/hapijs/subtext/milestone/20 + + 2016-10-19T06:30:37.000Z + +
  • [#37] Update dependencies
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v4.2.1]]> + https://github.com/hapijs/subtext/milestone/18 + + 2016-08-26T02:26:10.000Z + +
  • [#36] Pass options to built-in compressions
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v4.2.0]]> + https://github.com/hapijs/subtext/milestone/17 + + 2016-08-26T02:22:13.000Z + +
  • [#35] Support compression options
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v4.1.0]]> + https://github.com/hapijs/subtext/milestone/16 + + 2016-08-22T06:58:06.000Z + +
  • [#34] Support external decoders
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v4.0.5]]> + https://github.com/hapijs/subtext/milestone/15 + + 2016-07-28T19:25:13.000Z + +
  • [#33] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v4.0.4]]> + https://github.com/hapijs/subtext/milestone/14 + + 2016-07-28T19:23:28.000Z + +
  • [#29] update to code v3
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v4.0.3]]> + https://github.com/hapijs/subtext/milestone/13 + + 2016-05-11T15:05:46.000Z + +
  • [#28] update form-data dependency to 0.2.x
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v4.0.2]]> + https://github.com/hapijs/subtext/milestone/12 + + 2016-05-08T20:15:49.000Z + +
  • [#27] testing-node-6
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v4.0.1]]> + https://github.com/hapijs/subtext/milestone/11 + + 2016-04-06T15:12:01.000Z + +
  • [#26] Return error for multipart file exceeding maxBytes
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v4.0.0]]> + https://github.com/hapijs/subtext/milestone/10 + + 2015-12-22T21:14:23.000Z + +
  • [#25] Remove qs support. Closes #24
  • [#24] Remove qs dependency
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v3.0.1]]> + https://github.com/hapijs/subtext/milestone/9 + + 2015-11-14T14:01:42.000Z + +
  • [#23] Fix timeouts for multipart payloads
  • [#19] timeout for payload not working.
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v3.0.0]]> + https://github.com/hapijs/subtext/milestone/8 + + 2015-11-03T06:12:07.000Z + +
  • [#22] ES6 style changes and node v4
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v2.0.2]]> + https://github.com/hapijs/subtext/milestone/7 + + 2015-10-30T10:37:25.000Z + +
  • [#21] Missing dependency qs@4.x.x?
  • [#20] 2.0.2 tag
  • ]]>
    +
    + + <![CDATA[@hapi/subtext v2.0.1]]> + https://github.com/hapijs/subtext/milestone/6 + + 2015-10-30T10:35:00.000Z + +
  • [#18] upgrade to lab 6 and cleanup
  • [#17] testing different file sizes to get full code coverage
  • [#16] Test coverage timing issue
  • [#15] Move API docs to its own page
  • [#14] Move API docs to their own page
  • [#13] Update README with example and docs
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/teamwork.atom b/docs/public/atom/teamwork.atom new file mode 100644 index 00000000..bb7ff8e1 --- /dev/null +++ b/docs/public/atom/teamwork.atom @@ -0,0 +1,170 @@ + + + https://hapi.dev/module/teamwork + @hapi/teamwork changelog + 2025-08-21T15:05:34.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/teamwork v6.0.1]]> + https://github.com/hapijs/teamwork/milestone/21 + + 2025-08-21T15:05:34.000Z + +
  • [#39] Handle non-integer and empty meetings
  • [#38] Properly handle multiple iterators for Events
  • [#37] Fix regroup() to work after team error
  • [#36] Regroup should return the work output
  • ]]>
    +
    + + <![CDATA[@hapi/teamwork v6.0.0]]> + https://github.com/hapijs/teamwork/milestone/20 + + 2022-05-07T01:05:19.000Z + +
  • [#34] Support node v18 and drop node v12
  • ]]>
    +
    + + <![CDATA[@hapi/teamwork v5.1.1]]> + https://github.com/hapijs/teamwork/milestone/18 + + 2022-04-13T11:29:46.000Z + +
  • [#33] Fix memory leaks on attend for infinite teamwork instance
  • [#28] upgrade lab to v24 and devDependency of typescript
  • ]]>
    +
    + + <![CDATA[@hapi/teamwork v5.1.0]]> + https://github.com/hapijs/teamwork/milestone/17 + + 2020-05-07T04:40:03.000Z + +
  • [#26] Add strict mode
  • ]]>
    +
    + + <![CDATA[@hapi/teamwork v5.0.0]]> + https://github.com/hapijs/teamwork/milestone/16 + + 2020-03-23T01:10:32.000Z + +
  • [#25] Move Options to Team.Options
  • [#24] Add events iterator
  • ]]>
    +
    + + <![CDATA[@hapi/teamwork v4.0.0]]> + https://github.com/hapijs/teamwork/milestone/15 + + 2020-01-04T23:17:35.000Z + +
  • [#20] Change module to export Team instead of default class
  • [#19] Only node 12
  • [#18] Initialize all properties in constructor
  • ]]>
    +
    + + <![CDATA[@hapi/teamwork v3.3.2]]> + https://github.com/hapijs/teamwork/milestone/14 + + 2020-07-16T23:48:10.000Z + + ]]> + + + <![CDATA[@hapi/teamwork v3.3.1]]> + https://github.com/hapijs/teamwork/milestone/13 + + 2019-05-16T08:13:48.000Z + +
  • [#15] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/teamwork v3.3.0]]> + https://github.com/hapijs/teamwork/milestone/12 + + 2019-04-01T19:50:50.000Z + +
  • [#13] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/teamwork v3.2.0]]> + https://github.com/hapijs/teamwork/milestone/11 + + 2019-03-26T17:59:27.000Z + +
  • [#12] Add TypeScript definitions
  • ]]>
    +
    + + <![CDATA[@hapi/teamwork v3.1.0]]> + https://github.com/hapijs/teamwork/milestone/10 + + 2019-03-13T00:08:53.000Z + +
  • [#11] Support regroup()
  • ]]>
    +
    + + <![CDATA[@hapi/teamwork v3.0.3]]> + https://github.com/hapijs/teamwork/milestone/9 + + 2018-11-03T07:45:33.000Z + +
  • [#9] Relocate to hapi org
  • ]]>
    +
    + + <![CDATA[@hapi/teamwork v3.0.2]]> + https://github.com/hapijs/teamwork/milestone/8 + + 2018-11-03T00:48:39.000Z + +
  • [#8] Remove engines
  • ]]>
    +
    + + <![CDATA[@hapi/teamwork v3.0.1]]> + https://github.com/hapijs/teamwork/milestone/7 + + 2018-11-03T00:47:55.000Z + +
  • [#7] Remove Team
  • ]]>
    +
    + + <![CDATA[@hapi/teamwork v3.0.0]]> + https://github.com/hapijs/teamwork/milestone/6 + + 2017-10-26T06:23:44.000Z + +
  • [#6] Remove members and add notes support
  • ]]>
    +
    + + <![CDATA[@hapi/teamwork v2.1.0]]> + https://github.com/hapijs/teamwork/milestone/5 + + 2017-09-23T22:11:31.000Z + +
  • [#5] Add options
  • ]]>
    +
    + + <![CDATA[@hapi/teamwork v2.0.0]]> + https://github.com/hapijs/teamwork/milestone/4 + + 2017-09-23T22:07:08.000Z + +
  • [#4] Migrate to async/await interface
  • ]]>
    +
    + + <![CDATA[@hapi/teamwork v1.1.2]]> + https://github.com/hapijs/teamwork/milestone/3 + + 2016-12-01T06:01:25.000Z + +
  • [#3] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/teamwork v1.1.1]]> + https://github.com/hapijs/teamwork/milestone/2 + + 2016-07-28T23:10:26.000Z + +
  • [#2] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/teamwork v1.1.0]]> + https://github.com/hapijs/teamwork/milestone/1 + + 2015-11-04T08:14:34.000Z + +
  • [#1] Add meetings()
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/topo.atom b/docs/public/atom/topo.atom new file mode 100644 index 00000000..1e2be073 --- /dev/null +++ b/docs/public/atom/topo.atom @@ -0,0 +1,218 @@ + + + https://hapi.dev/module/topo + @hapi/topo changelog + 2023-02-11T18:39:18.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/topo v6.0.1]]> + https://github.com/hapijs/topo/milestone/32 + + 2023-02-11T18:39:18.000Z + +
  • [#70] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/topo v6.0.0]]> + https://github.com/hapijs/topo/milestone/31 + + 2023-02-11T18:38:17.000Z + +
  • [#69] Support node v18 and drop node v12
  • ]]>
    +
    + + <![CDATA[@hapi/topo v5.1.0]]> + https://github.com/hapijs/topo/milestone/29 + + 2021-06-28T21:54:35.000Z + +
  • [#66] Support manual sorting (performance)
  • [#64] upgrade lab to v24 and devDependency of typescript
  • ]]>
    +
    + + <![CDATA[@hapi/topo v5.0.0]]> + https://github.com/hapijs/topo/milestone/27 + + 2020-01-04T09:03:46.000Z + +
  • [#61] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/topo v4.0.1]]> + https://github.com/hapijs/topo/milestone/23 + + 2019-10-11T21:01:33.000Z + +
  • [#57] Adjust hoek to `^8.3.x`
  • ]]>
    +
    + + <![CDATA[@hapi/topo v4.0.0]]> + https://github.com/hapijs/topo/milestone/22 + + 2019-10-06T04:14:54.000Z + +
  • [#55] Move default export to Sorter
  • [#54] Drop node 8
  • ]]>
    +
    + + <![CDATA[@hapi/topo v3.1.6]]> + https://github.com/hapijs/topo/milestone/24 + + 2019-10-11T21:01:31.000Z + +
  • [#58] Update hoek dep
  • ]]>
    +
    + + <![CDATA[@hapi/topo v3.1.5]]> + https://github.com/hapijs/topo/milestone/21 + + 2019-10-06T04:13:19.000Z + +
  • [#56] Remove types
  • ]]>
    +
    + + <![CDATA[@hapi/topo v3.1.4]]> + https://github.com/hapijs/topo/milestone/20 + + 2019-09-19T22:17:36.000Z + +
  • [#46] Added TS declarations
  • ]]>
    +
    + + <![CDATA[@hapi/topo v3.1.3]]> + https://github.com/hapijs/topo/milestone/19 + + 2019-08-07T21:54:45.000Z + +
  • [#43] Direct hoek method require
  • ]]>
    +
    + + <![CDATA[@hapi/topo v3.1.2]]> + https://github.com/hapijs/topo/milestone/18 + + 2019-06-26T18:51:16.000Z + +
  • [#42] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/topo v3.1.1]]> + https://github.com/hapijs/topo/milestone/17 + + 2019-03-29T22:38:28.000Z + +
  • [#41] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/topo v3.1.0]]> + https://github.com/hapijs/topo/milestone/14 + + 2019-03-29T20:02:17.000Z + +
  • [#40] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/topo v3.0.3]]> + https://github.com/hapijs/topo/milestone/13 + + 2018-11-03T00:39:46.000Z + +
  • [#35] Remove engines
  • ]]>
    +
    + + <![CDATA[@hapi/topo v3.0.2]]> + https://github.com/hapijs/topo/milestone/12 + + 2018-11-01T19:26:29.000Z + +
  • [#33] Update hoek v6
  • ]]>
    +
    + + <![CDATA[@hapi/topo v3.0.1]]> + https://github.com/hapijs/topo/milestone/11 + + 2018-10-31T23:52:08.000Z + +
  • [#31] Cleanup
  • [#30] Update implementation to use classes. Update license and travis.
  • ]]>
    +
    + + <![CDATA[@hapi/topo v3.0.0]]> + https://github.com/hapijs/topo/milestone/10 + + 2017-09-26T09:01:28.000Z + +
  • [#28] Node 8
  • ]]>
    +
    + + <![CDATA[@hapi/topo v2.1.0]]> + https://github.com/hapijs/topo/milestone/15 + + 2019-03-22T06:44:53.000Z + +
  • [#39] Commercial version of v2 branch
  • ]]>
    +
    + + <![CDATA[@hapi/topo v2.0.3]]> + https://github.com/hapijs/topo/milestone/9 + + 2017-09-26T09:00:44.000Z + +
  • [#26] Cleanup sort routine, clarify usage of seq vs index
  • ]]>
    +
    + + <![CDATA[@hapi/topo v2.0.2]]> + https://github.com/hapijs/topo/milestone/8 + + 2016-07-17T18:46:24.000Z + +
  • [#25] Ensure groups can be named after props of Object.prototype
  • [#23] A problem with group names that are also property names of Object.prototype
  • [#22] Add .npmignore, update code to v3
  • ]]>
    +
    + + <![CDATA[@hapi/topo v2.0.1]]> + https://github.com/hapijs/topo/milestone/7 + + 2016-05-19T20:13:32.000Z + +
  • [#21] Test on node v6, update dependencies
  • ]]>
    +
    + + <![CDATA[@hapi/topo v2.0.0]]> + https://github.com/hapijs/topo/milestone/6 + + 2015-11-01T20:11:30.000Z + +
  • [#19] es6. Closes #18
  • [#18] ES6 style changes and node v4
  • ]]>
    +
    + + <![CDATA[@hapi/topo v1.1.0]]> + https://github.com/hapijs/topo/milestone/5 + + 2015-10-05T03:51:40.000Z + +
  • [#17] Lab v6 and travis node versions
  • [#16] Update to lab v6
  • [#15] merge() support. Closes #14
  • [#14] Add merge() support
  • ]]>
    +
    + + <![CDATA[@hapi/topo v1.0.3]]> + https://github.com/hapijs/topo/milestone/3 + + 2015-07-29T17:49:24.000Z + +
  • [#10] Linting and repo style updates.
  • [#9] `before` option as array misbehaves
  • [#7] Fix bug with usage of `before` as array.
  • [#6] Update to Lab 5.x.x and Code 1.x.x
  • ]]>
    +
    + + <![CDATA[@hapi/topo v1.0.2]]> + https://github.com/hapijs/topo/milestone/2 + + 2014-10-06T06:13:43.000Z + +
  • [#4] lab 4.0
  • ]]>
    +
    + + <![CDATA[@hapi/topo v1.0.1]]> + https://github.com/hapijs/topo/milestone/1 + + 2014-08-03T06:54:38.000Z + +
  • [#1] Don't die when user adds enumerable properties to Array.prototype
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/vise.atom b/docs/public/atom/vise.atom new file mode 100644 index 00000000..78698814 --- /dev/null +++ b/docs/public/atom/vise.atom @@ -0,0 +1,106 @@ + + + https://hapi.dev/module/vise + @hapi/vise changelog + 2023-02-11T17:58:10.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/vise v5.0.1]]> + https://github.com/hapijs/vise/milestone/15 + + 2023-02-11T17:58:10.000Z + +
  • [#30] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/vise v5.0.0]]> + https://github.com/hapijs/vise/milestone/14 + + 2022-05-23T03:59:44.000Z + +
  • [#29] Support node v18 and drop node v12
  • ]]>
    +
    + + <![CDATA[@hapi/vise v4.0.0]]> + https://github.com/hapijs/vise/milestone/12 + + 2020-01-05T06:33:19.000Z + +
  • [#20] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/vise v3.1.1]]> + https://github.com/hapijs/vise/milestone/10 + + 2019-08-15T00:57:28.000Z + +
  • [#18] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/vise v3.1.0]]> + https://github.com/hapijs/vise/milestone/7 + + 2019-04-02T17:43:33.000Z + +
  • [#16] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/vise v3.0.2]]> + https://github.com/hapijs/vise/milestone/6 + + 2018-11-03T00:40:42.000Z + +
  • [#13] Remove engines
  • ]]>
    +
    + + <![CDATA[@hapi/vise v3.0.1]]> + https://github.com/hapijs/vise/milestone/5 + + 2018-11-01T19:31:13.000Z + +
  • [#12] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/vise v3.0.0]]> + https://github.com/hapijs/vise/milestone/4 + + 2018-11-01T19:30:44.000Z + +
  • [#10] Node 8
  • ]]>
    +
    + + <![CDATA[@hapi/vise v2.1.0]]> + https://github.com/hapijs/vise/milestone/8 + + 2019-03-25T18:35:09.000Z + +
  • [#15] Commercial version of v2 branch
  • ]]>
    +
    + + <![CDATA[@hapi/vise v2.0.2]]> + https://github.com/hapijs/vise/milestone/3 + + 2016-07-28T19:46:31.000Z + +
  • [#9] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/vise v2.0.1]]> + https://github.com/hapijs/vise/milestone/2 + + 2016-05-05T17:02:07.000Z + +
  • [#7] Fix linting and update node/lab versions
  • ]]>
    +
    + + <![CDATA[@hapi/vise v2.0.0]]> + https://github.com/hapijs/vise/milestone/1 + + 2015-11-03T04:12:25.000Z + +
  • [#5] ES6 style changes and node v4
  • [#4] Update to Lab 5.x.x and Code 1.x.x
  • [#3] Update .travis.yml
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/vision.atom b/docs/public/atom/vision.atom new file mode 100644 index 00000000..b71a098a --- /dev/null +++ b/docs/public/atom/vision.atom @@ -0,0 +1,290 @@ + + + https://hapi.dev/module/vision + @hapi/vision changelog + 2023-08-04T13:48:45.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/vision v7.0.3]]> + https://github.com/hapijs/vision/milestone/39 + + 2023-08-04T13:48:45.000Z + +
  • [#217] fix: correct exported types
  • [#216] 7.0.2 typing inaccuracies
  • [#214] feat: 🎸 add types from DT
  • ]]>
    +
    + + <![CDATA[@hapi/vision v7.0.2]]> + https://github.com/hapijs/vision/milestone/38 + + 2023-06-09T15:34:48.000Z + +
  • [#215] chore: add typings from DT
  • ]]>
    +
    + + <![CDATA[@hapi/vision v7.0.1]]> + https://github.com/hapijs/vision/milestone/37 + + 2023-02-11T19:23:19.000Z + +
  • [#213] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/vision v7.0.0]]> + https://github.com/hapijs/vision/milestone/36 + + 2022-07-17T21:09:16.000Z + +
  • [#211] Support node v18 and hapi v21, drop node v12 and hapi v18/19
  • ]]>
    +
    + + <![CDATA[@hapi/vision v6.1.0]]> + https://github.com/hapijs/vision/milestone/34 + + 2021-05-25T08:09:16.000Z + +
  • [#205] Bring back old async support PR
  • [#202] upgrade lab to v24
  • [#201] update handlebars dependency
  • [#177] Async support
  • ]]>
    +
    + + <![CDATA[@hapi/vision v6.0.1]]> + https://github.com/hapijs/vision/milestone/33 + + 2020-09-10T15:47:49.000Z + + ]]> + + + <![CDATA[@hapi/vision v6.0.0]]> + https://github.com/hapijs/vision/milestone/32 + + 2020-01-10T07:29:42.000Z + +
  • [#192] Change plugin name to @hapi/vision
  • [#191] Drop hapi 17
  • [#190] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/vision v5.5.4]]> + https://github.com/hapijs/vision/milestone/30 + + 2019-09-12T23:40:47.000Z + +
  • [#186] Update joi
  • ]]>
    +
    + + <![CDATA[@hapi/vision v5.5.3]]> + https://github.com/hapijs/vision/milestone/29 + + 2019-08-15T00:50:30.000Z + +
  • [#185] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/vision v5.5.2]]> + https://github.com/hapijs/vision/milestone/28 + + 2019-04-10T22:17:29.000Z + +
  • [#182] Override package name
  • ]]>
    +
    + + <![CDATA[@hapi/vision v5.5.1]]> + https://github.com/hapijs/vision/milestone/27 + + 2019-04-09T06:48:46.000Z + +
  • [#181] Windows tests
  • ]]>
    +
    + + <![CDATA[@hapi/vision v5.5.0]]> + https://github.com/hapijs/vision/milestone/26 + + 2019-04-09T04:19:48.000Z + +
  • [#180] Change module namespace
  • [#165] Log errors instead of console.warn()
  • ]]>
    +
    + + <![CDATA[@hapi/vision v5.4.4]]> + https://github.com/hapijs/vision/milestone/25 + + 2018-12-15T18:00:05.000Z + + ]]> + + + <![CDATA[@hapi/vision v5.4.3]]> + https://github.com/hapijs/vision/milestone/24 + + 2018-11-07T07:39:19.000Z + +
  • [#169] Use new requirements config
  • ]]>
    +
    + + <![CDATA[@hapi/vision v5.4.2]]> + https://github.com/hapijs/vision/milestone/23 + + 2018-11-01T19:33:18.000Z + +
  • [#168] Update hoek v6
  • ]]>
    +
    + + <![CDATA[@hapi/vision v5.4.1]]> + https://github.com/hapijs/vision/milestone/22 + + 2018-11-01T05:56:08.000Z + +
  • [#167] Cleanup
  • ]]>
    +
    + + <![CDATA[@hapi/vision v5.3.4]]> + https://github.com/hapijs/vision/milestone/21 + + 2018-08-28T15:42:49.000Z + + ]]> + + + <![CDATA[@hapi/vision v5.3.3]]> + https://github.com/hapijs/vision/milestone/20 + + 2018-06-08T13:34:58.000Z + + ]]> + + + <![CDATA[@hapi/vision v5.3.1]]> + https://github.com/hapijs/vision/milestone/19 + + 2018-06-08T13:19:25.000Z + +
  • [#115] `request.render` does not pass the request to the context function
  • ]]>
    +
    + + <![CDATA[@hapi/vision v5.3.0]]> + https://github.com/hapijs/vision/milestone/18 + + 2017-12-29T01:34:34.000Z + +
  • [#135] Pass manager options at registration time
  • ]]>
    +
    + + <![CDATA[@hapi/vision v5.2.0]]> + https://github.com/hapijs/vision/milestone/17 + + 2017-12-24T19:31:23.000Z + +
  • [#133] Update API to hapi v17
  • [#132] Load partials and helpers before compile if isCached is false
  • [#130] Update docs, tests, and examples to hapi v17
  • [#110] Vision never reloads/recompiles partials
  • ]]>
    +
    + + <![CDATA[@hapi/vision v5.0.1]]> + https://github.com/hapijs/vision/milestone/16 + + 2017-11-06T18:06:30.000Z + + ]]> + + + <![CDATA[@hapi/vision v5.0.0]]> + https://github.com/hapijs/vision/milestone/15 + + 2017-11-03T19:48:37.000Z + +
  • [#128] Update deps
  • [#124] hapi v17
  • ]]>
    +
    + + <![CDATA[@hapi/vision v4.1.1]]> + https://github.com/hapijs/vision/milestone/14 + + 2016-11-29T01:36:33.000Z + +
  • [#105] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/vision v4.1.0]]> + https://github.com/hapijs/vision/milestone/13 + + 2016-11-29T01:14:27.000Z + +
  • [#82] Promises
  • [#81] Pass request to global context function when available
  • [#80] Register rendering helpers programmatically
  • [#79] Report errors when loading helpers
  • [#73] Send helper parsing error to user
  • [#68] Register Helpers programmatically
  • [#59] Global context with request argument
  • ]]>
    +
    + + <![CDATA[@hapi/vision v4.0.1]]> + https://github.com/hapijs/vision/milestone/12 + + 2015-11-09T16:30:25.000Z + +
  • [#67] Issue with underscore partials and vision
  • ]]>
    +
    + + <![CDATA[@hapi/vision v4.0.0]]> + https://github.com/hapijs/vision/milestone/11 + + 2015-11-09T16:26:02.000Z + +
  • [#66] ES6 style changes and node v4.
  • [#65] Update plugin attributes.
  • [#63] Add new attributes: connections: false, once: true
  • ]]>
    +
    + + <![CDATA[@hapi/vision v3.0.0]]> + https://github.com/hapijs/vision/milestone/9 + + 2015-08-16T02:26:19.000Z + +
  • [#40] request.render(). Closes #39
  • [#39] Add request.render() support
  • [#37] Engine initialization.
  • [#33] Make compilation errors available to extensions.
  • [#30] Style cleanup.
  • [#28] Fix lint errors.
  • [#10] Verify template and layout files exist in handler
  • ]]>
    +
    + + <![CDATA[@hapi/vision v2.0.1]]> + https://github.com/hapijs/vision/milestone/7 + + 2015-06-21T22:50:47.000Z + +
  • [#25] Update dependencies.
  • [#24] Ensure _loaderHelpers registers actual filenames
  • [#22] Helpful path location checked
  • ]]>
    +
    + + <![CDATA[@hapi/vision v2.0.0]]> + https://github.com/hapijs/vision/milestone/5 + + 2014-12-09T22:48:53.000Z + +
  • [#19] Jagoda feat multiple paths
  • [#18] Hapi8
  • [#15] Support multiple paths.
  • [#9] Multiple paths for views
  • [#8] Rename config basePath to relativeTo
  • [#5] Replace all of the backslashes in partial names to correctly name deeply nested partials.
  • ]]>
    +
    + + <![CDATA[@hapi/vision v1.2.2]]> + https://github.com/hapijs/vision/milestone/6 + + 2014-11-18T20:21:27.000Z + +
  • [#17] Fix crash when no global context is supplied, no handler context is supplied, and a layout template is being used
  • [#16] 404 gives error
  • ]]>
    +
    + + <![CDATA[@hapi/vision v1.2.1]]> + https://github.com/hapijs/vision/milestone/4 + + 2014-11-10T20:00:27.000Z + +
  • [#14] Global context performs deep merge which can produce unexpected results
  • [#13] Context is cloned every render() even when there is no global context
  • [#12] Schema allows setting global context per engine but not used
  • [#11] context should always be cloned shallowly
  • ]]>
    +
    + + <![CDATA[@hapi/vision v1.2.0]]> + https://github.com/hapijs/vision/milestone/3 + + 2014-11-04T08:04:56.000Z + +
  • [#7] Clean up code styling.
  • [#6] Support for global view context
  • [#4] Global View Context
  • ]]>
    +
    + + <![CDATA[@hapi/vision v1.1.0]]> + https://github.com/hapijs/vision/milestone/2 + + 2014-10-08T22:20:12.000Z + +
  • [#3] Allow appending default handler context
  • ]]>
    +
    + + <![CDATA[@hapi/vision v1.0.3]]> + https://github.com/hapijs/vision/milestone/1 + + 2014-10-08T22:01:56.000Z + +
  • [#2] Update Tests
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/wreck.atom b/docs/public/atom/wreck.atom new file mode 100644 index 00000000..da9319e8 --- /dev/null +++ b/docs/public/atom/wreck.atom @@ -0,0 +1,410 @@ + + + https://hapi.dev/module/wreck + @hapi/wreck changelog + 2024-04-10T17:38:08.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/wreck v18.1.0]]> + https://github.com/hapijs/wreck/milestone/78 + + 2024-04-10T17:38:08.000Z + +
  • [#309] support custom lookup function in request()
  • [#308] support custom lookup function in request()
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v18.0.2]]> + https://github.com/hapijs/wreck/milestone/77 + + 2024-04-10T17:30:20.000Z + +
  • [#310] Optimize header toLowerCasing
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v18.0.1]]> + https://github.com/hapijs/wreck/milestone/76 + + 2023-02-11T19:15:45.000Z + +
  • [#299] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v18.0.0]]> + https://github.com/hapijs/wreck/milestone/75 + + 2022-05-07T22:42:04.000Z + +
  • [#296] Support node v18 and drop node v12
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v17.2.0]]> + https://github.com/hapijs/wreck/milestone/73 + + 2022-05-07T01:40:01.000Z + +
  • [#295] [CI] Cancel redirect request
  • [#292] strip authorization and cookie headers when redirecting to a new hostname
  • [#287] Cancel redirect request
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v17.1.0]]> + https://github.com/hapijs/wreck/milestone/71 + + 2020-11-23T23:11:10.000Z + +
  • [#283] Create ci-module.yml
  • [#281] added IPv6 support
  • [#280] upgrade lab to v24 and devDependency of typescript
  • [#276] Unable to GET a server that listens to IPv6 address. ETIMEDOUT
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v17.0.0]]> + https://github.com/hapijs/wreck/milestone/70 + + 2020-01-04T21:06:07.000Z + +
  • [#270] Only node 12
  • [#267] Refactor early abort detection to use the 'abort' event
  • [#266] Don't set redirected host header
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v16.0.1]]> + https://github.com/hapijs/wreck/milestone/68 + + 2019-10-15T00:16:13.000Z + +
  • [#264] Allow any readable stream in read()
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v16.0.0]]> + https://github.com/hapijs/wreck/milestone/67 + + 2019-10-15T00:02:12.000Z + +
  • [#263] Add types
  • [#262] Drop node 8
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v15.1.0]]> + https://github.com/hapijs/wreck/milestone/64 + + 2019-09-18T19:00:00.000Z + +
  • [#254] 'abort' event
  • [#252] Respect uri parameter when using socketPath
  • [#250] memory leak issue
  • [#248] Change redirect method in `beforeRedirect`
  • [#247] Return an empty buffer payload on text content-type rather than `null`
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v15.0.2]]> + https://github.com/hapijs/wreck/milestone/63 + + 2019-08-15T00:45:46.000Z + +
  • [#256] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v15.0.1]]> + https://github.com/hapijs/wreck/milestone/62 + + 2019-04-16T07:02:25.000Z + +
  • [#246] Explicit host header trumps host implied in url
  • [#245] An explicit host header is ignored if the request url has no implicit host
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v15.0.0]]> + https://github.com/hapijs/wreck/milestone/59 + + 2019-04-01T15:35:32.000Z + +
  • [#244] 15.0.0 Release Notes
  • [#243] Change module namespace
  • [#242] Remove usage of deprecated url.Parse
  • [#235] Introduce new preRequest event and emit request on request event
  • [#209] Shouldn't request event emit request object?
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v14.2.0]]> + https://github.com/hapijs/wreck/milestone/58 + + 2019-03-05T22:32:13.000Z + +
  • [#240] Update eslint md dev dep
  • [#239] Whatwg url
  • [#238] Can Wreck parse urls with the WHATWG Url?
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v14.1.4]]> + https://github.com/hapijs/wreck/milestone/57 + + 2019-02-08T20:20:41.000Z + +
  • [#236] Protect against prototype poisoning
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v14.1.3]]> + https://github.com/hapijs/wreck/milestone/56 + + 2018-11-03T00:41:45.000Z + +
  • [#231] Remove engines
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v14.1.2]]> + https://github.com/hapijs/wreck/milestone/55 + + 2018-11-01T19:38:31.000Z + +
  • [#230] Update hoek v6
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v14.1.1]]> + https://github.com/hapijs/wreck/milestone/54 + + 2018-10-31T05:49:04.000Z + +
  • [#229] Cleanup
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v14.1.0]]> + https://github.com/hapijs/wreck/milestone/53 + + 2018-08-21T18:24:32.000Z + +
  • [#226] Handle edge cases introduced with deferred payload piping
  • [#225] Handle stream payload errors before socket connection
  • [#224] Workaround node 10 regression
  • [#223] Defer piping of options.payload until socket connection
  • [#222] Investigate only piping the payload after a connection is established
  • [#218] Remove new Buffer usage
  • [#215] test(request) correct tests to check errors for boom instance
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v14.0.2]]> + https://github.com/hapijs/wreck/milestone/52 + + 2017-11-03T18:41:17.000Z + +
  • [#208] Fix new Boom
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v14.0.1]]> + https://github.com/hapijs/wreck/milestone/51 + + 2017-11-03T18:40:55.000Z + +
  • [#207] Update deps
  • [#206] Upgrade to lab 15
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v14.0.0]]> + https://github.com/hapijs/wreck/milestone/50 + + 2017-10-21T16:25:23.000Z + +
  • [#205] Change maxBytes error to 413
  • [#204] Cleanup and lint readme
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v13.0.3]]> + https://github.com/hapijs/wreck/milestone/48 + + 2017-09-26T09:16:22.000Z + +
  • [#202] Update deps
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v13.0.2]]> + https://github.com/hapijs/wreck/milestone/47 + + 2017-09-25T14:52:30.000Z + +
  • [#199] Return errors for partial payload transfers
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v13.0.1]]> + https://github.com/hapijs/wreck/milestone/46 + + 2017-09-18T22:02:39.000Z + +
  • [#198] Retain boom errors from response stream on read()
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v13.0.0]]> + https://github.com/hapijs/wreck/milestone/45 + + 2017-09-18T00:17:55.000Z + +
  • [#197] Move to use async functions
  • [#196] Migrate to async/await
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v12.6.1]]> + https://github.com/hapijs/wreck/milestone/61 + + 2019-09-18T19:05:07.000Z + +
  • [#258] Backport #250
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v12.6.0]]> + https://github.com/hapijs/wreck/milestone/60 + + 2019-03-22T01:16:26.000Z + +
  • [#241] Commercial version of v12 branch
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v12.5.1]]> + https://github.com/hapijs/wreck/milestone/49 + + 2017-09-25T15:38:09.000Z + +
  • [#201] Return errors for partial payload transfers
  • [#200] version 12.5.1
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v12.5.0]]> + https://github.com/hapijs/wreck/milestone/44 + + 2017-09-07T16:27:31.000Z + +
  • [#195] closes #194 - support for a list of TLS ciphers
  • [#194] Add support for specifying the TLS ciphers list
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v12.4.0]]> + https://github.com/hapijs/wreck/milestone/43 + + 2017-09-01T15:01:21.000Z + +
  • [#193] Add onRequest to request options
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v12.3.0]]> + https://github.com/hapijs/wreck/milestone/42 + + 2017-09-01T02:56:08.000Z + +
  • [#192] Add a gunzipping option
  • [#190] Add "strict" json option
  • [#186] Add "strict" json option
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v12.2.3]]> + https://github.com/hapijs/wreck/milestone/41 + + 2017-08-10T17:14:15.000Z + +
  • [#189] Fix possible content-type header duplication
  • [#188] Possible `content-type` header duplication
  • [#184] Upgrade lab
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v12.2.2]]> + https://github.com/hapijs/wreck/milestone/40 + + 2017-05-28T09:05:06.000Z + +
  • [#183] Fix tests for node 7.10.0
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v12.2.1]]> + https://github.com/hapijs/wreck/milestone/39 + + 2017-05-28T07:02:09.000Z + +
  • [#182] Update deps.
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v12.2.0]]> + https://github.com/hapijs/wreck/milestone/38 + + 2017-05-08T14:47:54.000Z + +
  • [#177] fix(json): allow numbers in mime fixes #176
  • [#175] Include full response with the HTTP error
  • [#173] Return full response with the Boom HTTP error
  • [#170] 4XX is now an error
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v12.1.0]]> + https://github.com/hapijs/wreck/milestone/37 + + 2017-04-19T18:22:23.000Z + +
  • [#174] Tidy code around default agents
  • [#172] Update README.md
  • [#169] Pass an Error object to Boom.create for #168
  • [#156] Preserve `agents` across .defaults({...})
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v12.0.0]]> + https://github.com/hapijs/wreck/milestone/36 + + 2017-03-24T16:43:32.000Z + +
  • [#165] 12.0.0 Release Notes
  • [#164] Fix boom response error handling
  • [#163] Keep request on error status
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v11.0.0]]> + https://github.com/hapijs/wreck/milestone/35 + + 2017-03-21T23:44:53.000Z + +
  • [#162] 11.0.0 Release Notes
  • [#161] Fix redirection method for 301, 302
  • [#160] Update lab dep
  • [#159] Add example https agent setting
  • [#158] Wrap error response with Boom
  • [#157] Change response event signature
  • [#155] Update code dep
  • [#154] Clarify state of response in shortcuts
  • [#153] Question about responses as readable streams
  • [#138] Redirect 302 changes method from POST to GET
  • [#83] Change "response" Payload
  • [#82] Option to convert 4xx and 5xx to errors
  • [#66] Add certificate options for requests
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v10.0.0]]> + https://github.com/hapijs/wreck/milestone/34 + + 2016-09-08T17:33:49.000Z + +
  • [#150] 10.0.0 Release Notes
  • [#149] Update boom and lab deps
  • [#148] Refactor event propagation
  • [#147] Fix tests to timeout quicker
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v9.0.0]]> + https://github.com/hapijs/wreck/milestone/33 + + 2016-08-03T16:51:17.000Z + +
  • [#144] 9.0.0 Release Notes
  • [#143] Stringify payload objects
  • [#142] Fix redirect with different host on default options
  • [#131] Fail to redirect to different host
  • [#113] Suggestion: Allow json objects as payload
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v8.0.1]]> + https://github.com/hapijs/wreck/milestone/32 + + 2016-07-28T19:50:10.000Z + +
  • [#141] npmignore
  • [#137] add node version badge
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v8.0.0]]> + https://github.com/hapijs/wreck/milestone/31 + + 2016-06-02T15:24:05.000Z + +
  • [#136] Upgrade to code v3
  • [#135] 8.0.0 Release Notes
  • [#134] Expose response headers on redirect
  • [#133] Redirect 303 and expose headers
  • [#132] Support 303 Redirection
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v7.2.1]]> + https://github.com/hapijs/wreck/milestone/30 + + 2016-05-12T21:06:01.000Z + +
  • [#130] A missing callback on request still allows client requests to work
  • [#129] Use node 6 on travis
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v7.2.0]]> + https://github.com/hapijs/wreck/milestone/29 + + 2016-04-15T19:31:41.000Z + +
  • [#127] Add global request event
  • [#126] Add `request` emit
  • [#125] Use a global event emitter for wreck events
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v7.1.0]]> + https://github.com/hapijs/wreck/milestone/28 + + 2016-03-24T18:22:14.000Z + +
  • [#123] Add support for Unix sockets
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v7.0.2]]> + https://github.com/hapijs/wreck/milestone/27 + + 2016-03-05T20:01:09.000Z + +
  • [#121] Content-Length header check is now case insensitive
  • [#120] lowercase the content-length header
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v7.0.1]]> + https://github.com/hapijs/wreck/milestone/26 + + 2016-03-02T17:52:08.000Z + +
  • [#119] Update deps and fix tests
  • [#118] Add tests for defaults
  • [#117] Wreck#request's options are overridden by Defaults
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v7.0.0]]> + https://github.com/hapijs/wreck/milestone/25 + + 2015-10-31T19:41:15.000Z + +
  • [#109] ES6 style and node v4
  • ]]>
    +
    + + <![CDATA[@hapi/wreck v6.3.0]]> + https://github.com/hapijs/wreck/milestone/24 + + 2015-09-25T17:43:36.000Z + +
  • [#108] Add a beforeRedirect callback option
  • [#106] Fix code coverage
  • [#105] Workaround node issue in test
  • [#104] Fails on node v4
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/docs/public/atom/yar.atom b/docs/public/atom/yar.atom new file mode 100644 index 00000000..ce5344da --- /dev/null +++ b/docs/public/atom/yar.atom @@ -0,0 +1,194 @@ + + + https://hapi.dev/module/yar + @hapi/yar changelog + 2025-03-22T11:37:41.000Z + https://github.com/jpmonette/feed + + https://hapi.dev/img/logo.png + https://hapi.dev/favicon.png + + <![CDATA[@hapi/yar v11.0.3]]> + https://github.com/hapijs/yar/milestone/25 + + 2025-03-22T11:37:41.000Z + +
  • [#169] feat: 🎸 improve yar values and flash typings
  • ]]>
    +
    + + <![CDATA[@hapi/yar v11.0.2]]> + https://github.com/hapijs/yar/milestone/24 + + 2024-03-19T21:21:49.000Z + +
  • [#168] feat: 🎸 add types from DT
  • ]]>
    +
    + + <![CDATA[@hapi/yar v11.0.1]]> + https://github.com/hapijs/yar/milestone/23 + + 2023-02-11T20:19:24.000Z + +
  • [#164] chore: bump hoek
  • ]]>
    +
    + + <![CDATA[@hapi/yar v11.0.0]]> + https://github.com/hapijs/yar/milestone/22 + + 2022-08-29T03:34:50.000Z + +
  • [#162] Support hapi v21, drop hapi v19, test ESM support
  • [#161] Update deps, use null operator
  • [#159] Drop support for node v12
  • [#157] Use crypto.randomUUID as default session id
  • [#156] Use built-in crypto.randomUUID
  • ]]>
    +
    + + <![CDATA[@hapi/yar v10.1.1]]> + https://github.com/hapijs/yar/milestone/20 + + 2020-09-10T15:39:58.000Z + +
  • [#148] update to hapi v20
  • [#147] migrate to new travis format
  • [#146] upgrade lab and uuid dep
  • [#145] Update API.md
  • ]]>
    +
    + + <![CDATA[@hapi/yar v10.1.0]]> + https://github.com/hapijs/yar/milestone/19 + + 2020-03-19T06:44:43.000Z + +
  • [#144] Assign data in onPreResponse lifecycle extension with takeover
  • ]]>
    +
    + + <![CDATA[@hapi/yar v10.0.0]]> + https://github.com/hapijs/yar/milestone/18 + + 2020-01-13T12:37:58.000Z + +
  • [#141] Change plugin name to @hapi/yar
  • [#140] Require hapi 19
  • [#139] Only node 12
  • ]]>
    +
    + + <![CDATA[@hapi/yar v9.2.1]]> + https://github.com/hapijs/yar/milestone/17 + + 2019-08-15T00:33:03.000Z + +
  • [#134] Update dep
  • ]]>
    +
    + + <![CDATA[@hapi/yar v9.2.0]]> + https://github.com/hapijs/yar/milestone/16 + + 2019-04-20T04:02:28.000Z + +
  • [#131] Change module namespace
  • ]]>
    +
    + + <![CDATA[@hapi/yar v9.1.0]]> + https://github.com/hapijs/yar/milestone/15 + + 2018-11-03T21:58:12.000Z + +
  • [#127] chore: update dependencies
  • [#126] Add possibility to revoke specific session on the server side
  • [#125] Minor: Deprecated use of uuid
  • [#123] Delete a specific user's session
  • ]]>
    +
    + + <![CDATA[@hapi/yar v9.0.2]]> + https://github.com/hapijs/yar/milestone/14 + + 2018-09-24T00:21:36.000Z + +
  • [#124] Yar doesn't handle the session cookie multiple times correctly.
  • [#122] Do not cast all falsy values to null
  • [#121] Falsy values are converted to null
  • ]]>
    +
    + + <![CDATA[@hapi/yar v8.1.2]]> + https://github.com/hapijs/yar/milestone/13 + + 2016-12-19T08:24:37.000Z + +
  • [#110] Fix `main` in package.json
  • ]]>
    +
    + + <![CDATA[@hapi/yar v6.1.0]]> + https://github.com/hapijs/yar/milestone/12 + + 2016-12-19T08:24:41.000Z + +
  • [#90] add a route level config option to skip yar processing
  • ]]>
    +
    + + <![CDATA[@hapi/yar v6.0.0]]> + https://github.com/hapijs/yar/milestone/11 + + 2016-12-19T08:24:39.000Z + +
  • [#89] update yar to use request.yar instead of request.session
  • [#88] Decorate request with session key
  • ]]>
    +
    + + <![CDATA[@hapi/yar v4.3.0]]> + https://github.com/hapijs/yar/milestone/10 + + 2016-12-19T08:24:44.000Z + +
  • [#83] Option to skip exception on cache error
  • ]]>
    +
    + + <![CDATA[@hapi/yar v4.2.0]]> + https://github.com/hapijs/yar/milestone/9 + + 2016-12-19T08:24:45.000Z + +
  • [#75] Allow specification of whether to store blank sessions
  • ]]>
    +
    + + <![CDATA[@hapi/yar v4.0.0]]> + https://github.com/hapijs/yar/milestone/8 + + 2016-12-19T08:24:43.000Z + +
  • [#80] ignore invalid cookies so we don't get 400 errors on servers, which i…
  • [#65] "Invalid cookie value" after password change, but OK after refresh!
  • ]]>
    +
    + + <![CDATA[@hapi/yar v3.0.4]]> + https://github.com/hapijs/yar/milestone/6 + + 2016-12-19T08:24:47.000Z + +
  • [#79] Tests are failing
  • ]]>
    +
    + + <![CDATA[@hapi/yar v3.0.2]]> + https://github.com/hapijs/yar/milestone/5 + + 2016-12-19T08:29:46.000Z + + ]]> + + + <![CDATA[@hapi/yar v3.0.0]]> + https://github.com/hapijs/yar/milestone/4 + + 2014-12-10T22:39:44.000Z + +
  • [#61] Can't install yar from npm
  • [#57] hapi 8.0. Closes #56
  • [#56] hapi 8.0 API
  • ]]>
    +
    + + <![CDATA[@hapi/yar v2.4.0]]> + https://github.com/hapijs/yar/milestone/3 + + 2014-11-28T08:42:16.000Z + +
  • [#52] properly drop session during session.reset
  • [#46] Hapi6
  • [#45] Update examples, examples/package.json to use Hapi 6.x
  • [#44] Updated readme to match hapi 6.x API
  • [#43] Update tests / package.json to use Hapi 6.x
  • [#41] errorhandling after cookie password changes
  • ]]>
    +
    + + <![CDATA[@hapi/yar v2.1.0]]> + https://github.com/hapijs/yar/milestone/2 + + 2014-04-09T05:24:56.000Z + +
  • [#32] Upgrade to Hapi 4.x
  • ]]>
    +
    + + <![CDATA[@hapi/yar v2.0.0]]> + https://github.com/hapijs/yar/milestone/1 + + 2014-03-20T08:49:53.000Z + +
  • [#29] Replace ttl and store with cache options
  • [#28] Update to hapi 3.x
  • ]]>
    +
    +
    \ No newline at end of file diff --git a/static/favicon.png b/docs/public/favicon.png similarity index 100% rename from static/favicon.png rename to docs/public/favicon.png diff --git a/static/img/gettingStarted.jpg b/docs/public/img/books/gettingStarted.jpg similarity index 100% rename from static/img/gettingStarted.jpg rename to docs/public/img/books/gettingStarted.jpg diff --git a/static/img/hapi-edge.jpg b/docs/public/img/books/hapi-edge.jpg similarity index 100% rename from static/img/hapi-edge.jpg rename to docs/public/img/books/hapi-edge.jpg diff --git a/static/img/hapiHandbook.png b/docs/public/img/books/hapiHandbook.png similarity index 100% rename from static/img/hapiHandbook.png rename to docs/public/img/books/hapiHandbook.png diff --git a/static/img/hapiTypescript.png b/docs/public/img/books/hapiTypescript.png similarity index 100% rename from static/img/hapiTypescript.png rename to docs/public/img/books/hapiTypescript.png diff --git a/static/img/inAction.png b/docs/public/img/books/inAction.png similarity index 100% rename from static/img/inAction.png rename to docs/public/img/books/inAction.png diff --git a/static/img/practical-hapi-book.jpg b/docs/public/img/books/practical-hapi-book.jpg similarity index 100% rename from static/img/practical-hapi-book.jpg rename to docs/public/img/books/practical-hapi-book.jpg diff --git a/static/img/hapi.svg b/docs/public/img/hapi.svg similarity index 100% rename from static/img/hapi.svg rename to docs/public/img/hapi.svg diff --git a/static/img/icon_devs_greylines.svg b/docs/public/img/icons/icon_devs_greylines.svg similarity index 100% rename from static/img/icon_devs_greylines.svg rename to docs/public/img/icons/icon_devs_greylines.svg diff --git a/static/img/icon_helmets_extensibility.svg b/docs/public/img/icons/icon_helmets_extensibility.svg similarity index 100% rename from static/img/icon_helmets_extensibility.svg rename to docs/public/img/icons/icon_helmets_extensibility.svg diff --git a/static/img/icon_helmets_predictability.svg b/docs/public/img/icons/icon_helmets_predictability.svg similarity index 100% rename from static/img/icon_helmets_predictability.svg rename to docs/public/img/icons/icon_helmets_predictability.svg diff --git a/static/img/icon_helmets_quality.svg b/docs/public/img/icons/icon_helmets_quality.svg similarity index 100% rename from static/img/icon_helmets_quality.svg rename to docs/public/img/icons/icon_helmets_quality.svg diff --git a/static/img/icon_helmets_security.svg b/docs/public/img/icons/icon_helmets_security.svg similarity index 100% rename from static/img/icon_helmets_security.svg rename to docs/public/img/icons/icon_helmets_security.svg diff --git a/static/img/icon_helmets_support.svg b/docs/public/img/icons/icon_helmets_support.svg similarity index 100% rename from static/img/icon_helmets_support.svg rename to docs/public/img/icons/icon_helmets_support.svg diff --git a/docs/public/img/quotes/auth0-dark.svg b/docs/public/img/quotes/auth0-dark.svg new file mode 100644 index 00000000..12631af4 --- /dev/null +++ b/docs/public/img/quotes/auth0-dark.svg @@ -0,0 +1,55 @@ + + + + + + + + diff --git a/docs/public/img/quotes/auth0.svg b/docs/public/img/quotes/auth0.svg new file mode 100644 index 00000000..fbc55f72 --- /dev/null +++ b/docs/public/img/quotes/auth0.svg @@ -0,0 +1,55 @@ + + + + + + + + diff --git a/static/img/beats-logo.svg b/docs/public/img/quotes/beats-dark.svg similarity index 100% rename from static/img/beats-logo.svg rename to docs/public/img/quotes/beats-dark.svg diff --git a/docs/public/img/quotes/beats.svg b/docs/public/img/quotes/beats.svg new file mode 100644 index 00000000..0e2a689c --- /dev/null +++ b/docs/public/img/quotes/beats.svg @@ -0,0 +1,62 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/docs/public/img/quotes/brave-dark.svg b/docs/public/img/quotes/brave-dark.svg new file mode 100644 index 00000000..27cdd974 --- /dev/null +++ b/docs/public/img/quotes/brave-dark.svg @@ -0,0 +1 @@ +brave_logo_2color_reversed \ No newline at end of file diff --git a/static/img/brave-logo.svg b/docs/public/img/quotes/brave.svg similarity index 100% rename from static/img/brave-logo.svg rename to docs/public/img/quotes/brave.svg diff --git a/docs/public/img/quotes/conde-nast-dark.svg b/docs/public/img/quotes/conde-nast-dark.svg new file mode 100644 index 00000000..27411da5 --- /dev/null +++ b/docs/public/img/quotes/conde-nast-dark.svg @@ -0,0 +1,18 @@ + + + + logo-cn-us + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/public/img/quotes/conde-nast.svg b/docs/public/img/quotes/conde-nast.svg new file mode 100644 index 00000000..8d058be4 --- /dev/null +++ b/docs/public/img/quotes/conde-nast.svg @@ -0,0 +1,18 @@ + + + + logo-cn-us + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/public/img/quotes/vrbo-dark.svg b/docs/public/img/quotes/vrbo-dark.svg new file mode 100644 index 00000000..84317448 --- /dev/null +++ b/docs/public/img/quotes/vrbo-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/img/quotes/vrbo.svg b/docs/public/img/quotes/vrbo.svg new file mode 100644 index 00000000..84317448 --- /dev/null +++ b/docs/public/img/quotes/vrbo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/fork.png b/docs/public/img/ui/fork.png similarity index 100% rename from static/img/fork.png rename to docs/public/img/ui/fork.png diff --git a/static/img/githubLogo.png b/docs/public/img/ui/githubLogo.png similarity index 100% rename from static/img/githubLogo.png rename to docs/public/img/ui/githubLogo.png diff --git a/static/img/helmet.png b/docs/public/img/ui/helmet.png similarity index 100% rename from static/img/helmet.png rename to docs/public/img/ui/helmet.png diff --git a/static/img/release-notes.png b/docs/public/img/ui/release-notes.png similarity index 100% rename from static/img/release-notes.png rename to docs/public/img/ui/release-notes.png diff --git a/static/img/star.png b/docs/public/img/ui/star.png similarity index 100% rename from static/img/star.png rename to docs/public/img/ui/star.png diff --git a/docs/resources/changelog.md b/docs/resources/changelog.md new file mode 100644 index 00000000..2e6da2e1 --- /dev/null +++ b/docs/resources/changelog.md @@ -0,0 +1,13 @@ +--- +title: Changelog +--- + + + +# Changelog + +::: v-pre + + + +::: diff --git a/docs/resources/index.md b/docs/resources/index.md new file mode 100644 index 00000000..56237f36 --- /dev/null +++ b/docs/resources/index.md @@ -0,0 +1,12 @@ +--- +layout: false +head: + - - meta + - http-equiv: refresh + content: 0; url=/resources/changelog + - - script + - {} + - "window.location.replace('/resources/changelog');" +--- + +Redirecting to Changelog... diff --git a/docs/resources/list.md b/docs/resources/list.md new file mode 100644 index 00000000..57ed23bf --- /dev/null +++ b/docs/resources/list.md @@ -0,0 +1,71 @@ +--- +title: Resources +--- + +## Books {#books} + +- [Practical Hapi](https://www.amazon.com/Practical-hapi-Build-Industry-Studies/dp/1484258045) + + This book walks you through an end to end implementation of hapi, nodejs and asynchronous programming, right through Node JS Event Loop, Rest API best practices, Hapi Server Setup, Routing, Post and Get Requests with Payload and Parameters, Database Connectivity, Sequelize, Validation, Plugin Architecture, npm repository and its optimum use, swaggerui Integration, Postman tricks, Tricks and Tips for Neater Code, Constructs like await, fetch etc., Nodemon and much much more!!!! A capstone project with industry level challenges is what takes the cake in explaining Hapi in context. The framework is a great choice since it was tried and tested for high production demands and is backed by the best. With further releases coming, this framework is here to stay and is certainly an addition to your skills. + +- [Developing a hapi Edge](http://www.amazon.com/Developing-hapi-Edge-Framework-Services-ebook/dp/B013CWI3MY) + + This book shows you how to build enterprise-quality web applications using the hapi service and application framework. By walking through the creation of a real web application, hapi-plugins.com, you will learn how to configure and start hapi, build out APIs, perform authentication, validation, caching, and so much more. You will also discover tips and tricks used in production hapi deployments regarding plugins, testing, debugging, and security. hapi was developed and is used within Walmart and has been battle tested during the most critical days of the year for e-commerce websites, Black Friday. It has proven itself to not only handle extremely high production loads at a breeze but is also a pleasure to work with. The aim of the framework was to address pitfalls in the other established out there, and it has done so without fail. + +- [Getting Started with hapi.js](https://www.packtpub.com/web-development/getting-started-hapijs) + + This book introduces hapi.js and walks through the creation of your first working application using the out-of-the-box features hapi.js provides. Packed with real-world problems and examples, this book covers some of the basic concepts of hapi.js and Node.js and takes you through the typical journey you'll face when developing an application. Starting with easier concepts such as routing requests, building APIs serving JSON, using templates to build websites and applications, and connecting databases, we then move on to more complex problems such as authentication, model validation, caching, and techniques for structuring your codebase to scale gracefully. You will also develop skills to ensure your application's reliability through testing, code coverage, and logging. By the end of this book, you'll be equipped with all the skills you need to build your first fully featured application. This book will be invaluable if you are investigating Node.js frameworks or planning on using hapi.js in your next project. + +- [hapi.js in Action](http://manning.com/harrison) + + Packed with examples, this book takes you from your first simple server through the skills you'll need to build a complete application. In it, you'll learn how to build websites and APIs, implement caching, authentication, validation, error handling, and a lot more. You'll also explore vital techniques for production applications, such as testing, monitoring, deployment, and documentation. + +- [hapi with TypeScript](http://hapibook.jjude.com) + + This book introduces TypeScript into developing web applications with hapi. TypeScript, a language developed by Microsoft, brings the benefits of strong types and object-oriented programming to JavaScript. With ample code samples, this book teaches all aspects of developing a web application in hapi with TypeScript. It also introduces, hapidock, a docker container with all required components for developing in hapi. With hapidock, you can develop and test hapi applications in a production-like environment. Through this book, you will learn to build stable enterprise-level server applications. The book is free to read at http://hapibook.jjude.com. E-books (pdf, mobi, and epub) and fully executable code samples are available after purchase. + +- [Hapi.js Handbook](https://leanpub.com/hapi-handbook) + + This handbook is a collection of tutorials for Hapi.js framework. You can find tutorials about validation, working with 3rd plugins, sending/getting data, template engines, integrations with DB and etc. + +## Boilerplates {#boilerplates} + +- [appy](https://github.com/JKHeadley/appy) — A user system leveraging rest-hapi to bootstrap your app. +- [aqua](https://github.com/jedireza/aqua) — A website and user system. Implemented with React and Flux. +- [frame](https://github.com/jedireza/frame) — A user system API. Bring your own front-end. +- [generator-hapi-service](https://github.com/normative/generator-hapi-service) — Yeoman generator for hapi web services. +- [generator-hapi-style](https://github.com/jedireza/generator-hapi-style) — Yeoman generator for scaffolding hapi apps and plugins. +- [hanx.js](https://github.com/youhusam/hanx.js) — Full-stack boilerplate with Node.js, hapi, PostgreSQL and AngularJS (MEAN.js port) +- [hapi-angular-quickstart](https://github.com/ptpaterson/hapi-angular-quickstart) — Angular2 Quickstart example wrapped into a Hapi plugin. +- [hapi-api](https://github.com/rjmreis/hapi-api) — Lean hapi API Boilerplate with an opinionated view on project structure +- [hapi-cli](https://github.com/AMoreaux/hapi-cli) — Boilerplate for hapi with mongodb, mongoose. Work with Hapi V17. +- [hapi-dash](https://github.com/smaxwellstewart/hapi-dash) — A boilerplate hapi web and API server example, with frontend dashboard +- [hapi-moon](https://github.com/metoikos/hapi-moon) — Hassle-free and production ready hapi.js Server boilerplate +- [hapi-ninja](https://github.com/poeticninja/hapi-ninja) — Boilerplate hapi server example. Node.js, hapi, and Swig. +- [hapi-react-starter-kit](https://github.com/Dindaleon/hapi-react-starter-kit) — A hapi React Starter kit with react-router, redux, react-transform. +- [hapi-starter-kit](https://github.com/Codigami/hapi-starter-kit) — Hapi.js based REST boilerplate which uses latest ES7/ES8 features (async/await) with code coverage and follows best pratices +- [hapi-struct](https://github.com/MarcHanin/hapi-struct) — Simple Hapi server boilerplate with user authentication (MongoDB) +- [hapify boilerplate](https://github.com/Tractr/boilerplate-hapijs/) — Dynamic boilerplate providing an API built with HapiJS, MongoDB and Docker (build for [Hapify.io](https://hub.hapify.io/)) +- [hapitodo](https://github.com/genediazjr/hapitodo) — A TodoMVC jQuery front-end with a Hapi back-end. +- [jolly](https://github.com/ravisuhag/jolly) — Production ready boilerplate for hapi.js +- [mullet](https://github.com/lynnaloo/mullet) — Boilerplate hapi Server with Facebook and React +- [the pal boilerplate](https://github.com/hapipal/boilerplate) — A friendly, proven starting place for your next hapi plugin or deployment +- [rest-hapi](https://github.com/JKHeadley/rest-hapi) — A RESTful API generator built around the hapi framework and mongoose ODM. +- [rutha](https://github.com/molekilla/rutha) — frontend stack for hapi (server, api) and Angular (client) +- [snowflake-hapi-openshift](https://github.com/bartonhammond/snowflake-hapi-openshift) — Hapi Server running on OpenShift/local backed by MongoDB & Redis +- [start-hapiness](https://github.com/thebergamo/start-hapiness) — A Boilerplate that help you to create fast project with Hapi + MongoDB +- [testing-hapi](https://github.com/pashariger/testing-hapi) — Hapi API Server with Swagger Docs, Testing and Travis CI +- [typehapily](https://github.com/tejzpr/typehapily) — A TypeScript based boilerplate for HAPIJS with TypeORM & Dynamic Linting + +## Projects built with hapi.js {#projects} + +- [Colonizers](https://github.com/colonizers/colonizers) — A HTML5 multiplayer game, based on the popular board game "Catan" by Klaus Teuber. +- [MasteryJS](https://github.com/labibramadhan/mastery) — Scalable API Server framework build on top of Hapi and Sequelize. +- [Paydash](https://github.com/hks-epod/paydash) — Worker payments dashboard for MGNREGA, India's employment guarantee programme. +- [Postmile](https://github.com/hueniverse/postmile) — Postmile is a collaborative list making tool built using hapi.js, Node.js, and MongoDB. + +## Videos {#videos} + +- [Hapi Days Conf 2014 Videos](https://www.youtube.com/playlist?list=PLzc1AUDlJ7WvcMnv3NaEwgh0i2nJKl0GX) — hapi days is a one day conference that's focused on hapi and the people that use it. +- [Modern backend with TypeScript, Hapi, PostgreSQL and Prisma](https://www.youtube.com/watch?v=d9v7umfMNkM&list=PLn2e1F9Rfr6k7ULe0gzQvtaXLoXrPqpki&index=2&ab_channel=Prisma) — A series of live streams and articles on building a backend with TypeScript, Hapi, PostgreSQL, and Prisma. +- [Nodevember Conf 2014 hapi.js Workshop](https://www.youtube.com/watch?v=TEKFocYepFY) — A hapi from Scratch Tutorial By Ben Acker And Wyatt Preul at Nodevember Conf. diff --git a/docs/resources/status.md b/docs/resources/status.md new file mode 100644 index 00000000..99ed31f5 --- /dev/null +++ b/docs/resources/status.md @@ -0,0 +1,3 @@ +# Module Status + + diff --git a/docs/support.md b/docs/support.md new file mode 100644 index 00000000..beec48e7 --- /dev/null +++ b/docs/support.md @@ -0,0 +1,18 @@ +--- +title: Support +aside: false +--- + +# How can we help? + +Got a question or a problem with your hapi application? Not to worry! The [hapi Developer Portal](https://hapi.dev) contains plenty of resources to help you get started and use hapi. But when that's not enough... + +## No worries, we're here to help! + +support helmet + +**Free support** is always available on GitHub. Just open an issue with your question and a community member will try to help. For faster response, join either the [hapi Discord server](https://discord.gg/YYxZhpKKvu) or the [hapi Slack channel](https://join.slack.com/t/hapihour/shared_invite/zt-g5ortpsk-ErlnRA2rUcPIWES21oXBOg) — it's where many community members hang out and help each other. + + diff --git a/static/lib/tutorials/en_US/auth.md b/docs/tutorials/en_US/auth.md similarity index 70% rename from static/lib/tutorials/en_US/auth.md rename to docs/tutorials/en_US/auth.md index 4e1c8f25..17a40a8d 100644 --- a/static/lib/tutorials/en_US/auth.md +++ b/docs/tutorials/en_US/auth.md @@ -1,23 +1,28 @@ +--- +title: Authentication +--- + + + # Authentication _This tutorial is compatible with hapi v17 and newer_ - ## Overview -Most modern web apps use some form of authentication. Authentication within hapi is based on the concept of `schemes` and `strategies`. `Schemes` are a way of handling authentication within hapi. For example, the `@hapi/basic` and `@hapi/cookie` plugins would be considered `schemes`. A `strategy` is a pre-configured instance of a `scheme`. You use `strategies` to implement authentication `schemes` into your application. +Most modern web apps use some form of authentication. Authentication within hapi is based on the concept of `schemes` and `strategies`. `Schemes` are a way of handling authentication within hapi. For example, the `@hapi/basic` and `@hapi/cookie` plugins would be considered `schemes`. A `strategy` is a pre-configured instance of a `scheme`. You use `strategies` to implement authentication `schemes` into your application. ## Schemes A `scheme` is a method with the signature `function (server, options)`. The `server` parameter is a reference to the server the scheme is being added to, while the `options` parameter is the configuration object provided when registering a strategy that uses this scheme. -This method must return an object with *at least* the key `authenticate`. Other optional methods that can be used are `payload` and `response`. +This method must return an object with _at least_ the key `authenticate`. Other optional methods that can be used are `payload` and `response`. You can either write your own authentication `scheme`, or use one of the many hapi auth plugins, such as `@hapi/basic` or `@hapi/cookie`. ### authenticate -The `authenticate` method has a signature of `function (request, h)`, and is the only *required* method in a scheme. +The `authenticate` method has a signature of `function (request, h)`, and is the only _required_ method in a scheme. In this context, `request` is the `request` object created by the server. It is the same object that becomes available in a route handler, and is documented in the [API reference](/api#request). @@ -27,7 +32,7 @@ When authentication is successful, you must call and return `h.authenticated({ c The `credentials` and `artifacts` properties can be accessed later (in a route handler, for example) as part of the `request.auth` object. -If authentication is unsuccessful, you can either throw an error or call and return `h.unauthenticated(error, [data])` where `error` is an authentication error and `data` is an optional object containing `credentials` and `artifacts`. There's no difference between calling `return h.unauthenticated(error)` or throwing an error if no `data` object is provided. The specifics of the error passed will affect the behavior. More information can be found in the API documentation for [`server.auth.scheme(name, scheme)`](/api#server.auth.scheme()). It is recommend to use [boom](/module/boom) for errors. +If authentication is unsuccessful, you can either throw an error or call and return `h.unauthenticated(error, [data])` where `error` is an authentication error and `data` is an optional object containing `credentials` and `artifacts`. There's no difference between calling `return h.unauthenticated(error)` or throwing an error if no `data` object is provided. The specifics of the error passed will affect the behavior. More information can be found in the API documentation for [`server.auth.scheme(name, scheme)`](). It is recommend to use [boom](/module/boom) for errors. ### payload @@ -59,12 +64,13 @@ The `name` parameter must be a string, and will be used later to identify this s ```js server.auth.strategy('session', 'cookie', { - name: 'sid-example', - password: '!wsYhFA*C2U6nz=Bu^%A@^F#SF3&kSR6', - isSecure: false + name: 'sid-example', + password: '!wsYhFA*C2U6nz=Bu^%A@^F#SF3&kSR6', + isSecure: false, }); ``` -In the above example, you register the `strategy` with `server.auth.strategy()`. You name the `strategy` `session`, and say that you are using the `cookie` scheme. Lastly, you configure the `strategy` by giving it a `name`, `password`, and setting `isSecure: false`. + +In the above example, you register the `strategy` with `server.auth.strategy()`. You name the `strategy` `session`, and say that you are using the `cookie` scheme. Lastly, you configure the `strategy` by giving it a `name`, `password`, and setting `isSecure: false`. ## Default Strategy @@ -72,7 +78,7 @@ You may set a default strategy by using `server.auth.default()`. This method accepts one parameter, which may be either a string with the name of the strategy to be used as default, or an object in the same format as the route handler's [auth options](#route-configuration). -Note that all routes will have the default applied to them, even the ones added *before* `server.auth.default()` is called. +Note that all routes will have the default applied to them, even the ones added _before_ `server.auth.default()` is called. ## Route Configuration @@ -84,13 +90,13 @@ The `mode` parameter may be set to `'required'`, `'optional'`, or `'try'` and wo If set to `'required'`, in order to access the route, the user must be authenticated, and their authentication must be valid, otherwise they will receive an error. -If `mode` is set to `'optional'` the strategy will still be applied to the route but in this case the user does *not* need to be authenticated. Authentication data is optional, but must be valid if provided. +If `mode` is set to `'optional'` the strategy will still be applied to the route but in this case the user does _not_ need to be authenticated. Authentication data is optional, but must be valid if provided. The last `mode` setting is `'try'`. The difference between `'try'` and `'optional'` is that with `'try'` invalid authentication is accepted, and the user will still reach the route handler. When specifying one strategy, you may set the `strategy` property to a string with the name of the strategy. When specifying more than one strategy, the parameter name must be `strategies` and should be an array of strings each naming a strategy to try. The strategies will then be attempted in order until one succeeds, or they have all failed. -Lastly, the `payload` parameter can be set to `false` denoting the payload is not to be authenticated, `'required'` or `true` meaning that it *must* be authenticated, or `'optional'` meaning that if the client includes payload authentication information, the authentication must be valid. +Lastly, the `payload` parameter can be set to `false` denoting the payload is not to be authenticated, `'required'` or `true` meaning that it _must_ be authenticated, or `'optional'` meaning that if the client includes payload authentication information, the authentication must be valid. Is only possible to use the `payload` parameter, with a strategy that supports the `payload` method in its scheme. @@ -105,60 +111,57 @@ const Bcrypt = require('bcrypt'); const Hapi = require('@hapi/hapi'); const users = { - john: { - username: 'john', - password: '$2a$10$iqJSHD.BGr0E2IxQwYgJmeP3NvhPrXAeLSaGCj6IR/XU5QtjVu5Tm', // 'secret' - name: 'John Doe', - id: '2133d32a' - } + john: { + username: 'john', + password: '$2a$10$iqJSHD.BGr0E2IxQwYgJmeP3NvhPrXAeLSaGCj6IR/XU5QtjVu5Tm', // 'secret' + name: 'John Doe', + id: '2133d32a', + }, }; const validate = async (request, username, password) => { + const user = users[username]; + if (!user) { + return { credentials: null, isValid: false }; + } - const user = users[username]; - if (!user) { - return { credentials: null, isValid: false }; - } + const isValid = await Bcrypt.compare(password, user.password); + const credentials = { id: user.id, name: user.name }; - const isValid = await Bcrypt.compare(password, user.password); - const credentials = { id: user.id, name: user.name }; - - return { isValid, credentials }; + return { isValid, credentials }; }; const start = async () => { + const server = Hapi.server({ port: 4000 }); - const server = Hapi.server({ port: 4000 }); - - await server.register(require('@hapi/basic')); + await server.register(require('@hapi/basic')); - server.auth.strategy('simple', 'basic', { validate }); + server.auth.strategy('simple', 'basic', { validate }); - server.route({ - method: 'GET', - path: '/', - options: { - auth: 'simple' - }, - handler: function (request, h) { + server.route({ + method: 'GET', + path: '/', + options: { + auth: 'simple', + }, + handler: function (request, h) { + return 'welcome'; + }, + }); - return 'welcome'; - } - }); + await server.start(); - await server.start(); - - console.log('server running at: ' + server.info.uri); + console.log('server running at: ' + server.info.uri); }; start(); ``` -First, you define your `users` database, which is a simple object in this example. Then you define a validation function, which is a feature specific to [@hapi/basic](/module/basic) and allows you to verify that the user has provided valid credentials. For this validation function, you use `Bcrypt` to compare the user provided password with the hashed password in your database. +First, you define your `users` database, which is a simple object in this example. Then you define a validation function, which is a feature specific to [@hapi/basic](/module/basic) and allows you to verify that the user has provided valid credentials. For this validation function, you use `Bcrypt` to compare the user provided password with the hashed password in your database. Next, you register the plugin, which creates a scheme with the name of `basic`. This is done within the plugin via [server.auth.scheme()](/api#-serverauthschemename-scheme). -Once the plugin has been registered, you use [server.auth.strategy()](/api#server.auth.strategy()) to create a strategy with the name of `simple` that refers to your scheme named `basic`. You also pass an options object that gets passed to the scheme and allows you to configure its behavior. +Once the plugin has been registered, you use [server.auth.strategy()]() to create a strategy with the name of `simple` that refers to your scheme named `basic`. You also pass an options object that gets passed to the scheme and allows you to configure its behavior. The last thing you do is tell a route to use the strategy named `simple` for authentication. @@ -166,7 +169,7 @@ The last thing you do is tell a route to use the strategy named `simple` for aut [@hapi/cookie](/module/cookie) is a plugin that will store a cookie in the users browser once they are authenticated. This has the option of keeping the user logged in, even after they leave the site. Here is an example of setting up `@hapi/cookie`: -In this example, the home route, "/", is restricted and can only be accessed once a user has authenticated themselves: +In this example, the home route, "/", is restricted and can only be accessed once a user has authenticated themselves: ```js 'use strict'; @@ -175,59 +178,52 @@ const Bcrypt = require('bcrypt'); const Hapi = require('@hapi/hapi'); const users = [ - { - username: 'john', - password: '$2a$10$iqJSHD.BGr0E2IxQwYgJmeP3NvhPrXAeLSaGCj6IR/XU5QtjVu5Tm', // 'secret' - name: 'John Doe', - id: '2133d32a' - } + { + username: 'john', + password: '$2a$10$iqJSHD.BGr0E2IxQwYgJmeP3NvhPrXAeLSaGCj6IR/XU5QtjVu5Tm', // 'secret' + name: 'John Doe', + id: '2133d32a', + }, ]; const start = async () => { + const server = Hapi.server({ port: 4000 }); - const server = Hapi.server({ port: 4000 }); + await server.register(require('@hapi/cookie')); - await server.register(require('@hapi/cookie')); - - server.auth.strategy('session', 'cookie', { - cookie: { - name: 'sid-example', - password: '!wsYhFA*C2U6nz=Bu^%A@^F#SF3&kSR6', - isSecure: false - }, - redirectTo: '/login', - validate: async (request, session) => { + server.auth.strategy('session', 'cookie', { + cookie: { + name: 'sid-example', + password: '!wsYhFA*C2U6nz=Bu^%A@^F#SF3&kSR6', + isSecure: false, + }, + redirectTo: '/login', + validate: async (request, session) => { + const account = await users.find((user) => user.id === session.id); - const account = await users.find( - (user) => (user.id === session.id) - ); + if (!account) { + return { isValid: false }; + } - if (!account) { - - return { isValid: false }; - } - - return { isValid: true, credentials: account }; - } - }); + return { isValid: true, credentials: account }; + }, + }); - server.auth.default('session'); + server.auth.default('session'); - server.route([ - { - method: 'GET', - path: '/', - handler: function (request, h) { - - return 'Welcome to the restricted home page!'; - } - }, - { - method: 'GET', - path: '/login', - handler: function (request, h) { - - return ` + server.route([ + { + method: 'GET', + path: '/', + handler: function (request, h) { + return 'Welcome to the restricted home page!'; + }, + }, + { + method: 'GET', + path: '/login', + handler: function (request, h) { + return ` Login page @@ -239,64 +235,60 @@ const start = async () => { `; - }, - options: { - auth: false - } - }, - { - method: 'POST', - path: '/login', - handler: async (request, h) => { - - const { username, password } = request.payload; - const account = users.find( - (user) => user.username === username - ); - - if (!account || !(await Bcrypt.compare(password, account.password))) { - - return h.redirect('/login'); + }, + options: { + auth: false, + }, + }, + { + method: 'POST', + path: '/login', + handler: async (request, h) => { + const { username, password } = request.payload; + const account = users.find((user) => user.username === username); + + if (!account || !(await Bcrypt.compare(password, account.password))) { + return h.redirect('/login'); } - request.cookieAuth.set({ id: account.id }); + request.cookieAuth.set({ id: account.id }); - return h.redirect('/'); - }, - options: { - auth: { - mode: 'try' - } - } - } - ]); + return h.redirect('/'); + }, + options: { + auth: { + mode: 'try', + }, + }, + }, + ]); - await server.start(); + await server.start(); - console.log('server running at: ' + server.info.uri); + console.log('server running at: ' + server.info.uri); }; start(); ``` + First, you need to do is register the `@hapi/cookie` plugin with `server.register`. Once the plugin is registered, you configure your `strategy` by calling `server.auth.strategy`. `server.auth.strategy` takes three parameters: name of the strategy, what scheme you are using, and an options object. For your strategy, you name it `session`. For the scheme, you will be using the `cookie` scheme. If you were using `@hapi/basic`, this parameter would be `basic`. The last parameter is an options object. This is how you can customize your auth strategy to fit your needs. -The first property you configure is the `cookie` object. In your `strategy`, you will configure three properties of the `cookie` object. First, you set the name of the cookie, in this case `sid-example`. Next, you set the password that will be used to encrypt the cookie. This should be at least 32 characters long. Last, you set `isSecure` to `false`. This is ok for development while working over HTTP. In production, this should be switched back to `true`, which is the default setting. +The first property you configure is the `cookie` object. In your `strategy`, you will configure three properties of the `cookie` object. First, you set the name of the cookie, in this case `sid-example`. Next, you set the password that will be used to encrypt the cookie. This should be at least 32 characters long. Last, you set `isSecure` to `false`. This is ok for development while working over HTTP. In production, this should be switched back to `true`, which is the default setting. -The next property is `redirectTo`. This will tell the server where to redirect to if an unauthenticated user tries to access a resource that requires authentication. +The next property is `redirectTo`. This will tell the server where to redirect to if an unauthenticated user tries to access a resource that requires authentication. -The last property is the `validate` function, which validates that a current cookie is still valid. For example, if a user authenticates themselves successfully, receives a cookie, and then leaves the site. Once they return, the `validate` function will check if their current cookie is still valid. +The last property is the `validate` function, which validates that a current cookie is still valid. For example, if a user authenticates themselves successfully, receives a cookie, and then leaves the site. Once they return, the `validate` function will check if their current cookie is still valid. -You setup the default strategy by calling `server.auth.default('session')`. This will set the default auth strategy for all routes. +You setup the default strategy by calling `server.auth.default('session')`. This will set the default auth strategy for all routes. Once your strategy is set up, you need to set up route that will validate the provided username and password. In this case, your `POST` route to `'/login'` will do just that. First, it will pull the `username` and `password` from `request.payload`, which the user provided in the form from the `'/login'` `'GET'` route. Next, you find the user from the database by searching for their username: ```js -const account = users.find( - (user) => user.username === username -); +const account = users.find((user) => user.username === username); ``` -If the user doesn't exist, or if the provided password is wrong, you redirect the user back to the login page. You use `Bcrypt` to compare the user provided password with the hashed password from the database. -Lastly, if the user does exist, and the password matches, the user is then redirected to the homepage. +If the user doesn't exist, or if the provided password is wrong, you redirect the user back to the login page. You use `Bcrypt` to compare the user provided password with the hashed password from the database. + +Lastly, if the user does exist, and the password matches, the user is then redirected to the homepage. For more info on additional hapi auth plugins, please see the [plugin section](/plugins). diff --git a/static/lib/tutorials/en_US/caching.md b/docs/tutorials/en_US/caching.md similarity index 74% rename from static/lib/tutorials/en_US/caching.md rename to docs/tutorials/en_US/caching.md index af169919..28b753e6 100644 --- a/static/lib/tutorials/en_US/caching.md +++ b/docs/tutorials/en_US/caching.md @@ -1,8 +1,13 @@ +--- +title: Caching +--- + + + # Caching _This tutorial is compatible with hapi v17 and newer_ - ## Overview One of the best ways to improve website performance is to configure caching on your server. hapi makes it easy to configure both client-side and server-side caching. @@ -21,24 +26,23 @@ Let's see how you can set this header in hapi: ```javascript server.route({ - path: '/hapi/{ttl?}', - method: 'GET', - handler: function (request, h) { - - const response = h.response({ be: 'hapi' }); + path: '/hapi/{ttl?}', + method: 'GET', + handler: function (request, h) { + const response = h.response({ be: 'hapi' }); - if (request.params.ttl) { - response.ttl(request.params.ttl); - } + if (request.params.ttl) { + response.ttl(request.params.ttl); + } - return response; + return response; + }, + options: { + cache: { + expiresIn: 30 * 1000, + privacy: 'private', }, - options: { - cache: { - expiresIn: 30 * 1000, - privacy: 'private' - } - } + }, }); ``` @@ -58,9 +62,9 @@ When the `Last-Modified` header is set on a response, hapi compares it with the Assuming `lastModified` is a `Date` object you can set this header via the [response object](/api#response-object) as seen here: ```javascript -return h.response(result) - .header('Last-Modified', lastModified.toUTCString()); +return h.response(result).header('Last-Modified', lastModified.toUTCString()); ``` + There is one more example using `Last-Modified` in the [last section](#clientandserver) of this tutorial. ### ETag @@ -100,22 +104,22 @@ const Hapi = require('@hapi/hapi'); const CatboxRedis = require('@hapi/catbox-redis'); const server = Hapi.server({ - port: 8000, - cache: [ - { - name: 'my_cache', - provider: { - constructor: CatboxRedis, - options: { - partition : 'my_cached_data', - host: 'redis-cluster.domain.com', - port: 6379, - database: 0, - tls: {} - } - } - } - ] + port: 8000, + cache: [ + { + name: 'my_cache', + provider: { + constructor: CatboxRedis, + options: { + partition: 'my_cached_data', + host: 'redis-cluster.domain.com', + port: 6379, + database: 0, + tls: {}, + }, + }, + }, + ], }); ``` @@ -127,51 +131,48 @@ In the above example, you defined a new catbox client, `my_cache`. Including the ```javascript const start = async () => { + const server = Hapi.server(); - const server = Hapi.server(); - - const add = async (a, b) => { - - await Hoek.wait(1000); // Simulate some slow I/O - - return Number(a) + Number(b); - }; + const add = async (a, b) => { + await Hoek.wait(1000); // Simulate some slow I/O - const sumCache = server.cache({ - cache: 'my_cache', - expiresIn: 10 * 1000, - segment: 'customSegment', - generateFunc: async (id) => { + return Number(a) + Number(b); + }; - return await add(id.a, id.b); - }, - generateTimeout: 2000 - }); - - server.route({ - path: '/add/{a}/{b}', - method: 'GET', - handler: async function (request, h) { + const sumCache = server.cache({ + cache: 'my_cache', + expiresIn: 10 * 1000, + segment: 'customSegment', + generateFunc: async (id) => { + return await add(id.a, id.b); + }, + generateTimeout: 2000, + }); - const { a, b } = request.params; - const id = `${a}:${b}`; + server.route({ + path: '/add/{a}/{b}', + method: 'GET', + handler: async function (request, h) { + const { a, b } = request.params; + const id = `${a}:${b}`; - return await sumCache.get({ id, a, b }); - } - }); + return await sumCache.get({ id, a, b }); + }, + }); - await server.start(); + await server.start(); - console.log('Server running at:', server.info.uri); + console.log('Server running at:', server.info.uri); }; start(); ``` + If you make a request to `http://localhost:8000/add/1/5`, you should get the response `6` after about a second. If you hit that endpoint again the response should come immediately because it's being served from the cache. If you were to wait 10s and then call it again, you'd see that it took a while because the cached value has now been ejected from the cache. `server.cache(options)` provisions a cache segment within the server cache facility. In this case, your policy will be using `'my_cache'` which you created above with `server.cache`. -`expiresIn` states the time, in milliseconds, the cache will expire in relation to the time the item was saved in the cache. In this case, our cache will expire 10 seconds after the item was saved. +`expiresIn` states the time, in milliseconds, the cache will expire in relation to the time the item was saved in the cache. In this case, our cache will expire 10 seconds after the item was saved. `segment` that allow you to further isolate caches within one [client](/module/catbox/api#client) partition. If you want to cache results from two different methods, you usually don't want to mix the results together. In [redis](http://redis.io/), `segment` is an additional prefix along with the `partition` option. The default value for `segment` when [server.cache()](/api#-servercacheoptions) is called inside of a plugin will be `'!pluginName'`. When creating [server methods](/tutorials/servermethods), the `segment` value will be `'#methodName'`. If you have a use case for multiple policies sharing one segment there is a [shared](/api#-servercacheoptions) option available as well. @@ -179,7 +180,7 @@ If you make a request to `http://localhost:8000/add/1/5`, you should get the res `generateTimeout` is the number of milliseconds to wait before returning a timeout error when the `generateFunc` function takes too long to return a value. -`get(id)` is used to retrieve an item from the cache. If the item is not found, and the `generateFunc` method was provided, a new value is generated, stored in the cache, and is returned. +`get(id)` is used to retrieve an item from the cache. If the item is not found, and the `generateFunc` method was provided, a new value is generated, stored in the cache, and is returned. The first parameter of the `sumCache.get()` function is an id, which may either be a string or an object with a mandatory property `id`, which is a unique cache item identifier. @@ -191,34 +192,32 @@ But it can get better than that! In 95% cases you will use server methods for ca ```javascript const start = async () => { + const server = Hapi.server(); - const server = Hapi.server(); - - server.method('sum', add, { - cache: { - cache: 'my_cache', - expiresIn: 10 * 1000, - generateTimeout: 2000 - } - }); - - server.route({ - path: '/add/{a}/{b}', - method: 'GET', - handler: async function (request, h) { - - const { a, b } = request.params; - return await server.methods.sum(a, b); - } - }); + server.method('sum', add, { + cache: { + cache: 'my_cache', + expiresIn: 10 * 1000, + generateTimeout: 2000, + }, + }); - await server.start(); + server.route({ + path: '/add/{a}/{b}', + method: 'GET', + handler: async function (request, h) { + const { a, b } = request.params; + return await server.methods.sum(a, b); + }, + }); + await server.start(); }; start(); ``` -[server.method()](/api#server.method()) created a new [policy](/module/catbox/api#policy) with `segment: '#sum'` automatically for us. Also the unique item `id` (cache key) was automatically generated from parameters. By default, it handles `string`, `number` and `boolean` parameters. For more complex parameters, you have to provide your own `generateKey` function to create unique ids based on the parameters - check out the server methods tutorial for more information. + +[server.method()]() created a new [policy](/module/catbox/api#policy) with `segment: '#sum'` automatically for us. Also the unique item `id` (cache key) was automatically generated from parameters. By default, it handles `string`, `number` and `boolean` parameters. For more complex parameters, you have to provide your own `generateKey` function to create unique ids based on the parameters - check out the server methods tutorial for more information. ## Client and Server caching @@ -228,34 +227,30 @@ An example of server-side and client-side caching working together is using the ```javascript const start = async () => { + const server = Hapi.server(); + + server.method('sum', add, { + cache: { + cache: 'my_cache', + expiresIn: 10 * 1000, + generateTimeout: 2000, + getDecoratedValue: true, + }, + }); - const server = Hapi.server(); - - server.method('sum', add, { - cache: { - cache: 'my_cache', - expiresIn: 10 * 1000, - generateTimeout: 2000, - getDecoratedValue: true - } - }); - - server.route({ - path: '/add/{a}/{b}', - method: 'GET', - handler: async function (request, h) { - - const { a, b } = request.params; - const { value, cached } = await server.methods.sum(a, b); - const lastModified = cached ? new Date(cached.stored) : new Date(); - - return h.response(value) - .header('Last-modified', lastModified.toUTCString()); - } - }); + server.route({ + path: '/add/{a}/{b}', + method: 'GET', + handler: async function (request, h) { + const { a, b } = request.params; + const { value, cached } = await server.methods.sum(a, b); + const lastModified = cached ? new Date(cached.stored) : new Date(); - await server.start(); + return h.response(value).header('Last-modified', lastModified.toUTCString()); + }, + }); + await server.start(); }; ``` diff --git a/docs/tutorials/en_US/community.md b/docs/tutorials/en_US/community.md new file mode 100644 index 00000000..606d4b38 --- /dev/null +++ b/docs/tutorials/en_US/community.md @@ -0,0 +1,57 @@ +--- +title: Community +--- + + + +# Community Tutorials + +- [Authentication and Authorization with hapi](https://medium.com/@poeticninja/authentication-and-authorization-with-hapi-5529b5ecc8ec) + + Article on how to secure your hapi application. + +- [Building a Chat Application with hapi.js, Socket.io and Redis](https://github.com/dwyl/hapi-socketio-redis-chat-example) + + Real-time chat application built using hapi.js, Socket.io and Redis Pub/Sub with end-to-end tests. + +- [Building a modern backend with TypeScript, Hapi, PostgreSQL and Prisma](https://www.prisma.io/blog/series/modern-backend-bdes2ps5kibb) + + A series of live streams and articles on building a backend with TypeScript, Hapi, PostgreSQL, and Prisma. + The series covers data modeling, CRUD, aggregations, REST, validation with Joi, testing, authentication, authorization, integration with other APIs, continuous integration and deployment with GitHub Actions and Heroku. + The series explores and demonstrates different patterns, problems, and architectures for a modern backend by solving a concrete problem: a grading system for online courses. This is a good example because it features diverse relations types and is complex enough to represent a real-world use case. + +- [Handling plugin dependencies](https://hapipal.com/best-practices/handling-plugin-dependencies) + + In celebration of hapi plugin boundaries, here we offer a concrete approach to taming inter-plugin dependencies. + +- [hapi tutorial series (30+ tutorials)](https://futurestud.io/tutorials/hapi-get-your-server-up-and-running) + + This in-depth tutorial series on hapi covers route setup, authentication, plugins, request & response handling, and much more. + +- [hapi.js tutorials covering various topics](https://content.nanobox.io/tag/hapi.js/) + + A growing list of tutorials covering hapi.js application development, deployment, optimization, and production management (scaling, monitoring, etc.). + +- [How to create a REST API with hapi](http://blog.webkid.io/how-to-create-a-rest-api-with-hapi/) + + Tutorial about how to create a RESTful API with the Plugins Dogwater (Waterline ORM) and Bedwetter. + +- [The joys of server / plugin separation](https://hapipal.com/best-practices/server-plugin-separation) + + The joyful act of decoupling your application plugin from its deployment will make your hapi app more portable and simpler to test. + +- [rate-limiter-flexible-plugin-example](https://github.com/animir/node-rate-limiter-flexible/wiki/Hapi-plugin) + + Plugin example of rate limiting and DDoS protection with rate-limiter-flexible package + +- [Run hapi.js on Google Cloud Platform](https://cloud.google.com/nodejs/resources/frameworks/hapi) + + Tutorial and cloneable sample app showing how to create and deploy a hapi.js application on Google App Engine. + +- [Catbox-Redis and Cookie Auth Example](https://github.com/johnmanko/catbox-redis-example) + + Demonstrate how to use @hapi/catbox-redis and @hapi/cookie. + +- [WittCode's Hapi Tutorial Series](https://youtube.com/playlist?list=PLkqiWyX-_LotaQ9AuppIAXl0xyV-P5Ms-) + + 10 videos starting from creating a Hapi server, adding routes, plugins, through to using Sequelize/MySQL and cookie authentication. diff --git a/static/lib/tutorials/en_US/cookies.md b/docs/tutorials/en_US/cookies.md similarity index 83% rename from static/lib/tutorials/en_US/cookies.md rename to docs/tutorials/en_US/cookies.md index 9d3b012d..cb0e31ca 100644 --- a/static/lib/tutorials/en_US/cookies.md +++ b/docs/tutorials/en_US/cookies.md @@ -1,11 +1,16 @@ +--- +title: Cookies +--- + + + # Cookies _This tutorial is compatible with hapi v17 and newer_ - ## Overview -When writing a web application, cookies are often used to keep state about a user between requests. With hapi, cookies are flexible, secure, and simple to use. +When writing a web application, cookies are often used to keep state about a user between requests. With hapi, cookies are flexible, secure, and simple to use. ## Configuring the server @@ -13,20 +18,21 @@ hapi has several configurable options when dealing with cookies. The defaults ar ### server.state() -To use a cookie, you first need to configure it by calling [`server.state(name, [options])`](/api#server.state()) where `name` is the name of the cookie, and `options` is an object used to configure the cookie. +To use a cookie, you first need to configure it by calling [`server.state(name, [options])`]() where `name` is the name of the cookie, and `options` is an object used to configure the cookie. Please note that the default settings for `options` is good for most cases and don't need to be configured. For learning purposes, you will configure them in this tutorial: ```javascript server.state('data', { - ttl: null, - isSecure: true, - isHttpOnly: true, - encoding: 'base64json', - clearInvalid: true, - strictHeader: true + ttl: null, + isSecure: true, + isHttpOnly: true, + encoding: 'base64json', + clearInvalid: true, + strictHeader: true, }); ``` + In the example above, you first name the cookie `data`. You then configure the options to customize the cookie. The first option is `ttl`. This represents the cookies time to live in milliseconds. The default setting is `null`, which will delete the cookie once the browser is closed. @@ -47,14 +53,15 @@ Please note that configurations to cookies on the route-level are in addition to ```json5 { - options: { - state: { - parse: true, - failAction: 'error' - } - } + options: { + state: { + parse: true, + failAction: 'error', + }, + }, } ``` + The `parse` option determines if cookies are parsed and stored in `request.state`. The `failAction` options determines how cookie parsing errors will be handled. @@ -65,19 +72,19 @@ Setting a cookie is done via the [response toolkit](/api#response-toolkit) in a ### h.state() -You set a cookie by calling [`h.state(name, value, [options]`](/api#h.state()). In the following example, you set a cookie in a route handler: +You set a cookie by calling [`h.state(name, value, [options]`](). In the following example, you set a cookie in a route handler: ```javascript server.route({ - method: 'GET', - path: '/', - handler: function (request, h) { - - h.state('data', { firstVisit: false }); - return h.response('Hello'); - } + method: 'GET', + path: '/', + handler: function (request, h) { + h.state('data', { firstVisit: false }); + return h.response('Hello'); + }, }); ``` + In this example, you use the cookie we configured in the section above. Here, hapi will reply with the string `Hello` as well as set a cookie named `data` to a base64 encoded JSON string representation of `{ firstVisit: false }`. The `state()` method is also available on the [response object](/api#response-object) which allows for convenient chaining. The above example can therefore also be written: @@ -100,7 +107,7 @@ In this example the cookie will simply be set to the string `"test"` with no enc Access a cookie’s value via `request.state` in a route handler, pre-requisite, or request lifecycle extension point. -The `request.state` object contains the parsed HTTP state. Each key represents the cookie name and its value is the defined content. If multiple cookies with the same name are present on the request, the values are exposed as an array rather than a single value. +The `request.state` object contains the parsed HTTP state. Each key represents the cookie name and its value is the defined content. If multiple cookies with the same name are present on the request, the values are exposed as an array rather than a single value. The sample code uses the `data` cookie key from above where the related value is set to `{ firstVisit: false }`: @@ -116,5 +123,5 @@ The cookie can be cleared by calling the `unstate()` method on the [response too ```javascript return h.response('Bye').unstate('data'); ``` -Here, you just pass the name of the cookie into `unstate()` to clear the cookie. +Here, you just pass the name of the cookie into `unstate()` to clear the cookie. diff --git a/static/lib/tutorials/en_US/expresstohapi.md b/docs/tutorials/en_US/express-to-hapi.md similarity index 74% rename from static/lib/tutorials/en_US/expresstohapi.md rename to docs/tutorials/en_US/express-to-hapi.md index 267c6882..6f05f415 100644 --- a/static/lib/tutorials/en_US/expresstohapi.md +++ b/docs/tutorials/en_US/express-to-hapi.md @@ -1,11 +1,16 @@ +--- +title: Express to hapi +--- + + + # Express Migration _This guide is compatible with hapi v17 and newer_ - ## Overview -This Express to hapi guide will show you how to take what you know how to do in Express, and do it in hapi. While Express relies heavily on middleware for much of its functionality, hapi has more built into the core. Body parsing, cookie handling, input/output validation, and HTTP-friendly error objects are already built-in to the hapi framework. For additional functionality, hapi has a robust selection of plugins in its core ecosystem. hapi is also the only framework that doesn't rely on outside dependencies. Every dependency is managed by the core hapi team, which makes security and reliability some of hapi's greatest strengths. +This Express to hapi guide will show you how to take what you know how to do in Express, and do it in hapi. While Express relies heavily on middleware for much of its functionality, hapi has more built into the core. Body parsing, cookie handling, input/output validation, and HTTP-friendly error objects are already built-in to the hapi framework. For additional functionality, hapi has a robust selection of plugins in its core ecosystem. hapi is also the only framework that doesn't rely on outside dependencies. Every dependency is managed by the core hapi team, which makes security and reliability some of hapi's greatest strengths. ## Setup @@ -14,14 +19,13 @@ This Express to hapi guide will show you how to take what you know how to do in Express: `npm install express` - hapi: `npm install @hapi/hapi` - ### Creating a Server Express: + ```js var express = require('express'); var app = express(); @@ -32,49 +36,52 @@ app.listen(3000, function () { ``` hapi: + ```js const Hapi = require('@hapi/hapi'); const init = async () => { + const server = Hapi.server({ + port: 3000, + host: 'localhost', + }); - const server = Hapi.server({ - port: 3000, - host: 'localhost' - }); - - await server.start(); - console.log('Server running on port 3000'); + await server.start(); + console.log('Server running on port 3000'); }; init(); ``` + Unlike Express, in hapi you create a server object that will be the focal point of your application. The properties set in the server object will determine how your application behaves. Once you create your server object, you can start your server by calling `server.start()`. ## Routes -Routes in hapi get called in a specific order, so you will never have an issue where two routes are conflicting with one another. Routes are called from most specific to least specific. For example, a route with a path `'/home'` will be called before `'/{any*}'`. +Routes in hapi get called in a specific order, so you will never have an issue where two routes are conflicting with one another. Routes are called from most specific to least specific. For example, a route with a path `'/home'` will be called before `'/{any*}'`. Lets look at how to set up a basic route in hapi: Express: + ```js -app.get('/hello', function (req, res) { +app.get('/hello', function (req, res) { res.send('Hello World!'); }); ``` hapi: + ```js server.route({ - method: 'GET', - path:'/hello', - handler: (request, h) => { - - return 'Hello World!'; - } + method: 'GET', + path: '/hello', + handler: (request, h) => { + return 'Hello World!'; + }, }); ``` -To create a route, Express has the structure of `app.METHOD(PATH, HANDLER)` and hapi has the structure `server.route({METHOD, PATH, HANDLER})`. The method, path, and handler are passed to the hapi server as an object. As you can see, to return a string in Express, you call `res.send()`, whereas in hapi, you simply return the string. + +To create a route, Express has the structure of `app.METHOD(PATH, HANDLER)` and hapi has the structure `server.route({METHOD, PATH, HANDLER})`. The method, path, and handler are passed to the hapi server as an object. As you can see, to return a string in Express, you call `res.send()`, whereas in hapi, you simply return the string. ### Methods @@ -82,19 +89,19 @@ hapi can use all the route methods that Express can, except `HEAD`. hapi also ha ```js server.route({ - method: ['PUT', 'POST'], - path: '/', - handler: function (request, h) { - - return 'I did something!'; - } + method: ['PUT', 'POST'], + path: '/', + handler: function (request, h) { + return 'I did something!'; + }, }); ``` -To use all available methods, like in Express `app.all()`, use `method: '*'`. + +To use all available methods, like in Express `app.all()`, use `method: '*'`. ### Path -Like in Express, the path option in hapi must be a string, which can also contain parameters. Parameters in Express are preceded by `:`, such as: `'/users/:userId'`. In hapi, you would put the parameter in curly braces, like: `path: '/users/{userId}'`. +Like in Express, the path option in hapi must be a string, which can also contain parameters. Parameters in Express are preceded by `:`, such as: `'/users/:userId'`. In hapi, you would put the parameter in curly braces, like: `path: '/users/{userId}'`. ### Parameters @@ -103,80 +110,81 @@ You saw above how hapi handles simple parameters as compared to Express. Both ha Accessing the parameters in hapi is very similar to Express. As you know, in Express, the parameters are populated in the `req.params` object. In hapi, the parameters are available via the `request.params` object. Here is an example of both: Express: + ```js app.get('/hello/:name', function (req, res) { - - const name = req.params.name - res.send('Hello ' + name); -}); + const name = req.params.name; + res.send('Hello ' + name); +}); ``` hapi: + ```js server.route({ - method: 'GET', - path: '/hello/{name}', - handler: function (request, h) { - - const name = request.params.name; - return 'Hello ' + name - } + method: 'GET', + path: '/hello/{name}', + handler: function (request, h) { + const name = request.params.name; + return 'Hello ' + name; + }, }); ``` -Query parameters are also similar in both frameworks. In Express, they are available via `req.query` and hapi they are available via `request.query`. +Query parameters are also similar in both frameworks. In Express, they are available via `req.query` and hapi they are available via `request.query`. ### Handler -There are differences in the way Express and hapi structure their route handlers. Unlike Express, which has a handler with parameters of `req` and `res`, hapi has a handler with parameters of `request` and `h`. The second parameter, `h` is the response toolkit, which is an object with several methods used to respond to the request. +There are differences in the way Express and hapi structure their route handlers. Unlike Express, which has a handler with parameters of `req` and `res`, hapi has a handler with parameters of `request` and `h`. The second parameter, `h` is the response toolkit, which is an object with several methods used to respond to the request. Here is an example of route with a handler that redirects to another route in Express and hapi: Express: + ```js app.get('/home', function (req, res) { - - res.redirect('/'); + res.redirect('/'); }); ``` hapi: + ```js server.route({ - method: 'GET', - path: '/home', - handler: function (request, h) { - - return h.redirect('/'); - } + method: 'GET', + path: '/home', + handler: function (request, h) { + return h.redirect('/'); + }, }); ``` + Both routes will redirect to the `'/'` route. Express uses the response method `res.redirect` whereas hapi uses `h.redirect` which is part of the response toolkit. There are Express response methods that hapi can accomplish by just using `return`. Some of these methods include `res.send` and `res.json`. Here is an example of how hapi will respond with JSON data: ```js server.route({ - method: 'GET', - path: '/user', - handler: function (request, h) { - - const user = { - firstName: 'John', - lastName: 'Doe', - userName: 'JohnDoe', - id: 123 - } + method: 'GET', + path: '/user', + handler: function (request, h) { + const user = { + firstName: 'John', + lastName: 'Doe', + userName: 'JohnDoe', + id: 123, + }; - return user; - } + return user; + }, }); ``` + hapi has the functionality to respond with JSON data by default. The only thing you have to do is just return a valid JavaScript object and hapi will take care of the rest for you. ## Middleware vs Plugins and Extensions -To extend its functionality, Express uses middleware. Middleware essentially is a sequence of functions using callbacks to execute the next function. The issue with this is as your application grows in size and complexity, the order at which middleware executes becomes more crucial and more difficult to maintain. Having a middleware execute before one it is dependant on will cause your application to fail. hapi fixes this issue with its robust plugin and extension system. +To extend its functionality, Express uses middleware. Middleware essentially is a sequence of functions using callbacks to execute the next function. The issue with this is as your application grows in size and complexity, the order at which middleware executes becomes more crucial and more difficult to maintain. Having a middleware execute before one it is dependant on will cause your application to fail. hapi fixes this issue with its robust plugin and extension system. -Plugins allow you to break your application logic into isolated pieces of business logic, and reusable utilities. Each plugin comes with its own dependencies which are explicitly specified in the plugins themselves. This means you don't have to install dependencies yourself to make your plugins work. You can either add an existing hapi plugin, or write your own. For a more extensive tutorial on plugins, please see the [plugins](/tutorials/plugins/?lang=en_US) tutorial. +Plugins allow you to break your application logic into isolated pieces of business logic, and reusable utilities. Each plugin comes with its own dependencies which are explicitly specified in the plugins themselves. This means you don't have to install dependencies yourself to make your plugins work. You can either add an existing hapi plugin, or write your own. For a more extensive tutorial on plugins, please see the [plugins](/tutorials/plugins/?lang=en_US) tutorial. Each request in hapi follows a predefined path, the request lifecycle. hapi has extension points that let you create custom functionality along the lifecycle. Extension points in hapi let you know the precise order at which your application will run. For more info, please see the hapi [request lifecycle](/api/#request-lifecycle). @@ -186,66 +194,67 @@ hapi has 7 extension points along the request lifecycle. In order, they are `onR ```js server.ext('onRequest', function (request, h) { - - request.setUrl('/test'); - return h.continue; + request.setUrl('/test'); + return h.continue; }); ``` -This function will run at `onRequest`, which is the first extension point. `onRequest` is run just after the server receives the request object, before the route lookup. What this function will do is reroute all requests to the `'/test'` route. +This function will run at `onRequest`, which is the first extension point. `onRequest` is run just after the server receives the request object, before the route lookup. What this function will do is reroute all requests to the `'/test'` route. ### Creating a Plugin As you know, you can write your own middleware in Express. The same is true with hapi plugins. A plugin is an object with required `name` and `register` properties. The `register` property is a function with the signature of `async function (server, option)`. Lets look at how to create a basic plugin: Express: + ```js const getDate = function (req, res, next) { + req.getDate = function () { + const date = new Date(); + return date; + }; - req.getDate = function() { - - const date = new Date(); - return date; - }; - - next(); + next(); }; ``` hapi: + ```js const getDate = { - name: 'getDate', - version: '1.0.0', - register: async function (server, options) { - - const currentDate = function() { - - const date = new Date(); - return date; - }; + name: 'getDate', + version: '1.0.0', + register: async function (server, options) { + const currentDate = function () { + const date = new Date(); + return date; + }; - server.decorate('toolkit', 'getDate', currentDate); - } + server.decorate('toolkit', 'getDate', currentDate); + }, }; ``` -The hapi plugin will save the current date in `h.getDate()`. We can then use this in any of our route handlers. + +The hapi plugin will save the current date in `h.getDate()`. We can then use this in any of our route handlers. ### Loading a Plugin In Express, you load middleware by calling the `app.use()` method. In hapi, you call the `server.register()` method. Lets load the plugin we created in the previous section: Express: + ```js app.use(getDate); ``` hapi: + ```js await server.register({ - plugin: getDate + plugin: getDate, }); ``` + You can also provide options to your plugin by setting the `options` property on `server.register()`. ### Options @@ -253,41 +262,41 @@ You can also provide options to your plugin by setting the `options` property on You can add options to Express middleware by exporting a function that accepts an options parameter, which then returns the middleware. In hapi, you set the options when you register the plugin. Lets have a look: Express: + ```js module.exports = function (options) { - return function getDate(req, res, next) { - - req.getDate = function() { - - const date = 'Hello ' + options.name + ', the date is ' + new Date(); - return date; - }; - - next() + return function getDate(req, res, next) { + req.getDate = function () { + const date = 'Hello ' + options.name + ', the date is ' + new Date(); + return date; }; + + next(); + }; }; ``` hapi: + ```js const getDate = { - name: 'getDate', - version: '1.0.0', - register: async function (server, options) { - - const currentDate = function() { - - const date = 'Hello ' + options.name + ', the date is ' + new Date(); - return date; - }; + name: 'getDate', + version: '1.0.0', + register: async function (server, options) { + const currentDate = function () { + const date = 'Hello ' + options.name + ', the date is ' + new Date(); + return date; + }; - server.decorate('toolkit', 'getDate', currentDate); - } + server.decorate('toolkit', 'getDate', currentDate); + }, }; ``` + To get access to the options in hapi, you simply refer to the `options` object when you create the plugin: Express: + ```js const getDate = require('./mw/getDate.js'); @@ -295,13 +304,14 @@ app.use(getDate({ name: 'Tom' })); ``` hapi: + ```js server.register({ - plugin: getDate, - options: { - name: 'Tom' - } -}) + plugin: getDate, + options: { + name: 'Tom', + }, +}); ``` ## body-parser @@ -309,37 +319,38 @@ server.register({ hapi has parsing abilities built into its core. Unlike Express, you do not need middleware to parse payload data. In fact, you may need to install up to four additional middlewares in Express depending on what kind of data you would like to parse. In hapi the payload data, whether its JSON or plain text, is readily available in the `request.payload` object. Here is a side by side comparison of parsing simple payload data: Express: + ```js var bodyParser = require('body-parser'); -app.use(bodyParser.urlencoded({extend: true})); - -app.post('/hello', function (req, res) { +app.use(bodyParser.urlencoded({ extend: true })); - var name = req.body.name - res.send('Hello ' + name); +app.post('/hello', function (req, res) { + var name = req.body.name; + res.send('Hello ' + name); }); ``` hapi: + ```js server.route({ - method: 'POST', - path: '/hello', - handler: function (request, h) { - - const name = request.payload.name; - return `Hello ` + name; - } + method: 'POST', + path: '/hello', + handler: function (request, h) { + const name = request.payload.name; + return `Hello ` + name; + }, }); ``` To parse a JSON object in express, you have to specify it: + ```js app.use(bodyParser.json()); ``` -JSON parsing is built into hapi, so there are no further steps needed. +JSON parsing is built into hapi, so there are no further steps needed. ## cookie-parser @@ -351,16 +362,18 @@ const Hapi = require('@hapi/hapi'); const server = Hapi.server({ port: 8000 }); server.state('data', { - ttl: null, - isSecure: true, - isHttpOnly: true + ttl: null, + isSecure: true, + isHttpOnly: true, }); ``` ### Setting a Cookie + Once the cookie is configured, you can now set the cookie with `h.state()`. Here is an example: Express: + ```js var express = require('express'); var app = express(); @@ -368,43 +381,43 @@ var cookieParser = require('cookie-parser'); app.use(cookieParser()); -app.get('/', function(req, res) { - - res.cookie('username', 'tom', { maxAge: null, secure: true, httpOnly: true }); - res.send('Hello'); +app.get('/', function (req, res) { + res.cookie('username', 'tom', { maxAge: null, secure: true, httpOnly: true }); + res.send('Hello'); }); ``` hapi: + ```js const Hapi = require('@hapi/hapi'); const server = Hapi.server({ port: 8000 }); server.state('username', { - ttl: null, - isSecure: true, - isHttpOnly: true + ttl: null, + isSecure: true, + isHttpOnly: true, }); server.route({ - method: 'GET', - path: '/', - handler: function (request, h) { - - h.state('username', 'tom'); - return h.response('Hello'); - } + method: 'GET', + path: '/', + handler: function (request, h) { + h.state('username', 'tom'); + return h.response('Hello'); + }, }); ``` -In express, you configure cookie with the `options` object in `res.cookie`. In hapi, the cookie config is saved to the server object with `server.state`. You then use `h.state()` to attach data to the cookie. +In express, you configure cookie with the `options` object in `res.cookie`. In hapi, the cookie config is saved to the server object with `server.state`. You then use `h.state()` to attach data to the cookie. ### Getting a Cookie Value To get a cookie value in hapi, you call `request.state`. Lets have look: Express: + ```js var express = require('express'); var app = express(); @@ -413,32 +426,32 @@ var cookieParser = require('cookie-parser); app.use(cookieParser()); app.get('/', (req, res) => { - + res.cookie('username', 'tom', { maxAge: null, secure: true, httpOnly: true }) res.send(req.cookies.username); }); ``` hapi: + ```js const Hapi = require('@hapi/hapi'); const server = Hapi.server({ port: 8000 }); server.state('username', { - ttl: null, - isSecure: true, - isHttpOnly: true + ttl: null, + isSecure: true, + isHttpOnly: true, }); server.route({ - method: 'GET', - path: '/', - handler: async (request, h) => { - - h.state('username', 'tom'); - return h.response(request.state.username); - } + method: 'GET', + path: '/', + handler: async (request, h) => { + h.state('username', 'tom'); + return h.response(request.state.username); + }, }); ``` @@ -447,9 +460,11 @@ server.route({ In Express, third party authentication is handled with Passport. In hapi, you use the [bell](/module/bell) module for third party authentication. `bell` has over 30 predefined configurations for OAuth providers including Twitter, Facebook, Google, GitHub, and more. It will also allow you to set up your own custom provider. For a complete list, please see the [bell providers documentation](https://github.com/hapijs/bell/blob/master/Providers.md). `bell` was developed and is maintained by the core hapi team, so you know stability and reliability won't be an issue. Lets look how to authenticate using your Twitter credentials: Express: + ``` npm install passport passport-twitter ``` +
    ```js @@ -485,9 +500,11 @@ app.get('/auth/twitter/callback', passport.authenticate('twitter', { failureRedi ``` hapi: + ``` npm install '@hapi/bell' ``` +
    ```js @@ -499,49 +516,48 @@ const server = Hapi.server({ port: 8000 }); await server.register(Bell); server.auth.strategy('twitter', 'bell', { - provider: 'twitter', - password: 'cookie_encryption_password_secure', - clientId: TWITTER_CONSUMER_KEY, - clientSecret: TWITTER_CONSUMER_SECRET, - isSecure: false + provider: 'twitter', + password: 'cookie_encryption_password_secure', + clientId: TWITTER_CONSUMER_KEY, + clientSecret: TWITTER_CONSUMER_SECRET, + isSecure: false, }); server.route({ - method: '*', - path: '/auth/twitter', // The callback endpoint registered with the provider - handler: function (request, h) { - - if (!request.auth.isAuthenticated) { - return `Authentication failed due to: ${request.auth.error.message}`; - } - - // Perform any account lookup or registration, setup local session, - // and redirect to the application. The third-party credentials are - // stored in request.auth.credentials. Any query parameters from - // the initial request are passed back via request.auth.credentials.query. + method: '*', + path: '/auth/twitter', // The callback endpoint registered with the provider + handler: function (request, h) { + if (!request.auth.isAuthenticated) { + return `Authentication failed due to: ${request.auth.error.message}`; + } - return h.redirect('/home'); + // Perform any account lookup or registration, setup local session, + // and redirect to the application. The third-party credentials are + // stored in request.auth.credentials. Any query parameters from + // the initial request are passed back via request.auth.credentials.query. + + return h.redirect('/home'); + }, + options: { + auth: { + strategy: 'twitter', + mode: 'try', }, - options: { - auth: { - strategy: 'twitter', - mode: 'try' - } - } + }, }); ``` -To use bell, simply register the plugin and configure the strategy with `server.auth.strategy`. +To use bell, simply register the plugin and configure the strategy with `server.auth.strategy`. -`provider` is the name of the third-party provider. +`provider` is the name of the third-party provider. -`password` is the cookie encryption password. +`password` is the cookie encryption password. `clientId` is the OAuth client identifier, which is available from the provider. `clientSecret` is the OAuth client secret, which is available from the provider. -`isSecure` sets the cookie secure flag. For production, this should be set to `true`, which is the default value. +`isSecure` sets the cookie secure flag. For production, this should be set to `true`, which is the default value. ## express-validator -> joi @@ -552,9 +568,11 @@ To validate data in Express, you make use of the `express-validator` plugin. One Input validation allows you to validate any input data coming into the server, whether its parameters, payload, etc. Here is a look at how to validate a blog post entry in Express and hapi: Express: + ``` npm install express-validator ``` +
    ```js @@ -563,44 +581,44 @@ const expressValidator = require('express-validator'); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); -app.use(expressValidator()) +app.use(expressValidator()); app.post('/post', function (req, res) { - req.check('post', 'Post too long').isLength({ max: 140 }); let errors = req.validationErrors(); if (errors) { res.status(400).send(errors); } else { - res.send('Blog post added!') + res.send('Blog post added!'); } }); ``` hapi: + ``` npm install joi ``` +
    ```js -const Joi = require('joi') +const Joi = require('joi'); server.route({ - method: 'POST', - path: '/post', - handler: (request, h) => { - - return 'Blog post added!'; + method: 'POST', + path: '/post', + handler: (request, h) => { + return 'Blog post added!'; + }, + options: { + validate: { + payload: Joi.object({ + post: Joi.string().max(140), + }), }, - options: { - validate: { - payload: Joi.object({ - post: Joi.string().max(140) - }) - } - } + }, }); ``` @@ -615,30 +633,31 @@ Joi.string().min(1).max(140). As stated above, there is no clear way of doing response validation with `express-validator`. With `joi`, response validation is fast and simple. Lets have a look: hapi: + ```js const bookSchema = Joi.object({ - title: Joi.string().required(), - author: Joi.string().required(), - isbn: Joi.string().length(10), - pageCount: Joi.number(), - datePublished: Joi.date().iso() + title: Joi.string().required(), + author: Joi.string().required(), + isbn: Joi.string().length(10), + pageCount: Joi.number(), + datePublished: Joi.date().iso(), }); server.route({ - method: 'GET', - path: '/books', - handler: async function (request, h) { - - return await getBooks(); + method: 'GET', + path: '/books', + handler: async function (request, h) { + return await getBooks(); + }, + options: { + response: { + schema: Joi.array().items(bookSchema), + failAction: 'log', }, - options: { - response: { - schema: Joi.array().items(bookSchema), - failAction: 'log' - } - } + }, }); ``` + This route will return a list of books. In the `options` route property, we can specify what rules the list of books should follow. By setting the `failAction` to `log`, if there is an error, the server will log the error. ## app.set('view engine') -> vision @@ -654,17 +673,19 @@ app.set('view engine', 'pug'); ``` To set the views engine in hapi, you first must register the vision plugin, then configure `server.views`: + ```js await server.register(require('@hapi/vision')); server.views({ - engines: { - pug: require('pug') - }, - relativeTo: __dirname, - path: 'views' + engines: { + pug: require('pug'), + }, + relativeTo: __dirname, + path: 'views', }); ``` + By default, Express will look for views or templates in the `views` folder. In hapi, you specify where the views are located using the `relativeTo` and `path` properties. Like Express, hapi supports a wide variety of templating engines, such as pug, ejs, handlebars, etc. hapi has many more configurable options in `server.views`. To see the full list of capabilities, please go to the [views](/tutorials/views/?lang=en_US) tutorial. @@ -676,39 +697,40 @@ First, rendering a view in Express: ```js app.get('/', function (req, res) { - - res.render('index', { title: 'Homepage', message: 'Welcome' }); + res.render('index', { title: 'Homepage', message: 'Welcome' }); }); ``` + Using `h.view` in hapi: ```js server.route({ - method: 'GET', - path: '/', - handler: function (request, h) { - - return h.view('index', { title: 'Homepage', message: 'Welcome' }); - } + method: 'GET', + path: '/', + handler: function (request, h) { + return h.view('index', { title: 'Homepage', message: 'Welcome' }); + }, }); ``` + And using the view handler in hapi: ```js server.route({ - method: 'GET', - path: '/', - handler: { - view: { - template: 'index', - context: { - title: 'Homepage', - message: 'Welcome' - } - } - } + method: 'GET', + path: '/', + handler: { + view: { + template: 'index', + context: { + title: 'Homepage', + message: 'Welcome', + }, + }, + }, }); -``` +``` + To pass context in `h.view`, you pass an object as the second parameter. To pass context in the view handler, you use the `context` key. ## express.static() -> inert @@ -720,54 +742,56 @@ hapi gets its ability to serve static content from a plugin called [inert](/modu In Express, you would use the `res.sendFile` method to return a single file. In hapi, you can either use the `h.file()` method or the file handler, which is available via [inert](/module/inert). Once you register the inert plugin, you will be able to serve your static files: Express: + ```js app.get('/image', function (req, res) { - - res.sendFile('image.jpg', {root: './public'}); + res.sendFile('image.jpg', { root: './public' }); }); ``` hapi with `h.file()`: + ```js const server = new Hapi.Server({ - port: 3000, - routes: { - files: { - relativeTo: Path.join(__dirname, 'public') - } - } + port: 3000, + routes: { + files: { + relativeTo: Path.join(__dirname, 'public'), + }, + }, }); await server.register(require('@hapi/inert')); server.route({ - method: 'GET', - path: '/image', - handler: function (request, h) { - - return h.file('image.jpg'); - } + method: 'GET', + path: '/image', + handler: function (request, h) { + return h.file('image.jpg'); + }, }); ``` + hapi with file handler: + ```js const server = new Hapi.Server({ - port: 3000, - routes: { - files: { - relativeTo: Path.join(__dirname, 'public') - } - } + port: 3000, + routes: { + files: { + relativeTo: Path.join(__dirname, 'public'), + }, + }, }); await server.register(require('@hapi/inert')); server.route({ - method: 'GET', - path: '/image', - handler: { - file: 'image.jpg' - } + method: 'GET', + path: '/image', + handler: { + file: 'image.jpg', + }, }); ``` @@ -778,51 +802,55 @@ To serve static files in hapi, you first must tell hapi where the static files a To set up a static file server in Express, you would use the `express.static()` middleware. In hapi, you use the file handler made available by the [inert](/module/inert) plugin. You would setup the server in the same way as you did to serve a single static file, by telling where the files are located. You then would setup a route to catch all of the requests and return the correct files. Lets have a look: Express: + ```js app.use(express.static('/public')); ``` hapi: + ```js const server = new Hapi.Server({ - port: 3000, - routes: { - files: { - relativeTo: Path.join(__dirname, 'public') - } - } + port: 3000, + routes: { + files: { + relativeTo: Path.join(__dirname, 'public'), + }, + }, }); await server.register(require('@hapi/inert')); server.route({ - method: 'GET', - path: '/{param*}', - handler: { - directory: { - path: '.' - } - } + method: 'GET', + path: '/{param*}', + handler: { + directory: { + path: '.', + }, + }, }); ``` + Now, you can access any static files by going to `localhost:3000/filename`. [inert](/module/inert) has many other options and capabilities. To see what all it can do, please see the [serving static files](/tutorials/servingfiles/?lang=en_US) tutorial. ## Error Handling -> boom hapi uses the [boom](/module/boom) module to handle errors. By default, boom will return the errors in JSON format. Express on the other hand will return a text response by default, which is suboptimal with a JSON API. Lets look a 404 error response with the default settings by submitting a `GET` request to `'/hello'`, which does not exists: -Express: +Express: ```js Cannot GET /hello ``` hapi: + ```json { - "statusCode": 404, - "error": "Not Found", - "message": "Not Found" + "statusCode": 404, + "error": "Not Found", + "message": "Not Found" } ``` @@ -831,11 +859,13 @@ hapi: `boom` allows you to easily change the error message for any status code. Lets take the 404 error above and return a new message: Express: + ```js -res.status(400).send({status: 404, error: "Page not found"}); +res.status(400).send({ status: 404, error: 'Page not found' }); ``` hapi: + ```js throw Boom.notFound('Page not found'); ``` diff --git a/static/lib/tutorials/en_US/gettingstarted.md b/docs/tutorials/en_US/getting-started.md similarity index 81% rename from static/lib/tutorials/en_US/gettingstarted.md rename to docs/tutorials/en_US/getting-started.md index 15122d4b..8d4d2967 100644 --- a/static/lib/tutorials/en_US/gettingstarted.md +++ b/docs/tutorials/en_US/getting-started.md @@ -1,8 +1,13 @@ +--- +title: Getting Started +--- + + + # Getting Started _This tutorial is compatible with hapi v17 and newer_ - ## Overview This tutorial will show how to set up a basic hapi server that displays "Hello World!" in your browser. @@ -13,7 +18,7 @@ Create a new directory `myproject`, and from there: - Run: `cd myproject`, this goes into the created project folder. -- Run: `npm init` and follow the prompts. This will generate a package.json file for you. +- Run: `npm init` and follow the prompts. This will generate a package.json file for you. - Run: `npm install @hapi/hapi`, this will install the latest version of hapi as a dependency in your package.json. @@ -27,24 +32,23 @@ A very basic hapi server looks like the following: const Hapi = require('@hapi/hapi'); const init = async () => { + const server = Hapi.server({ + port: 3000, + host: 'localhost', + }); - const server = Hapi.server({ - port: 3000, - host: 'localhost' - }); - - await server.start(); - console.log('Server running on %s', server.info.uri); + await server.start(); + console.log('Server running on %s', server.info.uri); }; process.on('unhandledRejection', (err) => { - - console.log(err); - process.exit(1); + console.log(err); + process.exit(1); }); init(); ``` + First, you require hapi. Then you initialize a new `Hapi.server()` with connection details containing a port number to listen on and the host information. After that you start the server and log that it's running. When creating a server, you can provide a hostname, IP address, a Unix socket file, or Windows named pipe to bind the server to. For more details, see the API reference. @@ -61,29 +65,26 @@ After you get the server up and running, its time to add a route that will displ const Hapi = require('@hapi/hapi'); const init = async () => { - - const server = Hapi.server({ - port: 3000, - host: 'localhost' - }); - - server.route({ - method: 'GET', - path: '/', - handler: (request, h) => { - - return 'Hello World!'; - } - }); - - await server.start(); - console.log('Server running on %s', server.info.uri); + const server = Hapi.server({ + port: 3000, + host: 'localhost', + }); + + server.route({ + method: 'GET', + path: '/', + handler: (request, h) => { + return 'Hello World!'; + }, + }); + + await server.start(); + console.log('Server running on %s', server.info.uri); }; process.on('unhandledRejection', (err) => { - - console.log(err); - process.exit(1); + console.log(err); + process.exit(1); }); init(); diff --git a/static/lib/tutorials/en_US/logging.md b/docs/tutorials/en_US/logging.md similarity index 87% rename from static/lib/tutorials/en_US/logging.md rename to docs/tutorials/en_US/logging.md index 2233ca27..0646c6a3 100644 --- a/static/lib/tutorials/en_US/logging.md +++ b/docs/tutorials/en_US/logging.md @@ -1,15 +1,20 @@ +--- +title: Logging +--- + + + # Logging _This tutorial is compatible with hapi v17 and newer_ - ## Overview As with any server software, logging is very important. hapi has some built in logging methods, as well as some basic capabilities for displaying these logs. ## Built-in Methods -There are two nearly identical logging methods, `server.log(tags, [data, [timestamp]])`, and `request.log(tags, [data])`, which are to be called whenever you want to log an event in your application. +There are two nearly identical logging methods, `server.log(tags, [data, [timestamp]])`, and `request.log(tags, [data])`, which are to be called whenever you want to log an event in your application. ### request.log() @@ -23,22 +28,22 @@ For example: ```js server.route({ - method: 'GET', - path: '/', - handler: function (request, h) { - - request.log('error', 'Event error'); - return 'Hello World'; - } + method: 'GET', + path: '/', + handler: function (request, h) { + request.log('error', 'Event error'); + return 'Hello World'; + }, }); ``` -In this example, if there is a request-specific event with a tag of `error`, the event will get logged. You also send a `data` parameter of `Event error`. This can be anything you want, such as an error message or any other details. + +In this example, if there is a request-specific event with a tag of `error`, the event will get logged. You also send a `data` parameter of `Event error`. This can be anything you want, such as an error message or any other details. ### server.log() `server.log()` is used when you have no specific request in scope, for instance, just after your server has started or inside a plugin's `register()` method. -`server.log()` takes three parameters, `(tags, data, timestamp)`. The `tags` and `data` parameters are exactly the same as in `request.logs()`. The `timestamp` parameter defaults to `Date.now()` and should only be passed in if you need to override the default for some reason. +`server.log()` takes three parameters, `(tags, data, timestamp)`. The `tags` and `data` parameters are exactly the same as in `request.logs()`. The `timestamp` parameter defaults to `Date.now()` and should only be passed in if you need to override the default for some reason. ```js const Hapi = require('@hapi/hapi'); @@ -46,6 +51,7 @@ const server = Hapi.server({ port: 80 }); server.log(['test', 'error'], 'Test event'); ``` + In this example, you'll see that server will log an event with `tags` `'test'` and `'error'`. Since there is no specific request in scope in this example, you use `server.log()`. ## Retrieving and Displaying Logs @@ -54,29 +60,28 @@ The hapi server object emits events for each log event. You can use the standard ```js server.events.on('log', (event, tags) => { - - if (tags.error) { - console.log(`Server error: ${event.error ? event.error.message : 'unknown'}`); - } + if (tags.error) { + console.log(`Server error: ${event.error ? event.error.message : 'unknown'}`); + } }); ``` -In this example, you call `server.events.on()` to listen for any `log` event, in this case anything logged with `server.log()`. Events logged with `server.log()` will emit a `log` event and events logged with `request.log()` will emit a `request` event. + +In this example, you call `server.events.on()` to listen for any `log` event, in this case anything logged with `server.log()`. Events logged with `server.log()` will emit a `log` event and events logged with `request.log()` will emit a `request` event. You can retrieve all logs for a particular request at once via `request.logs`. This will be an array containing all the logged request events. You must first set the `log.collect` option to `true` on the route, otherwise this array will be empty. ```js server.route({ - method: 'GET', - path: '/', - options: { - log: { - collect: true - } + method: 'GET', + path: '/', + options: { + log: { + collect: true, }, - handler: function (request, h) { - - return 'hello'; - } + }, + handler: function (request, h) { + return 'hello'; + }, }); ``` diff --git a/static/lib/tutorials/en_US/plugins.md b/docs/tutorials/en_US/plugins.md similarity index 63% rename from static/lib/tutorials/en_US/plugins.md rename to docs/tutorials/en_US/plugins.md index a2f004a7..0fcc1268 100644 --- a/static/lib/tutorials/en_US/plugins.md +++ b/docs/tutorials/en_US/plugins.md @@ -1,11 +1,16 @@ +--- +title: Plugins +--- + + + # Plugins _This tutorial is compatible with hapi v17 and newer_ - ## Overview -hapi has an extensive and powerful plugin system that allows you to very easily break your application up into isolated pieces of business logic, and reusable utilities. You can either add an existing plugin to your application, or create your own. +hapi has an extensive and powerful plugin system that allows you to very easily break your application up into isolated pieces of business logic, and reusable utilities. You can either add an existing plugin to your application, or create your own. ## Creating a plugin @@ -17,27 +22,26 @@ A very simple plugin looks like: 'use strict'; const myPlugin = { - name: 'myPlugin', - version: '1.0.0', - register: async function (server, options) { - - // Create a route for example - - server.route({ - method: 'GET', - path: '/test', - handler: function (request, h) { - - return 'hello, world'; - } - }); + name: 'myPlugin', + version: '1.0.0', + register: async function (server, options) { + // Create a route for example + + server.route({ + method: 'GET', + path: '/test', + handler: function (request, h) { + return 'hello, world'; + }, + }); - // etc ... - await someAsyncMethods(); - } + // etc ... + await someAsyncMethods(); + }, }; ``` -Once this plugin is registered, the server will display `'hello, world'` when the user goes to route `/test`. + +Once this plugin is registered, the server will display `'hello, world'` when the user goes to route `/test`. To write a plugin as an external module, you can specify a `pkg` property: @@ -45,23 +49,21 @@ To write a plugin as an external module, you can specify a `pkg` property: 'use strict'; exports.plugin = { - pkg: require('./package.json'), - register: async function (server, options) { - - // Create a route for example - - server.route({ - method: 'GET', - path: '/test', - handler: function (request, h) { - - return 'hello, world'; - } - }); + pkg: require('./package.json'), + register: async function (server, options) { + // Create a route for example + + server.route({ + method: 'GET', + path: '/test', + handler: function (request, h) { + return 'hello, world'; + }, + }); - // etc... - await someAsyncMethods(); - } + // etc... + await someAsyncMethods(); + }, }; ``` @@ -87,40 +89,39 @@ The `options` parameter is simply whatever options the user passes to your plugi 'use strict'; exports.plugin = { - pkg: require('./package.json'), - register: async function (server, options) { - - // Create a route for example - - server.route({ - method: 'GET', - path: '/test', - handler: function (request, h) { - - const name = options.name; - return `Hello ${name}`; - } - }); + pkg: require('./package.json'), + register: async function (server, options) { + // Create a route for example + + server.route({ + method: 'GET', + path: '/test', + handler: function (request, h) { + const name = options.name; + return `Hello ${name}`; + }, + }); - // etc... - await someAsyncMethods(); - } + // etc... + await someAsyncMethods(); + }, }; ``` + Here, you grab a name from the `options` object via `options.name`. You then use that name to return a message to the user. Lets see how you pass that name to the plugin: ```javascript const start = async function () { - - await server.register({ - plugin: require('myplugin'), - options: { - name: 'Bob' - } - }); + await server.register({ + plugin: require('myplugin'), + options: { + name: 'Bob', + }, + }); }; ``` -When you register the plugin, you can pass whatever options to it with `server.register(plugins, [options])`. Here you are passing `{ name: "Bob" }` to your plugin, which as you see above, can be accessed with the `options` object when you create the plugin. + +When you register the plugin, you can pass whatever options to it with `server.register(plugins, [options])`. Here you are passing `{ name: "Bob" }` to your plugin, which as you see above, can be accessed with the `options` object when you create the plugin. ## Loading a plugin @@ -128,16 +129,15 @@ Plugins can be loaded one at a time, or as a group in an array, by the `server.r ```javascript const start = async function () { + const server = Hapi.server(); - const server = Hapi.server(); + // load one plugin - // load one plugin + await server.register(require('myplugin')); - await server.register(require('myplugin')); + // load multiple plugins - // load multiple plugins - - await server.register([require('myplugin'), require('yourplugin')]); + await server.register([require('myplugin'), require('yourplugin')]); }; ``` @@ -145,15 +145,14 @@ To pass options to your plugin, we instead pass an object with `plugin` and `opt ```javascript const start = async function () { - - const server = Hapi.server(); - - await server.register({ - plugin: require('myplugin'), - options: { - message: 'hello' - } - }); + const server = Hapi.server(); + + await server.register({ + plugin: require('myplugin'), + options: { + message: 'hello', + }, + }); }; ``` @@ -161,24 +160,26 @@ These objects can also be passed in an array: ```javascript const start = async function () { - - const server = Hapi.server(); - - await server.register([{ - plugin: require('plugin1'), - options: {} - }, { - plugin: require('plugin2'), - options: {} - }]); + const server = Hapi.server(); + + await server.register([ + { + plugin: require('plugin1'), + options: {}, + }, + { + plugin: require('plugin2'), + options: {}, + }, + ]); }; ``` ### Registration options -You may also pass a second optional parameter to `server.register()`. Documentation for this object can be found in the [API reference](/api#server.register()). +You may also pass a second optional parameter to `server.register()`. Documentation for this object can be found in the [API reference](). -The options object is used by hapi and is *not* passed to the plugin(s) being loaded. It allows you to apply `vhost` or `prefix` modifiers to any routes that your plugins register. +The options object is used by hapi and is _not_ passed to the plugin(s) being loaded. It allows you to apply `vhost` or `prefix` modifiers to any routes that your plugins register. For example, let's say we have a plugin that looks like this: @@ -186,21 +187,19 @@ For example, let's say we have a plugin that looks like this: 'use strict'; exports.plugin = { - pkg: require('./package.json'), - register: async function (server, options) { - - server.route({ - method: 'GET', - path: '/test', - handler: function (request, h) { - - return 'test passed'; - } - }); + pkg: require('./package.json'), + register: async function (server, options) { + server.route({ + method: 'GET', + path: '/test', + handler: function (request, h) { + return 'test passed'; + }, + }); - // etc... - await someAsyncMethods(); - } + // etc... + await someAsyncMethods(); + }, }; ``` @@ -208,17 +207,16 @@ Normally, when this plugin is loaded it will create a `GET` route at `/test`. Th ```javascript const start = async function () { + const server = Hapi.server(); - const server = Hapi.server(); - - await server.register(require('myplugin'), { - routes: { - prefix: '/plugins' - } - }); + await server.register(require('myplugin'), { + routes: { + prefix: '/plugins', + }, + }); }; ``` Now when the plugin is loaded, because of the `prefix` option the `GET` route will be created at `/plugins/test`. -Similarly the `options.routes.vhost` property will assign a default `vhost` configuration to any routes created by the plugins being loaded. More detail about the `vhost` configuration can be found in the [API reference](/api#server.route()). \ No newline at end of file +Similarly the `options.routes.vhost` property will assign a default `vhost` configuration to any routes created by the plugins being loaded. More detail about the `vhost` configuration can be found in the [API reference](). diff --git a/static/lib/tutorials/en_US/routing.md b/docs/tutorials/en_US/routing.md similarity index 78% rename from static/lib/tutorials/en_US/routing.md rename to docs/tutorials/en_US/routing.md index 2d274e9d..6a346899 100644 --- a/static/lib/tutorials/en_US/routing.md +++ b/docs/tutorials/en_US/routing.md @@ -1,7 +1,12 @@ +--- +title: Routing +--- + + + # Routing _This tutorial is compatible with hapi v17 and newer_ - ## Overview @@ -9,12 +14,11 @@ When defining a route in hapi, you need three basic elements: the path, the meth ```js server.route({ - method: 'GET', - path: '/', - handler: function (request, h) { - - return 'Hello World!'; - } + method: 'GET', + path: '/', + handler: function (request, h) { + return 'Hello World!'; + }, }); ``` @@ -24,12 +28,11 @@ The route above responds to a `GET` request to `/` with the string `Hello World! ```js server.route({ - method: ['PUT', 'POST'], - path: '/', - handler: function (request, h) { - - return 'I did something!'; - } + method: ['PUT', 'POST'], + path: '/', + handler: function (request, h) { + return 'I did something!'; + }, }); ``` @@ -39,19 +42,18 @@ The path option must be a string, though it can contain named parameters. To nam ```js server.route({ - method: 'GET', - path: '/hello/{user}', - handler: function (request, h) { - - return `Hello ${request.params.user}!`; - } + method: 'GET', + path: '/hello/{user}', + handler: function (request, h) { + return `Hello ${request.params.user}!`; + }, }); ``` Note: It is best practice to always return escaped and validated user inputs such as query/path parameters. This is done to prevent echo or XSS attacks. One way to do this is to use [Hoek](/module/hoek) `escapeHtml()` method. With escaping in place, the above example would look like the following: ```js -return `Hello ${Hoek.escapeHtml(request.params.user)}!` +return `Hello ${Hoek.escapeHtml(request.params.user)}!`; ``` As you can see above, you have the string `{user}` in your path, which means you're asking for that segment of the path to be assigned to a named parameter. These parameters are stored in the object `request.params` within the handler. Since you named your parameter user, you are able to access the value with the property `request.params.user`, after URI encoding it so as to prevent content injection attacks. For example, going to `/hello/ferris` in your browser, you will see `Hello ferris!`. @@ -62,16 +64,16 @@ In the above example, the user parameter is required: a request to `/hello/bob` ```js server.route({ - method: 'GET', - path: '/hello/{user?}', - handler: function (request, h) { - - const user = request.params.user ? request.params.user : 'stranger'; + method: 'GET', + path: '/hello/{user?}', + handler: function (request, h) { + const user = request.params.user ? request.params.user : 'stranger'; - return `Hello ${user}!`; - } + return `Hello ${user}!`; + }, }); ``` + Now a request to `/hello/sloan` will reply with `Hello sloan!` and a request to just `/hello` will reply with `Hello stranger!`. It is important to be aware that only the last named parameter in a path can be optional. That means that `/{one?}/{two}/` is an invalid path, since in this case there is another parameter after the optional one. You may also have a named parameter covering only part of a segment of the path for instance `/{filename}.jpg` is valid. You may also have multiple parameters per segment provided there is non-parameter separator between them, meaning `/{filename}.{ext}` is valid whereas `/{filename}{ext}` is not. ## Multi-Segment Parameters @@ -80,16 +82,16 @@ Along with optional path parameters, you can also allow parameters that match mu ```js server.route({ - method: 'GET', - path: '/hello/{user*2}', - handler: function (request, h) { - - const userParts = request.params.user.split('/'); + method: 'GET', + path: '/hello/{user*2}', + handler: function (request, h) { + const userParts = request.params.user.split('/'); - return `Hello ${userParts[0]} ${userParts[1]}!`; - } + return `Hello ${userParts[0]} ${userParts[1]}!`; + }, }); ``` + With this configuration, a request to `/hello/john/doe` will reply with the string `Hello john doe!`. The important thing to note here is that the parameter is actually the string `"john/doe"`. That's why you did a split on that character to get the two separate parts. The number after the asterisk represents how many path segments should be assigned to the parameter. You can also omit the number entirely, and the parameter will match any number of segments available. Like the optional parameters, a wildcard parameter (for example `/{files*}`) may only appear as the last parameter in your path. When determining what handler to use for a particular request, hapi searches paths in order from most specific to least specific. That means if you have two routes, one with the path `/filename.jpg` and a second route `/filename.{ext}` a request to `/filename.jpg` will match the first route, and not the second. This also means that a route with the path `/{files*}` will be the last route tested, and will only match if all other routes fail. @@ -104,68 +106,66 @@ There are two query parameters here, `name=ferris` and `location=chicago`. In ha ```js server.route({ - method: 'GET', - path: '/', - handler: function (request, h) { - - return `Hello ${request.query.name}!`; - } + method: 'GET', + path: '/', + handler: function (request, h) { + return `Hello ${request.query.name}!`; + }, }); ``` + Here, you simply access the `name` query parameter and return it in the handler, which would read `Hello ferris!`. For more complex query structures, you may opt to use the `qs` module. Consider the following: ```js server.route({ - method: 'GET', - path: '/', - handler: function (request, h) { - - return request.query; - } + method: 'GET', + path: '/', + handler: function (request, h) { + return request.query; + }, }); ``` -If you sent the request `localhost:3000?foo[bar]=baz`, hapi, by default would return `{ "foo[bar]": "baz" }`. -With the [qs](https://github.com/ljharb/qs) module, you can parse the query string out. An example: +If you sent the request `localhost:3000?foo[bar]=baz`, hapi, by default would return `{ "foo[bar]": "baz" }`. + +With the [qs](https://github.com/ljharb/qs) module, you can parse the query string out. An example: ```js const Hapi = require('@hapi/hapi'); const Qs = require('qs'); const server = Hapi.server({ - port: 3000, - host: 'localhost', - query: { - parser: (query) => Qs.parse(query) - } + port: 3000, + host: 'localhost', + query: { + parser: (query) => Qs.parse(query), + }, }); server.route({ - method: 'GET', - path: '/', - handler: function (request, h) { - - return request.query; - } + method: 'GET', + path: '/', + handler: function (request, h) { + return request.query; + }, }); const init = async () => { - - await server.start(); - console.log('Server running on %s', server.info.uri); + await server.start(); + console.log('Server running on %s', server.info.uri); }; process.on('unhandledRejection', (err) => { - - console.log(err); - process.exit(1); + console.log(err); + process.exit(1); }); init(); ``` -Here, you first require the [qs](https://github.com/ljharb/qs) module. + +Here, you first require the [qs](https://github.com/ljharb/qs) module. Second, you set the query parameters parser method by setting the `server.options.query.parser` value. In this case, you use the `Qs.parse()` method where `query` is an object containing the incoming `request.query` parameters. Now, anything coming into `request.query` will be parsed with `Qs.parse()`. @@ -178,7 +178,8 @@ Lastly, you returned the parsed query string, which would now be: } } ``` -Note: In the above example, you used the [qs](https://github.com/ljharb/qs) module to handle our parsing, but any parser will do, be it from `npm` or even custom. Just be aware that the method must return an object where each key is a parameter and matching value is the parameter value. + +Note: In the above example, you used the [qs](https://github.com/ljharb/qs) module to handle our parsing, but any parser will do, be it from `npm` or even custom. Just be aware that the method must return an object where each key is a parameter and matching value is the parameter value. ## Request Payload @@ -186,16 +187,16 @@ Anytime you send request data to your API, you will be able to access this data ```js server.route({ - method: 'POST', - path: '/signup', - handler: function (request, h) { - - const payload = request.payload; + method: 'POST', + path: '/signup', + handler: function (request, h) { + const payload = request.payload; - return `Welcome ${payload.username}!`; - } + return `Welcome ${payload.username}!`; + }, }); ``` + In the above example, the handler receives data via `request.payload`. In this case, the `request.payload` contains an object that stores user sign up data: `{ username: 'ferris', password: 'password' }` @@ -224,26 +225,26 @@ Here we will look at some options of validating with Joi. ```js server.route({ - method: 'POST', - path: '/signup', - handler: function (request, h) { - - const payload = request.payload; - - return `Welcome ${payload.username}!`; + method: 'POST', + path: '/signup', + handler: function (request, h) { + const payload = request.payload; + + return `Welcome ${payload.username}!`; + }, + options: { + auth: false, + validate: { + payload: { + username: Joi.string().min(1).max(20), + password: Joi.string().min(7), + }, }, - options: { - auth: false, - validate: { - payload: { - username: Joi.string().min(1).max(20), - password: Joi.string().min(7) - } - } - } + }, }); ``` -The first property under `options` is `auth`. `auth` will set the authentication configuration for the route. Since this route is for a new user signing up, you will disable authentication. + +The first property under `options` is `auth`. `auth` will set the authentication configuration for the route. Since this route is for a new user signing up, you will disable authentication. The second property is `validate`. This allows you to set validation rules for various request components, such as `headers`, `params`, `payload`, and `failAction`. You use the [joi](https://joi.dev) package to validate the `request.payload`. For more info, please check the validation tutorial. @@ -259,28 +260,28 @@ const Hapi = require('@hapi/hapi'); const internals = {}; const init = async () => { + const server = Hapi.server({ + port: 3000, + host: 'localhost', + }); + + server.route({ + method: '*', + path: '/{any*}', + handler: function (request, h) { + return h.response('404 Error! Page Not Found!').code(404); + }, + }); - const server = Hapi.server({ - port: 3000, - host: 'localhost' - }); - - server.route({ - method: '*', - path: '/{any*}', - handler: function (request, h) { - return h.response('404 Error! Page Not Found!').code(404); - } - }); - - await server.start(); - console.log('Server running on %s', server.info.uri); + await server.start(); + console.log('Server running on %s', server.info.uri); }; init(); ``` + First, you configure our server. -Next, you setup your route that return your custom 404 response. You use a wildcard, `*`, for the method, so it covers all available methods. Then, you use a very broad, generic path, `'/{any*}`. This will catch any route that our other routes do not. hapi routes will go the the most specific path first, then get broader, till it finds a match. For example, `localhost:3000/login` will go to the `/login` route and not the `/{any*}` route. +Next, you setup your route that return your custom 404 response. You use a wildcard, `*`, for the method, so it covers all available methods. Then, you use a very broad, generic path, `'/{any*}`. This will catch any route that our other routes do not. hapi routes will go the the most specific path first, then get broader, till it finds a match. For example, `localhost:3000/login` will go to the `/login` route and not the `/{any*}` route. Lastly, you return a custom 404 response in your handler, letting your users know that the resource they are asking for could not be found. diff --git a/static/lib/tutorials/en_US/servermethods.md b/docs/tutorials/en_US/server-methods.md similarity index 76% rename from static/lib/tutorials/en_US/servermethods.md rename to docs/tutorials/en_US/server-methods.md index d63f7781..94bab809 100644 --- a/static/lib/tutorials/en_US/servermethods.md +++ b/docs/tutorials/en_US/server-methods.md @@ -1,11 +1,16 @@ +--- +title: Server Methods +--- + + + # Server Methods _This tutorial is compatible with hapi v17 and newer_ - ## Overview -Server methods are a useful way of sharing functions by attaching them to your server object rather than requiring a common module everywhere it is needed. Server methods are also used heavily for caching purposes. Since server methods leverage hapi's native caching, they can help reduce your boilerplate to a minimum. See the caching tutorial for more. To register a server method, you call [`server.method()`](/api#server.method()). There are two different ways to call this function. You can call it with the signature `server.method(name, method, [options])`, or you can call it with the signature `server.method(method)`, where `method` is an object with `name`, `method`, and `options` parameters (note that you may also pass an array of these objects). +Server methods are a useful way of sharing functions by attaching them to your server object rather than requiring a common module everywhere it is needed. Server methods are also used heavily for caching purposes. Since server methods leverage hapi's native caching, they can help reduce your boilerplate to a minimum. See the caching tutorial for more. To register a server method, you call [`server.method()`](). There are two different ways to call this function. You can call it with the signature `server.method(name, method, [options])`, or you can call it with the signature `server.method(method)`, where `method` is an object with `name`, `method`, and `options` parameters (note that you may also pass an array of these objects). ## server.method() @@ -13,28 +18,28 @@ The first way to call `server.method()` is with the signature `server.method(nam ```js const add = function (x, y) { - - return x + y; + return x + y; }; server.method('add', add, {}); ``` -Here, you create a function called `add`, which takes two parameters and adds them together. Then you call `server.method()` with the name of the method being `add`, the method you are using, the one we just created called `add`, and no options. + +Here, you create a function called `add`, which takes two parameters and adds them together. Then you call `server.method()` with the name of the method being `add`, the method you are using, the one we just created called `add`, and no options. The second way to call `server.method()` is with the signature `server.method(method)`: ```js const add = function (x, y) { - - return x + y; + return x + y; }; server.method({ - name: 'add', - method: add, - options: {} + name: 'add', + method: add, + options: {}, }); ``` + You create the same function again, called `add`. When you register it this time, configure the `method` object. This case, `name` is the name of the method, `method` is the method you are using, and `options` is an object to configure various options. ### Name @@ -53,9 +58,8 @@ The `method` parameter is the actual function to call when the method is invoked ```js const add = async function (x, y) { - - const result = await someLongRunningFunction(x, y); - return result; + const result = await someLongRunningFunction(x, y); + return result; }; server.method('add', add, {}); @@ -73,25 +77,25 @@ A major advantage of server methods is that they may leverage hapi's native cach ```javascript server.method('add', add, { - cache: { - expiresIn: 60000, - expiresAt: '20:30', - staleIn: 30000, - staleTimeout: 10000, - generateTimeout: 100 - } + cache: { + expiresIn: 60000, + expiresAt: '20:30', + staleIn: 30000, + staleTimeout: 10000, + generateTimeout: 100, + }, }); ``` The parameters mean: -* `expiresIn`: relative expiration expressed in the number of milliseconds since the item was saved in the cache. Cannot be used together with `expiresAt`. -* `expiresAt`: time of day expressed in 24h notation using the 'HH:MM' format, at which point all cache records for the route expire. Uses local time. Cannot be used together with `expiresIn`. -* `staleIn`: number of milliseconds to mark an item stored in cache as stale and attempt to regenerate it. Must be less than `expiresIn`. -* `staleTimeout`: number of milliseconds to wait before returning a stale value while generateFunc is generating a fresh value. -* `generateTimeout`: number of milliseconds to wait before returning a timeout error when it takes too long to return a value. When the value is eventually returned, it is stored in the cache for future requests. -* `segment`: an optional segment name used to isolate cache items. -* `cache`: an optional string with the name of the cache connection configured on your server to use +- `expiresIn`: relative expiration expressed in the number of milliseconds since the item was saved in the cache. Cannot be used together with `expiresAt`. +- `expiresAt`: time of day expressed in 24h notation using the 'HH:MM' format, at which point all cache records for the route expire. Uses local time. Cannot be used together with `expiresIn`. +- `staleIn`: number of milliseconds to mark an item stored in cache as stale and attempt to regenerate it. Must be less than `expiresIn`. +- `staleTimeout`: number of milliseconds to wait before returning a stale value while generateFunc is generating a fresh value. +- `generateTimeout`: number of milliseconds to wait before returning a timeout error when it takes too long to return a value. When the value is eventually returned, it is stored in the cache for future requests. +- `segment`: an optional segment name used to isolate cache items. +- `cache`: an optional string with the name of the cache connection configured on your server to use More information on the caching options can be found in the [API Reference](/api#server.methods) as well as the documentation for [catbox](/module/catbox#policy). @@ -99,19 +103,18 @@ You can override the `ttl` (time-to-live) of a server method result per-invocati ```js const add = async function (x, y, flags) { + const result = await someLongRunningFunction(x, y); - const result = await someLongRunningFunction(x, y); - - flags.ttl = 5 * 60 * 1000; // 5 mins + flags.ttl = 5 * 60 * 1000; // 5 mins - return result; + return result; }; server.method('add', add, { - cache: { - expiresIn: 2000, - generateTimeout: 100 - } + cache: { + expiresIn: 2000, + generateTimeout: 100, + }, }); ``` @@ -123,19 +126,17 @@ In addition to the above options, you may also define a custom function used to ```javascript const sum = function (array) { + let total = 0; - let total = 0; - - array.forEach((item) => { + array.forEach((item) => { + total += item; + }); - total += item; - }); - - return total; + return total; }; server.method('sum', sum, { - generateKey: (array) => array.join(',') + generateKey: (array) => array.join(','), }); ``` @@ -147,10 +148,9 @@ The last option available to server methods is `bind`. The `bind` option changes ```javascript const lookup = async function (id) { + // calls myDB.getOne - // calls myDB.getOne - - return await this.getOne({ id }); + return await this.getOne({ id }); }; server.method('lookup', lookup, { bind: myDB }); @@ -162,19 +162,18 @@ To call the server methods we registered above, you would use `server.methods()` ```js const add = function (x, y) { - - return x + y; + return x + y; }; server.method({ - name: 'add', - method: add, - options: {} + name: 'add', + method: add, + options: {}, }); ``` To use this method, simply call `server.methods()` ```js -server.methods.add(1, 2); // 3 +server.methods.add(1, 2); // 3 ``` diff --git a/static/lib/tutorials/en_US/servingfiles.md b/docs/tutorials/en_US/serving-files.md similarity index 68% rename from static/lib/tutorials/en_US/servingfiles.md rename to docs/tutorials/en_US/serving-files.md index 0b7b44e4..9c0953af 100644 --- a/static/lib/tutorials/en_US/servingfiles.md +++ b/docs/tutorials/en_US/serving-files.md @@ -1,11 +1,16 @@ +--- +title: Serving Files +--- + + + # Serving Static Content _This tutorial is compatible with hapi v17 and newer_ - ## Overview -Inevitably while building any web application, the need arises to serve a simple file from disk. There is a hapi plugin called [inert](/module/inert) that adds this functionality to hapi through the use of additional handlers. +Inevitably while building any web application, the need arises to serve a simple file from disk. There is a hapi plugin called [inert](/module/inert) that adds this functionality to hapi through the use of additional handlers. First you need to install and add `inert` as a dependency to your project: @@ -13,7 +18,7 @@ First you need to install and add `inert` as a dependency to your project: ## Inert -The `inert` plugin provides new handler methods for serving static files and directories, as well as adding a `h.file()` method to the toolkit, which can respond with file based resources. +The `inert` plugin provides new handler methods for serving static files and directories, as well as adding a `h.file()` method to the toolkit, which can respond with file based resources. ## Relative paths @@ -26,29 +31,27 @@ const Hapi = require('@hapi/hapi'); const Path = require('path'); const start = async () => { + const server = Hapi.server({ + routes: { + files: { + relativeTo: Path.join(__dirname, 'public'), + }, + }, + }); - const server = Hapi.server({ - routes: { - files: { - relativeTo: Path.join(__dirname, 'public') - } - } - }); - - await server.register(require('@hapi/inert')); - - server.route({ - method: 'GET', - path: '/picture.jpg', - handler: function (request, h) { + await server.register(require('@hapi/inert')); - return h.file('picture.jpg'); - } - }); + server.route({ + method: 'GET', + path: '/picture.jpg', + handler: function (request, h) { + return h.file('picture.jpg'); + }, + }); - await server.start(); + await server.start(); - console.log('Server running at:', server.info.uri); + console.log('Server running at:', server.info.uri); }; start(); @@ -62,28 +65,27 @@ Now, let's see how to use the [`h.file()`](/module/inert/api#hfilepath-options) ```javascript const start = async () => { + const server = Hapi.server(); - const server = Hapi.server(); - - await server.register(require('@hapi/inert')); - - server.route({ - method: 'GET', - path: '/picture.jpg', - handler: function (request, h) { + await server.register(require('@hapi/inert')); - return h.file('/path/to/picture.jpg'); - } - }); + server.route({ + method: 'GET', + path: '/picture.jpg', + handler: function (request, h) { + return h.file('/path/to/picture.jpg'); + }, + }); - await server.start(); + await server.start(); - console.log('Server running at:', server.info.uri); + console.log('Server running at:', server.info.uri); }; start(); ``` -By requiring the `inert` plugin, you get access `h.file()` method. Here, you tell `h.file()` the path of the image you want to return. In this case, `'/path/to/picture.jpg'`. + +By requiring the `inert` plugin, you get access `h.file()` method. Here, you tell `h.file()` the path of the image you want to return. In this case, `'/path/to/picture.jpg'`. ## File handler @@ -91,11 +93,11 @@ An alternative to using the `h.file()` method would be to use the `file` handler ```javascript server.route({ - method: 'GET', - path: '/picture.jpg', - handler: { - file: 'picture.jpg' - } + method: 'GET', + path: '/picture.jpg', + handler: { + file: 'picture.jpg', + }, }); ``` @@ -105,13 +107,13 @@ You can also specify the parameter as a function that accepts the `request` obje ```javascript server.route({ - method: 'GET', - path: '/{filename}', - handler: { - file: function (request) { - return request.params.filename; - } - } + method: 'GET', + path: '/{filename}', + handler: { + file: function (request) { + return request.params.filename; + }, + }, }); ``` @@ -119,16 +121,16 @@ It can also be an object with a `path` property. When using the object form of t ```javascript server.route({ - method: 'GET', - path: '/script.js', - handler: { - file: { - path: 'script.js', - filename: 'client.js', // override the filename in the Content-Disposition header - mode: 'attachment', // specify the Content-Disposition is an attachment - lookupCompressed: true // allow looking for script.js.gz if the request allows it - } - } + method: 'GET', + path: '/script.js', + handler: { + file: { + path: 'script.js', + filename: 'client.js', // override the filename in the Content-Disposition header + mode: 'attachment', // specify the Content-Disposition is an attachment + lookupCompressed: true, // allow looking for script.js.gz if the request allows it + }, + }, }); ``` @@ -138,13 +140,13 @@ In addition to the `file` handler, inert also adds a `directory` handler that al ```javascript server.route({ - method: 'GET', - path: '/{param*}', - handler: { - directory: { - path: 'directory-path-here' - } - } + method: 'GET', + path: '/{param*}', + handler: { + directory: { + path: 'directory-path-here', + }, + }, }); ``` @@ -154,14 +156,14 @@ The above route will respond to any request by looking for a matching filename i ```javascript server.route({ - method: 'GET', - path: '/{param*}', - handler: { - directory: { - path: 'directory-path-here', - index: ['index.html', 'default.html'] - } - } + method: 'GET', + path: '/{param*}', + handler: { + directory: { + path: 'directory-path-here', + index: ['index.html', 'default.html'], + }, + }, }); ``` @@ -169,16 +171,17 @@ A request to `/` will now first try to load `/index.html`, then `/default.html`. ```javascript server.route({ - method: 'GET', - path: '/{param*}', - handler: { - directory: { - path: 'directory-path-here', - listing: true - } - } + method: 'GET', + path: '/{param*}', + handler: { + directory: { + path: 'directory-path-here', + listing: true, + }, + }, }); ``` + Now a request to `/` will reply with HTML showing the contents of the directory. When using the directory handler with listing enabled, by default hidden files will not be shown in the listing. That can be changed by setting the `showHidden` option to `true`. Like the file handler, the directory handler also has a `lookupCompressed` option to serve precompressed files when possible. You can also set a `defaultExtension` that will be appended to requests if the original path is not found. This means that a request for `/bacon` will also try the file `/bacon.html`. ## Static file server @@ -191,39 +194,38 @@ const Hapi = require('@hapi/hapi'); const Inert = require('@hapi/inert'); const init = async () => { + const server = new Hapi.Server({ + port: 3000, + routes: { + files: { + relativeTo: Path.join(__dirname, 'public'), + }, + }, + }); + + await server.register(Inert); + + server.route({ + method: 'GET', + path: '/{param*}', + handler: { + directory: { + path: '.', + redirectToSlash: true, + }, + }, + }); + + await server.start(); - const server = new Hapi.Server({ - port: 3000, - routes: { - files: { - relativeTo: Path.join(__dirname, 'public') - } - } - }); - - await server.register(Inert); - - server.route({ - method: 'GET', - path: '/{param*}', - handler: { - directory: { - path: '.', - redirectToSlash: true - } - } - }); - - await server.start(); - - console.log('Server running at:', server.info.uri); + console.log('Server running at:', server.info.uri); }; init(); ``` + The first thing you do is require both `inert` and `path`. As you will see, you will need both of these to get our file server up and running. -Next, you configure `server.options.routes`. You set the location the server will look for the static files by setting the `relativeTo` option. +Next, you configure `server.options.routes`. You set the location the server will look for the static files by setting the `relativeTo` option. After your server is configured, you then register the `inert` plugin. This will allow you to have access to the `directory` handler, which will enable you to server your files. In the `directory` handler, you configure `path`, which is required, to look in the entire `public` directory which you specified in the `relativeTo` option. The second option is the `redirectToSlash` option. By setting this to `true`, you tell the server to redirect requests without trailing slashes to the same path with those with the trailing slash. - diff --git a/static/lib/tutorials/en_US/testing.md b/docs/tutorials/en_US/testing.md similarity index 82% rename from static/lib/tutorials/en_US/testing.md rename to docs/tutorials/en_US/testing.md index f7c2bf67..33e7cd36 100644 --- a/static/lib/tutorials/en_US/testing.md +++ b/docs/tutorials/en_US/testing.md @@ -1,9 +1,15 @@ +--- +title: Testing +--- + + + # Testing _This tutorial is compatible with hapi v17 and newer_ - ## Overview + Hapi is designed for creating robust, testable applications. To this end, Hapi includes the ability to test routes without having to actually start a server, completely avoiding the time overheads and added complexity of the TCP protocol. This tutorial goes into a basic setup for testing routes, and outlines one possible setup for a testable application using [lab](/module/lab) and [code](/module/code). @@ -34,38 +40,35 @@ Taking the server example from the Getting Started tutorial, we make a minor mod const Hapi = require('@hapi/hapi'); const server = Hapi.server({ - port: 3000, - host: 'localhost' + port: 3000, + host: 'localhost', }); server.route({ method: 'GET', path: '/', handler: function () { - - return 'Hello World!'; - } + return 'Hello World!'; + }, }); exports.init = async () => { - - await server.initialize(); - return server; + await server.initialize(); + return server; }; exports.start = async () => { - - await server.start(); - console.log(`Server running at: ${server.info.uri}`); - return server; + await server.start(); + console.log(`Server running at: ${server.info.uri}`); + return server; }; process.on('unhandledRejection', (err) => { - - console.log(err); - process.exit(1); + console.log(err); + process.exit(1); }); ``` + You now export, but do not call, `init()` and `start()`. This will allow you to initialize and start the server from different files. The `init()` function will initialize the server (starts the caches, finalizes plugin registration) but does not start the server. This is what you will use in your tests. The `start()` function will actually start the server. This is what you will use in our main entry-point for the server: ```js @@ -75,13 +78,14 @@ const { start } = require('lib/server'); start(); ``` + What you've created here is a way of starting the server normally by calling its start function in our entry-point, and exposing a port for external HTTP traffic, but you've also got a module which doesn't do anything by default, which you can use in our tests. ## Writing a Route Test In this example you'll use [lab](/module/lab), but the same method can be used for any testing tool such as [Mocha](https://mochajs.org/), [Jest](https://jestjs.io/), [Tap](https://www.node-tap.org/), [Ava](https://github.com/avajs) etc. -By default, `lab` loads all the '*.js' files inside the local `test` directory and executes the tests found. To use different directories or files, pass the file or directories as arguments: +By default, `lab` loads all the '\*.js' files inside the local `test` directory and executes the tests found. To use different directories or files, pass the file or directories as arguments: `$ lab unit.js` @@ -92,34 +96,35 @@ To get started, create a file called `example.test.js` in the `test` directory: const Lab = require('@hapi/lab'); const { expect } = require('@hapi/code'); -const { afterEach, beforeEach, describe, it } = exports.lab = Lab.script(); +const { afterEach, beforeEach, describe, it } = (exports.lab = Lab.script()); const { init } = require('../lib/server'); describe('GET /', () => { - let server; + let server; - beforeEach(async () => { - server = await init(); - }); + beforeEach(async () => { + server = await init(); + }); - afterEach(async () => { - await server.stop(); - }); + afterEach(async () => { + await server.stop(); + }); - it('responds with 200', async () => { - const res = await server.inject({ - method: 'get', - url: '/' - }); - expect(res.statusCode).to.equal(200); + it('responds with 200', async () => { + const res = await server.inject({ + method: 'get', + url: '/', }); + expect(res.statusCode).to.equal(200); + }); }); ``` -Here you are testing whether or not our `'GET'` route will respond with a `200` status code. You first call `describe()` to provide the structure of your test. `describe()` takes two parameters, a description of the test, and the function that will setup the test. + +Here you are testing whether or not our `'GET'` route will respond with a `200` status code. You first call `describe()` to provide the structure of your test. `describe()` takes two parameters, a description of the test, and the function that will setup the test. Note that you call `init` rather than `start` to set up the server, which means that the server starts, but does not listen on a socket. After each test you call `stop` to cleanup and stop the server. -The `it()` function is what will run your test. `it()` takes two parameters, a description of a successful test, and a function to run the test. +The `it()` function is what will run your test. `it()` takes two parameters, a description of a successful test, and a function to run the test. You will note the use of `inject` on the server. `inject` uses [Shot](/module/shot) to `inject` a request directly into hapi's route handler. This is the magic which allows us to test HTTP methods. diff --git a/static/lib/tutorials/en_US/validation.md b/docs/tutorials/en_US/validation.md similarity index 67% rename from static/lib/tutorials/en_US/validation.md rename to docs/tutorials/en_US/validation.md index c6b0176e..fa9c344f 100644 --- a/static/lib/tutorials/en_US/validation.md +++ b/docs/tutorials/en_US/validation.md @@ -1,8 +1,13 @@ +--- +title: Validation +--- + + + # Validation _This tutorial is compatible with hapi v17 and newer; and joi v16 and newer_ - ## Overview Validating data can be very helpful in making sure that your application is stable and secure. hapi allows this functionality by using the module [Joi](https://joi.dev), which allows you to create your validations with a simple and clear object syntax. @@ -21,28 +26,29 @@ Then, you must import it to your project: The first type of validation hapi can perform is input validation. This is defined in the `options` object on a route, and is able to validate headers, path parameters, query parameters, and payload data. Note: In the below examples, you'll see that we give a JS object to `route.options.validate`. The `validate` option has a default value of: - ```json5 - { - headers: true, - params: true, - query: true, - payload: true, - state: true, - failAction: 'error' - } - ``` - -If a key has a value of `true`, there will be no validation. Keys can also be either a validation function using the signature `async function(value, options)` or a `joi` validation object for its properties. The latter allows you to set `joi` options for that particular schema. Here is a partial rewrite of the [Query Parameters](#queryparams) example: +```json5 +{ + headers: true, + params: true, + query: true, + payload: true, + state: true, + failAction: 'error', +} +``` + +If a key has a value of `true`, there will be no validation. Keys can also be either a validation function using the signature `async function(value, options)` or a `joi` validation object for its properties. The latter allows you to set `joi` options for that particular schema. Here is a partial rewrite of the [Query Parameters](#queryparams) example: ```js options: { - validate: { - query: Joi.object({ - limit: Joi.number().integer().min(1).max(100).default(10) - }).options({ stripUnknown: true }); - } + validate: { + query: Joi.object({ + limit: Joi.number().integer().min(1).max(100).default(10), + }).options({ stripUnknown: true }); + } } ``` + Look [here](https://joi.dev) for details about such options. ### Path parameters @@ -51,19 +57,18 @@ The first input type that `joi` can validate is path parameters. Consider the fo ```javascript server.route({ - method: 'GET', - path: '/hello/{name}', - handler: function (request, h) { - - return `Hello ${request.params.name}!`; + method: 'GET', + path: '/hello/{name}', + handler: function (request, h) { + return `Hello ${request.params.name}!`; + }, + options: { + validate: { + params: Joi.object({ + name: Joi.string().min(3).max(10), + }), }, - options: { - validate: { - params: Joi.object({ - name: Joi.string().min(3).max(10) - }) - } - } + }, }); ``` @@ -73,9 +78,9 @@ With this configuration, if you make a request to `/hello/jennifer` you will get ```json { - "error": "Bad Request", - "message": "Invalid request params input", - "statusCode": 400 + "error": "Bad Request", + "message": "Invalid request params input", + "statusCode": 400 } ``` @@ -83,25 +88,24 @@ Likewise, if you were to make a request to `/hello/thisnameiswaytoolong`, you'd ### Query parameters -To validate query parameters, you simply specify a `validate.query` option in the route's options, and you will get similar effects. By default hapi will not validate anything. If you specify a validator for even one query parameter, that means you *must* specify a validator for all possible query parameters that you would like to accept. +To validate query parameters, you simply specify a `validate.query` option in the route's options, and you will get similar effects. By default hapi will not validate anything. If you specify a validator for even one query parameter, that means you _must_ specify a validator for all possible query parameters that you would like to accept. For example, if you have a route that returns a list of blog posts and you would like the user to limit their result set by count, you could use the following configuration: ```javascript server.route({ - method: 'GET', - path: '/posts', - handler: function (request, h) { - - return posts.slice(0, request.query.limit); + method: 'GET', + path: '/posts', + handler: function (request, h) { + return posts.slice(0, request.query.limit); + }, + options: { + validate: { + query: Joi.object({ + limit: Joi.number().integer().min(1).max(100).default(10), + }), }, - options: { - validate: { - query: Joi.object({ - limit: Joi.number().integer().min(1).max(100).default(10) - }) - } - } + }, }); ``` @@ -111,63 +115,63 @@ You get an error because the `offset` parameter is not allowed. That's because y ### Payload parameters -Also valid is the `validate.payload` option, which will validate payload data sent to a route by the user. It works exactly the same way as query parameters, in that if you validate one key, you must validate them all. Here is an example: +Also valid is the `validate.payload` option, which will validate payload data sent to a route by the user. It works exactly the same way as query parameters, in that if you validate one key, you must validate them all. Here is an example: ```js server.route({ - method: 'POST', - path: '/post', - handler: function (request, h) { - - return 'Blog post added'; + method: 'POST', + path: '/post', + handler: function (request, h) { + return 'Blog post added'; + }, + options: { + validate: { + payload: Joi.object({ + post: Joi.string().min(1).max(140), + date: Joi.date().required(), + }), }, - options: { - validate: { - payload: Joi.object({ - post: Joi.string().min(1).max(140), - date: Joi.date().required() - }) - } - } + }, }); ``` -The above example is a very basic route that handles an incoming blog post. The user submits the blog post and date in the `request.payload` object. Typically, this would then be stored to a database. Before that can happen though, we must validate the payload. First, `joi` states that `post` must be a minimum of 1 character, and a maximum of 140 characters. It also states that `date` must be a valid date in the MM-DD-YYYY format and is required. + +The above example is a very basic route that handles an incoming blog post. The user submits the blog post and date in the `request.payload` object. Typically, this would then be stored to a database. Before that can happen though, we must validate the payload. First, `joi` states that `post` must be a minimum of 1 character, and a maximum of 140 characters. It also states that `date` must be a valid date in the MM-DD-YYYY format and is required. If any of payload fails validation, the following error will be thrown: ```json { - "error": "Bad Request", - "message": "Invalid request payload input", - "statusCode": 400 + "error": "Bad Request", + "message": "Invalid request payload input", + "statusCode": 400 } ``` ### Headers -You may validate incoming headers as well, with a `validate.headers` option. For example: +You may validate incoming headers as well, with a `validate.headers` option. For example: ```js server.route({ - method: 'GET', - path:'/hello/{name}', - handler: (request, h) => { - - return `Hello ${request.params.name}!`; + method: 'GET', + path: '/hello/{name}', + handler: (request, h) => { + return `Hello ${request.params.name}!`; + }, + options: { + validate: { + headers: Joi.object({ + cookie: Joi.string().required(), + }), + options: { + allowUnknown: true, + }, }, - options: { - validate: { - headers: Joi.object({ - cookie: Joi.string().required() - }), - options: { - allowUnknown: true - } - } - } + }, }); ``` -Here, you are validating the cookie header as a string and making sure it is required. The `allowUnknown` option allows other incoming headers to be accepted without being validated. + +Here, you are validating the cookie header as a string and making sure it is required. The `allowUnknown` option allows other incoming headers to be accepted without being validated. ## Output @@ -182,38 +186,39 @@ hapi supports quite a few options to fine-tune output validation. Here are a few ### response.failAction You can choose what to do when response validation fails by setting `response.failAction` to one of the following: -* `error`: send an Internal Server Error (500) response (default) -* `log`: just log the offense and send the response as-is -* `ignore`: take no action and continue processing the request -* A lifecycle method with signature `async function(request, h, err)` where `request` is the request object, `h` is the response toolkit and `err` is the validation error. -For example: +- `error`: send an Internal Server Error (500) response (default) +- `log`: just log the offense and send the response as-is +- `ignore`: take no action and continue processing the request +- A lifecycle method with signature `async function(request, h, err)` where `request` is the request object, `h` is the response toolkit and `err` is the validation error. + +For example: ```js const bookSchema = Joi.object({ - title: Joi.string().required(), - author: Joi.string().required(), - isbn: Joi.string().length(10), - pageCount: Joi.number(), - datePublished: Joi.date().iso() + title: Joi.string().required(), + author: Joi.string().required(), + isbn: Joi.string().length(10), + pageCount: Joi.number(), + datePublished: Joi.date().iso(), }); server.route({ - method: 'GET', - path: '/books', - handler: async function (request, h) { - - return await getBooks(); + method: 'GET', + path: '/books', + handler: async function (request, h) { + return await getBooks(); + }, + options: { + response: { + schema: Joi.array().items(bookSchema), + failAction: 'log', }, - options: { - response: { - schema: Joi.array().items(bookSchema), - failAction: 'log' - } - } + }, }); ``` -This is a route that will return a list of books. We can see that since `failAction` is set to `log`, the server will just log the error and send the response as-is. + +This is a route that will return a list of books. We can see that since `failAction` is set to `log`, the server will just log the error and send the response as-is. ### response.sample @@ -221,35 +226,36 @@ If performance is a concern, hapi can be configured to validate only a percentag ```javascript const bookSchema = Joi.object({ - title: Joi.string().required(), - author: Joi.string().required(), - isbn: Joi.string().length(10), - pageCount: Joi.number(), - datePublished: Joi.date().iso() + title: Joi.string().required(), + author: Joi.string().required(), + isbn: Joi.string().length(10), + pageCount: Joi.number(), + datePublished: Joi.date().iso(), }); server.route({ - method: 'GET', - path: '/books', - handler: async function (request, h) { - - return await getBooks(); + method: 'GET', + path: '/books', + handler: async function (request, h) { + return await getBooks(); + }, + options: { + response: { + sample: 50, + schema: Joi.array().items(bookSchema), }, - options: { - response: { - sample: 50, - schema: Joi.array().items(bookSchema) - } - } + }, }); ``` + Looking at your book route again, you can see, the `sample` value is set to `50`. This means the server will validate one half of the responses. ### response.status Sometimes one endpoint can serve different response objects. For instance, a `POST` route may return one of the following: -* `201` with the newly created resource if a new resource is created. -* `202` with the old and new values if an existing resource was updated. + +- `201` with the newly created resource if a new resource is created. +- `202` with the old and new values if an existing resource was updated. hapi supports this by allowing you to specify a different validation schema for each response status code. `response.status` is an object with keys that are numeric status codes, and properties that are joi schemas: diff --git a/static/lib/tutorials/en_US/views.md b/docs/tutorials/en_US/views.md similarity index 81% rename from static/lib/tutorials/en_US/views.md rename to docs/tutorials/en_US/views.md index f5dd35c0..82c3d694 100644 --- a/static/lib/tutorials/en_US/views.md +++ b/docs/tutorials/en_US/views.md @@ -1,15 +1,20 @@ +--- +title: Views +--- + + + # Views _This tutorial is compatible with hapi v17 and newer_ - ## Overview hapi has extensive support for template rendering, including the ability to load and leverage multiple templating engines, partials, helpers (functions used in templates to manipulate data), and layouts. These capabilities are provided by the [vision](/module/vision) plugin. ## Vision -[Vision](/module/vision) is a templates rendering plugin for hapi.js. `Vision` decorates the `server`, `request`, and `h` response toolkit interfaces with additional methods for managing view engines that can be used to render templated responses. `Vision` also provides a built-in handler implementation for creating templated responses. +[Vision](/module/vision) is a templates rendering plugin for hapi.js. `Vision` decorates the `server`, `request`, and `h` response toolkit interfaces with additional methods for managing view engines that can be used to render templated responses. `Vision` also provides a built-in handler implementation for creating templated responses. `Vision` is compatible with most major templating engines out of the box, such as ejs, handlebars, pug, twig, etc. Engines that don't follow the normal API pattern can still be used by mapping their API to the [vision API](/module/vision). @@ -27,20 +32,19 @@ const Hapi = require('@hapi/hapi'); const Hoek = require('@hapi/hoek'); const start = async () => { + const server = Hapi.server(); - const server = Hapi.server(); + await server.register(require('@hapi/vision')); - await server.register(require('@hapi/vision')); - - server.views({ - engines: { - html: require('handlebars') - }, - relativeTo: __dirname, - path: 'templates' - }); + server.views({ + engines: { + html: require('handlebars'), + }, + relativeTo: __dirname, + path: 'templates', + }); - await server.start(); + await server.start(); }; start(); @@ -60,13 +64,13 @@ Note that all options may be set either globally, which configures them for all ```javascript server.views({ - engines: { - html: { - module: require('handlebars'), - compileMode: 'sync' // engine specific - } + engines: { + html: { + module: require('handlebars'), + compileMode: 'sync', // engine specific }, - compileMode: 'async' // global setting + }, + compileMode: 'async', // global setting }); ``` @@ -116,35 +120,35 @@ Your configuration might look like: ```javascript server.views({ - engines: { - html: require('handlebars') - }, - relativeTo: __dirname, - path: './templates', - layoutPath: './templates/layout', - helpersPath: './templates/helpers' + engines: { + html: require('handlebars'), + }, + relativeTo: __dirname, + path: './templates', + layoutPath: './templates/layout', + helpersPath: './templates/helpers', }); ``` ### Global context -In the [rendering a view](#render) tutorial, you saw how to pass context directly into a view, but what if you have some default context that should *always* be available on all templates? +In the [rendering a view](#render) tutorial, you saw how to pass context directly into a view, but what if you have some default context that should _always_ be available on all templates? The simplest way to achieve this is by using the `context` option when calling `server.views()`: ```javascript const context = { - title: 'My personal site' + title: 'My personal site', }; server.views({ - engines: { - html: { - module: require('handlebars'), - compileMode: 'sync' // engine specific - } + engines: { + html: { + module: require('handlebars'), + compileMode: 'sync', // engine specific }, - context + }, + context, }); ``` @@ -158,22 +162,21 @@ The following snippet is the complete helper function which you will store in a ```javascript module.exports = function () { - - const fortunes = [ - 'Heisenberg may have slept here...', - 'Wanna buy a duck?', - 'Say no, then negotiate.', - 'Time and tide wait for no man.', - 'To teach is to learn.', - 'Never ask the barber if you need a haircut.', - 'You will forget that you ever knew me.', - 'You will be run over by a beer truck.', - 'Fortune favors the lucky.', - 'Have a nice day!' - ]; - - const x = Math.floor(Math.random() * fortunes.length); - return fortunes[x]; + const fortunes = [ + 'Heisenberg may have slept here...', + 'Wanna buy a duck?', + 'Say no, then negotiate.', + 'Time and tide wait for no man.', + 'To teach is to learn.', + 'Never ask the barber if you need a haircut.', + 'You will forget that you ever knew me.', + 'You will be run over by a beer truck.', + 'Fortune favors the lucky.', + 'Have a nice day!', + ]; + + const x = Math.floor(Math.random() * fortunes.length); + return fortunes[x]; }; ``` @@ -181,7 +184,7 @@ Now you can use the view helper in your templates. Here's a code snippet that sh ```html

    Your fortune

    -

    {{fortune}}

    +

    {{fortune}}

    ``` Now when you start the server and point your browser to the route which uses your template (which uses your view helper), you should see a paragraph with a randomly selected fortune right below the header. @@ -194,30 +197,28 @@ For reference, here is a complete server script that uses the fortune view helpe const Hapi = require('@hapi/hapi'); const start = async () => { + const server = Hapi.server({ port: 8080 }); - const server = Hapi.server({ port: 8080 }); - - await server.register(require('@hapi/vision')); - - server.views({ - engines: { - html: require('handlebars') - }, - relativeTo: __dirname, - path: 'templates', - helpersPath: 'helpers' - }); + await server.register(require('@hapi/vision')); - server.route({ - method: 'GET', - path: '/', - handler: function (request, h) { + server.views({ + engines: { + html: require('handlebars'), + }, + relativeTo: __dirname, + path: 'templates', + helpersPath: 'helpers', + }); - return h.view('index'); - } - }); + server.route({ + method: 'GET', + path: '/', + handler: function (request, h) { + return h.view('index'); + }, + }); - await server.start(); + await server.start(); }; start(); @@ -231,9 +232,9 @@ In order to use the built-in layout system, first setup the view engine: ```javascript server.views({ - // ... - layout: true, - layoutPath: 'templates/layout' + // ... + layout: true, + layoutPath: 'templates/layout', }); ``` @@ -244,8 +245,8 @@ Setup a content area in your `layout.html`: ```html - {{{content}}} - + {{{content}}} + ``` @@ -255,14 +256,14 @@ And your view should be just the content:
    Content
    ``` -When rendering the view, the `{{{content}}}` will be replaced by the view contents. +When rendering the view, the `{{{content}}}` will be replaced by the view contents. If you want a different default layout, you can set the option globally: ```javascript server.views({ - // ... - layout: 'another_default' + // ... + layout: 'another_default', }); ``` @@ -282,12 +283,11 @@ The first method of rendering a view we'll look at is `h.view()`. Here's what a ```javascript server.route({ - method: 'GET', - path: '/', - handler: function (request, h) { - - return h.view('index'); - } + method: 'GET', + path: '/', + handler: function (request, h) { + return h.view('index'); + }, }); ``` @@ -303,11 +303,11 @@ The second method of rendering a view, is using hapi's built in view handler. Th ```javascript server.route({ - method: 'GET', - path: '/', - handler: { - view: 'index' - } + method: 'GET', + path: '/', + handler: { + view: 'index', + }, }); ``` diff --git a/static/lib/tutorials/ko_KR/auth.md b/docs/tutorials/ko_KR/auth.md similarity index 84% rename from static/lib/tutorials/ko_KR/auth.md rename to docs/tutorials/ko_KR/auth.md index f9d86e69..6c4efe9c 100644 --- a/static/lib/tutorials/ko_KR/auth.md +++ b/docs/tutorials/ko_KR/auth.md @@ -1,3 +1,9 @@ +--- +title: Authentication +--- + + + ## 인증 _이 튜터리얼은 hapi v17과 호환됩니다._ @@ -15,50 +21,47 @@ const Bcrypt = require('bcrypt'); const Hapi = require('@hapi/hapi'); const users = { - john: { - username: 'john', - password: '$2a$10$iqJSHD.BGr0E2IxQwYgJmeP3NvhPrXAeLSaGCj6IR/XU5QtjVu5Tm', // 'secret' - name: 'John Doe', - id: '2133d32a' - } + john: { + username: 'john', + password: '$2a$10$iqJSHD.BGr0E2IxQwYgJmeP3NvhPrXAeLSaGCj6IR/XU5QtjVu5Tm', // 'secret' + name: 'John Doe', + id: '2133d32a', + }, }; const validate = async (request, username, password) => { + const user = users[username]; + if (!user) { + return { credentials: null, isValid: false }; + } - const user = users[username]; - if (!user) { - return { credentials: null, isValid: false }; - } - - const isValid = await Bcrypt.compare(password, user.password); - const credentials = { id: user.id, name: user.name }; + const isValid = await Bcrypt.compare(password, user.password); + const credentials = { id: user.id, name: user.name }; - return { isValid, credentials }; + return { isValid, credentials }; }; const start = async () => { + const server = Hapi.server({ port: 4000 }); - const server = Hapi.server({ port: 4000 }); + await server.register(require('hapi-auth-basic')); - await server.register(require('hapi-auth-basic')); + server.auth.strategy('simple', 'basic', { validate }); - server.auth.strategy('simple', 'basic', { validate }); + server.route({ + method: 'GET', + path: '/', + options: { + auth: 'simple', + }, + handler: function (request, h) { + return 'welcome'; + }, + }); - server.route({ - method: 'GET', - path: '/', - options: { - auth: 'simple' - }, - handler: function (request, h) { + await server.start(); - return 'welcome'; - } - }); - - await server.start(); - - console.log('server running at: ' + server.info.uri); + console.log('server running at: ' + server.info.uri); }; start(); @@ -76,11 +79,11 @@ start(); `scheme`은 `function (server, options)` 형태의 메소드 입니다. `server` 인자는 scheme이 추가될 서버를 참조하고 `options` 인자는 이 scheme을 사용하는 strategy가 등록될 때 제공되는 설정 객체입니다. -이 메소드는 *최소한* `authenticate` 키를 가진 객체를 반환해야 합니다. 사용될 수 있는 다른 선택적인 메소드는 `payload`와 `response`입니다. +이 메소드는 _최소한_ `authenticate` 키를 가진 객체를 반환해야 합니다. 사용될 수 있는 다른 선택적인 메소드는 `payload`와 `response`입니다. ### `authenticate` -`authenticate` 메소드는 `function (request, reply)` 모양을 가지고 scheme에서 유일한 *필수* 메소드입니다. +`authenticate` 메소드는 `function (request, reply)` 모양을 가지고 scheme에서 유일한 _필수_ 메소드입니다. `request`는 서버에서 생성된 `request` 객체입니다. route 처리기에서 사용 가능한 것과 같은 객체이고 [API reference](/api#request-object)에 문서로 만들어 져 있습니다. @@ -104,11 +107,11 @@ start(); `response` 메소드 역시 `function (request, h)` 형채로 되어 있으며 표준 응답 도구를 활용합니다. -이 메소드는 응답이 사용자에게 보내지기 전에 추가 헤더로 응답 객체를 (`request.response`) 꾸미기 위한 것입니다. +이 메소드는 응답이 사용자에게 보내지기 전에 추가 헤더로 응답 객체를 (`request.response`) 꾸미기 위한 것입니다. 한번 꾸미기가 완료되면 `h.continue`를 반환해야 합니다. 그리고 응답이 보내질 것입니다. -만약 에러가 발생하면 [boom](https://github.com/hapijs/boom)으로 권장되는 에러를 대신 던져야 합니다. +만약 에러가 발생하면 [boom](https://github.com/hapijs/boom)으로 권장되는 에러를 대신 던져야 합니다. ### 등록하기 @@ -120,7 +123,7 @@ scheme을 등록했으면 scheme을 사용해야 합니다. 이때 strategy가 앞서 언급했듯이 strategy는 본래 미리 설정된 scheme의 사본입니다. -strategy를 등록하려면 먼저 등록된 scheme이 있어야 합니다. scheme 등록이 완료되었으면 strategy를 등록하기 위해 `server.auth.strategy(name, scheme, [options])`를 사용합니다. +strategy를 등록하려면 먼저 등록된 scheme이 있어야 합니다. scheme 등록이 완료되었으면 strategy를 등록하기 위해 `server.auth.strategy(name, scheme, [options])`를 사용합니다. `name` 인자는 문자열이어야 하고 이후에 특정 strategy를 식별하기 위해 사용됩니다. `scheme` 또한 문자열이고 strategy로 인스턴스가 되는 scheme의 이름입니다. @@ -138,18 +141,17 @@ strategy를 등록하려면 먼저 등록된 scheme이 있어야 합니다. sche `options.auth` 인자로 경로에서 인증을 설정할 수 있습니다. 만약 `false`로 설정되어 있다면 그 경로에서 인증은 비활성화 됩니다. -사용할 strategy의 이름의 문자열 또는 `mode`, `strategies`, `payload` 인자가 있는 객체로 설정할 수 있습니다. +사용할 strategy의 이름의 문자열 또는 `mode`, `strategies`, `payload` 인자가 있는 객체로 설정할 수 있습니다. `mode` 인자는 `'required'`, `'optional'` 또는 `'try'`로 설정할 수 있습니다. 그리고 strategy를 등록할 때와 동일하게 동작합니다. -`'required'`로 설정하면 경로에 접근하기 위해선 사용자는 인증되어야 합니다. 인증이 유효하지 않다면 에러를 받을 것입니다. -`mode`가 `'optional'`로 설정되면 strategy는 여전히 경로에 적용될 것입니다. 그러나 이 경우 사용자가 인증 받을 필요는 *없습니다*. 인증 데이터는 선택적입니다. 제공된다면 유효해야 합니다. +`'required'`로 설정하면 경로에 접근하기 위해선 사용자는 인증되어야 합니다. 인증이 유효하지 않다면 에러를 받을 것입니다. +`mode`가 `'optional'`로 설정되면 strategy는 여전히 경로에 적용될 것입니다. 그러나 이 경우 사용자가 인증 받을 필요는 _없습니다_. 인증 데이터는 선택적입니다. 제공된다면 유효해야 합니다. 마지막 `mode` 설정은 `'try'`입니다. `'try'`와 `'optional'`의 차이점은 `'try'`에서 유효하지 않은 인증도 받아들여지고 사용자는 경로 처리기에 도달할 것입니다. - 하나의 strategy를 지정할 때 strategy 이름의 문자열로 `strategy` 속성을 설정할 수 있습니다. 하나 이상의 strategy를 지정한다면 인자 이름은 `strategies`가 돼야 하고 시도할 각 strategy의 이름 문자열의 배열이어야 합니다. strategy는 성공할 때 까지 하나씩 시도되거나 모두 실패합니다. -마지막으로 `payload` 인자는 payload는 인증되지 않음을 가리키는 `false`, *반드시* 인증돼야 하는 `'required'` 또는 `true`, 클라이언트가 payload 인증 정보를 포함한다면 반드시 유효해야 하는 `'optional'`로 설정될 수 있습니다. +마지막으로 `payload` 인자는 payload는 인증되지 않음을 가리키는 `false`, _반드시_ 인증돼야 하는 `'required'` 또는 `true`, 클라이언트가 payload 인증 정보를 포함한다면 반드시 유효해야 하는 `'optional'`로 설정될 수 있습니다. `payload` 인자는 scheme에서 `payload` 메소드를 지원하는 strategy에서만 사용 가능합니다. diff --git a/static/lib/tutorials/ko_KR/caching.md b/docs/tutorials/ko_KR/caching.md similarity index 72% rename from static/lib/tutorials/ko_KR/caching.md rename to docs/tutorials/ko_KR/caching.md index 7025e1c9..f9d30215 100644 --- a/static/lib/tutorials/ko_KR/caching.md +++ b/docs/tutorials/ko_KR/caching.md @@ -1,3 +1,9 @@ +--- +title: Caching +--- + + + ## Caching _이 튜터리얼은 hapi v17과 호환됩니다._ @@ -16,31 +22,30 @@ hapi에서 이 헤더를 어떻게 설정하는지 보겠습니다.: ```javascript server.route({ - path: '/hapi/{ttl?}', - method: 'GET', - handler: function (request, h) { - - const response = h.response({ be: 'hapi' }); + path: '/hapi/{ttl?}', + method: 'GET', + handler: function (request, h) { + const response = h.response({ be: 'hapi' }); - if (request.params.ttl) { - response.ttl(request.params.ttl); - } + if (request.params.ttl) { + response.ttl(request.params.ttl); + } - return response; + return response; + }, + options: { + cache: { + expiresIn: 30 * 1000, + privacy: 'private', }, - options: { - cache: { - expiresIn: 30 * 1000, - privacy: 'private' - } - } + }, }); ``` 위 예제는 경로에서 `cache` 옵션 객체를 설정하는 방법을 보여줍니다. `expiresIn`을 30초로 설정하고 `privacy`를 private로 설정합니다. 이 예제는 또한 `expiresIn` 값이 [response 객체](/api#response-object) 인터페이스에서 제공하는 `ttl(msec)` 메소드로 덮여질 수 있음을 보여줍니다. -`/hapi`에 요청하면 응답 헤더 `cache-control: max-age=30, must-revalidate, private`를 받을 것입니다. `/hapi/5000`에 요청하면 대신 응답 헤더 `cache-control: max-age=5, must-revalidate, private`를 받을 것입니다. +`/hapi`에 요청하면 응답 헤더 `cache-control: max-age=30, must-revalidate, private`를 받을 것입니다. `/hapi/5000`에 요청하면 대신 응답 헤더 `cache-control: max-age=5, must-revalidate, private`를 받을 것입니다. 공통적인 `cache` 설정 옵션에 대한 자세한 정보는 [route-options](/api#route-options)을 참고하세. @@ -53,9 +58,9 @@ server.route({ `lastModifed`가 Date 객체라고 가정하고 다음처럼 [response 객체](/api#response-object)를 통해 헤더를 설정할 수 있습니다. ```javascript -return h.response(result) - .header('Last-Modified', lastModified.toUTCString()); +return h.response(result).header('Last-Modified', lastModified.toUTCString()); ``` + 이 튜터리얼의 [마지막 절](#client-and-server-caching)에 `Last-Modified`를 사용한 또 다른 예제가 있습니다. #### ETag @@ -78,8 +83,7 @@ Catbox는 두 개의 인터페이스를 가지고 있습니다; client와 policy #### Client - -[Client](https://github.com/hapijs/catbox#client)는 키-값 쌍을 설정 / 가져올 수 있는 저수준 인터페이스입니다. 사용가능한 어댑터로 초기화 됩니다: ([Memory](https://github.com/hapijs/catbox-memory), [Redis](https://github.com/hapijs/catbox-redis), [mongoDB](https://github.com/hapijs/catbox-mongodb), [Memcached](https://github.com/hapijs/catbox-memcached), or [Riak](https://github.com/DanielBarnes/catbox-riak)) +[Client](https://github.com/hapijs/catbox#client)는 키-값 쌍을 설정 / 가져올 수 있는 저수준 인터페이스입니다. 사용가능한 어댑터로 초기화 됩니다: ([Memory](https://github.com/hapijs/catbox-memory), [Redis](https://github.com/hapijs/catbox-redis), [mongoDB](https://github.com/hapijs/catbox-mongodb), [Memcached](https://github.com/hapijs/catbox-memcached), or [Riak](https://github.com/DanielBarnes/catbox-riak)) hapi는 [catbox_memory](https://github.com/hapijs/catbox-memory) 어댑터를 사용하여 기본으로 [client](https://github.com/hapijs/catbox#client)를 초기화합니다. 여러 클라이언트를 정의하는 방법을 보겠습니다. @@ -89,21 +93,21 @@ hapi는 [catbox_memory](https://github.com/hapijs/catbox-memory) 어댑터를 const Hapi = require('@hapi/hapi'); const server = Hapi.server({ - port: 8000, - cache: [ - { - name: 'mongoCache', - engine: require('catbox-mongodb'), - host: '127.0.0.1', - partition: 'cache' - }, - { - name: 'redisCache', - engine: require('catbox-redis'), - host: '127.0.0.1', - partition: 'cache' - } - ] + port: 8000, + cache: [ + { + name: 'mongoCache', + engine: require('catbox-mongodb'), + host: '127.0.0.1', + partition: 'cache', + }, + { + name: 'redisCache', + engine: require('catbox-redis'), + host: '127.0.0.1', + partition: 'cache', + }, + ], }); ``` @@ -115,94 +119,90 @@ const server = Hapi.server({ ```javascript const start = async () => { + const add = async (a, b) => { + await Hoek.wait(1000); // Simulate some slow I/O + + return Number(a) + Number(b); + }; + + const sumCache = server.cache({ + cache: 'mongoCache', + expiresIn: 10 * 1000, + segment: 'customSegment', + generateFunc: async (id) => { + return await add(id.a, id.b); + }, + generateTimeout: 2000, + }); - const add = async (a, b) => { - - await Hoek.wait(1000); // Simulate some slow I/O - - return Number(a) + Number(b); - }; - - const sumCache = server.cache({ - cache: 'mongoCache', - expiresIn: 10 * 1000, - segment: 'customSegment', - generateFunc: async (id) => { - - return await add(id.a, id.b); - }, - generateTimeout: 2000 - }); - - server.route({ - path: '/add/{a}/{b}', - method: 'GET', - handler: async function (request, h) { - - const { a, b } = request.params; - const id = `${a}:${b}`; + server.route({ + path: '/add/{a}/{b}', + method: 'GET', + handler: async function (request, h) { + const { a, b } = request.params; + const id = `${a}:${b}`; - return await sumCache.get({ id, a, b }); - } - }); + return await sumCache.get({ id, a, b }); + }, + }); - await server.start(); + await server.start(); - console.log('Server running at:', server.info.uri); + console.log('Server running at:', server.info.uri); }; start(); ``` -http://localhost:8000/add/1/5 에 요청하면 1초 뒤에 응답 `6`을 받을 것입니다. 다시 요청하면 캐시에서 제공되기 때문에 응답을 즉시 받을 것입니다. 10초를 기다린 후, 다시 요청하면 캐시에서 제거되었기 때문에 시간이 좀더 걸리는 것을 볼 수 있습니다. + +http://localhost:8000/add/1/5 에 요청하면 1초 뒤에 응답 `6`을 받을 것입니다. 다시 요청하면 캐시에서 제공되기 때문에 응답을 즉시 받을 것입니다. 10초를 기다린 후, 다시 요청하면 캐시에서 제거되었기 때문에 시간이 좀더 걸리는 것을 볼 수 있습니다. `cache` 옵션은 hapi에 사용할 [client](https://github.com/hapijs/catbox#client)를 알려줍니다. `sumCache.get` 함수의 첫 번째 인자는 고유한 항목 식별자인 문자열 또는 필수 속성 `id`를 가진 객체이다. -**partitions**외에도 하나의 [client](https://github.com/hapijs/catbox#client)에서 캐시를 격리할 수 있는 **segments**가 있습니다. 두 개의 다른 메소드로부터의 결과를 캐시 하려고 할 때 보통 그 결과를 같이 섞이는 것을 원하지 않을 것입니다. [mongoDB](http://www.mongodb.org/) 어댑터에서 `segment`는 collection을 의미하고 [redis](http://redis.io/)에서는 `partition` 옵션과 함께 추가 접두사입니다 +**partitions**외에도 하나의 [client](https://github.com/hapijs/catbox#client)에서 캐시를 격리할 수 있는 **segments**가 있습니다. 두 개의 다른 메소드로부터의 결과를 캐시 하려고 할 때 보통 그 결과를 같이 섞이는 것을 원하지 않을 것입니다. [mongoDB](http://www.mongodb.org/) 어댑터에서 `segment`는 collection을 의미하고 [redis](http://redis.io/)에서는 `partition` 옵션과 함께 추가 접두사입니다 플러그인 안에서 [server.cache()](/api#servercacheoptions)가 호출될 때 `segment`의 기본값은 `'!pluginName'`입니다. [server methods](http://hapijs.com/tutorials/servermethods)를 만들 때 `segment`의 값은 `'#mothodName'`입니다. 여러 policy에서 하나의 segment를 공유하려는 여러 policy가 있는 경우라면 [shared](http://hapijs.com/api#servercacheoptions) 옵션을 사용할 수 있습니다. #### 서버 메소드 -더 좋아질 수 있습니다! 보일러 플레이트가 최소로 줄어들기 때문에 95% 경우 캐싱 목적으로 [server methods](/tutorials/servermethods)을 사용할 것입니다. 서버 메소드를 사용하여 앞의 예제를 다시 작성합니다.: +더 좋아질 수 있습니다! 보일러 플레이트가 최소로 줄어들기 때문에 95% 경우 캐싱 목적으로 [server methods](/tutorials/servermethods)을 사용할 것입니다. 서버 메소드를 사용하여 앞의 예제를 다시 작성합니다.: ```javascript const start = async () => { + // ... - // ... - - server.method('sum', add, { - cache: { - cache: 'mongoCache', - expiresIn: 10 * 1000, - generateTimeout: 2000 - } - }); - - server.route({ - path: '/add/{a}/{b}', - method: 'GET', - handler: async function (request, h) { + server.method('sum', add, { + cache: { + cache: 'mongoCache', + expiresIn: 10 * 1000, + generateTimeout: 2000, + }, + }); - const { a, b } = request.params; - return await server.methods.sum(a, b); - } - }); + server.route({ + path: '/add/{a}/{b}', + method: 'GET', + handler: async function (request, h) { + const { a, b } = request.params; + return await server.methods.sum(a, b); + }, + }); - await server.start(); + await server.start(); - // ... + // ... }; start(); ``` + [server.method()](/api#servermethodname-method-options)는 `segment: '#sum'`과 함께 자동으로 새로운 [policy](https://github.com/hapijs/catbox#policy)를 만듭니다. 또한, 고유 항목 `id`(캐시 키)는 인자로부터 자동으로 생성됩니다. 기본으로 `string`, `number`, `boolean` 인자를 받습니다. 더 복잡한 인자들은 인자를 기반으로 고유한 식별자를 만드는 `generateKey` 함수를 제공해야 합니다. - 더 자세한 내용은 서버 메소드 [tutorial](/tutorials/servermethods)에서 확인하세요. #### 다음은? -* catbox policy [options](https://github.com/hapijs/catbox#policy)을 살펴보고 catbox 캐싱의 모든 잠재력을 활용하기 위해 `staleIn`, `staleTimeout`, `generateTimeout`에 각별한 주의를 기울여주세요. -* 많은 예제는 서버 메소드 [tutorial](http://hapijs.com/tutorials/servermethods)을 확인하세요. +- catbox policy [options](https://github.com/hapijs/catbox#policy)을 살펴보고 catbox 캐싱의 모든 잠재력을 활용하기 위해 `staleIn`, `staleTimeout`, `generateTimeout`에 각별한 주의를 기울여주세요. +- 많은 예제는 서버 메소드 [tutorial](http://hapijs.com/tutorials/servermethods)을 확인하세요. ### 클라이언트와 서버 캐싱 @@ -212,35 +212,32 @@ start(); ```javascript const start = async () => { + //... + + server.method('sum', add, { + cache: { + cache: 'mongoCache', + expiresIn: 10 * 1000, + generateTimeout: 2000, + getDecoratedValue: true, + }, + }); - //... - - server.method('sum', add, { - cache: { - cache: 'mongoCache', - expiresIn: 10 * 1000, - generateTimeout: 2000, - getDecoratedValue: true - } - }); - - server.route({ - path: '/add/{a}/{b}', - method: 'GET', - handler: async function (request, h) { - - const { a, b } = request.params; - const { value, cached } = await server.methods.sum(a, b); - const lastModified = cached ? new Date(cached.stored) : new Date(); + server.route({ + path: '/add/{a}/{b}', + method: 'GET', + handler: async function (request, h) { + const { a, b } = request.params; + const { value, cached } = await server.methods.sum(a, b); + const lastModified = cached ? new Date(cached.stored) : new Date(); - return h.response(value) - .header('Last-modified', lastModified.toUTCString()); - } - }); + return h.response(value).header('Last-modified', lastModified.toUTCString()); + }, + }); - await server.start(); + await server.start(); - // ... + // ... }; ``` diff --git a/static/lib/tutorials/tr_TR/community.md b/docs/tutorials/ko_KR/community.md similarity index 76% rename from static/lib/tutorials/tr_TR/community.md rename to docs/tutorials/ko_KR/community.md index a651208c..b8eec564 100644 --- a/static/lib/tutorials/tr_TR/community.md +++ b/docs/tutorials/ko_KR/community.md @@ -1,3 +1,9 @@ +--- +title: Community +--- + + + # Community Tutorials ## No tutorials yet diff --git a/static/lib/tutorials/ko_KR/cookies.md b/docs/tutorials/ko_KR/cookies.md similarity index 90% rename from static/lib/tutorials/ko_KR/cookies.md rename to docs/tutorials/ko_KR/cookies.md index 1ccdb338..35140030 100644 --- a/static/lib/tutorials/ko_KR/cookies.md +++ b/docs/tutorials/ko_KR/cookies.md @@ -1,3 +1,9 @@ +--- +title: Cookies +--- + + + ## Cookies _이 튜터리얼은 hapi v17에 호환됩니다._ @@ -12,12 +18,12 @@ hapi는 쿠키를 다룰 때 몇 가지 설정 가능한 옵션을 가지고 있 ```javascript server.state('data', { - ttl: null, - isSecure: true, - isHttpOnly: true, - encoding: 'base64json', - clearInvalid: false, // remove invalid cookies - strictHeader: true // don't allow violations of RFC 6265 + ttl: null, + isSecure: true, + isHttpOnly: true, + encoding: 'base64json', + clearInvalid: false, // remove invalid cookies + strictHeader: true, // don't allow violations of RFC 6265 }); ``` @@ -27,12 +33,12 @@ server.state('data', { ```json5 { - options: { - state: { - parse: true, // parse cookies and store in request.state - failAction: 'error' // may also be 'ignore' or 'log' - } - } + options: { + state: { + parse: true, // parse cookies and store in request.state + failAction: 'error', // may also be 'ignore' or 'log' + }, + }, } ``` @@ -77,9 +83,9 @@ const value = request.state.data; 예제 코드는 `{ firstVisit: false }` 값을 설정한 위 예제의 `data` 쿠키 키를 사용합니다. ## 쿠키 지우기 + [response toolkit](/api#response-toolkit) 또는 [response object](/api#response-object)의 `unstate()` 메소드를 호출하는 것으로 쿠키를 지울 수 있습니다. ```javascript return h.response('Bye').unstate('data'); ``` - diff --git a/static/lib/tutorials/pt_BR/expresstohapi.md b/docs/tutorials/ko_KR/express-to-hapi.md similarity index 55% rename from static/lib/tutorials/pt_BR/expresstohapi.md rename to docs/tutorials/ko_KR/express-to-hapi.md index 0af99a4a..51576c5c 100644 --- a/static/lib/tutorials/pt_BR/expresstohapi.md +++ b/docs/tutorials/ko_KR/express-to-hapi.md @@ -1,5 +1,11 @@ +--- +title: Express to hapi +--- + + + # Express to hapi Guide ## No Translation Yet -This guide has not been translated yet. If you would like to translate it, please submit a pull request. \ No newline at end of file +This guide has not been translated yet. If you would like to translate it, please submit a pull request. diff --git a/static/lib/tutorials/ko_KR/gettingstarted.md b/docs/tutorials/ko_KR/getting-started.md similarity index 79% rename from static/lib/tutorials/ko_KR/gettingstarted.md rename to docs/tutorials/ko_KR/getting-started.md index 6f4d0836..1a304e14 100644 --- a/static/lib/tutorials/ko_KR/gettingstarted.md +++ b/docs/tutorials/ko_KR/getting-started.md @@ -1,3 +1,9 @@ +--- +title: Getting Started +--- + + + ## Getting started _이 튜터리얼은 hapi v17과 호환됩니다._ @@ -6,9 +12,9 @@ _이 튜터리얼은 hapi v17과 호환됩니다._ `myproject`라는 디렉터리를 만들어 주세요. 그리고 거기서: -* 실행: `cd myproject` 생성한 프로젝트 폴더로 이동합니다. -* 실행: `npm init` 입력 후, 지시 메시지를 따르세요. package.json 파일을 생성할 것입니다. -* 실행: `npm install --save @hapi/hapi@17.x.x` 이 명령은 hapi를 설치하고 프로젝트 의존성을 package.json에 기록합니다. +- 실행: `cd myproject` 생성한 프로젝트 폴더로 이동합니다. +- 실행: `npm init` 입력 후, 지시 메시지를 따르세요. package.json 파일을 생성할 것입니다. +- 실행: `npm install --save @hapi/hapi@17.x.x` 이 명령은 hapi를 설치하고 프로젝트 의존성을 package.json에 기록합니다. 이게 전부입니다! hapi를 사용하는 서버를 만드는 데 필요한 모든 것을 갖췄습니다. @@ -22,20 +28,18 @@ _이 튜터리얼은 hapi v17과 호환됩니다._ const Hapi = require('@hapi/hapi'); const server = Hapi.server({ - port: 3000, - host: 'localhost' + port: 3000, + host: 'localhost', }); const init = async () => { - - await server.start(); - console.log(`Server running at: ${server.info.uri}`); + await server.start(); + console.log(`Server running at: ${server.info.uri}`); }; process.on('unhandledRejection', (err) => { - - console.log(err); - process.exit(1); + console.log(err); + process.exit(1); }); init(); @@ -55,38 +59,34 @@ init(); const Hapi = require('@hapi/hapi'); const server = Hapi.server({ - port: 3000, - host: 'localhost' + port: 3000, + host: 'localhost', }); server.route({ - method: 'GET', - path: '/', - handler: (request, h) => { - - return 'Hello, world!'; - } + method: 'GET', + path: '/', + handler: (request, h) => { + return 'Hello, world!'; + }, }); server.route({ - method: 'GET', - path: '/{name}', - handler: (request, h) => { - - return 'Hello, ' + encodeURIComponent(request.params.name) + '!'; - } + method: 'GET', + path: '/{name}', + handler: (request, h) => { + return 'Hello, ' + encodeURIComponent(request.params.name) + '!'; + }, }); const init = async () => { - - await server.start(); - console.log(`Server running at: ${server.info.uri}`); + await server.start(); + console.log(`Server running at: ${server.info.uri}`); }; process.on('unhandledRejection', (err) => { - - console.log(err); - process.exit(1); + console.log(err); + process.exit(1); }); init(); @@ -106,22 +106,20 @@ Hello World 응용프로그램으로 간단한 hapi 앱을 실행할 수 있음 `server.js` 파일에 `init` 함수를 변경합니다.: -``` javascript +```javascript const init = async () => { + await server.register(require('@hapi/inert')); - await server.register(require('@hapi/inert')); - - server.route({ - method: 'GET', - path: '/hello', - handler: (request, h) => { - - return h.file('./public/hello.html'); - } - }); + server.route({ + method: 'GET', + path: '/hello', + handler: (request, h) => { + return h.file('./public/hello.html'); + }, + }); - await server.start(); - console.log(`Server running at: ${server.info.uri}`); + await server.start(); + console.log(`Server running at: ${server.info.uri}`); }; ``` @@ -137,7 +135,7 @@ const init = async () => { - + Hapi.js is awesome! @@ -172,54 +170,49 @@ npm install hapi-pino const Hapi = require('@hapi/hapi'); const server = Hapi.server({ - port: 3000, - host: 'localhost' + port: 3000, + host: 'localhost', }); server.route({ - method: 'GET', - path: '/', - handler: (request, h) => { - - return 'Hello, world!'; - } + method: 'GET', + path: '/', + handler: (request, h) => { + return 'Hello, world!'; + }, }); server.route({ - method: 'GET', - path: '/{name}', - handler: (request, h) => { - - // request.log(['a', 'name'], "Request name"); - // or - request.logger.info('In handler %s', request.path); - - return `Hello, ${encodeURIComponent(request.params.name)}!`; - } + method: 'GET', + path: '/{name}', + handler: (request, h) => { + // request.log(['a', 'name'], "Request name"); + // or + request.logger.info('In handler %s', request.path); + + return `Hello, ${encodeURIComponent(request.params.name)}!`; + }, }); const init = async () => { - - await server.register({ - plugin: require('hapi-pino'), - options: { - prettyPrint: false, - logEvents: ['response', 'onPostStart'] - } - }); - - await server.start(); - console.log(`Server running at: ${server.info.uri}`); + await server.register({ + plugin: require('hapi-pino'), + options: { + prettyPrint: false, + logEvents: ['response', 'onPostStart'], + }, + }); + + await server.start(); + console.log(`Server running at: ${server.info.uri}`); }; process.on('unhandledRejection', (err) => { - - console.log(err); - process.exit(1); + console.log(err); + process.exit(1); }); init(); - ``` 이제 서버가 시작할 때, 다음과 같은 것을 볼 것입니다.: diff --git a/static/lib/tutorials/ko_KR/logging.md b/docs/tutorials/ko_KR/logging.md similarity index 92% rename from static/lib/tutorials/ko_KR/logging.md rename to docs/tutorials/ko_KR/logging.md index a0ec0dc0..f33dab11 100644 --- a/static/lib/tutorials/ko_KR/logging.md +++ b/docs/tutorials/ko_KR/logging.md @@ -1,3 +1,9 @@ +--- +title: Logging +--- + + + ## Logging _이 튜터리얼은 hapi v17에 호환됩니다._ @@ -6,7 +12,7 @@ _이 튜터리얼은 hapi v17에 호환됩니다._ ### 내장 메소드 -거의 동일한 두 가지 로깅 방법인 [`server.log(tags, [data, [timestamp]])`](/api#-serverlogtags-data-timestamp)와 [`request.log(tags, [data])`](https://hapijs.com/api#-requestlogtags-data)가 있습니다. 이 둘은 응용프로그램에서 이벤트를 로깅할 때 호출될 수 있습니다. 경로 처리기(route handler), 요청 생애주기 확장(request lifecycle extension)또는 인증 스킴(authentication scheme)같은 request의 문맥 안에서 `request.log()`를 호출할 것입니다. 예를들어 서버가 시작한 직후 또는 플러그인의 `register()` 메소드 안에서 처럼 특별한 요청이 없는 그 밖에 다른 곳에서는 `server.log()`를 사용할 것입니다. +거의 동일한 두 가지 로깅 방법인 [`server.log(tags, [data, [timestamp]])`](/api#-serverlogtags-data-timestamp)와 [`request.log(tags, [data])`](https://hapijs.com/api#-requestlogtags-data)가 있습니다. 이 둘은 응용프로그램에서 이벤트를 로깅할 때 호출될 수 있습니다. 경로 처리기(route handler), 요청 생애주기 확장(request lifecycle extension)또는 인증 스킴(authentication scheme)같은 request의 문맥 안에서 `request.log()`를 호출할 것입니다. 예를들어 서버가 시작한 직후 또는 플러그인의 `register()` 메소드 안에서 처럼 특별한 요청이 없는 그 밖에 다른 곳에서는 `server.log()`를 사용할 것입니다. 둘 모두 처음 2개의 동일한 인자를 받습니다. 순서대로 `tags`, `data`입니다. @@ -26,13 +32,11 @@ hapi가 내부에서 생성하는 로그 이벤트는 항상 그 이벤트와 hapi 서버 객체는 각 로그 이벤트마다 이벤트를 생성합니다. 표준 EventEmitter API를 사용하여 그 이벤트를 수신하고 원하는 대로 표시할 수 있습니다. - ```javascript server.events.on('log', (event, tags) => { - - if (tags.error) { - console.log(`Server error: ${event.error ? event.error.message : 'unknown'}`); - } + if (tags.error) { + console.log(`Server error: ${event.error ? event.error.message : 'unknown'}`); + } }); ``` @@ -42,17 +46,16 @@ server.events.on('log', (event, tags) => { ```javascript server.route({ - method: 'GET', - path: '/', - options: { - log: { - collect: true - } + method: 'GET', + path: '/', + options: { + log: { + collect: true, }, - handler: function (request, h) { - - return 'hello'; - } + }, + handler: function (request, h) { + return 'hello'; + }, }); ``` diff --git a/static/lib/tutorials/ko_KR/plugins.md b/docs/tutorials/ko_KR/plugins.md similarity index 70% rename from static/lib/tutorials/ko_KR/plugins.md rename to docs/tutorials/ko_KR/plugins.md index 594bfb0b..ffb1d24a 100644 --- a/static/lib/tutorials/ko_KR/plugins.md +++ b/docs/tutorials/ko_KR/plugins.md @@ -1,3 +1,9 @@ +--- +title: Plugins +--- + + + ## Plugins _이 튜터리얼은 hapi v17과 호환됩니다._ @@ -14,24 +20,22 @@ hapi는 막대하고 강력한 플러그인 시스템을 가지고 있어 응용 'use strict'; const myPlugin = { - name: 'myPlugin', - version: '1.0.0', - register: async function (server, options) { - - // Create a route for example - - server.route({ - method: 'GET', - path: '/test', - handler: function (request, h) { - - return 'hello, world'; - } - }); + name: 'myPlugin', + version: '1.0.0', + register: async function (server, options) { + // Create a route for example + + server.route({ + method: 'GET', + path: '/test', + handler: function (request, h) { + return 'hello, world'; + }, + }); - // etc ... - await someAsyncMethods(); - } + // etc ... + await someAsyncMethods(); + }, }; ``` @@ -41,23 +45,21 @@ const myPlugin = { 'use strict'; exports.plugin = { - pkg: require('./package.json'), - register: async function (server, options) { - - // Create a route for example - - server.route({ - method: 'GET', - path: '/test', - handler: function (request, h) { - - return 'hello, world'; - } - }); + pkg: require('./package.json'), + register: async function (server, options) { + // Create a route for example + + server.route({ + method: 'GET', + path: '/test', + handler: function (request, h) { + return 'hello, world'; + }, + }); - // etc... - await someAsyncMethods(); - } + // etc... + await someAsyncMethods(); + }, }; ``` @@ -85,14 +87,13 @@ exports.plugin = { ```javascript const start = async function () { + // load one plugin - // load one plugin + await server.register(require('myplugin')); - await server.register(require('myplugin')); + // load multiple plugins - // load multiple plugins - - await server.register([require('myplugin'), require('yourplugin')]); + await server.register([require('myplugin'), require('yourplugin')]); }; ``` @@ -100,13 +101,12 @@ const start = async function () { ```javascript const start = async function () { - - await server.register({ - plugin: require('myplugin'), - options: { - message: 'hello' - } - }); + await server.register({ + plugin: require('myplugin'), + options: { + message: 'hello', + }, + }); }; ``` @@ -114,14 +114,16 @@ const start = async function () { ```javascript const start = async function () { - - await server.register([{ - plugin: require('plugin1'), - options: {} - }, { - plugin: require('plugin2'), - options: {} - }]); + await server.register([ + { + plugin: require('plugin1'), + options: {}, + }, + { + plugin: require('plugin2'), + options: {}, + }, + ]); }; ``` @@ -129,7 +131,7 @@ const start = async function () { 두 번째 선택적인 인자를 `server.register()`에 전달할 수 있습니다. 이 객체에 대한 문서는 [API reference](/api#-await-serverregisterplugins-options)에서 찾을 수 있습니다. -options 객체는 로드될 플러그인에 전달되지 *않고* hapi에서 사용됩니다. 이는 플러그인이 등록된 어떤 경로에 `vhost` 또는 `prefix` 수정자를 적용할 수 있습니다. +options 객체는 로드될 플러그인에 전달되지 _않고_ hapi에서 사용됩니다. 이는 플러그인이 등록된 어떤 경로에 `vhost` 또는 `prefix` 수정자를 적용할 수 있습니다. 예를 들면 다음과 같은 플러그인이 있다고 가정합니다.: @@ -137,21 +139,19 @@ options 객체는 로드될 플러그인에 전달되지 *않고* hapi에서 사 'use strict'; exports.plugin = { - pkg: require('./package.json'), - register: async function (server, options) { - - server.route({ - method: 'GET', - path: '/test', - handler: function (request, h) { - - return 'test passed'; - } - }); + pkg: require('./package.json'), + register: async function (server, options) { + server.route({ + method: 'GET', + path: '/test', + handler: function (request, h) { + return 'test passed'; + }, + }); - // etc... - await someAsyncMethods(); - } + // etc... + await someAsyncMethods(); + }, }; ``` @@ -159,12 +159,11 @@ exports.plugin = { ```javascript const start = async function () { - - await server.register(require('myplugin'), { - routes: { - prefix: '/plugins' - } - }); + await server.register(require('myplugin'), { + routes: { + prefix: '/plugins', + }, + }); }; ``` diff --git a/static/lib/tutorials/ko_KR/routing.md b/docs/tutorials/ko_KR/routing.md similarity index 77% rename from static/lib/tutorials/ko_KR/routing.md rename to docs/tutorials/ko_KR/routing.md index 0e0b3652..462d242e 100644 --- a/static/lib/tutorials/ko_KR/routing.md +++ b/docs/tutorials/ko_KR/routing.md @@ -1,3 +1,9 @@ +--- +title: Routing +--- + + + ## Routing _이 튜터리얼은 hapi v17과 호환됩니다._ @@ -6,12 +12,11 @@ hapi에서 라우트를 정의할 때 다른 프레임워크와 마찬가지로 ```javascript server.route({ - method: 'GET', - path: '/', - handler: function (request, h) { - - return 'Hello!'; - } + method: 'GET', + path: '/', + handler: function (request, h) { + return 'Hello!'; + }, }); ``` @@ -21,12 +26,11 @@ server.route({ ```javascript server.route({ - method: ['PUT', 'POST'], - path: '/', - handler: function (request, h) { - - return 'I did something!'; - } + method: ['PUT', 'POST'], + path: '/', + handler: function (request, h) { + return 'I did something!'; + }, }); ``` @@ -36,12 +40,11 @@ server.route({ ```javascript server.route({ - method: 'GET', - path: '/hello/{user}', - handler: function (request, h) { - - return `Hello ${encodeURIComponent(request.params.user)}!`; - } + method: 'GET', + path: '/hello/{user}', + handler: function (request, h) { + return `Hello ${encodeURIComponent(request.params.user)}!`; + }, }); ``` @@ -53,20 +56,17 @@ server.route({ ```javascript server.route({ - method: 'GET', - path: '/hello/{user?}', - handler: function (request, h) { - - const user = request.params.user ? - encodeURIComponent(request.params.user) : - 'stranger'; + method: 'GET', + path: '/hello/{user?}', + handler: function (request, h) { + const user = request.params.user ? encodeURIComponent(request.params.user) : 'stranger'; - return `Hello ${user}!`; - } + return `Hello ${user}!`; + }, }); ``` -이제 `/hello/mary`에 대한 요청은 `Hello mary!`로 응답하고 `/hello`에 대한 요청은 `Hello stranger!`로 응답할 것입니다. 경로에서 *마지막* 명명된 인자만이 선택적으로 될 수 있습니다. 선택적 인자 뒤에 다른 인자가 있기 때문에 `/{one?}/{two}`는 무효한 경로임을 의미합니다. 경로의 부분에서 일부분을 다루는 명명된 인자를 가질 수 있습니다. 예를 들어 `/{filename}.jpg`는 유효합니다. 한 부분에서 인자 사이에 인자가 아닌 구분자가 제공되면 여러 인자를 가질 수 있습니다. 이는 `/{filename}.{ext}`는 유효하지만 `/{filename}{ext}`는 유효하지 않음을 의미합니다. +이제 `/hello/mary`에 대한 요청은 `Hello mary!`로 응답하고 `/hello`에 대한 요청은 `Hello stranger!`로 응답할 것입니다. 경로에서 _마지막_ 명명된 인자만이 선택적으로 될 수 있습니다. 선택적 인자 뒤에 다른 인자가 있기 때문에 `/{one?}/{two}`는 무효한 경로임을 의미합니다. 경로의 부분에서 일부분을 다루는 명명된 인자를 가질 수 있습니다. 예를 들어 `/{filename}.jpg`는 유효합니다. 한 부분에서 인자 사이에 인자가 아닌 구분자가 제공되면 여러 인자를 가질 수 있습니다. 이는 `/{filename}.{ext}`는 유효하지만 `/{filename}{ext}`는 유효하지 않음을 의미합니다. ### 복수 부분 인자 @@ -74,19 +74,18 @@ server.route({ ```javascript server.route({ - method: 'GET', - path: '/hello/{user*2}', - handler: function (request, h) { - - const userParts = request.params.user.split('/'); - return `Hello ${encodeURIComponent(userParts[0])} ${encodeURIComponent(userParts[1])}!`; - } + method: 'GET', + path: '/hello/{user*2}', + handler: function (request, h) { + const userParts = request.params.user.split('/'); + return `Hello ${encodeURIComponent(userParts[0])} ${encodeURIComponent(userParts[1])}!`; + }, }); ``` -이 설정으로 `/hello/john/doe`에 대한 요청은 문자열 `Hello john doe!` 응답을 받을 것입니다. 중요한 것은 인자는 `"john/doe"` 문자열이라는 것입니다. 그래서 두 개의 분리된 부분을 얻기 위해 그 글자로 나누었습니다. 별표 뒤에 숫자는 인자에 할당될 경로 부분의 개수를 나타냅니다. 숫자를 생략할 수도 있습니다. 그러면 인자는 가능한 부분의 개수와 일치합니다. 선택적 인자같이 복수 부분 인자는(예 `/{files*}`) *오직* 경로의 마지막 인자로만 나타날 수 있습니다. +이 설정으로 `/hello/john/doe`에 대한 요청은 문자열 `Hello john doe!` 응답을 받을 것입니다. 중요한 것은 인자는 `"john/doe"` 문자열이라는 것입니다. 그래서 두 개의 분리된 부분을 얻기 위해 그 글자로 나누었습니다. 별표 뒤에 숫자는 인자에 할당될 경로 부분의 개수를 나타냅니다. 숫자를 생략할 수도 있습니다. 그러면 인자는 가능한 부분의 개수와 일치합니다. 선택적 인자같이 복수 부분 인자는(예 `/{files*}`) _오직_ 경로의 마지막 인자로만 나타날 수 있습니다. -특정 요청에 대한 처리기를 결정할 때 hapi는 가장 구체적인 것부터 덜 구체적인 순서로 경로를 찾습니다. 만약 하나는 `/filename.jpg`와 다른 하나는 `/filename.{ext}` 이렇게 2개의 라우트를 가지고 있다면 `filename.jpg`에 대한 요청은 첫 번째 라우트에 일치하고 두 번째 라우트에는 일치하지 않습니다. `/{files*}` 경로의 라우트는 테스트 되는 *마지막* 라우트가 될 것이고 다른 라우트가 모두 실패할 경우에만 일치한다는 것을 의미합니다. +특정 요청에 대한 처리기를 결정할 때 hapi는 가장 구체적인 것부터 덜 구체적인 순서로 경로를 찾습니다. 만약 하나는 `/filename.jpg`와 다른 하나는 `/filename.{ext}` 이렇게 2개의 라우트를 가지고 있다면 `filename.jpg`에 대한 요청은 첫 번째 라우트에 일치하고 두 번째 라우트에는 일치하지 않습니다. `/{files*}` 경로의 라우트는 테스트 되는 _마지막_ 라우트가 될 것이고 다른 라우트가 모두 실패할 경우에만 일치한다는 것을 의미합니다. ## Handler 메소드 @@ -94,7 +93,7 @@ handler 옵션은 `request`와 `h` 2개의 인자를 받습니다. `request` 인자는 경로 인자,연관된 페이로드, 인증 정보, 헤더 같은 최종 사용자에 대한 자세한 정보를 가진 객체입니다. `request` 객체에 대한 전체 문서는 [API reference](/api#request-properties)에서 찾을 수 있습니다. -두 번째 인자인 `h`는 요청에 응답하기 위해 사용하는 몇 가지 메소드를 가지고 있는 객체인 응답 도구입니다. 앞의 예제에서 본 것처럼 요청에 어떤 값으로 응답하기를 원하면 처리기에서 단순히 그 값을 반환하면 됩니다. payload는 문자열, 버퍼, 직렬화된 JSON 객체, 스트림 또는 Promise 이어야 합니다. +두 번째 인자인 `h`는 요청에 응답하기 위해 사용하는 몇 가지 메소드를 가지고 있는 객체인 응답 도구입니다. 앞의 예제에서 본 것처럼 요청에 어떤 값으로 응답하기를 원하면 처리기에서 단순히 그 값을 반환하면 됩니다. payload는 문자열, 버퍼, 직렬화된 JSON 객체, 스트림 또는 Promise 이어야 합니다. 또는 같은 값을 `h.response(value)`에 전달하고 처리기에서 반환하면 됩니다. 이 호출의 결과는 응답 객체이고 이 객체는 응답을 전송하기 전에 응답을 변경하는 추가적인 메소드로 연결될 수 있습니다. 예를 들어 `h.response('created').code(201)`은 HTTP 상태 코드 `201`과 함께 `created`의 payload를 전송할 것입니다. 헤더, 내용물 종류, 내용물 길이를 설정하거나 리다이렉션 응답을 전송할 수 있습니다. 많은 다른 것들에 대해서는 [API reference](/api#response-toolkit)에 정리되어 있습니다. @@ -106,21 +105,18 @@ handler 옵션은 `request`와 `h` 2개의 인자를 받습니다. ```javascript server.route({ - method: 'GET', - path: '/hello/{user?}', - handler: function (request, h) { - - const user = request.params.user ? - encodeURIComponent(request.params.user) : - 'stranger'; - - return `Hello ${user}!`; - }, - options: { - description: 'Say hello!', - notes: 'The user parameter defaults to \'stranger\' if unspecified', - tags: ['api', 'greeting'] - } + method: 'GET', + path: '/hello/{user?}', + handler: function (request, h) { + const user = request.params.user ? encodeURIComponent(request.params.user) : 'stranger'; + + return `Hello ${user}!`; + }, + options: { + description: 'Say hello!', + notes: "The user parameter defaults to 'stranger' if unspecified", + tags: ['api', 'greeting'], + }, }); ``` diff --git a/static/lib/tutorials/ko_KR/servermethods.md b/docs/tutorials/ko_KR/server-methods.md similarity index 74% rename from static/lib/tutorials/ko_KR/servermethods.md rename to docs/tutorials/ko_KR/server-methods.md index 41d0a4c5..36c46cf9 100644 --- a/static/lib/tutorials/ko_KR/servermethods.md +++ b/docs/tutorials/ko_KR/server-methods.md @@ -1,13 +1,18 @@ +--- +title: Server Methods +--- + + + ## Server methods _이 튜터리얼은 hapi v17과 호환됩니다._ -서버 메소드는 필요한 곳에서 공통 모듈을 요구하지 않고 서버 객체에 함수를 첨부하여 공유하는 유용한 방법입니다. 서버 메소드를 등록하려면 [`server.method()`](https://hapijs.com/api#server.method())를 호출합니다. 이 함수를 호출하는 두 가지 다른 방법이 있습니다. `server.method(name, method, [options])` 형식으로 호출할 수 있습니다. 예를 들면: +서버 메소드는 필요한 곳에서 공통 모듈을 요구하지 않고 서버 객체에 함수를 첨부하여 공유하는 유용한 방법입니다. 서버 메소드를 등록하려면 [`server.method()`]()를 호출합니다. 이 함수를 호출하는 두 가지 다른 방법이 있습니다. `server.method(name, method, [options])` 형식으로 호출할 수 있습니다. 예를 들면: ```javascript const add = function (x, y) { - - return x + y; + return x + y; }; server.method('add', add, {}); @@ -17,14 +22,13 @@ server.method('add', add, {}); ```javascript const add = function (x, y) { - - return x + y; + return x + y; }; server.method({ - name: 'add', - method: add, - options: {} + name: 'add', + method: add, + options: {}, }); ``` @@ -44,9 +48,8 @@ server.method('math.add', add); ```js const add = async function (x, y) { - - const result = await someLongRunningFunction(x, y); - return result; + const result = await someLongRunningFunction(x, y); + return result; }; server.method('add', add, {}); @@ -60,45 +63,44 @@ server.method('add', add, {}); ```javascript server.method('add', add, { - cache: { - expiresIn: 60000, - expiresAt: '20:30', - staleIn: 30000, - staleTimeout: 10000, - generateTimeout: 100 - } + cache: { + expiresIn: 60000, + expiresAt: '20:30', + staleIn: 30000, + staleTimeout: 10000, + generateTimeout: 100, + }, }); ``` 인자의 의미: -* `expiresIn`: 캐시에 항목이 저장된 이후 밀리 초 단위로 표현된 상대적인 만료시간. `expiresAt`과 같이 사용할 수 없습니다. -* `expiresAt`: route의 모든 캐시 레코드가 만료될 'HH:MM' 형식의 24시간 표기법으로 표현된 시간. 지역 시간을 사용합니다. `expiresIn`과 같이 사용할 수 없습니다. -* `staleIn`: 캐시에 저장된 항목을 신선하지 않음을 표시하고 다시 생성하려는 밀리 초 단위 시간. `expiresIn`보다 작아야 합니다. -* `staleTimeout`: generateFunc가 새로운 값을 생성하는 동안 신선하지 않은 값을 반환하기 전에 기다리는 밀리 초 단위 시간. -* `generateTimeout`: 값을 반환하는데 너무 오랜 시간이 걸려 시간 초과 에러를 반환하기 전에 기다리는 밀리 초 단위 시간. 값이 최종적으로 반환되면 이후 요청을 위해 캐시에 저장합니다. -* `segment`: 캐시 항목을 분리하는데 사용되는 선택적 부분 이름입니다. -* `cache`: 사용할 서버에 설정된 캐시 연결의 이름을 가진 선택적 문자열입니다. +- `expiresIn`: 캐시에 항목이 저장된 이후 밀리 초 단위로 표현된 상대적인 만료시간. `expiresAt`과 같이 사용할 수 없습니다. +- `expiresAt`: route의 모든 캐시 레코드가 만료될 'HH:MM' 형식의 24시간 표기법으로 표현된 시간. 지역 시간을 사용합니다. `expiresIn`과 같이 사용할 수 없습니다. +- `staleIn`: 캐시에 저장된 항목을 신선하지 않음을 표시하고 다시 생성하려는 밀리 초 단위 시간. `expiresIn`보다 작아야 합니다. +- `staleTimeout`: generateFunc가 새로운 값을 생성하는 동안 신선하지 않은 값을 반환하기 전에 기다리는 밀리 초 단위 시간. +- `generateTimeout`: 값을 반환하는데 너무 오랜 시간이 걸려 시간 초과 에러를 반환하기 전에 기다리는 밀리 초 단위 시간. 값이 최종적으로 반환되면 이후 요청을 위해 캐시에 저장합니다. +- `segment`: 캐시 항목을 분리하는데 사용되는 선택적 부분 이름입니다. +- `cache`: 사용할 서버에 설정된 캐시 연결의 이름을 가진 선택적 문자열입니다. 캐싱 옵션에 대한 자세한 정보는 [API Reference](/api#servermethodmethod)와 [catbox](https://github.com/hapijs/catbox#policy)의 문서를 참고해주세요. -`ttl` flag 설정으로 호출마다 서버 메소드 결과의 `ttl`(time-to-live) 값을 덮어 쓸 수 있습니다. 앞의 예제에서 어떻게 동작하는지 보겠습니다. +`ttl` flag 설정으로 호출마다 서버 메소드 결과의 `ttl`(time-to-live) 값을 덮어 쓸 수 있습니다. 앞의 예제에서 어떻게 동작하는지 보겠습니다. ```js const add = async function (x, y, flags) { + const result = await someLongRunningFunction(x, y); - const result = await someLongRunningFunction(x, y); + flags.ttl = 5 * 60 * 1000; // 5 mins - flags.ttl = 5 * 60 * 1000; // 5 mins - - return result; + return result; }; server.method('add', add, { - cache: { - expiresIn: 2000, - generateTimeout: 100 - } + cache: { + expiresIn: 2000, + generateTimeout: 100, + }, }); server.methods.add(5, 12); @@ -112,19 +114,17 @@ server.methods.add(5, 12); ```javascript const sum = function (array) { + let total = 0; - let total = 0; - - array.forEach((item) => { + array.forEach((item) => { + total += item; + }); - total += item; - }); - - return total; + return total; }; server.method('sum', sum, { - generateKey: (array) => array.join(',') + generateKey: (array) => array.join(','), }); ``` @@ -132,14 +132,13 @@ server.method('sum', sum, { ### Bind -서버 메소드에서 사용가능한 마지막 옵션은 `bind`입니다. `bind` 옵션은 메소드 안에서 `this` 값을 변경합니다. 메소드가 추가될 때 현재 활성 컨텍스트를 기본 설정됩니다. 이는 사용자 `generateKey` 함수에서 필요한 데이터베이스 클라이언트를 인자로 전달하지 않고 데이터베이스 클라이언트를 다음처럼 전달할 때 유용합니다.: +서버 메소드에서 사용가능한 마지막 옵션은 `bind`입니다. `bind` 옵션은 메소드 안에서 `this` 값을 변경합니다. 메소드가 추가될 때 현재 활성 컨텍스트를 기본 설정됩니다. 이는 사용자 `generateKey` 함수에서 필요한 데이터베이스 클라이언트를 인자로 전달하지 않고 데이터베이스 클라이언트를 다음처럼 전달할 때 유용합니다.: ```javascript const lookup = async function (id) { + // calls myDB.getOne - // calls myDB.getOne - - return await this.getOne({ id }); + return await this.getOne({ id }); }; server.method('lookup', lookup, { bind: myDB }); diff --git a/static/lib/tutorials/ko_KR/servingfiles.md b/docs/tutorials/ko_KR/serving-files.md similarity index 66% rename from static/lib/tutorials/ko_KR/servingfiles.md rename to docs/tutorials/ko_KR/serving-files.md index 92235976..495d2a20 100644 --- a/static/lib/tutorials/ko_KR/servingfiles.md +++ b/docs/tutorials/ko_KR/serving-files.md @@ -1,3 +1,9 @@ +--- +title: Serving Files +--- + + + ## 정적 파일 제공하기 _이 튜터리얼은 hapi v17과 호환됩니다._ @@ -14,21 +20,19 @@ _이 튜터리얼은 hapi v17과 호환됩니다._ ```javascript const start = async () => { + await server.register(require('@hapi/inert')); - await server.register(require('@hapi/inert')); - - server.route({ - method: 'GET', - path: '/picture.jpg', - handler: function (request, h) { - - return h.file('/path/to/picture.jpg'); - } - }); + server.route({ + method: 'GET', + path: '/picture.jpg', + handler: function (request, h) { + return h.file('/path/to/picture.jpg'); + }, + }); - await server.start(); + await server.start(); - console.log('Server running at:', server.info.uri); + console.log('Server running at:', server.info.uri); }; start(); @@ -47,35 +51,33 @@ const Hapi = require('@hapi/hapi'); const Path = require('path'); const server = Hapi.server({ - routes: { - files: { - relativeTo: Path.join(__dirname, 'public') - } - } + routes: { + files: { + relativeTo: Path.join(__dirname, 'public'), + }, + }, }); const start = async () => { + await server.register(require('@hapi/inert')); - await server.register(require('@hapi/inert')); - - server.route({ - method: 'GET', - path: '/picture.jpg', - handler: function (request, h) { - - return h.file('picture.jpg'); - } - }); + server.route({ + method: 'GET', + path: '/picture.jpg', + handler: function (request, h) { + return h.file('picture.jpg'); + }, + }); - await server.start(); + await server.start(); - console.log('Server running at:', server.info.uri); + console.log('Server running at:', server.info.uri); }; start(); ``` -위와 같이 `server.options.routes` 아래의 옵션을 설정하면 _모든_ 경로에 적용될 것입니다. 경로 수준에서 `relativeTo` 옵션을 포함하여 이 옵션을 설정할 수 있습니다. +위와 같이 `server.options.routes` 아래의 옵션을 설정하면 _모든_ 경로에 적용될 것입니다. 경로 수준에서 `relativeTo` 옵션을 포함하여 이 옵션을 설정할 수 있습니다. ## 파일 핸들러(handler) @@ -83,11 +85,11 @@ start(); ```javascript server.route({ - method: 'GET', - path: '/picture.jpg', - handler: { - file: 'picture.jpg' - } + method: 'GET', + path: '/picture.jpg', + handler: { + file: 'picture.jpg', + }, }); ``` @@ -97,13 +99,13 @@ server.route({ ```javascript server.route({ - method: 'GET', - path: '/{filename}', - handler: { - file: function (request) { - return request.params.filename; - } - } + method: 'GET', + path: '/{filename}', + handler: { + file: function (request) { + return request.params.filename; + }, + }, }); ``` @@ -111,64 +113,65 @@ server.route({ ```javascript server.route({ - method: 'GET', - path: '/script.js', - handler: { - file: { - path: 'script.js', - filename: 'client.js', // override the filename in the Content-Disposition header - mode: 'attachment', // specify the Content-Disposition is an attachment - lookupCompressed: true // allow looking for script.js.gz if the request allows it - } - } + method: 'GET', + path: '/script.js', + handler: { + file: { + path: 'script.js', + filename: 'client.js', // override the filename in the Content-Disposition header + mode: 'attachment', // specify the Content-Disposition is an attachment + lookupCompressed: true, // allow looking for script.js.gz if the request allows it + }, + }, }); ``` ## 디렉터리 핸들러 -`file` 핸들러 외에 inert는 여러 파일을 제공하는 하나의 경로를 지정할 수 있는 `directory` 핸들러를 추가했습니다. 이를 사용하려면 인자를 가진 경로를 지정해야 합니다. 그러나 인자의 이름은 중요하지 않습니다. 인자에 별표(*) 확장을 사용하여 파일 깊이도 제약할 수 있습니다. directory 핸들러의 가장 기본적인 사용법은 다음과 같습니다.: +`file` 핸들러 외에 inert는 여러 파일을 제공하는 하나의 경로를 지정할 수 있는 `directory` 핸들러를 추가했습니다. 이를 사용하려면 인자를 가진 경로를 지정해야 합니다. 그러나 인자의 이름은 중요하지 않습니다. 인자에 별표(\*) 확장을 사용하여 파일 깊이도 제약할 수 있습니다. directory 핸들러의 가장 기본적인 사용법은 다음과 같습니다.: ```javascript server.route({ - method: 'GET', - path: '/{param*}', - handler: { - directory: { - path: 'directory-path-here' - } - } + method: 'GET', + path: '/{param*}', + handler: { + directory: { + path: 'directory-path-here', + }, + }, }); ``` ### 디렉터리 핸들러 옵션 위의 경로는 `directory-path-here` 디렉터리 안의 일치하는 파일 이름을 찾아 요청에 응답합니다. 이 설정에서 `/`에 대한 요청은 HTTP `403`으로 응답할 것입니다. index 파일을 추가하여 이를 수정할 수 있습니다. 기본으로 hapi는 `index.html`으로 불리는 파일을 디렉터리에서 찾을 것입니다. index 옵션을 `false`로 설정하여 index 파일을 제공하지 않도록 할 수 있습니다. 또는 inert가 index 파일로 찾을 파일의 배열을 지정할 수 있습니다. - + ```javascript server.route({ - method: 'GET', - path: '/{param*}', - handler: { - directory: { - path: 'directory-path-here', - index: ['index.html', 'default.html'] - } - } + method: 'GET', + path: '/{param*}', + handler: { + directory: { + path: 'directory-path-here', + index: ['index.html', 'default.html'], + }, + }, }); ``` -`/`에 대한 요청은 먼저 `/index.html`을 불러오려고 시도할 것이고, 그 다음에는 `/default.html`을 시도할 것입니다. 사용가능한 index 파일이 없다면 inert는 디렉터리의 내용을 목록 페이지로 보여줄 것입니다. 다음과 같이 `listing` 속성을 `true`로 설정하여 활성화 할 수 있습니다.: +`/`에 대한 요청은 먼저 `/index.html`을 불러오려고 시도할 것이고, 그 다음에는 `/default.html`을 시도할 것입니다. 사용가능한 index 파일이 없다면 inert는 디렉터리의 내용을 목록 페이지로 보여줄 것입니다. 다음과 같이 `listing` 속성을 `true`로 설정하여 활성화 할 수 있습니다.: ```javascript server.route({ - method: 'GET', - path: '/{param*}', - handler: { - directory: { - path: 'directory-path-here', - listing: true - } - } + method: 'GET', + path: '/{param*}', + handler: { + directory: { + path: 'directory-path-here', + listing: true, + }, + }, }); ``` + 이제 `/`에 대한 요청은 디렉터리의 내용을 보여주는 HTML로 응답할 것입니다. 목록이 활성화된 directory 핸들러를 사용할 때, 기본으로 숨겨진 파일들은 목록에서 보이지 않습니다. `showHidden` 옵션을 `true`로 설정하는 것으로 변경할 수 있습니다. file 핸들러처럼 directory 핸들러 또한 가능한 경우 미리 압축된 파일을 제공하는 `lookupCompressed` 옵션을 가지고 있습니다. 원래 경로를 찾지 못할 경우 요청에 추가되는 `defaultExtension` 옵션을 설정할 수 있습니다. `/bacon`에 대한 요청은 파일 `/bacon.html`에 대해서도 시도할 것입니다. diff --git a/static/lib/tutorials/tr_TR/testing.md b/docs/tutorials/ko_KR/testing.md similarity index 53% rename from static/lib/tutorials/tr_TR/testing.md rename to docs/tutorials/ko_KR/testing.md index e25dee5f..4cf0e0bd 100644 --- a/static/lib/tutorials/tr_TR/testing.md +++ b/docs/tutorials/ko_KR/testing.md @@ -1,5 +1,11 @@ +--- +title: Testing +--- + + + # Testing ## No Translation Yet -This tutorial has not been translated yet. If you would like to translate it, please submit a pull request. \ No newline at end of file +This tutorial has not been translated yet. If you would like to translate it, please submit a pull request. diff --git a/static/lib/tutorials/ko_KR/validation.md b/docs/tutorials/ko_KR/validation.md similarity index 79% rename from static/lib/tutorials/ko_KR/validation.md rename to docs/tutorials/ko_KR/validation.md index 243334d9..186c1e3d 100644 --- a/static/lib/tutorials/ko_KR/validation.md +++ b/docs/tutorials/ko_KR/validation.md @@ -1,3 +1,9 @@ +--- +title: Validation +--- + + + ## 유효성 검사 _이 튜터리얼은 hapi v17과 호환됩니다._ @@ -12,19 +18,18 @@ hapi가 실행하는 첫 번째 유형의 유효성 검사는 입력 유효성 ```javascript server.route({ - method: 'GET', - path: '/hello/{name}', - handler: function (request, h) { - - return `Hello ${request.params.name}!`; + method: 'GET', + path: '/hello/{name}', + handler: function (request, h) { + return `Hello ${request.params.name}!`; + }, + options: { + validate: { + params: { + name: Joi.string().min(3).max(10), + }, }, - options: { - validate: { - params: { - name: Joi.string().min(3).max(10) - } - } - } + }, }); ``` @@ -36,9 +41,9 @@ server.route({ ```json { - "error": "Bad Request", - "message": "Invalid request params input", - "statusCode": 400 + "error": "Bad Request", + "message": "Invalid request params input", + "statusCode": 400 } ``` @@ -46,31 +51,30 @@ server.route({ ### 질의 인자 -질의 인자의 유효성을 검사하려면 route 옵션에 `validate.query` 옵션을 지정하면 유사한 효과가 나타날 것입니다. 기본으로 hapi는 아무 유효성 검사를 하지 않습니다. 하나의 질의 인자에 대한 유효성 검사를 지정하면 받아들일 수 있는 모든 질의 인자들에 대한 유효성 검사기를 *반드시* 지정해야 합니다. +질의 인자의 유효성을 검사하려면 route 옵션에 `validate.query` 옵션을 지정하면 유사한 효과가 나타날 것입니다. 기본으로 hapi는 아무 유효성 검사를 하지 않습니다. 하나의 질의 인자에 대한 유효성 검사를 지정하면 받아들일 수 있는 모든 질의 인자들에 대한 유효성 검사기를 _반드시_ 지정해야 합니다. 예를 들면 블로그 글의 목록을 반환하는 route를 가지고 있고 사용자가 결과의 개수를 제한하려는 경우 다음 설정을 사용할 수 있습니다.: ```javascript server.route({ - method: 'GET', - path: '/posts', - handler: function (request, h) { - - return posts.slice(0, request.query.limit); + method: 'GET', + path: '/posts', + handler: function (request, h) { + return posts.slice(0, request.query.limit); + }, + options: { + validate: { + query: { + limit: Joi.number().integer().min(1).max(100).default(10), + }, }, - options: { - validate: { - query: { - limit: Joi.number().integer().min(1).max(100).default(10) - } - } - } + }, }); ``` `limit` 질의 인자는 항상 1과 100 사이의 정수인 것을 확인하고, 만약 없다면 기본값으로 10을 설정합니다. `/list?limit=15&offset=15`로 요청하면 HTTP `400` 응답을 다음과 같이 받을 것입니다. -`offset` 인자가 허락되지 않기때문에 에러를 받았습니다. `limit` 인자의 유효성 검사를 제공했지만 `offset`에 대한 유효성 검사기를 제공하지 않았기 때문입니다. +`offset` 인자가 허락되지 않기때문에 에러를 받았습니다. `limit` 인자의 유효성 검사를 제공했지만 `offset`에 대한 유효성 검사기를 제공하지 않았기 때문입니다. ### 헤더 @@ -93,10 +97,11 @@ hapi는 출력 유효성 검사를 세밀하게 조정할 수 있는 몇 가지 ### response.failAction `response.failAction`을 다음 중 하나로 설정하여 응답 유효성 검사가 실패할 때 수행할 작업을 선택할 수 있습니다. -* `error`: 내부 서버 에러 (500) 응답을 전송합니다. (기본) -* `log`: 공격을 기록하고 그대로 응답을 전송합니다. -* `ignore`: 아무 행동을 하지 않고 요청 처리를 계속 합니다. -* `request`는 요청 객체, `h`는 응답 도구, `err`이 유효성 에러인 async function(request, h, err)` 형식의 라이프사이클 메소드 + +- `error`: 내부 서버 에러 (500) 응답을 전송합니다. (기본) +- `log`: 공격을 기록하고 그대로 응답을 전송합니다. +- `ignore`: 아무 행동을 하지 않고 요청 처리를 계속 합니다. +- `request`는 요청 객체, `h`는 응답 도구, `err`이 유효성 에러인 async function(request, h, err)` 형식의 라이프사이클 메소드 ### response.sample @@ -105,8 +110,9 @@ hapi는 출력 유효성 검사를 세밀하게 조정할 수 있는 몇 가지 ### response.status 때때로 하나의 단말이 여러 응답 객체를 제공할 수 있습니다. 예를 들어 `POST` route는 다음 중 하나를 반환할 수 있습니다.: -* 새로운 자원이 생성되었다면 새로 생성된 자원과 함께 `201` -* 기존에 있던 자원이 갱신된 경우 이전 값과 새 값을 함께 `202` + +- 새로운 자원이 생성되었다면 새로 생성된 자원과 함께 `201` +- 기존에 있던 자원이 갱신된 경우 이전 값과 새 값을 함께 `202` hapi는 각 응답 코드에 대해 다른 유효성 검사를 지정하는 것을 제공합니다. `response.status`는 숫자 상태 코드인 키와 joi 스키마인 속성을 가진 객체입니다.: @@ -122,6 +128,7 @@ hapi는 각 응답 코드에 대해 다른 유효성 검사를 지정하는 것 ``` ### response.options + 유효성 검사중에 joi에 전달할 옵션입니다. 자세한 내용은 [API docs](/api#-routeoptionsresponseoptions)를 봐주세요. ### Example @@ -130,31 +137,29 @@ hapi는 각 응답 코드에 대해 다른 유효성 검사를 지정하는 것 ```javascript const bookSchema = Joi.object({ - title: Joi.string().required(), - author: Joi.string().required(), - isbn: Joi.string().length(10), - pageCount: Joi.number(), - datePublished: Joi.date().iso() + title: Joi.string().required(), + author: Joi.string().required(), + isbn: Joi.string().length(10), + pageCount: Joi.number(), + datePublished: Joi.date().iso(), }); server.route({ - method: 'GET', - path: '/books', - handler: async function (request, h) { - - return await getBooks(); + method: 'GET', + path: '/books', + handler: async function (request, h) { + return await getBooks(); + }, + options: { + response: { + sample: 50, + schema: Joi.array().items(bookSchema), }, - options: { - response: { - sample: 50, - schema: Joi.array().items(bookSchema) - } - } + }, }); - ``` -응답의 반만 유효성을 검사합니다. (`sample: 50`) `response.failAction`이 설정되지 않았기 때문에 `books`가 `bookSchema`에 정확히 일치하지 않으면 hapi는 `500` 에러 코드를 응답할 것입니다. 에러 응답은 에러의 이유를 표지하지 *않습니다*. 로깅이 설정되어 있으면 응답 유효성 검사가 실패 원인의 정보를 에러 로그에서 확인할 수 있습니다. `response.failAction`이 `log`로 설정되었다면 hapi는 원래 페이로드로 응답을 하고 유효성 검사 에러를 기록할 것입니다. +응답의 반만 유효성을 검사합니다. (`sample: 50`) `response.failAction`이 설정되지 않았기 때문에 `books`가 `bookSchema`에 정확히 일치하지 않으면 hapi는 `500` 에러 코드를 응답할 것입니다. 에러 응답은 에러의 이유를 표지하지 _않습니다_. 로깅이 설정되어 있으면 응답 유효성 검사가 실패 원인의 정보를 에러 로그에서 확인할 수 있습니다. `response.failAction`이 `log`로 설정되었다면 hapi는 원래 페이로드로 응답을 하고 유효성 검사 에러를 기록할 것입니다. ### Joi의 대안 diff --git a/static/lib/tutorials/ko_KR/views.md b/docs/tutorials/ko_KR/views.md similarity index 81% rename from static/lib/tutorials/ko_KR/views.md rename to docs/tutorials/ko_KR/views.md index e6fd1903..0e182771 100644 --- a/static/lib/tutorials/ko_KR/views.md +++ b/docs/tutorials/ko_KR/views.md @@ -1,3 +1,9 @@ +--- +title: Views +--- + + + ## Views _이 튜터리얼은 hapi v17과 호환됩니다._ @@ -18,16 +24,15 @@ const Hoek = require('@hapi/hoek'); const server = Hapi.server(); const start = async () => { + await server.register(require('@hapi/vision')); - await server.register(require('@hapi/vision')); - - server.views({ - engines: { - html: require('handlebars') - }, - relativeTo: __dirname, - path: 'templates' - }); + server.views({ + engines: { + html: require('handlebars'), + }, + relativeTo: __dirname, + path: 'templates', + }); }; start(); @@ -37,7 +42,7 @@ start(); 두 번째 `handlebars` 모듈을 `.html` 확장자를 가진 템플릿을 렌더링을 담당하는 엔진으로 등록합니다. -그 다음 현재 경로의 `templates` 디렉터리에 템플릿이 있음을 서버에게 알립니다. `relativeTo` 옵션을 제공하여 현재 디렉터리의 상대 경로로 이 디렉터리를 가리킬 수 있습니다. 기본적으로 hapi는 현재 작업 디렉터리에서 템플릿을 찾습니다. +그 다음 현재 경로의 `templates` 디렉터리에 템플릿이 있음을 서버에게 알립니다. `relativeTo` 옵션을 제공하여 현재 디렉터리의 상대 경로로 이 디렉터리를 가리킬 수 있습니다. 기본적으로 hapi는 현재 작업 디렉터리에서 템플릿을 찾습니다. ### View options @@ -47,13 +52,13 @@ hapi에서 view 엔진에 대한 여러가지 옵션이 있습니다. 전체 문 ```javascript server.views({ - engines: { - html: { - module: require('handlebars'), - compileMode: 'sync' // engine specific - } + engines: { + html: { + module: require('handlebars'), + compileMode: 'sync', // engine specific }, - compileMode: 'async' // global setting + }, + compileMode: 'async', // global setting }); ``` @@ -63,13 +68,13 @@ hapi에서 view를 사용하려면 서버에 최소한 하나의 템플릿 엔 동기적 엔진을 위한 `compile` 메소드는 `function (template, options)`이며 에러를 던지거나 컴파일된 html을 반환하는 `function (context, option)` 형태의 함수를 반환합니다. -비동기적 템플릿 엔진은 `function (template, options, callback)` 형태의 `compile` 메소드를 가지고 있습니다. 이 메소드는 표준 에러를 첫 인자로 가지는 `callback`을 호출하고 `function(context, options, callback)` 형태의 새로운 메소드를 반환합니다. 반환된 메소드는 역시 에러를 첫 인자로, 컴파일된 html을 두 번째 인자로 가지는 콜백을 호출합니다. +비동기적 템플릿 엔진은 `function (template, options, callback)` 형태의 `compile` 메소드를 가지고 있습니다. 이 메소드는 표준 에러를 첫 인자로 가지는 `callback`을 호출하고 `function(context, options, callback)` 형태의 새로운 메소드를 반환합니다. 반환된 메소드는 역시 에러를 첫 인자로, 컴파일된 html을 두 번째 인자로 가지는 콜백을 호출합니다. 기본으로 hapi는 템플릿 엔진을 동기로 가정합니다. (즉 `compileMode`가 기본으로 `sync`) 비동기적 엔진을 사용하려면 `complieMode`를 `async`로 설정해야 합니다. `compileOptions`와 `runtimeOptions` 설정을 통해 `compile` 메소드와 그 메소드가 반환하는 두 곳에서 `options` 인자를 사용합니다. 이 두 옵션의 기본 값은 빈 객체 `{}`입니다. -`compileOptions`는 `compile`에 두 번째 인자로 전달되는 객체이고 `runtimeOptions`는 `compile` 반환하는 메소드에 전달됩니다. +`compileOptions`는 `compile`에 두 번째 인자로 전달되는 객체이고 `runtimeOptions`는 `compile` 반환하는 메소드에 전달됩니다. 하나의 템플릿 엔진만 등록되어 있으면 자동으로 기본이 되어 view를 요청할 때 파일 확장자를 생략할 수 있습니다. 그러나 둘 이상의 엔진이 등록되어 있다면 파일 확장자를 붙이거나 가장 자주 사용하는 엔진에 `defaultExtenstion`을 설정해야 합니다. 기본 엔진을 사용하지 않는 view의 경우 여전히 파일 확장자를 지정해야 합니다. @@ -85,7 +90,7 @@ view는 여러 다른 위치에 파일들을 가질 수 있기 때문에 hapi는 - `layoutPath`: 레이아웃 템플릿을 담고 있는 디렉터리 - `relativeTo`: 다른 경로에 대한 접두어로 사용. 만약 지정되었다면 다른 경로는 이 디렉터리의 상대 경로입니다. -또한 hapi가 경로를 사용하는 방법을 변경하는 두 가지 설정이 있습니다. 기본으로 절대 경로와 `path` 디렉터리의 외부로 이동은 허용되지 않습니다. 이 동작은 `allowAbsolutePaths`와 `allowInsecureAccess`를 true로 설정하여 변경할 수 있습니다. +또한 hapi가 경로를 사용하는 방법을 변경하는 두 가지 설정이 있습니다. 기본으로 절대 경로와 `path` 디렉터리의 외부로 이동은 허용되지 않습니다. 이 동작은 `allowAbsolutePaths`와 `allowInsecureAccess`를 true로 설정하여 변경할 수 있습니다. 예를 들면 다음과 같은 디렉터리 구조로 되어 있다면: @@ -103,13 +108,13 @@ templates\ ```javascript server.views({ - engines: { - html: require('handlebars') - }, - relativeTo: __dirname, - path: './templates', - layoutPath: './templates/layout', - helpersPath: './templates/helpers' + engines: { + html: require('handlebars'), + }, + relativeTo: __dirname, + path: './templates', + layoutPath: './templates/layout', + helpersPath: './templates/helpers', }); ``` @@ -123,12 +128,11 @@ view를 렌더링하는 첫 번째 방법은 `h.view()`입니다. 이 방법을 ```javascript server.route({ - method: 'GET', - path: '/', - handler: function (request, h) { - - return h.view('index'); - } + method: 'GET', + path: '/', + handler: function (request, h) { + return h.view('index'); + }, }); ``` @@ -144,11 +148,11 @@ view를 렌더링하는 두 번째 방법은 hapi의 내장 view 처리기를 ```javascript server.route({ - method: 'GET', - path: '/', - handler: { - view: 'index' - } + method: 'GET', + path: '/', + handler: { + view: 'index', + }, }); ``` @@ -167,23 +171,23 @@ handler: { ### 전역 context -view에 context를 직접 전달하는 방법을 살펴보았지만 모든 템플릿에 *항상* 사용가능한 기본 context가 있다면 어떻할까요? +view에 context를 직접 전달하는 방법을 살펴보았지만 모든 템플릿에 _항상_ 사용가능한 기본 context가 있다면 어떻할까요? 가장 간단한 방법은 `server.view()`를 호출할 때 `context` 옵션을 사용하는 것입니다. ```javascript const context = { - title: 'My personal site' + title: 'My personal site', }; server.views({ - engines: { - html: { - module: require('handlebars'), - compileMode: 'sync' // engine specific - } + engines: { + html: { + module: require('handlebars'), + compileMode: 'sync', // engine specific }, - context + }, + context, }); ``` @@ -197,22 +201,21 @@ server.views({ ```javascript module.exports = function () { - - const fortunes = [ - 'Heisenberg may have slept here...', - 'Wanna buy a duck?', - 'Say no, then negotiate.', - 'Time and tide wait for no man.', - 'To teach is to learn.', - 'Never ask the barber if you need a haircut.', - 'You will forget that you ever knew me.', - 'You will be run over by a beer truck.', - 'Fortune favors the lucky.', - 'Have a nice day!' - ]; - - const x = Math.floor(Math.random() * fortunes.length); - return fortunes[x]; + const fortunes = [ + 'Heisenberg may have slept here...', + 'Wanna buy a duck?', + 'Say no, then negotiate.', + 'Time and tide wait for no man.', + 'To teach is to learn.', + 'Never ask the barber if you need a haircut.', + 'You will forget that you ever knew me.', + 'You will be run over by a beer truck.', + 'Fortune favors the lucky.', + 'Have a nice day!', + ]; + + const x = Math.floor(Math.random() * fortunes.length); + return fortunes[x]; }; ``` @@ -220,7 +223,7 @@ module.exports = function () { ```html

    Your fortune

    -

    {{fortune}}

    +

    {{fortune}}

    ``` 이제 서버를 시작하고 브라우저가 템플릿을 (view 헬퍼를 사용한) 사용하는 route에 접근하면 헤더 바로 아래에 무작위로 선택된 행운을 가진 단락을 볼 것입니다. @@ -235,26 +238,24 @@ const Hapi = require('@hapi/hapi'); const server = Hapi.server({ port: 8080 }); const start = async () => { + await server.register(require('@hapi/vision')); - await server.register(require('@hapi/vision')); - - server.views({ - engines: { - html: require('handlebars') - }, - relativeTo: __dirname, - path: 'templates', - helpersPath: 'helpers' - }); - - server.route({ - method: 'GET', - path: '/', - handler: function (request, h) { + server.views({ + engines: { + html: require('handlebars'), + }, + relativeTo: __dirname, + path: 'templates', + helpersPath: 'helpers', + }); - return h.view('index'); - } - }); + server.route({ + method: 'GET', + path: '/', + handler: function (request, h) { + return h.view('index'); + }, + }); }; start(); @@ -268,9 +269,9 @@ vision은 view 레이아웃에 대한 내장 지원을 가지고 있습니다. ```javascript server.views({ - // ... - layout: true, - layoutPath: 'templates/layout' + // ... + layout: true, + layoutPath: 'templates/layout', }); ``` @@ -281,8 +282,8 @@ server.views({ ```html - {{{content}}} - + {{{content}}} + ``` @@ -298,8 +299,8 @@ view를 렌더링할 때 `{{content}}`는 view 콘텐츠로 바뀔 것입니다. ```javascript server.views({ - // ... - layout: 'another_default' + // ... + layout: 'another_default', }); ``` diff --git a/static/lib/tutorials/pt_BR/auth.md b/docs/tutorials/pt_BR/auth.md similarity index 86% rename from static/lib/tutorials/pt_BR/auth.md rename to docs/tutorials/pt_BR/auth.md index a451c520..e7fe4cfa 100644 --- a/static/lib/tutorials/pt_BR/auth.md +++ b/docs/tutorials/pt_BR/auth.md @@ -1,3 +1,9 @@ +--- +title: Authentication +--- + + + ## Autenticação _Este tutorial é compatível com hapi v16_ @@ -8,7 +14,6 @@ Pense num esquema como um tipo geral de autenticação, como "basic" ou "digest" Para começar, der uma olhada num exemplo de como utilizar [hapi-auth-basic](https://github.com/hapijs/hapi-auth-basic): - ```javascript 'use strict'; @@ -20,51 +25,49 @@ const server = new Hapi.Server(); server.connection({ port: 3000 }); const users = { - john: { - username: 'john', - password: '$2a$10$iqJSHD.BGr0E2IxQwYgJmeP3NvhPrXAeLSaGCj6IR/XU5QtjVu5Tm', // 'secreto' - name: 'John Doe', - id: '2133d32a' - } + john: { + username: 'john', + password: '$2a$10$iqJSHD.BGr0E2IxQwYgJmeP3NvhPrXAeLSaGCj6IR/XU5QtjVu5Tm', // 'secreto' + name: 'John Doe', + id: '2133d32a', + }, }; const validate = function (request, username, password, callback) { - const user = users[username]; - if (!user) { - return callback(null, false); - } - - Bcrypt.compare(password, user.password, (err, isValid) => { - callback(err, isValid, { id: user.id, name: user.name }); - }); + const user = users[username]; + if (!user) { + return callback(null, false); + } + + Bcrypt.compare(password, user.password, (err, isValid) => { + callback(err, isValid, { id: user.id, name: user.name }); + }); }; server.register(Basic, (err) => { - + if (err) { + throw err; + } + + server.auth.strategy('simple', 'basic', { validate }); + server.route({ + method: 'GET', + path: '/', + options: { + auth: 'simple', + handler: function (request, reply) { + reply('hello, ' + request.auth.credentials.name); + }, + }, + }); + + server.start((err) => { if (err) { - throw err; + throw err; } - server.auth.strategy('simple', 'basic', { validate }); - server.route({ - method: 'GET', - path: '/', - options: { - auth: 'simple', - handler: function (request, reply) { - reply('hello, ' + request.auth.credentials.name); - } - } - }); - - server.start((err) => { - - if (err) { - throw err; - } - - console.log('server running at: ' + server.info.uri); - }); + console.log('server running at: ' + server.info.uri); + }); }); ``` @@ -76,21 +79,18 @@ Uma vez que o plugin foi registrado, nos utilizamos [server.auth.strategy()](/ap Por último, definimos uma rota que utiliza a estratégia denominada `simple` para a autenticação. - ## Esquemas (`Schemes`) Um esquema (`scheme`) é um método com a assinatura `function (server, options)`. O parâmetros `server` é uma referência ao servidor em que o esquema está sendo adicionado, e o parâmetro `options` é o objeto de configuração fornecido quando a estratégia que utiliza este esquema foi registrada. -Este método precisa retornar um objeto com *pelo menos* a chave `authenticate`. Outros métodos que podem ser utilizados opcionalmente são `payload` e `response`. +Este método precisa retornar um objeto com _pelo menos_ a chave `authenticate`. Outros métodos que podem ser utilizados opcionalmente são `payload` e `response`. ### `authenticate` -O método `authenticate` tem a assinatura `function (request, reply)`, e é um único método *obrigatório* em um esquema. +O método `authenticate` tem a assinatura `function (request, reply)`, e é um único método _obrigatório_ em um esquema. Neste contexto, `request` é o objeto de requisição criado pelo servidor. É o mesmo objeto que se torna disponível para um manipulador de rota (`route handler`) e está documentado na [referência da API](/api#request-object). - - `reply` é a interface de resposta padrão do hapi, e aceita `err` e `result` como parâmetros (nesta ordem). Se `err` não é um valor null, isto indica uma falha da autenticação e o error poderá ser enviado como uma resposta ao usuário final. É aconselhável utilizar [boom](https://github.com/hapijs/boom) para criar este erro e simplificar o fornecimento de um apropriado `status code` e menssagem de erro. @@ -135,7 +135,7 @@ Como mencionado acima, uma estratégia é essencialmente uma cópia pré-configu Para registrar uma estratégia, precisamos primeiramente ter um esquema registrado. Uma vez que você já tenha registrado um esquema, utilize `server.auth.strategy(name, scheme, [mode], [options])` para registrar sua estratégia. -O parâmetro `name` deve ser uma string que será utilizada posteriormente para identificar esta estratégia específica. `scheme` também é uma string que é o nome do esquema cuja instância será usada na estratégia. +O parâmetro `name` deve ser uma string que será utilizada posteriormente para identificar esta estratégia específica. `scheme` também é uma string que é o nome do esquema cuja instância será usada na estratégia. ### Mode @@ -145,7 +145,7 @@ O valor padrão é `false`, o que significa que a estratégia será registrada m Se mode é definido como `true` ou `'required'`, que são iguais, a estratégia será automaticamente assinalada para todas as rotas que não contenham uma configuração `auth`. Essa configuração significa que para acessar uma rota o usuário precisa ser autenticado, e a autenticação precisa ser válida, caso contrário o usuário receberá um erro. -Se mode é definido como `'optional'` a estratégia será aplicada mesmo em rotas sem configuração `auth`, mas nesse caso o usuário *não* necessita ser autenticado. Os dados de autenticação são opcionais, mas se forem fornecidos precisam ser válidos. +Se mode é definido como `'optional'` a estratégia será aplicada mesmo em rotas sem configuração `auth`, mas nesse caso o usuário _não_ necessita ser autenticado. Os dados de autenticação são opcionais, mas se forem fornecidos precisam ser válidos. A última configuração de mode é `'try'` que também é aplicada em todas as rotas sem uma configuração `auth`. A diferença entre `'try'` e `'optional'` é que com o uso de `'try'` autenticações inválidas também são aceitas, e o usuário ainda chegará no manipulador de rota (route handler). @@ -159,7 +159,7 @@ Como previamente mencionado, o parâmetro `mode` pode ser usado com `server.auth Este método aceita um parâmetro, que pode ser uma string com o nome da estratégia a ser utilizada por padrão, ou um objeto formatado da mesma forma como os manipuladores de rota [auth options](#route-configuration). -É importante observar que a estratégia padrão é aplicada a todas as rotas, inclusive as rotas que foram definidas *antes* da chamada do método `server.auth.default()`. +É importante observar que a estratégia padrão é aplicada a todas as rotas, inclusive as rotas que foram definidas _antes_ da chamada do método `server.auth.default()`. ## Configuração de rota @@ -171,6 +171,6 @@ O parâmetro `mode` pode ser definido para `'required'`, `'optional'`, ou `'try' Ao especificar uma estratégia, você pode definir a propriedade `strategy` para uma string com o nome da estratégia. Para especificar mais que uma estratégia, o nome do parâmetro precisa ser `strategies` e deve ser um array de strings com o nome das estratégias para tentar. As estratégias serão então tentadas na ordem de sucessão até que uma tenha sucesso, ou que todas falhem. -Finalmente, o parâmetro `payload` pode ser definido como `false` indicando que o payload não será autenticado, `'required'` ou `true` indica que payload *precisa* ser autenticado, ou `'optional'` indica que se o cliente incluir informações para autenticação do payload, essa autenticação precisa ser válida. +Finalmente, o parâmetro `payload` pode ser definido como `false` indicando que o payload não será autenticado, `'required'` ou `true` indica que payload _precisa_ ser autenticado, ou `'optional'` indica que se o cliente incluir informações para autenticação do payload, essa autenticação precisa ser válida. O parâmetro `payload` só pode ser utilizado com uma estratégia que dê suporte ao método `payload` no seu esquema. diff --git a/static/lib/tutorials/pt_BR/caching.md b/docs/tutorials/pt_BR/caching.md similarity index 77% rename from static/lib/tutorials/pt_BR/caching.md rename to docs/tutorials/pt_BR/caching.md index 77979fcc..59662041 100644 --- a/static/lib/tutorials/pt_BR/caching.md +++ b/docs/tutorials/pt_BR/caching.md @@ -1,3 +1,9 @@ +--- +title: Caching +--- + + + ## Aramazenamento em cache no lado do cliente _Este tutorial é compatível com hapi v16_ @@ -12,23 +18,23 @@ Vamos ver como nos podemos colocar estes cabeçalhos no hapi: ```javascript server.route({ - path: '/hapi/{ttl?}', - method: 'GET', - handler: function (request, reply) { - - const response = reply({ be: 'hapi' }); - if (request.params.ttl) { - response.ttl(request.params.ttl); - } - }, - options: { - cache: { - expiresIn: 30 * 1000, - privacy: 'private' - } + path: '/hapi/{ttl?}', + method: 'GET', + handler: function (request, reply) { + const response = reply({ be: 'hapi' }); + if (request.params.ttl) { + response.ttl(request.params.ttl); } + }, + options: { + cache: { + expiresIn: 30 * 1000, + privacy: 'private', + }, + }, }); ``` + **Listagem 1** Setar Cache-Control no cabeçalho Na Listagem 1 ilustra que o valor `expiresIn` pode ser sobrescrito com o método `ttl(msec)` pelo [objeto de resposta](http://hapijs.com/api#response-object). @@ -46,6 +52,7 @@ Assumindo que `lastModified` é um objeto do tipo Date, é possivel definir no c ```javascript reply(result).header('Last-Modified', lastModified.toUTCString()); ``` + **Listagem 2** Configurar Last-Modified no cabeçalho Este é mais um exemplo usando `Last-Modified` na [última seção](#client-and-server-caching) deste tutorial. @@ -59,13 +66,14 @@ Você só precisa definir `ETag` no seu manipulador com a função `etag(tag, op ```javascript reply(result).etag('xxxxxxxxx'); ``` + **Listagem 3** Configurar ETag no cabeçalho Verificar o documento da `etag` no [objeto de resposta](http://hapijs.com/api#response-object) para mais detalhes sobre os parâmetros e as opções desponíveis. ## Cacheando no lado do servidor -hapi fornece um sistema de cache poderoso do lado do servidor via [catbox](https://www.github.com/hapijs/catbox) e torna o uso do cache bem mais confiavel. Este seção do tutorial vai ajudar você a entender como o catbox é utilizado dentro do hapi e como você pode influênciar nele. +hapi fornece um sistema de cache poderoso do lado do servidor via [catbox](https://www.github.com/hapijs/catbox) e torna o uso do cache bem mais confiavel. Este seção do tutorial vai ajudar você a entender como o catbox é utilizado dentro do hapi e como você pode influênciar nele. Catbox tem duas interfaces; client e policy. @@ -81,26 +89,27 @@ hapi sempre incializa com um [client](http://github.com/hapijs/catbox#client) pa const Hapi = require('hapi'); const server = new Hapi.Server({ - cache: [ - { - name: 'mongoCache', - engine: require('catbox-mongodb'), - host: '127.0.0.1', - partition: 'cache' - }, - { - name: 'redisCache', - engine: require('catbox-redis'), - host: '127.0.0.1', - partition: 'cache' - } - ] + cache: [ + { + name: 'mongoCache', + engine: require('catbox-mongodb'), + host: '127.0.0.1', + partition: 'cache', + }, + { + name: 'redisCache', + engine: require('catbox-redis'), + host: '127.0.0.1', + partition: 'cache', + }, + ], }); server.connection({ - port: 8000 + port: 8000, }); ``` + **Listagem 4** Definindo catbox clients Na Listagem 4, nós definimos 2 catbox clients; mongoCache e redisCache. Incluindo o memory cache padrão criada pelo hapi, existem três cliente de cache disponivel. Você pode replicar o cliente padrão por omitindo a propriedade `name` quando estiver registrando o novo cliente de cache. `partition` diz ao adaptador como o cache deve ser nomeado ('catbox' por padrão). Em caso de [mongoDB](http://www.mongodb.org) é o nome do banco de dados, em caso de [redis](http://redis.io/) é usado o prefixo da chave. @@ -111,37 +120,34 @@ Na Listagem 4, nós definimos 2 catbox clients; mongoCache e redisCache. Incluin ```javascript const add = function (a, b, next) { - - return next(null, Number(a) + Number(b)); + return next(null, Number(a) + Number(b)); }; const sumCache = server.cache({ - cache: 'mongoCache', - expiresIn: 20 * 1000, - segment: 'customSegment', - generateFunc: function (id, next) { - - add(id.a, id.b, next); - }, - generateTimeout: 100 + cache: 'mongoCache', + expiresIn: 20 * 1000, + segment: 'customSegment', + generateFunc: function (id, next) { + add(id.a, id.b, next); + }, + generateTimeout: 100, }); server.route({ - path: '/add/{a}/{b}', - method: 'GET', - handler: function (request, reply) { - - const id = request.params.a + ':' + request.params.b; - sumCache.get({ id: id, a: request.params.a, b: request.params.b }, (err, result) => { - - if (err) { - return reply(err); - } - reply(result); - }); - } + path: '/add/{a}/{b}', + method: 'GET', + handler: function (request, reply) { + const id = request.params.a + ':' + request.params.b; + sumCache.get({ id: id, a: request.params.a, b: request.params.b }, (err, result) => { + if (err) { + return reply(err); + } + reply(result); + }); + }, }); ``` + **Listagem 5** Usando `server.cache` `cache` diz ao hapi como user o [client](https://github.com/hapijs/catbox#client) @@ -158,41 +164,39 @@ Mas ele pode ficar melhor que isto! Em 95% dos casos você pode user [server met ```javascript const add = function (a, b, next) { - - return next(null, Number(a) + Number(b)); + return next(null, Number(a) + Number(b)); }; server.method('sum', add, { - cache: { - cache: 'mongoCache', - expiresIn: 30 * 1000, - generateTimeout: 100 - } + cache: { + cache: 'mongoCache', + expiresIn: 30 * 1000, + generateTimeout: 100, + }, }); server.route({ - path: '/add/{a}/{b}', - method: 'GET', - handler: function (request, reply) { - - server.methods.sum(request.params.a, request.params.b, (err, result) => { - - if (err) { - return reply(err); - } - reply(result); - }); - } + path: '/add/{a}/{b}', + method: 'GET', + handler: function (request, reply) { + server.methods.sum(request.params.a, request.params.b, (err, result) => { + if (err) { + return reply(err); + } + reply(result); + }); + }, }); ``` + **Listagem 6** Usando cache via métodos do servidor [server.method()](http://hapijs.com/api#servermethodname-method-options) cria uma nova [policy](https://github.com/hapijs/catbox#policy) com `segment: '#sum'` automaticamente para nós. Além disso, o único item `id` (chave do cache) esta gerda automaticamente a partir dos parâmetros. Por padrão, ele lida com parâmetros do tipo `string`, `number` e `boolean`. Para parâmetros mais complexos, você tem que fornecer sua próprio função `generateKey` para criar os ids único baseado nos parêmetros - confira os métodos do servidor [tutorial](http://hapijs.com/tutorials/servermethods) para mais informações. ### Qual a próxima? -* De uma olhada melhor em catbox policy [options](https://github.com/hapijs/catbox#policy) e preste bastante atenção em `staleIn`, `staleTimeout`, `generateTimeout`, que aproveita todo o potencial do armazenamento em cache do catbox. -* Varifique os métodos do servidor [tutorial](http://hapijs.com/tutorials/servermethods) para mais exemplos. +- De uma olhada melhor em catbox policy [options](https://github.com/hapijs/catbox#policy) e preste bastante atenção em `staleIn`, `staleTimeout`, `generateTimeout`, que aproveita todo o potencial do armazenamento em cache do catbox. +- Varifique os métodos do servidor [tutorial](http://hapijs.com/tutorials/servermethods) para mais exemplos. ## Caheando no lado do cliente e servidor. @@ -202,19 +206,18 @@ Neste caso nós usamos `cached.stored` timestamp para adicionar no header `last- ```javascript server.route({ - path: '/add/{a}/{b}', - method: 'GET', - handler: function (request, reply) { - - server.methods.sum(request.params.a, request.params.b, (err, result, cached, report) => { - - if (err) { - return reply(err); - } - const lastModified = cached ? new Date(cached.stored) : new Date(); - return reply(result).header('last-modified', lastModified.toUTCString()); - }); - } + path: '/add/{a}/{b}', + method: 'GET', + handler: function (request, reply) { + server.methods.sum(request.params.a, request.params.b, (err, result, cached, report) => { + if (err) { + return reply(err); + } + const lastModified = cached ? new Date(cached.stored) : new Date(); + return reply(result).header('last-modified', lastModified.toUTCString()); + }); + }, }); ``` + **Listagem 7** Cacheando no lado do servidor e cliente juntos diff --git a/static/lib/tutorials/ko_KR/community.md b/docs/tutorials/pt_BR/community.md similarity index 76% rename from static/lib/tutorials/ko_KR/community.md rename to docs/tutorials/pt_BR/community.md index a651208c..b8eec564 100644 --- a/static/lib/tutorials/ko_KR/community.md +++ b/docs/tutorials/pt_BR/community.md @@ -1,3 +1,9 @@ +--- +title: Community +--- + + + # Community Tutorials ## No tutorials yet diff --git a/static/lib/tutorials/pt_BR/cookies.md b/docs/tutorials/pt_BR/cookies.md similarity index 85% rename from static/lib/tutorials/pt_BR/cookies.md rename to docs/tutorials/pt_BR/cookies.md index ac8e26ce..9c9fd5bc 100644 --- a/static/lib/tutorials/pt_BR/cookies.md +++ b/docs/tutorials/pt_BR/cookies.md @@ -1,3 +1,9 @@ +--- +title: Cookies +--- + + + ## Cookies _Este tutorial é compatível com hapi v16_ @@ -12,12 +18,12 @@ Para configurá-los, invoque `server.state(nome, opções)` onde `nome` é o nom ```javascript server.state('data', { - ttl: null, - isSecure: true, - isHttpOnly: true, - encoding: 'base64json', - clearInvalid: false, // remove cookies inválidos - strictHeader: true // não permite violações da RFC 6265 + ttl: null, + isSecure: true, + isHttpOnly: true, + encoding: 'base64json', + clearInvalid: false, // remove cookies inválidos + strictHeader: true, // não permite violações da RFC 6265 }); ``` @@ -27,12 +33,12 @@ Além disso, você pode passar dois parâmetros para o `options` ao adicionar um ```json5 { - options: { - state: { - parse: true, // analisa e armazena em request.state - failAction: 'error' // também pode ser 'ignore' ou 'log' - } - } + options: { + state: { + parse: true, // analisa e armazena em request.state + failAction: 'error', // também pode ser 'ignore' ou 'log' + }, + }, } ``` @@ -55,6 +61,7 @@ reply('Hello').state('data', 'test', { encoding: 'none' }); ``` ## Eliminando um cookie + O cookie pode ser eliminado invocando o método `unstate()` no objecto [`response`](/api#response-object): ```javascript diff --git a/static/lib/tutorials/ko_KR/expresstohapi.md b/docs/tutorials/pt_BR/express-to-hapi.md similarity index 55% rename from static/lib/tutorials/ko_KR/expresstohapi.md rename to docs/tutorials/pt_BR/express-to-hapi.md index 0af99a4a..51576c5c 100644 --- a/static/lib/tutorials/ko_KR/expresstohapi.md +++ b/docs/tutorials/pt_BR/express-to-hapi.md @@ -1,5 +1,11 @@ +--- +title: Express to hapi +--- + + + # Express to hapi Guide ## No Translation Yet -This guide has not been translated yet. If you would like to translate it, please submit a pull request. \ No newline at end of file +This guide has not been translated yet. If you would like to translate it, please submit a pull request. diff --git a/static/lib/tutorials/pt_BR/gettingstarted.md b/docs/tutorials/pt_BR/getting-started.md similarity index 72% rename from static/lib/tutorials/pt_BR/gettingstarted.md rename to docs/tutorials/pt_BR/getting-started.md index dda182b4..282bb25c 100644 --- a/static/lib/tutorials/pt_BR/gettingstarted.md +++ b/docs/tutorials/pt_BR/getting-started.md @@ -1,11 +1,17 @@ +--- +title: Getting Started +--- + + + ## Instalando o hapi _Este tutorial é compatível com hapi v16_ Crie um novo diretório `meuprojeto`, entre nele e: -* Execute: `npm init` e siga as instruções, esse comando irá gerar o arquivo package.json para você. -* Execute: `npm install --save hapi` esse comando instalará o hapi e irá salvá-lo no package.json como uma dependência do seu projeto. +- Execute: `npm init` e siga as instruções, esse comando irá gerar o arquivo package.json para você. +- Execute: `npm install --save hapi` esse comando instalará o hapi e irá salvá-lo no package.json como uma dependência do seu projeto. É isso! Agora você tem tudo que precisa para criar um servidor usando hapi. @@ -22,13 +28,13 @@ const server = new Hapi.Server(); server.connection({ port: 3000 }); server.start((err) => { - - if (err) { - throw err; - } - console.log(`Server running at: ${server.info.uri}`); + if (err) { + throw err; + } + console.log(`Server running at: ${server.info.uri}`); }); ``` + Primeiro, precisamos do hapi. Então, criamos um novo objeto do servidor hapi. Em seguida, adicionamos uma conexão ao servidor, passando o número da porta a ser escutada. E então, o servidor é iniciado e o log indicará que ele está sendo executado. Ao adicionar a conexão ao servidor, podemos informar um hostname, o endereço IP, ou até mesmo um arquivo de socket Unix ou uma pipe nomeada do Windows para vincular ao servidor. Para mais detalhes, veja [a API de referência](/api/#serverconnectionoptions). @@ -46,27 +52,26 @@ const server = new Hapi.Server(); server.connection({ port: 3000 }); server.route({ - method: 'GET', - path: '/', - handler: function (request, reply) { - reply('Olá, mundo!'); - } + method: 'GET', + path: '/', + handler: function (request, reply) { + reply('Olá, mundo!'); + }, }); server.route({ - method: 'GET', - path: '/{name}', - handler: function (request, reply) { - reply('Olá, ' + encodeURIComponent(request.params.name) + '!'); - } + method: 'GET', + path: '/{name}', + handler: function (request, reply) { + reply('Olá, ' + encodeURIComponent(request.params.name) + '!'); + }, }); server.start((err) => { - - if (err) { - throw err; - } - console.log(`Servidor rodando em: ${server.info.uri}`); + if (err) { + throw err; + } + console.log(`Servidor rodando em: ${server.info.uri}`); }); ``` @@ -74,7 +79,7 @@ Salve o código acima como `server.js` e inicie o servidor com o comando `node s Perceba que nós codificamos o parâmetro name na URI, isso é para evitar ataques de injeção de conteúdo. Lembre-se, não é uma boa prática exibir os dados para o usuário sem antes codificá-lo! -O parâmetro `method` pode ser qualquer método HTTP válido, uma coleção de métodos, ou ainda um asterisco (*), para permitir qualquer método. Já o `path` define o caminho com a inclusão de parâmetros. Ele pode conter parâmetros opcionais, numerados e até mesmo coringas. Para mais detalhes, veja [o tutorial sobre rotas](/tutorials/routing). +O parâmetro `method` pode ser qualquer método HTTP válido, uma coleção de métodos, ou ainda um asterisco (\*), para permitir qualquer método. Já o `path` define o caminho com a inclusão de parâmetros. Ele pode conter parâmetros opcionais, numerados e até mesmo coringas. Para mais detalhes, veja [o tutorial sobre rotas](/tutorials/routing). ## Criando páginas estáticas e conteúdo @@ -84,23 +89,20 @@ Para instalar o inert, execute o comando no terminal: `npm install --save inert` Adicione o código abaixo ao seu arquivo `server.js`: -``` javascript +```javascript server.register(require('inert'), (err) => { + if (err) { + throw err; + } - if (err) { - throw err; - } - - server.route({ - method: 'GET', - path: '/hello', - handler: function (request, reply) { - reply.file('./public/hello.html'); - } - }); + server.route({ + method: 'GET', + path: '/hello', + handler: function (request, reply) { + reply.file('./public/hello.html'); + }, + }); }); - - ``` O comando `server.register()` adiciona o plugin inert na sua aplicação Hapi. Se algo de errado acontecer, queremos saber. Então, passamos uma função anônima que, se invocada, receberá `err` e em seguida lançará esse erro. Essa função de retorno é necessária quando registramos os plugins. @@ -109,7 +111,7 @@ O comando `server.route()` registra a rota `/hello`, que informa ao seu servidor Inicie o seu servidor com `npm start` e acesse a url `http://localhost:3000/hello` no seu navegador. Ah não! Recebemos o erro 404, pois nunca criamos o arquivo `hello.html`. Você precisa criar o arquivo para que o erro não volte a acontecer. -Crie um diretório chamado `public` na raiz do seu projeto. Depois, crie um arquivo chamado `hello.html`, dentro desse diretório, com o HTML a seguir: `

    Olá mundo.

    `. Em seguida, recarregue a página no seu navegador. Você deverá ler a expressão "Olá mundo.". +Crie um diretório chamado `public` na raiz do seu projeto. Depois, crie um arquivo chamado `hello.html`, dentro desse diretório, com o HTML a seguir: `

    Olá mundo.

    `. Em seguida, recarregue a página no seu navegador. Você deverá ler a expressão "Olá mundo.". Inert exibirá qualquer conteúdo salvo no seu disco rígido quando a requisição for feita, isto é o que leva a carregar em tempo real. Você pode personalizar a página `/hello` ao seu gosto. @@ -117,4 +119,4 @@ Para mais detalhes sobre como o conteúdo estático funciona acesse [Servindo Co ## Outras informações -Hapi oferece muitas mais capacidades, no entanto apenas algumas estão documentadas em tutoriais como este. Por favor, use a lista da direita para vê-los. Ademais, o restante da documentação pode ser vista na [API de referência](/api) e, como sempre, sinta-se à vontade para fazer perguntas no [github](https://github.com/hapijs/discuss/issues) ou visite-nos no [slack](https://join.slack.com/t/hapihour/shared_invite/zt-g5ortpsk-ErlnRA2rUcPIWES21oXBOg). +Hapi oferece muitas mais capacidades, no entanto apenas algumas estão documentadas em tutoriais como este. Por favor, use a lista da direita para vê-los. Ademais, o restante da documentação pode ser vista na [API de referência](/api) e, como sempre, sinta-se à vontade para fazer perguntas no [github](https://github.com/hapijs/discuss/issues) ou visite-nos no [slack](https://join.slack.com/t/hapihour/shared_invite/zt-g5ortpsk-ErlnRA2rUcPIWES21oXBOg). diff --git a/static/lib/tutorials/pt_BR/logging.md b/docs/tutorials/pt_BR/logging.md similarity index 95% rename from static/lib/tutorials/pt_BR/logging.md rename to docs/tutorials/pt_BR/logging.md index b87bec12..43a19d9a 100644 --- a/static/lib/tutorials/pt_BR/logging.md +++ b/docs/tutorials/pt_BR/logging.md @@ -1,3 +1,9 @@ +--- +title: Logging +--- + + + ## Métodos nativos Como todo programa de servidor, o log é muito importante. O Hapi possui alguns métodos nativos de log, bem como uma capacidade limitada para visualização destes logs. @@ -14,10 +20,9 @@ server.log(['error', 'database', 'read']); Qualquer evento de log que o hapi gera internamente sempre terá a tag `hapi` associada a ele. É através deste parâmetro que você deve passar coisas como uma mensagem de erro, ou algum outro detalhe que você deseja que vá com a suas tags. O evento de log terá automaticamente a URI do server o qual ele é associado como uma propriedade. +Por último o parâmetro timestamp. O valor padrão (_default_) dele é `Date.now()`, e somente deve ser passado se você precisa sobrescrever o valor padrão por algum motivo. -Por último o parâmetro timestamp. O valor padrão (*default*) dele é `Date.now()`, e somente deve ser passado se você precisa sobrescrever o valor padrão por algum motivo. - -### Recuperando logs de *request* +### Recuperando logs de _request_ O Hapi também possui um método (`request.getLog`) para recuperar eventos de log de um request, assumindo que você ainda tem acesso ao objeto de request. Se chamado sem parâmetros ele ira retornar um array com todos os eventos de log associados ao request. Você também pode passar uma tag ou um array de tags para filtrar o retorno. Isto pode ser útil para recuperar o histórico de todos os eventos de log em um request quando ocorrer um erro para análise. diff --git a/static/lib/tutorials/pt_BR/plugins.md b/docs/tutorials/pt_BR/plugins.md similarity index 82% rename from static/lib/tutorials/pt_BR/plugins.md rename to docs/tutorials/pt_BR/plugins.md index 063a9f65..cbdd66ea 100644 --- a/static/lib/tutorials/pt_BR/plugins.md +++ b/docs/tutorials/pt_BR/plugins.md @@ -1,3 +1,9 @@ +--- +title: Plugins +--- + + + ## Plugins hapi possui um poderoso e extensível sistema de plugins que permite que você facilmente divida sua aplicação em pedaços isolados contendo lógica de negócios, e utilitários reutilizáveis. @@ -12,14 +18,14 @@ Um plugin básico pode ser definido da seguinte forma: 'use strict'; const myPlugin = { - register: function (server, options, next) { - next(); - } + register: function (server, options, next) { + next(); + }, }; myPlugin.register.attributes = { - name: 'myPlugin', - version: '1.0.0' + name: 'myPlugin', + version: '1.0.0', }; ``` @@ -29,11 +35,11 @@ Ou quando escrito como módulo externo: 'use strict'; exports.register = function (server, options, next) { - next(); + next(); }; exports.register.attributes = { - pkg: require('./package.json') + pkg: require('./package.json'), }; ``` @@ -68,11 +74,11 @@ Por exemplo, para adicionar uma rota somente para as conexões com o label `'api const api = server.select('api'); api.route({ - method: 'GET', - path: '/', - handler: function (request, reply) { - reply('api index'); - } + method: 'GET', + path: '/', + handler: function (request, reply) { + reply('api index'); + }, }); ``` @@ -96,57 +102,64 @@ Plugins podem ser carregados individualmente, ou como parte de um grupo definido ```javascript // carrega um plugin server.register(require('myplugin'), (err) => { - if (err) { - console.error('Failed to load plugin:', err); - } + if (err) { + console.error('Failed to load plugin:', err); + } }); // carrega múltiplos plugins server.register([require('myplugin'), require('yourplugin')], (err) => { - if (err) { - console.error('Failed to load a plugin:', err); - } + if (err) { + console.error('Failed to load a plugin:', err); + } }); ``` Para passar opções para o seu plugin, cria-se um objeto com as chaves `register` e `options`, por exemplo: ```javascript -server.register({ +server.register( + { register: require('myplugin'), options: { - message: 'hello' - } -}, (err) => { - + message: 'hello', + }, + }, + (err) => { if (err) { - throw err; + throw err; } -}); + }, +); ``` Esses objetos podem também ser passados como itens de um array ```javascript -server.register([{ - register: require('plugin1'), - options: {} -}, { - register: require('plugin2'), - options: {} -}], (err) => { - +server.register( + [ + { + register: require('plugin1'), + options: {}, + }, + { + register: require('plugin2'), + options: {}, + }, + ], + (err) => { if (err) { - throw err; + throw err; } -}); + }, +); ``` ### Opções dos plugins Você pode também passar um parâmetro opcional para `server.register()` antes do callback. Documentação para esse objeto pode ser encontrado [API reference](/api#serverregisterplugins-options-callback). -O objeto de opções é utilizado pelo hapi e *não* é passado para o plugin(s) sendo carregado(s). Isso permite que você pré-selecione os servidores baseados em uma ou mais labels, como também aplique modificadores `vhost` ou `prefix` em qualquer rota que o seu plugin registrar. +O objeto de opções é utilizado pelo hapi e _não_ é passado para o plugin(s) sendo carregado(s). Isso permite que você pré-selecione os servidores baseados em uma ou mais labels, como também aplique modificadores `vhost` ou `prefix` em qualquer rota que o seu plugin registrar. Por exemplo, vamos dizer que temos um plugin definido da seguinte forma: @@ -154,36 +167,38 @@ Por exemplo, vamos dizer que temos um plugin definido da seguinte forma: 'use strict'; exports.register = function (server, options, next) { + server.route({ + method: 'GET', + path: '/test', + handler: function (request, reply) { + reply('test passed'); + }, + }); - server.route({ - method: 'GET', - path: '/test', - handler: function (request, reply) { - reply('test passed'); - } - }); - - next(); + next(); }; exports.register.attributes = { - pkg: require('./package.json') + pkg: require('./package.json'), }; ``` Normalmente, quando esse plugin é carregado ele cria uma rota `GET` em `/test`. Isso pode ser alterado utilizando a configuração `prefix` do objeto de opcões, que irá concatenar uma string como prefixo para todas as rotas definidas por esse plugin: ```javascript -server.register({ register: require('myplugin') }, { +server.register( + { register: require('myplugin') }, + { routes: { - prefix: '/plugins' - } -}, (err) => { - + prefix: '/plugins', + }, + }, + (err) => { if (err) { - throw err; + throw err; } -}); + }, +); ``` Agora, quando este plugin for carregado, por causa da opção `prexix` a rota `GET` será criada em `/plugins/test`. @@ -193,15 +208,17 @@ De forma análoga o parâmetro `options.routes.vhost` irá designar uma configur O parâmetro `select` funciona exatamente do mesmo jeito que `server.select()` funciona, de forma que você pode passar uma label ou um array de labels para o plugin para o plugins se associar. ```javascript -server.register({ register: require('myplugin') }, { - select: ['webserver', 'admin'] -}, (err) => { - +server.register( + { register: require('myplugin') }, + { + select: ['webserver', 'admin'], + }, + (err) => { if (err) { - throw err; + throw err; } -}); + }, +); ``` Isso permite que você defina plugins para conexões específicas em um server sem precisar alterar o código do plugin. - diff --git a/static/lib/tutorials/pt_BR/routing.md b/docs/tutorials/pt_BR/routing.md similarity index 68% rename from static/lib/tutorials/pt_BR/routing.md rename to docs/tutorials/pt_BR/routing.md index 859f8fd1..f292d262 100644 --- a/static/lib/tutorials/pt_BR/routing.md +++ b/docs/tutorials/pt_BR/routing.md @@ -1,28 +1,34 @@ +--- +title: Routing +--- + + + ## Rotas Quando definimos uma rota no Hapi, assim como em outros frameworks, são necessários três elementos básicos: o caminho, o método e o manipulador. Estes elementos são passados para o servidor como um objeto, e pode ser tão simples quanto o exemplo seguinte: ```javascript server.route({ - method: 'GET', - path: '/', - handler: function (request, reply) { - reply('Hello!'); - } + method: 'GET', + path: '/', + handler: function (request, reply) { + reply('Hello!'); + }, }); ``` ## Métodos -Está rota responde a um método `GET` com a `string` 'Hello!'. A opção `method` pode ser qualquer qualquer método http válido, ou uma `array` de métodos. Você dizer que você deseja a mesma resposta quando o usuário envia tanto um pedido `PUT` quanto o `POST`, você poderia fazer isso da seguinte forma: +Está rota responde a um método `GET` com a `string` 'Hello!'. A opção `method` pode ser qualquer qualquer método http válido, ou uma `array` de métodos. Você dizer que você deseja a mesma resposta quando o usuário envia tanto um pedido `PUT` quanto o `POST`, você poderia fazer isso da seguinte forma: ```javascript server.route({ - method: ['PUT', 'POST'], - path: '/', - handler: function (request, reply) { - reply('I did something!'); - } + method: ['PUT', 'POST'], + path: '/', + handler: function (request, reply) { + reply('I did something!'); + }, }); ``` @@ -32,11 +38,11 @@ A opção `path` deve ser uma `string` e também poderá conter parâmetros nome ```javascript server.route({ - method: 'GET', - path: '/hello/{user}', - handler: function (request, reply) { - reply('Hello ' + encodeURIComponent(request.params.user) + '!'); - } + method: 'GET', + path: '/hello/{user}', + handler: function (request, reply) { + reply('Hello ' + encodeURIComponent(request.params.user) + '!'); + }, }); ``` @@ -48,16 +54,16 @@ Neste exemplo, o parâmetro `user` é obrigatório: uma requisição a `/hello/b ```javascript server.route({ - method: 'GET', - path: '/hello/{user?}', - handler: function (request, reply) { - const user = request.params.user ? encodeURIComponent(request.params.user) : 'stranger'; - reply('Hello ' + user + '!'); - } + method: 'GET', + path: '/hello/{user?}', + handler: function (request, reply) { + const user = request.params.user ? encodeURIComponent(request.params.user) : 'stranger'; + reply('Hello ' + user + '!'); + }, }); ``` -Agora uma requisição para `/hello/mary` irá responder com `Hello mary!` e a requisição para `/hello` irá responder com `Hello stranger!`. É importante estar ciente que apenas o *último* parâmetro em um caminho pode ser opcional. Isso significa que `/{one?}/{two}/` é um caminho inválido, isso porque existe outro parâmetro após um opcional. Você também pode ter um parâmetro nomeado parcial em um segmento do caminho, mas você só pode ter um parâmetro por segmento. Isso significa que `/{filename}.jpg` é valido, enquando `/{filename}.{ext}` é inválido. +Agora uma requisição para `/hello/mary` irá responder com `Hello mary!` e a requisição para `/hello` irá responder com `Hello stranger!`. É importante estar ciente que apenas o _último_ parâmetro em um caminho pode ser opcional. Isso significa que `/{one?}/{two}/` é um caminho inválido, isso porque existe outro parâmetro após um opcional. Você também pode ter um parâmetro nomeado parcial em um segmento do caminho, mas você só pode ter um parâmetro por segmento. Isso significa que `/{filename}.jpg` é valido, enquando `/{filename}.{ext}` é inválido. ### Parâmetros de multisegmentos @@ -65,12 +71,12 @@ Junto com o parâmetro de caminho opcional, você também pode permitir que esse ```javascript server.route({ - method: 'GET', - path: '/hello/{user*2}', - handler: function (request, reply) { - const userParts = request.params.user.split('/'); - reply('Hello ' + encodeURIComponent(userParts[0]) + ' ' + encodeURIComponent(userParts[1]) + '!'); - } + method: 'GET', + path: '/hello/{user*2}', + handler: function (request, reply) { + const userParts = request.params.user.split('/'); + reply('Hello ' + encodeURIComponent(userParts[0]) + ' ' + encodeURIComponent(userParts[1]) + '!'); + }, }); ``` @@ -84,7 +90,7 @@ A opção `handler` é uma função que aceita dois parâmetros, `request` e `re O parâmetro `request` é um objeto com detalhes sobre a solicitação do usuário final, como parâmetros de caminho, carga associada, informações de autenticação, cabeçalhos, etc... Toda a documentação sobre o que o objeto `request` contem pode ser encontrado na [referência de API](/api#request-properties). -O segundo parâmetro, `reply`, é um método usado para responder as requisições. Como você viu nos exemplos anteriores, se você deseja responder com uma carga útil, você precisa simplesmente passar como um parâmetro para o `reply`. A resposta pode ser uma string, um buffer um objeto serializado em json ou uma stream. O resultado de `reply` é um objeto de resposta, que pode ser encadeado com métodos adicionais para alterar a resposta antes de serem enviados. Por exemplo `reply('created').code(201)` enviará uma carga de trabalho `created` com um código de status `201`. Você também pode atribuir valores aos `header`, `content-type`, `content-lenght`, enviar uma resposta direta, e muitas outras coisas que são documentadas na [referência de API](/api#response-object). +O segundo parâmetro, `reply`, é um método usado para responder as requisições. Como você viu nos exemplos anteriores, se você deseja responder com uma carga útil, você precisa simplesmente passar como um parâmetro para o `reply`. A resposta pode ser uma string, um buffer um objeto serializado em json ou uma stream. O resultado de `reply` é um objeto de resposta, que pode ser encadeado com métodos adicionais para alterar a resposta antes de serem enviados. Por exemplo `reply('created').code(201)` enviará uma carga de trabalho `created` com um código de status `201`. Você também pode atribuir valores aos `header`, `content-type`, `content-lenght`, enviar uma resposta direta, e muitas outras coisas que são documentadas na [referência de API](/api#response-object). ## Configuração @@ -94,17 +100,17 @@ Aqui vamos exemplificar um par de opções concebidas para ajudar a gerar a docu ```javascript server.route({ - method: 'GET', - path: '/hello/{user?}', - handler: function (request, reply) { - const user = request.params.user ? encodeURIComponent(request.params.user) : 'stranger'; - reply('Hello ' + user + '!'); - }, - options: { - description: 'Say hello!', - notes: 'The user parameter defaults to \'stranger\' if unspecified', - tags: ['api', 'greeting'] - } + method: 'GET', + path: '/hello/{user?}', + handler: function (request, reply) { + const user = request.params.user ? encodeURIComponent(request.params.user) : 'stranger'; + reply('Hello ' + user + '!'); + }, + options: { + description: 'Say hello!', + notes: "The user parameter defaults to 'stranger' if unspecified", + tags: ['api', 'greeting'], + }, }); ``` diff --git a/static/lib/tutorials/pt_BR/servermethods.md b/docs/tutorials/pt_BR/server-methods.md similarity index 76% rename from static/lib/tutorials/pt_BR/servermethods.md rename to docs/tutorials/pt_BR/server-methods.md index 29168db3..d74439eb 100644 --- a/static/lib/tutorials/pt_BR/servermethods.md +++ b/docs/tutorials/pt_BR/server-methods.md @@ -1,11 +1,17 @@ +--- +title: Server Methods +--- + + + ## Métodos de Servidor Métodos de servidor são uma maneira útil para compartilhar funções. Eles são anexados no seu objeto servidor em vez de exigirem um módulo comum em todos os lugares necessários. Para registrar um método de servidor, você precisa acessar o objeto `server`. Há duas formas diferentes de fazer isso, uma delas é a passagem de parâmetros separados: ```javascript const add = function (x, y, next) { - // note que a função 'next' é utilizada para retornar valores - next(null, x + y); + // note que a função 'next' é utilizada para retornar valores + next(null, x + y); }; server.method('add', add, {}); @@ -15,13 +21,13 @@ Ou um objeto com os parâmetros `name`, `method`, and `options` (perceba que voc ```javascript const add = function (x, y, next) { - next(null, x + y); + next(null, x + y); }; server.method({ - name: 'add', - method: add, - options: {} + name: 'add', + method: add, + options: {}, }); ``` @@ -37,7 +43,7 @@ será acessível como server.methods.math.add ## Função -O parâmetro `method` é na verdade a função que será chamada quando o método é invocado. Ele pode receber qualquer quantidade de argumentos, mas o seu *último* parâmetro deve ser a função de retorno. A função de retorno aceita três parâmetros: `err`, `result`, and `ttl`. Caso ocorra algum erro no seu método, ele será passado como o primeiro argumento. Se não ocorrer erro, o primeiro argumento deve ser indefinido ou nulo e o valor de retorno será passado como o segundo argumento. O argumento `ttl` é usado para informar ao hapi quanto tempo o valor de retorno pode ser armazenado em cache; se ele for especificado como `0`, então o valor nunca será armazenado em cache. +O parâmetro `method` é na verdade a função que será chamada quando o método é invocado. Ele pode receber qualquer quantidade de argumentos, mas o seu _último_ parâmetro deve ser a função de retorno. A função de retorno aceita três parâmetros: `err`, `result`, and `ttl`. Caso ocorra algum erro no seu método, ele será passado como o primeiro argumento. Se não ocorrer erro, o primeiro argumento deve ser indefinido ou nulo e o valor de retorno será passado como o segundo argumento. O argumento `ttl` é usado para informar ao hapi quanto tempo o valor de retorno pode ser armazenado em cache; se ele for especificado como `0`, então o valor nunca será armazenado em cache. ## Caching @@ -45,24 +51,24 @@ Falando de caching, outra grande vantagem dos métodos de servidor é que eles p ```javascript server.method('add', add, { - cache: { - expiresIn: 60000, - expiresAt: '30:22', - staleIn: 30000, - staleTimeout: 10000 - } + cache: { + expiresIn: 60000, + expiresAt: '30:22', + staleIn: 30000, + staleTimeout: 10000, + }, }); ``` Os parâmetros são: -* `expiresIn`: o tempo em milisegundos para ser mantido em cache, a partir do momento que foi criado -* `expiresAt`: notação em MM:HH, serve para informar o prazo para invalidar o cache. Não pode ser utilizado ao mesmo tempo que expiresIn -* `staleIn`: informa em milisegundos quanto tempo o item deve aguardar para ser marcado como velho no cache, deve ser *menor* que o expiresIn -* `staleTimeout`: milissegundos para aguardar uma resposta antes de informar um valor obsoleto -* `generateTimeout`: milisegundos para aguardar antes de retornar um erro de tempo esgotado quando demora muito para retornar um valor. Eventualmente, quando o valor é retornado, é guardado no cache para as requisições futuras. -* `segment`: um nome de segmento opcional usado para isolar itens do cache. -* `cache`: um nome da conexão do cache que foi configurada para uso no servidor, esse parâmetro é opcional +- `expiresIn`: o tempo em milisegundos para ser mantido em cache, a partir do momento que foi criado +- `expiresAt`: notação em MM:HH, serve para informar o prazo para invalidar o cache. Não pode ser utilizado ao mesmo tempo que expiresIn +- `staleIn`: informa em milisegundos quanto tempo o item deve aguardar para ser marcado como velho no cache, deve ser _menor_ que o expiresIn +- `staleTimeout`: milissegundos para aguardar uma resposta antes de informar um valor obsoleto +- `generateTimeout`: milisegundos para aguardar antes de retornar um erro de tempo esgotado quando demora muito para retornar um valor. Eventualmente, quando o valor é retornado, é guardado no cache para as requisições futuras. +- `segment`: um nome de segmento opcional usado para isolar itens do cache. +- `cache`: um nome da conexão do cache que foi configurada para uso no servidor, esse parâmetro é opcional Mais informações sobre as opções de cache podem ser encontradas na [API de Referência](/api#servermethodmethod), bem como na documentação do [catbox](https://github.com/hapijs/catbox#policy). @@ -72,23 +78,23 @@ Além das opções acima, você também pode passar uma função personalizada. ```javascript const sum = function (array, next) { - let total = 0; + let total = 0; - array.forEach((item) => { - total += item; - }); + array.forEach((item) => { + total += item; + }); - next(null, total); + next(null, total); }; server.method('sum', sum, { - generateKey: function (array) { - return array.join(','); - } + generateKey: function (array) { + return array.join(','); + }, }); ``` -Todos os argumentos passados para o seu método são acessíveis através do método generateKey, com *exceção* da função de retorno. +Todos os argumentos passados para o seu método são acessíveis através do método generateKey, com _exceção_ da função de retorno. ## Bind @@ -96,10 +102,10 @@ A última opção disponvível para métodos de servidor é o `bind`. Essa opç ```javascript const lookup = function (id, next) { - // calls myDB.getOne - this.getOne({ id: id }, (err, value) => { - next(err, value); - }); + // calls myDB.getOne + this.getOne({ id: id }, (err, value) => { + next(err, value); + }); }; server.method('lookup', lookup, { bind: myDB }); diff --git a/static/lib/tutorials/pt_BR/servingfiles.md b/docs/tutorials/pt_BR/serving-files.md similarity index 71% rename from static/lib/tutorials/pt_BR/servingfiles.md rename to docs/tutorials/pt_BR/serving-files.md index a07ab06a..80f3beec 100644 --- a/static/lib/tutorials/pt_BR/servingfiles.md +++ b/docs/tutorials/pt_BR/serving-files.md @@ -1,3 +1,9 @@ +--- +title: Serving Files +--- + + + ## Servindo arquivos estáticos _Este tutorial é compatível com hapi v16_ @@ -14,27 +20,25 @@ Primeiro, para usar o método reply: ```javascript server.register(require('inert'), (err) => { + if (err) { + throw err; + } + server.route({ + method: 'GET', + path: '/picture.jpg', + handler: function (request, reply) { + reply.file('/path/to/picture.jpg'); + }, + }); + + server.start((err) => { if (err) { - throw err; + throw err; } - server.route({ - method: 'GET', - path: '/picture.jpg', - handler: function (request, reply) { - reply.file('/path/to/picture.jpg'); - } - }); - - server.start((err) => { - - if (err) { - throw err; - } - - console.log('Servidor rodando em:', server.info.uri); - }); + console.log('Servidor rodando em:', server.info.uri); + }); }); ``` @@ -51,37 +55,35 @@ const Path = require('path'); const Hapi = require('hapi'); const server = new Hapi.Server({ - connections: { - routes: { - files: { - relativeTo: Path.join(__dirname, 'public') - } - } - } + connections: { + routes: { + files: { + relativeTo: Path.join(__dirname, 'public'), + }, + }, + }, }); server.register(require('inert'), (err) => { + if (err) { + throw err; + } + + server.route({ + method: 'GET', + path: '/picture.jpg', + handler: function (request, reply) { + reply.file('path/to/picture.jpg'); + }, + }); + server.start((err) => { if (err) { - throw err; + throw err; } - server.route({ - method: 'GET', - path: '/picture.jpg', - handler: function (request, reply) { - reply.file('path/to/picture.jpg'); - } - }); - - server.start((err) => { - - if (err) { - throw err; - } - - console.log('Server running at:', server.info.uri); - }); + console.log('Server running at:', server.info.uri); + }); }); ``` @@ -93,11 +95,11 @@ Uma alternativa para a rota acima seria o uso do manipulador `file`: ```javascript server.route({ - method: 'GET', - path: '/picture.jpg', - handler: { - file: 'picture.jpg' - } + method: 'GET', + path: '/picture.jpg', + handler: { + file: 'picture.jpg', + }, }); ``` @@ -107,13 +109,13 @@ Nós também podemos especificar o parâmetro como uma função que aceita o obj ```javascript server.route({ - method: 'GET', - path: '/{filename}', - handler: { - file: function (request) { - return request.params.filename; - } - } + method: 'GET', + path: '/{filename}', + handler: { + file: function (request) { + return request.params.filename; + }, + }, }); ``` @@ -122,16 +124,16 @@ nós podemos fazer algumas coisas adicionais, como o ajuste do cabeçalho `Conte ```javascript server.route({ - method: 'GET', - path: '/script.js', - handler: { - file: { - path: 'script.js', - filename: 'client.js', // sobreescreve o nome do arquivo no cabeçalho Content-Disposition - mode: 'attachment', // especifica o Content-Disposition com um anexo - lookupCompressed: true // permite olhar para script.js.gz se a requisição permitir isso - } - } + method: 'GET', + path: '/script.js', + handler: { + file: { + path: 'script.js', + filename: 'client.js', // sobreescreve o nome do arquivo no cabeçalho Content-Disposition + mode: 'attachment', // especifica o Content-Disposition com um anexo + lookupCompressed: true, // permite olhar para script.js.gz se a requisição permitir isso + }, + }, }); ``` @@ -141,13 +143,13 @@ Além do manipulador `file`, inert também adiciona um manipulador de `directory ```javascript server.route({ - method: 'GET', - path: '/{param*}', - handler: { - directory: { - path: 'public' - } - } + method: 'GET', + path: '/{param*}', + handler: { + directory: { + path: 'public', + }, + }, }); ``` @@ -157,14 +159,14 @@ A rota acima responderá qualquer requisição procurando por um arquivo corresp ```javascript server.route({ - method: 'GET', - path: '/{param*}', - handler: { - directory: { - path: 'public', - listing: true - } - } + method: 'GET', + path: '/{param*}', + handler: { + directory: { + path: 'public', + listing: true, + }, + }, }); ``` diff --git a/static/lib/tutorials/ko_KR/testing.md b/docs/tutorials/pt_BR/testing.md similarity index 53% rename from static/lib/tutorials/ko_KR/testing.md rename to docs/tutorials/pt_BR/testing.md index e25dee5f..4cf0e0bd 100644 --- a/static/lib/tutorials/ko_KR/testing.md +++ b/docs/tutorials/pt_BR/testing.md @@ -1,5 +1,11 @@ +--- +title: Testing +--- + + + # Testing ## No Translation Yet -This tutorial has not been translated yet. If you would like to translate it, please submit a pull request. \ No newline at end of file +This tutorial has not been translated yet. If you would like to translate it, please submit a pull request. diff --git a/static/lib/tutorials/pt_BR/validation.md b/docs/tutorials/pt_BR/validation.md similarity index 75% rename from static/lib/tutorials/pt_BR/validation.md rename to docs/tutorials/pt_BR/validation.md index 94d4fb79..af09f6a8 100644 --- a/static/lib/tutorials/pt_BR/validation.md +++ b/docs/tutorials/pt_BR/validation.md @@ -1,3 +1,9 @@ +--- +title: Validation +--- + + + ## Validação Validação de dados é uma ferramenta muito útil para garantir que a sua aplicação é estável e segura. hapi permite essa funcionalidade utilizando o módulo `joi`. @@ -18,18 +24,18 @@ Vamos observar um exemplo: ```javascript server.route({ - method: 'GET', - path: '/hello/{name}', - handler: function (request, reply) { - reply('Hello ' + request.params.name + '!'); + method: 'GET', + path: '/hello/{name}', + handler: function (request, reply) { + reply('Hello ' + request.params.name + '!'); + }, + options: { + validate: { + params: { + name: Joi.string().min(3).max(10), + }, }, - options: { - validate: { - params: { - name: Joi.string().min(3).max(10) - } - } - } + }, }); ``` @@ -41,15 +47,13 @@ Com essa configuração, se nós fizermos uma requisição para `/hello/jennifer ```json { - "error": "Bad Request", - "message": "the length of name must be at least 3 characters long", - "statusCode": 400, - "validation": { - "keys": [ - "name" - ], - "source": "params" - } + "error": "Bad Request", + "message": "the length of name must be at least 3 characters long", + "statusCode": 400, + "validation": { + "keys": ["name"], + "source": "params" + } } ``` @@ -57,38 +61,36 @@ Da memsa forma, se nós fizermos uma requisição para `/hello/thisnameiswaytool ```json { - "error": "Bad Request", - "message": "the length of name must be less than or equal to 10 characters long", - "statusCode": 400, - "validation": { - "keys": [ - "name" - ], - "source": "params" - } + "error": "Bad Request", + "message": "the length of name must be less than or equal to 10 characters long", + "statusCode": 400, + "validation": { + "keys": ["name"], + "source": "params" + } } ``` ### Parâmetros de Query -Para validar parâmetros de query, nós simplesmente especificamos um parâmetro `validate.query` na configuração de rota, e nós vamos obter efeitos similares. Por padrão hapi não irá validar nenhum parâmetro. Se você especificar um validador para um parâmetro de query qualquer, isso significa que você *deve* especificar validadores para todos os parâmetros de query que você gostaria de aceitar. +Para validar parâmetros de query, nós simplesmente especificamos um parâmetro `validate.query` na configuração de rota, e nós vamos obter efeitos similares. Por padrão hapi não irá validar nenhum parâmetro. Se você especificar um validador para um parâmetro de query qualquer, isso significa que você _deve_ especificar validadores para todos os parâmetros de query que você gostaria de aceitar. Por exemplo, se você tem uma rota que lista todos os recursos e você gostaria que o usuário pudesse limitar a quantidade total do resultado, você poderia utilizar a seguinte configuração: ```javascript server.route({ - method: 'GET', - path: '/list', - handler: function (request, reply) { - reply(resources.slice(0, request.query.limit)); + method: 'GET', + path: '/list', + handler: function (request, reply) { + reply(resources.slice(0, request.query.limit)); + }, + options: { + validate: { + query: { + limit: Joi.number().integer().min(1).max(100).default(10), + }, }, - options: { - validate: { - query: { - limit: Joi.number().integer().min(1).max(100).default(10) - } - } - } + }, }); ``` @@ -96,15 +98,13 @@ Essa configuração garante que o parâmetro de query `limit` é sempre um intei ```json { - "error": "Bad Request", - "message": "the key offset is not allowed", - "statusCode": 400, - "validation": { - "keys": [ - "offset" - ], - "source": "query" - } + "error": "Bad Request", + "message": "the key offset is not allowed", + "statusCode": 400, + "validation": { + "keys": ["offset"], + "source": "query" + } } ``` @@ -133,10 +133,12 @@ O Hapi também suporta algumas opções para um ajuste fino na validação de sa ### respose.failAction Você pode escolher o que acontece quando sua validação falha, configurando `response.failAction` para uma das opções abaixo: -* `error`: enviar um Erro Interno do Servidor (500) como resposta (padrão). -* `log`: apenas registre a violação e envie a resposta como ela está. + +- `error`: enviar um Erro Interno do Servidor (500) como resposta (padrão). +- `log`: apenas registre a violação e envie a resposta como ela está. ### response.sample + Se performance é uma preocupação, é possível configurar para a validar apenas uma porcentagem das respostas. Isso pode ser feito usando a propriedade `response.sample` do objeto `options` na rota. @@ -144,11 +146,13 @@ Isso pode ser feito usando a propriedade `response.sample` do objeto `options` n Em alguns casos, uma rota pode servir respostas objetos de resposta diferentes. Por exemplo. uma rota `POST` pode retornar uma das opções a seguir: -* `201` com o novo recurso criado, se um novo recurso for criado. -* `202` com os antigo e os novos valores se um recurso existente foi atualizado. + +- `201` com o novo recurso criado, se um novo recurso for criado. +- `202` com os antigo e os novos valores se um recurso existente foi atualizado. O Hapi suporta isso, permitindo você especificar um esquema de validação para cada _status code_. `response.status` é um objeto onde as chaves são os números de _status codes_, e as propriedades são os esquemas do Joi: + ``` { response: { @@ -161,6 +165,7 @@ O Hapi suporta isso, permitindo você especificar um esquema de validação para ``` ### response.options + As opções passadas para o Joi durante a validação. Veja a documentação da API para mais detalhes. ### Exemplo @@ -169,39 +174,36 @@ Aqui está um exemplo da configuração de uma rota que retorna uma lista de liv ```javascript const bookSchema = Joi.object({ - title: Joi.string().required(), - author: Joi.string().required(), - isbn: Joi.string().length(10), - pageCount: Joi.number(), - datePublished: Joi.date().iso() + title: Joi.string().required(), + author: Joi.string().required(), + isbn: Joi.string().length(10), + pageCount: Joi.number(), + datePublished: Joi.date().iso(), }); server.route({ - method: 'GET', - path: '/books', - options: { - handler: function (request, reply) { - - getBooks((err, books) => { - - if (err) { - return reply(err); - } - - return reply(books); - }); - }, - response: { - sample: 50, - schema: Joi.array().items(bookSchema) + method: 'GET', + path: '/books', + options: { + handler: function (request, reply) { + getBooks((err, books) => { + if (err) { + return reply(err); } - } -}); + return reply(books); + }); + }, + response: { + sample: 50, + schema: Joi.array().items(bookSchema), + }, + }, +}); ``` Assim, será validado apenas metade das respostas (`sample: 50`). Por quê, `response.failAction` não é especificado, o Hapi irá responder com `500` como código de erro, se algum dos livros não for exatamente válido para o esquema. -A resposta de erro *não* indica a razão do erro. +A resposta de erro _não_ indica a razão do erro. Se os registros (logging) estiverem configurados, você será capaz de inspecionar os registros de erros sobre a causa da falha na validação da resposta. Se `response.failAction` estiver configurada para `log`, então o Hapi irá responder com os dados originais, e registrar o erro na validação. diff --git a/static/lib/tutorials/pt_BR/views.md b/docs/tutorials/pt_BR/views.md similarity index 80% rename from static/lib/tutorials/pt_BR/views.md rename to docs/tutorials/pt_BR/views.md index 29d98118..835520b0 100644 --- a/static/lib/tutorials/pt_BR/views.md +++ b/docs/tutorials/pt_BR/views.md @@ -1,3 +1,9 @@ +--- +title: Views +--- + + + ## Views _Este tutorial é compatível com hapi v16_ @@ -18,18 +24,16 @@ const Hoek = require('hoek'); const server = new Hapi.Server(); server.register(require('vision'), (err) => { + Hoek.assert(!err, err); - Hoek.assert(!err, err); - - server.views({ - engines: { - html: require('handlebars') - }, - relativeTo: __dirname, - path: 'templates' - }); + server.views({ + engines: { + html: require('handlebars'), + }, + relativeTo: __dirname, + path: 'templates', + }); }); - ``` Nós estamos fazendo várias coisas aqui. @@ -48,13 +52,13 @@ Note que todas opções pode ser definidas de forma global, que configura todos ```javascript server.views({ - engines: { - 'html': { - module: require('handlebars'), - compileMode: 'sync' // motor específica - } + engines: { + html: { + module: require('handlebars'), + compileMode: 'sync', // motor específica }, - compileMode: 'async' // configuração global + }, + compileMode: 'async', // configuração global }); ``` @@ -74,7 +78,6 @@ Aproveitando o parâmetro `options` tanto o método `compile`, e o método que r Se somente um motor de template é registardo, torna-se automaticamento padrão, permitindo que você deixe de fora a extenção do arquivo ao solicitar a view. Contudo, se mais de um motor for registardo, você deve adiciona a extensão do arquvio, ou definir o `defaultExtension` para o motor que você usa com mais frenquente. Para qualquer views que não usa o motor padrão, você ainda precisa especificar o extenção do arquivo. - Outro opção util é `isCached`. Se definida como `false`, hapi não irá cachear o resultado do template e em vez disso vai ler o template do arquivo tada vez que usar. Quando desenvolver sua aplicação, isto pode ser bastante útil pois evita que você reinicie a sua aplicação toda vez que alterar o templete. É recomentdado que você deixe o `isCached` com o valor padrão `true` em produção. #### Paths @@ -82,7 +85,7 @@ Outro opção util é `isCached`. Se definida como `false`, hapi não irá cache As views pode ter varios arquivos em difrente locais, hapi permite que você configure varios caminhos para ajudar encontrar os arquvios. As opções são: -- `path`: o diretório que contém seus principais templates +- `path`: o diretório que contém seus principais templates - `partialsPath`: o diretório que contém suas partials - `helpersPath`: o diretório que contém suas templates helpers - `layoutPath`: o diretório que contém templates layout @@ -106,13 +109,13 @@ Sua configuração pode parecer isso: ```javascript server.views({ - engines: { - html: require('handlebars') - }, - relativeTo: __dirname, - path: './views', - layoutPath: './views/layout', - helpersPath: './views/helpers' + engines: { + html: require('handlebars'), + }, + relativeTo: __dirname, + path: './views', + layoutPath: './views/layout', + helpersPath: './views/helpers', }); ``` @@ -126,13 +129,14 @@ O primeiro método que renderiza um view que vamos olhar é `reply.view()`. Aqui ```javascript server.route({ - method: 'GET', - path: '/', - handler: function (request, reply) { - reply.view('index'); - } + method: 'GET', + path: '/', + handler: function (request, reply) { + reply.view('index'); + }, }); ``` + Podemos passar o contexto para o `reply.view()`, você passa um objeto no segundo parâmetro, por exemplo: ```javascript @@ -145,11 +149,11 @@ O segundo método para renderizar a view, é usando um objeto com a propriedade ```javascript server.route({ - method: 'GET', - path: '/', - handler: { - view: 'index' - } + method: 'GET', + path: '/', + handler: { + view: 'index', + }, }); ``` @@ -168,23 +172,23 @@ handler: { ### Contexto global -Nós estamos vendo como passar o contexto direto para uma view, mas como é que temos alguns contextos padrão que deve *sempre* estar disponível em todos os templates? +Nós estamos vendo como passar o contexto direto para uma view, mas como é que temos alguns contextos padrão que deve _sempre_ estar disponível em todos os templates? O mais simplete caminho para alcançar isso é usando a opção `context` ao chamar `server.views()`: ```javascript const defaultContext = { - title: 'My personal site' + title: 'My personal site', }; server.views({ - engines: { - 'html': { - module: require('handlebars'), - compileMode: 'sync' // específico do motor - } + engines: { + html: { + module: require('handlebars'), + compileMode: 'sync', // específico do motor }, - context: defaultContext + }, + context: defaultContext, }); ``` @@ -199,20 +203,20 @@ O código a seguir é uma função helper que irá armazerna em um arquivo chama ```javascript module.exports = function () { - const fortunes = [ - 'Heisenberg may have slept here...', - 'Wanna buy a duck?', - 'Say no, then negotiate.', - 'Time and tide wait for no man.', - 'To teach is to learn.', - 'Never ask the barber if you need a haircut.', - 'You will forget that you ever knew me.', - 'You will be run over by a beer truck.', - 'Fortune favors the lucky.', - 'Have a nice day!' - ]; - const x = Math.floor(Math.random() * fortunes.length); - return fortunes[x]; + const fortunes = [ + 'Heisenberg may have slept here...', + 'Wanna buy a duck?', + 'Say no, then negotiate.', + 'Time and tide wait for no man.', + 'To teach is to learn.', + 'Never ask the barber if you need a haircut.', + 'You will forget that you ever knew me.', + 'You will be run over by a beer truck.', + 'Fortune favors the lucky.', + 'Have a nice day!', + ]; + const x = Math.floor(Math.random() * fortunes.length); + return fortunes[x]; }; ``` @@ -220,7 +224,7 @@ Agora nos podemos usar o view helper dentro do nosso template. Aqui está um tre ```html

    Your fortune

    -

    {{fortune}}

    +

    {{fortune}}

    ``` Agora quando nós iniciamos o servidor e apontar o seu browser para a rota que utiliza seu template (que usa nossa view helper), devemos ver um parágrafo com um frase escolhida randomicamente logo abaixo do cabeçalho. @@ -235,30 +239,29 @@ const Hapi = require('hapi'); const server = new Hapi.Server(); server.connection({ - port: Number(process.argv[2] || 8080), - host: 'localhost' + port: Number(process.argv[2] || 8080), + host: 'localhost', }); server.register(require('vision'), (err) => { + Hoek.assert(!err, err); - Hoek.assert(!err, err); - - server.views({ - engines: { - html: require('handlebars') - }, - relativeTo: __dirname, - path: 'templates', - helpersPath: 'helpers' - }); - - server.route({ - method: 'GET', - path: '/', - handler: function (request, reply) { - reply.view('index'); - } - }); + server.views({ + engines: { + html: require('handlebars'), + }, + relativeTo: __dirname, + path: 'templates', + helpersPath: 'helpers', + }); + + server.route({ + method: 'GET', + path: '/', + handler: function (request, reply) { + reply.view('index'); + }, + }); }); server.start(); @@ -272,9 +275,9 @@ Podemos usar o sistema de layout embutido, primeiro configure a view: ```javascript server.views({ - // ... - layout: true, - layoutPath: Path.join(__dirname, 'views/layout') + // ... + layout: true, + layoutPath: Path.join(__dirname, 'views/layout'), }); ``` @@ -285,8 +288,8 @@ Estabelecer uma área de conteúdo em seu `layout.html`: ```html - {{{content}}} - + {{{content}}} + ``` @@ -296,16 +299,17 @@ E seu view deve ter somente o conteúdo:
    Content
    ``` -Quando renderizamos a view, o `{{{content}}}` irá replicar pelo conteúdo da view. +Quando renderizamos a view, o `{{{content}}}` irá replicar pelo conteúdo da view. Se você quiser uma layout padrão diferente, você pode definir uma opção globalmente: ```javascript server.views({ - // ... - layout: 'another_default' + // ... + layout: 'another_default', }); ``` + Você também pode especificar um layout diferente por view: ```javascript diff --git a/static/lib/tutorials/tr_TR/auth.md b/docs/tutorials/tr_TR/auth.md similarity index 88% rename from static/lib/tutorials/tr_TR/auth.md rename to docs/tutorials/tr_TR/auth.md index 1f4f887f..d7cabab7 100644 --- a/static/lib/tutorials/tr_TR/auth.md +++ b/docs/tutorials/tr_TR/auth.md @@ -1,3 +1,9 @@ +--- +title: Authentication +--- + + + ## Kimlik Dogrulama _Bu kurs hapi v17 ile uyumludur_ @@ -15,50 +21,47 @@ const Bcrypt = require('bcrypt'); const Hapi = require('@hapi/hapi'); const users = { - john: { - username: 'john', - password: '$2a$10$iqJSHD.BGr0E2IxQwYgJmeP3NvhPrXAeLSaGCj6IR/XU5QtjVu5Tm', // 'secret' - name: 'John Doe', - id: '2133d32a' - } + john: { + username: 'john', + password: '$2a$10$iqJSHD.BGr0E2IxQwYgJmeP3NvhPrXAeLSaGCj6IR/XU5QtjVu5Tm', // 'secret' + name: 'John Doe', + id: '2133d32a', + }, }; const validate = async (request, username, password) => { + const user = users[username]; + if (!user) { + return { credentials: null, isValid: false }; + } - const user = users[username]; - if (!user) { - return { credentials: null, isValid: false }; - } - - const isValid = await Bcrypt.compare(password, user.password); - const credentials = { id: user.id, name: user.name }; + const isValid = await Bcrypt.compare(password, user.password); + const credentials = { id: user.id, name: user.name }; - return { isValid, credentials }; + return { isValid, credentials }; }; const start = async () => { + const server = Hapi.server({ port: 4000 }); - const server = Hapi.server({ port: 4000 }); - - await server.register(require('hapi-auth-basic')); - - server.auth.strategy('simple', 'basic', { validate }); + await server.register(require('hapi-auth-basic')); - server.route({ - method: 'GET', - path: '/', - options: { - auth: 'simple' - }, - handler: function (request, h) { + server.auth.strategy('simple', 'basic', { validate }); - return 'welcome'; - } - }); + server.route({ + method: 'GET', + path: '/', + options: { + auth: 'simple', + }, + handler: function (request, h) { + return 'welcome'; + }, + }); - await server.start(); + await server.start(); - console.log('server running at: ' + server.info.uri); + console.log('server running at: ' + server.info.uri); }; start(); @@ -76,11 +79,11 @@ Son olarak bir yola (route) kimlik doğrulama için `simple` adlı stratejiyi ku Bir şema (`scheme`) `function (server, options)` imzası taşıyan bir yöntemdir. Sunucu (`server`) değiştirgesi şemanın eklendiği sunucunun referansıyken, seçenekler (`options`) değiştirgesi bu şemayı kullanan stratejiyi kaydederken kullanılan yapılandırma nesnesidir. -Bu yöntem içerisinde *en az* `authenticate` anahtarı olan bir nesne dönmelidir. Kullanılabilecek diğer isteğe bağlı yöntemler `payload` ve `response`tur. +Bu yöntem içerisinde _en az_ `authenticate` anahtarı olan bir nesne dönmelidir. Kullanılabilecek diğer isteğe bağlı yöntemler `payload` ve `response`tur. ### `authenticate` -`authenticate` yönteminin imzası `function (request, h)`'dir ve bir şemada *gerekli* olan tek yöntemdir. +`authenticate` yönteminin imzası `function (request, h)`'dir ve bir şemada _gerekli_ olan tek yöntemdir. Bu kapsamda, istek (`request`) sunucu tarafından oluşturulan `request` nesnesidir. Yol işleyici içerisinde erişilebilir olan nesne ile aynı nesnedir ve [API Referansı](/api#request-object)nda dokümantasyonu bulunabilir. @@ -152,6 +155,6 @@ Son `mode` ayarı ise `'try'`dır (dene). `'try'` (dene) ile `'optional'` (seçi Bir strateji (strategy) belirlerken, `strategy` değiştirgesini stratejinin adı olarak ayarlayabilirsin. Birden fazla strateji (strategy) tanımlarken, değiştirgenin adı `strategies` olmalı ve değeri denenecek her bir stratejinin adını taşıyan karakter katarlarından oluşan bir dizi olmalıdır. Her bir strateji biri biri başarılı olana ya da hepsi hata verene kadar denenir. -Son olarak, `payload` (yararlı yük) değiştirgesi `false` olarak ayarlanarak kimlik doğrulama yapılmamış olmasını kontrol etmeye ayarlanabilir. `'required'` ya da `true` ise kimlik doğrulamasının *zorunlu olduğu* olduğu, ya da `'optional'`, eğer kullanıcı bu bilgileri sağlıyorsa geçerli olması gerektiği anlamında kullanılabilir. +Son olarak, `payload` (yararlı yük) değiştirgesi `false` olarak ayarlanarak kimlik doğrulama yapılmamış olmasını kontrol etmeye ayarlanabilir. `'required'` ya da `true` ise kimlik doğrulamasının _zorunlu olduğu_ olduğu, ya da `'optional'`, eğer kullanıcı bu bilgileri sağlıyorsa geçerli olması gerektiği anlamında kullanılabilir. `payload` değiştirgesi yalnızca `payload` yöntemini destekleyen şemalarda kullanılabilir. diff --git a/static/lib/tutorials/tr_TR/caching.md b/docs/tutorials/tr_TR/caching.md similarity index 76% rename from static/lib/tutorials/tr_TR/caching.md rename to docs/tutorials/tr_TR/caching.md index 60708295..0214faf4 100644 --- a/static/lib/tutorials/tr_TR/caching.md +++ b/docs/tutorials/tr_TR/caching.md @@ -1,3 +1,9 @@ +--- +title: Caching +--- + + + ## Önbellekleme _Bu kurs hapi v17 ile uyumludur_ @@ -16,30 +22,29 @@ Hadi bu başlığı hapi ile nasıl ayarlayabileceğimize bakalım: ```javascript server.route({ - path: '/hapi/{ttl?}', - method: 'GET', - handler: function (request, h) { - - const response = h.response({ be: 'hapi' }); + path: '/hapi/{ttl?}', + method: 'GET', + handler: function (request, h) { + const response = h.response({ be: 'hapi' }); - if (request.params.ttl) { - response.ttl(request.params.ttl); - } + if (request.params.ttl) { + response.ttl(request.params.ttl); + } - return response; + return response; + }, + options: { + cache: { + expiresIn: 30 * 1000, + privacy: 'private', }, - options: { - cache: { - expiresIn: 30 * 1000, - privacy: 'private' - } - } + }, }); ``` Yukarıdaki örnek bir yol (route) üzerinde nasıl `cache` seçeneklerini ayarlayabileceğini gösteriyor. Burada `expiresIn` değerini 30 saniye ve `privacy` değerini `private` olarak ayarladık. -Bu örnek aynı zamanda `expiresIn` değerinin üzerine [yanıt nesnesi](/api#response-object) arayüzünde bulunan `ttl(msec)` yöntemi ile yazılabileceğini gösteriyor. +Bu örnek aynı zamanda `expiresIn` değerinin üzerine [yanıt nesnesi](/api#response-object) arayüzünde bulunan `ttl(msec)` yöntemi ile yazılabileceğini gösteriyor. `/hapi`ye bir istekte bulunursak yanıt başlığı olarak `cache-control: max-age=30, must-revalidate, private` alırız. Eper isteği `/hapi/5000`e yaparsak bunun yerine şu başlık gelir: `cache-control: max-age=5, must-revalidate, private`. @@ -49,16 +54,14 @@ Bu örnek aynı zamanda `expiresIn` değerinin üzerine [yanıt nesnesi](/api#r Bazı durumlarda, sunucu bir kaynağın son düzenlendiği tarihi sağlayabilir. Durağan içerikler sunmak için [inert](https://github.com/hapijs/inert) eklentisini kullanırken otomatik olarak her yanıta `Last-Modified` başlığı eklenir. - Bir yanıtta `Last-Modified` başlığı ayarlandığında hapi bu bilgiyi istemciden gelen `If-Modified-Since` başlığıyla karşılaştırarak yanıt durum kodunun `304 Not Modified` olup olmayacağına karar verir. Bu olay anı zamanda koşullu GET isteği olarak da bilinir. Bu yanıtın güzel tarafı, `304` yanıtı alan tarayıcının aynı içeriği tekrar indirmesine gerek kalmamasıdır. - `lastModified` bilgsinin bir `Date` nesnesi olduğunu varsayarsak bu başlığı [yanıt nesnesi (response object)](/api#response-object) kullanarak şu şekilde ayarlayabilirsiniz: ```javascript -return h.response(result) - .header('Last-Modified', lastModified.toUTCString()); +return h.response(result).header('Last-Modified', lastModified.toUTCString()); ``` + Bu yazının [son bölümünde](#istemci-ve-sunucu-önbellekleme) `Last-Modified` kullanan bir örnek daha var. #### ETag @@ -91,21 +94,21 @@ hapi varsayılan olarak [catbox memory](https://github.com/hapijs/catbox-memory) const Hapi = require('@hapi/hapi'); const server = Hapi.server({ - port: 8000, - cache: [ - { - name: 'mongoCache', - engine: require('catbox-mongodb'), - host: '127.0.0.1', - partition: 'cache' - }, - { - name: 'redisCache', - engine: require('catbox-redis'), - host: '127.0.0.1', - partition: 'cache' - } - ] + port: 8000, + cache: [ + { + name: 'mongoCache', + engine: require('catbox-mongodb'), + host: '127.0.0.1', + partition: 'cache', + }, + { + name: 'redisCache', + engine: require('catbox-redis'), + host: '127.0.0.1', + partition: 'cache', + }, + ], }); ``` @@ -117,40 +120,36 @@ Yukarıdaki örnekte, iki tane catbox istemcisi tanımladık: mongoCache ve redi ```javascript const start = async () => { + const add = async (a, b) => { + await Hoek.wait(1000); // Yavaş I/O simülasyonu + + return Number(a) + Number(b); + }; + + const sumCache = server.cache({ + cache: 'mongoCache', + expiresIn: 10 * 1000, + segment: 'customSegment', + generateFunc: async (id) => { + return await add(id.a, id.b); + }, + generateTimeout: 2000, + }); - const add = async (a, b) => { - - await Hoek.wait(1000); // Yavaş I/O simülasyonu - - return Number(a) + Number(b); - }; - - const sumCache = server.cache({ - cache: 'mongoCache', - expiresIn: 10 * 1000, - segment: 'customSegment', - generateFunc: async (id) => { - - return await add(id.a, id.b); - }, - generateTimeout: 2000 - }); - - server.route({ - path: '/add/{a}/{b}', - method: 'GET', - handler: async function (request, h) { - - const { a, b } = request.params; - const id = `${a}:${b}`; + server.route({ + path: '/add/{a}/{b}', + method: 'GET', + handler: async function (request, h) { + const { a, b } = request.params; + const id = `${a}:${b}`; - return await sumCache.get({ id, a, b }); - } - }); + return await sumCache.get({ id, a, b }); + }, + }); - await server.start(); + await server.start(); - console.log('Server running at:', server.info.uri); + console.log('Server running at:', server.info.uri); }; start(); @@ -172,40 +171,39 @@ Daha iyi olabilir! Yüzde doksan beş ihtimal önbellekleme için [sunucu yönte ```javascript const start = async () => { + // ... - // ... - - server.method('sum', add, { - cache: { - cache: 'mongoCache', - expiresIn: 10 * 1000, - generateTimeout: 2000 - } - }); - - server.route({ - path: '/add/{a}/{b}', - method: 'GET', - handler: async function (request, h) { + server.method('sum', add, { + cache: { + cache: 'mongoCache', + expiresIn: 10 * 1000, + generateTimeout: 2000, + }, + }); - const { a, b } = request.params; - return await server.methods.sum(a, b); - } - }); + server.route({ + path: '/add/{a}/{b}', + method: 'GET', + handler: async function (request, h) { + const { a, b } = request.params; + return await server.methods.sum(a, b); + }, + }); - await server.start(); + await server.start(); - // ... + // ... }; start(); ``` + [server.method()](/api#-servermethodname-method-options) otomatik olarak `segment: '#sum'` kesitiyle yeni bir [politika (policy)](https://github.com/hapijs/catbox#policy) oluşturdu. Ayrıca değiştirgelerle tekil bir `id`(önbellek anahtarı)'de oluşturuldu. Varsayılan olarak, `string`, `number` ve `boolean` değiştirgelerle çalışabilir. Daha kompleks değiştirgeler için değiştirgeleri kullanarak nasıl tekil tanımlayıcılar üretileceğini belirleyen bir `generateKey` işlevi tanımlamalısın. - [Sunucu yöntemleri](/tutorials/servermethods) öğreticisinden daha fazla bilgi alabilirsin. #### Sırada ne var? -* catbox politikasının [seçenekler](https://github.com/hapijs/catbox#policy)inin içine bakarak ve catbox önbelleklemenin tüm potansiyelinden faydalanmak için `staleIn`, `staleTimeout`, `generateTimeout` kısımlarına özellikle dikkat etmelisiniz. -* Daha fazla örnek için [sunucu yöntemleri (server methods)](http://hapijs.com/tutorials/servermethods) öğreticisine göz atabilirsin. +- catbox politikasının [seçenekler](https://github.com/hapijs/catbox#policy)inin içine bakarak ve catbox önbelleklemenin tüm potansiyelinden faydalanmak için `staleIn`, `staleTimeout`, `generateTimeout` kısımlarına özellikle dikkat etmelisiniz. +- Daha fazla örnek için [sunucu yöntemleri (server methods)](http://hapijs.com/tutorials/servermethods) öğreticisine göz atabilirsin. ### İstemci ve Sunucu önbellekleme @@ -215,35 +213,32 @@ start(); ```javascript const start = async () => { + //... + + server.method('sum', add, { + cache: { + cache: 'mongoCache', + expiresIn: 10 * 1000, + generateTimeout: 2000, + getDecoratedValue: true, + }, + }); - //... - - server.method('sum', add, { - cache: { - cache: 'mongoCache', - expiresIn: 10 * 1000, - generateTimeout: 2000, - getDecoratedValue: true - } - }); - - server.route({ - path: '/add/{a}/{b}', - method: 'GET', - handler: async function (request, h) { - - const { a, b } = request.params; - const { value, cached } = await server.methods.sum(a, b); - const lastModified = cached ? new Date(cached.stored) : new Date(); + server.route({ + path: '/add/{a}/{b}', + method: 'GET', + handler: async function (request, h) { + const { a, b } = request.params; + const { value, cached } = await server.methods.sum(a, b); + const lastModified = cached ? new Date(cached.stored) : new Date(); - return h.response(value) - .header('Last-modified', lastModified.toUTCString()); - } - }); + return h.response(value).header('Last-modified', lastModified.toUTCString()); + }, + }); - await server.start(); + await server.start(); - // ... + // ... }; ``` diff --git a/static/lib/tutorials/zh_CN/community.md b/docs/tutorials/tr_TR/community.md similarity index 76% rename from static/lib/tutorials/zh_CN/community.md rename to docs/tutorials/tr_TR/community.md index a651208c..b8eec564 100644 --- a/static/lib/tutorials/zh_CN/community.md +++ b/docs/tutorials/tr_TR/community.md @@ -1,3 +1,9 @@ +--- +title: Community +--- + + + # Community Tutorials ## No tutorials yet diff --git a/static/lib/tutorials/tr_TR/cookies.md b/docs/tutorials/tr_TR/cookies.md similarity index 90% rename from static/lib/tutorials/tr_TR/cookies.md rename to docs/tutorials/tr_TR/cookies.md index c40b7ff3..ab6c49bb 100644 --- a/static/lib/tutorials/tr_TR/cookies.md +++ b/docs/tutorials/tr_TR/cookies.md @@ -1,3 +1,9 @@ +--- +title: Cookies +--- + + + ## Kurabiyeler _Bu kurs hapi v17 ile uyumludur_ @@ -12,12 +18,12 @@ Bir kurabiye kullanmak için önce [`server.state(name, [options])`](/api#-serve ```javascript server.state('data', { - ttl: null, - isSecure: true, - isHttpOnly: true, - encoding: 'base64json', - clearInvalid: false, // bozuk kurabiyeleri at - strictHeader: true // RFC 6265 ihlallerine göz yumma + ttl: null, + isSecure: true, + isHttpOnly: true, + encoding: 'base64json', + clearInvalid: false, // bozuk kurabiyeleri at + strictHeader: true, // RFC 6265 ihlallerine göz yumma }); ``` @@ -27,12 +33,12 @@ Buna ek olarak, `options.state` nesnesinde bulunan iki özelliği kullanarak kur ```json5 { - options: { - state: { - parse: true, // kurabiyeleri ayristir ve request.state icerisinde tut - failAction: 'error' // 'ignore' ya da 'log' da olabilir - } - } + options: { + state: { + parse: true, // kurabiyeleri ayristir ve request.state icerisinde tut + failAction: 'error', // 'ignore' ya da 'log' da olabilir + }, + }, } ``` @@ -55,7 +61,6 @@ return h.response('Hello').state('data', { firstVisit: false }); ### Seceneklerin uzerine yazmak - Bir kurabiye ayarlarkan, `server.state()` yöntemine bazı seçenekler de gönderebilirsin. Mesela: ```javascript diff --git a/static/lib/tutorials/tr_TR/expresstohapi.md b/docs/tutorials/tr_TR/express-to-hapi.md similarity index 55% rename from static/lib/tutorials/tr_TR/expresstohapi.md rename to docs/tutorials/tr_TR/express-to-hapi.md index 0af99a4a..51576c5c 100644 --- a/static/lib/tutorials/tr_TR/expresstohapi.md +++ b/docs/tutorials/tr_TR/express-to-hapi.md @@ -1,5 +1,11 @@ +--- +title: Express to hapi +--- + + + # Express to hapi Guide ## No Translation Yet -This guide has not been translated yet. If you would like to translate it, please submit a pull request. \ No newline at end of file +This guide has not been translated yet. If you would like to translate it, please submit a pull request. diff --git a/static/lib/tutorials/tr_TR/gettingstarted.md b/docs/tutorials/tr_TR/getting-started.md similarity index 78% rename from static/lib/tutorials/tr_TR/gettingstarted.md rename to docs/tutorials/tr_TR/getting-started.md index fd5736f8..5d3452a4 100644 --- a/static/lib/tutorials/tr_TR/gettingstarted.md +++ b/docs/tutorials/tr_TR/getting-started.md @@ -1,3 +1,9 @@ +--- +title: Getting Started +--- + + + ## Başlarken _Bu kurs hapi v17 ile uyumludur_ @@ -6,10 +12,9 @@ _Bu kurs hapi v17 ile uyumludur_ `projem` adında yeni bir dizin oluştur ve sonra: - -* `cd myproject` komutunu çalıştırarak proje dizinine gir. -* `npm init` komutunu çalıştırarak yönergeleri izle, bu komut senin için package.json dosyası oluşturur. -* `npm install --save @hapi/hapi@17.x.x` komutunu çalıştır. Bu komut hapiyi kurar ve package.json dosyasına gereksinim olarak kaydeder. +- `cd myproject` komutunu çalıştırarak proje dizinine gir. +- `npm init` komutunu çalıştırarak yönergeleri izle, bu komut senin için package.json dosyası oluşturur. +- `npm install --save @hapi/hapi@17.x.x` komutunu çalıştır. Bu komut hapiyi kurar ve package.json dosyasına gereksinim olarak kaydeder. Hepsi bu kadar! Artık hapi kullanarak bir sunucu oluşturmak için ihtiyacın olan herşeye sahipsin. @@ -23,20 +28,18 @@ En basit sunucu şöyle bir şeydir: const Hapi = require('@hapi/hapi'); const server = Hapi.server({ - port: 3000, - host: 'localhost' + port: 3000, + host: 'localhost', }); const init = async () => { - - await server.start(); - console.log(`Server running at: ${server.info.uri}`); + await server.start(); + console.log(`Server running at: ${server.info.uri}`); }; process.on('unhandledRejection', (err) => { - - console.log(err); - process.exit(1); + console.log(err); + process.exit(1); }); init(); @@ -46,8 +49,6 @@ init(); Bir sunucu oluştururken, konak adı, IP adresi ve hatta bir Unix soket dosyası ya da bağlanılacak Windows adlı veri yolu (Windows named pipe) bile sağlayabiliriz. Daha fazla detay için bkz: [API Referansı](/api/#-server-options). - - ### Güzergah eklemek Artık sunucumuz olduğuna göre, bir iki güzergah eklemeliyiz ki gerçekten bir şeyler yapsın. Bakalım nasıl olacak: @@ -58,38 +59,34 @@ Artık sunucumuz olduğuna göre, bir iki güzergah eklemeliyiz ki gerçekten bi const Hapi = require('@hapi/hapi'); const server = Hapi.server({ - port: 3000, - host: 'localhost' + port: 3000, + host: 'localhost', }); server.route({ - method: 'GET', - path: '/', - handler: (request, h) => { - - return 'Hello, world!'; - } + method: 'GET', + path: '/', + handler: (request, h) => { + return 'Hello, world!'; + }, }); server.route({ - method: 'GET', - path: '/{name}', - handler: (request, h) => { - - return 'Hello, ' + encodeURIComponent(request.params.name) + '!'; - } + method: 'GET', + path: '/{name}', + handler: (request, h) => { + return 'Hello, ' + encodeURIComponent(request.params.name) + '!'; + }, }); const init = async () => { - - await server.start(); - console.log(`Server running at: ${server.info.uri}`); + await server.start(); + console.log(`Server running at: ${server.info.uri}`); }; process.on('unhandledRejection', (err) => { - - console.log(err); - process.exit(1); + console.log(err); + process.exit(1); }); init(); @@ -109,22 +106,20 @@ Hello world uygulamamızla basit bir hapi uygulaması başlatabildiğimizi kanı `server.js` dosyasını açarak `init` işlevini şu şekilde güncelle: -``` javascript +```javascript const init = async () => { + await server.register(require('@hapi/inert')); - await server.register(require('@hapi/inert')); - - server.route({ - method: 'GET', - path: '/hello', - handler: (request, h) => { - - return h.file('./public/hello.html'); - } - }); + server.route({ + method: 'GET', + path: '/hello', + handler: (request, h) => { + return h.file('./public/hello.html'); + }, + }); - await server.start(); - console.log(`Server running at: ${server.info.uri}`); + await server.start(); + console.log(`Server running at: ${server.info.uri}`); }; ``` @@ -140,7 +135,7 @@ Ana dizininde içerisinde `hello.html` olan `public` diye bir dizin oluştur ve - + Hapi.js is awesome! @@ -156,7 +151,8 @@ Bu basit bir HTML5 dokümanı. [Inert](https://github.com/hapijs/inert) istek yapıldığında diskinde ne varsa onu sunar. Bu canlı yenileme olayına sebep olan da bu. `/hello` yolunu zevkine göre düzenle. Durağan içeriklerin nasıl sunulduğu [Durağan İçerik Sunmak](/tutorials/servingfiles) adresinde detaylandırılıyor. Bu teknik genelde resim, biçem sayfaları (stylesheet) ve durağan sayfaları sunmak için kullanırılır. -___ + +--- ### Eklentileri Kullanmak @@ -176,50 +172,46 @@ Sonra `server.js` dosyasını güncelle: const Hapi = require('@hapi/hapi'); const server = Hapi.server({ - port: 3000, - host: 'localhost' + port: 3000, + host: 'localhost', }); server.route({ - method: 'GET', - path: '/', - handler: (request, h) => { - - return 'Hello, world!'; - } + method: 'GET', + path: '/', + handler: (request, h) => { + return 'Hello, world!'; + }, }); server.route({ - method: 'GET', - path: '/{name}', - handler: (request, h) => { - - // request.log(['a', 'name'], "Request name"); - // or - request.logger.info('In handler %s', request.path); - - return `Hello, ${encodeURIComponent(request.params.name)}!`; - } + method: 'GET', + path: '/{name}', + handler: (request, h) => { + // request.log(['a', 'name'], "Request name"); + // or + request.logger.info('In handler %s', request.path); + + return `Hello, ${encodeURIComponent(request.params.name)}!`; + }, }); const init = async () => { - - await server.register({ - plugin: require('hapi-pino'), - options: { - prettyPrint: false, - logEvents: ['response', 'onPostStart'] - } - }); - - await server.start(); - console.log(`Server running at: ${server.info.uri}`); + await server.register({ + plugin: require('hapi-pino'), + options: { + prettyPrint: false, + logEvents: ['response', 'onPostStart'], + }, + }); + + await server.start(); + console.log(`Server running at: ${server.info.uri}`); }; process.on('unhandledRejection', (err) => { - - console.log(err); - process.exit(1); + console.log(err); + process.exit(1); }); init(); diff --git a/static/lib/tutorials/tr_TR/logging.md b/docs/tutorials/tr_TR/logging.md similarity index 86% rename from static/lib/tutorials/tr_TR/logging.md rename to docs/tutorials/tr_TR/logging.md index 911ac7a3..d83580a1 100644 --- a/static/lib/tutorials/tr_TR/logging.md +++ b/docs/tutorials/tr_TR/logging.md @@ -1,3 +1,9 @@ +--- +title: Logging +--- + + + ## Gunlukleme _Bu kurs hapi v17 ile uyumludur_ @@ -26,34 +32,30 @@ Ek olarak `server.log()` yönteminin üçüncü bir `timestamp` (zaman damgası) hapi sunucu nesnesi her bir günlükleme olayı için bir olay yayınlar. Standart EventEmitter API (olay yayınlayıcı uygulama programa arayüzü)nü kullanarak bu olayları dinleyebilir ve istediğin gibi gösterebilirsin. - ```javascript server.events.on('log', (event, tags) => { - - if (tags.error) { - console.log(`Server error: ${event.error ? event.error.message : 'unknown'}`); - } + if (tags.error) { + console.log(`Server error: ${event.error ? event.error.message : 'unknown'}`); + } }); ``` - `server.log()` kullanılarak günlüklenen olaylar bir `log` (günlükleme) olayı, `request.log()` kullanılarak günlüklenen olaylar ise bir `request` (istek) olayı yayınlar. -Bir istek ile ilgili tüm günlükleri `request.logs` kullanarak alabilirsin. Günlüklenen tüm istek olaylarını içeren bir dizi döner. Önce yol (route) üzerinde `log.collect` seçeneğini `true` olarak ayarlamalısın, yoksa dizi boş gelir. +Bir istek ile ilgili tüm günlükleri `request.logs` kullanarak alabilirsin. Günlüklenen tüm istek olaylarını içeren bir dizi döner. Önce yol (route) üzerinde `log.collect` seçeneğini `true` olarak ayarlamalısın, yoksa dizi boş gelir. ```javascript server.route({ - method: 'GET', - path: '/', - options: { - log: { - collect: true - } + method: 'GET', + path: '/', + options: { + log: { + collect: true, }, - handler: function (request, h) { - - return 'hello'; - } + }, + handler: function (request, h) { + return 'hello'; + }, }); ``` diff --git a/static/lib/tutorials/tr_TR/plugins.md b/docs/tutorials/tr_TR/plugins.md similarity index 70% rename from static/lib/tutorials/tr_TR/plugins.md rename to docs/tutorials/tr_TR/plugins.md index 867e54ef..5504ee9f 100644 --- a/static/lib/tutorials/tr_TR/plugins.md +++ b/docs/tutorials/tr_TR/plugins.md @@ -1,3 +1,9 @@ +--- +title: Plugins +--- + + + ## Eklentiler _Bu kurs hapi v17 ile uyumludur_ @@ -14,24 +20,22 @@ Eklenti yazmak çok kolay. Aslında yalnızca `register` (kaydet) özelliği ola 'use strict'; const myPlugin = { - name: 'myPlugin', - version: '1.0.0', - register: async function (server, options) { - - // Örnek bir yol yaratalım - - server.route({ - method: 'GET', - path: '/test', - handler: function (request, h) { - - return 'hello, world'; - } - }); + name: 'myPlugin', + version: '1.0.0', + register: async function (server, options) { + // Örnek bir yol yaratalım + + server.route({ + method: 'GET', + path: '/test', + handler: function (request, h) { + return 'hello, world'; + }, + }); - // vesaire... - await someAsyncMethods(); - } + // vesaire... + await someAsyncMethods(); + }, }; ``` @@ -41,23 +45,21 @@ Ya da harici bir modül olarak yazıldıklarında `pkg` özelliği belirleyebili 'use strict'; exports.plugin = { - pkg: require('./package.json'), - register: async function (server, options) { - - // Örnek bir yol yaratalım - - server.route({ - method: 'GET', - path: '/test', - handler: function (request, h) { - - return 'hello, world'; - } - }); + pkg: require('./package.json'), + register: async function (server, options) { + // Örnek bir yol yaratalım + + server.route({ + method: 'GET', + path: '/test', + handler: function (request, h) { + return 'hello, world'; + }, + }); - // vesaire... - await someAsyncMethods(); - } + // vesaire... + await someAsyncMethods(); + }, }; ``` @@ -69,7 +71,6 @@ Ayrıca, eklenti nesnesi değeri `true` olan bir `multiple` (çoklu) özelliği Kullanılabilir bir diğer özellik ise `once`tır (bir kez). `true` olarak ayarlandığında mükerrer kayıtlar hapi tarafından hata fırlatmaksızın görmezden gelinecektir. - ### Kaydetme (register) Yontemi Yukarıda gördüğümüz üzere, `register` (kaydet) yöntemi iki değiştirge kabul eder: `server` ve `options`. @@ -86,14 +87,13 @@ Eklentiler `server.register()` yöntemiyle tek tek ya da bir grup olarak bir diz ```javascript const start = async function () { + // bir eklenti yükle - // bir eklenti yükle - - await server.register(require('myplugin')); + await server.register(require('myplugin')); - // birden fazla eklenti yükle + // birden fazla eklenti yükle - await server.register([require('myplugin'), require('yourplugin')]); + await server.register([require('myplugin'), require('yourplugin')]); }; ``` @@ -101,13 +101,12 @@ Eklentine seçenekler göndermek için, bunun yerine `plugin` (eklenti) ve `opti ```javascript const start = async function () { - - await server.register({ - plugin: require('myplugin'), - options: { - message: 'hello' - } - }); + await server.register({ + plugin: require('myplugin'), + options: { + message: 'hello', + }, + }); }; ``` @@ -115,14 +114,16 @@ Bu nesneler bir dizi içinde de gönderilebilir: ```javascript const start = async function () { - - await server.register([{ - plugin: require('plugin1'), - options: {} - }, { - plugin: require('plugin2'), - options: {} - }]); + await server.register([ + { + plugin: require('plugin1'), + options: {}, + }, + { + plugin: require('plugin2'), + options: {}, + }, + ]); }; ``` @@ -138,21 +139,19 @@ Farzı mahal şöyle bir eklentimiz olsun: 'use strict'; exports.plugin = { - pkg: require('./package.json'), - register: async function (server, options) { - - server.route({ - method: 'GET', - path: '/test', - handler: function (request, h) { - - return 'test passed'; - } - }); + pkg: require('./package.json'), + register: async function (server, options) { + server.route({ + method: 'GET', + path: '/test', + handler: function (request, h) { + return 'test passed'; + }, + }); - // vesaire... - await someAsyncMethods(); - } + // vesaire... + await someAsyncMethods(); + }, }; ``` @@ -160,12 +159,11 @@ Normalde bu eklenti yüklendiğinde `/test`e bir `GET` yolu oluşturur. Ancak se ```javascript const start = async function () { - - await server.register(require('myplugin'), { - routes: { - prefix: '/plugins' - } - }); + await server.register(require('myplugin'), { + routes: { + prefix: '/plugins', + }, + }); }; ``` diff --git a/static/lib/tutorials/tr_TR/routing.md b/docs/tutorials/tr_TR/routing.md similarity index 82% rename from static/lib/tutorials/tr_TR/routing.md rename to docs/tutorials/tr_TR/routing.md index cbcb8cb6..2fbc5920 100644 --- a/static/lib/tutorials/tr_TR/routing.md +++ b/docs/tutorials/tr_TR/routing.md @@ -1,3 +1,9 @@ +--- +title: Routing +--- + + + ## Yol Tayin Etmek (routing) _Bu kurs hapi v17 ile uyumludur_ @@ -6,12 +12,11 @@ Aynı diğer çatılarda (framework) olduğu gibi, hapide de bir yol tanımlarke ```javascript server.route({ - method: 'GET', - path: '/', - handler: function (request, h) { - - return 'Selam!'; - } + method: 'GET', + path: '/', + handler: function (request, h) { + return 'Selam!'; + }, }); ``` @@ -21,12 +26,11 @@ Yukarıdaki yol (route) `/` güzergahına yapılan bir `GET` isteğine `Selam!` ```javascript server.route({ - method: ['PUT', 'POST'], - path: '/', - handler: function (request, h) { - - return 'Bir şey yaptım!'; - } + method: ['PUT', 'POST'], + path: '/', + handler: function (request, h) { + return 'Bir şey yaptım!'; + }, }); ``` @@ -36,12 +40,11 @@ Güzergah seçeneği bir metin olmalı. Bununla birlikte içerisinde adlandırı ```javascript server.route({ - method: 'GET', - path: '/selam/{user}', - handler: function (request, h) { - - return `Selam ${encodeURIComponent(request.params.user)}!`; - } + method: 'GET', + path: '/selam/{user}', + handler: function (request, h) { + return `Selam ${encodeURIComponent(request.params.user)}!`; + }, }); ``` @@ -53,16 +56,13 @@ Yukarıdaki örnekte, user değiştirgesi gereklidir: `/selam/hilmi` ya da `/sel ```javascript server.route({ - method: 'GET', - path: '/selam/{user?}', - handler: function (request, h) { - - const user = request.params.user ? - encodeURIComponent(request.params.user) : - 'yabancı'; + method: 'GET', + path: '/selam/{user?}', + handler: function (request, h) { + const user = request.params.user ? encodeURIComponent(request.params.user) : 'yabancı'; - return `Selam ${user}!`; - } + return `Selam ${user}!`; + }, }); ``` @@ -74,19 +74,18 @@ Seçime bağlı güzergah değiştirgelerinin yanı sıra, birden çok bölmeyle ```javascript server.route({ - method: 'GET', - path: '/selam/{user*2}', - handler: function (request, h) { - - const userParts = request.params.user.split('/'); - return `Selam ${encodeURIComponent(userParts[0])} ${encodeURIComponent(userParts[1])}!`; - } + method: 'GET', + path: '/selam/{user*2}', + handler: function (request, h) { + const userParts = request.params.user.split('/'); + return `Selam ${encodeURIComponent(userParts[0])} ${encodeURIComponent(userParts[1])}!`; + }, }); ``` Bu yapılandırmayla, `/selam/ali/veli` güzergahına yapılan bir istek `Selam ali veli!` metinyla cevaplanır. Burada önemli olan değişgenin `"ali/veli"` metinnın tamamı olmasıdır. Bu yüzden metinna ayrıştırma uygulayarak iki parça elde ettik. Yıldız içinden sonraki sayı değiştirgeye kaç bölme atanacağını belirler. Numarayı hiç yazmaya da bilirsin. Bu durumda değiştirge var olan bütün bölmelerle eşlenir. -Belirli bir istek için hangi işleç kullanılacağına karar vermek için hapi, en kesin olandan en az kesin olana doğru güzergahları arar. Örneğin `/dosyaadi.jpg` ve `/dosyaadi.{uzanti}` şeklinde iki güzergah tanımlarsanız; `/dosyaadi.jpg`ye yapılan bir istek ilk güzergahla eşleşecek, ikincisi ile eşleşmeyecektir. Bu aynı zamanda `/{dosyalar*}` şeklinde tanımlanmış bir güzergahın denenen *son* güzergah olacağı ve yalnızca diğer güzergahların eşleşme denemeleri sonuçsuz kaldığında eşleşeceği anlamına gelir. +Belirli bir istek için hangi işleç kullanılacağına karar vermek için hapi, en kesin olandan en az kesin olana doğru güzergahları arar. Örneğin `/dosyaadi.jpg` ve `/dosyaadi.{uzanti}` şeklinde iki güzergah tanımlarsanız; `/dosyaadi.jpg`ye yapılan bir istek ilk güzergahla eşleşecek, ikincisi ile eşleşmeyecektir. Bu aynı zamanda `/{dosyalar*}` şeklinde tanımlanmış bir güzergahın denenen _son_ güzergah olacağı ve yalnızca diğer güzergahların eşleşme denemeleri sonuçsuz kaldığında eşleşeceği anlamına gelir. ## Islec yöntem @@ -106,21 +105,18 @@ Burada dokümantasyon üretmek için tasarlanan bir kaç seçeneğe bakıyoruz: ```javascript server.route({ - method: 'GET', - path: '/selam/{user?}', - handler: function (request, h) { - - const user = request.params.user ? - encodeURIComponent(request.params.user) : - 'stranger'; - - return `Selam ${user}!`; - }, - options: { - description: 'Say Selam!', - notes: 'The user parameter defaults to \'stranger\' if unspecified', - tags: ['api', 'greeting'] - } + method: 'GET', + path: '/selam/{user?}', + handler: function (request, h) { + const user = request.params.user ? encodeURIComponent(request.params.user) : 'stranger'; + + return `Selam ${user}!`; + }, + options: { + description: 'Say Selam!', + notes: "The user parameter defaults to 'stranger' if unspecified", + tags: ['api', 'greeting'], + }, }); ``` diff --git a/static/lib/tutorials/tr_TR/servermethods.md b/docs/tutorials/tr_TR/server-methods.md similarity index 77% rename from static/lib/tutorials/tr_TR/servermethods.md rename to docs/tutorials/tr_TR/server-methods.md index 897d3cdc..0531ad8d 100644 --- a/static/lib/tutorials/tr_TR/servermethods.md +++ b/docs/tutorials/tr_TR/server-methods.md @@ -1,13 +1,18 @@ +--- +title: Server Methods +--- + + + ## Sunucu yöntemleri _Bu kurs hapi v17 ile uyumludur_ -Sunucu yöntemleri birden fazla yerde kullanılan modüllerin lazım olan her talep edilmesindense sunucu nesnene iliştirebildiğin kullanışlı bir yol sunar. Bir sunucu yöntemi kaydetmek için [`server.method()`](https://hapijs.com/api#server.method()) çağrısı yap. Bu yöntemi çağırmanın iki farklı yöntemi var. `server.method(name, method, [options])` imzasıyla çağırabilirsin. Örneğin: +Sunucu yöntemleri birden fazla yerde kullanılan modüllerin lazım olan her talep edilmesindense sunucu nesnene iliştirebildiğin kullanışlı bir yol sunar. Bir sunucu yöntemi kaydetmek için [`server.method()`]() çağrısı yap. Bu yöntemi çağırmanın iki farklı yöntemi var. `server.method(name, method, [options])` imzasıyla çağırabilirsin. Örneğin: ```javascript const add = function (x, y) { - - return x + y; + return x + y; }; server.method('add', add, {}); @@ -17,14 +22,13 @@ server.method('add', add, {}); ```javascript const add = function (x, y) { - - return x + y; + return x + y; }; server.method({ - name: 'add', - method: add, - options: {} + name: 'add', + method: add, + options: {}, }); ``` @@ -44,9 +48,8 @@ Bu sunucu yöntemi `server.methods.math.add()` ile çağrılır. ```js const add = async function (x, y) { - - const result = await someLongRunningFunction(x, y); - return result; + const result = await someLongRunningFunction(x, y); + return result; }; server.method('add', add, {}); @@ -60,25 +63,25 @@ Sunucu yöntemlerinin başlıca avantajlarından biri hapinin ana önbelleklemes ```javascript server.method('add', add, { - cache: { - expiresIn: 60000, - expiresAt: '20:30', - staleIn: 30000, - staleTimeout: 10000, - generateTimeout: 100 - } + cache: { + expiresIn: 60000, + expiresAt: '20:30', + staleIn: 30000, + staleTimeout: 10000, + generateTimeout: 100, + }, }); ``` değiştirgelerin anlamları: -* `expiresIn`: öğe son kez önbelleklendiği andan itibaren süresinin dolması için geçmesi gereken milisaniye cinsinden süre. `expiresAt` ile birlikte kullanılamaz. -* `expiresAt`: Yol (route) ile ilgili önbelleklerin süresinin dolması için 24 saatlik gösterimle 'HH:MM' formatında ifade edilen günün saati. Yerel zamanı kullanır. `expiresIn` ile birlikte kullanılamaz. -* `staleIn`: Önbellekteki bir öğenin bayat olarak işaretlenerek yeniden oluşturmaya kalkışmadan önce geçmesi gerek milisaniye cinsinden süre. En az `expiresIn` kadar olmalıdır. -* `staleTimeout`: Bayatlamış bir öğeyi dönmeden önce generateFunc oluşturma fonksiyonunun taze bir değer üretmesi için beklenilecek maksimum süre. -* `generateTimeout`: Bir değeri üretmek uzun sürdüğünde zaman aşımı hatası vermeden önce beklenecek milisaniye cinsinden süre. Değer gerçekten döndüğünde gelecek istekler için önbelleklenir. -* `segment`: Önbellek öğelerini ayrıştırmak (isolate) için kullanılan isteğe bağlı bölme adı -* `cache`: Sunucuda kullanılmak için yapılandırılmış bir önbellek bağlantı adını taşıyan isteğe bağlı bir metin +- `expiresIn`: öğe son kez önbelleklendiği andan itibaren süresinin dolması için geçmesi gereken milisaniye cinsinden süre. `expiresAt` ile birlikte kullanılamaz. +- `expiresAt`: Yol (route) ile ilgili önbelleklerin süresinin dolması için 24 saatlik gösterimle 'HH:MM' formatında ifade edilen günün saati. Yerel zamanı kullanır. `expiresIn` ile birlikte kullanılamaz. +- `staleIn`: Önbellekteki bir öğenin bayat olarak işaretlenerek yeniden oluşturmaya kalkışmadan önce geçmesi gerek milisaniye cinsinden süre. En az `expiresIn` kadar olmalıdır. +- `staleTimeout`: Bayatlamış bir öğeyi dönmeden önce generateFunc oluşturma fonksiyonunun taze bir değer üretmesi için beklenilecek maksimum süre. +- `generateTimeout`: Bir değeri üretmek uzun sürdüğünde zaman aşımı hatası vermeden önce beklenecek milisaniye cinsinden süre. Değer gerçekten döndüğünde gelecek istekler için önbelleklenir. +- `segment`: Önbellek öğelerini ayrıştırmak (isolate) için kullanılan isteğe bağlı bölme adı +- `cache`: Sunucuda kullanılmak için yapılandırılmış bir önbellek bağlantı adını taşıyan isteğe bağlı bir metin Önbellekleme hakkında daha fazla bilgi [catbox](https://github.com/hapijs/catbox#policy) dokümantasyonu ve [API referansında](/api#servermethodmethod) bulunabilir. @@ -86,19 +89,18 @@ Bir sunucu yönteminin her bir çağrı sonucunun `ttl` (time-to-live (yaşanaca ```js const add = async function (x, y, flags) { + const result = await someLongRunningFunction(x, y); - const result = await someLongRunningFunction(x, y); + flags.ttl = 5 * 60 * 1000; // 5 mins - flags.ttl = 5 * 60 * 1000; // 5 mins - - return result; + return result; }; server.method('add', add, { - cache: { - expiresIn: 2000, - generateTimeout: 100 - } + cache: { + expiresIn: 2000, + generateTimeout: 100, + }, }); server.methods.add(5, 12); @@ -112,19 +114,17 @@ Yukarıdaki seçeneklere ek olarak, yöntemine gönderilen değiştirgeleri kull ```javascript const sum = function (array) { + let total = 0; - let total = 0; - - array.forEach((item) => { + array.forEach((item) => { + total += item; + }); - total += item; - }); - - return total; + return total; }; server.method('sum', sum, { - generateKey: (array) => array.join(',') + generateKey: (array) => array.join(','), }); ``` @@ -136,10 +136,9 @@ Sunucu yöntemine gönderilen son isteğe bağlı yöntem `bind` (bağla)dır. ` ```javascript const lookup = async function (id) { + // myDB.getOne çağrısı yapar - // myDB.getOne çağrısı yapar - - return await this.getOne({ id }); + return await this.getOne({ id }); }; server.method('lookup', lookup, { bind: myDB }); diff --git a/static/lib/tutorials/tr_TR/servingfiles.md b/docs/tutorials/tr_TR/serving-files.md similarity index 68% rename from static/lib/tutorials/tr_TR/servingfiles.md rename to docs/tutorials/tr_TR/serving-files.md index df9775ef..ea4418a6 100644 --- a/static/lib/tutorials/tr_TR/servingfiles.md +++ b/docs/tutorials/tr_TR/serving-files.md @@ -1,3 +1,9 @@ +--- +title: Serving Files +--- + + + ## Durağan dosya sunumu _Bu kurs hapi v17 ile uyumludur_ @@ -14,21 +20,19 @@ Bir ağ uygulaması yazarken eninde sonunda diskten bir dosya sunmanın vakti ge ```javascript const start = async () => { + await server.register(require('@hapi/inert')); - await server.register(require('@hapi/inert')); - - server.route({ - method: 'GET', - path: '/picture.jpg', - handler: function (request, h) { - - return h.file('/path/to/picture.jpg'); - } - }); + server.route({ + method: 'GET', + path: '/picture.jpg', + handler: function (request, h) { + return h.file('/path/to/picture.jpg'); + }, + }); - await server.start(); + await server.start(); - console.log('Server running at:', server.info.uri); + console.log('Server running at:', server.info.uri); }; start(); @@ -47,29 +51,27 @@ const Hapi = require('@hapi/hapi'); const Path = require('path'); const server = Hapi.server({ - routes: { - files: { - relativeTo: Path.join(__dirname, 'public') - } - } + routes: { + files: { + relativeTo: Path.join(__dirname, 'public'), + }, + }, }); const start = async () => { + await server.register(require('@hapi/inert')); - await server.register(require('@hapi/inert')); - - server.route({ - method: 'GET', - path: '/picture.jpg', - handler: function (request, h) { - - return h.file('picture.jpg'); - } - }); + server.route({ + method: 'GET', + path: '/picture.jpg', + handler: function (request, h) { + return h.file('picture.jpg'); + }, + }); - await server.start(); + await server.start(); - console.log('Server running at:', server.info.uri); + console.log('Server running at:', server.info.uri); }; start(); @@ -83,11 +85,11 @@ start(); ```javascript server.route({ - method: 'GET', - path: '/picture.jpg', - handler: { - file: 'picture.jpg' - } + method: 'GET', + path: '/picture.jpg', + handler: { + file: 'picture.jpg', + }, }); ``` @@ -97,13 +99,13 @@ Değiştirgeyi `request` (istek) nesnesi kabul ederek dosyanın güzergahını ( ```javascript server.route({ - method: 'GET', - path: '/{filename}', - handler: { - file: function (request) { - return request.params.filename; - } - } + method: 'GET', + path: '/{filename}', + handler: { + file: function (request) { + return request.params.filename; + }, + }, }); ``` @@ -111,16 +113,16 @@ server.route({ ```javascript server.route({ - method: 'GET', - path: '/script.js', - handler: { - file: { - path: 'script.js', - filename: 'client.js', // Content-Disposition başlığındaki dosya adının üstüne yaz - mode: 'attachment', // Content-Dispositionın bir eklenti olduğunu belirt - lookupCompressed: true // eğer istek izin veriyorsa script.js.gz aramasını etkinleştir - } - } + method: 'GET', + path: '/script.js', + handler: { + file: { + path: 'script.js', + filename: 'client.js', // Content-Disposition başlığındaki dosya adının üstüne yaz + mode: 'attachment', // Content-Dispositionın bir eklenti olduğunu belirt + lookupCompressed: true, // eğer istek izin veriyorsa script.js.gz aramasını etkinleştir + }, + }, }); ``` @@ -130,13 +132,13 @@ inert, `file` (dosya) işleyicisine ek olarak birden fazla dosya sunacak şekild ```javascript server.route({ - method: 'GET', - path: '/{param*}', - handler: { - directory: { - path: 'public' - } - } + method: 'GET', + path: '/{param*}', + handler: { + directory: { + path: 'public', + }, + }, }); ``` @@ -146,14 +148,14 @@ Yukarıdaki yol (route) her isteği `public` dizininde istenen dosya adı eşle ```javascript server.route({ - method: 'GET', - path: '/{param*}', - handler: { - directory: { - path: 'public', - index: ['index.html', 'default.html'] - } - } + method: 'GET', + path: '/{param*}', + handler: { + directory: { + path: 'public', + index: ['index.html', 'default.html'], + }, + }, }); ``` @@ -161,14 +163,15 @@ server.route({ ```javascript server.route({ - method: 'GET', - path: '/{param*}', - handler: { - directory: { - path: 'public', - listing: true - } - } + method: 'GET', + path: '/{param*}', + handler: { + directory: { + path: 'public', + listing: true, + }, + }, }); ``` -Şimdi `/` güzergahına yapılan bir istek dizin içeriğini gösteren HTML ile yanıtlanacak. Dizin işleyiciyi listeleme açık olarak kullanırken varsayılan olarak gizli dosyalar listede gösterilmez. Bu `showHidden` seçeneğini `true` olarak ayarlanarak değiştirilebilir. Dosya işleyicide olduğu gibi, dizin işleyicinin de mümkün olduğunda önceden sıkıştırılmış dosyaları sunmak için `lookupCompressed` (sıkıştırılmışına bak) adlı bir seçeneği bulunur. Orjinal güzergah bulunamadığında isteklere eklenmek üzere `defaultExtension` (varsayılan uzantı) da ayarlayabilirsin. Bu demek oluyor ki `/havuc` için yapılan bir istekte aynı zamanda `/index.html` de denenecek. + +Şimdi `/` güzergahına yapılan bir istek dizin içeriğini gösteren HTML ile yanıtlanacak. Dizin işleyiciyi listeleme açık olarak kullanırken varsayılan olarak gizli dosyalar listede gösterilmez. Bu `showHidden` seçeneğini `true` olarak ayarlanarak değiştirilebilir. Dosya işleyicide olduğu gibi, dizin işleyicinin de mümkün olduğunda önceden sıkıştırılmış dosyaları sunmak için `lookupCompressed` (sıkıştırılmışına bak) adlı bir seçeneği bulunur. Orjinal güzergah bulunamadığında isteklere eklenmek üzere `defaultExtension` (varsayılan uzantı) da ayarlayabilirsin. Bu demek oluyor ki `/havuc` için yapılan bir istekte aynı zamanda `/index.html` de denenecek. diff --git a/static/lib/tutorials/pt_BR/testing.md b/docs/tutorials/tr_TR/testing.md similarity index 53% rename from static/lib/tutorials/pt_BR/testing.md rename to docs/tutorials/tr_TR/testing.md index e25dee5f..4cf0e0bd 100644 --- a/static/lib/tutorials/pt_BR/testing.md +++ b/docs/tutorials/tr_TR/testing.md @@ -1,5 +1,11 @@ +--- +title: Testing +--- + + + # Testing ## No Translation Yet -This tutorial has not been translated yet. If you would like to translate it, please submit a pull request. \ No newline at end of file +This tutorial has not been translated yet. If you would like to translate it, please submit a pull request. diff --git a/static/lib/tutorials/tr_TR/validation.md b/docs/tutorials/tr_TR/validation.md similarity index 82% rename from static/lib/tutorials/tr_TR/validation.md rename to docs/tutorials/tr_TR/validation.md index 9df63ffa..9353a288 100644 --- a/static/lib/tutorials/tr_TR/validation.md +++ b/docs/tutorials/tr_TR/validation.md @@ -1,3 +1,9 @@ +--- +title: Validation +--- + + + ## Doğrulama _Bu kurs hapi v17 ile uyumludur_ @@ -12,19 +18,18 @@ Haydi bir örneğe bakalım: ```javascript server.route({ - method: 'GET', - path: '/selam/{name}', - handler: function (request, h) { - - return `Selam ${request.params.name}!`; + method: 'GET', + path: '/selam/{name}', + handler: function (request, h) { + return `Selam ${request.params.name}!`; + }, + options: { + validate: { + params: { + name: Joi.string().min(3).max(10), + }, }, - options: { - validate: { - params: { - name: Joi.string().min(3).max(10) - } - } - } + }, }); ``` @@ -36,9 +41,9 @@ Eğer bu yapılandırma ile `/selam/aylin` adresine bir istekte bulunursak bekle ```json { - "error": "Bad Request", - "message": "Invalid request params input", - "statusCode": 400 + "error": "Bad Request", + "message": "Invalid request params input", + "statusCode": 400 } ``` @@ -46,25 +51,24 @@ Benzeri şekilde, eğer isteği `/selam/adimokadaruzunkianlatamam` adresine yapm ### Sorgu degistirgeleri -Sorgu değiştirgelerini doğrulamak için `validate.query` (sorguyu doğrula) seçeneğini gönderiyoruz ve benzeri sonuçlar elde ediyoruz. Varsayılan olarak hapi hiç bir şeyi doğrulamaz. Eğer değiştirgelerden biri için bile doğrulayıcı belirlersen bu demektir ki kabul etmek istediğin mümkün olan tüm sorgu değiştirgileri için doğrulayıcı sağlamak *zorundasın*. +Sorgu değiştirgelerini doğrulamak için `validate.query` (sorguyu doğrula) seçeneğini gönderiyoruz ve benzeri sonuçlar elde ediyoruz. Varsayılan olarak hapi hiç bir şeyi doğrulamaz. Eğer değiştirgelerden biri için bile doğrulayıcı belirlersen bu demektir ki kabul etmek istediğin mümkün olan tüm sorgu değiştirgileri için doğrulayıcı sağlamak _zorundasın_. Örneğin, eğer kullanıcı blog yazılarının listesini dönen bir güzergahın varsa ve kullanıcıların sonuç kümesine sayı sınırı uygulamasını istiyorsan aşağıdaki yapılandırmayı kullanabilirsin: ```javascript server.route({ - method: 'GET', - path: '/posts', - handler: function (request, h) { - - return posts.slice(0, request.query.limit); + method: 'GET', + path: '/posts', + handler: function (request, h) { + return posts.slice(0, request.query.limit); + }, + options: { + validate: { + query: { + limit: Joi.number().integer().min(1).max(100).default(10), + }, }, - options: { - validate: { - query: { - limit: Joi.number().integer().min(1).max(100).default(10) - } - } - } + }, }); ``` @@ -93,16 +97,16 @@ Buna ek olarak, [hapi-swagger](https://github.com/glennjones/hapi-swagger) ve [l hapi çıktı doğrulamasına ince ayar yapmak için bir çok seçenek sunar. İşte bir kaçı: - -___ +--- ### response.failAction `response.failAction`ı aşağıdakilerden birine ayarlayarak yanıt doğrulama başarısız olduğunda ne olacağına karar verebilirsin: -* `error`: bir İç Sunucu Hatası (500) gönder (varsayılan) -* `log`: Sıkıntıyı günlükle ve yanıtı olduğu gibi gönder -* `ignore`: görmezden gel ve isteği işlemeye devam et -* İmzası `async function(request, h, err)` olan bir yaşam göngüsü yöntemi. İmzada bulunan değiştirgelerden `request` istek nesnesi, `h` yanıt alet takımı ve `err` doğrulama hatası olarak gelir + +- `error`: bir İç Sunucu Hatası (500) gönder (varsayılan) +- `log`: Sıkıntıyı günlükle ve yanıtı olduğu gibi gönder +- `ignore`: görmezden gel ve isteği işlemeye devam et +- İmzası `async function(request, h, err)` olan bir yaşam göngüsü yöntemi. İmzada bulunan değiştirgelerden `request` istek nesnesi, `h` yanıt alet takımı ve `err` doğrulama hatası olarak gelir ### response.sample @@ -112,8 +116,9 @@ Eğer performans kaygın varsa, hapi yanıtların yalnızca bir kısmını doğr Bazen bir uç noktada (endpoint) birden fazla yanıt nesnesi sunulur. Örneğin bir `POST` yolu (route) aşağıdakilerden birini dönebilir: -* `201` durum kodu ile birlikte yeni yaratılan kaynak -* `202` durum kodu ile birlikte güncellenen kaynağın eski ve yeni değerleri + +- `201` durum kodu ile birlikte yeni yaratılan kaynak +- `202` durum kodu ile birlikte güncellenen kaynağın eski ve yeni değerleri hapi bunun üstesinden her yanıt durum kodu (response status code) için farklı bir doğrulama şeması vermeni sağlayarak gelir. `response.status` anahtarları sayısal durum kodları olan bir nesnedir ve özellikleri joi şemalarıdır. @@ -130,6 +135,7 @@ hapi bunun üstesinden her yanıt durum kodu (response status code) için farkl ``` ### response.options + joiye doğrulama sırasında gönderilecek seçenekler. Detaylı bilgi için [API dokümantasyonu](/api#-routeoptionsresponseoptions)na bak. ### Örnek @@ -138,33 +144,31 @@ Burada örnek olarak kitap listesi dönen bir yol (route) yapılandırması var: ```javascript const bookSchema = Joi.object({ - title: Joi.string().required(), - author: Joi.string().required(), - isbn: Joi.string().length(10), - pageCount: Joi.number(), - datePublished: Joi.date().iso() + title: Joi.string().required(), + author: Joi.string().required(), + isbn: Joi.string().length(10), + pageCount: Joi.number(), + datePublished: Joi.date().iso(), }); server.route({ - method: 'GET', - path: '/books', - handler: async function (request, h) { - - return await getBooks(); + method: 'GET', + path: '/books', + handler: async function (request, h) { + return await getBooks(); + }, + options: { + response: { + sample: 50, + schema: Joi.array().items(bookSchema), }, - options: { - response: { - sample: 50, - schema: Joi.array().items(bookSchema) - } - } + }, }); - ``` Yanıtların yarısını (`sample: 50`) doğrulayacak. `response.failAction` vermediğimizden, eğer kitaplardan biri `bookSchema`ya (kitap şeması) uymazsa hapi `500` hata kodu verir. -Hata yanıtı hatanın sebebini *göstermez*. +Hata yanıtı hatanın sebebini _göstermez_. Eğer günlükleme yapılandırdıysan, yanıt doğrulamanın hata vermesine neyin sebep oılduğunu inceleyebilirsin. Eğer `response.failAction` `log` olarak ayarlansaydı, hapi orjinal yanıtla cevap verirken doğrulama hatasını da günlükleyebilirdi. diff --git a/static/lib/tutorials/tr_TR/views.md b/docs/tutorials/tr_TR/views.md similarity index 83% rename from static/lib/tutorials/tr_TR/views.md rename to docs/tutorials/tr_TR/views.md index 5fd35154..d537649a 100644 --- a/static/lib/tutorials/tr_TR/views.md +++ b/docs/tutorials/tr_TR/views.md @@ -1,3 +1,9 @@ +--- +title: Views +--- + + + ## Views _Bu kurs hapi v17 ile uyumludur_ @@ -18,16 +24,15 @@ const Hoek = require('@hapi/hoek'); const server = Hapi.server(); const start = async () => { + await server.register(require('@hapi/vision')); - await server.register(require('@hapi/vision')); - - server.views({ - engines: { - html: require('handlebars') - }, - relativeTo: __dirname, - path: 'templates' - }); + server.views({ + engines: { + html: require('handlebars'), + }, + relativeTo: __dirname, + path: 'templates', + }); }; start(); @@ -47,13 +52,13 @@ Unutmayın ki tüm seçenekler kayıtlı tüm motorları yapılandıracak şekil ```javascript server.views({ - engines: { - html: { - module: require('handlebars'), - compileMode: 'sync' // motora özel - } + engines: { + html: { + module: require('handlebars'), + compileMode: 'sync', // motora özel }, - compileMode: 'async' // evrensel ayar + }, + compileMode: 'async', // evrensel ayar }); ``` @@ -103,13 +108,13 @@ Ayarların şöyle olabilir: ```javascript server.views({ - engines: { - html: require('handlebars') - }, - relativeTo: __dirname, - path: './templates', - layoutPath: './templates/layout', - helpersPath: './templates/helpers' + engines: { + html: require('handlebars'), + }, + relativeTo: __dirname, + path: './templates', + layoutPath: './templates/layout', + helpersPath: './templates/helpers', }); ``` @@ -123,12 +128,11 @@ Bakacağımız ilk kullanıcı arayüzü yorumlayan yöntem `h.view()`. Hemen a ```javascript server.route({ - method: 'GET', - path: '/', - handler: function (request, h) { - - return h.view('index'); - } + method: 'GET', + path: '/', + handler: function (request, h) { + return h.view('index'); + }, }); ``` @@ -144,11 +148,11 @@ Kullanıcı arayüzü işlemenin ikinci yöntemi, hapi'nin hazır gelen kullanı ```javascript server.route({ - method: 'GET', - path: '/', - handler: { - view: 'index' - } + method: 'GET', + path: '/', + handler: { + view: 'index', + }, }); ``` @@ -167,23 +171,23 @@ handler: { ### Evrensel kapsam -Bir kapsamı nasıl direkt kullanıcı arayüzüne göndereceğimize baktık ancak; ya tüm şablonlarda *her zaman* elimizin altında olmasını istediğimiz varsayılan bir kapsam varsa? +Bir kapsamı nasıl direkt kullanıcı arayüzüne göndereceğimize baktık ancak; ya tüm şablonlarda _her zaman_ elimizin altında olmasını istediğimiz varsayılan bir kapsam varsa? Bunu yapmanın en kolay yolu `server.views()` yöntemini çağırırken `context` (kapsam) seçeneğini kullanmaktır. ```javascript const context = { - title: 'Benim sitem' + title: 'Benim sitem', }; server.views({ - engines: { - html: { - module: require('handlebars'), - compileMode: 'sync' // motora özgü - } + engines: { + html: { + module: require('handlebars'), + compileMode: 'sync', // motora özgü }, - context + }, + context, }); ``` @@ -197,22 +201,21 @@ Aşağıdaki kod bloğu `fortune.js` içerisinde `helpers` dizininde saklayacağ ```javascript module.exports = function () { - - const fortune = [ - 'Tolga burada uyumuş olabilir...', - 'Ördek lazım mı?', - 'Önce hayır de, sonra pazarlık yap.', - 'Sona kalan dona kalır.', - 'Öğretmek öğrenmektir.', - 'Elinde çekiç olan her şeyi çivi sanır', - 'Beni tanıdığın için kendini affedeceksin', - 'Eller günahkar diller günahkar.', - 'Talih şanslıdan yanadır.', - 'İyi günler!' - ]; - - const x = Math.floor(Math.random() * fortune.length); - return fortune[x]; + const fortune = [ + 'Tolga burada uyumuş olabilir...', + 'Ördek lazım mı?', + 'Önce hayır de, sonra pazarlık yap.', + 'Sona kalan dona kalır.', + 'Öğretmek öğrenmektir.', + 'Elinde çekiç olan her şeyi çivi sanır', + 'Beni tanıdığın için kendini affedeceksin', + 'Eller günahkar diller günahkar.', + 'Talih şanslıdan yanadır.', + 'İyi günler!', + ]; + + const x = Math.floor(Math.random() * fortune.length); + return fortune[x]; }; ``` @@ -220,7 +223,7 @@ Artık kullanıcı arayüzü yardımcımızı şablonumuzda kullanabiliriz. Aşa ```html

    Kısmetin

    -

    {{fortune}}

    +

    {{fortune}}

    ``` Artık sunucumuzu çalıştırdığımızda ve tarayıcımızı şablonu kullanan bir yola (route) yönlendirğimizde (kullanıcı arayüzü yardımcımızı kullanan), başlığın hemen altında rasgele çekilmiş bir kısmet paragrafı görmeliyiz. @@ -235,26 +238,24 @@ const Hapi = require('@hapi/hapi'); const server = Hapi.server({ port: 8080 }); const start = async () => { + await server.register(require('@hapi/vision')); - await server.register(require('@hapi/vision')); - - server.views({ - engines: { - html: require('handlebars') - }, - relativeTo: __dirname, - path: 'templates', - helpersPath: 'helpers' - }); - - server.route({ - method: 'GET', - path: '/', - handler: function (request, h) { + server.views({ + engines: { + html: require('handlebars'), + }, + relativeTo: __dirname, + path: 'templates', + helpersPath: 'helpers', + }); - return h.view('index'); - } - }); + server.route({ + method: 'GET', + path: '/', + handler: function (request, h) { + return h.view('index'); + }, + }); }; start(); @@ -268,9 +269,9 @@ Yerleşik olarak gelen sayfa düzeni sistemini kullanmak için önce kullanıcı ```javascript server.views({ - // ... - layout: true, - layoutPath: 'templates/layout' + // ... + layout: true, + layoutPath: 'templates/layout', }); ``` @@ -281,8 +282,8 @@ Bu, yerleşik sayfa düzenlerini aktifleştiri ve varsayılan sayfa düzeni olar ```html - {{{content}}} - + {{{content}}} + ``` @@ -292,14 +293,14 @@ Ve kullanıcı arayüzüne yalnızca içeriği koy:
    Content
    ``` -Kullanıcı arayüzünü yorumlarken, `{{{content}}}` ile kullanıcı arayüzünün içeriği değiştirilecek. +Kullanıcı arayüzünü yorumlarken, `{{{content}}}` ile kullanıcı arayüzünün içeriği değiştirilecek. Varsayılan bir sayfa düzeni ayarlamak istersen bunu evrensel olarak yapabilirsin: ```javascript server.views({ - // ... - layout: 'another_default' + // ... + layout: 'another_default', }); ``` diff --git a/static/lib/tutorials/zh_CN/auth.md b/docs/tutorials/zh_CN/auth.md similarity index 85% rename from static/lib/tutorials/zh_CN/auth.md rename to docs/tutorials/zh_CN/auth.md index f0828790..844d53f6 100644 --- a/static/lib/tutorials/zh_CN/auth.md +++ b/docs/tutorials/zh_CN/auth.md @@ -1,3 +1,9 @@ +--- +title: Authentication +--- + + + ## 身份认证 _该教程适用于 hapi v17版本_ @@ -15,50 +21,47 @@ const Bcrypt = require('bcrypt'); const Hapi = require('@hapi/hapi'); const users = { - john: { - username: 'john', - password: '$2a$10$iqJSHD.BGr0E2IxQwYgJmeP3NvhPrXAeLSaGCj6IR/XU5QtjVu5Tm', // '密码: secret' - name: 'John Doe', - id: '2133d32a' - } + john: { + username: 'john', + password: '$2a$10$iqJSHD.BGr0E2IxQwYgJmeP3NvhPrXAeLSaGCj6IR/XU5QtjVu5Tm', // '密码: secret' + name: 'John Doe', + id: '2133d32a', + }, }; const validate = async (request, username, password) => { + const user = users[username]; + if (!user) { + return { credentials: null, isValid: false }; + } - const user = users[username]; - if (!user) { - return { credentials: null, isValid: false }; - } - - const isValid = await Bcrypt.compare(password, user.password); - const credentials = { id: user.id, name: user.name }; + const isValid = await Bcrypt.compare(password, user.password); + const credentials = { id: user.id, name: user.name }; - return { isValid, credentials }; + return { isValid, credentials }; }; const start = async () => { + const server = Hapi.server({ port: 4000 }); - const server = Hapi.server({ port: 4000 }); - - await server.register(require('hapi-auth-basic')); - - server.auth.strategy('simple', 'basic', { validate }); + await server.register(require('hapi-auth-basic')); - server.route({ - method: 'GET', - path: '/', - options: { - auth: 'simple' - }, - handler: function (request, h) { + server.auth.strategy('simple', 'basic', { validate }); - return 'welcome'; - } - }); + server.route({ + method: 'GET', + path: '/', + options: { + auth: 'simple', + }, + handler: function (request, h) { + return 'welcome'; + }, + }); - await server.start(); + await server.start(); - console.log('server running at: ' + server.info.uri); + console.log('server running at: ' + server.info.uri); }; start(); @@ -75,11 +78,11 @@ start(); `scheme` 是一个拥有签名 `function (server, options)` 的方法。 `server` 参数是需要添加这个 scheme 的服务器对象的引用,`options` 参数是使用它注册 strategy 时的配置。 -这个方法返回的对象 *至少* 包含了 `authenticate` 方法。而其他可用的非必须返回的方法是 `payload` 和 `response`。 +这个方法返回的对象 _至少_ 包含了 `authenticate` 方法。而其他可用的非必须返回的方法是 `payload` 和 `response`。 ### `authenticate` -`authenticate` 方法的签名为 `function (request, h)`, 也是 scheme 中唯一 *必须* 有的方法。 +`authenticate` 方法的签名为 `function (request, h)`, 也是 scheme 中唯一 _必须_ 有的方法。 在这里 `request` 为服务器创建的 `request` 对象。 这个对象与路由 handler 中的对象为同一个, 完整的文档可以参阅 [API reference](/api#request-object)。 @@ -143,12 +146,12 @@ start(); 如果 `mode` 设置为 `'required'` ,在访问路由的时候必须对用户进行身份进行验证,并且验证必须有效,否则他们将收到错误。 -如果 `mode` 设置为 `'optional'` , 路由也将会使用这个 strategy 。但是用户 *不必* 进行身份验证。一旦如果验证信息提供了,那就必须是有效的。 +如果 `mode` 设置为 `'optional'` , 路由也将会使用这个 strategy 。但是用户 _不必_ 进行身份验证。一旦如果验证信息提供了,那就必须是有效的。 最后 `mode` 可以被设置为 `'try'`。 `'try'` 与 `'optional'` 的区别在于:如果用 `'try'` ,不合法的身份验证是被接受的, 用户依然可以访问路由 handler。 当只需一个 strategy 时,你可以设置 `strategy` 属性为 strategy 的名字。如果指定多个 strategy 时, 参数名称必须为 `strategies`, 属性为 strategy 名称的数组。 这些 strategies 将会按照顺序执行一直到有第一个成功的, 否则的话将全部失败。 -最后 `payload` 参数可以被设置为 `false` 表示内容信息不需要被认证。如果设置为 `'required'` 或者 `true` 则意味着内容 *必须* 被验证。 如果设置为 `'optional'` 意味着如果客户端一旦包含了内容认证的信息,这些信息就必须是有效的。 +最后 `payload` 参数可以被设置为 `false` 表示内容信息不需要被认证。如果设置为 `'required'` 或者 `true` 则意味着内容 _必须_ 被验证。 如果设置为 `'optional'` 意味着如果客户端一旦包含了内容认证的信息,这些信息就必须是有效的。 `payload` 只有在支持`payload` 方法的 strategy 中才会生效。 diff --git a/static/lib/tutorials/zh_CN/caching.md b/docs/tutorials/zh_CN/caching.md similarity index 71% rename from static/lib/tutorials/zh_CN/caching.md rename to docs/tutorials/zh_CN/caching.md index 5289fae3..4d51154c 100644 --- a/static/lib/tutorials/zh_CN/caching.md +++ b/docs/tutorials/zh_CN/caching.md @@ -1,3 +1,9 @@ +--- +title: Caching +--- + + + ## 缓存 _该教程适用于 hapi v17版本_ @@ -16,24 +22,23 @@ HTTP 协议定义了许多 HTTP 头部(headers)信息,方便如浏览器 ```javascript server.route({ - path: '/hapi/{ttl?}', - method: 'GET', - handler: function (request, h) { - - const response = h.response({ be: 'hapi' }); + path: '/hapi/{ttl?}', + method: 'GET', + handler: function (request, h) { + const response = h.response({ be: 'hapi' }); - if (request.params.ttl) { - response.ttl(request.params.ttl); - } + if (request.params.ttl) { + response.ttl(request.params.ttl); + } - return response; + return response; + }, + options: { + cache: { + expiresIn: 30 * 1000, + privacy: 'private', }, - options: { - cache: { - expiresIn: 30 * 1000, - privacy: 'private' - } - } + }, }); ``` @@ -53,9 +58,9 @@ server.route({ 假设 `lastModified` 是一个 `Date` 对象,你可以通过 [response 对象](/api#response-object) 设置这个头部信息。 ```javascript -return h.response(result) - .header('Last-Modified', lastModified.toUTCString()); +return h.response(result).header('Last-Modified', lastModified.toUTCString()); ``` + 这个示例展示了使用 `Last-Modified` 在本教程的 [最后一节](#客户端和服务器端缓存) 中。 #### ETag @@ -88,21 +93,21 @@ hapi 通过 [catbox memory](https://github.com/hapijs/catbox-memory) 适配器 const Hapi = require('@hapi/hapi'); const server = Hapi.server({ - port: 8000, - cache: [ - { - name: 'mongoCache', - engine: require('catbox-mongodb'), - host: '127.0.0.1', - partition: 'cache' - }, - { - name: 'redisCache', - engine: require('catbox-redis'), - host: '127.0.0.1', - partition: 'cache' - } - ] + port: 8000, + cache: [ + { + name: 'mongoCache', + engine: require('catbox-mongodb'), + host: '127.0.0.1', + partition: 'cache', + }, + { + name: 'redisCache', + engine: require('catbox-redis'), + host: '127.0.0.1', + partition: 'cache', + }, + ], }); ``` @@ -114,44 +119,41 @@ const server = Hapi.server({ ```javascript const start = async () => { + const add = async (a, b) => { + await Hoek.wait(1000); // 模拟一些慢的 I/O 操作 + + return Number(a) + Number(b); + }; + + const sumCache = server.cache({ + cache: 'mongoCache', + expiresIn: 10 * 1000, + segment: 'customSegment', + generateFunc: async (id) => { + return await add(id.a, id.b); + }, + generateTimeout: 2000, + }); - const add = async (a, b) => { - - await Hoek.wait(1000); // 模拟一些慢的 I/O 操作 - - return Number(a) + Number(b); - }; - - const sumCache = server.cache({ - cache: 'mongoCache', - expiresIn: 10 * 1000, - segment: 'customSegment', - generateFunc: async (id) => { - - return await add(id.a, id.b); - }, - generateTimeout: 2000 - }); - - server.route({ - path: '/add/{a}/{b}', - method: 'GET', - handler: async function (request, h) { - - const { a, b } = request.params; - const id = `${a}:${b}`; + server.route({ + path: '/add/{a}/{b}', + method: 'GET', + handler: async function (request, h) { + const { a, b } = request.params; + const id = `${a}:${b}`; - return await sumCache.get({ id, a, b }); - } - }); + return await sumCache.get({ id, a, b }); + }, + }); - await server.start(); + await server.start(); - console.log('Server running at:', server.info.uri); + console.log('Server running at:', server.info.uri); }; start(); ``` + 如果发送一个请求到 http://localhost:8000/add/1/5, 你将在一秒后得到一个响应 `6`。 如果你再次请求的时候,因为被缓存了,将会立刻得到结果。如果你等待10秒后再次请求, 你会发现它需要等待一段时间,因为缓存的值现在已从缓存中移除了。 `cache` 选项告诉 hapi 哪个 [client](https://github.com/hapijs/catbox#client) 该被使用。 @@ -168,78 +170,74 @@ start(); ```javascript const start = async () => { + // ... - // ... - - server.method('sum', add, { - cache: { - cache: 'mongoCache', - expiresIn: 10 * 1000, - generateTimeout: 2000 - } - }); - - server.route({ - path: '/add/{a}/{b}', - method: 'GET', - handler: async function (request, h) { + server.method('sum', add, { + cache: { + cache: 'mongoCache', + expiresIn: 10 * 1000, + generateTimeout: 2000, + }, + }); - const { a, b } = request.params; - return await server.methods.sum(a, b); - } - }); + server.route({ + path: '/add/{a}/{b}', + method: 'GET', + handler: async function (request, h) { + const { a, b } = request.params; + return await server.methods.sum(a, b); + }, + }); - await server.start(); + await server.start(); - // ... + // ... }; start(); ``` -[server.method()](/api#-servermethodname-method-options) 创建一个新的包含 `segment: '#sum'` 的 [policy](https://github.com/hapijs/catbox#policy),以及通过参数自动生成的唯一的 `id` (缓存的键)。 默认来说它只处理 `string`, `number` 以及 `boolean` 参数。对于更复杂的参数,需要提供 `generateKey` 函数去创建一个基于参数的唯一id。 - 请参阅教程的这部分内容 [服务器方法](/tutorials/servermethods) 。 + +[server.method()](/api#-servermethodname-method-options) 创建一个新的包含 `segment: '#sum'` 的 [policy](https://github.com/hapijs/catbox#policy),以及通过参数自动生成的唯一的 `id` (缓存的键)。 默认来说它只处理 `string`, `number` 以及 `boolean` 参数。对于更复杂的参数,需要提供 `generateKey` 函数去创建一个基于参数的唯一id。 - 请参阅教程的这部分内容 [服务器方法](/tutorials/servermethods) 。 #### 接下来呢? -* 更深入的了解 catbox policy [options](https://github.com/hapijs/catbox#policy) ,了解更多关于 `staleIn`, `staleTimeout`, `generateTimeout`的信息, 以充分利用 catbox 缓存的潜力。 -* 阅读服务器方法的教程 [服务器方法](http://hapijs.com/tutorials/servermethods) 了解更多示例。 +- 更深入的了解 catbox policy [options](https://github.com/hapijs/catbox#policy) ,了解更多关于 `staleIn`, `staleTimeout`, `generateTimeout`的信息, 以充分利用 catbox 缓存的潜力。 +- 阅读服务器方法的教程 [服务器方法](http://hapijs.com/tutorials/servermethods) 了解更多示例。 ### 客户端和服务器端缓存 -通常作为可选项,[Catbox Policy](https://github.com/hapijs/catbox#policy) 可以提供从缓存中检索的值的更多信息。若要开启此选项,需要在创建 policy 时将 `getDecoratedValue` 的值设置为 true 。这样,从服务器方法返回的任何值都将是一个对象 `{ value, cached, report }`。 `value` 只是缓存中的项目, `cached` 和 `report` 提供了有关项目缓存状态的一些额外细节。 +通常作为可选项,[Catbox Policy](https://github.com/hapijs/catbox#policy) 可以提供从缓存中检索的值的更多信息。若要开启此选项,需要在创建 policy 时将 `getDecoratedValue` 的值设置为 true 。这样,从服务器方法返回的任何值都将是一个对象 `{ value, cached, report }`。 `value` 只是缓存中的项目, `cached` 和 `report` 提供了有关项目缓存状态的一些额外细节。 服务器端和客户端缓存协同工作的一个例子是使用 `cached.stored` 时间戳设置 `last-modified` 头信息来实现的: ```javascript const start = async () => { + //... + + server.method('sum', add, { + cache: { + cache: 'mongoCache', + expiresIn: 10 * 1000, + generateTimeout: 2000, + getDecoratedValue: true, + }, + }); - //... - - server.method('sum', add, { - cache: { - cache: 'mongoCache', - expiresIn: 10 * 1000, - generateTimeout: 2000, - getDecoratedValue: true - } - }); - - server.route({ - path: '/add/{a}/{b}', - method: 'GET', - handler: async function (request, h) { - - const { a, b } = request.params; - const { value, cached } = await server.methods.sum(a, b); - const lastModified = cached ? new Date(cached.stored) : new Date(); + server.route({ + path: '/add/{a}/{b}', + method: 'GET', + handler: async function (request, h) { + const { a, b } = request.params; + const { value, cached } = await server.methods.sum(a, b); + const lastModified = cached ? new Date(cached.stored) : new Date(); - return h.response(value) - .header('Last-modified', lastModified.toUTCString()); - } - }); + return h.response(value).header('Last-modified', lastModified.toUTCString()); + }, + }); - await server.start(); + await server.start(); - // ... + // ... }; ``` diff --git a/static/lib/tutorials/pt_BR/community.md b/docs/tutorials/zh_CN/community.md similarity index 76% rename from static/lib/tutorials/pt_BR/community.md rename to docs/tutorials/zh_CN/community.md index a651208c..b8eec564 100644 --- a/static/lib/tutorials/pt_BR/community.md +++ b/docs/tutorials/zh_CN/community.md @@ -1,3 +1,9 @@ +--- +title: Community +--- + + + # Community Tutorials ## No tutorials yet diff --git a/static/lib/tutorials/zh_CN/cookies.md b/docs/tutorials/zh_CN/cookies.md similarity index 88% rename from static/lib/tutorials/zh_CN/cookies.md rename to docs/tutorials/zh_CN/cookies.md index 9d03022f..751002e5 100644 --- a/static/lib/tutorials/zh_CN/cookies.md +++ b/docs/tutorials/zh_CN/cookies.md @@ -1,3 +1,9 @@ +--- +title: Cookies +--- + + + ## Cookies _该教程适用于 hapi v17版本_ @@ -12,12 +18,12 @@ hapi 有许多配置选项用于处理 cookies。默认的配置已经可以适 ```javascript server.state('data', { - ttl: null, - isSecure: true, - isHttpOnly: true, - encoding: 'base64json', - clearInvalid: false, // remove invalid cookies - strictHeader: true // don't allow violations of RFC 6265 + ttl: null, + isSecure: true, + isHttpOnly: true, + encoding: 'base64json', + clearInvalid: false, // remove invalid cookies + strictHeader: true, // don't allow violations of RFC 6265 }); ``` @@ -27,12 +33,12 @@ server.state('data', { ```json5 { - config: { - state: { - parse: true, // 解析 cookies 并储存在 request.state - failAction: 'error' // 也可以为 'ignore' 或者 'log' - } - } + config: { + state: { + parse: true, // 解析 cookies 并储存在 request.state + failAction: 'error', // 也可以为 'ignore' 或者 'log' + }, + }, } ``` @@ -77,9 +83,9 @@ const value = request.state.data; 示例代码使用了 `data` cookie 键,而相关的值被设定为了 `{ firstVisit: false }`. ## 清理一个 cookie + cookie 可以通过调用 `unstate()` 来清理,这个方法在[response toolkit](/api#response-toolkit) 或者[response object](/api#response-object) 中: ```javascript return h.response('Bye').unstate('data'); ``` - diff --git a/static/lib/tutorials/zh_CN/expresstohapi.md b/docs/tutorials/zh_CN/express-to-hapi.md similarity index 77% rename from static/lib/tutorials/zh_CN/expresstohapi.md rename to docs/tutorials/zh_CN/express-to-hapi.md index 630d4c05..732d8eec 100644 --- a/static/lib/tutorials/zh_CN/expresstohapi.md +++ b/docs/tutorials/zh_CN/express-to-hapi.md @@ -1,8 +1,13 @@ +--- +title: Express to hapi +--- + + + # Express 迁移 _当前文献适用于 hapi v17 或者更新的版本_ - ## 总揽 这个Express 到 hapi的指南将向您展示如何使用Express中的知识,以及如何在hapi中做到这一点。 Express的大部分功能都严重依赖中间件,而hapi则更多地内置于核心中。 正文解析 (Body Parsing),cookie的处理,输入/输出验证以及HTTP友好错误处理对象已内置在hapi的框架中。 为了获得更多功能,hapi在其核心生态系统中提供了丰富的插件选择。 hapi也是唯一一个不依赖外部依赖项的框架。每个依赖项均由核心hapi团队进行管理,这使安全性和可靠性成为了hapi的最大优势。 @@ -14,14 +19,13 @@ _当前文献适用于 hapi v17 或者更新的版本_ Express: `npm install express` - hapi: `npm install @hapi/hapi` - ### 创建一个 `Server` Express: + ```js var express = require('express'); var app = express(); @@ -32,22 +36,23 @@ app.listen(3000, function () { ``` hapi: + ```js const Hapi = require('@hapi/hapi'); const init = async () => { + const server = Hapi.server({ + port: 3000, + host: 'localhost', + }); - const server = Hapi.server({ - port: 3000, - host: 'localhost' - }); - - await server.start(); - console.log('Server running on port 3000'); + await server.start(); + console.log('Server running on port 3000'); }; init(); ``` + 与Express不同,在hapi中,您创建了一个服务器对象,它将成为您应用程序的焦点。 服务器对象中设置的属性将确定您的应用程序的行为。 创建服务器对象后,您可以通过调用以下命令启动服务器。 ## 路由 `Routes` @@ -57,23 +62,25 @@ hapi中的路由以特定顺序被调用,因此,两条路由之间相互冲 让我们来看一下如何在hapi中设置一个基本的路由: Express: + ```js -app.get('/hello', function (req, res) { +app.get('/hello', function (req, res) { res.send('Hello World!'); }); ``` hapi: + ```js server.route({ - method: 'GET', - path:'/hello', - handler: (request, h) => { - - return 'Hello World!'; - } + method: 'GET', + path: '/hello', + handler: (request, h) => { + return 'Hello World!'; + }, }); ``` + 要创建路由,Express的结构为`app.METHOD(PATH, HANDLER)`,而hapi的结构为`server.route({METHOD, PATH, HANDLER})`。该方法,路径和处理程序作为对象传递给hapi服务器。 如您所见,要在Express中返回字符串,需要调用`res.send()`,而在hapi中,您只需简单的返回字符串。 ### 方法 @@ -82,14 +89,14 @@ server.route({ ```js server.route({ - method: ['PUT', 'POST'], - path: '/', - handler: function (request, h) { - - return 'I did something!'; - } + method: ['PUT', 'POST'], + path: '/', + handler: function (request, h) { + return 'I did something!'; + }, }); ``` + 如需使用所有可用的方法,像Express使用 `app.all()` 一样,使用 `method: '*'`。 ### 路径 @@ -103,24 +110,24 @@ server.route({ 在hapi中访问参数与Express非常相似。 如您所知,在Express中,参数填充在 `req.params` 对象中。 在hapi中,可通过 `request.params` 对象获得参数。 这是两个示例: Express: + ```js app.get('/hello/:name', function (req, res) { - - const name = req.params.name - res.send('Hello ' + name); -}); + const name = req.params.name; + res.send('Hello ' + name); +}); ``` hapi: + ```js server.route({ - method: 'GET', - path: '/hello/{name}', - handler: function (request, h) { - - const name = request.params.name; - return 'Hello ' + name - } + method: 'GET', + path: '/hello/{name}', + handler: function (request, h) { + const name = request.params.name; + return 'Hello ' + name; + }, }); ``` @@ -133,22 +140,22 @@ Express和hapi构造其路由处理程序的方式有所不同。 与Express的 这里是一个关于使用Express和hapi的路由和handler用来重定向到一个新的路由的用例: Express: + ```js app.get('/home', function (req, res) { - - res.redirect('/'); + res.redirect('/'); }); ``` hapi: + ```js server.route({ - method: 'GET', - path: '/home', - handler: function (request, h) { - - return h.redirect('/'); - } + method: 'GET', + path: '/home', + handler: function (request, h) { + return h.redirect('/'); + }, }); ``` @@ -156,21 +163,21 @@ server.route({ ```js server.route({ - method: 'GET', - path: '/user', - handler: function (request, h) { - - const user = { - firstName: 'John', - lastName: 'Doe', - userName: 'JohnDoe', - id: 123 - } + method: 'GET', + path: '/user', + handler: function (request, h) { + const user = { + firstName: 'John', + lastName: 'Doe', + userName: 'JohnDoe', + id: 123, + }; - return user; - } + return user; + }, }); ``` + hapi具有默认情况下响应JSON数据的功能。唯一要做的就是返回一个有效的JavaScript对象,而hapi将为您处理其余的工作。 ## 中间件 vs 插件和扩展 `Middleware vs Plugins and Extensions` @@ -187,9 +194,8 @@ hapi在请求周期内一共具有7个扩展点。 按顺序,它们分别都 ```js server.ext('onRequest', function (request, h) { - - request.setUrl('/test'); - return h.continue; + request.setUrl('/test'); + return h.continue; }); ``` @@ -200,36 +206,35 @@ server.ext('onRequest', function (request, h) { 如您所知,您可以在Express中编写自己的中间件。 hapi插件也是如此。 插件是具有必需的 `name` 和 `register` 属性的对象。`register` 属性是一个带有 `async function (server, option)` 签名的功能。 让我们看一下如何创建一个基本的插件: Express: + ```js const getDate = function (req, res, next) { + req.getDate = function () { + const date = new Date(); + return date; + }; - req.getDate = function() { - - const date = new Date(); - return date; - }; - - next(); + next(); }; ``` hapi: + ```js const getDate = { - name: 'getDate', - version: '1.0.0', - register: async function (server, options) { - - const currentDate = function() { - - const date = new Date(); - return date; - }; + name: 'getDate', + version: '1.0.0', + register: async function (server, options) { + const currentDate = function () { + const date = new Date(); + return date; + }; - server.decorate('toolkit', 'getDate', currentDate); - } + server.decorate('toolkit', 'getDate', currentDate); + }, }; ``` + hapi插件会将当前日期保存在 `h.getDate()` 中。然后,我们可以在任何路由处理程序中使用它。 ### 加载一个插件 @@ -237,16 +242,19 @@ hapi插件会将当前日期保存在 `h.getDate()` 中。然后,我们可以 在Express中,您可以通过调用 `app.use()` 方法来加载中间件。 在hapi中,您可以调用 `server.register()` 方法。 让我们加载上一节中创建的插件: Express: + ```js app.use(getDate); ``` hapi: + ```js await server.register({ - plugin: getDate + plugin: getDate, }); ``` + 您还可以通过在 `server.register()` 上设置 `options` 属性来为插件提供选项。 ### 选项 @@ -254,33 +262,35 @@ await server.register({ 您可以通过导出接受options参数的函数来向Express中间件添加选项,该函数随后返回中间件。在hapi中,您可以在注册插件时设置选项。我们来看一下: Express: + ```js module.exports = function (options) { - return function getDate(req, res, next) { - - req.getDate = function() { - - const date = 'Hello ' + options.name + ', the date is ' + new Date(); - return date; - }; - - next() + return function getDate(req, res, next) { + req.getDate = function () { + const date = 'Hello ' + options.name + ', the date is ' + new Date(); + return date; }; + + next(); + }; }; ``` hapi: + ```js server.register({ - plugin: getDate, - options: { - name: 'Tom' - } -}) + plugin: getDate, + options: { + name: 'Tom', + }, +}); ``` + 要访问hapi中的选项,只需在创建插件时引用 `options` 对象即可: Express: + ```js const getDate = require('./mw/getDate.js'); @@ -288,20 +298,19 @@ app.use(getDate({ name: 'Tom' })); ``` hapi: + ```js const getDate = { - name: 'getDate', - version: '1.0.0', - register: async function (server, options) { - - const currentDate = function() { - - const date = 'Hello ' + options.name + ', the date is ' + new Date(); - return date; - }; + name: 'getDate', + version: '1.0.0', + register: async function (server, options) { + const currentDate = function () { + const date = 'Hello ' + options.name + ', the date is ' + new Date(); + return date; + }; - server.decorate('toolkit', 'getDate', currentDate); - } + server.decorate('toolkit', 'getDate', currentDate); + }, }; ``` @@ -310,31 +319,33 @@ const getDate = { hapi的核心具有解析能力。与Express不同,您不需要中间件来解析有效载荷数据。实际上,根据要解析的数据类型,您可能需要在Express中最多安装四个附加的中间件。在hapi中,有效载荷数据(无论是JSON还是纯文本)都可以在 `request.payload` 对象中获得。这是解析简单有效负载数据的并排比较: Express: + ```js var bodyParser = require('body-parser'); -app.use(bodyParser.urlencoded({extend: true})); +app.use(bodyParser.urlencoded({ extend: true })); -app.post('/hello', function (req, res) { - - var name = req.body.name - res.send('Hello ' + name); +app.post('/hello', function (req, res) { + var name = req.body.name; + res.send('Hello ' + name); }); ``` hapi: + ```js server.route({ - method: 'POST', - path: '/hello', - handler: function (request, h) { - - const name = request.payload.name; - return `Hello ` + name; - } + method: 'POST', + path: '/hello', + handler: function (request, h) { + const name = request.payload.name; + return `Hello ` + name; + }, }); ``` + 要解析express中的JSON对象,您必须指定它: + ```js app.use(bodyParser.json()); ``` @@ -351,16 +362,18 @@ const Hapi = require('@hapi/hapi'); const server = Hapi.server({ port: 8000 }); server.state('data', { - ttl: null, - isSecure: true, - isHttpOnly: true + ttl: null, + isSecure: true, + isHttpOnly: true, }); ``` ### 设定 Cookie + 设置cookie一旦配置了cookie,就可以使用 `h.state()` 设置cookie。这里有一个例子: Express: + ```js var express = require('express'); var app = express(); @@ -368,33 +381,32 @@ var cookieParser = require('cookie-parser'); app.use(cookieParser()); -app.get('/', function(req, res) { - - res.cookie('username', 'tom', { maxAge: null, secure: true, httpOnly: true }); - res.send('Hello'); +app.get('/', function (req, res) { + res.cookie('username', 'tom', { maxAge: null, secure: true, httpOnly: true }); + res.send('Hello'); }); ``` hapi: + ```js const Hapi = require('@hapi/hapi'); const server = Hapi.server({ port: 8000 }); server.state('username', { - ttl: null, - isSecure: true, - isHttpOnly: true + ttl: null, + isSecure: true, + isHttpOnly: true, }); server.route({ - method: 'GET', - path: '/', - handler: function (request, h) { - - h.state('username', 'tom'); - return h.response('Hello'); - } + method: 'GET', + path: '/', + handler: function (request, h) { + h.state('username', 'tom'); + return h.response('Hello'); + }, }); ``` @@ -405,6 +417,7 @@ server.route({ 要获取hapi中的cookie值,请调用 `request.state`。让我们看看: Express: + ```js var express = require('express'); var app = express(); @@ -413,32 +426,32 @@ var cookieParser = require('cookie-parser); app.use(cookieParser()); app.get('/', (req, res) => { - + res.cookie('username', 'tom', { maxAge: null, secure: true, httpOnly: true }) res.send(req.cookies.username); }); ``` hapi: + ```js const Hapi = require('@hapi/hapi'); const server = Hapi.server({ port: 8000 }); server.state('username', { - ttl: null, - isSecure: true, - isHttpOnly: true + ttl: null, + isSecure: true, + isHttpOnly: true, }); server.route({ - method: 'GET', - path: '/', - handler: async (request, h) => { - - h.state('username', 'tom'); - return h.response(request.state.username); - } + method: 'GET', + path: '/', + handler: async (request, h) => { + h.state('username', 'tom'); + return h.response(request.state.username); + }, }); ``` @@ -447,9 +460,11 @@ server.route({ 在Express中,第三方身份验证是通过Passport处理的。在hapi中,您可以使用 [bell](/module/bell) 模块进行第三方身份验证。`bell` 为OAuth提供者提供了30多种预定义的配置,包括Twitter,Facebook,Google,GitHub等。 它还将允许您设置自己的自定义提供程序。 有关完整列表,请参阅 [bell providers documentation](https://github.com/hapijs/bell/blob/master/Providers.md)。 `bell` 是由核心hapi团队开发并维护的,因此您知道稳定性和可靠性不会成为问题。 让我们看看如何使用您的Twitter凭据进行身份验证: Express: + ``` npm install passport passport-twitter ``` +
    ```js @@ -485,9 +500,11 @@ app.get('/auth/twitter/callback', passport.authenticate('twitter', { failureRedi ``` hapi: + ``` npm install '@hapi/bell' ``` +
    ```js @@ -499,37 +516,37 @@ const server = Hapi.server({ port: 8000 }); await server.register(Bell); server.auth.strategy('twitter', 'bell', { - provider: 'twitter', - password: 'cookie_encryption_password_secure', - clientId: TWITTER_CONSUMER_KEY, - clientSecret: TWITTER_CONSUMER_SECRET, - isSecure: false + provider: 'twitter', + password: 'cookie_encryption_password_secure', + clientId: TWITTER_CONSUMER_KEY, + clientSecret: TWITTER_CONSUMER_SECRET, + isSecure: false, }); server.route({ - method: '*', - path: '/auth/twitter', // The callback endpoint registered with the provider - handler: function (request, h) { - - if (!request.auth.isAuthenticated) { - return `Authentication failed due to: ${request.auth.error.message}`; - } - - // Perform any account lookup or registration, setup local session, - // and redirect to the application. The third-party credentials are - // stored in request.auth.credentials. Any query parameters from - // the initial request are passed back via request.auth.credentials.query. + method: '*', + path: '/auth/twitter', // The callback endpoint registered with the provider + handler: function (request, h) { + if (!request.auth.isAuthenticated) { + return `Authentication failed due to: ${request.auth.error.message}`; + } - return h.redirect('/home'); + // Perform any account lookup or registration, setup local session, + // and redirect to the application. The third-party credentials are + // stored in request.auth.credentials. Any query parameters from + // the initial request are passed back via request.auth.credentials.query. + + return h.redirect('/home'); + }, + options: { + auth: { + strategy: 'twitter', + mode: 'try', }, - options: { - auth: { - strategy: 'twitter', - mode: 'try' - } - } + }, }); ``` + 要使用bell,只需注册插件并使用 `server.auth.strategy` 配置策略。 `provider` 是第三方的名称。 @@ -551,9 +568,11 @@ server.route({ 输入验证使您可以验证任何输入到服务器的输入数据,包括其参数,有效负载等。下面介绍如何验证Express和hapi中的博客文章条目: Express: + ``` npm install express-validator ``` +
    ```js @@ -562,44 +581,44 @@ const expressValidator = require('express-validator'); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); -app.use(expressValidator()) +app.use(expressValidator()); app.post('/post', function (req, res) { - req.check('post', 'Post too long').isLength({ max: 140 }); let errors = req.validationErrors(); if (errors) { res.status(400).send(errors); } else { - res.send('Blog post added!') + res.send('Blog post added!'); } }); ``` hapi: + ``` npm install joi ``` +
    ```js -const Joi = require('joi') +const Joi = require('joi'); server.route({ - method: 'POST', - path: '/post', - handler: (request, h) => { - - return 'Blog post added!'; + method: 'POST', + path: '/post', + handler: (request, h) => { + return 'Blog post added!'; + }, + options: { + validate: { + payload: Joi.object({ + post: Joi.string().max(140), + }), }, - options: { - validate: { - payload: Joi.object({ - post: Joi.string().max(140) - }) - } - } + }, }); ``` @@ -614,30 +633,31 @@ Joi.string().min(1).max(140). 如上所述,没有明确的方法可以使用 `express-validator` 进行响应验证。使用 `joi`,响应验证既快速又简单。我们来看一下: hapi: + ```js const bookSchema = Joi.object({ - title: Joi.string().required(), - author: Joi.string().required(), - isbn: Joi.string().length(10), - pageCount: Joi.number(), - datePublished: Joi.date().iso() + title: Joi.string().required(), + author: Joi.string().required(), + isbn: Joi.string().length(10), + pageCount: Joi.number(), + datePublished: Joi.date().iso(), }); server.route({ - method: 'GET', - path: '/books', - handler: async function (request, h) { - - return await getBooks(); + method: 'GET', + path: '/books', + handler: async function (request, h) { + return await getBooks(); + }, + options: { + response: { + schema: Joi.array().items(bookSchema), + failAction: 'log', }, - options: { - response: { - schema: Joi.array().items(bookSchema), - failAction: 'log' - } - } + }, }); ``` + 此路线将返回书籍列表。 在 `options` 路线属性中,我们可以指定书籍清单应遵循的规则。 通过将 `failAction` 设置为 `log`,如果出现错误,服务器将记录该错误。 ## app.set('view engine') -> vision @@ -651,18 +671,21 @@ hapi对模板渲染提供了广泛的支持,包括加载和利用多个模板 ```js app.set('view engine', 'pug'); ``` + 要在hapi中设置view engine,首先必须注册vision plugin,然后配置 `server.views`: + ```js await server.register(require('@hapi/vision')); server.views({ - engines: { - pug: require('pug') - }, - relativeTo: __dirname, - path: 'views' + engines: { + pug: require('pug'), + }, + relativeTo: __dirname, + path: 'views', }); ``` + 默认情况下,Express将在 `views` 文件夹中寻找视图或模板。在hapi中,您可以使用 `relativeTo` 和 `path` 属性来指定视图的位置。像Express一样,hapi支持各种模板引擎(`template engines`),例如pug,ejs,handbars等。 By default, Express will look for views or templates in the `views` folder. In hapi, you specify where the views are located using the `relativeTo` and `path` properties. Like Express, hapi supports a wide variety of templating engines, such as pug, ejs, handlebars, etc. @@ -676,39 +699,40 @@ hapi在 `server.views` 中有更多可配置的选项。要查看功能的完整 ```js app.get('/', function (req, res) { - - res.render('index', { title: 'Homepage', message: 'Welcome' }); + res.render('index', { title: 'Homepage', message: 'Welcome' }); }); ``` + Using `h.view` in hapi: ```js server.route({ - method: 'GET', - path: '/', - handler: function (request, h) { - - return h.view('index', { title: 'Homepage', message: 'Welcome' }); - } + method: 'GET', + path: '/', + handler: function (request, h) { + return h.view('index', { title: 'Homepage', message: 'Welcome' }); + }, }); ``` + 然后是在hapi中使用handler来渲染 view: ```js server.route({ - method: 'GET', - path: '/', - handler: { - view: { - template: 'index', - context: { - title: 'Homepage', - message: 'Welcome' - } - } - } + method: 'GET', + path: '/', + handler: { + view: { + template: 'index', + context: { + title: 'Homepage', + message: 'Welcome', + }, + }, + }, }); -``` +``` + 为了在 `h.view` 中传递上下文,您需要传递一个对象作为第二个参数。 要在 view 处理程序中传递 `context`,请使用 `context` 键。 ## express.static() -> inert @@ -720,90 +744,96 @@ hapi可以从名为 [inert](/module/inert) 的插件中提供静态内容。iner 在Express中,您可以使用 `res.sendFile` 方法返回单个文件。在hapi中,您可以使用 `h.file()` 方法或文件处理程序,可以通过 [inert](/module/inert) 使用。一旦注册了插件,便可以提供静态文件: Express: + ```js app.get('/image', function (req, res) { - - res.sendFile('image.jpg', {root: './public'}); + res.sendFile('image.jpg', { root: './public' }); }); ``` hapi with `h.file()`: + ```js const server = new Hapi.Server({ - port: 3000, - routes: { - files: { - relativeTo: Path.join(__dirname, 'public') - } - } + port: 3000, + routes: { + files: { + relativeTo: Path.join(__dirname, 'public'), + }, + }, }); await server.register(require('@hapi/inert')); server.route({ - method: 'GET', - path: '/image', - handler: function (request, h) { - - return h.file('image.jpg'); - } + method: 'GET', + path: '/image', + handler: function (request, h) { + return h.file('image.jpg'); + }, }); ``` + hapi with file handler: + ```js const server = new Hapi.Server({ - port: 3000, - routes: { - files: { - relativeTo: Path.join(__dirname, 'public') - } - } + port: 3000, + routes: { + files: { + relativeTo: Path.join(__dirname, 'public'), + }, + }, }); await server.register(require('@hapi/inert')); server.route({ - method: 'GET', - path: '/image', - handler: { - file: 'image.jpg' - } + method: 'GET', + path: '/image', + handler: { + file: 'image.jpg', + }, }); ``` 要在hapi中提供静态文件,您首先必须告诉hapi静态文件位于何处。您可以通过配置 `server.options.routes` 对象来实现。您将 `relativeTo` 设置为文件所在的文件夹,就像在Express中 `res.sendFile` 的 options 对象中所做的一样。接下来,您需要注册惰性插件。这将使您能够访问允许提供静态文件的方法。现在,在路由处理程序中,您可以使用 `h.file()` 方法或文件处理程序来处理您的静态文件。 ### 静态文件服务器 + 要在Express中设置静态文件服务器,可以使用 `express.static()` 中间件。在hapi中,您使用 [inert](/module/inert) 插件提供的文件处理程序。您将通过告诉文件位于何处,以与服务单个静态文件相同的方式设置服务器。 然后,您将设置一条路由以捕获所有请求并返回正确的文件。 我们来看一下: Express: + ```js app.use(express.static('/public')); ``` hapi: + ```js const server = new Hapi.Server({ - port: 3000, - routes: { - files: { - relativeTo: Path.join(__dirname, 'public') - } - } + port: 3000, + routes: { + files: { + relativeTo: Path.join(__dirname, 'public'), + }, + }, }); await server.register(require('@hapi/inert')); server.route({ - method: 'GET', - path: '/{param*}', - handler: { - directory: { - path: '.' - } - } + method: 'GET', + path: '/{param*}', + handler: { + directory: { + path: '.', + }, + }, }); ``` + 现在,您可以通过访问 `localhost:3000/filename` 来访问任何静态文件。 [inert](/module/inert) 具有许多其他选项和功能。要查看其所有功能,请参阅 [serving static files](/tutorials/servingfiles/?lang=en_US) tutorial 教程。 Now, you can access any static files by going to `localhost:3000/filename`. [inert](/module/inert) has many other options and capabilities. To see what all it can do, please see the [serving static files](/tutorials/servingfiles/?lang=en_US) tutorial. @@ -811,18 +841,19 @@ Now, you can access any static files by going to `localhost:3000/filename`. [ine hapi使用 [boom](/module/boom) 模块来处理错误。默认情况下,boom将以JSON格式返回错误。另一方面,Express默认情况下将返回文本响应,该响应在JSON API中并非最佳。通过向不存在的 `'/hello'` 提交 `GET` 请求,以默认设置查看404错误响应: -Express: +Express: ```js Cannot GET /hello ``` hapi: + ```json { - "statusCode": 404, - "error": "Not Found", - "message": "Not Found" + "statusCode": 404, + "error": "Not Found", + "message": "Not Found" } ``` @@ -831,11 +862,13 @@ hapi: `boom` 可让您轻松更改任何状态代码的错误消息。让我们使用上面的404错误并返回一条新消息: Express: + ```js -res.status(400).send({status: 404, error: "Page not found"}); +res.status(400).send({ status: 404, error: 'Page not found' }); ``` hapi: + ```js throw Boom.notFound('Page not found'); ``` diff --git a/static/lib/tutorials/zh_CN/gettingstarted.md b/docs/tutorials/zh_CN/getting-started.md similarity index 76% rename from static/lib/tutorials/zh_CN/gettingstarted.md rename to docs/tutorials/zh_CN/getting-started.md index 3ae7ba19..250d4263 100644 --- a/static/lib/tutorials/zh_CN/gettingstarted.md +++ b/docs/tutorials/zh_CN/getting-started.md @@ -1,3 +1,9 @@ +--- +title: Getting Started +--- + + + ## 快速入门 _该教程适用于 hapi v17版本_ @@ -6,9 +12,9 @@ _该教程适用于 hapi v17版本_ 新建一个目录 `myproject`: -* 运行: `cd myproject` 跳转到目录内。 -* 运行: `npm init` 根据提示生成文件 package.json。 -* 运行: `npm install --save @hapi/hapi@17.x.x` 将安装 hapi ,并将相应的依赖并保存至 package.json 中。 +- 运行: `cd myproject` 跳转到目录内。 +- 运行: `npm init` 根据提示生成文件 package.json。 +- 运行: `npm install --save @hapi/hapi@17.x.x` 将安装 hapi ,并将相应的依赖并保存至 package.json 中。 就是这么简单! 你现在已经做好了创建一个 hapi 应用的全部准备。 @@ -22,20 +28,18 @@ _该教程适用于 hapi v17版本_ const Hapi = require('@hapi/hapi'); const server = Hapi.server({ - port: 3000, - host: 'localhost' + port: 3000, + host: 'localhost', }); const init = async () => { - - await server.start(); - console.log(`Server running at: ${server.info.uri}`); + await server.start(); + console.log(`Server running at: ${server.info.uri}`); }; process.on('unhandledRejection', (err) => { - - console.log(err); - process.exit(1); + console.log(err); + process.exit(1); }); init(); @@ -55,38 +59,34 @@ Web 服务器可以通过以下方式创建:指定主机名、填写IP地址 const Hapi = require('@hapi/hapi'); const server = Hapi.server({ - port: 3000, - host: 'localhost' + port: 3000, + host: 'localhost', }); server.route({ - method: 'GET', - path: '/', - handler: (request, h) => { - - return 'Hello, world!'; - } + method: 'GET', + path: '/', + handler: (request, h) => { + return 'Hello, world!'; + }, }); server.route({ - method: 'GET', - path: '/{name}', - handler: (request, h) => { - - return 'Hello, ' + encodeURIComponent(request.params.name) + '!'; - } + method: 'GET', + path: '/{name}', + handler: (request, h) => { + return 'Hello, ' + encodeURIComponent(request.params.name) + '!'; + }, }); const init = async () => { - - await server.start(); - console.log(`Server running at: ${server.info.uri}`); + await server.start(); + console.log(`Server running at: ${server.info.uri}`); }; process.on('unhandledRejection', (err) => { - - console.log(err); - process.exit(1); + console.log(err); + process.exit(1); }); init(); @@ -106,22 +106,20 @@ init(); 在你的 `server.js` 文件中修改 `init` 函数如下: -``` javascript +```javascript const init = async () => { + await server.register(require('@hapi/inert')); - await server.register(require('@hapi/inert')); - - server.route({ - method: 'GET', - path: '/hello', - handler: (request, h) => { - - return h.file('./public/hello.html'); - } - }); + server.route({ + method: 'GET', + path: '/hello', + handler: (request, h) => { + return h.file('./public/hello.html'); + }, + }); - await server.start(); - console.log(`Server running at: ${server.info.uri}`); + await server.start(); + console.log(`Server running at: ${server.info.uri}`); }; ``` @@ -137,7 +135,7 @@ const init = async () => { - + Hapi.js is awesome! @@ -172,54 +170,49 @@ npm install hapi-pino const Hapi = require('@hapi/hapi'); const server = Hapi.server({ - port: 3000, - host: 'localhost' + port: 3000, + host: 'localhost', }); server.route({ - method: 'GET', - path: '/', - handler: (request, h) => { - - return 'Hello, world!'; - } + method: 'GET', + path: '/', + handler: (request, h) => { + return 'Hello, world!'; + }, }); server.route({ - method: 'GET', - path: '/{name}', - handler: (request, h) => { - - // request.log(['a', 'name'], "Request name"); - // or - request.logger.info('In handler %s', request.path); - - return `Hello, ${encodeURIComponent(request.params.name)}!`; - } + method: 'GET', + path: '/{name}', + handler: (request, h) => { + // request.log(['a', 'name'], "Request name"); + // or + request.logger.info('In handler %s', request.path); + + return `Hello, ${encodeURIComponent(request.params.name)}!`; + }, }); const init = async () => { - - await server.register({ - plugin: require('hapi-pino'), - options: { - prettyPrint: false, - logEvents: ['response', 'onPostStart'] - } - }); - - await server.start(); - console.log(`Server running at: ${server.info.uri}`); + await server.register({ + plugin: require('hapi-pino'), + options: { + prettyPrint: false, + logEvents: ['response', 'onPostStart'], + }, + }); + + await server.start(); + console.log(`Server running at: ${server.info.uri}`); }; process.on('unhandledRejection', (err) => { - - console.log(err); - process.exit(1); + console.log(err); + process.exit(1); }); init(); - ``` 当服务器启动的时候你将会看到以下内容: diff --git a/static/lib/tutorials/zh_CN/logging.md b/docs/tutorials/zh_CN/logging.md similarity index 91% rename from static/lib/tutorials/zh_CN/logging.md rename to docs/tutorials/zh_CN/logging.md index 43315ab9..68cccb04 100644 --- a/static/lib/tutorials/zh_CN/logging.md +++ b/docs/tutorials/zh_CN/logging.md @@ -1,3 +1,9 @@ +--- +title: Logging +--- + + + ## 日志 _该教程适用于 hapi v17版本_ @@ -26,13 +32,11 @@ hapi 中所有生成的日志事件,都会有一个 `hapi` 标签。 hapi 服务器对象为每个日志事件都发出了事件。你可以通过标准的 EventEmitter API 去监听这些事件并做处理。 - ```javascript server.events.on('log', (event, tags) => { - - if (tags.error) { - console.log(`Server error: ${event.error ? event.error.message : 'unknown'}`); - } + if (tags.error) { + console.log(`Server error: ${event.error ? event.error.message : 'unknown'}`); + } }); ``` @@ -42,17 +46,16 @@ server.events.on('log', (event, tags) => { ```javascript server.route({ - method: 'GET', - path: '/', - options: { - log: { - collect: true - } + method: 'GET', + path: '/', + options: { + log: { + collect: true, }, - handler: function (request, h) { - - return 'hello'; - } + }, + handler: function (request, h) { + return 'hello'; + }, }); ``` diff --git a/static/lib/tutorials/zh_CN/plugins.md b/docs/tutorials/zh_CN/plugins.md similarity index 65% rename from static/lib/tutorials/zh_CN/plugins.md rename to docs/tutorials/zh_CN/plugins.md index 2d5f7765..5da71503 100644 --- a/static/lib/tutorials/zh_CN/plugins.md +++ b/docs/tutorials/zh_CN/plugins.md @@ -1,3 +1,9 @@ +--- +title: Plugins +--- + + + ## 插件 _该教程适用于 hapi v17版本_ @@ -14,24 +20,22 @@ hapi 拥有一个可扩展并且强健的插件系统,它允许你将应用分 'use strict'; const myPlugin = { - name: 'myPlugin', - version: '1.0.0', - register: async function (server, options) { - - // 创建一个路由作为示例 - - server.route({ - method: 'GET', - path: '/test', - handler: function (request, h) { - - return 'hello, world'; - } - }); + name: 'myPlugin', + version: '1.0.0', + register: async function (server, options) { + // 创建一个路由作为示例 + + server.route({ + method: 'GET', + path: '/test', + handler: function (request, h) { + return 'hello, world'; + }, + }); - // etc ... - await someAsyncMethods(); - } + // etc ... + await someAsyncMethods(); + }, }; ``` @@ -41,23 +45,21 @@ const myPlugin = { 'use strict'; exports.plugin = { - pkg: require('./package.json'), - register: async function (server, options) { - - // 创建一个路由作为示例 - - server.route({ - method: 'GET', - path: '/test', - handler: function (request, h) { - - return 'hello, world'; - } - }); + pkg: require('./package.json'), + register: async function (server, options) { + // 创建一个路由作为示例 + + server.route({ + method: 'GET', + path: '/test', + handler: function (request, h) { + return 'hello, world'; + }, + }); - // etc... - await someAsyncMethods(); - } + // etc... + await someAsyncMethods(); + }, }; ``` @@ -85,14 +87,13 @@ exports.plugin = { ```javascript const start = async function () { + // 载入一个插件 - // 载入一个插件 + await server.register(require('myplugin')); - await server.register(require('myplugin')); + // 载入多个插件 - // 载入多个插件 - - await server.register([require('myplugin'), require('yourplugin')]); + await server.register([require('myplugin'), require('yourplugin')]); }; ``` @@ -100,13 +101,12 @@ const start = async function () { ```javascript const start = async function () { - - await server.register({ - plugin: require('myplugin'), - options: { - message: 'hello' - } - }); + await server.register({ + plugin: require('myplugin'), + options: { + message: 'hello', + }, + }); }; ``` @@ -114,14 +114,16 @@ const start = async function () { ```javascript const start = async function () { - - await server.register([{ - plugin: require('plugin1'), - options: {} - }, { - plugin: require('plugin2'), - options: {} - }]); + await server.register([ + { + plugin: require('plugin1'), + options: {}, + }, + { + plugin: require('plugin2'), + options: {}, + }, + ]); }; ``` @@ -129,7 +131,7 @@ const start = async function () { 你也可以传递第二个可选参数到 `server.register()`。 关于这个对象的文档可以在 [API reference](/api#-await-serverregisterplugins-options) 中找到。 -options 对象将被 hapi 使用,并且 *不会* 传递到被装载的插件中。它可以将`vhost`或`prefix`修饰符添加到使用插件的路由上。 +options 对象将被 hapi 使用,并且 _不会_ 传递到被装载的插件中。它可以将`vhost`或`prefix`修饰符添加到使用插件的路由上。 例如我们有这样一个插件: @@ -137,34 +139,31 @@ options 对象将被 hapi 使用,并且 *不会* 传递到被装载的插件 'use strict'; exports.plugin = { - pkg: require('./package.json'), - register: async function (server, options) { - - server.route({ - method: 'GET', - path: '/test', - handler: function (request, h) { - - return 'test passed'; - } - }); + pkg: require('./package.json'), + register: async function (server, options) { + server.route({ + method: 'GET', + path: '/test', + handler: function (request, h) { + return 'test passed'; + }, + }); - // 其他... - await someAsyncMethods(); - } + // 其他... + await someAsyncMethods(); + }, }; ``` -通常来说, 当插件载入的时候将会创建一个 `GET` 路由在 `/test` 路径上。 我们可以通过添加 `prefix` 的值来修改任意使用这个插件生成的路由。 +通常来说, 当插件载入的时候将会创建一个 `GET` 路由在 `/test` 路径上。 我们可以通过添加 `prefix` 的值来修改任意使用这个插件生成的路由。 ```javascript const start = async function () { - - await server.register(require('myplugin'), { - routes: { - prefix: '/plugins' - } - }); + await server.register(require('myplugin'), { + routes: { + prefix: '/plugins', + }, + }); }; ``` diff --git a/static/lib/tutorials/zh_CN/routing.md b/docs/tutorials/zh_CN/routing.md similarity index 73% rename from static/lib/tutorials/zh_CN/routing.md rename to docs/tutorials/zh_CN/routing.md index ecc2878c..60cf81b7 100644 --- a/static/lib/tutorials/zh_CN/routing.md +++ b/docs/tutorials/zh_CN/routing.md @@ -1,3 +1,9 @@ +--- +title: Routing +--- + + + ## 路由 _该教程适用于 hapi v17版本_ @@ -6,12 +12,11 @@ _该教程适用于 hapi v17版本_ ```javascript server.route({ - method: 'GET', - path: '/', - handler: function (request, h) { - - return 'Hello!'; - } + method: 'GET', + path: '/', + handler: function (request, h) { + return 'Hello!'; + }, }); ``` @@ -21,12 +26,11 @@ server.route({ ```javascript server.route({ - method: ['PUT', 'POST'], - path: '/', - handler: function (request, h) { - - return 'I did something!'; - } + method: ['PUT', 'POST'], + path: '/', + handler: function (request, h) { + return 'I did something!'; + }, }); ``` @@ -36,12 +40,11 @@ path 参数必须为一个字符串, 虽然他们可以包含一个命名的参 ```javascript server.route({ - method: 'GET', - path: '/hello/{user}', - handler: function (request, h) { - - return `Hello ${encodeURIComponent(request.params.user)}!`; - } + method: 'GET', + path: '/hello/{user}', + handler: function (request, h) { + return `Hello ${encodeURIComponent(request.params.user)}!`; + }, }); ``` @@ -53,40 +56,36 @@ server.route({ ```javascript server.route({ - method: 'GET', - path: '/hello/{user?}', - handler: function (request, h) { - - const user = request.params.user ? - encodeURIComponent(request.params.user) : - 'stranger'; + method: 'GET', + path: '/hello/{user?}', + handler: function (request, h) { + const user = request.params.user ? encodeURIComponent(request.params.user) : 'stranger'; - return `Hello ${user}!`; - } + return `Hello ${user}!`; + }, }); ``` -现在一个请求发往 `/hello/mary` 将会返回 `Hello mary!` 如果只是发给 `/hello` 将会返回 `Hello stranger!`。 这里需要注意的是在路径中只有 *最后* 一个命名的参数可以为可选的。 这意味着 `/{one?}/{two}/` 是不合法的路径, 因为在可选参数后有另一个命名的参数。你可以针对路径内容的一部分进行命名,例如 `/{filename}.jpg` 是合法的。你可以指定多个命名参数,但是请注意需要用非参的分隔符进行分割。 这意味着 `/{filename}.{ext}` 是合法的而 `/{filename}{ext}` 不是。 +现在一个请求发往 `/hello/mary` 将会返回 `Hello mary!` 如果只是发给 `/hello` 将会返回 `Hello stranger!`。 这里需要注意的是在路径中只有 _最后_ 一个命名的参数可以为可选的。 这意味着 `/{one?}/{two}/` 是不合法的路径, 因为在可选参数后有另一个命名的参数。你可以针对路径内容的一部分进行命名,例如 `/{filename}.jpg` 是合法的。你可以指定多个命名参数,但是请注意需要用非参的分隔符进行分割。 这意味着 `/{filename}.{ext}` 是合法的而 `/{filename}{ext}` 不是。 ### 多段参数 -除了可选的路径参数,参数也可以匹配多段内容,可以通过 * 或数字来完成。例如: +除了可选的路径参数,参数也可以匹配多段内容,可以通过 \* 或数字来完成。例如: ```javascript server.route({ - method: 'GET', - path: '/hello/{user*2}', - handler: function (request, h) { - - const userParts = request.params.user.split('/'); - return `Hello ${encodeURIComponent(userParts[0])} ${encodeURIComponent(userParts[1])}!`; - } + method: 'GET', + path: '/hello/{user*2}', + handler: function (request, h) { + const userParts = request.params.user.split('/'); + return `Hello ${encodeURIComponent(userParts[0])} ${encodeURIComponent(userParts[1])}!`; + }, }); ``` -通过这个配置, 请求 `/hello/john/doe` 将会返回字符串 `Hello john doe!`。重点要注意的是,这里的参数实际上是字符串 `"john/doe"`. 所以需要通过 `split` 分割来获取里面的内容。 * 后面的数字表示有多少段内容将会被赋予参数。 你也可以完全省略这个数字,该参数将会匹配任意数量的可用段。 正如同可选参数一样, 通配参数 (如 `/{files*}`) *只会* 只能出现在路径的最后。 +通过这个配置, 请求 `/hello/john/doe` 将会返回字符串 `Hello john doe!`。重点要注意的是,这里的参数实际上是字符串 `"john/doe"`. 所以需要通过 `split` 分割来获取里面的内容。 _ 后面的数字表示有多少段内容将会被赋予参数。 你也可以完全省略这个数字,该参数将会匹配任意数量的可用段。 正如同可选参数一样, 通配参数 (如 `/{files_}`) _只会_ 只能出现在路径的最后。 -对于处理请求时,越是具体的路径参数,hapi将越优先使用。这意味着当你拥有两个路由时,一个路径为 `/filename.jpg` 另一个路径为 `/filename.{ext}`。当一个请求访问 `/filename.jpg` 将会匹配到第一个而不是第二个。 这意味着一个路由的路径参数为 `/{files*}`时,将会是 *最后一个* 使用的路由,而且只会在前面的路由都无法匹配才会这样。 +对于处理请求时,越是具体的路径参数,hapi将越优先使用。这意味着当你拥有两个路由时,一个路径为 `/filename.jpg` 另一个路径为 `/filename.{ext}`。当一个请求访问 `/filename.jpg` 将会匹配到第一个而不是第二个。 这意味着一个路由的路径参数为 `/{files*}`时,将会是 _最后一个_ 使用的路由,而且只会在前面的路由都无法匹配才会这样。 ## Handler 方法 @@ -106,21 +105,18 @@ Handler 是一个接收两个参数的函数, `request` 和 `h`。 ```javascript server.route({ - method: 'GET', - path: '/hello/{user?}', - handler: function (request, h) { - - const user = request.params.user ? - encodeURIComponent(request.params.user) : - 'stranger'; - - return `Hello ${user}!`; - }, - options: { - description: 'Say hello!', - notes: 'The user parameter defaults to \'stranger\' if unspecified', - tags: ['api', 'greeting'] - } + method: 'GET', + path: '/hello/{user?}', + handler: function (request, h) { + const user = request.params.user ? encodeURIComponent(request.params.user) : 'stranger'; + + return `Hello ${user}!`; + }, + options: { + description: 'Say hello!', + notes: "The user parameter defaults to 'stranger' if unspecified", + tags: ['api', 'greeting'], + }, }); ``` diff --git a/static/lib/tutorials/zh_CN/servermethods.md b/docs/tutorials/zh_CN/server-methods.md similarity index 74% rename from static/lib/tutorials/zh_CN/servermethods.md rename to docs/tutorials/zh_CN/server-methods.md index 2aedbcac..a55dbaa1 100644 --- a/static/lib/tutorials/zh_CN/servermethods.md +++ b/docs/tutorials/zh_CN/server-methods.md @@ -1,13 +1,18 @@ +--- +title: Server Methods +--- + + + ## 服务器方法 _该教程适用于 hapi v17版本_ -服务器方法是一种非常有用的函数共享方式,与引入公用的模块不同,它只需附加在服务器对象上。注册一个服务器方法,你只需调用 [`server.method()`](https://hapijs.com/api#server.method())。 有两种方式调用这个函数,你可以通过方法 `server.method(name, method, [options])` 调用, 如: +服务器方法是一种非常有用的函数共享方式,与引入公用的模块不同,它只需附加在服务器对象上。注册一个服务器方法,你只需调用 [`server.method()`]()。 有两种方式调用这个函数,你可以通过方法 `server.method(name, method, [options])` 调用, 如: ```javascript const add = function (x, y) { - - return x + y; + return x + y; }; server.method('add', add, {}); @@ -17,14 +22,13 @@ server.method('add', add, {}); ```javascript const add = function (x, y) { - - return x + y; + return x + y; }; server.method({ - name: 'add', - method: add, - options: {} + name: 'add', + method: add, + options: {}, }); ``` @@ -44,9 +48,8 @@ server.method('math.add', add); ```js const add = async function (x, y) { - - const result = await someLongRunningFunction(x, y); - return result; + const result = await someLongRunningFunction(x, y); + return result; }; server.method('add', add, {}); @@ -60,45 +63,44 @@ server.method('add', add, {}); ```javascript server.method('add', add, { - cache: { - expiresIn: 60000, - expiresAt: '20:30', - staleIn: 30000, - staleTimeout: 10000, - generateTimeout: 100 - } + cache: { + expiresIn: 60000, + expiresAt: '20:30', + staleIn: 30000, + staleTimeout: 10000, + generateTimeout: 100, + }, }); ``` 参数可以是: -* `expiresIn`: 以项目保存在缓存中的时间起,超过这个时间将失效。其中时间以毫秒数表示,不能与 `expiresAt`一同使用。 -* `expiresAt`: 使用以 'HH:MM' 格式以24小时为指定时间, 这个时间之后路由所有的缓存记录都将失效。这个时间使用本地时间,不能与 `expiresIn` 一同使用。 -* `staleIn`: 缓存失效时,尝试重新生成它毫秒数,必须小于 `expiresIn`。 -* `staleTimeout`: 在 generateFunc 生成新值时返回之前,可以允许返回过期值的毫秒数。 -* `generateTimeout`: 当返回时间太长时,如返回超时错误之前,等待的毫秒数。但当这个值最终被返回时,它将储存在缓存中以便将来的请求使用。 -* `segment`: 用于隔离缓存项的可选分段名称。 -* `cache`: 一个可选字符串,其中包含要使用的服务器上配置的缓存连接的名称。 +- `expiresIn`: 以项目保存在缓存中的时间起,超过这个时间将失效。其中时间以毫秒数表示,不能与 `expiresAt`一同使用。 +- `expiresAt`: 使用以 'HH:MM' 格式以24小时为指定时间, 这个时间之后路由所有的缓存记录都将失效。这个时间使用本地时间,不能与 `expiresIn` 一同使用。 +- `staleIn`: 缓存失效时,尝试重新生成它毫秒数,必须小于 `expiresIn`。 +- `staleTimeout`: 在 generateFunc 生成新值时返回之前,可以允许返回过期值的毫秒数。 +- `generateTimeout`: 当返回时间太长时,如返回超时错误之前,等待的毫秒数。但当这个值最终被返回时,它将储存在缓存中以便将来的请求使用。 +- `segment`: 用于隔离缓存项的可选分段名称。 +- `cache`: 一个可选字符串,其中包含要使用的服务器上配置的缓存连接的名称。 更多关于缓存的选项的信息可以通过 [API Reference](/api#servermethodmethod) 以及 [catbox](https://github.com/hapijs/catbox#policy) 中找到。 -通过设置 `ttl` 标记,可以修改每次调用服务器方法结果的 `ttl` (生存时间)。我们来看一下如何让它与之前的例子工作: +通过设置 `ttl` 标记,可以修改每次调用服务器方法结果的 `ttl` (生存时间)。我们来看一下如何让它与之前的例子工作: ```js const add = async function (x, y, flags) { + const result = await someLongRunningFunction(x, y); - const result = await someLongRunningFunction(x, y); + flags.ttl = 5 * 60 * 1000; // 5 mins - flags.ttl = 5 * 60 * 1000; // 5 mins - - return result; + return result; }; server.method('add', add, { - cache: { - expiresIn: 2000, - generateTimeout: 100 - } + cache: { + expiresIn: 2000, + generateTimeout: 100, + }, }); server.methods.add(5, 12); @@ -112,19 +114,17 @@ server.methods.add(5, 12); ```javascript const sum = function (array) { + let total = 0; - let total = 0; - - array.forEach((item) => { + array.forEach((item) => { + total += item; + }); - total += item; - }); - - return total; + return total; }; server.method('sum', sum, { - generateKey: (array) => array.join(',') + generateKey: (array) => array.join(','), }); ``` @@ -136,10 +136,9 @@ server.method('sum', sum, { ```javascript const lookup = async function (id) { + // 调用 myDB.getOne - // 调用 myDB.getOne - - return await this.getOne({ id }); + return await this.getOne({ id }); }; server.method('lookup', lookup, { bind: myDB }); diff --git a/static/lib/tutorials/zh_CN/servingfiles.md b/docs/tutorials/zh_CN/serving-files.md similarity index 66% rename from static/lib/tutorials/zh_CN/servingfiles.md rename to docs/tutorials/zh_CN/serving-files.md index 89fcd639..626ab9bd 100644 --- a/static/lib/tutorials/zh_CN/servingfiles.md +++ b/docs/tutorials/zh_CN/serving-files.md @@ -1,3 +1,9 @@ +--- +title: Serving Files +--- + + + ## 静态内容 _该教程适用于 hapi v17版本_ @@ -14,21 +20,19 @@ _该教程适用于 hapi v17版本_ ```javascript const start = async () => { + await server.register(require('@hapi/inert')); - await server.register(require('@hapi/inert')); - - server.route({ - method: 'GET', - path: '/picture.jpg', - handler: function (request, h) { - - return h.file('/path/to/picture.jpg'); - } - }); + server.route({ + method: 'GET', + path: '/picture.jpg', + handler: function (request, h) { + return h.file('/path/to/picture.jpg'); + }, + }); - await server.start(); + await server.start(); - console.log('Server running at:', server.info.uri); + console.log('Server running at:', server.info.uri); }; start(); @@ -47,29 +51,27 @@ const Hapi = require('@hapi/hapi'); const Path = require('path'); const server = Hapi.server({ - routes: { - files: { - relativeTo: Path.join(__dirname, 'public') - } - } + routes: { + files: { + relativeTo: Path.join(__dirname, 'public'), + }, + }, }); const start = async () => { + await server.register(require('@hapi/inert')); - await server.register(require('@hapi/inert')); - - server.route({ - method: 'GET', - path: '/picture.jpg', - handler: function (request, h) { - - return h.file('picture.jpg'); - } - }); + server.route({ + method: 'GET', + path: '/picture.jpg', + handler: function (request, h) { + return h.file('picture.jpg'); + }, + }); - await server.start(); + await server.start(); - console.log('Server running at:', server.info.uri); + console.log('Server running at:', server.info.uri); }; start(); @@ -83,11 +85,11 @@ start(); ```javascript server.route({ - method: 'GET', - path: '/picture.jpg', - handler: { - file: 'picture.jpg' - } + method: 'GET', + path: '/picture.jpg', + handler: { + file: 'picture.jpg', + }, }); ``` @@ -97,30 +99,30 @@ server.route({ ```javascript server.route({ - method: 'GET', - path: '/{filename}', - handler: { - file: function (request) { - return request.params.filename; - } - } + method: 'GET', + path: '/{filename}', + handler: { + file: function (request) { + return request.params.filename; + }, + }, }); ``` -它也可以是具有 `path` 属性的对象。当在 handler 中使用对象时,我们可以附加一些别的东西,如设 `Content-Disposition` 头并允许压缩文件。如下: +它也可以是具有 `path` 属性的对象。当在 handler 中使用对象时,我们可以附加一些别的东西,如设 `Content-Disposition` 头并允许压缩文件。如下: ```javascript server.route({ - method: 'GET', - path: '/script.js', - handler: { - file: { - path: 'script.js', - filename: 'client.js', // 修改 Content-Disposition 头中的文件名 - mode: 'attachment', // 指定 Content-Disposition 是一个附件 - lookupCompressed: true // 如果请求允许,将允许查找 script.js.gz - } - } + method: 'GET', + path: '/script.js', + handler: { + file: { + path: 'script.js', + filename: 'client.js', // 修改 Content-Disposition 头中的文件名 + mode: 'attachment', // 指定 Content-Disposition 是一个附件 + lookupCompressed: true, // 如果请求允许,将允许查找 script.js.gz + }, + }, }); ``` @@ -130,13 +132,13 @@ server.route({ ```javascript server.route({ - method: 'GET', - path: '/{param*}', - handler: { - directory: { - path: 'public' - } - } + method: 'GET', + path: '/{param*}', + handler: { + directory: { + path: 'public', + }, + }, }); ``` @@ -146,14 +148,14 @@ server.route({ ```javascript server.route({ - method: 'GET', - path: '/{param*}', - handler: { - directory: { - path: 'public', - index: ['index.html', 'default.html'] - } - } + method: 'GET', + path: '/{param*}', + handler: { + directory: { + path: 'public', + index: ['index.html', 'default.html'], + }, + }, }); ``` @@ -161,14 +163,15 @@ server.route({ ```javascript server.route({ - method: 'GET', - path: '/{param*}', - handler: { - directory: { - path: 'public', - listing: true - } - } + method: 'GET', + path: '/{param*}', + handler: { + directory: { + path: 'public', + listing: true, + }, + }, }); ``` + 现在,对 `/` 的请求将会回复一个显示目录内容的 HTML。使用启用了列表的目录 handler 时,默认情况下隐藏文件不会显示在列表中,可以通过将 `showHidden` 选项设置为 `true` 来显示。与文件 handler 一样,目录 handler 也有一个 `lookupCompressed` 的选项用于提供预压缩文件。你还可以设置一个 `defaultExtension`,如果找不到原始路径,它将附加到请求中。这意味着对 `/bacon` 的请求也会尝试文件 `/bacon.html`。 diff --git a/static/lib/tutorials/zh_CN/testing.md b/docs/tutorials/zh_CN/testing.md similarity index 80% rename from static/lib/tutorials/zh_CN/testing.md rename to docs/tutorials/zh_CN/testing.md index 88cecf84..8b6c7d62 100644 --- a/static/lib/tutorials/zh_CN/testing.md +++ b/docs/tutorials/zh_CN/testing.md @@ -1,3 +1,9 @@ +--- +title: Testing +--- + + + # Testing 此教程兼容hapi v17以及更高版本. @@ -8,7 +14,6 @@ Hapi设计理念是创建健壮的、可测试的应用.为此,Hapi具备不用 此教程带你进行路由测试的基本设置, 并提出了一种通过[lab](/module/lab)和[code](/module/code)创建可测试应用的一种可能. - ## lab `lab` 是Node.js的一个简单的测试套件. 区别于其他测试套件, lab 只使用 async/await 特性,并且包含了所有你在现代化Node.js测试套件里所需要的工具. `lab` 可以和任何其他的断言库兼容,在条件不符合时候掏出错误. 在本教程中,你将使用 `code` 断言库. @@ -35,38 +40,35 @@ Hapi设计理念是创建健壮的、可测试的应用.为此,Hapi具备不用 const Hapi = require('@hapi/hapi'); const server = Hapi.server({ - port: 3000, - host: 'localhost' + port: 3000, + host: 'localhost', }); server.route({ method: 'GET', path: '/', handler: function () { - - return 'Hello World!'; - } + return 'Hello World!'; + }, }); exports.init = async () => { - - await server.initialize(); - return server; + await server.initialize(); + return server; }; exports.start = async () => { - - await server.start(); - console.log(`Server running at: ${server.info.uri}`); - return server; + await server.start(); + console.log(`Server running at: ${server.info.uri}`); + return server; }; process.on('unhandledRejection', (err) => { - - console.log(err); - process.exit(1); + console.log(err); + process.exit(1); }); ``` + 现在用导出 `init()` 和 `start()`方法代替原来的调用这两个方法. 这样我们可以在别的文件中来初始化、启动服务. `init()` 方法可以初始化 (开启缓存, 完成插件注册) 但是并未启动服务. 接下来要在测试用例中启动服务. `start()` 会自动启动服务. 我们将要在入口文件中调用: ```js @@ -76,13 +78,14 @@ const { start } = require('lib/server'); start(); ``` + 你在这里创建的,是通常启动服务时候使用的,在入口文件通过调用start方法来启动服务的一种方式, 这种方式对外暴露出一个外部HTTP端口, 此外你也可以在我们的测试用例中使用一个什么都不做的模块. ## Writing a Route Test 在这个例子中你将使用 [lab](/module/lab), 同样的方法也可以在任何测试工具中使用,例如 [Mocha](https://mochajs.org/), [Jest](https://jestjs.io/), [Tap](https://www.node-tap.org/), [Ava](https://github.com/avajs) 等. -默认情况下, `lab` 加载所有文件'*.js' 在本地的 `test` 目录里,并执行所有发现的测试用例. 如果想设置其他的文件夹或者文件, 需要将文件或者文件夹路径作为参数传入: +默认情况下, `lab` 加载所有文件'\*.js' 在本地的 `test` 目录里,并执行所有发现的测试用例. 如果想设置其他的文件夹或者文件, 需要将文件或者文件夹路径作为参数传入: `$ lab unit.js` @@ -93,34 +96,35 @@ start(); const Lab = require('@hapi/lab'); const { expect } = require('@hapi/code'); -const { afterEach, beforeEach, describe, it } = exports.lab = Lab.script(); +const { afterEach, beforeEach, describe, it } = (exports.lab = Lab.script()); const { init } = require('../lib/server'); describe('GET /', () => { - let server; + let server; - beforeEach(async () => { - server = await init(); - }); + beforeEach(async () => { + server = await init(); + }); - afterEach(async () => { - await server.stop(); - }); + afterEach(async () => { + await server.stop(); + }); - it('responds with 200', async () => { - const res = await server.inject({ - method: 'get', - url: '/' - }); - expect(res.statusCode).to.equal(200); + it('responds with 200', async () => { + const res = await server.inject({ + method: 'get', + url: '/', }); + expect(res.statusCode).to.equal(200); + }); }); ``` -这里你将要测试我们的 `'GET'` 路由是否会响应 `200` 状态码. 首先调用 `describe()` 来给你的测试用例提供一个构造函数. `describe()` 接受2个参数, 一个是测试用例的描述, 另一个是设置测试用例的方法. + +这里你将要测试我们的 `'GET'` 路由是否会响应 `200` 状态码. 首先调用 `describe()` 来给你的测试用例提供一个构造函数. `describe()` 接受2个参数, 一个是测试用例的描述, 另一个是设置测试用例的方法. 请注意 `init` 代替 `start` 来设置服务, 意味着我们启动了服务, 但是没有监听任何端口. 每个测试用例后都会调用 `stop` 来清理和停止服务. -`it()` 方法将会运行你的测试用例. `it()` 接受2个参数, 一个是测试用例通过的描述语句, 另一个是运行测试用例的方法. +`it()` 方法将会运行你的测试用例. `it()` 接受2个参数, 一个是测试用例通过的描述语句, 另一个是运行测试用例的方法. 你需要了解服务器上的 `inject`. `inject` 使用 [Shot](/module/shot) 来 `inject` 直接向hapi的hanlder注入请求. 这就是让我们能够测试HTTP方法的关键所在. diff --git a/static/lib/tutorials/zh_CN/validation.md b/docs/tutorials/zh_CN/validation.md similarity index 77% rename from static/lib/tutorials/zh_CN/validation.md rename to docs/tutorials/zh_CN/validation.md index 6dc5e2e7..6fbe9f96 100644 --- a/static/lib/tutorials/zh_CN/validation.md +++ b/docs/tutorials/zh_CN/validation.md @@ -1,3 +1,9 @@ +--- +title: Validation +--- + + + ## 数据验证 _该教程适用于 hapi v17版本_ @@ -12,19 +18,18 @@ _该教程适用于 hapi v17版本_ ```javascript server.route({ - method: 'GET', - path: '/hello/{name}', - handler: function (request, h) { - - return `Hello ${request.params.name}!`; + method: 'GET', + path: '/hello/{name}', + handler: function (request, h) { + return `Hello ${request.params.name}!`; + }, + options: { + validate: { + params: { + name: Joi.string().min(3).max(10), + }, }, - options: { - validate: { - params: { - name: Joi.string().min(3).max(10) - } - } - } + }, }); ``` @@ -36,9 +41,9 @@ server.route({ ```json { - "error": "Bad Request", - "message": "Invalid request params input", - "statusCode": 400 + "error": "Bad Request", + "message": "Invalid request params input", + "statusCode": 400 } ``` @@ -46,25 +51,24 @@ server.route({ ### 查询参数 -验证查询参数我们只需要在路由选项中配置 `validate.query`。默认情况下 hapi 不做任何验证,但是如果一但为一个查询参数添加验证时,这将意味着你 *必须* 为你所接受的所有查询参数添加验证。 +验证查询参数我们只需要在路由选项中配置 `validate.query`。默认情况下 hapi 不做任何验证,但是如果一但为一个查询参数添加验证时,这将意味着你 _必须_ 为你所接受的所有查询参数添加验证。 例如,一个路由返回 blog 列表,并且你希望限制用户的请求条目的数量,你可以通过以下配置来完成: ```javascript server.route({ - method: 'GET', - path: '/posts', - handler: function (request, h) { - - return posts.slice(0, request.query.limit); + method: 'GET', + path: '/posts', + handler: function (request, h) { + return posts.slice(0, request.query.limit); + }, + options: { + validate: { + query: { + limit: Joi.number().integer().min(1).max(100).default(10), + }, }, - options: { - validate: { - query: { - limit: Joi.number().integer().min(1).max(100).default(10) - } - } - } + }, }); ``` @@ -93,10 +97,11 @@ hapi 支持多种选项来调整输出验证,这里简单列举一下: ### response.failAction 你可以通过以下 `response.failAction` 的设置来修改验证失败的行为: -* `error`: 发送内部服务器错误 (500) 请求 (默认) -* `log`: 只记录错误的日志并按原样返回 -* `ignore`: 继续处理请求而不做任何事情 -* 或者一个带有签名 `async function(request, h, err)` 的方法,其中 `request` 是请求对象, `h` 是 response toolkit ,`err` 是验证错误。 + +- `error`: 发送内部服务器错误 (500) 请求 (默认) +- `log`: 只记录错误的日志并按原样返回 +- `ignore`: 继续处理请求而不做任何事情 +- 或者一个带有签名 `async function(request, h, err)` 的方法,其中 `request` 是请求对象, `h` 是 response toolkit ,`err` 是验证错误。 ### response.sample @@ -105,8 +110,9 @@ hapi 支持多种选项来调整输出验证,这里简单列举一下: ### response.status 有时候同样的endpoint会有不同的响应类型,比如一个`POST`路由可能会返回以下内容: -* `201` 代表一个新的资源被创建。 -* `202` 代表一个资源被更新。 + +- `201` 代表一个新的资源被创建。 +- `202` 代表一个资源被更新。 hapi 可以通过不同的验证模式对此进行支持。`response.status` 是一个以返回码作为Key的对象, 它的属性是 joi 模式: @@ -122,6 +128,7 @@ hapi 可以通过不同的验证模式对此进行支持。`response.status` 是 ``` ### response.options + 选项可以在验证的时候传递给 joi。 更多细节请参阅 [API docs](/api#-routeoptionsresponseoptions)。 ### 示例 @@ -130,31 +137,29 @@ hapi 可以通过不同的验证模式对此进行支持。`response.status` 是 ```javascript const bookSchema = Joi.object({ - title: Joi.string().required(), - author: Joi.string().required(), - isbn: Joi.string().length(10), - pageCount: Joi.number(), - datePublished: Joi.date().iso() + title: Joi.string().required(), + author: Joi.string().required(), + isbn: Joi.string().length(10), + pageCount: Joi.number(), + datePublished: Joi.date().iso(), }); server.route({ - method: 'GET', - path: '/books', - handler: async function (request, h) { - - return await getBooks(); + method: 'GET', + path: '/books', + handler: async function (request, h) { + return await getBooks(); + }, + options: { + response: { + sample: 50, + schema: Joi.array().items(bookSchema), }, - options: { - response: { - sample: 50, - schema: Joi.array().items(bookSchema) - } - } + }, }); - ``` -这里只验证一半的请求 (`sample: 50`)。如果 `books` 不精确匹配 `bookSchema`时,之所以 hapi 返回 `500` 错误码,是因为 `response.failAction` 没有被定义。与此同时,错误请求 *不* 再能鉴别错误的原因。但是如果你配置了日志, 你依然可以通过查阅日志来发现验证错误的具体原因。如果 `response.failAction` 设置为 `log`, hapi 将会返回原始的内容信息,并将验证错误记录在日之内。 +这里只验证一半的请求 (`sample: 50`)。如果 `books` 不精确匹配 `bookSchema`时,之所以 hapi 返回 `500` 错误码,是因为 `response.failAction` 没有被定义。与此同时,错误请求 _不_ 再能鉴别错误的原因。但是如果你配置了日志, 你依然可以通过查阅日志来发现验证错误的具体原因。如果 `response.failAction` 设置为 `log`, hapi 将会返回原始的内容信息,并将验证错误记录在日之内。 ### 除Joi之外的选择 diff --git a/static/lib/tutorials/zh_CN/views.md b/docs/tutorials/zh_CN/views.md similarity index 79% rename from static/lib/tutorials/zh_CN/views.md rename to docs/tutorials/zh_CN/views.md index f00da55c..50921593 100644 --- a/static/lib/tutorials/zh_CN/views.md +++ b/docs/tutorials/zh_CN/views.md @@ -1,3 +1,9 @@ +--- +title: Views +--- + + + ## 视图 _该教程适用于 hapi v17版本_ @@ -18,16 +24,15 @@ const Hoek = require('@hapi/hoek'); const server = Hapi.server(); const start = async () => { + await server.register(require('@hapi/vision')); - await server.register(require('@hapi/vision')); - - server.views({ - engines: { - html: require('handlebars') - }, - relativeTo: __dirname, - path: 'templates' - }); + server.views({ + engines: { + html: require('handlebars'), + }, + relativeTo: __dirname, + path: 'templates', + }); }; start(); @@ -48,13 +53,13 @@ hapi 的视图引擎有众多的选项。完整的文档可以在这里找到 [v ```javascript server.views({ - engines: { - html: { - module: require('handlebars'), - compileMode: 'sync' // 引擎特定配置 - } + engines: { + html: { + module: require('handlebars'), + compileMode: 'sync', // 引擎特定配置 }, - compileMode: 'async' // 全局配置 + }, + compileMode: 'async', // 全局配置 }); ``` @@ -103,13 +108,13 @@ templates\ ```javascript server.views({ - engines: { - html: require('handlebars') - }, - relativeTo: __dirname, - path: './templates', - layoutPath: './templates/layout', - helpersPath: './templates/helpers' + engines: { + html: require('handlebars'), + }, + relativeTo: __dirname, + path: './templates', + layoutPath: './templates/layout', + helpersPath: './templates/helpers', }); ``` @@ -123,12 +128,11 @@ server.views({ ```javascript server.route({ - method: 'GET', - path: '/', - handler: function (request, h) { - - return h.view('index'); - } + method: 'GET', + path: '/', + handler: function (request, h) { + return h.view('index'); + }, }); ``` @@ -144,11 +148,11 @@ return h.view('index', { title: 'My home page' }); ```javascript server.route({ - method: 'GET', - path: '/', - handler: { - view: 'index' - } + method: 'GET', + path: '/', + handler: { + view: 'index', + }, }); ``` @@ -167,23 +171,23 @@ handler: { ### 全局内容 -我们已经知道了如何传递内容去一个视图,但是我们有一些默认的内容 *都必须* 显示在所有的模板上该如何呢? +我们已经知道了如何传递内容去一个视图,但是我们有一些默认的内容 _都必须_ 显示在所有的模板上该如何呢? 最简单的方式是在调用 `server.views()` 使用 `context` 选项 : ```javascript const context = { - title: 'My personal site' + title: 'My personal site', }; server.views({ - engines: { - html: { - module: require('handlebars'), - compileMode: 'sync' // engine specific - } + engines: { + html: { + module: require('handlebars'), + compileMode: 'sync', // engine specific }, - context + }, + context, }); ``` @@ -197,22 +201,21 @@ server.views({ ```javascript module.exports = function () { - - const fortunes = [ - 'Heisenberg may have slept here...', - 'Wanna buy a duck?', - 'Say no, then negotiate.', - 'Time and tide wait for no man.', - 'To teach is to learn.', - 'Never ask the barber if you need a haircut.', - 'You will forget that you ever knew me.', - 'You will be run over by a beer truck.', - 'Fortune favors the lucky.', - 'Have a nice day!' - ]; - - const x = Math.floor(Math.random() * fortunes.length); - return fortunes[x]; + const fortunes = [ + 'Heisenberg may have slept here...', + 'Wanna buy a duck?', + 'Say no, then negotiate.', + 'Time and tide wait for no man.', + 'To teach is to learn.', + 'Never ask the barber if you need a haircut.', + 'You will forget that you ever knew me.', + 'You will be run over by a beer truck.', + 'Fortune favors the lucky.', + 'Have a nice day!', + ]; + + const x = Math.floor(Math.random() * fortunes.length); + return fortunes[x]; }; ``` @@ -220,7 +223,7 @@ module.exports = function () { ```html

    Your fortune

    -

    {{fortune}}

    +

    {{fortune}}

    ``` 现在,当我们启动服务器并用浏览器访问使用我们模板的路径(使用我们的视图helper)时,我们应该会在标题下方看到一个随机显示的段落。 @@ -235,26 +238,24 @@ const Hapi = require('@hapi/hapi'); const server = Hapi.server({ port: 8080 }); const start = async () => { + await server.register(require('@hapi/vision')); - await server.register(require('@hapi/vision')); - - server.views({ - engines: { - html: require('handlebars') - }, - relativeTo: __dirname, - path: 'templates', - helpersPath: 'helpers' - }); - - server.route({ - method: 'GET', - path: '/', - handler: function (request, h) { + server.views({ + engines: { + html: require('handlebars'), + }, + relativeTo: __dirname, + path: 'templates', + helpersPath: 'helpers', + }); - return h.view('index'); - } - }); + server.route({ + method: 'GET', + path: '/', + handler: function (request, h) { + return h.view('index'); + }, + }); }; start(); @@ -268,9 +269,9 @@ vision 对于视图布局有一些内建的支持,这个功能默认是关闭 ```javascript server.views({ - // ... - layout: true, - layoutPath: 'templates/layout' + // ... + layout: true, + layoutPath: 'templates/layout', }); ``` @@ -281,8 +282,8 @@ server.views({ ```html - {{{content}}} - + {{{content}}} + ``` @@ -292,14 +293,14 @@ server.views({
    Content
    ``` -当渲染这个视图时 `{{{content}}}` 将会被视图中的内容替换。 +当渲染这个视图时 `{{{content}}}` 将会被视图中的内容替换。 你可以通过全局配置来修改这个默认布局: ```javascript server.views({ - // ... - layout: 'another_default' + // ... + layout: 'another_default', }); ``` diff --git a/env.d.ts b/env.d.ts new file mode 100644 index 00000000..cfab8ba8 --- /dev/null +++ b/env.d.ts @@ -0,0 +1,13 @@ +declare module '*.vue' { + import type { DefineComponent } from 'vue'; + // oxlint-disable-next-line typescript/ban-types + const component: DefineComponent<{}, {}, any>; + export default component; +} + +declare module '*?raw' { + const content: string; + export default content; +} + +declare module '*.css' {} diff --git a/generated/markdown/accept/6/api.md b/generated/markdown/accept/6/api.md new file mode 100644 index 00000000..4115ef38 --- /dev/null +++ b/generated/markdown/accept/6/api.md @@ -0,0 +1,148 @@ +## Introduction + +Accept helps to answer the question of how best to respond to a HTTP request, based on the requesting browser's capabilities. Accept will parse the headers of a HTTP request and tell you what the preferred encoding is, what language should be used, and what charsets and media types are accepted. + +Additional details about Accept headers and content negotiation can be found in [IETF RFC 7231, Section 5.3](https://tools.ietf.org/html/rfc7231#section-5.3). + +## Methods + +### `charset(charsetHeader, [preferences])` + +Given a string of acceptable charsets from a HTTP request Accept-Charset header, and an optional array of charset preferences, it will return a string indicating the best charset option that can be used in the HTTP response. This takes into account any weighting parameters given in the header for ordering and exclusion. + +``` +const charset = Accept.charsets("iso-8859-5, unicode-1-1;q=0.8"); // charset === "iso-8859-5" +const charset = Accept.charsets("iso-8859-5, unicode-1-1;q=0.8", ["unicode-1-1"]); // charset === "unicode-1-1" +``` + +### `charsets(charsetHeader)` + +Given a string of acceptable charsets from a HTTP request Accept-Charset header it will return an array of strings indicating the possible charset options that can be used in the HTTP response, in order from most preferred to least as determined by the [q weightings](#weightings) + +``` +const charsets = Accept.charsets("iso-8859-5, unicode-1-1;q=0.8"); // charsets === ["iso-8859-5", "unicode-1-1"] +const charsets = Accept.charsets("iso-8859-5;q=0.5, unicode-1-1;q=0.8"); // charsets === ["unicode-1-1", "iso-8859-5"] +``` + +### `encoding(encodingHeader, [preferences])` + +Given a string of acceptable encodings from a HTTP request Accept-Encoding header, and optionally an array of preferences, it will return a string with the best fit encoding that should be used in the HTTP response. If no preferences array parameter is given the highest weighted or first ordered encoding is returned. If weightings are given in the header (using the q parameter) they are taken into account and the highest weighted match is returned. If a preferences array is given the best match from the array is returned. For more information about how the preferences array works see the section below on [Preferences](#preferences). + +``` +const encoding = Accept.encoding("gzip, deflate, sdch"); // encoding === "gzip" +const encoding = Accept.encoding("gzip, deflate, sdch", ["deflate", "identity"]); // encoding === "delate" +``` + +### `encodings(encodingHeader)` + +Given a string of acceptable encodings from a HTTP request Accept-Encoding header it will return an array of strings indicating the possible encoding options that can be used in the HTTP response, in order from most preferred to least as determined by the [q weightings](#weightings) + +``` +const encodings = Accept.encodings("compress;q=0.5, gzip;q=1.0"); // encodings === ["gzip", "compress", "identity"] +``` + +### `language(languageHeader, [preferences])` + +Given a string of acceptable language ranges from a HTTP request Accept-Language header, and an optional array of language-tag preferences, it will return a string indicating the best language that can be used in the HTTP response. It respects the [q weightings](#weightings) of the languages in the header, returning the matched preference with the highest weighting. The case of the preference does not have to match the case of the option in the header. + +If preferences is missing or an empty array, the highest weighted language is returned. If no preference matches, an empty string is returned. + +``` +const language = Accept.language("en;q=0.7, en-GB;q=0.8"); // language === "en-gb" + +// the case of the preference "en-gb" does not match the case of the header option "en-GB" +const language = Accept.language("en;q=0.7, en-GB;q=0.8", ["en-gb"]); // language === "en-gb" +``` + +### `languages(languageHeader)` + +Given a string of acceptable languages from a HTTP request Accept-Language header it will return an array of strings indicating the possible languages that can be used in the HTTP response, in order from most preferred to least as determined by the [q weightings](#weightings). + +``` +const languages = Accept.languages("da, en;q=0.7, en-GB;q=0.8"); // languages === ["da", "en-gb", "en"] +``` + +### `mediaType(mediaTypeHeader, [preferences])` + +Given a string of acceptable media types from a HTTP request Accept header, and optionally an array of preferences, it will return a string with the best fit media type that should be used in the HTTP response. If no preferences array parameter is given the highest weighted or first ordered media type is returned. If weightings are given in the header (using the q parameter) they are taken into account and the highest weighted match is returned. If a preferences array is given the best match from the array is returned. For more information about how the preferences array works see the section below on [Preferences](#preferences). + +``` +const mediaType = Accept.mediaType("text/plain, application/json;q=0.5, text/html, */*;q=0.1"); +// mediaType === "text/plain" + +const mediaType = Accept.mediaType("text/plain, application/json;q=0.5, text/html, */*;q=0.1", ["text/html", "application/json"]); +// mediaType === "text/html" +``` + +### `mediaTypes(mediaTypeHeader)` + +Given a string of acceptable media types from a HTTP request Accept header it will return an array of strings indicating the possible media types that can be used in the HTTP response, in order from most preferred to least as determined by the [q weightings](#weightings). + +``` +const mediaTypes = Accept.mediaTypes("text/plain, application/json;q=0.5, text/html, */*;q=0.1"); +// mediaTypes === ["text/plain", "text/html", "application/json", "*/*"] +``` + +### `parseAll(headers)` + +Given the headers from a Hapi request object, `parseAll()` will parse all of the Accepts-\* headers it currently understands into an object. + +``` +const all = Accept.parseAll(request.headers); +// all === { +// "charsets": ["iso-8859-5", "unicode-1-1"], +// "encodings": ["gzip", "compress", "identity"], +// "languages": ["da", "en-gb", "en"], +// "mediaTypes": ["text/plain", "text/html", "application/json", "*/*"] +// } +``` + +## Q Weightings + +The Accept-\* headers may optionally include preferential weighting to indicate which options are best for the requester. It does this with `q` parameters in the headers (which stands for quality). These q weightings must be in the range of 0 to 1, with a max of three decimal places. The weightings are used to order the data given in the header, with the highest number being most preferential. Anything with a q rating of 0 is not allowed at all. + +If a particular Accept method allows a `preferences` array parameter, such as `encoding()`, the weightings in the header affect which preference will be returned. Your preferences are matched with the weighting in mind, and the highest weighted option will be returned, no matter what order you list your preferences. The header weighting is most important. + +``` +const encoding = Accept.encoding("gzip;q=1.0, identity;q=0.5", ["identity", "gzip"]); +// encoding === "gzip" +// despite identity getting listed first in the preferences array, gzip has a higher q weighting, so it is returned. +``` + +## Encodings + +### Preferences + +If you are looking for a set of specific encodings you can pass that in as an array to the `preferences` parameter. Your preferences **must** be an array. In the preferences array you specify a list of possible encodings you want to look for, in order of preference. Accept will return back the most preferential option it can find, if any match. The preferences array does not support parameters, only base types. + +``` +const encoding = Accept.encoding("gzip, deflate, sdch", ["deflate", "identity"]); // encoding === "delate" +``` + +Your preferences are evaluated without any case sensitivity, to better match what the browser sends. This means that "gZip" will match a preference of ["gzip"]. + +``` +const encoding = Accept.encoding("gZip, deflate, sdch", ["gzip"]); // encoding === "gzip" +``` + +If you supply a preferences array, and no match is found, `encoding()` will return an empty string, rather than an encoding from the header. + +``` +const encoding = Accept.encoding("gZip", ["deflate"]); // encoding === "" +``` + +If the encoding header is the special "\*" that indicates the browser will accept any encoding. In that case the top preference from your supplied options will be returned. + +``` +const encoding = Accept.encoding("*", ["gzip"]); // encoding === "gzip" +``` + +### Identity + +When you ask Accept for a list of all the supported encodings from the request, using the `encodings()` function (plural, not singular), you will be returned an array of strings in order from most preferred to least as determined by the encoding weight. + +``` +const encodings = Accept.encodings("compress;q=0.5, gzip;q=1.0"); // encodings === ["gzip", "compress", "identity"] +``` + +You'll notice that `identity` was returned in the array, even though it's not in the encoding header. Identity is always an option for encoding, unless specifically excluded in the header using a weighting of zero. Identity just means respond with no special encoding. diff --git a/generated/markdown/accept/changelog.md b/generated/markdown/accept/changelog.md new file mode 100644 index 00000000..2542483a --- /dev/null +++ b/generated/markdown/accept/changelog.md @@ -0,0 +1,135 @@ +## Version 6 {#v6} + +### [6.0.3](https://github.com/hapijs/accept/milestone/33) {#6.0.3} + +- [#73](https://github.com/hapijs/accept/pull/73) allow readonly arrays to be used as preferences + +### [6.0.2](https://github.com/hapijs/accept/milestone/32) {#6.0.2} + +- [#72](https://github.com/hapijs/accept/pull/72) update typing of mediaTypes to match actual implementation + +### [6.0.1](https://github.com/hapijs/accept/milestone/31) {#6.0.1} + +- [#71](https://github.com/hapijs/accept/pull/71) chore: bump hoek + +### [6.0.0](https://github.com/hapijs/accept/milestone/30) {#6.0.0} + +- [#70](https://github.com/hapijs/accept/pull/70) Support node v18 and drop node v12 + +## Version 5 {#v5} + +### [5.0.2](https://github.com/hapijs/accept/milestone/28) {#5.0.2} + +- [#65](https://github.com/hapijs/accept/pull/65) Enable prefix matching for language tags +- [#63](https://github.com/hapijs/accept/issues/63) Accept.language does not match more specific language tag +- [#59](https://github.com/hapijs/accept/pull/59) update lab and typescript now needs to be added as a devdependency + +### [5.0.1](https://github.com/hapijs/accept/milestone/26) {#5.0.1} + +- [#53](https://github.com/hapijs/accept/issues/53) Use maps + +### [5.0.0](https://github.com/hapijs/accept/milestone/25) {#5.0.0} + +- [#51](https://github.com/hapijs/accept/issues/51) Only node 12 + +## Version 4 {#v4} + +### [4.0.1](https://github.com/hapijs/accept/milestone/24) {#4.0.1} + +- [#54](https://github.com/hapijs/accept/issues/54) Backport #53 + +### [4.0.0](https://github.com/hapijs/accept/milestone/23) {#4.0.0} + +- [#48](https://github.com/hapijs/accept/issues/48) Drop node 8 +- [#47](https://github.com/hapijs/accept/issues/47) Add types + +## Version 3 {#v3} + +### [3.2.4](https://github.com/hapijs/accept/milestone/22) {#3.2.4} + +- [#55](https://github.com/hapijs/accept/issues/55) Backport #53 + +### [3.2.3](https://github.com/hapijs/accept/milestone/21) {#3.2.3} + +- [#42](https://github.com/hapijs/accept/issues/42) Update deps + +### [3.2.2](https://github.com/hapijs/accept/milestone/20) {#3.2.2} + +- [#41](https://github.com/hapijs/accept/issues/41) Missing bias for server preferences among equal q values + +### [3.2.1](https://github.com/hapijs/accept/milestone/19) {#3.2.1} + +- [#40](https://github.com/hapijs/accept/issues/40) Update deps + +### [3.2.0](https://github.com/hapijs/accept/milestone/14) {#3.2.0} + +- [#39](https://github.com/hapijs/accept/issues/39) Change module namespace +- [#34](https://github.com/hapijs/accept/issues/34) headerType() '\*' logic is incorrect. + +### [3.1.3](https://github.com/hapijs/accept/milestone/13) {#3.1.3} + +- [#32](https://github.com/hapijs/accept/issues/32) Remove engines + +### [3.1.2](https://github.com/hapijs/accept/milestone/12) {#3.1.2} + +- [#31](https://github.com/hapijs/accept/issues/31) Update hoek v6 + +### [3.1.1](https://github.com/hapijs/accept/milestone/11) {#3.1.1} + +- [#30](https://github.com/hapijs/accept/issues/30) Fix node 11 sort + +### [3.1.0](https://github.com/hapijs/accept/milestone/10) {#3.1.0} + +- [#28](https://github.com/hapijs/accept/pull/28) add mediaType method + +### [3.0.2](https://github.com/hapijs/accept/milestone/9) {#3.0.2} + +- [#22](https://github.com/hapijs/accept/issues/22) Update boom + +### [3.0.1](https://github.com/hapijs/accept/milestone/8) {#3.0.1} + +- [#21](https://github.com/hapijs/accept/issues/21) Update deps + +### [3.0.0](https://github.com/hapijs/accept/milestone/7) {#3.0.0} + +- [#20](https://github.com/hapijs/accept/issues/20) Throw all errors + +## Version 2 {#v2} + +### [2.2.2](https://github.com/hapijs/accept/milestone/17) {#2.2.2} + +- [#38](https://github.com/hapijs/accept/issues/38) Node 11 (language) + +### [2.2.1](https://github.com/hapijs/accept/milestone/16) {#2.2.1} + +- [#37](https://github.com/hapijs/accept/issues/37) Fix node 11 + +### [2.2.0](https://github.com/hapijs/accept/milestone/15) {#2.2.0} + +- [#36](https://github.com/hapijs/accept/issues/36) Commercial version of v2 branch + +### [2.1.4](https://github.com/hapijs/accept/milestone/6) {#2.1.4} + +- [#18](https://github.com/hapijs/accept/issues/18) Update deps. + +### [2.1.2](https://github.com/hapijs/accept/milestone/5) {#2.1.2} + +- [#17](https://github.com/hapijs/accept/issues/17) Update lab + +### [2.1.0](https://github.com/hapijs/accept/milestone/4) {#2.1.0} + +- [#14](https://github.com/hapijs/accept/pull/14) Mediatypes + +### [2.0.0](https://github.com/hapijs/accept/milestone/2) {#2.0.0} + +- [#15](https://github.com/hapijs/accept/issues/15) ES6 style changes and node v4 +- [#13](https://github.com/hapijs/accept/issues/13) Update docs to use API.md +- [#11](https://github.com/hapijs/accept/pull/11) add language() and languages() + +## Version 1 {#v1} + +### [1.1.0](https://github.com/hapijs/accept/milestone/1) {#1.1.0} + +- [#9](https://github.com/hapijs/accept/pull/9) Charset +- [#2](https://github.com/hapijs/accept/pull/2) Update to Lab 5.x.x and Code 1.x.x +- [#1](https://github.com/hapijs/accept/pull/1) Update .travis.yml diff --git a/generated/markdown/ammo/6/api.md b/generated/markdown/ammo/6/api.md new file mode 100644 index 00000000..d40bf80f --- /dev/null +++ b/generated/markdown/ammo/6/api.md @@ -0,0 +1,35 @@ +## Usage + +```js +// basic usage +const range = Ammo.header('bytes=1-5', 10); +// range --> [{ from: 1, to: 5 }] + +// multiple ranges +const range = Ammo.header('bytes=1-5,7-10', 10); +// range --> [{ from: 1, to: 5 }, { from: 7, to: 9 }] + +// streams (get range within a `source`) +const range = Ammo.header('bytes=1000-4000', 5000); +const stream = new Ammo.Stream(range[0]); +const buffer = await Wreck.read(source.pipe(stream)); + +// buffer is the portion of source within range +``` + +## Methods + +### `header(header, length)` + +Parses the range from a HTTP header, where: + +- `header` - A string in the form of `bytes=from-to`, where `from` and `to` are integers specifying the range. Both are optional. Multiple ranges can be passed as a comma delimited list. +- `length` - A positive integer specifying the maximum length the range can cover. If a `to` value passed in the `header` string is greater than `length`, the `to` value is set as `length - 1`. + +Returns an array of objects with the properties `from` and `to`, which specify the beginning and ending of the range. Overlapping ranges are combined into one object. Returns `null` for invalid input. + +### `new Ammo.Stream(range)` + +Creates a [`Transform Stream`](https://nodejs.org/api/stream.html) that extracts the portion of a piped in stream within `range`, where: + +- `range` - an object with the properties `from` and `to` that specify the range of the piped in stream to read. Objects returned by `Ammo.header` can be passed into `range`. diff --git a/generated/markdown/ammo/changelog.md b/generated/markdown/ammo/changelog.md new file mode 100644 index 00000000..95cf17c2 --- /dev/null +++ b/generated/markdown/ammo/changelog.md @@ -0,0 +1,98 @@ +## Version 6 {#v6} + +### [6.0.1](https://github.com/hapijs/ammo/milestone/22) {#6.0.1} + +- [#54](https://github.com/hapijs/ammo/pull/54) chore: bump hoek + +### [6.0.0](https://github.com/hapijs/ammo/milestone/21) {#6.0.0} + +- [#53](https://github.com/hapijs/ammo/pull/53) Support node v18 and drop node v12 + +## Version 5 {#v5} + +### [5.0.1](https://github.com/hapijs/ammo/milestone/19) {#5.0.1} + +- [#37](https://github.com/hapijs/ammo/issues/37) Strict parsing + +### [5.0.0](https://github.com/hapijs/ammo/milestone/18) {#5.0.0} + +- [#35](https://github.com/hapijs/ammo/issues/35) Only node 12 + +## Version 4 {#v4} + +### [4.0.1](https://github.com/hapijs/ammo/milestone/17) {#4.0.1} + +- [#38](https://github.com/hapijs/ammo/issues/38) Backport #37 + +### [4.0.0](https://github.com/hapijs/ammo/milestone/16) {#4.0.0} + +- [#32](https://github.com/hapijs/ammo/issues/32) Add types +- [#31](https://github.com/hapijs/ammo/issues/31) Drop node 8 +- [#16](https://github.com/hapijs/ammo/issues/16) Stream early exit + +## Version 3 {#v3} + +### [3.1.2](https://github.com/hapijs/ammo/milestone/15) {#3.1.2} + +- [#39](https://github.com/hapijs/ammo/issues/39) Backport #37 + +### [3.1.1](https://github.com/hapijs/ammo/milestone/14) {#3.1.1} + +- [#25](https://github.com/hapijs/ammo/issues/25) Update deps + +### [3.1.0](https://github.com/hapijs/ammo/milestone/11) {#3.1.0} + +- [#23](https://github.com/hapijs/ammo/issues/23) Change module namespace + +### [3.0.3](https://github.com/hapijs/ammo/milestone/10) {#3.0.3} + +- [#20](https://github.com/hapijs/ammo/issues/20) Remove engines + +### [3.0.2](https://github.com/hapijs/ammo/milestone/9) {#3.0.2} + +- [#19](https://github.com/hapijs/ammo/issues/19) Update hoek v6 + +### [3.0.1](https://github.com/hapijs/ammo/milestone/8) {#3.0.1} + +- [#18](https://github.com/hapijs/ammo/pull/18) Improve error handling + +### [3.0.0](https://github.com/hapijs/ammo/milestone/7) {#3.0.0} + +- [#17](https://github.com/hapijs/ammo/issues/17) Node 8 + +## Version 2 {#v2} + +### [2.1.1](https://github.com/hapijs/ammo/milestone/13) {#2.1.1} + +- [#40](https://github.com/hapijs/ammo/issues/40) Backport #37 + +### [2.1.0](https://github.com/hapijs/ammo/milestone/12) {#2.1.0} + +- [#22](https://github.com/hapijs/ammo/issues/22) Commercial version of v2 branch + +### [2.0.4](https://github.com/hapijs/ammo/milestone/6) {#2.0.4} + +- [#15](https://github.com/hapijs/ammo/issues/15) Update deps. + +### [2.0.3](https://github.com/hapijs/ammo/milestone/5) {#2.0.3} + +- [#14](https://github.com/hapijs/ammo/issues/14) Update deps +- [#10](https://github.com/hapijs/ammo/pull/10) dependency update + +### [2.0.2](https://github.com/hapijs/ammo/milestone/4) {#2.0.2} + +- [#8](https://github.com/hapijs/ammo/issues/8) Update deps + +### [2.0.1](https://github.com/hapijs/ammo/milestone/3) {#2.0.1} + +- [#6](https://github.com/hapijs/ammo/pull/6) Test on node v6, update dependencies + +### [2.0.0](https://github.com/hapijs/ammo/milestone/2) {#2.0.0} + +- [#4](https://github.com/hapijs/ammo/issues/4) ES6 style changes and node v4 + +## Version 1 {#v1} + +### [1.0.1](https://github.com/hapijs/ammo/milestone/1) {#1.0.1} + +- [#3](https://github.com/hapijs/ammo/issues/3) Apply hapi project style diff --git a/generated/markdown/b64/6/api.md b/generated/markdown/b64/6/api.md new file mode 100644 index 00000000..7403a3da --- /dev/null +++ b/generated/markdown/b64/6/api.md @@ -0,0 +1,51 @@ +### encode(buffer) + +Base64 encode the buffer and return it as a new Buffer. + +### decode(buffer) + +Base64 decode the buffer and return the result as a new buffer. + +### Encoder + +Transform stream that base64 encodes each chunk of the stream. + +Example: + +```js +'use strict'; + +const Fs = require('fs'); +const B64 = require('@hapi/b64'); + +const stream = Fs.createReadStream(`${__dirname}/package.json`); +const encoder = new B64.Encoder(); + +stream.pipe(encoder).pipe(process.stdout); +``` + +### Decoder + +Transform stream that base64 decodes each chunk of the stream. + +Example: + +```js +'use strict'; + +const Fs = require('fs'); +const B64 = require('@hapi/b64'); + +const stream = Fs.createReadStream(`${__dirname}/encodedfile.b64`); +const decoder = new B64.Decoder(); + +stream.pipe(decoder).pipe(process.stdout); +``` + +### base64urlEncode(value) + +Encodes value of string or buffer type in Base64 or URL encoding, function will assert input value is correct. + +### base64urlDecode(value) + +Decodes string into Base64 or URL encoding, function throws an error on invalid input and returns a string or buffer depending on encoding provided. Default encoding is binary. diff --git a/generated/markdown/b64/changelog.md b/generated/markdown/b64/changelog.md new file mode 100644 index 00000000..232ed566 --- /dev/null +++ b/generated/markdown/b64/changelog.md @@ -0,0 +1,81 @@ +## Version 6 {#v6} + +### [6.0.1](https://github.com/hapijs/b64/milestone/18) {#6.0.1} + +- [#41](https://github.com/hapijs/b64/pull/41) chore: bump hoek + +### [6.0.0](https://github.com/hapijs/b64/milestone/17) {#6.0.0} + +- [#40](https://github.com/hapijs/b64/pull/40) Support node v18 and drop node v12 + +## Version 5 {#v5} + +### [5.0.0](https://github.com/hapijs/b64/milestone/15) {#5.0.0} + +- [#33](https://github.com/hapijs/b64/issues/33) Only node 12 + +## Version 4 {#v4} + +### [4.2.2](https://github.com/hapijs/b64/milestone/14) {#4.2.2} + +### [4.2.1](https://github.com/hapijs/b64/milestone/13) {#4.2.1} + +- [#26](https://github.com/hapijs/b64/issues/26) Update deps + +### [4.2.0](https://github.com/hapijs/b64/milestone/10) {#4.2.0} + +- [#25](https://github.com/hapijs/b64/issues/25) Change module namespace + +### [4.1.2](https://github.com/hapijs/b64/milestone/9) {#4.1.2} + +- [#22](https://github.com/hapijs/b64/issues/22) Remove engines + +### [4.1.1](https://github.com/hapijs/b64/milestone/8) {#4.1.1} + +- [#21](https://github.com/hapijs/b64/issues/21) Update hoek v6 + +### [4.1.0](https://github.com/hapijs/b64/milestone/7) {#4.1.0} + +- [#20](https://github.com/hapijs/b64/issues/20) Move base64 methods from hoek + +### [4.0.0](https://github.com/hapijs/b64/milestone/6) {#4.0.0} + +- [#18](https://github.com/hapijs/b64/issues/18) Node 8 + +## Version 3 {#v3} + +### [3.1.1](https://github.com/hapijs/b64/milestone/12) {#3.1.1} + +### [3.1.0](https://github.com/hapijs/b64/milestone/11) {#3.1.0} + +- [#24](https://github.com/hapijs/b64/issues/24) Commercial version of v3 branch + +### [3.0.3](https://github.com/hapijs/b64/milestone/5) {#3.0.3} + +- [#17](https://github.com/hapijs/b64/issues/17) 3.0.3 Release notes +- [#16](https://github.com/hapijs/b64/pull/16) Remove deprecated buffer usage +- [#15](https://github.com/hapijs/b64/issues/15) Pending deprecation for new Buffer() + +### [3.0.2](https://github.com/hapijs/b64/milestone/4) {#3.0.2} + +- [#14](https://github.com/hapijs/b64/issues/14) Update deps +- [#13](https://github.com/hapijs/b64/pull/13) Document API +- [#12](https://github.com/hapijs/b64/pull/12) Separate decode/encode modules +- [#10](https://github.com/hapijs/b64/issues/10) Document API + +### [3.0.1](https://github.com/hapijs/b64/milestone/3) {#3.0.1} + +- [#11](https://github.com/hapijs/b64/pull/11) update hoek to 4.x.x +- [#9](https://github.com/hapijs/b64/pull/9) Update lab and travis node version + +### [3.0.0](https://github.com/hapijs/b64/milestone/2) {#3.0.0} + +- [#8](https://github.com/hapijs/b64/pull/8) es6. Closes #7 +- [#7](https://github.com/hapijs/b64/issues/7) ES6 style, node v4 + +## Version 2 {#v2} + +### [2.0.1](https://github.com/hapijs/b64/milestone/1) {#2.0.1} + +- [#5](https://github.com/hapijs/b64/pull/5) Update to Lab 5.x.x and Code 1.x.x +- [#4](https://github.com/hapijs/b64/pull/4) Update .travis.yml diff --git a/generated/markdown/basic/7/api.md b/generated/markdown/basic/7/api.md new file mode 100644 index 00000000..3b45a364 --- /dev/null +++ b/generated/markdown/basic/7/api.md @@ -0,0 +1,75 @@ +## Usage + +Basic authentication requires validating a username and password combination. The `'basic'` scheme takes the following options: + +- `validate` - (required) a user lookup and password validation function with the signature `[async] function(request, username, password, h)` where: + - `request` - is the hapi request object of the request which is being authenticated. + - `username` - the username received from the client. + - `password` - the password received from the client. + - `h` - the response toolkit. + - Returns an object `{ isValid, credentials, response }` where: + - `isValid` - `true` if both the username was found and the password matched, otherwise `false`. + - `credentials` - a credentials object passed back to the application in `request.auth.credentials`. + - `response` - Optional. If provided will be used immediately as a takeover response. Can be used to redirect the client, for example. Don't need to provide `isValid` or `credentials` if `response` is provided + - Throwing an error from this function will replace default `Boom.unauthorized` error + - Typically, `credentials` are only included when `isValid` is `true`, but there are cases when the application needs to know who tried to authenticate even when it fails (e.g. with authentication mode `'try'`). +- `allowEmptyUsername` - (optional) if `true`, allows making requests with an empty username. Defaults to `false`. +- `unauthorizedAttributes` - (optional) if set, passed directly to [Boom.unauthorized](https://github.com/hapijs/boom#boomunauthorizedmessage-scheme-attributes) if no custom `err` is thrown. Useful for setting realm attribute in WWW-Authenticate header. Defaults to `undefined`. + +```javascript +const Bcrypt = require('bcrypt'); +const Hapi = require('@hapi/hapi'); + +const users = { + john: { + username: 'john', + password: '$2a$10$iqJSHD.BGr0E2IxQwYgJmeP3NvhPrXAeLSaGCj6IR/XU5QtjVu5Tm', // 'secret' + name: 'John Doe', + id: '2133d32a', + }, +}; + +const validate = async (request, username, password, h) => { + if (username === 'help') { + return { response: h.redirect('https://hapijs.com/help') }; // custom response + } + + const user = users[username]; + if (!user) { + return { credentials: null, isValid: false }; + } + + const isValid = await Bcrypt.compare(password, user.password); + const credentials = { id: user.id, name: user.name }; + + return { isValid, credentials }; +}; + +const main = async () => { + const server = Hapi.server({ port: 4000 }); + + await server.register(require('@hapi/basic')); + + server.auth.strategy('simple', 'basic', { validate }); + server.auth.default('simple'); + + server.route({ + method: 'GET', + path: '/', + handler: function (request, h) { + return 'welcome'; + }, + }); + + await server.start(); + + return server; +}; + +main() + .then((server) => console.log(`Server listening on ${server.info.uri}`)) + .catch((err) => { + console.error(err); + process.exit(1); + }); +``` diff --git a/generated/markdown/basic/changelog.md b/generated/markdown/basic/changelog.md new file mode 100644 index 00000000..84965f54 --- /dev/null +++ b/generated/markdown/basic/changelog.md @@ -0,0 +1,87 @@ +## Version 7 {#v7} + +### [7.0.1](https://github.com/hapijs/basic/milestone/19) {#7.0.1} + +- [#91](https://github.com/hapijs/basic/pull/91) chore: bump hoek + +### [7.0.0](https://github.com/hapijs/basic/milestone/18) {#7.0.0} + +- [#90](https://github.com/hapijs/basic/pull/90) Support node v18 and hapi v21, drop node v12 and hapi v18/19 +- [#83](https://github.com/hapijs/basic/pull/83) upgrade lab to v24 + +## Version 6 {#v6} + +### [6.0.0](https://github.com/hapijs/basic/milestone/17) {#6.0.0} + +- [#78](https://github.com/hapijs/basic/issues/78) Change plugin name to @hapi/basic +- [#77](https://github.com/hapijs/basic/issues/77) Drop hapi 17 +- [#76](https://github.com/hapijs/basic/issues/76) Only support node 12 + +## Version 5 {#v5} + +### [5.1.1](https://github.com/hapijs/basic/milestone/15) {#5.1.1} + +- [#70](https://github.com/hapijs/basic/issues/70) Update deps + +### [5.1.0](https://github.com/hapijs/basic/milestone/14) {#5.1.0} + +- [#69](https://github.com/hapijs/basic/issues/69) Change module namespace + +### [5.0.0](https://github.com/hapijs/basic/milestone/13) {#5.0.0} + +- [#61](https://github.com/hapijs/basic/pull/61) Update for hapi 17.x.x + +## Version 4 {#v4} + +### [4.2.0](https://github.com/hapijs/basic/milestone/12) {#4.2.0} + +- [#51](https://github.com/hapijs/basic/pull/51) Test on node v6, update dependencies +- [#48](https://github.com/hapijs/basic/pull/48) Documentation update + +### [4.1.0](https://github.com/hapijs/basic/milestone/11) {#4.1.0} + +- [#46](https://github.com/hapijs/basic/pull/46) add option to pass attributes to unauthorized replies + +### [4.0.0](https://github.com/hapijs/basic/milestone/10) {#4.0.0} + +- [#44](https://github.com/hapijs/basic/pull/44) Node 4+, Hapi 10+, ES6 changes. Closes #42 +- [#42](https://github.com/hapijs/basic/issues/42) Node >= 4 / es2015 updates +- [#41](https://github.com/hapijs/basic/pull/41) Update devDependencies. Closes #40 + +## Version 3 {#v3} + +### [3.0.0](https://github.com/hapijs/basic/milestone/8) {#3.0.0} + +- [#34](https://github.com/hapijs/basic/pull/34) Added request object as the first argument in validateFunc + +## Version 2 {#v2} + +### [2.0.0](https://github.com/hapijs/basic/milestone/7) {#2.0.0} + +- [#22](https://github.com/hapijs/basic/issues/22) hapi 8.0 API + +## Version 1 {#v1} + +### [1.1.2](https://github.com/hapijs/basic/milestone/6) {#1.1.2} + +- [#21](https://github.com/hapijs/basic/pull/21) Update dev deps. Closes #20 +- [#20](https://github.com/hapijs/basic/issues/20) Test deps + +### [1.1.1](https://github.com/hapijs/basic/milestone/5) {#1.1.1} + +- [#11](https://github.com/hapijs/basic/issues/11) Authentication fails when password contains one or more colons +- [#10](https://github.com/hapijs/basic/pull/10) issue passing errors to validateFunc + +### [1.1.0](https://github.com/hapijs/basic/milestone/4) {#1.1.0} + +- [#7](https://github.com/hapijs/basic/pull/7) Updated to Hapi 6.0 +- [#6](https://github.com/hapijs/basic/issues/6) Prepare for hapi v6.0 + +### [1.0.2](https://github.com/hapijs/basic/milestone/2) {#1.0.2} + +- [#5](https://github.com/hapijs/basic/issues/5) Bring coverage back to 100% + +### [1.0.1](https://github.com/hapijs/basic/milestone/1) {#1.0.1} + +- [#2](https://github.com/hapijs/basic/pull/2) update peerDependency +- [#1](https://github.com/hapijs/basic/issues/1) change hapi peer dependency to 3.0.0 diff --git a/generated/markdown/bell/13/api.md b/generated/markdown/bell/13/api.md new file mode 100644 index 00000000..38909141 --- /dev/null +++ b/generated/markdown/bell/13/api.md @@ -0,0 +1,403 @@ +### Introduction + +**bell** ships with built-in support for authentication using `ArcGIS Online`, `Auth0`, `AzureAD`, +`BitBucket`, `Cognito`, `DigitalOcean`, `Discord`, `Dropbox`, `Facebook`, `Fitbit`, `Foursquare`, +`GitHub`, `GitLab`, `Google Plus`, `Google`, `Instagram`, `LinkedIn`, `Medium`, `Meetup`, +`Nest`, `Office365`, `Okta`, `Phabricator`, `Pingfed`, `Pinterest`, `Reddit`, `Salesforce`, `Slack`, +`Spotify`, `Stripe`, `trakt.tv`, `Tumblr`, `Twitch`, `Twitter`, `VK`, `Wordpress`, `Windows Live`, +and `Yahoo`. + +It also supports any compliant `OAuth 1.0a` and `OAuth 2.0` based login services with a simple +configuration object. + +[**Providers Documentation**](https://hapi.dev/family/bell/providers) + +### Tutorials + +[**Social Login with Twitter using hapi.js**](http://mph-web.de/social-signup-with-twitter-using-hapi-js/) + +### Examples + +[**All Examples**](https://github.com/hapijs/bell/tree/master/examples) + +Twitter: + +```js +// Load modules + +const Bell = require('@hapi/bell'); +const Hapi = require('@hapi/hapi'); + +// Declare internals + +const internals = {}; + +internals.start = async function () { + const server = Hapi.server({ port: 8000 }); + + // Register bell with the server + + await server.register(Bell); + + // Declare an authentication strategy using the bell scheme + // with the name of the provider, cookie encryption password, + // and the OAuth client credentials. + + server.auth.strategy('twitter', 'bell', { + provider: 'twitter', + password: 'cookie_encryption_password_secure', + clientId: 'my_twitter_client_id', + clientSecret: 'my_twitter_client_secret', + isSecure: false, // Terrible idea but required if not using HTTPS especially if developing locally + }); + + // Use the 'twitter' authentication strategy to protect the + // endpoint handling the incoming authentication credentials. + // This endpoint usually looks up the third party account in + // the database and sets some application state (cookie) with + // the local application account information. + + server.route({ + method: ['GET', 'POST'], // Must handle both GET and POST + path: '/login', // The callback endpoint registered with the provider + options: { + auth: { + mode: 'try', + strategy: 'twitter', + }, + handler: function (request, h) { + if (!request.auth.isAuthenticated) { + return `Authentication failed due to: ${request.auth.error.message}`; + } + + // Perform any account lookup or registration, setup local session, + // and redirect to the application. The third-party credentials are + // stored in request.auth.credentials. Any query parameters from + // the initial request are passed back via request.auth.credentials.query. + + return h.redirect('/home'); + }, + }, + }); + + await server.start(); +}; + +internals.start(); +``` + +### Notes + +Testing third-party authorization is often a painful process. They are hard to test, tidious to configure, and tend to break when running on local servers. If you are having issues running **bell** locally, you might want to look at the `isSecure` and `isSameSite` options. Since most people don't run TLS on their local test server, `isSecure` must be set to `false` to remove the TLS requirement. `isSameSite` might need to be set to `'Lax'` in some cases. + +You should also review the default scope set for each provider early in your implementation. The default scope is meant to get the minimal permissions needed to perform simple user login. In most cases, you would want to ask for more permissions as the default often does not provide access to most API calls provided by the third-party services. + +### Usage + +**bell** works by adding a login endpoint and setting it to use a **bell**-based authentication strategy. **bell** will manage the third-party authentication flow and will only call the handler if the user successfully authenticated. The handler function is then used to examine the third-party credentials (e.g. lookup an existing account or offer a registration page), setup an active session, and redirect to the actual application. + +**bell** does not maintain a session beyond a temporary state between the authorization flow. If a user authenticated once when accessing the endpoint, they will have to authenticate again. This means **bell** cannot be used alone as a login system except for single-page applications that require loading a single resource. Once the handler is called, the application must set its own +session management. A common solution is to combine **bell** with the [**@hapi/cookie**](https://hapi.dev/family/cookie) authentication scheme plugin. + +```js +// Load modules + +const Bell = require('@hapi/bell'); +const Hapi = require('@hapi/hapi'); + +// Declare internals + +const internals = {}; + +internals.start = async function () { + const server = Hapi.server({ port: 8000 }); + + // Register bell with the server + + await server.register(Bell); + + // Declare an authentication strategy using the bell scheme + // with the name of the provider, cookie encryption password, + // and the OAuth client credentials. + + server.auth.strategy('twitter', 'bell', { + provider: 'twitter', + password: 'cookie_encryption_password_secure', + clientId: 'my_twitter_client_id', + clientSecret: 'my_twitter_client_secret', + isSecure: false, // Terrible idea but required if not using HTTPS especially if developing locally + }); + + // Use the 'twitter' authentication strategy to protect the + // endpoint handling the incoming authentication credentials. + // This endpoints usually looks up the third party account in + // the database and sets some application state (cookie) with + // the local application account information. + + server.route({ + method: ['GET', 'POST'], // Must handle both GET and POST + path: '/login', // The callback endpoint registered with the provider + options: { + auth: { + mode: 'try', + strategy: 'twitter', + }, + handler: function (request, h) { + if (!request.auth.isAuthenticated) { + return `Authentication failed due to: ${request.auth.error.message}`; + } + + // Perform any account lookup or registration, setup local session, + // and redirect to the application. The third-party credentials are + // stored in request.auth.credentials. Any query parameters from + // the initial request are passed back via request.auth.credentials.query. + + return h.redirect('/home'); + }, + }, + }); + + await server.start(); +}; + +internals.start(); +``` + +### Options + +The `server.auth.strategy()` method requires the following strategy options: + +- `provider` - the name of the third-party provider (`'auth0'`, `'azure'`, `'bitbucket'`, + `'dropbox'`, `'facebook'`, `'fitbit'`, `'foursquare'`, `'github'`, `'google'`, `'googleplus'`, + `'instagram'`, `'linkedin'`, `'live'`, `'twitter'`, `'vk'`, `'arcgisonline'`, `'yahoo'`, + `'nest'`, `'phabricator'`, `'pinterest'`) or an object containing a custom + provider with the following: + - `name` - the custom provider name. Defaults to `custom`. + - `protocol` - the authorization protocol used. Must be one of: + - `'oauth'` - OAuth 1.0a + - `'oauth2'` - OAuth 2.0 + - `signatureMethod` - the OAuth signature method (OAuth 1.0a only). Must be one of: + - `'HMAC-SHA1'` - default + - `'RSA-SHA1'` - in that case, the `clientSecret` is your RSA private key + - `temporary` - the temporary credentials (request token) endpoint (OAuth 1.0a only). + - `useParamsAuth` - boolean that determines if OAuth client id and client secret will be sent + as parameters as opposed to an Authorization header (OAuth 2.0 only). Defaults to `false`. + - `auth` - the authorization endpoint URI. + - `token` - the access token endpoint URI. + - `scope` - an array of scope strings (OAuth 2.0 only). + - `scopeSeparator` - the scope separator character (OAuth 2.0 only). Only required when a + provider has a broken OAuth 2.0 implementation. Defaults to space (Facebook and GitHub + default to comma). + - `headers` - a headers object with additional headers required by the provider (e.g. GitHub + required the 'User-Agent' header which is set by default). + - `profileMethod` - `get` or `post` for obtaining user profile by `profile` function. Default + is `get`. + - `profile` - a function used to obtain user profile information and normalize it. The function + signature is `async function(credentials, params, get)` where: + - `credentials` - the credentials object. Change the object directly within the function + (profile information is typically stored under `credentials.profile`). + - `params` - the parsed information received from the provider (e.g. token, secret, and + other custom fields). + - `get` - an OAuth helper function to make authenticated requests using the credentials + received. The `get` function signature is `async function(uri, params)` where: + - `uri` - the requested resource URI (**bell** will add the token or authentication + header as needed). + - `params` - any URI query parameters (cannot include them in the URI due to signature + requirements). + - returns the parsed profile response object. + +- `password` - the cookie encryption password. Used to encrypt the temporary state cookie used by + the module in between the authorization protocol steps. +- `clientId` - the OAuth client identifier (consumer key). +- `clientSecret` - the OAuth client secret (consumer secret). This is usually a client password + formatted as a _string_, but to allow [OAuth2 custom client authentication](https://tools.ietf.org/html/rfc6749#section-2.3) + (e.g. client certificate-based authentication), this option can be passed as an _object_. This + object will be merged with the Wreck request object used to call the token endpoint. Such an + object can contain custom HTTP headers or TLS options (e.g. + `{ agent: new Https.Agent({ cert: myClientCert, key: myClientKey}) }`). + To allow dynamically updating secret, this option can be passed as a _function_ returning string + to be used as `clientSecret`. +- `forceHttps` - A boolean indicating whether or not you want the redirect_uri to be forced to + https. Useful if your hapi application runs as http, but is accessed through https. +- `location` - Set the base redirect_uri manually if it cannot be inferred properly from server + settings. Useful to override port, protocol, and host if proxied or forwarded. It may be passed + either as a string (in which case request.path is appended for you), or a function which takes + the client's `request` and returns a non-empty string, which is used as provided. In both cases, + an empty string will result in default processing just as if the `location` option had not been + specified. + +Each strategy accepts the following optional settings: + +- `cookie` - the name of the cookie used to manage the temporary state. Defaults to + `'bell-provider'` where 'provider' is the provider name. For + example, the Twitter cookie name defaults to `'bell-twitter'`. +- `isSameSite` - sets the cookie same site option. Defaults to `Strict`. +- `isSecure` - sets the cookie secure flag. Defaults to `true`. +- `isHttpOnly` - sets the cookie HTTP only flag. Defaults to `true`. +- `ttl` - cookie time-to-live in milliseconds. Defaults to `null` (session time-life - cookies are + deleted when the browser is closed). +- `domain` - the domain scope. Defaults to `null` (no domain). +- `providerParams` - provider-specific query parameters for the authentication endpoint. It may be + passed either as an object to merge into the query string, or a function which takes the client's + `request` and returns an object. Each provider supports its own set of parameters which customize + the user's login experience. For example: + - Facebook supports `display` ('page', 'popup', or 'touch'), `auth_type`, `auth_nonce`. + - Google supports `access_type`, `approval_prompt`, `prompt`, `login_hint`, `user_id`, `hd`. + - Twitter supports `force_login`, `screen_name`. + - Linkedin supports `fields`. +- `allowRuntimeProviderParams` - allows passing query parameters from a **bell** protected endpoint + to the auth request. It will merge the query params you pass along with the providerParams and + any other predefined ones. Be aware that this will override predefined query parameters! Default + to `false`. +- `scope` - Each built-in vendor comes with the required scope for basic profile information. Use + `scope` to specify a different scope as required by your application. It may be passed either as + an object to merge into the query string, or a function which takes the client's `request` and + returns an object. Consult the provider for their specific supported scopes. +- `skipProfile` - skips obtaining a user profile from the provider. Useful if you need specific + `scope`s, but not the user profile. Defaults to `false`. +- `config` - a configuration object used to customize the provider settings: + - Twitter: + - `extendedProfile` + - `getMethod` + - GitHub and Phabricator: + - `uri` - allows pointing to a private enterprise installation (e.g. + `'https://vpn.example.com'`). See [Providers documentation](https://github.com/hapijs/bell/blob/master/Providers.md) for more + information. +- `tokenParams` - provider-specific query parameters for the token endpoint. It may be + passed either as an object to merge into the query string, or a function which takes the client's + `request` and returns an object. Each provider supports its own set of parameters which customize + the user's login experience. +- `profileParams` - an object of key-value pairs that specify additional URL query parameters to + send with the profile request to the provider. The built-in `facebook` provider, for example, + could have `fields` specified to determine the fields returned from the user's graph, which would + then be available to you in the `auth.credentials.profile.raw` object. +- `runtimeStateCallback` - allows passing additional OAuth state from initial request. This must be + a function returning a string, which will be appended to the **bell** internal `state` parameter + for OAuth code flow. + +### Authentication information + +On route handlers, the [authentication object](https://hapi.dev/api/#request.auth) may contain one or more of the following properties depending on your route configuration and whether the authentication process was completed successfully or not: + +#### Always present + +```javascript +auth.credentials = { + provider: String, // provider name +}; +``` + +#### Present on successful authentication + +##### OAuth protocol + +```javascript +auth.credentials = { + token: String, + secret: String, + query: Object, // sign-in request query params +}; +``` + +##### OAuth2 protocol + +```javascript +auth.credentials = { + token: String, + refreshToken: String, + expiresIn: Number, + query: Object, // sign-in request query params +}; + +auth.artifacts = Object; // OAuth token payload response +``` + +##### Present on failed authentication (route.auth.mode=try) + +```javascript +auth.credentials = { + query: Object, // sign-in request query params +}; +``` + +### Advanced Usage + +#### Configuration via Environment Variables + +The `server.auth.strategy()` method supports string representations of its boolean and number typed +options. For example, `forceHttps` can be set to 'true', 'false', 'yes', or 'no'. In effect, this +allows you to configure any strategy option using environment variables. + +#### Handling Errors + +By default, **bell** will reply back with an internal error (500) on most authentication errors due +to the nature of the OAuth protocol. There is little that can be done to recover from errors as +almost all of them are caused by implementation or deployment issues. + +If you would like to display a useful error page instead of the default JSON response, use the +**hapi** [`onPreResponse`](https://hapi.dev/api#error-transformation) extension point to transform +the error into a useful page or to redirect the user to another destination. + +Another way to handle authentication errors is within the route handler. By default, an +authentication error will cause the handler to be skipped. However, if the authentication mode is +set to `'try'` instead of `'required'`, the handler will still be called. In this case, the +`request.auth.isAuthenticated` must be checked to test if authentication failed. In that case, +`request.auth.error` will contain the error. + +#### Token Refresh + +To keep track of the token expiry time, `request.auth.credentials.expiresIn` provides you the +duration (in seconds) after which you could send a refresh token request using the +`request.auth.credentials.refreshToken` to get a new token. + +#### Simulated authentication + +Testing applications using third-party login can be challenging given the lack of user interaction +to perform the third-party login flow as well as the multiple steps required. To assist in testing +such application without having to modify the application with custom code, **Bell** provides an +override method `Bell.simulate()` which puts the module into simulation mode and any strategies +created while it is in this mode will return the simulated credentials. + +The `Bell.simulate(credentialsFunc)` takes a single argument: + +- `credentialsFunc` - a function called for each incoming request to the protected resource that + should return the credentials object to be set in `request.auth.credentials`. Note that **bell** + will set the default keys automatically if not present except for the provider-specific values. + + has the signature `function(request)` where: + - `request` - the **hapi** request object. + +Note that you must call `Bell.simulate()` before the module is registered by your application and +need to call `Bell.simulate(false)` to stop it from simulating authentication. + +### Usage without a strategy + +Sometimes, you want to use bell without using specifying a Hapi strategy. This can be the case when +combining the auth logic together with another module. + +**bell** exposes an oauth object in its plugin. Therefore, `server.plugins.bell.oauth` now has all +that's needed. For example, calling the `v2` method with all the settings documented above, will +handle the oauth2 flow. + +### Customized Scope and Params + +You can pass a function, rather than an object, into the `providerParams` and `scope` config +options to allow you to customize the scope or parameters based on the user's request. For example, +this may be used you want people to be able to log in with a provider (and only need some basic +user information) but also want to let users authorize your application to post messages or status +updates on their behalf. + +```js +server.auth.strategy('twitter', 'bell', { + provider: 'twitter', + password: 'some cookie password', + location: 'http://example.com/oauth', + scope(request) { + const scopes = ['public_profile', 'email']; + if (request.query.wantsSharePermission) { + scopes.push('publish_actions'); + } + return scopes; + }, +}); +``` diff --git a/generated/markdown/bell/changelog.md b/generated/markdown/bell/changelog.md new file mode 100644 index 00000000..34191048 --- /dev/null +++ b/generated/markdown/bell/changelog.md @@ -0,0 +1,496 @@ +## Version 13 {#v13} + +### [13.1.0](https://github.com/hapijs/bell/milestone/91) {#13.1.0} + +- [#497](https://github.com/hapijs/bell/pull/497) Add tokenParams option +- [#496](https://github.com/hapijs/bell/pull/496) chore: remove mixer provider +- [#485](https://github.com/hapijs/bell/pull/485) remove the bit about google plus + +### [13.0.2](https://github.com/hapijs/bell/milestone/90) {#13.0.2} + +- [#493](https://github.com/hapijs/bell/pull/493) feat: 🎸 add types + +### [13.0.1](https://github.com/hapijs/bell/milestone/89) {#13.0.1} + +- [#490](https://github.com/hapijs/bell/pull/490) chore: bump hoek + +### [13.0.0](https://github.com/hapijs/bell/milestone/88) {#13.0.0} + +- [#488](https://github.com/hapijs/bell/pull/488) Support hapi v21 and node v18, drop hapi v19 and node v12, test ESM support + +## Version 12 {#v12} + +### [12.3.0](https://github.com/hapijs/bell/milestone/86) {#12.3.0} + +- [#481](https://github.com/hapijs/bell/pull/481) Support OAuth1 client wreck options + +### [12.2.0](https://github.com/hapijs/bell/milestone/85) {#12.2.0} + +- [#476](https://github.com/hapijs/bell/pull/476) Add support for providing clientSecret as a function + +### [12.1.1](https://github.com/hapijs/bell/milestone/84) {#12.1.1} + +- [#473](https://github.com/hapijs/bell/pull/473) upgrade lab to v24 +- [#470](https://github.com/hapijs/bell/pull/470) migrate to new travis format +- [#469](https://github.com/hapijs/bell/pull/469) [Bugfix] Okta example code +- [#467](https://github.com/hapijs/bell/pull/467) update to hapi 20 +- [#466](https://github.com/hapijs/bell/pull/466) upgrade bell to use just regular joi package and update teamwork as well + +### [12.1.0](https://github.com/hapijs/bell/milestone/83) {#12.1.0} + +- [#450](https://github.com/hapijs/bell/pull/450) Support Okta custom authorization server + +### [12.0.1](https://github.com/hapijs/bell/milestone/82) {#12.0.1} + +- [#458](https://github.com/hapijs/bell/issues/458) Issue with the meetup provider + +### [12.0.0](https://github.com/hapijs/bell/milestone/81) {#12.0.0} + +- [#449](https://github.com/hapijs/bell/issues/449) Change plugin name to @hapi/bell +- [#448](https://github.com/hapijs/bell/issues/448) Require hapi 19 +- [#447](https://github.com/hapijs/bell/issues/447) Only node 12 +- [#445](https://github.com/hapijs/bell/pull/445) Use actual package name for plugin name + +## Version 11 {#v11} + +### [11.1.0](https://github.com/hapijs/bell/milestone/80) {#11.1.0} + +- [#432](https://github.com/hapijs/bell/issues/432) Return azureAD provider + +### [11.0.0](https://github.com/hapijs/bell/milestone/79) {#11.0.0} + +- [#428](https://github.com/hapijs/bell/issues/428) Make dropbox-v2 the only provider +- [#427](https://github.com/hapijs/bell/issues/427) Replace office365, azuread with updated azure provider +- [#426](https://github.com/hapijs/bell/issues/426) Update joi +- [#420](https://github.com/hapijs/bell/issues/420) Add support for PKCE +- [#418](https://github.com/hapijs/bell/pull/418) New Twitch API oAuth & profile +- [#416](https://github.com/hapijs/bell/pull/416) Update github login example +- [#411](https://github.com/hapijs/bell/pull/411) [Bell-410] Add AWS Cognito provider +- [#410](https://github.com/hapijs/bell/issues/410) Add provider for AWS Cognito +- [#409](https://github.com/hapijs/bell/pull/409) RFC 7636: Proof Key for Code Exchange +- [#404](https://github.com/hapijs/bell/pull/404) Add Azure Oauth2 v2 provider +- [#403](https://github.com/hapijs/bell/issues/403) Correctly utilize JWT tokens instead of normal accessTokens for AzureAD +- [#376](https://github.com/hapijs/bell/issues/376) Update Office365 / Microsoft provider + +## Version 10 {#v10} + +### [10.1.1](https://github.com/hapijs/bell/milestone/77) {#10.1.1} + +- [#421](https://github.com/hapijs/bell/issues/421) Update deps + +### [10.1.0](https://github.com/hapijs/bell/milestone/76) {#10.1.0} + +- [#405](https://github.com/hapijs/bell/issues/405) Change module namespace + +### [10.0.0](https://github.com/hapijs/bell/milestone/75) {#10.0.0} + +- [#400](https://github.com/hapijs/bell/issues/400) 10.0.0 Release Notes +- [#397](https://github.com/hapijs/bell/pull/397) Add support for hapi 18 +- [#394](https://github.com/hapijs/bell/issues/394) Google auth redirect loop with hapi v18 +- [#391](https://github.com/hapijs/bell/pull/391) Update LinkedIn to use new lite profile +- [#390](https://github.com/hapijs/bell/issues/390) Upgrade LinkedIn to support new 'Lite Profile' + +## Version 9 {#v9} + +### [9.6.0](https://github.com/hapijs/bell/milestone/78) {#9.6.0} + +- [#406](https://github.com/hapijs/bell/issues/406) Change module namespace for v9 branch + +### [9.5.0](https://github.com/hapijs/bell/milestone/74) {#9.5.0} + +- [#396](https://github.com/hapijs/bell/pull/396) Allow isSameSite customization +- [#395](https://github.com/hapijs/bell/issues/395) Safari isSameSite +- [#389](https://github.com/hapijs/bell/pull/389) Add changelog.md + +### [9.4.0](https://github.com/hapijs/bell/milestone/73) {#9.4.0} + +- [#386](https://github.com/hapijs/bell/issues/386) Cleanup +- [#381](https://github.com/hapijs/bell/pull/381) FB custom scope + upgrade api version +- [#374](https://github.com/hapijs/bell/pull/374) Ensure Auth0 profile is availabe in all cases +- [#373](https://github.com/hapijs/bell/pull/373) Use Stripe Express +- [#372](https://github.com/hapijs/bell/pull/372) Add config 'fields' to vk provider + +### [9.3.1](https://github.com/hapijs/bell/milestone/71) {#9.3.1} + +- [#358](https://github.com/hapijs/bell/pull/358) Use OIDC compliant profile from Auth0 + +### [9.3.0](https://github.com/hapijs/bell/milestone/70) {#9.3.0} + +- [#356](https://github.com/hapijs/bell/pull/356) fix(package): update Boom and fix trying to create an instance of .internal +- [#355](https://github.com/hapijs/bell/pull/355) Set SameSite=Strict for improved security + +### [9.2.0](https://github.com/hapijs/bell/milestone/68) {#9.2.0} + +- [#354](https://github.com/hapijs/bell/pull/354) Remove new Buffer usage +- [#350](https://github.com/hapijs/bell/pull/350) Picture object included in the profile object for facebook oauth +- [#349](https://github.com/hapijs/bell/pull/349) Fix problem with not exist required param 'v' last versitons today 5.… +- [#348](https://github.com/hapijs/bell/issues/348) VK auth dev error: 'v' is required +- [#347](https://github.com/hapijs/bell/pull/347) facebook picture field added to get profile picture + +### [9.1.0](https://github.com/hapijs/bell/milestone/67) {#9.1.0} + +- [#295](https://github.com/hapijs/bell/issues/295) Expose query in spite of errors +- [#288](https://github.com/hapijs/bell/issues/288) Remove or more comprehensively document provider.version + +### [9.0.0](https://github.com/hapijs/bell/milestone/63) {#9.0.0} + +- [#345](https://github.com/hapijs/bell/issues/345) 9.0.0 Release Notes +- [#332](https://github.com/hapijs/bell/pull/332) [WIP] Hapi 17 Support +- [#330](https://github.com/hapijs/bell/issues/330) hapi v17 support + +## Version 8 {#v8} + +### [8.9.0](https://github.com/hapijs/bell/milestone/66) {#8.9.0} + +- [#325](https://github.com/hapijs/bell/pull/325) Changed the discord providers image url prefix +- [#321](https://github.com/hapijs/bell/pull/321) Add trakt.tv provider +- [#286](https://github.com/hapijs/bell/pull/286) Added custom OAuth2 client authentication + +### [8.8.0](https://github.com/hapijs/bell/milestone/65) {#8.8.0} + +- [#319](https://github.com/hapijs/bell/pull/319) Allowing the location option to be a function +- [#318](https://github.com/hapijs/bell/pull/318) Add Mixer as a new provider +- [#316](https://github.com/hapijs/bell/pull/316) Add Stripe as a new provider +- [#315](https://github.com/hapijs/bell/pull/315) Add `fields` option to Facebook provider +- [#244](https://github.com/hapijs/bell/pull/244) New dropbox-v2 provider which uses Dropbox V2 API + +### [8.7.0](https://github.com/hapijs/bell/milestone/64) {#8.7.0} + +- [#312](https://github.com/hapijs/bell/pull/312) add DigitalOcean provider +- [#311](https://github.com/hapijs/bell/pull/311) Updates Facebook API to v2.9 +- [#308](https://github.com/hapijs/bell/pull/308) Add `'profile'` to list of default scopes for Okta +- [#303](https://github.com/hapijs/bell/pull/303) Facebook +- [#252](https://github.com/hapijs/bell/pull/252) [Update] Updates Facebook provider to v2.7 + +### [8.6.0](https://github.com/hapijs/bell/milestone/62) {#8.6.0} + +- [#299](https://github.com/hapijs/bell/pull/299) Add support for authentication with Okta +- [#298](https://github.com/hapijs/bell/pull/298) added spotify +- [#273](https://github.com/hapijs/bell/pull/273) Fixes #261 expose OAUTH2 token response as request.auth.artifacts + +### [8.5.1](https://github.com/hapijs/bell/milestone/61) {#8.5.1} + +- [#289](https://github.com/hapijs/bell/pull/289) AzureAD: Support email, when userPrincipalName (upn) is not available + +### [8.5.0](https://github.com/hapijs/bell/milestone/54) {#8.5.0} + +- [#291](https://github.com/hapijs/bell/issues/291) Medium provider + +### [8.4.0](https://github.com/hapijs/bell/milestone/60) {#8.4.0} + +- [#280](https://github.com/hapijs/bell/issues/280) hapi 16 +- [#266](https://github.com/hapijs/bell/issues/266) Implement Azure Active Directory authentication for enterprise AD logins + +### [8.3.0](https://github.com/hapijs/bell/milestone/59) {#8.3.0} + +- [#267](https://github.com/hapijs/bell/pull/267) Fixes #266 Implements azure active directory as bell azuread module + +### [8.2.1](https://github.com/hapijs/bell/milestone/58) {#8.2.1} + +- [#265](https://github.com/hapijs/bell/pull/265) Set isSameSite to false and add code to support Hapi 13.5+ +- [#264](https://github.com/hapijs/bell/issues/264) Bell is not compatible with Hapi 15 due to same-site: strict for cookie + +### [8.2.0](https://github.com/hapijs/bell/milestone/57) {#8.2.0} + +- [#259](https://github.com/hapijs/bell/issues/259) Support Hapi 15 & upgrade boom + wreck dependencies +- [#256](https://github.com/hapijs/bell/pull/256) allow for leading whitespace in JSON +- [#248](https://github.com/hapijs/bell/pull/248) Add discord as a new provider + +### [8.1.1](https://github.com/hapijs/bell/milestone/56) {#8.1.1} + +- [#254](https://github.com/hapijs/bell/pull/254) fix mapping of google profile fixes #251 +- [#251](https://github.com/hapijs/bell/issues/251) Google user info + +### [8.1.0](https://github.com/hapijs/bell/milestone/55) {#8.1.0} + +- [#249](https://github.com/hapijs/bell/pull/249) Twitter additional GET parameters on extended profile request + +### [8.0.1](https://github.com/hapijs/bell/milestone/52) {#8.0.1} + +- [#247](https://github.com/hapijs/bell/issues/247) Allow hapi 14 + +### [8.0.0](https://github.com/hapijs/bell/milestone/34) {#8.0.0} + +- [#243](https://github.com/hapijs/bell/issues/243) Bell 8.0.0 Release Notes +- [#242](https://github.com/hapijs/bell/issues/242) Upgrade Joi dependence to 9.x.x +- [#240](https://github.com/hapijs/bell/pull/240) Fitbit provider +- [#235](https://github.com/hapijs/bell/pull/235) Separate Google into two providers. #228 +- [#233](https://github.com/hapijs/bell/pull/233) Allow providerParams to be a method invoked with the request +- [#228](https://github.com/hapijs/bell/issues/228) Remove dependency on Google Plus APIs + +## Version 7 {#v7} + +### [7.9.3](https://github.com/hapijs/bell/milestone/51) {#7.9.3} + +- [#239](https://github.com/hapijs/bell/pull/239) [Fix] Fixes email address field in LinkedIn + +### [7.9.1](https://github.com/hapijs/bell/milestone/50) {#7.9.1} + +- [#237](https://github.com/hapijs/bell/issues/237) Profiles are broken when used directly + +### [7.9.0](https://github.com/hapijs/bell/milestone/49) {#7.9.0} + +- [#236](https://github.com/hapijs/bell/pull/236) Aphuang2013 patch 1 +- [#232](https://github.com/hapijs/bell/issues/232) Update dependencies +- [#231](https://github.com/hapijs/bell/pull/231) Only publish root and lib directory in npm. #230 +- [#230](https://github.com/hapijs/bell/issues/230) Only publish root and lib directory in npm +- [#227](https://github.com/hapijs/bell/pull/227) Implemented RSA-SHA1 signatures for OAuth v1 +- [#226](https://github.com/hapijs/bell/issues/226) OAuth v1: How to handle RSA-SHA1 signing? + +### [7.8.0](https://github.com/hapijs/bell/milestone/47) {#7.8.0} + +- [#221](https://github.com/hapijs/bell/pull/221) getMethod option + +### [7.7.3](https://github.com/hapijs/bell/milestone/48) {#7.7.3} + +- [#225](https://github.com/hapijs/bell/pull/225) Fix markup to quote URL correctly to avoid infinite redirect + +### [7.7.2](https://github.com/hapijs/bell/milestone/45) {#7.7.2} + +- [#224](https://github.com/hapijs/bell/pull/224) Apply the same html redirection logic to oauth v1. Closes #223 +- [#223](https://github.com/hapijs/bell/issues/223) OAuth 1.0 missing HTML redirection workaround + +### [7.7.1](https://github.com/hapijs/bell/milestone/46) {#7.7.1} + +- [#222](https://github.com/hapijs/bell/pull/222) Upgrade to code 3.x.x +- [#210](https://github.com/hapijs/bell/pull/210) Test with Node 6 + +### [7.7.0](https://github.com/hapijs/bell/milestone/44) {#7.7.0} + +- [#216](https://github.com/hapijs/bell/pull/216) Consistently return node req object in oauth v1 client. Closes #215 +- [#215](https://github.com/hapijs/bell/issues/215) Fails to always return the node req object from wreck +- [#213](https://github.com/hapijs/bell/pull/213) Add Pinterest provider + +### [7.6.1](https://github.com/hapijs/bell/milestone/42) {#7.6.1} + +- [#208](https://github.com/hapijs/bell/pull/208) Fix Safari CORS with Facebook & potentially other providers +- [#206](https://github.com/hapijs/bell/pull/206) Fix weird error happening when logging in through Facebook on safari … +- [#191](https://github.com/hapijs/bell/issues/191) Can not login with Facebook on Safari + +### [7.6.0](https://github.com/hapijs/bell/milestone/43) {#7.6.0} + +- [#207](https://github.com/hapijs/bell/pull/207) Add GitLab provider + +### [7.5.1](https://github.com/hapijs/bell/milestone/38) {#7.5.1} + +- [#205](https://github.com/hapijs/bell/pull/205) Added appsecret_proof to wordpress provider + +### [7.5.0](https://github.com/hapijs/bell/milestone/41) {#7.5.0} + +- [#204](https://github.com/hapijs/bell/pull/204) WordPress Provider + +### [7.4.0](https://github.com/hapijs/bell/milestone/40) {#7.4.0} + +- [#202](https://github.com/hapijs/bell/pull/202) Office365 provider + +### [7.3.0](https://github.com/hapijs/bell/milestone/39) {#7.3.0} + +- [#199](https://github.com/hapijs/bell/pull/199) Salesforce provider + +### [7.2.0](https://github.com/hapijs/bell/milestone/37) {#7.2.0} + +- [#198](https://github.com/hapijs/bell/pull/198) Add Slack provider +- [#196](https://github.com/hapijs/bell/pull/196) Bitbucket incorrect id and styling inconsistency. + +### [7.1.0](https://github.com/hapijs/bell/milestone/35) {#7.1.0} + +- [#194](https://github.com/hapijs/bell/pull/194) Support returning raw resource payload. Closes #193 +- [#193](https://github.com/hapijs/bell/issues/193) client.resource() raw payload + +### [7.0.0](https://github.com/hapijs/bell/milestone/33) {#7.0.0} + +- [#189](https://github.com/hapijs/bell/issues/189) Bell 7 release notes +- [#188](https://github.com/hapijs/bell/pull/188) Add Auth0 provider +- [#187](https://github.com/hapijs/bell/issues/187) peerDependency on Hapi 13 +- [#182](https://github.com/hapijs/bell/pull/182) Allow passing additional state + +## Version 6 {#v6} + +### [6.3.0](https://github.com/hapijs/bell/milestone/32) {#6.3.0} + +- [#183](https://github.com/hapijs/bell/pull/183) skipProfile option +- [#163](https://github.com/hapijs/bell/issues/163) Auth fails silently + +### [6.2.0](https://github.com/hapijs/bell/milestone/31) {#6.2.0} + +- [#179](https://github.com/hapijs/bell/pull/179) Added Twitch provider +- [#178](https://github.com/hapijs/bell/pull/178) Upgrade devDependencies, test Hapi 12, lint update with tests/examples + +### [6.1.0](https://github.com/hapijs/bell/milestone/30) {#6.1.0} + +- [#174](https://github.com/hapijs/bell/pull/174) Update bitbucket to use the oAuth2 endpoint +- [#168](https://github.com/hapijs/bell/pull/168) Add simulated mode. Closes #167 +- [#167](https://github.com/hapijs/bell/issues/167) Simulated mode + +### [6.0.0](https://github.com/hapijs/bell/milestone/26) {#6.0.0} + +- [#162](https://github.com/hapijs/bell/pull/162) Add error if using non-https server when isSecure is set to true +- [#160](https://github.com/hapijs/bell/pull/160) Upgrade to Node 4+, Hapi 10+, ES6 styling, Update dependencies +- [#159](https://github.com/hapijs/bell/issues/159) Bell 6 Release Notes + +## Version 5 {#v5} + +### [5.4.0](https://github.com/hapijs/bell/milestone/29) {#5.4.0} + +- [#155](https://github.com/hapijs/bell/pull/155) Added Tumblr provider +- [#154](https://github.com/hapijs/bell/pull/154) Fixed no-comma-dangle in README +- [#153](https://github.com/hapijs/bell/pull/153) Test Hapi 9 and 10 +- [#150](https://github.com/hapijs/bell/pull/150) Add documentation about Linkedin custom profile fields +- [#148](https://github.com/hapijs/bell/pull/148) upgrade to lab 6 and cleanup + +### [5.3.0](https://github.com/hapijs/bell/milestone/28) {#5.3.0} + +- [#147](https://github.com/hapijs/bell/pull/147) Update Wreck to 6.x.x and some devDependencies +- [#133](https://github.com/hapijs/bell/issues/133) Update Wreck to 6.1.0 or latest version + +### [5.2.0](https://github.com/hapijs/bell/milestone/27) {#5.2.0} + +- [#146](https://github.com/hapijs/bell/pull/146) Meetup.com Provider +- [#142](https://github.com/hapijs/bell/pull/142) Update Providers.md +- [#141](https://github.com/hapijs/bell/issues/141) 500 error on google auth +- [#140](https://github.com/hapijs/bell/pull/140) Fix tests +- [#139](https://github.com/hapijs/bell/pull/139) Split up the documentation and add provider specific information plus… +- [#137](https://github.com/hapijs/bell/pull/137) Node v4 +- [#132](https://github.com/hapijs/bell/issues/132) Fix lasting linting issues +- [#127](https://github.com/hapijs/bell/issues/127) Document Bell Core API and Providers API +- [#109](https://github.com/hapijs/bell/issues/109) Provider wiki +- [#25](https://github.com/hapijs/bell/issues/25) Test Cleanup + +### [5.1.0](https://github.com/hapijs/bell/milestone/23) {#5.1.0} + +- [#131](https://github.com/hapijs/bell/pull/131) Fix wrong tests. OAuth1 does not include expiresIn for yahoo/bitbucke… +- [#130](https://github.com/hapijs/bell/pull/130) fixed linting issues // now extends lab linting +- [#129](https://github.com/hapijs/bell/pull/129) added allowRuntimeProviderParams to allow runtime query params +- [#125](https://github.com/hapijs/bell/issues/125) Provide variable providerParams + +### [5.0.1](https://github.com/hapijs/bell/milestone/22) {#5.0.1} + +- [#120](https://github.com/hapijs/bell/pull/120) Facebook Provider: Fix expiresIn, add example, backwards compatibility +- [#119](https://github.com/hapijs/bell/pull/119) Update google.js +- [#117](https://github.com/hapijs/bell/issues/117) Lois Desplat is the new maintainer +- [#115](https://github.com/hapijs/bell/pull/115) Add fields to the query +- [#89](https://github.com/hapijs/bell/issues/89) facebook expiration won't be mapped properly + +### [5.0.0](https://github.com/hapijs/bell/milestone/21) {#5.0.0} + +- [#116](https://github.com/hapijs/bell/issues/116) 5.0.0 Release Notes +- [#114](https://github.com/hapijs/bell/pull/114) Updated LinkedIn's default scope +- [#110](https://github.com/hapijs/bell/pull/110) Fix google example +- [#108](https://github.com/hapijs/bell/pull/108) Updated Google provider so that login uses the recommended Google+ People endpoint +- [#66](https://github.com/hapijs/bell/issues/66) Deprecated Google and Facebook APIs + +## Version 4 {#v4} + +### [4.0.1](https://github.com/hapijs/bell/milestone/20) {#4.0.1} + +- [#107](https://github.com/hapijs/bell/pull/107) Fix clientSecret usage and adds test case +- [#103](https://github.com/hapijs/bell/pull/103) remove property username as it is not part of the google profile +- [#101](https://github.com/hapijs/bell/pull/101) Fix clientSecret usage + +### [4.0.0](https://github.com/hapijs/bell/milestone/19) {#4.0.0} + +- [#100](https://github.com/hapijs/bell/issues/100) 4.0.0 Release Notes +- [#99](https://github.com/hapijs/bell/pull/99) Ensure only 1 authentication method is used during /token access in o… +- [#98](https://github.com/hapijs/bell/issues/98) Don't send client credentials as parameters and basic auth while retrieving token +- [#96](https://github.com/hapijs/bell/pull/96) Allow null for domain + +## Version 3 {#v3} + +### [3.0.0](https://github.com/hapijs/bell/milestone/18) {#3.0.0} + +- [#94](https://github.com/hapijs/bell/pull/94) Rewrite OAuth 1.0 client interface +- [#92](https://github.com/hapijs/bell/issues/92) Fix POST payload format and location + +## Version 2 {#v2} + +### [2.9.0](https://github.com/hapijs/bell/milestone/17) {#2.9.0} + +- [#91](https://github.com/hapijs/bell/pull/91) OAuth client resource() endpoint +- [#90](https://github.com/hapijs/bell/issues/90) Expose OAuth 1.0 client protected resource endpoing + +### [2.8.0](https://github.com/hapijs/bell/milestone/16) {#2.8.0} + +- [#88](https://github.com/hapijs/bell/pull/88) Expose OAuth interface. Closes #48 +- [#48](https://github.com/hapijs/bell/issues/48) Expose Client as a plugin method + +### [2.7.1](https://github.com/hapijs/bell/milestone/15) {#2.7.1} + +- [#87](https://github.com/hapijs/bell/pull/87) Pass `forceHttps` and `location` to v1 client + +### [2.7.0](https://github.com/hapijs/bell/milestone/14) {#2.7.0} + +- [#85](https://github.com/hapijs/bell/pull/85) add location setting similar to old hapi server location + +### [2.6.0](https://github.com/hapijs/bell/milestone/13) {#2.6.0} + +- [#84](https://github.com/hapijs/bell/pull/84) Add nest authentication + +### [2.5.0](https://github.com/hapijs/bell/milestone/12) {#2.5.0} + +- [#81](https://github.com/hapijs/bell/pull/81) Added option to specify the LinkedIn profile fields +- [#80](https://github.com/hapijs/bell/pull/80) Support Reddit as an OAuth provider +- [#79](https://github.com/hapijs/bell/issues/79) LinkedIn profile fields + +### [2.4.0](https://github.com/hapijs/bell/milestone/11) {#2.4.0} + +- [#78](https://github.com/hapijs/bell/pull/78) update facebook URLs to use facebook Graph v2.3 +- [#77](https://github.com/hapijs/bell/pull/77) Support for Phabricator +- [#73](https://github.com/hapijs/bell/pull/73) Allow environment variables to configure options + +### [2.3.0](https://github.com/hapijs/bell/milestone/10) {#2.3.0} + +- [#71](https://github.com/hapijs/bell/pull/71) Fix linting issues +- [#70](https://github.com/hapijs/bell/pull/70) Update Joi to 6.x +- [#69](https://github.com/hapijs/bell/pull/69) Add LinkedIn provider +- [#68](https://github.com/hapijs/bell/pull/68) Add ArcGIS Online provider +- [#67](https://github.com/hapijs/bell/pull/67) Support new wreck in mocks +- [#62](https://github.com/hapijs/bell/pull/62) Update .travis.yml + +### [2.2.0](https://github.com/hapijs/bell/milestone/9) {#2.2.0} + +- [#60](https://github.com/hapijs/bell/pull/60) Make forceHttps complete +- [#58](https://github.com/hapijs/bell/pull/58) passing back expires_in for oauth 2.0 refresh token request +- [#54](https://github.com/hapijs/bell/pull/54) Added Dropbox. +- [#49](https://github.com/hapijs/bell/issues/49) pass back expires_in + +### [2.1.0](https://github.com/hapijs/bell/milestone/8) {#2.1.0} + +- [#53](https://github.com/hapijs/bell/pull/53) Add option for forcing https. + +### [2.0.0](https://github.com/hapijs/bell/milestone/7) {#2.0.0} + +- [#43](https://github.com/hapijs/bell/pull/43) Hapi8 +- [#42](https://github.com/hapijs/bell/issues/42) hapi 8.0 API + +## Version 1 {#v1} + +### [1.3.1](https://github.com/hapijs/bell/milestone/6) {#1.3.1} + +- [#39](https://github.com/hapijs/bell/pull/39) handle oauth user rejection for v2 as well + +### [1.3.0](https://github.com/hapijs/bell/milestone/5) {#1.3.0} + +- [#35](https://github.com/hapijs/bell/pull/35) Add VK provider. + +### [1.2.0](https://github.com/hapijs/bell/milestone/4) {#1.2.0} + +- [#34](https://github.com/hapijs/bell/pull/34) handle oauth login user rejection +- [#31](https://github.com/hapijs/bell/pull/31) Add bitbucket provider +- [#27](https://github.com/hapijs/bell/pull/27) Replaced nipple with wreck. +- [#26](https://github.com/hapijs/bell/issues/26) Wreck + +### [1.1.0](https://github.com/hapijs/bell/milestone/3) {#1.1.0} + +- [#17](https://github.com/hapijs/bell/pull/17) Add Instagram provider. +- [#14](https://github.com/hapijs/bell/pull/14) Add Foursquare as built-in provider +- [#13](https://github.com/hapijs/bell/pull/13) Added ability to specify additional query params for the profile request... +- [#11](https://github.com/hapijs/bell/pull/11) Allow specifying provider name in custom schema + +### [1.0.2](https://github.com/hapijs/bell/milestone/2) {#1.0.2} + +- [#7](https://github.com/hapijs/bell/pull/7) Use correct API path for GitHub Enterprise, fix #6 +- [#6](https://github.com/hapijs/bell/issues/6) Unable to get GitHub Enterprise profile data + +### [1.0.1](https://github.com/hapijs/bell/milestone/1) {#1.0.1} + +- [#5](https://github.com/hapijs/bell/pull/5) Bump peer dependency to Hapi >= 6 diff --git a/generated/markdown/bell/examples.md b/generated/markdown/bell/examples.md new file mode 100644 index 00000000..6bdb219d --- /dev/null +++ b/generated/markdown/bell/examples.md @@ -0,0 +1,669 @@ +## Arcgisonline + +```js +'use strict'; + +const Bell = require('..'); +const Hapi = require('@hapi/hapi'); + +const internals = {}; + +internals.start = async function () { + const server = Hapi.server({ port: 8000 }); + await server.register(Bell); + + // You'll need to go to https://developers.arcgis.com/en/applications and set up an application to get started + // Once you create your app you will get your ClientID and Client Secret. + // Also be sure to set redirect URL as well at the bottom of the screen in Redirect URIs section. + + server.auth.strategy('arcgisonline', 'bell', { + provider: 'arcgisonline', + password: 'cookie_encryption_password_secure', + isSecure: false, + clientId: '', + clientSecret: '', + providerParams: { + redirect_uri: server.info.uri + '/bell/door', + }, + }); + + server.route({ + method: '*', + path: '/bell/door', + options: { + auth: 'arcgisonline', + handler: function (request, h) { + return ( + '
    ' + JSON.stringify(request.auth.credentials, null, 4) + '
    ' + ); + }, + }, + }); + + await server.start(); + console.log('Server started at:', server.info.uri); +}; + +internals.start(); +``` + +## Discord + +```js +'use strict'; + +const Bell = require('..'); +const Hapi = require('@hapi/hapi'); + +const internals = {}; + +internals.start = async function () { + const server = Hapi.server({ port: 8000 }); + await server.register(Bell); + + // Fill in your clientId and clientSecret: https://discord.com/developers/applications/me + + server.auth.strategy('discord', 'bell', { + provider: 'discord', + password: 'cookie_encryption_password_secure', + isSecure: false, + clientId: '', + clientSecret: '', + }); + + server.route({ + method: '*', + path: '/bell/door', + options: { + auth: 'discord', + handler: function (request, h) { + return ( + '
    ' + JSON.stringify(request.auth.credentials, null, 4) + '
    ' + ); + }, + }, + }); + + await server.start(); + console.log('Server started at:', server.info.uri); +}; + +internals.start(); +``` + +## Facebook + +```js +'use strict'; + +const Bell = require('..'); +const Hapi = require('@hapi/hapi'); + +const internals = {}; + +internals.start = async function () { + const server = Hapi.server({ host: 'localhost', port: 8000 }); + await server.register(Bell); + + // You'll need to go to https://developers.facebook.com/ and set up a + // Website application to get started + // Once you create your app, fill out Settings and set the App Domains + // Under Settings >> Advanced, set the Valid OAuth redirect URIs to include http:///bell/door + // and enable Client OAuth Login + + server.auth.strategy('facebook', 'bell', { + provider: 'facebook', + password: 'cookie_encryption_password_secure', + isSecure: false, + clientId: '', + clientSecret: '', + location: server.info.uri, + }); + + server.route({ + method: '*', + path: '/bell/door', + options: { + auth: { + strategy: 'facebook', + mode: 'try', + }, + handler: function (request, h) { + if (!request.auth.isAuthenticated) { + return 'Authentication failed due to: ' + request.auth.error.message; + } + + return ( + '
    ' + JSON.stringify(request.auth.credentials, null, 4) + '
    ' + ); + }, + }, + }); + + await server.start(); + console.log('Server started at:', server.info.uri); +}; + +internals.start(); +``` + +## Github + +```js +'use strict'; + +const Bell = require('..'); +const Hapi = require('@hapi/hapi'); + +const internals = {}; + +internals.start = async function () { + const server = Hapi.server({ port: 8000 }); + await server.register(Bell); + + // You will need github account for setting up an application and get a clientID and ClientSecret + // This is a helpful tutorial for the whole process: https://developer.github.com/apps/building-github-apps/creating-a-github-app/ + // This guide will help you set up your app and generate ID and secret. + + server.auth.strategy('github', 'bell', { + provider: 'github', + password: 'cookie_encryption_password_secure', + isSecure: false, // For testing or in environments secured via other means + clientId: '', + clientSecret: '', + location: 'https://example.com', + scope: [], + }); + + server.route({ + method: ['GET', 'POST'], + path: '/login', + options: { + auth: { + strategy: 'github', + mode: 'try', + }, + handler: function (request, h) { + if (!request.auth.isAuthenticated) { + return `Authentication failed due to: ${request.auth.error.message}`; + } + + return ( + '
    ' + JSON.stringify(request.auth.credentials, null, 4) + '
    ' + ); + }, + }, + }); + + await server.start(); + console.log('Server started at:', server.info.uri); +}; + +internals.start(); +``` + +## Google + +```js +'use strict'; + +const Bell = require('..'); +const Hapi = require('@hapi/hapi'); + +const internals = {}; + +internals.start = async function () { + const server = Hapi.server({ host: 'localhost', port: 8000 }); + await server.register(Bell); + + // You'll need to go to https://console.developers.google.com and set up an application to get started + // Once you create your app, fill out "APIs & auth >> Consent screen" and make sure to set the email field + // Next, go to "APIs & auth >> Credentials and Create new Client ID + // Select "web application" and set "AUTHORIZED JAVASCRIPT ORIGINS" and "AUTHORIZED REDIRECT URIS" + // This will net you the clientId and the clientSecret needed. + // Also be sure to pass the location as well. It must be in the list of "AUTHORIZED REDIRECT URIS" + + server.auth.strategy('google', 'bell', { + provider: 'google', + password: 'cookie_encryption_password_secure', + isSecure: false, + clientId: '', + clientSecret: '', + location: server.info.uri, + }); + + server.route({ + method: '*', + path: '/bell/door', + options: { + auth: { + strategy: 'google', + mode: 'try', + }, + handler: function (request, h) { + if (!request.auth.isAuthenticated) { + return 'Authentication failed due to: ' + request.auth.error.message; + } + + return ( + '
    ' + JSON.stringify(request.auth.credentials, null, 4) + '
    ' + ); + }, + }, + }); + + await server.start(); + console.log('Server started at:', server.info.uri); +}; + +internals.start(); +``` + +## Linkedin + +```js +'use strict'; + +const Bell = require('..'); +const Hapi = require('@hapi/hapi'); + +const internals = {}; + +internals.start = async function () { + const server = Hapi.server({ port: 8000 }); + await server.register(Bell); + + // You'll need to go to https://www.linkedin.com/secure/developer?newapp= and set up an application to get started + // Follow the instructions on https://developer.linkedin.com/docs/oauth2 to setup redirect_uri and default scopes + + server.auth.strategy('linkedin', 'bell', { + provider: 'linkedin', + password: 'cookie_encryption_password_secure', + isSecure: false, + clientId: '', + clientSecret: '', + providerParams: { + redirect_uri: server.info.uri + '/bell/door', + }, + }); + + server.route({ + method: '*', + path: '/bell/door', + options: { + auth: 'linkedin', + handler: function (request, h) { + return ( + '
    ' + JSON.stringify(request.auth.credentials, null, 4) + '
    ' + ); + }, + }, + }); + + await server.start(); + console.log('Server started at:', server.info.uri); +}; + +internals.start(); +``` + +## Meetup + +```js +'use strict'; + +const Bell = require('..'); +const Hapi = require('@hapi/hapi'); + +const internals = {}; + +internals.start = async function () { + const server = Hapi.server({ port: 8000 }); + await server.register(Bell); + + // Firstly give the meetup oauth docs a quick glance --> http://www.meetup.com/meetup_api/auth/#oauth2 + // Secondly you'll need to create an OAuth consumer --> https://secure.meetup.com/meetup_api/oauth_consumers/ + // Now you can fill in the required fields below and take this example for a test drive + + server.auth.strategy('meetup', 'bell', { + provider: 'meetup', + password: 'cookie_encryption_password_secure', + isSecure: false, + clientId: '', + clientSecret: '', + // scope: ['basic', 'ageless', 'group_edit', 'reporting'] // Uncomment for more scopes, if not you get the "basic" scope by default + }); + + server.route({ + method: '*', + path: '/bell/door', + options: { + auth: 'meetup', + handler: function (request, h) { + return ( + '
    ' + JSON.stringify(request.auth.credentials, null, 4) + '
    ' + ); + }, + }, + }); + + await server.start(); + console.log('Server started at:', server.info.uri); +}; + +internals.start(); +``` + +## Nest + +```js +'use strict'; + +const Bell = require('..'); +const Hapi = require('@hapi/hapi'); + +const internals = {}; + +internals.start = async function () { + const server = Hapi.server({ port: 8000 }); + await server.register(Bell); + + server.auth.strategy('nest', 'bell', { + provider: 'nest', + password: 'cookie_encryption_password_secure', + isSecure: false, + clientId: '', // Fill in your clientId and clientSecret + clientSecret: '', + }); + + server.route({ + method: '*', + path: '/bell/door', + options: { + auth: 'nest', + handler: function (request, h) { + return ( + '
    ' + JSON.stringify(request.auth.credentials, null, 4) + '
    ' + ); + }, + }, + }); + + await server.start(); + console.log('Server started at:', server.info.uri); +}; + +internals.start(); +``` + +## Office365 + +```js +'use strict'; + +const Bell = require('..'); +const Hapi = require('@hapi/hapi'); + +const internals = {}; + +internals.start = async function () { + const server = Hapi.server({ host: 'localhost', port: 8000 }); + await server.register(Bell); + + // You'll need an Office 365 account to set up an application and get a clientID and ClientSecret + // This is a helpful tutorial for the whole process: https://dev.outlook.com/restapi/tutorial/node + // Once you have an account, you can set up your app and generate an ID and Secret here: + // https://apps.dev.microsoft.com/ + + server.auth.strategy('office', 'bell', { + provider: 'office365', + clientId: '', + clientSecret: '', + providerParams: { + response_type: 'code', + }, + scope: ['openid', 'offline_access', 'profile'], + }); + + server.route({ + method: '*', + path: '/bell/door', + options: { + auth: { + strategy: 'office', + mode: 'try', + }, + handler: function (request, h) { + if (!request.auth.isAuthenticated) { + return 'Authentication failed due to: ' + request.auth.error.message; + } + + return ( + '
    ' + JSON.stringify(request.auth.credentials, null, 4) + '
    ' + ); + }, + }, + }); + + await server.start(); + console.log('Server started at:', server.info.uri); +}; + +internals.start(); +``` + +## Okta + +```js +'use strict'; + +const Bell = require('..'); +const Boom = require('@hapi/boom'); +const Hapi = require('@hapi/hapi'); + +const internals = {}; + +internals.start = async function () { + const server = Hapi.server({ port: 8000 }); + await server.register([require('@hapi/cookie'), Bell]); + + server.auth.strategy('session', 'cookie', { + cookie: { + name: 'sid-okta-example', // Cookie name + password: 'password-should-be-32-characters', // Use something more secure in production + isSecure: false, // Should be set to true (which is the default) in production + }, + redirectTo: '/auth/okta', // If there is no session, redirect here + }); + + server.auth.strategy('okta', 'bell', { + provider: 'okta', + config: { uri: 'https://your-organization.okta.com' }, + password: 'cookie_encryption_password_secure', + isSecure: false, + location: 'http://127.0.0.1:8000', + clientId: 'IIA1yMR7IK4XGhfyfCno', + clientSecret: 'PEh_HemJovaR-Zjs-unX8-cC9IhQgzF5M1RUrUgW', + }); + + server.route({ + method: 'GET', + path: '/auth/okta', + options: { + auth: { + strategy: 'okta', + mode: 'try', + }, + handler: function (request, h) { + if (!request.auth.isAuthenticated) { + throw Boom.unauthorized( + 'Authentication failed: ' + request.auth.error.message, + ); + } + + // Just store the third party credentials in the session as an example. You could do something + // more useful here - like loading or setting up an account (social signup). + + request.auth.session.set(request.auth.credentials); + return h.redirect('/'); + }, + }, + }); + + server.route({ + method: 'GET', + path: '/', + options: { + auth: 'session', + handler: function (request, h) { + //Return a message using the information from the session + + return 'Hello, ' + request.auth.credentials.profile.email + '!'; + }, + }, + }); + + await server.start(); + console.log('Server started at:', server.info.uri); +}; + +internals.start(); +``` + +## Slack + +```js +'use strict'; + +const Bell = require('..'); +const Hapi = require('@hapi/hapi'); + +const internals = {}; + +internals.start = async function () { + const server = Hapi.server({ port: 8000 }); + await server.register(Bell); + server.auth.strategy('slack', 'bell', { + provider: 'slack', + password: 'cookie_encryption_password_secure', + isSecure: false, + clientId: '', + clientSecret: '', + }); + + server.route({ + method: '*', + path: '/bell/door', + options: { + auth: 'slack', + handler: function (request, h) { + return ( + '
    ' + JSON.stringify(request.auth.credentials, null, 4) + '
    ' + ); + }, + }, + }); + + await server.start(); +}; + +internals.start(); +``` + +## Twitch + +```js +'use strict'; + +const Bell = require('..'); +const Hapi = require('@hapi/hapi'); + +const internals = {}; + +internals.start = async function () { + const server = Hapi.server({ port: 8000 }); + await server.register(Bell); + + // You need to register developer application with a Twitch account to obtain your clientId, clientSecret, and assign redirect URI + + server.auth.strategy('twitch', 'bell', { + provider: 'twitch', + password: 'cookie_encryption_password_secure', + isSecure: false, + clientId: '', // Set client id + clientSecret: '', // Set client secret + // scope: ['user_read', 'channel_read'] // Uncomment for more scopes (check Twitch API documentation), "user_read" scope is set as default + }); + + server.route({ + method: ['GET', 'POST'], + path: '/bell/door', + options: { + auth: { + strategy: 'twitch', + mode: 'try', + }, + handler: function (request, h) { + if (!request.auth.isAuthenticated) { + return 'Authentication failed due to: ' + request.auth.error.message; + } + + return ( + '
    ' + JSON.stringify(request.auth.credentials, null, 4) + '
    ' + ); + }, + }, + }); + + await server.start(); + console.log('Server started at:', server.info.uri); +}; + +internals.start(); +``` + +## Twitter + +```js +'use strict'; + +const Bell = require('..'); +const Hapi = require('@hapi/hapi'); + +const internals = {}; + +internals.start = async function () { + const server = Hapi.server({ port: 8000 }); + await server.register(Bell); + + // Make sure to set a "Callback URL" and + // check the "Allow this application to be used to Sign in with Twitter" + // on the "Settings" tab in your Twitter application + + server.auth.strategy('twitter', 'bell', { + provider: 'twitter', + password: 'cookie_encryption_password_secure', + isSecure: false, + clientId: '', // Set client id + clientSecret: '', // Set client secret + }); + + server.route({ + method: '*', + path: '/bell/door', + options: { + auth: 'twitter', + handler: function (request, h) { + return ( + '
    ' + JSON.stringify(request.auth.credentials, null, 4) + '
    ' + ); + }, + }, + }); + + await server.start(); + console.log('Server started at:', server.info.uri); +}; + +internals.start(); +``` diff --git a/generated/markdown/bell/providers.md b/generated/markdown/bell/providers.md new file mode 100644 index 00000000..54bc8beb --- /dev/null +++ b/generated/markdown/bell/providers.md @@ -0,0 +1,884 @@ +If you want to write your own provider please see the section at the bottom of this page. + +## Existing Providers + +Each provider may specify configuration options that are unique. Any of these unique options are +documented here and must be provided during strategy creation. See the [API Documentation](API.md) +for all other options. + +### ArcGIS Online + +[Provider Documentation](http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r30000009z000000) + +- `scope`: No default scope +- `config`: not applicable +- `auth`: https://www.arcgis.com/sharing/rest/oauth2/authorize +- `token`: https://www.arcgis.com/sharing/rest/oauth2/token + +The default profile response will look like this: + +```javascript +credentials.profile = { + provider: 'arcgisonline', + orgId: profile.orgId, + username: profile.username, + displayName: profile.fullName, + name: { + first: profile.firstName, + last: profile.lastName, + }, + email: profile.email, + role: profile.role, + raw: profile, +}; +``` + +### Auth0 + +[Provider Documentation](https://auth0.com/docs/protocols#oauth-server-side) + +- `scope`: Defaults to `['openid', 'email', 'profile']` +- `config`: + - `domain`: Your Auth0 domain name, such as `example.auth0.com` or `example.eu.auth0.com` +- `auth`: [/authorize](https://auth0.com/docs/auth-api#!#get--authorize_social) +- `token`: [/oauth/token](https://auth0.com/docs/protocols#3-getting-the-access-token) + +To create a token for a specific endpoint, add it to the `providerParams` and `tokenParams` options, eg.: + +```js +providerParams: { + endpoint: 'https://api.service.com' +}, +tokenParams: { + endpoint: 'https://api.service.com' +} +``` + +To authenticate a user with a specific identity provider directly, use `providerParams`. For example: + +```javascript +providerParams: { + connection: 'Username-Password-Authentication'; +} +``` + +The default profile response will look like this: + +```javascript +credentials.profile = { + id: profile.user_id, + email: profile.email, + displayName: profile.name, + name: { + first: profile.given_name, + last: profile.family_name, + }, + raw: profile, +}; +``` + +Specific fields may vary depending on the identity provider used. For more information, +[refer to the documentation on user profiles](https://auth0.com/docs/user-profile/normalized). + +### Bitbucket + +[Provider Documentation](https://confluence.atlassian.com/bitbucket/oauth-on-bitbucket-238027431.html) + +- `scope`: not applicable +- `config`: not applicable +- `auth`: https://bitbucket.org/site/oauth2/authorize +- `token`: https://bitbucket.org/site/oauth2/access_token + +The default profile response will look like this: + +```javascript +credentials.profile = { + id: profile.uuid, + username: profile.username, + displayName: profile.display_name, + raw: profile, +}; +``` + +### Cognito + +[Provider Documentation](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-userpools-server-contract-reference.html) + +- `scope`: Defaults to `['openid', 'email', 'profile']` +- `config`: + - `uri`: Point to your Cognito user pool uri. Intentionally no default as Cognito is organization specific. +- `auth`: https://your-cognito-user-pool.amazoncognito.com/oauth2/authorize +- `token`: https://your-cognito-user-pool.amazoncognito.com/oauth2/token + +The default profile response will look like this: + +```javascript +credentials.profile = { + id: profile.sub, + username: profile.preferred_username, + displayName: profile.name, + firstName: profile.given_name, + lastName: profile.family_name, + email: profile.email, + raw: profile, +}; +``` + +### DigitalOcean + +[Provider Documentation](https://developers.digitalocean.com/documentation/oauth) + +- `scope`: defaults to `read` scope +- `config`: not applicable +- `auth`: https://cloud.digitalocean.com/v1/oauth/authorize +- `token`: https://cloud.digitalocean.com/v1/oauth/token + +The default profile response will look like this: + +```javascript +credentials.profile = { + id: profile.account.uuid, + email: profile.account.email, + status: profile.account.status, + dropletLimit: profile.account.droplet_limit, + raw: profile.account, +}; +``` + +### Discord + +[Provider Documentation](https://discord.com/developers/docs/topics/oauth2) + +- `scope`: Defaults to `['email', 'identify']` +- `config`: not applicable +- `auth`: https://discord.com/api/oauth2/authorize +- `token`: https://discord.com/api/oauth2/token + +The default profile response will look like this: + +```javascript +credentials.profile = { + id: profile.id, + discriminator: profile.discriminator, + username: profile.username, + email: profile.email, + mfa_enabled: profile.mfa_enabled, + verified: profile.verified, + avatar: { + id: profile.avatar, + url: + 'https://discord.com/api/users/' + + profile.id + + '/avatars/' + + profile.avatar + + '.jpg', + }, + raw: profile, +}; +``` + +### Dropbox + +[Provider Documentation](https://www.dropbox.com/developers/core/docs) + +- `scope`: No default scope +- `config`: not applicable +- `auth`: https://www.dropbox.com/1/oauth2/authorize +- `token`: https://api.dropbox.com/1/oauth2/token + +The default profile response will look like this: + +```javascript +// default profile response from dropbox +``` + +### Facebook + +[Provider Documentation](https://developers.facebook.com/docs/facebook-login/access-tokens) + +- `scope`: Defaults to `['email']` +- `config`: + - `fields`: List of profile fields to retrieve, as described in [Facebook's documentation](https://developers.facebook.com/docs/graph-api/reference/user). Defaults to `'id,name,email,first_name,last_name,middle_name,gender,link,locale,timezone,updated_time,verified'`. +- `auth`: https://www.facebook.com/v3.1/dialog/oauth +- `token`: https://graph.facebook.com/v3.1/oauth/access_token + +The default profile response will look like this: + +```javascript +credentials.profile = { + id: profile.id, + username: profile.username, + displayName: profile.name, + name: { + first: profile.first_name, + last: profile.last_name, + middle: profile.middle_name, + }, + email: profile.email, + raw: profile, +}; +``` + +### Fitbit + +[Provider Documentation](https://dev.fitbit.com/docs/oauth2/) + +- `scope`: Defaults to `['activity', 'profile']` +- `config`: not applicable +- `auth`: https://www.fitbit.com/oauth2/authorize +- `token`: https://api.fitbit.com/oauth2/token + +The default profile response will look like this: + +```javascript +credentials.profile = { + id: profile.user.encodedId, + displayName: profile.user.displayName, + name: profile.user.fullName, +}; +``` + +### Foursquare + +[Provider Documentation](https://developer.foursquare.com/overview/auth) + +- `scope`: No default scope +- `config`: not applicable +- `auth`: https://foursquare.com/oauth2/authenticate +- `token`: https://foursquare.com/oauth2/access_token + +The default profile response will look like this: + +```javascript +credentials.profile = { + id: profile.id, + displayName: profile.firstName + ' ' + profile.lastName, + name: { + first: profile.firstName, + last: profile.lastName, + }, + email: profile.contact.email, + raw: profile, +}; +``` + +### Github + +[Provider Documentation](https://developer.github.com/v3/oauth/) + +- `scope`: Defaults to `['user:email']` +- `config`: + - `uri`: Point to your github enterprise uri. Defaults to `https://github.com`. +- `auth`: /login/oauth/authorize +- `token`: /login/oauth/access_token + +The default profile response will look like this: + +```javascript +credentials.profile = { + id: profile.id, + username: profile.login, + displayName: profile.name, + email: profile.email, + raw: profile, +}; +``` + +### GitLab + +[Provider Documentation](https://gitlab.com/help/api/oauth2.md) + +- `scope`: No default scope. +- `config`: + - `uri`: Point to your gitlab uri. Defaults to `https://gitlab.com`. +- `auth`: /oauth/authorize +- `token`: /oauth/token + +The default profile response will look like this: + +```javascript +// Defaults to gitlab response (https://gitlab.com/help/api/users.md#current-user) +``` + +### Google + +[Provider Documentation](https://developers.google.com/identity/protocols/OpenIDConnect) + +- `scope`: Defaults to `['profile', 'email']` +- `config`: not applicable +- `auth`: https://accounts.google.com/o/oauth2/v2/auth +- `token`: https://www.googleapis.com/oauth2/v4/token + +The default profile response will look like this: + +```javascript +credentials.profile = { + id: profile.id, + displayName: profile.name, + name: { + given_name: profile.given_name, + family_name: profile.family_name, + }, + email: profile.email, + raw: profile, +}; +``` + +### Google Plus + +[Provider Documentation](https://developers.google.com/identity/protocols/OpenIDConnect) + +You must also enable the Google+ API in your profile. Go to APIs & Auth, then APIs and under Social APIs click Google+ API and enable it. + +- `scope`: Defaults to `['profile', 'email']` +- `config`: not applicable +- `auth`: https://accounts.google.com/o/oauth2/v2/auth +- `token`: https://www.googleapis.com/oauth2/v4/token + +The default profile response will look like this: + +```javascript +credentials.profile = { + id: profile.id, + displayName: profile.displayName, + name: profile.name, + emails: profile.emails, + raw: profile, +}; +``` + +### Instagram + +[Provider Documentation](https://instagram.com/developer/authentication/) + +- `scope`: Defaults to `['basic']` +- `config`: + - `extendedProfile`: Boolean that determines if extended profile information will be fetched +- `auth`: https://api.instagram.com/oauth/authorize +- `token`: https://api.instagram.com/oauth/access_token + +The default profile response will look like this: + +```javascript +credentials.profile = { + id: params.user.id, + username: params.user.username, + displayName: params.user.full_name, + raw: params.user, +}; + +// if extendedProfile is true then raw will have access to all the information +``` + +### LinkedIn + +[Provider Documentation](https://developer.linkedin.com/docs/oauth2) + +- `scope`: Defaults to `['r_basicprofile', 'r_emailaddress']` +- `config`: not applicable +- `auth`: https://www.linkedin.com/uas/oauth2/authorization +- `token`: https://www.linkedin.com/uas/oauth2/accessToken + +The default profile response will look like this: + +```javascript +credentials.profile = { + id: profile.id, + name: { + first: profile.firstName, + last: profile.lastName, + }, + email: profile.email, + headline: profile.headline, + raw: profile, +}; +``` + +You can request additional profile fields by setting the `fields` option of `providerParams`. All possible fields are described in the [Basic Profile Fields documentation](https://developer.linkedin.com/docs/fields/basic-profile) (see an example on [this page](https://developer.linkedin.com/docs/signin-with-linkedin) under _Requesting additional profile fields_). + +Here is an example of a custom strategy configuration: + +```javascript +providerParams: { + fields: ':(id,first-name,last-name,positions,picture-url,picture-urls::(original),email-address)'; +} +``` + +### Medium + +[Provider Documentation](https://github.com/Medium/medium-api-docs) + +- `scope`: Defaults to `['basicProfile']` +- `config`: not applicable +- `auth`: https://medium.com/m/oauth/authorize +- `token`: https://medium.com/v1/tokens + +The default profile response will look like this: + +```javascript +credentials.profile = { + id: profile.data.id, + username: profile.data.username, + displayName: profile.data.name, + raw: profile.data, +}; +``` + +### Meetup + +[Provider Documentation](http://www.meetup.com/meetup_api/auth) + +- `scope`: Defaults to `['basic']` +- `config`: not applicable +- `auth`: https://secure.meetup.com/oauth2/authorize +- `token`: https://secure.meetup.com/oauth2/access + +The default profile response will look like this: + +```javascript +// Defaults to meetup response (http://www.meetup.com/meetup_api/docs/2/member/#get) +``` + +### Microsoft Live + +[Provider Documentation](https://msdn.microsoft.com/en-us/library/hh243647.aspx) + +- `scope`: Defaults to `['wl.basic', 'wl.emails']` +- `config`: not applicable +- `auth`: https://login.live.com/oauth20_authorize.srf +- `token`: https://login.live.com/oauth20_token.srf + +The default profile response will look like this: + +```javascript +credentials.profile = { + id: profile.id, + username: profile.username, + displayName: profile.name, + name: { + first: profile.first_name, + last: profile.last_name, + }, + email: profile.emails && (profile.emails.preferred || profile.emails.account), + raw: profile, +}; +``` + +### Nest + +[Provider Documentation](https://developer.nest.com/documentation/cloud/how-to-auth) + +- `scope`: No default scope +- `config`: not applicable +- `auth`: https://home.nest.com/login/oauth2 +- `token`: https://api.home.nest.com/oauth2/access_token + +The default profile response will look like this: + +```javascript +// According to the official docs, no user data is available via the Nest +// OAuth service. Therefore, there is no `profile`. +``` + +### Phabricator + +[Provider Documentation](https://secure.phabricator.com/book/phabcontrib/article/using_oauthserver/) + +- `scope`: Defaults to `['whoami']` +- `config`: + - `uri`: URI of phabricator instance +- `auth`: /oauthserver/auth/ +- `token`: /oauthserver/token/ + +The default profile response will look like this: + +```javascript +credentials.profile = { + id: profile.result.phid, + username: profile.result.userName, + displayName: profile.result.realName, + email: profile.result.primaryEmail, + raw: profile, +}; +``` + +### Pingfed + +[Provider Documentation](https://www.pingidentity.com/content/developer/en/resources/openid-connect-developers-guide.html) + +- `scope`: Defaults to `['openid', 'email']` +- `config`: + - `uri`: Point to your Pingfederate enterprise uri. Intentionally no default as Ping is organization specific. +- `auth`: https://www.example.com:9031/as/authorization.oauth2 +- `token`: https://www.example.com:9031/as/token.oauth2 + +The default profile response will look like this: + +```javascript +credentials.profile = { + id: profile.sub, + username: profile.email, + displayName: profile.email, + email: profile.email, + raw: profile, +}; +``` + +### Pinterest + +[Provider Documentation](https://developers.pinterest.com/docs/api/overview/) + +- `scope`: Defaults to `['read_public', 'write_public', 'read_relationships', 'write_relationships']` +- `config`: not applicable +- `auth`: https://api.pinterest.com/oauth/ +- `token`: https://api.pinterest.com/v1/oauth/token + +The default profile response will look like this: + +```javascript +credentials.profile = { + id: profile.data.id, + username: profile.data.username, + name: { + first: profile.data.first_name, + last: profile.data.last_name, + }, + raw: profile, +}; +``` + +### Reddit + +[Provider Documentation](https://github.com/reddit/reddit/wiki/OAuth2) + +- `scope`: Defaults to `['identity']` +- `config`: not applicable +- `auth`: https://www.reddit.com/api/v1/authorize +- `token`: https://www.reddit.com/api/v1/access_token + +The default profile response will look like this: + +```javascript +// Defaults to reddit response +``` + +### Slack + +[Provider Documentation](https://api.slack.com/docs/oauth) + +- `scope`: Defaults to `['identify']` +- `config`: + - `extendedProfile`: Set to `false` if all you want is the `access_token`, without `user_id`, `user`, `raw`, etc... +- `auth`: https://slack.com/oauth/authorize +- `token`: https://slack.com/api/oauth.access + +To authenticate user in a specific team, use `providerParams`. For example: + +```javascript +providerParams: { + team: 'T0XXXXXX'; +} +``` + +The default profile response will look like this: + +```javascript +credentials.profile = { + scope: params.scope, + access_token: params.access_token, + user: params.user, + user_id: params.user_id, +}; + +// credentials.profile.raw will contain all of the keys sent by Slack for the `auth.test` method +``` + +### Spotify + +[Provider Documentation](https://developer.spotify.com/web-api/) + +- `scope`: Defaults to `-` allowing to read the public information only. [Spotify Scopes](https://developer.spotify.com/web-api/using-scopes/) +- `auth`: https://accounts.spotify.com/authorize +- `token`: https://accounts.spotify.com/api/token + +Read more about the Spotify Web API's Authorization Flow here: [https://developer.spotify.com/web-api/authorization-guide/](https://developer.spotify.com/web-api/authorization-guide/) + +The default profile response will look like this: + +```javascript +credentials.profile = { + id: profile.id, + username: profile.id, + displayName: profile.display_name, + email: profile.email, + raw: profile, +}; +``` + +### trakt.tv + +[Provider Documentation](http://docs.trakt.apiary.io/#reference/authentication-oauth) + +- `scope`: not applicable +- `config`: not applicable +- `auth`: https://api.trakt.tv/oauth/authorize +- `token`: https://api.trakt.tv/oauth/token + +The default profile response will look like this: + +```javascript +credentials.profile = { + username: profile.username, + private: profile.private, + joined_at: profile.joined_at, + name: profile.name, + vip: profile.vip, + ids: profile.ids, + location: profile.location, + about: profile.about, + gender: profile.gender, + age: profile.age, + images: profile.images, +}; +``` + +### Twitter + +[Provider Documentation](https://dev.twitter.com/oauth) + +- `scope`: not applicable +- `config`: + - `extendedProfile`: Request for more profile information + - `getMethod`: [Twitter API](https://dev.twitter.com/rest/public) GET method to call when `extendedProfile` is enabled. Defaults to `'users/show'` + - `getParams`: Additional parameters to pass to the GET method. For example, the `include_email` parameter for the [`account/verify` route](https://dev.twitter.com/rest/reference/get/account/verify_credentials) +- `temporary`: 'https://api.twitter.com/oauth/request_token' +- `auth`: https://api.twitter.com/oauth/authenticate +- `token`: https://api.twitter.com/oauth/access_token + +The default profile response will look like this: + +```javascript +credentials.profile = { + id: params.user_id, + username: params.screen_name, +}; + +// credentials.profile.raw will contain extendedProfile if enabled +``` + +### Vk + +[Provider Documentation](https://vk.com/dev/auth_sites) + +- `scope`: No default scope +- `config`: not applicable +- `auth`: https://oauth.vk.com/authorize +- `token`: https://oauth.vk.com/access_token + +The default profile response will look like this: + +```javascript +credentials.profile = { + id: profile.uid, + displayName: profile.first_name + ' ' + profile.last_name, + name: { + first: profile.first_name, + last: profile.last_name, + }, + raw: profile, +}; +``` + +### Yahoo + +[Provider Documentation](https://developer.yahoo.com/oauth/) + +- `scope`: not applicable +- `config`: not applicable +- `temporary`: https://api.login.yahoo.com/oauth/v2/get_request_token +- `auth`: https://api.login.yahoo.com/oauth/v2/request_auth +- `token`: https://api.login.yahoo.com/oauth/v2/get_token + +The default profile response will look like this: + +```javascript +credentials.profile = { + id: profile.profile.guid, + displayName: profile.profile.givenName + ' ' + profile.profile.familyName, + name: { + first: profile.profile.givenName, + last: profile.profile.familyName, + }, + raw: profile, +}; +``` + +### Tumblr + +[Provider Documentation](https://www.tumblr.com/docs/en/api/v2#auth) + +- `scope`: not applicable +- `temporary`: https://www.tumblr.com/oauth/request_token +- `auth`: https://www.tumblr.com/oauth/authorize +- `token`: https://www.tumblr.com/oauth/access_token + +The default profile response will look like this: + +```javascript +credentials.profile = { + username: profile.response.user.name, + raw: profile.response.user, +}; +``` + +### Twitch + +[Provider Documentation](https://github.com/justintv/Twitch-API/blob/master/authentication.md) + +- `scope`: Defaults to `'user_read'` +- `auth`: https://api.twitch.tv/kraken/oauth2/authorize +- `token`: https://api.twitch.tv/kraken/oauth2/token + +The default profile response will look like this: + +```javascript +// default profile response from Twitch +``` + +### Salesforce + +[Provider Documentation](https://developer.salesforce.com/page/Digging_Deeper_into_OAuth_2.0_on_Force.com) + +- `scope`: not applicable +- `config`: + - `uri`: Point to your Salesforce org. Defaults to `https://login.salesforce.com` + - `extendedProfile`: Request for more profile information. Defaults to true + - `identityServiceProfile`: Determines if the profile information fetch uses the [Force.com Identity Service](https://developer.salesforce.com/page/Digging_Deeper_into_OAuth_2.0_on_Force.com#The_Force.com_Identity_Service). Defaults to false (UserInfo Endpoint) +- `auth`: /services/oauth2/authorize +- `token`: /services/oauth2/token + +The default profile response will look like this: [UserInfo Response](https://developer.salesforce.com/page/Inside_OpenID_Connect_on_Force.com#User_Profile_Service) + +```javascript +credentials.profile = { + "sub": "https://login.salesforce.com/id/00Dx0000000A9y0EAC/005x0000000UnYmAAK", + "user_id": "005x0000000UnYmAAK", + "organization_id": "00Dx0000000A9y0EAC", + "preferred_username": "user@ example.com", + "nickname": "user", + "name": "Pat Patterson", + "email": "user@ example.com", + "email_verified": true, + "given_name": "Pat", + "family_name": "Patterson", + ... +} +``` + +The Force.com Identity profile response will look like this: [Force.com Identity Response](https://developer.salesforce.com/page/Digging_Deeper_into_OAuth_2.0_on_Force.com#The_Force.com_Identity_Service) + +```javascript +credentials.profile = { + "id":"https://login.salesforce.com/id/00D50000000IZ3ZEAW/00550000001fg5OAAQ", + "asserted_user":true, + "user_id":"00550000001fg5OAAQ", + "organization_id":"00D50000000IZ3ZEAW", + "username":"user@ example. com", + "nick_name":"user1.2950476911907334E12", + "display_name":"Sample User", + "email":"user@ example. com", + "email_verified": true, + "first_name": "Sample", + "last_name": "User", + ... +} +``` + +### Stripe + +[Provider Documentation](https://stripe.com/docs/connect/oauth-reference) + +- `scope`: defaults to `read_only` scope +- `config`: not applicable +- `auth`: https://connect.stripe.com/oauth/authorize +- `token`: https://connect.stripe.com/oauth/token + +The default profile response will look like this: + +```javascript +credentials.profile = { + id: profile.id, + legalName: profile.business_name, + displayName: profile.display_name, + email: profile.email, + raw: profile, +}; +``` + +### Office 365 + +[Provider Documentation](https://msdn.microsoft.com/en-us/library/azure/dn645545.aspx) + +- `scope`: Defaults to `['openid','offline_access', 'profile']` +- `config`: not applicable +- `auth`: https://login.microsoftonline.com/common/oauth2/v2.0/authorize +- `token`: https://login.microsoftonline.com/common/oauth2/v2.0/token + +The default profile response will look like this: + +```javascript +credentials.profile = { + id: profile.Id, + displayName: profile.DisplayName, + email: profile.EmailAddress, + raw: profile, +}; +``` + +### Okta + +[Provider Documentation](http://developer.okta.com/use_cases/authentication/) + +- `scope`: Defaults to `['openid', 'email', 'offline_access']` +- `config`: + - `uri`: Point to your Okta enterprise uri. Intentionally no default as Okta is organization specific. + - `authorizationServerId`: If you are using a [custom authorization server](https://support.okta.com/help/s/article/Difference-Between-Okta-as-An-Authorization-Server-vs-Custom-Authorization-Server) you need to pass the alphanumeric ID here. +- `auth`: https://your-organization.okta.com/oauth2/v1/authorize +- `token`: https://your-organization.okta.com/oauth2/v1/token + +The default profile response will look like this: + +```javascript +credentials.profile = { + id: profile.sub, + username: profile.email, + displayName: profile.nickname, + firstName: profile.given_name, + lastName: profile.family_name, + email: profile.email, + raw: profile, +}; +``` + +### WordPress + +[Provider Documentation](https://developer.wordpress.com/docs/api/) + +- `scope`: Defaults to `'global'` +- `auth`: /oauth2/authorize +- `token`: /oauth2/token + +The default profile response will look like this: + +```javascript +credentials.profile = { + id: profile.ID, + username: profile.username, + displayName: profile.display_name, + raw: profile, +}; +``` + +## Writing a new provider + +When writing a new provider see existing implementations (in `lib/providers`) for reference as well as any documentation provided by your provider. You may want to support `uri` or `extendedProfile` options depending on your needs. diff --git a/generated/markdown/boom/10/api.md b/generated/markdown/boom/10/api.md new file mode 100644 index 00000000..4e28c58d --- /dev/null +++ b/generated/markdown/boom/10/api.md @@ -0,0 +1,819 @@ +**boom** provides a set of utilities for returning HTTP errors. Each utility returns a `Boom` +error response object which includes the following properties: + +- `isBoom` - if `true`, indicates this is a `Boom` object instance. Note that this boolean should + only be used if the error is an instance of `Error`. If it is not certain, use `Boom.isBoom()` + instead. +- `isServer` - convenience bool indicating status code >= 500. +- `message` - the error message. +- `typeof` - the constructor used to create the error (e.g. `Boom.badRequest`). +- `output` - the formatted response. Can be directly manipulated after object construction to return a custom + error response. Allowed root keys: + - `statusCode` - the HTTP status code (typically 4xx or 5xx). + - `headers` - an object containing any HTTP headers where each key is a header name and value is the header content. + - `payload` - the formatted object used as the response payload (stringified). Can be directly manipulated but any + changes will be lost + if `reformat()` is called. Any content allowed and by default includes the following content: + - `statusCode` - the HTTP status code, derived from `error.output.statusCode`. + - `error` - the HTTP status message (e.g. 'Bad Request', 'Internal Server Error') derived from `statusCode`. + - `message` - the error message derived from `error.message`. +- inherited `Error` properties. + +The `Boom` object also supports the following method: + +#### `reformat(debug)` + +Rebuilds `error.output` using the other object properties where: + +- `debug` - a Boolean that, when `true`, causes Internal Server Error messages to be left in tact. Defaults to `false`, meaning that Internal Server Error messages are redacted. + +Note that `Boom` object will return `true` when used with `instanceof Boom`, but do not use the +`Boom` prototype (they are either plain `Error` or the error prototype passed in). This means +`Boom` objects should only be tested using `instanceof Boom` or `Boom.isBoom()` but not by looking +at the prototype or contructor information. This limitation is to avoid manipulating the prototype +chain which is very slow. + +#### Helper Methods + +##### `new Boom.Boom(message, [options])` + +Creates a new `Boom` object using the provided `message` and then calling +[`boomify()`](#boomifyerr-options) to decorate the error with the `Boom` properties, where: + +- `message` - the error message. If `message` is an error, it is the same as calling + [`boomify()`](#boomifyerr-options) directly. +- `options` - and optional object where: + - `statusCode` - the HTTP status code. Defaults to `500` if no status code is already set. + - `data` - additional error information (assigned to `error.data`). + - `decorate` - an option with extra properties to set on the error object. + - `ctor` - constructor reference used to crop the exception call stack output. + - if `message` is an error object, also supports the other [`boomify()`](#boomifyerr-options) + options. + +##### `boomify(err, [options])` + +Decorates an error with the `Boom` properties where: + +- `err` - the `Error` object to decorate. +- `options` - optional object with the following optional settings: + - `statusCode` - the HTTP status code. Defaults to `500` if no status code is already set and `err` is not a `Boom` object. + - `message` - error message string. If the error already has a message, the provided `message` is added as a prefix. + Defaults to no message. + - `decorate` - an option with extra properties to set on the error object. + - `override` - if `false`, the `err` provided is a `Boom` object, and a `statusCode` or `message` are provided, + the values are ignored. Defaults to `true` (apply the provided `statusCode` and `message` options to the error + regardless of its type, `Error` or `Boom` object). + +```js +var error = new Error('Unexpected input'); +Boom.boomify(error, { statusCode: 400 }); +``` + +##### `isBoom(err, [statusCode])` + +Identifies whether an error is a `Boom` object. Same as calling `instanceof Boom.Boom`. + +- `err` - Error object. +- `statusCode` - optional status code. + +```js +Boom.isBoom(Boom.badRequest()); // true +Boom.isBoom(Boom.badRequest(), 400); // true +``` + +#### HTTP 4xx Errors + +##### `Boom.badRequest([message], [data])` + +Returns a 400 Bad Request error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.badRequest('invalid query'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 400, + "error": "Bad Request", + "message": "invalid query" +} +``` + +##### `Boom.unauthorized([message], [scheme], [attributes])` + +Returns a 401 Unauthorized error where: + +- `message` - optional message. +- `scheme` can be one of the following: + - an authentication scheme name + - an array of string values. These values will be separated by ', ' and set to the 'WWW-Authenticate' header. +- `attributes` - an object of values to use while setting the 'WWW-Authenticate' header. This value is only used + when `scheme` is a string, otherwise it is ignored. Every key/value pair will be included in the + 'WWW-Authenticate' in the format of 'key="value"' as well as in the response payload under the `attributes` key. Alternatively value can be a string which is use to set the value of the scheme, for example setting the token value for negotiate header. If string is used message parameter must be null. + `null` and `undefined` will be replaced with an empty string. If `attributes` is set, `message` will be used as + the 'error' segment of the 'WWW-Authenticate' header. If `message` is unset, the 'error' segment of the header + will not be present and `isMissing` will be true on the error object. + +If either `scheme` or `attributes` are set, the resultant `Boom` object will have the +'WWW-Authenticate' header set for the response. + +```js +Boom.unauthorized('invalid password'); +``` + +Generates the following response: + +```json +"payload": { + "statusCode": 401, + "error": "Unauthorized", + "message": "invalid password" +}, +"headers": {} +``` + +```js +Boom.unauthorized('invalid password', 'sample'); +``` + +Generates the following response: + +```json +"payload": { + "statusCode": 401, + "error": "Unauthorized", + "message": "invalid password", + "attributes": { + "error": "invalid password" + } +}, +"headers": { + "WWW-Authenticate": "sample error=\"invalid password\"" +} +``` + +```js +Boom.unauthorized(null, 'Negotiate', 'VGhpcyBpcyBhIHRlc3QgdG9rZW4='); +``` + +Generates the following response: + +```json +"payload": { + "statusCode": 401, + "error": "Unauthorized", + "attributes": "VGhpcyBpcyBhIHRlc3QgdG9rZW4=" +}, +"headers": { + "WWW-Authenticate": "Negotiate VGhpcyBpcyBhIHRlc3QgdG9rZW4=" +} +``` + +```js +Boom.unauthorized('invalid password', 'sample', { + ttl: 0, + cache: null, + foo: 'bar', +}); +``` + +Generates the following response: + +```json +"payload": { + "statusCode": 401, + "error": "Unauthorized", + "message": "invalid password", + "attributes": { + "error": "invalid password", + "ttl": 0, + "cache": "", + "foo": "bar" + } +}, +"headers": { + "WWW-Authenticate": "sample ttl=\"0\", cache=\"\", foo=\"bar\", error=\"invalid password\"" +} +``` + +##### `Boom.paymentRequired([message], [data])` + +Returns a 402 Payment Required error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.paymentRequired('bandwidth used'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 402, + "error": "Payment Required", + "message": "bandwidth used" +} +``` + +##### `Boom.forbidden([message], [data])` + +Returns a 403 Forbidden error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.forbidden('try again some time'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 403, + "error": "Forbidden", + "message": "try again some time" +} +``` + +##### `Boom.notFound([message], [data])` + +Returns a 404 Not Found error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.notFound('missing'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 404, + "error": "Not Found", + "message": "missing" +} +``` + +##### `Boom.methodNotAllowed([message], [data], [allow])` + +Returns a 405 Method Not Allowed error where: + +- `message` - optional message. +- `data` - optional additional error data. +- `allow` - optional string or array of strings (to be combined and separated by ', ') which is set to the 'Allow' header. + +```js +Boom.methodNotAllowed('that method is not allowed'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 405, + "error": "Method Not Allowed", + "message": "that method is not allowed" +} +``` + +##### `Boom.notAcceptable([message], [data])` + +Returns a 406 Not Acceptable error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.notAcceptable('unacceptable'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 406, + "error": "Not Acceptable", + "message": "unacceptable" +} +``` + +##### `Boom.proxyAuthRequired([message], [data])` + +Returns a 407 Proxy Authentication Required error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.proxyAuthRequired('auth missing'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 407, + "error": "Proxy Authentication Required", + "message": "auth missing" +} +``` + +##### `Boom.clientTimeout([message], [data])` + +Returns a 408 Request Time-out error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.clientTimeout('timed out'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 408, + "error": "Request Time-out", + "message": "timed out" +} +``` + +##### `Boom.conflict([message], [data])` + +Returns a 409 Conflict error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.conflict('there was a conflict'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 409, + "error": "Conflict", + "message": "there was a conflict" +} +``` + +##### `Boom.resourceGone([message], [data])` + +Returns a 410 Gone error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.resourceGone('it is gone'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 410, + "error": "Gone", + "message": "it is gone" +} +``` + +##### `Boom.lengthRequired([message], [data])` + +Returns a 411 Length Required error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.lengthRequired('length needed'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 411, + "error": "Length Required", + "message": "length needed" +} +``` + +##### `Boom.preconditionFailed([message], [data])` + +Returns a 412 Precondition Failed error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.preconditionFailed(); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 412, + "error": "Precondition Failed" +} +``` + +##### `Boom.entityTooLarge([message], [data])` + +Returns a 413 Request Entity Too Large error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.entityTooLarge('too big'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 413, + "error": "Request Entity Too Large", + "message": "too big" +} +``` + +##### `Boom.uriTooLong([message], [data])` + +Returns a 414 Request-URI Too Large error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.uriTooLong('uri is too long'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 414, + "error": "Request-URI Too Large", + "message": "uri is too long" +} +``` + +##### `Boom.unsupportedMediaType([message], [data])` + +Returns a 415 Unsupported Media Type error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.unsupportedMediaType('that media is not supported'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 415, + "error": "Unsupported Media Type", + "message": "that media is not supported" +} +``` + +##### `Boom.rangeNotSatisfiable([message], [data])` + +Returns a 416 Requested Range Not Satisfiable error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.rangeNotSatisfiable(); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 416, + "error": "Requested Range Not Satisfiable" +} +``` + +##### `Boom.expectationFailed([message], [data])` + +Returns a 417 Expectation Failed error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.expectationFailed('expected this to work'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 417, + "error": "Expectation Failed", + "message": "expected this to work" +} +``` + +##### `Boom.teapot([message], [data])` + +Returns a 418 I'm a Teapot error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.teapot('sorry, no coffee...'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 418, + "error": "I'm a Teapot", + "message": "Sorry, no coffee..." +} +``` + +##### `Boom.badData([message], [data])` + +Returns a 422 Unprocessable Entity error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.badData('your data is bad and you should feel bad'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 422, + "error": "Unprocessable Entity", + "message": "your data is bad and you should feel bad" +} +``` + +##### `Boom.locked([message], [data])` + +Returns a 423 Locked error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.locked('this resource has been locked'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 423, + "error": "Locked", + "message": "this resource has been locked" +} +``` + +##### `Boom.failedDependency([message], [data])` + +Returns a 424 Failed Dependency error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.failedDependency('an external resource failed'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 424, + "error": "Failed Dependency", + "message": "an external resource failed" +} +``` + +##### `Boom.tooEarly([message], [data])` + +Returns a 425 Too Early error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.tooEarly('the server is unwilling to risk processing the request'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 425, + "error": "Too Early", + "message": "the server is unwilling to risk processing the request" +} +``` + +##### `Boom.preconditionRequired([message], [data])` + +Returns a 428 Precondition Required error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.preconditionRequired('you must supply an If-Match header'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 428, + "error": "Precondition Required", + "message": "you must supply an If-Match header" +} +``` + +##### `Boom.tooManyRequests([message], [data])` + +Returns a 429 Too Many Requests error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.tooManyRequests('you have exceeded your request limit'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 429, + "error": "Too Many Requests", + "message": "you have exceeded your request limit" +} +``` + +##### `Boom.illegal([message], [data])` + +Returns a 451 Unavailable For Legal Reasons error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.illegal('you are not permitted to view this resource for legal reasons'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 451, + "error": "Unavailable For Legal Reasons", + "message": "you are not permitted to view this resource for legal reasons" +} +``` + +#### HTTP 5xx Errors + +All 500 errors hide your message from the end user. + +##### `Boom.badImplementation([message], [data])` - (_alias: `internal`_) + +Returns a 500 Internal Server Error error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.badImplementation('terrible implementation'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 500, + "error": "Internal Server Error", + "message": "An internal server error occurred" +} +``` + +##### `Boom.notImplemented([message], [data])` + +Returns a 501 Not Implemented error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.notImplemented('method not implemented'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 501, + "error": "Not Implemented", + "message": "method not implemented" +} +``` + +##### `Boom.badGateway([message], [data])` + +Returns a 502 Bad Gateway error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.badGateway('that is a bad gateway'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 502, + "error": "Bad Gateway", + "message": "that is a bad gateway" +} +``` + +##### `Boom.serverUnavailable([message], [data])` + +Returns a 503 Service Unavailable error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.serverUnavailable('unavailable'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 503, + "error": "Service Unavailable", + "message": "unavailable" +} +``` + +##### `Boom.gatewayTimeout([message], [data])` + +Returns a 504 Gateway Time-out error where: + +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.gatewayTimeout(); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 504, + "error": "Gateway Time-out" +} +``` + +#### F.A.Q. + +**Q** How do I include extra information in my responses? `output.payload` is missing `data`, what gives? + +**A** There is a reason the values passed back in the response payloads are pretty locked down. It's mostly for security and to not leak any important information back to the client. This means you will need to put in a little more effort to include extra information about your custom error. Check out the ["Error transformation"](https://github.com/hapijs/hapi/blob/master/API.md#error-transformation) section in the hapi documentation. diff --git a/generated/markdown/boom/changelog.md b/generated/markdown/boom/changelog.md new file mode 100644 index 00000000..66f285f9 --- /dev/null +++ b/generated/markdown/boom/changelog.md @@ -0,0 +1,322 @@ +## Version 10 {#v10} + +### [10.0.1](https://github.com/hapijs/boom/milestone/69) {#10.0.1} + +- [#299](https://github.com/hapijs/boom/pull/299) chore: bump hoek and lab +- [#297](https://github.com/hapijs/boom/pull/297) Document 1st arg can be an Error + +### [10.0.0](https://github.com/hapijs/boom/milestone/68) {#10.0.0} + +- [#295](https://github.com/hapijs/boom/pull/295) Support node v18, drop node v12 + +## Version 9 {#v9} + +### [9.1.4](https://github.com/hapijs/boom/milestone/66) {#9.1.4} + +- [#289](https://github.com/hapijs/boom/pull/289) fix: make reformat configurable in initialize + +### [9.1.3](https://github.com/hapijs/boom/milestone/64) {#9.1.3} + +- [#286](https://github.com/hapijs/boom/pull/286) Don't mess with instanceof checks called on subclasses +- [#285](https://github.com/hapijs/boom/issues/285) Extending Boom and unexpected instanceof behavior + +### [9.1.2](https://github.com/hapijs/boom/milestone/63) {#9.1.2} + +- [#281](https://github.com/hapijs/boom/pull/281) Add proper index type to headers property + +### [9.1.1](https://github.com/hapijs/boom/milestone/62) {#9.1.1} + +- [#279](https://github.com/hapijs/boom/pull/279) TypeScript: Allow custom properties on output.payload +- [#278](https://github.com/hapijs/boom/pull/278) Clean up d.ts comments +- [#277](https://github.com/hapijs/boom/issues/277) output.payload.attributes is not exposed in the .d.ts file +- [#275](https://github.com/hapijs/boom/pull/275) Make isBoom type definition laxer +- [#273](https://github.com/hapijs/boom/pull/273) upgrade lab to v24 and devDependency of typescript + +### [9.1.0](https://github.com/hapijs/boom/milestone/61) {#9.1.0} + +- [#266](https://github.com/hapijs/boom/pull/266) Add optional statusCode parameter to Boom.isBoom +- [#265](https://github.com/hapijs/boom/issues/265) Optional second param for Boom.isBoom() to verify status code + +### [9.0.0](https://github.com/hapijs/boom/milestone/60) {#9.0.0} + +- [#262](https://github.com/hapijs/boom/issues/262) Support only node 12 +- [#261](https://github.com/hapijs/boom/pull/261) Add HTTP code 425 Too Early +- [#260](https://github.com/hapijs/boom/issues/260) boom.unathorized adds extra space to string value scheme in WWW-Authenticate header + +## Version 8 {#v8} + +### [8.0.1](https://github.com/hapijs/boom/milestone/58) {#8.0.1} + +- [#253](https://github.com/hapijs/boom/issues/253) change new Boom() to new Boom.Boom() +- [#252](https://github.com/hapijs/boom/issues/252) Drop support for node 8 +- [#251](https://github.com/hapijs/boom/issues/251) Add types +- [#246](https://github.com/hapijs/boom/issues/246) boom doesn't consider message not set directly on error object when deciding whether it is a compatible error + +## Version 7 {#v7} + +### [7.4.12](https://github.com/hapijs/boom/milestone/65) {#7.4.12} + +- [#282](https://github.com/hapijs/boom/issues/282) Latest v7-commercial release (v7.4.11) is broken + +### [7.4.11](https://github.com/hapijs/boom/milestone/56) {#7.4.11} + +- [#248](https://github.com/hapijs/boom/issues/248) Error TS2709: Cannot use namespace 'Boom' as a type. + +### [7.4.10](https://github.com/hapijs/boom/milestone/55) {#7.4.10} + +- [#245](https://github.com/hapijs/boom/pull/245) Fix default export. Fixes #244. +- [#244](https://github.com/hapijs/boom/issues/244) Typescript - can't extend Boom + +### [7.4.9](https://github.com/hapijs/boom/milestone/54) {#7.4.9} + +- [#243](https://github.com/hapijs/boom/issues/243) Improve types + +### [7.4.8](https://github.com/hapijs/boom/milestone/53) {#7.4.8} + +- [#242](https://github.com/hapijs/boom/issues/242) Typescript definitions missing internal() +- [#241](https://github.com/hapijs/boom/pull/241) Ts fix +- [#240](https://github.com/hapijs/boom/pull/240) Fix types: Update static isBoom to be a type guard. + +### [7.4.7](https://github.com/hapijs/boom/milestone/52) {#7.4.7} + +- [#239](https://github.com/hapijs/boom/issues/239) Missing error properties + +### [7.4.6](https://github.com/hapijs/boom/milestone/51) {#7.4.6} + +- [#238](https://github.com/hapijs/boom/pull/238) Fix types: serviceUnavailable -> serverUnavailable. +- [#237](https://github.com/hapijs/boom/issues/237) Types have typo: serverUnavailable -> serviceUnavailable + +### [7.4.5](https://github.com/hapijs/boom/milestone/50) {#7.4.5} + +- [#216](https://github.com/hapijs/boom/issues/216) Handle case of message property with getter-only +- [#215](https://github.com/hapijs/boom/issues/215) `typeof` and `reformat` should not be enumerable + +### [7.4.4](https://github.com/hapijs/boom/milestone/49) {#7.4.4} + +- [#233](https://github.com/hapijs/boom/pull/233) Added TS declarations + +### [7.4.3](https://github.com/hapijs/boom/milestone/48) {#7.4.3} + +- [#229](https://github.com/hapijs/boom/issues/229) Update deps + +### [7.4.2](https://github.com/hapijs/boom/milestone/47) {#7.4.2} + +- [#221](https://github.com/hapijs/boom/issues/221) Update deps + +### [7.4.1](https://github.com/hapijs/boom/milestone/46) {#7.4.1} + +- [#220](https://github.com/hapijs/boom/issues/220) Fix dependency + +### [7.4.0](https://github.com/hapijs/boom/milestone/42) {#7.4.0} + +- [#219](https://github.com/hapijs/boom/issues/219) Change module namespace + +### [7.3.0](https://github.com/hapijs/boom/milestone/41) {#7.3.0} + +- [#211](https://github.com/hapijs/boom/pull/211) add debug mode to reformat() + +### [7.2.2](https://github.com/hapijs/boom/milestone/40) {#7.2.2} + +- [#208](https://github.com/hapijs/boom/issues/208) Remove engines + +### [7.2.1](https://github.com/hapijs/boom/milestone/39) {#7.2.1} + +- [#206](https://github.com/hapijs/boom/issues/206) Update hoek v6 + +### [7.2.0](https://github.com/hapijs/boom/milestone/38) {#7.2.0} + +- [#188](https://github.com/hapijs/boom/pull/188) 424 Failed dependency implementation + +### [7.1.1](https://github.com/hapijs/boom/milestone/37) {#7.1.1} + +- [#173](https://github.com/hapijs/boom/issues/173) Support instanceof + +### [7.1.0](https://github.com/hapijs/boom/milestone/36) {#7.1.0} + +- [#172](https://github.com/hapijs/boom/issues/172) Add decorate option + +### [7.0.0](https://github.com/hapijs/boom/milestone/35) {#7.0.0} + +- [#171](https://github.com/hapijs/boom/issues/171) Remove wrap() and create() + +## Version 6 {#v6} + +### [6.0.0](https://github.com/hapijs/boom/milestone/34) {#6.0.0} + +- [#165](https://github.com/hapijs/boom/issues/165) Node v8 + +## Version 5 {#v5} + +### [5.3.1](https://github.com/hapijs/boom/milestone/44) {#5.3.1} + +- [#218](https://github.com/hapijs/boom/issues/218) Load the commercial version of hoek + +### [5.3.0](https://github.com/hapijs/boom/milestone/43) {#5.3.0} + +- [#217](https://github.com/hapijs/boom/issues/217) Commercial version of v5 branch + +### [5.2.0](https://github.com/hapijs/boom/milestone/33) {#5.2.0} + +- [#160](https://github.com/hapijs/boom/issues/160) Allow decorating a boom error + +### [5.1.0](https://github.com/hapijs/boom/milestone/32) {#5.1.0} + +- [#157](https://github.com/hapijs/boom/issues/157) Hide message on 500 when error is provided as data +- [#156](https://github.com/hapijs/boom/pull/156) Added typeOf functionality + +### [5.0.0](https://github.com/hapijs/boom/milestone/31) {#5.0.0} + +- [#154](https://github.com/hapijs/boom/issues/154) Boom.wrap with a provided message doesn't format the payload +- [#152](https://github.com/hapijs/boom/issues/152) Boom.badGateway( string, Boom.anything() ) + +## Version 4 {#v4} + +### [4.3.1](https://github.com/hapijs/boom/milestone/30) {#4.3.1} + +- [#149](https://github.com/hapijs/boom/pull/149) fix #148 when Boom supplied to wrapper +- [#148](https://github.com/hapijs/boom/issues/148) Remove line from wrap function + +### [4.3.0](https://github.com/hapijs/boom/milestone/29) {#4.3.0} + +- [#147](https://github.com/hapijs/boom/pull/147) Unauthorized extension for #146 +- [#146](https://github.com/hapijs/boom/issues/146) Unauthorized +- [#142](https://github.com/hapijs/boom/issues/142) Boom.wrap never sends custom message to client +- [#139](https://github.com/hapijs/boom/pull/139) Adds support for `Boom.someMethod(err)`, closes #138 +- [#138](https://github.com/hapijs/boom/issues/138) Preservation of `err.name` via `Boom.create` or `Boom[someMethod]` +- [#78](https://github.com/hapijs/boom/pull/78) Add Boom.teapot() method with documentation and tests + +### [4.2.0](https://github.com/hapijs/boom/milestone/28) {#4.2.0} + +- [#133](https://github.com/hapijs/boom/pull/133) Add 'allow' parameter to methodNotAllowed for setting 'Allow' header +- [#132](https://github.com/hapijs/boom/issues/132) 405 Method Not Allowed should provide an argument for specifying "Allow" header + +### [4.1.0](https://github.com/hapijs/boom/milestone/27) {#4.1.0} + +- [#130](https://github.com/hapijs/boom/pull/130) Add 402 payment required +- [#129](https://github.com/hapijs/boom/pull/129) Add Boom.internal() to API docs fixes #127 + +### [4.0.0](https://github.com/hapijs/boom/milestone/26) {#4.0.0} + +- [#125](https://github.com/hapijs/boom/pull/125) Remove deprecated serverTimeout +- [#118](https://github.com/hapijs/boom/issues/118) Remove serverTimeout() + +## Version 3 {#v3} + +### [3.2.2](https://github.com/hapijs/boom/milestone/25) {#3.2.2} + +- [#121](https://github.com/hapijs/boom/pull/121) Added .npmignore file. +- [#119](https://github.com/hapijs/boom/pull/119) Rename serverTimeout to serverUnavailable +- [#117](https://github.com/hapijs/boom/issues/117) serverTimeout() should be aliased to serverUnavailable() +- [#108](https://github.com/hapijs/boom/pull/108) Create .npmignore + +### [3.2.1](https://github.com/hapijs/boom/milestone/24) {#3.2.1} + +- [#113](https://github.com/hapijs/boom/pull/113) Updated to code 3. + +### [3.2.0](https://github.com/hapijs/boom/milestone/23) {#3.2.0} + +- [#112](https://github.com/hapijs/boom/pull/112) Added HTTP code 423 Locked +- [#111](https://github.com/hapijs/boom/issues/111) HTTP Error 423 (Locked) + +### [3.1.3](https://github.com/hapijs/boom/milestone/22) {#3.1.3} + +- [#110](https://github.com/hapijs/boom/pull/110) Added node 6. + +### [3.1.2](https://github.com/hapijs/boom/milestone/21) {#3.1.2} + +- [#97](https://github.com/hapijs/boom/pull/97) Use quotes instead of backticks + +### [3.1.1](https://github.com/hapijs/boom/milestone/20) {#3.1.1} + +- [#95](https://github.com/hapijs/boom/pull/95) Changed prototype logic. + +### [3.1.0](https://github.com/hapijs/boom/milestone/19) {#3.1.0} + +- [#94](https://github.com/hapijs/boom/pull/94) Cleanup for 254593fd1d09e79049692675a4f9b7b5108b36d8 +- [#93](https://github.com/hapijs/boom/issues/93) Document Illegal +- [#92](https://github.com/hapijs/boom/issues/92) Status Code Hash +- [#91](https://github.com/hapijs/boom/pull/91) Add new 451 Unavailable For Legal Reasons + +### [3.0.0](https://github.com/hapijs/boom/milestone/18) {#3.0.0} + +- [#83](https://github.com/hapijs/boom/pull/83) es6 style. Closes #77 +- [#77](https://github.com/hapijs/boom/issues/77) Node 4 Updates + +## Version 2 {#v2} + +### [2.10.1](https://github.com/hapijs/boom/milestone/17) {#2.10.1} + +- [#81](https://github.com/hapijs/boom/pull/81) Upgrade to lab 7.x.x +- [#80](https://github.com/hapijs/boom/pull/80) Fix ctor passing in serverError helper +- [#79](https://github.com/hapijs/boom/issues/79) Stack trace filtering not working for serverError constructors + +### [2.10.0](https://github.com/hapijs/boom/milestone/16) {#2.10.0} + +- [#75](https://github.com/hapijs/boom/pull/75) Support Precondition Required +- [#74](https://github.com/hapijs/boom/issues/74) Precondition required is not supported + +### [2.9.0](https://github.com/hapijs/boom/milestone/15) {#2.9.0} + +- [#68](https://github.com/hapijs/boom/pull/68) Call captureStackTrace to filter boom from traces +- [#67](https://github.com/hapijs/boom/issues/67) Use captureStackTrace to remove boom artifacts from stack traces + +### [2.8.0](https://github.com/hapijs/boom/milestone/14) {#2.8.0} + +- [#63](https://github.com/hapijs/boom/pull/63) Unauthorized +- [#62](https://github.com/hapijs/boom/issues/62) Expose unauthorized attributes in payload +- [#60](https://github.com/hapijs/boom/issues/60) Style Cleanup + +### [2.7.2](https://github.com/hapijs/boom/milestone/13) {#2.7.2} + +- [#59](https://github.com/hapijs/boom/pull/59) Update license attribute + +### [2.7.1](https://github.com/hapijs/boom/milestone/12) {#2.7.1} + +- [#52](https://github.com/hapijs/boom/pull/52) Coerse statusCode to an Integer +- [#51](https://github.com/hapijs/boom/issues/51) Make sure Boom initialize method auto cast string statusCode to Integer if possible + +### [2.7.0](https://github.com/hapijs/boom/milestone/11) {#2.7.0} + +- [#45](https://github.com/hapijs/boom/pull/45) Added isServer +- [#41](https://github.com/hapijs/boom/issues/41) Easy way to determine if the client or server is at fault + +### [2.6.1](https://github.com/hapijs/boom/milestone/10) {#2.6.1} + +- [#40](https://github.com/hapijs/boom/issues/40) Lab 5.0, code 1.0 + +### [2.6.0](https://github.com/hapijs/boom/milestone/9) {#2.6.0} + +- [#33](https://github.com/hapijs/boom/pull/33) Added status code 429 Too Many Requests. + +### [2.5.1](https://github.com/hapijs/boom/milestone/8) {#2.5.1} + +- [#27](https://github.com/hapijs/boom/pull/27) Update to lab 4.x.x. Bumped version. + +### [2.5.0](https://github.com/hapijs/boom/milestone/7) {#2.5.0} + +- [#26](https://github.com/hapijs/boom/issues/26) Rename spumko to hapijs +- [#25](https://github.com/hapijs/boom/pull/25) Add a 422 badData method + +### [2.4.2](https://github.com/hapijs/boom/milestone/5) {#2.4.2} + +- [#23](https://github.com/hapijs/boom/issues/23) Default message to http status + +### [2.4.1](https://github.com/hapijs/boom/milestone/6) {#2.4.1} + +- [#22](https://github.com/hapijs/boom/issues/22) Upgrade dependencies + +### [2.4.0](https://github.com/hapijs/boom/milestone/4) {#2.4.0} + +- [#21](https://github.com/hapijs/boom/issues/21) Allow every helper to set data property + +### [2.3.0](https://github.com/hapijs/boom/milestone/2) {#2.3.0} + +- [#20](https://github.com/hapijs/boom/issues/20) Internal errors (500) should never expose err.message + +### [2.2.2](https://github.com/hapijs/boom/milestone/3) {#2.2.2} + +- [#19](https://github.com/hapijs/boom/issues/19) Bring coverage back to 100% after lab fix + +### [2.2.1](https://github.com/hapijs/boom/milestone/1) {#2.2.1} + +- [#17](https://github.com/hapijs/boom/pull/17) Don't override data if user error already have a data attribute diff --git a/generated/markdown/bossy/5/api.md b/generated/markdown/bossy/5/api.md new file mode 100644 index 00000000..d075e430 --- /dev/null +++ b/generated/markdown/bossy/5/api.md @@ -0,0 +1,192 @@ +## Usage + +```js +const Bossy = require('@hapi/bossy'); + +const definition = { + h: { + description: 'Show help', + alias: 'help', + type: 'boolean', + }, + n: { + description: 'Show your name', + alias: 'name', + }, +}; + +const args = Bossy.parse(definition); + +if (args instanceof Error) { + console.error(args.message); + return; +} + +if (args.h || !args.n) { + console.log(Bossy.usage(definition, 'hello -n ')); + return; +} + +console.log('Hello ' + args.n); +console.log('Hello ' + args.name); +``` + +## Methods + +### `parse(definition, [options])` + +Expects a _bossy_ definition object and will return the parsed `process.argv` arguments provided. If there is an error +then the return value will be an `instanceof Error`. + +Options accepts the following keys: + +- `argv` - custom argv array value. Defaults to process.argv. + +### `usage(definition, [usage], [options])` + +Format a _bossy_ definition object for display in the console. If `usage` is provided the returned value will +include the usage value formatted at the top of the message. + +Options accepts the following keys: + +- `colors` - Determines if colors are enabled when formatting usage. Defaults to whatever TTY supports. + +### `object(name, parsed)` + +Un-flattens dot-separated arguments based at `name` from `Bossy.parse()`'s output into an object. + +```js +const Bossy = require('@hapi/bossy'); + +const definition = { + 'pet.name': { + type: 'string', + }, + 'pet.age': { + type: 'number', + }, +}; + +// Example CLI args: --pet.name Maddie --pet.age 5 + +const parsed = Bossy.parse(definition); // { 'pet.name': 'Maddie', 'pet.age': 5 } + +if (parsed instanceof Error) { + console.error(parsed.message); + return; +} + +const pet = Bossy.object('pet', parsed); // { name: 'Maddie', age: 5 } +``` + +## Definition Object + +The definition object should be structured with each object key representing the short form of an available command +line argument. Each argument key supports the following properties: + +- `alias`: A string or array of strings that can also be used as the argument name. For example: + + ```js + h: { + alias: 'help'; + } + ``` + +- `type`: Available types are: `boolean`, `range`, `number`, `string`, `json`, and `help`. Defaults to `string`. + + The `boolean` type may be negated by passing its argument prefixed with `no-`. + For example, if the command line argument is named `color` then `--color` would + ensure the boolean is `true` and `--no-color` would ensure it is `false`. + + `help` is a special type that allows the switch to be executed even though + other paramters are required. Use case is to display a help message and + quit. This will bypass all other errors, so be sure to capture it. It + behaves like a `boolean`. + + The `json` type allows building an object using command line arguments that utilize + dot-separated (`.`) paths and JSON values. For example, an object argument named + `pet` might be built from `--pet '{ "type": "dog" }' --pet.name Maddie`, resulting in + the parsing output `{ pet: { type: 'dog', name: 'Maddie' } }`. The contents of the + flags are deeply merged together in the order they were specified. Additionally, + JSON primitives (i.e. `null`, booleans, and numbers) and non-JSON are treated as strings + by default, though this behavior may be controlled with the `parsePrimitives` option + documented below. The following example demonstrates the default behavior: + + ```sh + # CLI input + create-pet --pet.type kangaroo --pet.legs 2 --pet.mammal true \ + --pet '{ "name": "Maddie", "type": "dog" }' --pet.legs 4 + ``` + + ```js + // Parsing output + { pet: { name: 'Maddie', type: 'dog', legs: '4', mammal: 'true' } } + ``` + +- `multiple` : Boolean to indicate if the same argument can be provided multiple times. If true, the parsed value + will always be an array of `type`'s. Defaults to `false`. Does not apply to `json` type arguments. + +- `description`: Description message that will be returned with usage information. + +- `require`: Boolean to indicate if the argument is required. Defaults to `false` + +- `default`: A default value to assign to the argument if its not provided as an argument. + +- `valid`: A value or array of values that the argument is allowed to equal. Does not apply to `json` type arguments. + +- `parsePrimitives`: A value of `false`, `true`, or `'strict'` used to control the treatment of input to `json` type arguments. Defaults to `false`. Each of the settings are described below: + - `false` - JSON primitives (i.e. `null`, booleans, and numbers) are treated as strings, non-JSON input is interpreted as a string, and the input may be a JSON array or object. This is the default behavior. + + ```sh + # CLI input + create-pet --pet.type kangaroo --pet.legs 2 --pet.mammal true \ + --pet '{ "name": "Maddie", "type": "dog" }' --pet.legs 4 + ``` + + ```js + // Parsing output + { pet: { name: 'Maddie', type: 'dog', legs: '4', mammal: 'true' } } + ``` + + - `true` - JSON primitives are parsed, non-JSON input is interpreted as a string, and the input may be a JSON array or object. + + For example, when `parsePrimitives` is `false`, `--pet.name null` will result in the output `{ pet: { name: 'null' } }`. However, when `parsePrimitives` is `true`, the same input would result in the output `{ pet: { name: null } }`. The same applies for other JSON primitives too, i.e. booleans and numbers. When this option is `true`, users may represent string values as JSON in order to avoid ambiguity, e.g. `--pet.name '"null"'`. It's recommended that applications using this option document the behavior for their users. + + ```sh + # CLI input + create-pet --pet.type kangaroo --pet.legs 2 --pet.mammal true \ + --pet '{ "name": "Maddie", "type": "dog" }' --pet.legs 4 + ``` + + ```js + // Parsing output + { pet: { name: 'Maddie', type: 'dog', legs: 4, mammal: true } } + ``` + + - `'strict'` - JSON primitives are parsed, non-JSON input is not allowed, and the input may not be a JSON array or object. In other words, the user may only set primitive values, and they are required to be valid JSON. + + When this option is used, users must represent string values as JSON, e.g. `--pet.name '"Maddie"'`. It's recommended that applications using this option document the behavior for their users. + + ```sh + # CLI input + create-pet --pet.type '"kangaroo"' --pet.legs 2 --pet.mammal true + ``` + + ```js + // Parsing output + { pet: { type: 'kangaroo', legs: 2, mammal: true } } + ``` + + The following input would result in an error because the input to `--pet.type` is invalid JSON: + + ```sh + # CLI input + create-pet --pet.type kangaroo --pet.legs 2 --pet.mammal true + ``` + + The following input would result in an error because the input to `--pet` does not represent a JSON primitive: + + ```sh + # CLI input + create-pet --pet '{ "name": "Maddie", "type": "dog" }' --pet.type '"kangaroo"' + ``` diff --git a/generated/markdown/bossy/6/api.md b/generated/markdown/bossy/6/api.md new file mode 100644 index 00000000..d075e430 --- /dev/null +++ b/generated/markdown/bossy/6/api.md @@ -0,0 +1,192 @@ +## Usage + +```js +const Bossy = require('@hapi/bossy'); + +const definition = { + h: { + description: 'Show help', + alias: 'help', + type: 'boolean', + }, + n: { + description: 'Show your name', + alias: 'name', + }, +}; + +const args = Bossy.parse(definition); + +if (args instanceof Error) { + console.error(args.message); + return; +} + +if (args.h || !args.n) { + console.log(Bossy.usage(definition, 'hello -n ')); + return; +} + +console.log('Hello ' + args.n); +console.log('Hello ' + args.name); +``` + +## Methods + +### `parse(definition, [options])` + +Expects a _bossy_ definition object and will return the parsed `process.argv` arguments provided. If there is an error +then the return value will be an `instanceof Error`. + +Options accepts the following keys: + +- `argv` - custom argv array value. Defaults to process.argv. + +### `usage(definition, [usage], [options])` + +Format a _bossy_ definition object for display in the console. If `usage` is provided the returned value will +include the usage value formatted at the top of the message. + +Options accepts the following keys: + +- `colors` - Determines if colors are enabled when formatting usage. Defaults to whatever TTY supports. + +### `object(name, parsed)` + +Un-flattens dot-separated arguments based at `name` from `Bossy.parse()`'s output into an object. + +```js +const Bossy = require('@hapi/bossy'); + +const definition = { + 'pet.name': { + type: 'string', + }, + 'pet.age': { + type: 'number', + }, +}; + +// Example CLI args: --pet.name Maddie --pet.age 5 + +const parsed = Bossy.parse(definition); // { 'pet.name': 'Maddie', 'pet.age': 5 } + +if (parsed instanceof Error) { + console.error(parsed.message); + return; +} + +const pet = Bossy.object('pet', parsed); // { name: 'Maddie', age: 5 } +``` + +## Definition Object + +The definition object should be structured with each object key representing the short form of an available command +line argument. Each argument key supports the following properties: + +- `alias`: A string or array of strings that can also be used as the argument name. For example: + + ```js + h: { + alias: 'help'; + } + ``` + +- `type`: Available types are: `boolean`, `range`, `number`, `string`, `json`, and `help`. Defaults to `string`. + + The `boolean` type may be negated by passing its argument prefixed with `no-`. + For example, if the command line argument is named `color` then `--color` would + ensure the boolean is `true` and `--no-color` would ensure it is `false`. + + `help` is a special type that allows the switch to be executed even though + other paramters are required. Use case is to display a help message and + quit. This will bypass all other errors, so be sure to capture it. It + behaves like a `boolean`. + + The `json` type allows building an object using command line arguments that utilize + dot-separated (`.`) paths and JSON values. For example, an object argument named + `pet` might be built from `--pet '{ "type": "dog" }' --pet.name Maddie`, resulting in + the parsing output `{ pet: { type: 'dog', name: 'Maddie' } }`. The contents of the + flags are deeply merged together in the order they were specified. Additionally, + JSON primitives (i.e. `null`, booleans, and numbers) and non-JSON are treated as strings + by default, though this behavior may be controlled with the `parsePrimitives` option + documented below. The following example demonstrates the default behavior: + + ```sh + # CLI input + create-pet --pet.type kangaroo --pet.legs 2 --pet.mammal true \ + --pet '{ "name": "Maddie", "type": "dog" }' --pet.legs 4 + ``` + + ```js + // Parsing output + { pet: { name: 'Maddie', type: 'dog', legs: '4', mammal: 'true' } } + ``` + +- `multiple` : Boolean to indicate if the same argument can be provided multiple times. If true, the parsed value + will always be an array of `type`'s. Defaults to `false`. Does not apply to `json` type arguments. + +- `description`: Description message that will be returned with usage information. + +- `require`: Boolean to indicate if the argument is required. Defaults to `false` + +- `default`: A default value to assign to the argument if its not provided as an argument. + +- `valid`: A value or array of values that the argument is allowed to equal. Does not apply to `json` type arguments. + +- `parsePrimitives`: A value of `false`, `true`, or `'strict'` used to control the treatment of input to `json` type arguments. Defaults to `false`. Each of the settings are described below: + - `false` - JSON primitives (i.e. `null`, booleans, and numbers) are treated as strings, non-JSON input is interpreted as a string, and the input may be a JSON array or object. This is the default behavior. + + ```sh + # CLI input + create-pet --pet.type kangaroo --pet.legs 2 --pet.mammal true \ + --pet '{ "name": "Maddie", "type": "dog" }' --pet.legs 4 + ``` + + ```js + // Parsing output + { pet: { name: 'Maddie', type: 'dog', legs: '4', mammal: 'true' } } + ``` + + - `true` - JSON primitives are parsed, non-JSON input is interpreted as a string, and the input may be a JSON array or object. + + For example, when `parsePrimitives` is `false`, `--pet.name null` will result in the output `{ pet: { name: 'null' } }`. However, when `parsePrimitives` is `true`, the same input would result in the output `{ pet: { name: null } }`. The same applies for other JSON primitives too, i.e. booleans and numbers. When this option is `true`, users may represent string values as JSON in order to avoid ambiguity, e.g. `--pet.name '"null"'`. It's recommended that applications using this option document the behavior for their users. + + ```sh + # CLI input + create-pet --pet.type kangaroo --pet.legs 2 --pet.mammal true \ + --pet '{ "name": "Maddie", "type": "dog" }' --pet.legs 4 + ``` + + ```js + // Parsing output + { pet: { name: 'Maddie', type: 'dog', legs: 4, mammal: true } } + ``` + + - `'strict'` - JSON primitives are parsed, non-JSON input is not allowed, and the input may not be a JSON array or object. In other words, the user may only set primitive values, and they are required to be valid JSON. + + When this option is used, users must represent string values as JSON, e.g. `--pet.name '"Maddie"'`. It's recommended that applications using this option document the behavior for their users. + + ```sh + # CLI input + create-pet --pet.type '"kangaroo"' --pet.legs 2 --pet.mammal true + ``` + + ```js + // Parsing output + { pet: { type: 'kangaroo', legs: 2, mammal: true } } + ``` + + The following input would result in an error because the input to `--pet.type` is invalid JSON: + + ```sh + # CLI input + create-pet --pet.type kangaroo --pet.legs 2 --pet.mammal true + ``` + + The following input would result in an error because the input to `--pet` does not represent a JSON primitive: + + ```sh + # CLI input + create-pet --pet '{ "name": "Maddie", "type": "dog" }' --pet.type '"kangaroo"' + ``` diff --git a/generated/markdown/bossy/changelog.md b/generated/markdown/bossy/changelog.md new file mode 100644 index 00000000..c1dd2cb5 --- /dev/null +++ b/generated/markdown/bossy/changelog.md @@ -0,0 +1,138 @@ +## Version 6 {#v6} + +### [6.0.1](https://github.com/hapijs/bossy/milestone/25) {#6.0.1} + +- [#83](https://github.com/hapijs/bossy/pull/83) chore: bump hoek + +### [6.0.0](https://github.com/hapijs/bossy/milestone/24) {#6.0.0} + +- [#82](https://github.com/hapijs/bossy/pull/82) Support node v18 and drop node v12 + +## Version 5 {#v5} + +### [5.1.1](https://github.com/hapijs/bossy/milestone/23) {#5.1.1} + +- [#78](https://github.com/hapijs/bossy/pull/78) Fix display of defaults for json args and zero + +### [5.1.0](https://github.com/hapijs/bossy/milestone/22) {#5.1.0} + +- [#77](https://github.com/hapijs/bossy/pull/77) Implement object argument type +- [#76](https://github.com/hapijs/bossy/pull/76) Implement negation of boolean arguments + +### [5.0.1](https://github.com/hapijs/bossy/milestone/21) {#5.0.1} + +- [#74](https://github.com/hapijs/bossy/pull/74) upgrade lab to v24 + +### [5.0.0](https://github.com/hapijs/bossy/milestone/20) {#5.0.0} + +- [#70](https://github.com/hapijs/bossy/issues/70) Only node 12 + +## Version 4 {#v4} + +### [4.1.3](https://github.com/hapijs/bossy/milestone/19) {#4.1.3} + +- [#66](https://github.com/hapijs/bossy/issues/66) Update joi + +### [4.1.2](https://github.com/hapijs/bossy/milestone/18) {#4.1.2} + +- [#63](https://github.com/hapijs/bossy/issues/63) Update deps + +### [4.1.1](https://github.com/hapijs/bossy/milestone/17) {#4.1.1} + +- [#62](https://github.com/hapijs/bossy/issues/62) Update deps + +### [4.1.0](https://github.com/hapijs/bossy/milestone/16) {#4.1.0} + +- [#61](https://github.com/hapijs/bossy/issues/61) Change module namespace + +### [4.0.3](https://github.com/hapijs/bossy/milestone/15) {#4.0.3} + +- [#58](https://github.com/hapijs/bossy/issues/58) Update hoek v6 + +### [4.0.2](https://github.com/hapijs/bossy/milestone/14) {#4.0.2} + +- [#57](https://github.com/hapijs/bossy/issues/57) Cleanup + +### [4.0.1](https://github.com/hapijs/bossy/milestone/13) {#4.0.1} + +- [#55](https://github.com/hapijs/bossy/issues/55) Use Boom for errors + +### [4.0.0](https://github.com/hapijs/bossy/milestone/12) {#4.0.0} + +- [#54](https://github.com/hapijs/bossy/issues/54) Node v8 + +## Version 3 {#v3} + +### [3.0.3](https://github.com/hapijs/bossy/milestone/11) {#3.0.3} + +- [#52](https://github.com/hapijs/bossy/issues/52) node 7 + +### [3.0.2](https://github.com/hapijs/bossy/milestone/10) {#3.0.2} + +### [3.0.1](https://github.com/hapijs/bossy/milestone/9) {#3.0.1} + +- [#49](https://github.com/hapijs/bossy/issues/49) Update deps + +### [3.0.0](https://github.com/hapijs/bossy/milestone/8) {#3.0.0} + +- [#47](https://github.com/hapijs/bossy/pull/47) Upgrade to current hapi.js standards +- [#46](https://github.com/hapijs/bossy/issues/46) Upgrade to current hapi.js standards +- [#43](https://github.com/hapijs/bossy/pull/43) Show default value when printing options + +## Version 2 {#v2} + +### [2.0.0](https://github.com/hapijs/bossy/milestone/7) {#2.0.0} + +- [#41](https://github.com/hapijs/bossy/pull/41) Add `multiple` option parameter +- [#40](https://github.com/hapijs/bossy/pull/40) update project style +- [#39](https://github.com/hapijs/bossy/issues/39) Update project style +- [#37](https://github.com/hapijs/bossy/pull/37) Enable multiple values to be passed in +- [#36](https://github.com/hapijs/bossy/issues/36) Support multiple values for an option +- [#35](https://github.com/hapijs/bossy/pull/35) Validate input arguments using Joi +- [#24](https://github.com/hapijs/bossy/pull/24) Cleanup + +## Version 1 {#v1} + +### [1.0.3](https://github.com/hapijs/bossy/milestone/6) {#1.0.3} + +- [#32](https://github.com/hapijs/bossy/pull/32) Update to Lab 5.x.x and Code 1.x.x +- [#31](https://github.com/hapijs/bossy/pull/31) Update .travis.yml +- [#29](https://github.com/hapijs/bossy/pull/29) fix minor lint +- [#28](https://github.com/hapijs/bossy/pull/28) Allow numeric arguments to be passed in without spaces +- [#27](https://github.com/hapijs/bossy/issues/27) Bossy should support numeric arguments without spaces +- [#26](https://github.com/hapijs/bossy/pull/26) Add help type +- [#23](https://github.com/hapijs/bossy/issues/23) Slice + +### [1.0.2](https://github.com/hapijs/bossy/milestone/5) {#1.0.2} + +- [#20](https://github.com/hapijs/bossy/pull/20) Populate all aliases. +- [#18](https://github.com/hapijs/bossy/issues/18) Alias keys should be assigned argument value + +### [1.0.1](https://github.com/hapijs/bossy/milestone/4) {#1.0.1} + +- [#17](https://github.com/hapijs/bossy/pull/17) Format unknown option error message +- [#16](https://github.com/hapijs/bossy/issues/16) Unhelpful message for unknown argument + +### [1.0.0](https://github.com/hapijs/bossy/milestone/3) {#1.0.0} + +- [#15](https://github.com/hapijs/bossy/pull/15) Support colorizing usage information +- [#14](https://github.com/hapijs/bossy/pull/14) Add valid definition option for arguments +- [#13](https://github.com/hapijs/bossy/pull/13) Orders usage message with -shortname, --longname +- [#12](https://github.com/hapijs/bossy/issues/12) Add `valid` property to definition objects +- [#11](https://github.com/hapijs/bossy/issues/11) Order alias and full name correctly on usage +- [#10](https://github.com/hapijs/bossy/issues/10) Colorize the usage/help output + +## Version 0 {#v0} + +### [0.0.2](https://github.com/hapijs/bossy/milestone/2) {#0.0.2} + +- [#9](https://github.com/hapijs/bossy/pull/9) Can override argv +- [#8](https://github.com/hapijs/bossy/pull/8) Support null defaults for boolean +- [#7](https://github.com/hapijs/bossy/issues/7) Allow boolean to be defaulted to null +- [#6](https://github.com/hapijs/bossy/issues/6) Support argv being passed in options to parse + +### [0.0.1](https://github.com/hapijs/bossy/milestone/1) {#0.0.1} + +- [#4](https://github.com/hapijs/bossy/pull/4) Adding help formatting +- [#2](https://github.com/hapijs/bossy/issues/2) Implement function for displaying usage +- [#1](https://github.com/hapijs/bossy/pull/1) Lab 4, defaults, and require diff --git a/generated/markdown/bounce/3/api.md b/generated/markdown/bounce/3/api.md new file mode 100644 index 00000000..f0ca417f --- /dev/null +++ b/generated/markdown/bounce/3/api.md @@ -0,0 +1,124 @@ +## Introduction + +Working with `async`/`await` introduces a new challenge in handling errors. Unlike callbacks, which +provide a dual mechanism for passing application errors via the callback `err` argument and +developer errors via exceptions, `await` combines these two channels into one. + +It is common practice to ignore application errors in background processing or when there is no +useful fallback. In those cases, it is still imperative to allow developer errors to surface and +not get swallowed. + +For more information read: + +- [Learning to Throw Again](https://medium.com/@eranhammer/learning-to-throw-again-79b498504d28) +- [Catching without Awaiting](https://medium.com/@eranhammer/catching-without-awaiting-b2cb7df45790) + +For example: + +```js +async function email(user) { + if (!user.address) { + throw new Error('User has no email address'); + } + + const message = 'Welcome!'; + if (user.name) { + message = `Welcome ${user.name}!`; + } + + await mailer.send(user.address, message); +} + +async function register(address, name) { + const user = { address, name }; + const id = await db.user.insert(user); + user.id = id; + + try { + await email(user); + } catch (err) {} // Ignore errors + + return user; +} +``` + +This will fail silently every time the user has a `name` because it is reassigning a value to a +`const` variable. However, because `email()` errors are ignored, system errors are ignored as well. +The idea is that `email()` can be used in both critical and non-critical paths. In the critical +paths, errors are checked and addressed, but in the non-critical paths, errors are simply ignored. + +This can be solved by adding a `rethrow()` statement: + +```js +const Bounce = require('@hapi/bounce'); + +async function register(address, name) { + const user = { address, name }; + const id = await db.user.insert(user); + user.id = id; + + try { + await email(user); + } catch (err) { + Bounce.rethrow(err, 'system'); // Rethrows system errors and ignores application errors + } + + return user; +} +``` + +## Usage + +### `rethrow(err, types, [options])` + +Throws the error passed if it matches any of the specified rules where: + +- `err` - the error. +- `type` - a single item or an array of items of: + - An error constructor (e.g. `SyntaxError`). + - `'system'` - matches any languange native error or node assertions. + - `'boom'` - matches [**boom**](https://github.com/hapijs/boom) errors. + - an object where each property is compared with the error and must match the error property + value. All the properties in the object must match the error but do not need to include all + the error properties. +- `options` - optional object where: + - `decorate` - an object which is assigned to the `err`, copying the properties onto the error. + - `override` - an error used to override `err` when `err` matches. If used with `decorate`, + the `override` object is modified. + - `return` - if `true`, the error is returned instead of thrown. Defaults to `false`. + +### `ignore(err, types, [options])` + +The opposite action of `rethrow()`. Ignores any errors matching the specified `types`. Any error +not matching is thrown after applying the `options`. + +### `background(operation, [action], [types], [options])` + +Awaits for the value to resolve in the background and then apply either the `rethrow()` or `ignore()` +actions where: + +- `operation` - a function, promise, or value that is `await`ed on inside a `try...catch` and any + error thrown processed by the `action` rule. +- `action` - one of `'rethrow'` or `'ignore'`. Defaults to `'rethrow'`. +- `types` - same as the `types` argument passed to `rethrow()` or `ignore()`. Defaults to `'system'`. +- `options` - same as the `options` argument passed to `rethrow()` or `ignore()`. + +### `isBoom(err)` + +Returns `true` when `err` is a [**boom**](https://github.com/hapijs/boom) error. + +### `isError(err)` + +Returns `true` when `err` is an error. + +### `isSystem(err)` + +Return `true` when `err` is one of: + +- `EvalError` +- `RangeError` +- `ReferenceError` +- `SyntaxError` +- `TypeError` +- `URIError` +- Node's `AssertionError` diff --git a/generated/markdown/bounce/changelog.md b/generated/markdown/bounce/changelog.md new file mode 100644 index 00000000..69471c18 --- /dev/null +++ b/generated/markdown/bounce/changelog.md @@ -0,0 +1,65 @@ +## Version 3 {#v3} + +### [3.0.2](https://github.com/hapijs/bounce/milestone/17) {#3.0.2} + +- [#38](https://github.com/hapijs/bounce/pull/38) Fix background() missing return option support + +### [3.0.1](https://github.com/hapijs/bounce/milestone/16) {#3.0.1} + +- [#35](https://github.com/hapijs/bounce/pull/35) chore: bump hoek + +### [3.0.0](https://github.com/hapijs/bounce/milestone/15) {#3.0.0} + +- [#33](https://github.com/hapijs/bounce/pull/33) Support node v18 and drop node v12 + +## Version 2 {#v2} + +### [2.0.0](https://github.com/hapijs/bounce/milestone/13) {#2.0.0} + +- [#23](https://github.com/hapijs/bounce/issues/23) Only node 12 + +## Version 1 {#v1} + +### [1.3.2](https://github.com/hapijs/bounce/milestone/11) {#1.3.2} + +- [#21](https://github.com/hapijs/bounce/issues/21) Fix hoek contain bug + +### [1.3.1](https://github.com/hapijs/bounce/milestone/10) {#1.3.1} + +- [#16](https://github.com/hapijs/bounce/issues/16) Treat hoek assertion as system + +### [1.3.0](https://github.com/hapijs/bounce/milestone/9) {#1.3.0} + +- [#15](https://github.com/hapijs/bounce/issues/15) Change module namespace + +### [1.2.3](https://github.com/hapijs/bounce/milestone/8) {#1.2.3} + +- [#13](https://github.com/hapijs/bounce/pull/13) Fix contain() options + +### [1.2.2](https://github.com/hapijs/bounce/milestone/7) {#1.2.2} + +- [#12](https://github.com/hapijs/bounce/issues/12) Remove engines + +### [1.2.1](https://github.com/hapijs/bounce/milestone/6) {#1.2.1} + +- [#10](https://github.com/hapijs/bounce/issues/10) Update hoek v6 + +### [1.2.0](https://github.com/hapijs/bounce/milestone/5) {#1.2.0} + +- [#6](https://github.com/hapijs/bounce/issues/6) Support background functions + +### [1.1.0](https://github.com/hapijs/bounce/milestone/4) {#1.1.0} + +- [#5](https://github.com/hapijs/bounce/issues/5) Background processing with error protection + +### [1.0.3](https://github.com/hapijs/bounce/milestone/3) {#1.0.3} + +- [#4](https://github.com/hapijs/bounce/issues/4) Ignore boomified system errors + +### [1.0.2](https://github.com/hapijs/bounce/milestone/2) {#1.0.2} + +- [#3](https://github.com/hapijs/bounce/issues/3) Update boom + +### [1.0.1](https://github.com/hapijs/bounce/milestone/1) {#1.0.1} + +- [#2](https://github.com/hapijs/bounce/issues/2) Hoek missing from dependencies diff --git a/generated/markdown/bourne/3/api.md b/generated/markdown/bourne/3/api.md new file mode 100644 index 00000000..838d72a8 --- /dev/null +++ b/generated/markdown/bourne/3/api.md @@ -0,0 +1,50 @@ +### Introduction + +Consider this: + +``` +> const a = '{"__proto__":{ "b":5}}'; +'{"__proto__":{ "b":5}}' + +> const b = JSON.parse(a); +{ __proto__: { b: 5 } } + +> b.b; +undefined + +> const c = Object.assign({}, b); +{} + +> c.b +5 +``` + +The problem is that `JSON.parse()` retains the `__proto__` property as a plain object key. By +itself, this is not a security issue. However, as soon as that object is assigned to another or +iterated on and values copied, the `__proto__` property leaks and becomes the object's prototype. + +### `Bourne.parse(text, [reviver], [options])` + +Parses a given JSON-formatted text into an object where: + +- `text` - the JSON text string. +- `reviver` - the `JSON.parse()` optional `reviver` argument. +- `options` - optional configuration object where: + - `protoAction` - optional string with one of: + - `'error'` - throw a `SyntaxError` when a `__proto__` key is found. This is the default value. + - `'remove'` - deletes any `__proto__` keys from the result object. + - `'ignore'` - skips all validation (same as calling `JSON.parse()` directly). + +### `Bourne.scan(obj, [options])` + +Scans a given object for prototype properties where: + +- `obj` - the object being scanned. +- `options` - optional configuration object where: + - `protoAction` - optional string with one of: + - `'error'` - throw a `SyntaxError` when a `__proto__` key is found. This is the default value. + - `'remove'` - deletes any `__proto__` keys from the input `obj`. + +### `Bourne.safeParse(text, [reviver])` + +Same as `Bourne.parse()` except that it returns `null` instead of throwing a `SyntaxError` when a `__proto__` key is found. diff --git a/generated/markdown/bourne/changelog.md b/generated/markdown/bourne/changelog.md new file mode 100644 index 00000000..406ada3f --- /dev/null +++ b/generated/markdown/bourne/changelog.md @@ -0,0 +1,38 @@ +## Version 2 {#v2} + +### [2.1.0](https://github.com/hapijs/bourne/milestone/9) {#2.1.0} + +- [#26](https://github.com/hapijs/bourne/pull/26) Add Typescript types +- [#22](https://github.com/hapijs/bourne/pull/22) upgrade lab to v24 + +### [2.0.0](https://github.com/hapijs/bourne/milestone/8) {#2.0.0} + +- [#17](https://github.com/hapijs/bourne/issues/17) Only node 12 + +## Version 1 {#v1} + +### [1.3.2](https://github.com/hapijs/bourne/milestone/6) {#1.3.2} + +- [#10](https://github.com/hapijs/bourne/pull/10) Fix uppercase hex strings validating as safe + +### [1.3.0](https://github.com/hapijs/bourne/milestone/5) {#1.3.0} + +- [#9](https://github.com/hapijs/bourne/issues/9) Add safeParse() + +### [1.2.0](https://github.com/hapijs/bourne/milestone/4) {#1.2.0} + +- [#8](https://github.com/hapijs/bourne/issues/8) Change module namespace + +### [1.1.2](https://github.com/hapijs/bourne/milestone/3) {#1.1.2} + +- [#7](https://github.com/hapijs/bourne/pull/7) Don't assume `hasOwnProperty` is safe + +### [1.1.1](https://github.com/hapijs/bourne/milestone/2) {#1.1.1} + +- [#5](https://github.com/hapijs/bourne/pull/5) Use syntax available down to Node 4. +- [#4](https://github.com/hapijs/bourne/issues/4) Improve regex to only flag keys + +### [1.1.0](https://github.com/hapijs/bourne/milestone/1) {#1.1.0} + +- [#3](https://github.com/hapijs/bourne/issues/3) Handle escaped unicode characters +- [#2](https://github.com/hapijs/bourne/issues/2) Expose validation logic diff --git a/generated/markdown/call/9/api.md b/generated/markdown/call/9/api.md new file mode 100644 index 00000000..04d89099 --- /dev/null +++ b/generated/markdown/call/9/api.md @@ -0,0 +1,117 @@ +## Introduction + +`call` is a simple node.js HTTP Router. It is used by popular [hapi.js](https://github.com/hapijs/hapi) web framework. It implements predictable and easy to use routing. Even if it is designed to work with Hapi.js, you can still use it as an independent router in your app. + +## Example + +```js +const Call = require('@hapi/call'); + +// Create new router +const router = new Call.Router(); + +// Add route +router.add({ method: 'get', path: '/' }, { label: 'root-path' }); + +// Add another route +router.add({ method: 'post', path: '/users' }, 'route specific data'); + +// Add another route with dynamic path +router.add({ method: 'put', path: '/users/{userId}' }, () => { + /* ...handler... */ +}); + +// Match route +router.route('post', '/users'); +/* If matching route is found, it returns an object containing + { + params: {}, // All dynamic path parameters as key/value + paramsArray: [], // All dynamic path parameter values in order + route: 'route specific data'; // routeData + } +*/ + +// Match route +router.route('put', '/users/1234'); +/* returns + { + params: { userId: '1234' }, + paramsArray: [ '1234' ], + route: [Function] + } +*/ +``` + +## Paths matching + +### Exact match + +`{param}`: If path contains `/users/{user}` then it matches `/users/john` or `/users/1234` but not `/users`. + +### Optional parameters + +`{param?}`: ? means parameter is optional . If path contains `/users/{user?}` It matches `/users/john` as well as `/users`. + +It is important to be aware that only the last named parameter in a path can be optional. That means that `/{one?}/{two}/` is an invalid path, since in this case there is another parameter after the optional one. You may also have a named parameter covering only part of a segment of the path, but you may only have one named parameter per segment. That means that /`{filename}.jpg` is valid while `/{filename}.{ext}` is not. + +### Multi-segment parameters + +`{params*n}`: With path configuration `/users/{user*2}`, it matches `/users/john/doe` or `/users/harshal/patil` but not `/users/john`. Number **n** after asterisk sign specifies the multiplier. + +Like the optional parameters, a wildcard parameter (for example `/{users*}`) may only appear as the last parameter in your path. + +### Catch all + +`{params*}`: Using this option, it matches anything. So `/users/{user*}` with match `/users/`, `/users/john`, `/users/john/doe`, `/users/john/doe/smith` + +For more details about path parameters, [read hapi.js docs](https://github.com/hapijs/hapi/blob/master/API.md#path-parameters). + +## Routing order + +When determining what handler to use for a particular request, router searches paths in order from most specific to least specific. That means if you have two routes, one with the path `/filename.jpg` and a second route `/filename.{ext}` a request to /filename.jpg will match the first route, and not the second. This also means that a route with the path `/{files*}` will be the last route tested, and will only match if all other routes fail. + +**Call** router has deterministic order than other routers and because of this deterministic order, `call` is able to detect conflicting routes and throw exception accordingly. In comparison, Express.js has different routing mechanism based on simple RegEx pattern matching making it faster (probably it only matters in theory) but unable to catch route conflicts. + +## Method + +### `new Router([options])` + +Constructor to create a new router instance where: + +- `options` - an optional configuration object with the following fields: + - `isCaseSensitive` - specifies if the paths should case sensitive. If set to `true`, + `/users` and `/USERS` are considered as two different paths. Defaults to `true`. + +```js +const router = new Call.Router(); +``` + +### `add(options, [data])` + +Adds a new route to the router where: + +- `options` - a configuration object with the following fields: + - `method` - the HTTP method (`'get'`, `'put'`, `'post'`, `'delete'`, etc.) or the wildcard + character (`'*'`) to match any methods. The method must be lowercase. + - `path` - the URL path to be used for route matching. The path segment can be static like + `'/users/1234'` or it can be a [dynamic path](#path-matching). +- `data` - the application data to retrieve when a route match is found during lookup. This is + typically the route handler or other metadata about what to do when a route is matched. + +Throws on invalid route configuration or on a conflict with existing routes. + +### `route(method, path)` + +Finds a matching route where: + +- `method` - the requested route method. +- `path` - the requested route path. + +Returns an object with the following when a match is found: + +- `params` - an object containing all path parameters where each **key** is path name and + **value** is the corresponding parameter value in the requested `path`. +- `paramsArray` - an array of the parameter values in order. +- `route` - the `data` value provided when the route was added. + +If no match is found, returns (not throws) an error. diff --git a/generated/markdown/call/changelog.md b/generated/markdown/call/changelog.md new file mode 100644 index 00000000..cf1661ff --- /dev/null +++ b/generated/markdown/call/changelog.md @@ -0,0 +1,130 @@ +## Version 8 {#v8} + +### [8.0.1](https://github.com/hapijs/call/milestone/28) {#8.0.1} + +- [#62](https://github.com/hapijs/call/pull/62) upgrade lab to v24 + +### [8.0.0](https://github.com/hapijs/call/milestone/27) {#8.0.0} + +- [#56](https://github.com/hapijs/call/issues/56) Switch tables to maps + +## Version 7 {#v7} + +### [7.0.1](https://github.com/hapijs/call/milestone/26) {#7.0.1} + +- [#55](https://github.com/hapijs/call/issues/55) Switch to use maps + +### [7.0.0](https://github.com/hapijs/call/milestone/25) {#7.0.0} + +- [#54](https://github.com/hapijs/call/issues/54) Only node 12 + +## Version 6 {#v6} + +### [6.0.1](https://github.com/hapijs/call/milestone/23) {#6.0.1} + +- [#52](https://github.com/hapijs/call/issues/52) Special case '/' + +### [6.0.0](https://github.com/hapijs/call/milestone/22) {#6.0.0} + +- [#51](https://github.com/hapijs/call/issues/51) Improve performance +- [#50](https://github.com/hapijs/call/issues/50) Drop node 8 + +## Version 5 {#v5} + +### [5.1.3](https://github.com/hapijs/call/milestone/21) {#5.1.3} + +- [#57](https://github.com/hapijs/call/issues/57) Check method exists + +### [5.1.2](https://github.com/hapijs/call/milestone/20) {#5.1.2} + +- [#49](https://github.com/hapijs/call/pull/49) Fix typo: wilcard -> wildcard + +### [5.1.1](https://github.com/hapijs/call/milestone/19) {#5.1.1} + +- [#42](https://github.com/hapijs/call/issues/42) Update deps + +### [5.1.0](https://github.com/hapijs/call/milestone/16) {#5.1.0} + +- [#41](https://github.com/hapijs/call/issues/41) Change module namespace + +### [5.0.3](https://github.com/hapijs/call/milestone/15) {#5.0.3} + +- [#37](https://github.com/hapijs/call/issues/37) Remove engines + +### [5.0.2](https://github.com/hapijs/call/milestone/14) {#5.0.2} + +- [#36](https://github.com/hapijs/call/issues/36) Update hoek v6 + +### [5.0.1](https://github.com/hapijs/call/milestone/13) {#5.0.1} + +- [#34](https://github.com/hapijs/call/issues/34) Update boom + +### [5.0.0](https://github.com/hapijs/call/milestone/12) {#5.0.0} + +- [#33](https://github.com/hapijs/call/issues/33) Node 8 + +## Version 4 {#v4} + +### [4.1.1](https://github.com/hapijs/call/milestone/18) {#4.1.1} + +- [#58](https://github.com/hapijs/call/issues/58) Check method exists + +### [4.1.0](https://github.com/hapijs/call/milestone/17) {#4.1.0} + +- [#40](https://github.com/hapijs/call/issues/40) Commercial version of v4 branch + +### [4.0.2](https://github.com/hapijs/call/milestone/11) {#4.0.2} + +- [#32](https://github.com/hapijs/call/issues/32) Update deps. + +### [4.0.1](https://github.com/hapijs/call/milestone/10) {#4.0.1} + +- [#29](https://github.com/hapijs/call/pull/29) Apply path segment normalization +- [#28](https://github.com/hapijs/call/issues/28) No "Path Segment Normalization"? + +### [4.0.0](https://github.com/hapijs/call/milestone/9) {#4.0.0} + +- [#24](https://github.com/hapijs/call/issues/24) {path\*} segments disappear when empty + +## Version 3 {#v3} + +### [3.0.4](https://github.com/hapijs/call/milestone/8) {#3.0.4} + +- [#26](https://github.com/hapijs/call/issues/26) Update deps + +### [3.0.3](https://github.com/hapijs/call/milestone/7) {#3.0.3} + +- [#23](https://github.com/hapijs/call/issues/23) npmignore + +### [3.0.2](https://github.com/hapijs/call/milestone/6) {#3.0.2} + +- [#21](https://github.com/hapijs/call/pull/21) Fix empty segment bug + +### [3.0.1](https://github.com/hapijs/call/milestone/5) {#3.0.1} + +- [#20](https://github.com/hapijs/call/pull/20) Test on node v6, update dependencies +- [#16](https://github.com/hapijs/call/pull/16) fix TypeError if path /constructor/foo is accessed + +### [3.0.0](https://github.com/hapijs/call/milestone/4) {#3.0.0} + +- [#17](https://github.com/hapijs/call/issues/17) ES6 style changes and node v4 + +## Version 2 {#v2} + +### [2.0.2](https://github.com/hapijs/call/milestone/3) {#2.0.2} + +- [#14](https://github.com/hapijs/call/issues/14) Update project style + +### [2.0.1](https://github.com/hapijs/call/milestone/2) {#2.0.1} + +- [#11](https://github.com/hapijs/call/issues/11) Performance tweaks + +### [2.0.0](https://github.com/hapijs/call/milestone/1) {#2.0.0} + +- [#10](https://github.com/hapijs/call/issues/10) Support route id +- [#9](https://github.com/hapijs/call/issues/9) /a/{p}/{p*} conflicts with /a/{p*} (which is not reachable) +- [#8](https://github.com/hapijs/call/issues/8) '/a/b/{p*}' is more specific than '/{p*5}' +- [#7](https://github.com/hapijs/call/issues/7) /a/b/{p\*} is more specific than /a/{b}/{c} +- [#6](https://github.com/hapijs/call/issues/6) '/a/{b*}' is less specific than '/a/{b}/{c*}' +- [#3](https://github.com/hapijs/call/issues/3) Support for flexible routes +- [#2](https://github.com/hapijs/call/pull/2) Match case-insensitive paths with no params diff --git a/generated/markdown/catbox-memcached/4/api.md b/generated/markdown/catbox-memcached/4/api.md new file mode 100644 index 00000000..3680ee35 --- /dev/null +++ b/generated/markdown/catbox-memcached/4/api.md @@ -0,0 +1,5 @@ +### `new CatboxMemcached.Engine(options)` + +- `host` - the Memcache server hostname. Defaults to `127.0.0.1`. **Cannot be used with `server`.** +- `port` - the Memcache server port. Defaults to `11211`. **Cannot be used with `server`.** +- `server` - the Memcache server hostname and port. Defaults to `127.0.0.1:11211`. Can be a string or an object as per [memcache-client server specification](https://github.com/electrode-io/memcache/tree/3dd8e7cc3da3ec78ac45c4a69379e810cb25f6c7/packages/memcache-client#client-options). diff --git a/generated/markdown/catbox-memcached/changelog.md b/generated/markdown/catbox-memcached/changelog.md new file mode 100644 index 00000000..4cd2cd33 --- /dev/null +++ b/generated/markdown/catbox-memcached/changelog.md @@ -0,0 +1,34 @@ +## Version 3 {#v3} + +### [3.0.0](https://github.com/hapijs/catbox-memcached/milestone/8) {#3.0.0} + +- [#44](https://github.com/hapijs/catbox-memcached/issues/44) Only node 12 + +## Version 2 {#v2} + +### [2.1.1](https://github.com/hapijs/catbox-memcached/milestone/6) {#2.1.1} + +- [#38](https://github.com/hapijs/catbox-memcached/issues/38) Update deps + +### [2.1.0](https://github.com/hapijs/catbox-memcached/milestone/5) {#2.1.0} + +- [#35](https://github.com/hapijs/catbox-memcached/issues/35) Change module namespace + +### [2.0.5](https://github.com/hapijs/catbox-memcached/milestone/4) {#2.0.5} + +- [#21](https://github.com/hapijs/catbox-memcached/issues/21) Remove test connections + +## Version 1 {#v1} + +### [1.1.1](https://github.com/hapijs/catbox-memcached/milestone/3) {#1.1.1} + +- [#17](https://github.com/hapijs/catbox-memcached/pull/17) upgrade to lab 6 minor fixes license fix +- [#9](https://github.com/hapijs/catbox-memcached/issues/9) Using catbox-memcache with yar, response body is replaced with `true` + +### [1.0.3](https://github.com/hapijs/catbox-memcached/milestone/2) {#1.0.3} + +- [#5](https://github.com/hapijs/catbox-memcached/issues/5) Hapi hangs if the memcached server is down + +### [1.0.2](https://github.com/hapijs/catbox-memcached/milestone/1) {#1.0.2} + +- [#4](https://github.com/hapijs/catbox-memcached/issues/4) Rename spumko to hapijs diff --git a/generated/markdown/catbox-memory/6/api.md b/generated/markdown/catbox-memory/6/api.md new file mode 100644 index 00000000..b84d6074 --- /dev/null +++ b/generated/markdown/catbox-memory/6/api.md @@ -0,0 +1,18 @@ +### Introduction + +Memory adapter for [catbox](https://github.com/hapijs/catbox). +This adapter is not designed to share a common cache between multiple processes (e.g. in a cluster +mode). It uses a single interval timeout to look for expired records and clean them from memory. + +### `new CatboxMemory.Engine(options)` + +- `maxByteSize` - sets an upper limit on the number of bytes that can be stored in the + cache. Once this limit is reached no additional items will be added to the cache + until some expire. The utilized memory calculation is a rough approximation and must + not be relied on. Defaults to `104857600` (100MB). +- `minCleanupIntervalMsec` - the minimum number of milliseconds in between each cache cleanup. + Defaults to 1 second (`1000`). +- `cloneBuffersOnGet` - by default, buffers stored in the cache are copied when they are set but + not when they are retrieved. This means a change to the buffer returned by a `get()` will change + the value in the cache. To prevent this, set `cloneBuffersOnGet` to `true` to always return a + copy of the cached buffer. Defaults to `false`. diff --git a/generated/markdown/catbox-memory/changelog.md b/generated/markdown/catbox-memory/changelog.md new file mode 100644 index 00000000..20b47531 --- /dev/null +++ b/generated/markdown/catbox-memory/changelog.md @@ -0,0 +1,145 @@ +## Version 6 {#v6} + +### [6.0.2](https://github.com/hapijs/catbox-memory/milestone/31) {#6.0.2} + +- [#90](https://github.com/hapijs/catbox-memory/pull/90) feat: 🎸 bring in typings from DT + +### [6.0.1](https://github.com/hapijs/catbox-memory/milestone/30) {#6.0.1} + +- [#87](https://github.com/hapijs/catbox-memory/pull/87) chore: bump hoek + +### [6.0.0](https://github.com/hapijs/catbox-memory/milestone/29) {#6.0.0} + +- [#86](https://github.com/hapijs/catbox-memory/pull/86) Support node v18 and drop node v12, make exports ESM-friendly + +## Version 5 {#v5} + +### [5.0.1](https://github.com/hapijs/catbox-memory/milestone/27) {#5.0.1} + +- [#83](https://github.com/hapijs/catbox-memory/pull/83) fix: make class extendable +- [#81](https://github.com/hapijs/catbox-memory/pull/81) upgrade lab to v24 + +### [5.0.0](https://github.com/hapijs/catbox-memory/milestone/26) {#5.0.0} + +- [#77](https://github.com/hapijs/catbox-memory/issues/77) Only node 12 + +## Version 4 {#v4} + +### [4.1.1](https://github.com/hapijs/catbox-memory/milestone/22) {#4.1.1} + +- [#69](https://github.com/hapijs/catbox-memory/issues/69) Update deps + +### [4.1.0](https://github.com/hapijs/catbox-memory/milestone/19) {#4.1.0} + +- [#66](https://github.com/hapijs/catbox-memory/issues/66) Remove allowMixedContent option +- [#65](https://github.com/hapijs/catbox-memory/issues/65) Change module namespace +- [#64](https://github.com/hapijs/catbox-memory/issues/64) Typo \_timeDue vs \_timerDue + +### [4.0.1](https://github.com/hapijs/catbox-memory/milestone/16) {#4.0.1} + +- [#61](https://github.com/hapijs/catbox-memory/issues/61) Remove engines + +### [4.0.0](https://github.com/hapijs/catbox-memory/milestone/15) {#4.0.0} + +- [#57](https://github.com/hapijs/catbox-memory/issues/57) Update hoek v6 +- [#55](https://github.com/hapijs/catbox-memory/issues/55) Buffers can change while in cache +- [#8](https://github.com/hapijs/catbox-memory/issues/8) Large overhead from expires times when highly populated + +## Version 3 {#v3} + +### [3.2.2](https://github.com/hapijs/catbox-memory/milestone/24) {#3.2.2} + +### [3.2.0](https://github.com/hapijs/catbox-memory/milestone/23) {#3.2.0} + +- [#67](https://github.com/hapijs/catbox-memory/issues/67) Change module namespace v3 + +### [3.1.4](https://github.com/hapijs/catbox-memory/milestone/18) {#3.1.4} + +- [#60](https://github.com/hapijs/catbox-memory/issues/60) Remove engines + +### [3.1.3](https://github.com/hapijs/catbox-memory/milestone/17) {#3.1.3} + +- [#58](https://github.com/hapijs/catbox-memory/issues/58) Update deps + +### [3.1.2](https://github.com/hapijs/catbox-memory/milestone/14) {#3.1.2} + +- [#56](https://github.com/hapijs/catbox-memory/pull/56) Remove new Buffer usage + +### [3.1.1](https://github.com/hapijs/catbox-memory/milestone/13) {#3.1.1} + +- [#54](https://github.com/hapijs/catbox-memory/issues/54) Fix new Boom + +### [3.1.0](https://github.com/hapijs/catbox-memory/milestone/12) {#3.1.0} + +- [#53](https://github.com/hapijs/catbox-memory/issues/53) Replace hash with Map +- [#52](https://github.com/hapijs/catbox-memory/issues/52) Sync client for catbox 10 +- [#48](https://github.com/hapijs/catbox-memory/pull/48) Use big-time for long timeout support + +### [3.0.0](https://github.com/hapijs/catbox-memory/milestone/11) {#3.0.0} + +- [#47](https://github.com/hapijs/catbox-memory/issues/47) Node 8 + +## Version 2 {#v2} + +### [2.1.0](https://github.com/hapijs/catbox-memory/milestone/20) {#2.1.0} + +- [#63](https://github.com/hapijs/catbox-memory/issues/63) Commercial version of v2 branch + +### [2.0.4](https://github.com/hapijs/catbox-memory/milestone/10) {#2.0.4} + +- [#43](https://github.com/hapijs/catbox-memory/pull/43) Update deps +- [#42](https://github.com/hapijs/catbox-memory/pull/42) fix: cancel timeouts on drop + +### [2.0.3](https://github.com/hapijs/catbox-memory/milestone/9) {#2.0.3} + +- [#38](https://github.com/hapijs/catbox-memory/issues/38) Add .npmignore +- [#37](https://github.com/hapijs/catbox-memory/pull/37) add note to readme about the limitation of ttl + +### [2.0.1](https://github.com/hapijs/catbox-memory/milestone/8) {#2.0.1} + +- [#33](https://github.com/hapijs/catbox-memory/issues/33) Update hapijs/catbox to 7.0.0 + +## Version 1 {#v1} + +### [1.1.2](https://github.com/hapijs/catbox-memory/milestone/7) {#1.1.2} + +- [#32](https://github.com/hapijs/catbox-memory/pull/32) v1.1.2 +- [#27](https://github.com/hapijs/catbox-memory/pull/27) Clean up timers when the cache is stopped. +- [#26](https://github.com/hapijs/catbox-memory/pull/26) Remove Makefile in favor of npm scripts and enable linting +- [#24](https://github.com/hapijs/catbox-memory/pull/24) add node 0.11 to travis file + +### [1.1.1](https://github.com/hapijs/catbox-memory/milestone/6) {#1.1.1} + +- [#23](https://github.com/hapijs/catbox-memory/pull/23) version 1.1.1. update to catbox 4 and lab 5 (replace chai with code) +- [#22](https://github.com/hapijs/catbox-memory/issues/22) Update to Lab 5 +- [#21](https://github.com/hapijs/catbox-memory/issues/21) Update to catbox 4 + +### [1.1.0](https://github.com/hapijs/catbox-memory/milestone/5) {#1.1.0} + +- [#17](https://github.com/hapijs/catbox-memory/pull/17) Bump version to 1.1.0 +- [#16](https://github.com/hapijs/catbox-memory/issues/16) Release 1.1.0 +- [#15](https://github.com/hapijs/catbox-memory/pull/15) Add support for Buffers +- [#14](https://github.com/hapijs/catbox-memory/pull/14) Add build status to README +- [#13](https://github.com/hapijs/catbox-memory/issues/13) Add build status to readme +- [#12](https://github.com/hapijs/catbox-memory/pull/12) Update owner +- [#5](https://github.com/hapijs/catbox-memory/pull/5) Option to store buffer data + +### [1.0.5](https://github.com/hapijs/catbox-memory/milestone/4) {#1.0.5} + +- [#11](https://github.com/hapijs/catbox-memory/pull/11) Up version and use lab 4 +- [#10](https://github.com/hapijs/catbox-memory/pull/10) Fix total byteSize tracking in connection +- [#9](https://github.com/hapijs/catbox-memory/pull/9) Create named classes for cache objects +- [#7](https://github.com/hapijs/catbox-memory/issues/7) Memory limit does not restrict data size properly + +### [1.0.4](https://github.com/hapijs/catbox-memory/milestone/3) {#1.0.4} + +- [#6](https://github.com/hapijs/catbox-memory/issues/6) Rename spumko to hapijs + +### [1.0.3](https://github.com/hapijs/catbox-memory/milestone/2) {#1.0.3} + +- [#4](https://github.com/hapijs/catbox-memory/issues/4) Move large ttl (over 32bit) check from catbox + +### [1.0.2](https://github.com/hapijs/catbox-memory/milestone/1) {#1.0.2} + +- [#2](https://github.com/hapijs/catbox-memory/issues/2) Bring coverage back to 100% +- [#1](https://github.com/hapijs/catbox-memory/issues/1) why peer depend instead of verify in parent diff --git a/generated/markdown/catbox-object/3/api.md b/generated/markdown/catbox-object/3/api.md new file mode 100644 index 00000000..4e33cbe7 --- /dev/null +++ b/generated/markdown/catbox-object/3/api.md @@ -0,0 +1,15 @@ +### Introduction + +Memory object adapter for [catbox](https://github.com/hapijs/catbox). +This adapter is not designed to share a common cache between multiple processes (e.g. in a cluster +mode). It uses a single interval timeout to look for expired records and clean them from memory. +Unlike the **catbox-memory** cache, it does not clone objects stored (in either direction) or keep +track of memory usage. + +### `new CatboxObject.Engine(options)` + +- `maxSize` - sets an upper limit on the number of items that can be stored in the + cache. Once this limit is reached no additional items will be added to the cache + until some expire. Defaults to `1000`. +- `minCleanupIntervalMsec` - the minimum number of milliseconds in between each cache cleanup. + Defaults to 1 second (`1000`). diff --git a/generated/markdown/catbox-object/changelog.md b/generated/markdown/catbox-object/changelog.md new file mode 100644 index 00000000..a0769228 --- /dev/null +++ b/generated/markdown/catbox-object/changelog.md @@ -0,0 +1,21 @@ +## Version 3 {#v3} + +### [3.0.1](https://github.com/hapijs/catbox-object/milestone/5) {#3.0.1} + +- [#14](https://github.com/hapijs/catbox-object/pull/14) chore: bump hoek + +### [3.0.0](https://github.com/hapijs/catbox-object/milestone/4) {#3.0.0} + +- [#13](https://github.com/hapijs/catbox-object/pull/13) Support for node v18, change default export, ESM tests + +## Version 2 {#v2} + +### [2.0.0](https://github.com/hapijs/catbox-object/milestone/2) {#2.0.0} + +- [#6](https://github.com/hapijs/catbox-object/issues/6) Only node 12 + +## Version 1 {#v1} + +### [1.0.1](https://github.com/hapijs/catbox-object/milestone/1) {#1.0.1} + +- [#1](https://github.com/hapijs/catbox-object/issues/1) Update deps diff --git a/generated/markdown/catbox-redis/7/api.md b/generated/markdown/catbox-redis/7/api.md new file mode 100644 index 00000000..ee0081ac --- /dev/null +++ b/generated/markdown/catbox-redis/7/api.md @@ -0,0 +1,85 @@ +### `new CatboxRedis.Engine(options)` + +The connection can be specified with one (and only one) of: + +- `client` - a custom Redis client instance where `client` must: + - be manually started and stopped, + - be compatible with the **ioredis** module API, and + - expose the `status` property that must be set to `'ready'` when connected. + +- `url` - a Redis server URL. + +- `socket` - a unix socket string. + +- `cluster` - an array of `{ host, port }` pairs. + +Or: + +- `host` - a Redis server hostname. Defaults to `'127.0.0.1'` if no other connection method specified from the above. +- `port` - a Redis server port or unix domain socket path. Defaults to `6379` if no other connection method specified from the above. + +**catbox** options: + +- `partition` - a string used to prefix all item keys with. Defaults to `''`. + +Other supported Redis options: + +- `password` - the Redis authentication password when required. +- `db` - a Redis database name or number. +- `sentinels` - an array of `{ host, port }` sentinel address pairs. +- `sentinelName` - the name of the sentinel master (when `sentinels` is specified). +- `tls` - an object representing TLS config options for **ioredis**. + +The plugin also accepts other `redis` options not mentioned above. + +### Usage + +Sample catbox cache initialization: + +```js +const Catbox = require('@hapi/catbox'); +const { Engine: CatboxRedis } = require('@hapi/catbox-redis'); + +const cache = new Catbox.Client(CatboxRedis, { + partition: 'my_cached_data', + host: 'redis-cluster.domain.com', + port: 6379, + db: 0, + tls: {}, +}); +``` + +When used in a hapi server (hapi version 18 or newer): + +```js +const Hapi = require('hapi'); +const { Engine: CatboxRedis } = require('@hapi/catbox-redis'); + +const server = new Hapi.Server({ + cache: [ + { + name: 'my_cache', + provider: { + constructor: CatboxRedis, + options: { + partition: 'my_cached_data', + host: 'redis-cluster.domain.com', + port: 6379, + db: 0, + tls: {}, + }, + }, + }, + ], +}); +``` + +### Tests + +The test suite expects: + +- a redis server to be running on port 6379 +- a redis server listenning to port 6378 and requiring a password: 'secret' +- a redis cluster contains nodes running on ports 7000 to 7005 + +See [docker-compose.yml](./docker-compose.yml) diff --git a/generated/markdown/catbox-redis/changelog.md b/generated/markdown/catbox-redis/changelog.md new file mode 100644 index 00000000..e8b4a842 --- /dev/null +++ b/generated/markdown/catbox-redis/changelog.md @@ -0,0 +1,147 @@ +## Version 7 {#v7} + +### [7.0.2](https://github.com/hapijs/catbox-redis/milestone/33) {#7.0.2} + +- [#128](https://github.com/hapijs/catbox-redis/pull/128) chore: enable lab type tests +- [#126](https://github.com/hapijs/catbox-redis/pull/126) feat: 🎸 add and improve typings from DT + +### [7.0.1](https://github.com/hapijs/catbox-redis/milestone/32) {#7.0.1} + +- [#125](https://github.com/hapijs/catbox-redis/pull/125) chore: bump hoek + +### [7.0.0](https://github.com/hapijs/catbox-redis/milestone/31) {#7.0.0} + +- [#123](https://github.com/hapijs/catbox-redis/pull/123) Support for node v18, ESM tests, upgrade ioredis + +## Version 6 {#v6} + +### [6.0.2](https://github.com/hapijs/catbox-redis/milestone/29) {#6.0.2} + +- [#117](https://github.com/hapijs/catbox-redis/pull/117) update deps and use travis templates + +### [6.0.1](https://github.com/hapijs/catbox-redis/milestone/28) {#6.0.1} + +- [#115](https://github.com/hapijs/catbox-redis/issues/115) Redis Configuration Options + +### [6.0.0](https://github.com/hapijs/catbox-redis/milestone/27) {#6.0.0} + +- [#112](https://github.com/hapijs/catbox-redis/issues/112) Only node 12 + +## Version 5 {#v5} + +### [5.0.5](https://github.com/hapijs/catbox-redis/milestone/26) {#5.0.5} + +- [#109](https://github.com/hapijs/catbox-redis/pull/109) Use PSETEX instead of SET and PEXP + +### [5.0.4](https://github.com/hapijs/catbox-redis/milestone/25) {#5.0.4} + +- [#107](https://github.com/hapijs/catbox-redis/issues/107) Update joi +- [#103](https://github.com/hapijs/catbox-redis/issues/103) Example "db" parameter error + +### [5.0.3](https://github.com/hapijs/catbox-redis/milestone/24) {#5.0.3} + +- [#106](https://github.com/hapijs/catbox-redis/issues/106) Update deps + +### [5.0.2](https://github.com/hapijs/catbox-redis/milestone/23) {#5.0.2} + +- [#102](https://github.com/hapijs/catbox-redis/issues/102) Allowing empty password + +### [5.0.1](https://github.com/hapijs/catbox-redis/milestone/22) {#5.0.1} + +- [#100](https://github.com/hapijs/catbox-redis/pull/100) hotfix: redis tls opt is an object, not boolean + +### [5.0.0](https://github.com/hapijs/catbox-redis/milestone/21) {#5.0.0} + +- [#98](https://github.com/hapijs/catbox-redis/issues/98) Switch to use Redis pexpire +- [#97](https://github.com/hapijs/catbox-redis/issues/97) Refactor options +- [#96](https://github.com/hapijs/catbox-redis/issues/96) Change module namespace + +## Version v4 {#vv4} + +### [v4.1.0](https://github.com/hapijs/catbox-redis/milestone/20) {#v4.1.0} + +- [#79](https://github.com/hapijs/catbox-redis/pull/79) Don't mess with provided clients + +### [v4.0.1](https://github.com/hapijs/catbox-redis/milestone/18) {#v4.0.1} + +- [#69](https://github.com/hapijs/catbox-redis/pull/69) added support for dropSegment + +### [v4.0.0](https://github.com/hapijs/catbox-redis/milestone/15) {#v4.0.0} + +- [#77](https://github.com/hapijs/catbox-redis/pull/77) Update to work with Catbox 10 (Hapi 17) + +## Version v3 {#vv3} + +### [v3.2.0](https://github.com/hapijs/catbox-redis/milestone/16) {#v3.2.0} + +### [v3.1.1](https://github.com/hapijs/catbox-redis/milestone/17) {#v3.1.1} + +- [#74](https://github.com/hapijs/catbox-redis/pull/74) Ensure the client really is ready + +### [v3.1.0](https://github.com/hapijs/catbox-redis/milestone/14) {#v3.1.0} + +- [#72](https://github.com/hapijs/catbox-redis/pull/72) Upgrade `ioredis` to `3.x.x` +- [#71](https://github.com/hapijs/catbox-redis/pull/71) chore(package): update ioredis to v3 + +### [v3.0.3](https://github.com/hapijs/catbox-redis/milestone/13) {#v3.0.3} + +### [v3.0.0](https://github.com/hapijs/catbox-redis/milestone/12) {#v3.0.0} + +- [#62](https://github.com/hapijs/catbox-redis/pull/62) update dependencies +- [#53](https://github.com/hapijs/catbox-redis/pull/53) Move to `ioredis` + +## Version v2 {#vv2} + +### [v2.0.3](https://github.com/hapijs/catbox-redis/milestone/11) {#v2.0.3} + +- [#52](https://github.com/hapijs/catbox-redis/pull/52) upgrade code@3 and lab@11 +- [#51](https://github.com/hapijs/catbox-redis/pull/51) Add option to ignore startup failures + +### [v2.0.2](https://github.com/hapijs/catbox-redis/milestone/10) {#v2.0.2} + +- [#49](https://github.com/hapijs/catbox-redis/pull/49) Use `false` parameter to `client.end` in order to fail silently + +### [v2.0.1](https://github.com/hapijs/catbox-redis/milestone/9) {#v2.0.1} + +- [#47](https://github.com/hapijs/catbox-redis/pull/47) Adding flush parameter when calling client.end +- [#45](https://github.com/hapijs/catbox-redis/pull/45) Test on node v6, update dependencies + +## Version v1 {#vv1} + +### [v1.1.0](https://github.com/hapijs/catbox-redis/milestone/7) {#v1.1.0} + +- [#36](https://github.com/hapijs/catbox-redis/pull/36) Ignore partition if not defined + +### [v1.0.9](https://github.com/hapijs/catbox-redis/milestone/8) {#v1.0.9} + +- [#40](https://github.com/hapijs/catbox-redis/pull/40) Allow passing a ready Redis client +- [#39](https://github.com/hapijs/catbox-redis/pull/39) Drop node 0.10 support +- [#30](https://github.com/hapijs/catbox-redis/pull/30) Add unix socket support + +### [v1.0.8](https://github.com/hapijs/catbox-redis/milestone/6) {#v1.0.8} + +- [#38](https://github.com/hapijs/catbox-redis/pull/38) Cleanup tests +- [#37](https://github.com/hapijs/catbox-redis/pull/37) Wait redis client to be ready in order to make sure that authentication has been done +- [#31](https://github.com/hapijs/catbox-redis/pull/31) Loosen dependency to redis 2.x.x to allow 2.3.0 to match + +### [v1.0.6](https://github.com/hapijs/catbox-redis/milestone/5) {#v1.0.6} + +- [#27](https://github.com/hapijs/catbox-redis/pull/27) Upgrade outdated node-redis dependency + +## Version 1 {#v1} + +### [1.0.4](https://github.com/hapijs/catbox-redis/milestone/4) {#1.0.4} + +- [#8](https://github.com/hapijs/catbox-redis/issues/8) Rename spumko to hapijs + +### [1.0.3](https://github.com/hapijs/catbox-redis/milestone/3) {#1.0.3} + +- [#7](https://github.com/hapijs/catbox-redis/issues/7) Remove large ttl test + +### [1.0.2](https://github.com/hapijs/catbox-redis/milestone/2) {#1.0.2} + +- [#5](https://github.com/hapijs/catbox-redis/issues/5) Bring coverage back to 100% + +### [1.0.1](https://github.com/hapijs/catbox-redis/milestone/1) {#1.0.1} + +- [#3](https://github.com/hapijs/catbox-redis/issues/3) Add example diff --git a/generated/markdown/catbox/12/api.md b/generated/markdown/catbox/12/api.md new file mode 100644 index 00000000..55344140 --- /dev/null +++ b/generated/markdown/catbox/12/api.md @@ -0,0 +1,182 @@ +**catbox** is a multi-strategy key-value object store. It comes with extensions supporting a memory +cache, [Redis](http://redis.io/), and [Memcached](http://memcached.org/). Additional providers from the +community can be found on the [npm Registry](https://www.npmjs.com/search?q=keywords:catbox). + +**catbox** provides two interfaces: a low-level `Client` and a high-level `Policy`. + +### Installation + +In order to reduce module dependencies, **catbox** does not include the external caching +strategies. To use other strategies, each service must be manually installed via npm or package +dependencies manually. The available strategies are: + +- [Memory](https://github.com/hapijs/catbox-memory) +- [Redis](https://github.com/hapijs/catbox-redis) +- [Memcached](https://github.com/hapijs/catbox-memcached) + +### `Client` + +The `Client` object provides a low-level cache abstraction. The object is constructed using +`new Client(engine, options)` where: + +- `engine` - is an object or a prototype function implementing the cache strategy: + - function - a prototype function with the signature `function(options)`. **catbox** will call + `new func(options)`. + - object - a pre instantiated client implementation object. Does not support passing `options`. +- `options` - the strategy configuration object. Each strategy defines its own configuration + options with the following common options: + - `partition` - the partition name used to isolate the cached results across multiple clients. + The partition name is used as the MongoDB database name, the Riak bucket, or as a key prefix + in Redis and Memcached. To share the cache across multiple clients, use the same partition + name. + +Note that any implementation of client strategies must return deep copies of the stored data as the +API assumes that the object returned from a `get()` is owned by the called and can be safely +modified without affecting the cache copy. + +#### API + +The `Client` object provides the following methods: + +- `await start()` - creates a connection to the cache server. Must be called before any other + method is available. Any errors are thrown. +- `await stop()` - terminates the connection to the cache server. +- `await get(key)` - retrieve an item from the cache engine if found where: + - `key` - a cache key object (see below). + - return value: + - `null` is the item is not found. + - throws an error if the request failed. + - otherwise, an object with the following properties: + - `item` - the value stored in the cache using `set()`. + - `stored` - the timestamp when the item was stored in the cache (in milliseconds). + - `ttl` - the remaining time-to-live (not the original value used when storing the + object). +- `await set(key, value, ttl)` - store an item in the cache for a specified length of time, where: + - `key` - a cache key object (see below). + - `value` - the string or object value to be stored. + - `ttl` - a time-to-live value in milliseconds after which the item is automatically removed + from the cache (or is marked invalid). + - any errors are thrown. +- `await drop(key)` - remove an item from cache where: + - `key` - a cache key object (see below). + - any errors are thrown. +- `isReady()` - returns `true` if cache engine determines itself as ready, `false` if it is not + ready. +- `validateSegmentName(segment)` - returns `null` if the segment name is valid (see below), + otherwise should return an instance of `Error` with an appropriate message. + +Any method with a `key` argument takes an object with the following required properties: + +- `segment` - a caching segment name string. Enables using a single cache server for storing + different sets of items with overlapping ids. +- `id` - a unique item identifier string (per segment). Can be an empty string. + +### `Policy` + +The `Policy` object provides a convenient cache interface by setting a global policy which is +automatically applied to every storage action. The object is constructed using +`new Policy(options, [cache, segment])` where: + +- `options` - is an object with the following optional keys (unless noted otherwise): + - `expiresIn` - relative expiration expressed in the number of milliseconds since the item was + saved in the cache. Cannot be used together with `expiresAt`. + - `expiresAt` - time of day expressed in 24h notation using the 'HH:MM' format, at which point + all cache records for the route expire. Uses local time. Cannot be used together with + `expiresIn`. + - `generateFunc` - a function used to generate a new cache item if one is not found in the + cache when calling `get()`. The method's signature is `async function(id, flags)` where: + - `id` - the `id` string or object provided to the `get()` method as-is (not normalized). + - `flags` - an object used to pass back additional flags: + - `ttl` - the cache ttl value in milliseconds. Set to `0` to skip storing in the cache. + Defaults to the cache global policy. + - `staleIn` - number of milliseconds to mark an item stored in cache as stale and attempt to + regenerate it when `generateFunc` is provided. Must be less than `expiresIn`. Alternatively + function that returns staleIn value in milliseconds. The function signature is + `function(stored, ttl)` where: + - `stored` - the timestamp when the item was stored in the cache (in milliseconds). + - `ttl` - the remaining time-to-live (not the original value used when storing the object). + - `staleTimeout` - number of milliseconds to wait before returning a stale value while + generateFunc is generating a fresh value. + - `generateTimeout` - number of milliseconds to wait before returning a timeout error when the + `generateFunc` function takes too long to return a value. When the value is eventually + returned, it is stored in the cache for future requests. Required if `generateFunc` is + present. Set to `false` to disable timeouts which may cause all `get()` requests to get stuck + forever. + - `dropOnError` - if `true`, an error or timeout in the `generateFunc` causes the stale value + to be evicted from the cache. Defaults to `true`. + - `generateOnReadError` - if `false`, an upstream cache read error will stop the `get()` method + from calling the generate function and will instead pass back the cache error. Defaults to + `true`. + - `generateIgnoreWriteError` - if `false`, an upstream cache write error will be passed back + with the generated value when calling the `get()` method. Defaults to `true`. + - `pendingGenerateTimeout` - number of milliseconds while generateFunc call is in progress for + a given id, before a subsequent generateFunc call is allowed. Defaults to 0, no blocking of + concurrent generateFunc calls beyond staleTimeout. + - `getDecoratedValue` - if `true`, the return value of `policy.get()` calls is an object with + `{ value, cached, report }`. Defaults to `false` which returns a plain value. +- `cache` - a `Client` instance (which has already been started). +- `segment` - required when `cache` is provided. The segment name used to isolate cached items + within the cache partition. + +#### API + +The `Policy` object provides the following methods: + +- `await get(id)` - retrieve an item from the cache. If the item is not found and the + `generateFunc` method was provided, a new value is generated, stored in the cache, and returned. + Multiple concurrent requests are queued and processed once. The method arguments are: + - `id` - the unique item identifier (within the policy segment). Can be a string or an object + with the required 'id' key. + - return value: + - the requested item if found, otherwise `null`. + - any errors are thrown. + - if `getDecoratedValue` is `true`, returns an object with the following properties: + - `value` - the fetched or generated value. + - `cached` - `null` if a valid item was not found in the cache, or an object with the + following keys: + - `item` - the cached `value`. + - `stored` - the timestamp when the item was stored in the cache. + - `ttl` - the cache ttl value for the record. + - `isStale` - `true` if the item is stale. + - `report` - an object with logging information about the generation operation + containing the following keys (as relevant): + - `msec` - the cache lookup time in milliseconds. + - `stored` - the timestamp when the item was stored in the cache. + - `isStale` - `true` if the item is stale. + - `ttl` - the cache ttl value for the record. + - `error` - lookup error. +- `await set(id, value, ttl)` - store an item in the cache where: + - `id` - the unique item identifier (within the policy segment). + - `value` - the string or object value to be stored. + - `ttl` - a time-to-live **override** value in milliseconds after which the item is + automatically removed from the cache (or is marked invalid). This should be set to `0` in + order to use the caching rules configured when creating the `Policy` object. + - any errors are thrown. +- `await drop(id)` - remove the item from cache where: + - `id` - the unique item identifier (within the policy segment). + - any errors are thrown. +- `ttl(created)` - given a `created` timestamp in milliseconds, returns the time-to-live left based + on the configured rules. +- `rules(options)` - changes the policy rules after construction (note that items already stored + will not be affected) where: + - `options` - the same `options` as the `Policy` constructor. +- `isReady()` - returns `true` if cache engine determines itself as ready, `false` if it is not + ready or if there is no cache engine set. +- `stats` - an object with cache statistics where: + - `sets` - number of cache writes. + - `gets` - number of cache `get()` requests. + - `hits` - number of cache `get()` requests in which the requested id was found in the cache + (can be stale). + - `stales` - number of cache reads with stale requests (only counts the first request in a + queued `get()` operation). + - `generates` - number of calls to the generate function. + - `errors` - cache operations errors. +- `events` - a [**podium**](https://github.com/hapijs/podium) event emitter, emitting `'error'` + events under the following channels: + - `'persist'` - emits any cache errors thrown during the generation of new values as a result + of a `get()` request. + - `'generate'` - emits any new value generation errors thrown as a result of a `get()` request. +- `client` - a reference to the cache client if set. + +Note that errors generated by `set()` and `drop()` are reported directly by the functions calls and +are not included in the reported events. diff --git a/generated/markdown/catbox/changelog.md b/generated/markdown/catbox/changelog.md new file mode 100644 index 00000000..69505342 --- /dev/null +++ b/generated/markdown/catbox/changelog.md @@ -0,0 +1,281 @@ +## Version 12 {#v12} + +### [12.1.1](https://github.com/hapijs/catbox/milestone/58) {#12.1.1} + +- [#243](https://github.com/hapijs/catbox/pull/243) chore: bump hoek + +### [12.1.0](https://github.com/hapijs/catbox/milestone/57) {#12.1.0} + +- [#242](https://github.com/hapijs/catbox/pull/242) Add typescript types + +### [12.0.1](https://github.com/hapijs/catbox/milestone/56) {#12.0.1} + +- [#240](https://github.com/hapijs/catbox/issues/240) Validate engines to detect legacy adaptor modules + +### [12.0.0](https://github.com/hapijs/catbox/milestone/55) {#12.0.0} + +- [#239](https://github.com/hapijs/catbox/pull/239) Support node v18 and drop node v12 + +## Version 11 {#v11} + +### [11.1.1](https://github.com/hapijs/catbox/milestone/54) {#11.1.1} + +- [#231](https://github.com/hapijs/catbox/pull/231) Replace joi with validate + +### [11.1.0](https://github.com/hapijs/catbox/milestone/53) {#11.1.0} + +- [#229](https://github.com/hapijs/catbox/issues/229) Expose cache client in policy + +### [11.0.1](https://github.com/hapijs/catbox/milestone/52) {#11.0.1} + +- [#228](https://github.com/hapijs/catbox/issues/228) pendingGenerateTimeout causes weird timing situation + +### [11.0.0](https://github.com/hapijs/catbox/milestone/51) {#11.0.0} + +- [#227](https://github.com/hapijs/catbox/issues/227) Only node 12 + +## Version 10 {#v10} + +### [10.2.3](https://github.com/hapijs/catbox/milestone/49) {#10.2.3} + +- [#220](https://github.com/hapijs/catbox/issues/220) Update joi + +### [10.2.2](https://github.com/hapijs/catbox/milestone/48) {#10.2.2} + +- [#217](https://github.com/hapijs/catbox/issues/217) Update deps + +### [10.2.1](https://github.com/hapijs/catbox/milestone/47) {#10.2.1} + +- [#216](https://github.com/hapijs/catbox/issues/216) Update joi dep + +### [10.2.0](https://github.com/hapijs/catbox/milestone/46) {#10.2.0} + +- [#215](https://github.com/hapijs/catbox/issues/215) Old pendingGenerateTimeout can clear new one +- [#210](https://github.com/hapijs/catbox/issues/210) If generate takes longer than staleTimeout, errors get swallowed + +### [10.1.0](https://github.com/hapijs/catbox/milestone/43) {#10.1.0} + +- [#214](https://github.com/hapijs/catbox/issues/214) Change module namespace + +### [10.0.6](https://github.com/hapijs/catbox/milestone/42) {#10.0.6} + +- [#208](https://github.com/hapijs/catbox/pull/208) Add changelog.md +- [#206](https://github.com/hapijs/catbox/pull/206) Support ioredis client option for catbox-redis + +### [10.0.5](https://github.com/hapijs/catbox/milestone/41) {#10.0.5} + +- [#205](https://github.com/hapijs/catbox/issues/205) Remove engines + +### [10.0.4](https://github.com/hapijs/catbox/milestone/40) {#10.0.4} + +- [#204](https://github.com/hapijs/catbox/issues/204) Update hoek v6 + +### [10.0.3](https://github.com/hapijs/catbox/milestone/39) {#10.0.3} + +- [#201](https://github.com/hapijs/catbox/issues/201) Update lab +- [#200](https://github.com/hapijs/catbox/pull/200) Unhandled rejection on get() errors + +### [10.0.2](https://github.com/hapijs/catbox/milestone/38) {#10.0.2} + +- [#194](https://github.com/hapijs/catbox/issues/194) Add bounce protection + +### [10.0.1](https://github.com/hapijs/catbox/milestone/37) {#10.0.1} + +- [#193](https://github.com/hapijs/catbox/issues/193) Update boom + +### [10.0.0](https://github.com/hapijs/catbox/milestone/36) {#10.0.0} + +- [#192](https://github.com/hapijs/catbox/issues/192) Require clients to be async + +## Version 9 {#v9} + +### [9.0.0](https://github.com/hapijs/catbox/milestone/35) {#9.0.0} + +- [#191](https://github.com/hapijs/catbox/issues/191) Change policy.get() return value to plain (with override option) + +## Version 8 {#v8} + +### [8.0.1](https://github.com/hapijs/catbox/milestone/34) {#8.0.1} + +### [8.0.0](https://github.com/hapijs/catbox/milestone/33) {#8.0.0} + +- [#190](https://github.com/hapijs/catbox/pull/190) Migrate to async/await + +## Version 7 {#v7} + +### [7.2.0](https://github.com/hapijs/catbox/milestone/44) {#7.2.0} + +- [#213](https://github.com/hapijs/catbox/issues/213) Commercial version of v7 branch + +### [7.1.5](https://github.com/hapijs/catbox/milestone/32) {#7.1.5} + +- [#185](https://github.com/hapijs/catbox/pull/185) Fix pendingGenerateTimeout timeout issue + +### [7.1.4](https://github.com/hapijs/catbox/milestone/31) {#7.1.4} + +- [#178](https://github.com/hapijs/catbox/pull/178) Ensure generate timeout is triggered when staleTimeout > ttl +- [#166](https://github.com/hapijs/catbox/issues/166) Can we remove the max() from staleIn? +- [#165](https://github.com/hapijs/catbox/issues/165) Can't drop method without arguments + +### [7.1.3](https://github.com/hapijs/catbox/milestone/30) {#7.1.3} + +- [#176](https://github.com/hapijs/catbox/issues/176) Update deps + +### [7.1.2](https://github.com/hapijs/catbox/milestone/29) {#7.1.2} + +- [#168](https://github.com/hapijs/catbox/issues/168) Update deps + +### [7.1.1](https://github.com/hapijs/catbox/milestone/28) {#7.1.1} + +- [#162](https://github.com/hapijs/catbox/pull/162) Test on node v6, update dependencies + +### [7.1.0](https://github.com/hapijs/catbox/milestone/27) {#7.1.0} + +- [#152](https://github.com/hapijs/catbox/pull/152) Adding pendingGenerateTimeout +- [#149](https://github.com/hapijs/catbox/issues/149) Proposal: Stale while revalidate - prevent multiple generate calls +- [#147](https://github.com/hapijs/catbox/pull/147) Update drop function to allow for object keys + +### [7.0.0](https://github.com/hapijs/catbox/milestone/26) {#7.0.0} + +- [#146](https://github.com/hapijs/catbox/issues/146) ES6 style changes and node v4 +- [#145](https://github.com/hapijs/catbox/pull/145) Fixed this.constructor issue + +## Version 6 {#v6} + +### [6.0.0](https://github.com/hapijs/catbox/milestone/25) {#6.0.0} + +- [#140](https://github.com/hapijs/catbox/issues/140) Replace generate cache error handing options + +## Version 5 {#v5} + +### [5.0.0](https://github.com/hapijs/catbox/milestone/24) {#5.0.0} + +- [#137](https://github.com/hapijs/catbox/issues/137) Add generateOnGetError option +- [#136](https://github.com/hapijs/catbox/issues/136) Pass cache set() errors when generating value on get() +- [#134](https://github.com/hapijs/catbox/pull/134) Require generateTimeout with generateFunc. +- [#128](https://github.com/hapijs/catbox/pull/128) Explicitly binding process.domain to the callback +- [#127](https://github.com/hapijs/catbox/issues/127) callbacks are called with wrong process.domain +- [#115](https://github.com/hapijs/catbox/issues/115) get() can get stuck when first request never returns +- [#70](https://github.com/hapijs/catbox/issues/70) No way to monitor cache error rates + +## Version 4 {#v4} + +### [4.3.0](https://github.com/hapijs/catbox/milestone/23) {#4.3.0} + +- [#114](https://github.com/hapijs/catbox/pull/114) Expose cache engine connection isReady as public method + +### [4.2.2](https://github.com/hapijs/catbox/milestone/22) {#4.2.2} + +- [#120](https://github.com/hapijs/catbox/pull/120) Upgrade to Joi 6 + +### [4.2.1](https://github.com/hapijs/catbox/milestone/21) {#4.2.1} + +- [#116](https://github.com/hapijs/catbox/pull/116) Prefix keys with a `'+'` when using object as a hash + +### [4.2.0](https://github.com/hapijs/catbox/milestone/20) {#4.2.0} + +- [#113](https://github.com/hapijs/catbox/issues/113) Allow empty keys +- [#109](https://github.com/hapijs/catbox/pull/109) Return cached on error when dropOnError is false +- [#105](https://github.com/hapijs/catbox/pull/105) StaleIn can be function. + +### [4.1.0](https://github.com/hapijs/catbox/milestone/19) {#4.1.0} + +- [#111](https://github.com/hapijs/catbox/issues/111) Allow changing policy rules after construction + +### [4.0.3](https://github.com/hapijs/catbox/milestone/18) {#4.0.3} + +- [#104](https://github.com/hapijs/catbox/issues/104) Fix tests + +### [4.0.2](https://github.com/hapijs/catbox/milestone/17) {#4.0.2} + +- [#103](https://github.com/hapijs/catbox/issues/103) Explicitly allow hapi keys in policy instead of allowUnknown + +### [4.0.1](https://github.com/hapijs/catbox/milestone/16) {#4.0.1} + +- [#102](https://github.com/hapijs/catbox/issues/102) Use joi for validating policy rules + +### [4.0.0](https://github.com/hapijs/catbox/milestone/15) {#4.0.0} + +- [#101](https://github.com/hapijs/catbox/issues/101) Change policy.get() callback to use a consistent signature regardless of generateFunc +- [#100](https://github.com/hapijs/catbox/issues/100) Require generateFunc options for staleIn, staleTimeout, and generateTimeout +- [#99](https://github.com/hapijs/catbox/issues/99) Remove getOrGenerate() +- [#98](https://github.com/hapijs/catbox/pull/98) Adding ability to retain a stale value when generate function fails +- [#97](https://github.com/hapijs/catbox/issues/97) Retain stale on error + +## Version 3 {#v3} + +### [3.4.3](https://github.com/hapijs/catbox/milestone/14) {#3.4.3} + +- [#95](https://github.com/hapijs/catbox/issues/95) Leftover background timeouts can interlace with new requests +- [#93](https://github.com/hapijs/catbox/pull/93) Rarely cache can serve old value having slower backend + +### [3.4.2](https://github.com/hapijs/catbox/milestone/13) {#3.4.2} + +- [#86](https://github.com/hapijs/catbox/pull/86) Fix concurrent getOrGenerate bug. Closes #85 +- [#85](https://github.com/hapijs/catbox/pull/85) Problems with concurrent invocation of getOrGenerate. + +### [3.4.1](https://github.com/hapijs/catbox/milestone/12) {#3.4.1} + +- [#84](https://github.com/hapijs/catbox/issues/84) null or undefined expiresIn/At break compile + +### [3.4.0](https://github.com/hapijs/catbox/milestone/11) {#3.4.0} + +- [#83](https://github.com/hapijs/catbox/issues/83) Errors thrown in get() block pending queue +- [#82](https://github.com/hapijs/catbox/issues/82) Allow setting cache with default expiresIn 0 (no cache) + +### [3.3.0](https://github.com/hapijs/catbox/milestone/10) {#3.3.0} + +- [#80](https://github.com/hapijs/catbox/issues/80) Allow setting policy without expiration when server side disabled + +### [3.2.0](https://github.com/hapijs/catbox/milestone/9) {#3.2.0} + +- [#79](https://github.com/hapijs/catbox/pull/79) Queue get requests +- [#78](https://github.com/hapijs/catbox/issues/78) Incomplete coverage when testing at 23:00 +- [#77](https://github.com/hapijs/catbox/issues/77) expiredAt fails to zero milliseconds +- [#76](https://github.com/hapijs/catbox/issues/76) expiredAt returns negative ttl on created < expired < now +- [#75](https://github.com/hapijs/catbox/issues/75) Move generate method to policy config +- [#73](https://github.com/hapijs/catbox/issues/73) Chain concurrent gets +- [#71](https://github.com/hapijs/catbox/pull/71) Update to Lab 4 + +### [3.1.0](https://github.com/hapijs/catbox/milestone/8) {#3.1.0} + +- [#69](https://github.com/hapijs/catbox/issues/69) Error fails to clear cache is error arrives before stale timeout +- [#68](https://github.com/hapijs/catbox/issues/68) staleTimeout for first request should returns null if no data at timeout time + +### [3.0.0](https://github.com/hapijs/catbox/milestone/6) {#3.0.0} + +- [#67](https://github.com/hapijs/catbox/issues/67) Remove internal require() call +- [#66](https://github.com/hapijs/catbox/pull/66) Remove large ttl check +- [#65](https://github.com/hapijs/catbox/issues/65) Move 32bit ttl restriction to catbox-memory + +## Version 2 {#v2} + +### [2.2.1](https://github.com/hapijs/catbox/milestone/7) {#2.2.1} + +- [#62](https://github.com/hapijs/catbox/issues/62) Bring coverage back to 100% + +### [2.2.0](https://github.com/hapijs/catbox/milestone/5) {#2.2.0} + +- [#58](https://github.com/hapijs/catbox/pull/58) Allow falsey values to be cached + +### [2.1.0](https://github.com/hapijs/catbox/milestone/4) {#2.1.0} + +- [#56](https://github.com/hapijs/catbox/issues/56) Policy.getOrGenerate returns content in two different formats +- [#51](https://github.com/hapijs/catbox/issues/51) Impossible to use a custom storage backend with the Hapi CLI + +## Version 1 {#v1} + +### [1.2.0](https://github.com/hapijs/catbox/milestone/3) {#1.2.0} + +- [#49](https://github.com/hapijs/catbox/pull/49) Close the redis connection on error + +## Version 0 {#v0} + +### [0.1.0](https://github.com/hapijs/catbox/milestone/2) {#0.1.0} + +- [#14](https://github.com/hapijs/catbox/issues/14) Remove redis and mongodb dependencies (and move to devdeps) +- [#13](https://github.com/hapijs/catbox/issues/13) Remove hapi dependencies +- [#12](https://github.com/hapijs/catbox/issues/12) Need to better organize config options +- [#6](https://github.com/hapijs/catbox/issues/6) Add examples +- [#5](https://github.com/hapijs/catbox/issues/5) Document interfaces, features +- [#4](https://github.com/hapijs/catbox/issues/4) Bring test coverage to 100% diff --git a/generated/markdown/code/9/api.md b/generated/markdown/code/9/api.md new file mode 100644 index 00000000..9fbd90f0 --- /dev/null +++ b/generated/markdown/code/9/api.md @@ -0,0 +1,752 @@ +### Introduction + +**code** was created as a direct rewrite of the powerful [**chai**](http://chaijs.com) assertions +library. This virtual fork was created for a few reasons. First, **chai** mixed usage of methods and +properties creates a problematic environment in which it is too easy to forget a method `()` and result +in an assertion that is never executed (and therefore passes incorrectly). This observation was noted by +the [**must**](https://github.com/moll/js-must) author. + +The second reason is that similar to [**lab**](https://github.com/hapijs/lab), our test runner, we wanted +an assertion library that is small, simple, and intuitive - without plugins, extensions, or the overhead +of having to support testing in the browser. **code** provides much of the same functionality in about +300 lines of code that are trivial to read in a few minutes. + +And last, we wanted to experiment with some new features that allow deeper integration between the test +runner and assertions library. The first of which are two methods exported (and used by **lab**) for getting +the total assertions count (which is a measure of the tests comprehensiveness), and by verifying that every +assertion created (e.g. every `expect()` call) is also executed. This will alert when a statement like +`expect(5).to.be.a.string` is not allowed to remain unnoticed (and fail to throw due to the missing `()`). + +Like **lab**, the goal is to keep this module small and simple. If you need extensibility or other +functionality, we recommend looking at the many other excellent assertions libraries available. + +### Example + +```js +const Code = require('@hapi/code'); +const expect = Code.expect; + +expect(true).to.be.a.boolean().and.to.not.equal(false); +expect('this string').to.only.include(['this', 'string']); +``` + +### Grammar + +**code** supports usage of connecting words to make assertions more readable. The inclusion of these +grammar elements has no impact over the assertion outcome and are used for human readability only. +Every method or property of the assertion object returned by `expect()` returns `this` which allows +chaining addition assertions or grammar words. + +The supported words are: + +- `a` +- `an` +- `and` +- `at` +- `be` +- `have` +- `in` +- `to` + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(10).to.be.above(5); +expect('abc').to.be.a.string(); +expect([1, 2]).to.be.an.array(); +expect(20).to.be.at.least(20); +expect('abc').to.have.length(3); +expect('abc').to.be.a.string().and.contain(['a', 'b']); +expect(6).to.be.in.range(5, 6); +``` + +### Flags + +The following words toggle a status flag for the current assertion: + +- `not` - inverses the expected result of any assertion. +- `once` - requires that inclusion matches appear only once in the provided value. Used by `include()`. +- `only` - requires that only the provided elements appear in the provided value. Used by `include()`. +- `part` - allows a partial match when asserting inclusion. Used by `include()`. Defaults to `false`. +- `shallow` - performs a comparison using strict equality (`===`). Code defaults to deep comparison. Used by `equal()` and `include()`. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(10).to.not.be.above(20); +expect([1, 2, 3]).to.shallow.include(3); +expect([1, 1, 2]).to.only.include([1, 2]); +expect([1, 2]).to.once.include([1, 2]); +expect([1, 2, 3]).to.part.include([1, 4]); +``` + +Note that including the same flag twice toggles the last value set. This is especially important when +chaining multiple assertions in a single statement (e.g. when using the `and` grammar word). + +### `expect(value, [prefix])` + +Generates an assertion object where: + +- `value` - the reference value on which to apply the assertion rules. +- `prefix` - an optional string used as an error message prefix. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(10, 'Age').to.be.above(5); +``` + +#### Types + +Asserts that the reference value is of a certain type. + +##### `arguments()` + +Asserts that the reference value is an `arguments` object. + +```js +const Code = require('code'); +const expect = Code.expect; +const func = function () { + return arguments; +}; +expect(func()).to.be.arguments(); +``` + +##### `array()` + +Asserts that the reference value is an `Array`. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect([1, 2]).to.be.an.array(); +``` + +##### `boolean()` + +Asserts that the reference value is a boolean. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(true).to.be.a.boolean(); +``` + +##### `buffer()` + +Asserts that the reference value is a `Buffer`. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(new Buffer('')).to.be.a.buffer(); +``` + +##### `date()` + +Asserts that the reference value is a `Date`. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(new Date()).to.be.a.date(); +``` + +##### `error([type], [message])` + +Asserts that the reference value is an error. You can provide optional requirements where: + +- `type` - the `instanceof` value of the error. +- `message` a string or regular expression matching the error `message` property. Note that a string + must provide a full match. + +```js +const Code = require('code'); +const expect = Code.expect; + +const err = new Error('Oops an error occured.'); +expect(err).to.be.an.error(); +expect(err).to.be.an.error(Error); +expect(err).to.be.an.error('Oops an error occured.'); +expect(err).to.be.an.error(Error, /occured/); +``` + +##### `function()` + +Asserts that the reference value is a `function`. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(function () {}).to.be.a.function(); +``` + +##### `number()` + +Asserts that the reference value is a `number`. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(123).to.be.a.number(); +``` + +##### `regexp()` + +Asserts that the reference value is an `RegExp`. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(/abc/).to.be.a.regexp(); +``` + +##### `string()` + +Asserts that the reference value is a string. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect('abc').to.be.a.string(); +``` + +##### `object()` + +Asserts that the reference value is an object (excluding array, buffer, or other native objects). + +```js +const Code = require('code'); +const expect = Code.expect; + +expect({ a: '1' }).to.be.an.object(); +``` + +#### Values + +Asserts that the reference value is equal to a predefined value. + +##### `true()` + +Asserts that the reference value is true. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(true).to.be.true(); +``` + +##### `false()` + +Asserts that the reference value is false. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(false).to.be.false(); +``` + +##### `null()` + +Asserts that the reference value is null. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(null).to.be.null(); +``` + +##### `undefined()` + +Asserts that the reference value is undefined. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(undefined).to.be.undefined(); +``` + +##### `NaN()` + +Asserts that the reference value is `NaN`. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(NaN).to.be.NaN(); +``` + +#### `include(values)` + +Aliases: `includes()`, `contain()`, `contains()` + +See also: [`Hoek.contain()`](https://github.com/hapijs/hoek/blob/master/API.md#containref-values-options) + +Asserts that the reference value (a string, array, or object) includes the provided values where: + +- `values` - a single or array of values. If the reference value is a string, the values must be strings. + If the reference value is an array, the values can be any array member. If the reference value is an object, the values can be key names, or a single object + with key-value pairs to match. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect('abc').to.include('ab'); +expect('abc').to.only.include('abc'); +expect('aaa').to.only.include('a'); +expect('abc').to.once.include('b'); +expect('abc').to.include(['a', 'c']); +expect('abc').to.part.include(['a', 'd']); + +expect([1, 2, 3]).to.include(1); +expect([{ a: 1 }]).to.include({ a: 1 }); +expect([1, 2, 3]).to.include([1, 2]); +expect([{ a: 1 }]).to.include([{ a: 1 }]); +expect([1, 1, 2]).to.only.include([1, 2]); +expect([1, 2]).to.once.include([1, 2]); +expect([1, 2, 3]).to.part.include([1, 4]); +expect([[1], [2]]).to.include([[1]]); + +expect({ a: 1, b: 2, c: 3 }).to.include('a'); +expect({ a: 1, b: 2, c: 3 }).to.include(['a', 'c']); +expect({ a: 1, b: 2, c: 3 }).to.only.include(['a', 'b', 'c']); +expect({ a: 1, b: 2, c: 3 }).to.include({ a: 1 }); +expect({ a: 1, b: 2, c: 3 }).to.include({ a: 1, c: 3 }); +expect({ a: 1, b: 2, c: 3 }).to.part.include({ a: 1, d: 4 }); +expect({ a: 1, b: 2, c: 3 }).to.only.include({ a: 1, b: 2, c: 3 }); +expect({ a: [1], b: [2], c: [3] }).to.include({ a: [1], c: [3] }); +``` + +#### `startWith(value)` + +Aliases: `startsWith()`, + +Asserts that the reference value (a string) starts with the provided value where: + +- `value` - a string. + +Note that this assertion is case sensitive. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect('https://example.org/secure').to.startWith('https://'); +``` + +#### `endWith(value)` + +Aliases: `endsWith()`, + +Asserts that the reference value (a string) ends with the provided value where: + +- `value` - a string. + +Note that this assertion is case sensitive. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect('http://example.org/relative').to.endWith('/relative'); +``` + +#### `exist()` + +Aliases: `exists` + +Asserts that the reference value exists (not `null` or `undefined`). + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(4).to.exist(); +expect(null).to.not.exist(); +``` + +#### `empty()` + +Asserts that the reference value has a `length` property equal to zero or an object with no keys. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect('abc').to.be.empty(); +``` + +#### `length(size)` + +Asserts that the reference value has a `length` property matching the provided size or an object with the +specified number of keys where: + +- `size` - the required size. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect('abcd').to.have.length(4); +``` + +#### `equal(value[, options])` + +Aliases: `equals()` + +Asserts that the reference value equals the provided value where: + +- `value` - the value to compare to. +- `options` - optional object specifying comparison options. This is ignored on `shallow` comparisons. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(5).to.equal(5); +expect({ a: 1 }).to.equal({ a: 1 }); +``` + +Deep comparisons (the default) are performed using +[`Hoek.deepEqual()`](https://github.com/hapijs/hoek/blob/master/API.md#deepequalb-a-options). The +optional `options` argument is passed directly to `Hoek.deepEqual()`. An example +deep comparison which ignores object prototypes is shown below. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(Object.create(null)).to.equal({}, { prototype: false }); +``` + +Strict equality can be checked using the `shallow` modifier. This yields the same output as a `===` check. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(5).to.shallow.equal(5); +expect({ a: 1 }).to.shallow.equal({ a: 1 }); // fails as they are not the same reference +``` + +#### `above(value)` + +Aliases: `greaterThan()` + +Asserts that the reference value is greater than (`>`) the provided value where: + +- `value` - the value to compare to. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(10).to.be.above(5); +``` + +#### `least(value)` + +Aliases: `min()` + +Asserts that the reference value is at least (`>=`) the provided value where: + +- `value` - the value to compare to. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(10).to.be.at.least(10); +``` + +#### `below(value)` + +Aliases: `lessThan()` + +Asserts that the reference value is less than (`<`) the provided value where: + +- `value` - the value to compare to. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(10).to.be.below(20); +``` + +#### `most(value)` + +Aliases: `max()` + +Asserts that the reference value is at most (`<=`) the provided value where: + +- `value` - the value to compare to. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(10).to.be.at.most(10); +``` + +#### `within(from, to)` + +Aliases: `range()` + +Asserts that the reference value is within (`from <= value <= to`) the provided values where: + +- `from` - the start of the range (inclusive). +- `to` - the end of the range (inclusive). + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(10).to.be.within(10, 20); +expect(20).to.be.within(10, 20); +``` + +#### `between(from, to)` + +Asserts that the reference value is between but not equal (`from < value < to`) the provided values where: + +- `from` - the start of the range (exclusive). +- `to` - the end of the range (exclusive). + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(15).to.be.between(10, 20); +``` + +#### `about(value, delta)` + +Asserts that the reference value is about the provided value within a delta margin of difference where: + +- `value` - the value to compare to. +- `delta` - the allowed margin of difference. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(10).to.be.about(9, 1); +``` + +#### `instanceof(type)` + +Aliases: `instanceOf()` + +Asserts that the reference value has the provided `instanceof` value where: + +- `type` - the type value to match. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(new Date()).to.be.an.instanceof(Date); +``` + +#### `match(regex)` + +Aliases: `matches()` + +Asserts that the reference value's `toString()` representation matches the provided regular +expression where: + +- `regex` - the regular expression to match. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect('a5').to.match(/\w\d/); +expect(['abc', 'def']).to.match(/^[\w\d,]*$/); +expect(1).to.match(/^\d$/); +``` + +#### `satisfy(validator)` + +Aliases: `satisfies()` + +Asserts that the reference value satisfies the provided validator function where: + +- `validator` - a function with the signature `function(value)` with return value `true` or `false`. The + reference value is passed as the only argument to the `validator` function and the assertion passes if + the return value is `true`. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect('x').to.satisfy(function (value) { + return value === 'x'; +}); +``` + +#### `throw([type], [message])` + +Aliases: `throws` + +Asserts that the function reference value throws an exception when called. The provided reference function +is invoked within a `try`-`catch` block and any error throws is caught and compared to the provided optional +requirements where: + +- `type` - the `instanceof` value of the thrown object. +- `message` a string or regular expression matching the thrown error `message` property. Note that a string + must provide a full match. + +```js +const NodeUtil = require('util'); +const Code = require('code'); +const expect = Code.expect; + +const CustomError = function (message) { + Error.call(this, message); +}; + +NodeUtil.inherit(CustomError, Error); + +const throws = function () { + throw new CustomError('Oh no!'); +}; + +expect(throws).to.throw(CustomError, 'Oh no!'); +``` + +#### `await reject([type], [message])` + +Aliases: `rejects` + +Asserts that the `Promise` reference value rejects with an exception when called. The provided reference +promise is resolved using an `await` statement within a `try`-`catch` block and any error throws is caught +and compared to the provided optional requirements where: + +- `type` - the `instanceof` value of the rejected object. +- `message` a string or regular expression matching the rejected error `message` property. Note that a string + must provide a full match. + +Returns a promise resolving to the rejected error object. + +```js +const NodeUtil = require('util'); +const Code = require('code'); +const expect = Code.expect; + +const CustomError = function (message, code) { + this.message = message; + this.code = code; +}; + +NodeUtil.inherits(CustomError, Error); + +const rejects = function () { + return new Promise((resolve, reject) => + reject(new CustomError('Oh no!', 123)), + ); +}; + +const err = await expect(rejects()).to.reject(CustomError, 'Oh no!'); +expect(err.code).to.equal(123); +``` + +### `fail(message)` + +Makes the test fail with `message`. + +```js +const Code = require('code'); + +Code.fail('This should not occur'); +``` + +### `count()` + +Returns the total number of assertions created using the `expect()` method. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(5).to.not.be.a.string(); +console.log(Code.count()); // -> 1 +``` + +### `incomplete()` + +Returns an array of the locations where incomplete assertions were declared or `null` if no incomplete assertions found. + +```js +const Code = require('code'); +const expect = Code.expect; + +expect(5).to.not.be.a.string; +console.log(Code.incomplete()); // -> [ 'readme.js:667:1' ] +``` + +### `thrownAt([error])` + +Returns the filename, line number, and column number of where the `error` was created. If no error is provided, the current location returned. + +```js +const Code = require('code'); + +const error = new Error('oops'); +Code.thrownAt(error); +``` + +### Settings + +**code** can be configured using the module's `settings` object. The following +settings are supported: + +#### `truncateMessages` + +A Boolean value that, when `true`, causes long assertion error messages to be +truncated for readability. Setting this to `false` causes the entire message +to be displayed. Defaults to `true`. + +```js +const Code = require('code'); +const expect = Code.expect; +const foo = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; + +Code.settings.truncateMessages = false; +expect(foo).to.equal([]); +``` + +#### `comparePrototypes` + +A Boolean value that, when `false`, ignores object prototypes when doing a deep comparison. Defaults to `false`. + +```js +const Code = require('code'); +const expect = Code.expect; +const foo = Object.create(null); + +Code.settings.comparePrototypes = false; +expect(foo).to.equal({}); + +Code.settings.comparePrototypes = true; +expect(foo).to.equal({}); // fails +``` diff --git a/generated/markdown/code/changelog.md b/generated/markdown/code/changelog.md new file mode 100644 index 00000000..fa90924a --- /dev/null +++ b/generated/markdown/code/changelog.md @@ -0,0 +1,232 @@ +## Version 9 {#v9} + +### [9.0.3](https://github.com/hapijs/code/milestone/41) {#9.0.3} + +- [#179](https://github.com/hapijs/code/pull/179) chore: bump hoek + +### [9.0.2](https://github.com/hapijs/code/milestone/40) {#9.0.2} + +- [#178](https://github.com/hapijs/code/pull/178) Fix typo and add missing type + +### [9.0.1](https://github.com/hapijs/code/milestone/39) {#9.0.1} + +- [#177](https://github.com/hapijs/code/pull/177) Fix `reject()` types + +### [9.0.0](https://github.com/hapijs/code/milestone/38) {#9.0.0} + +- [#175](https://github.com/hapijs/code/pull/175) Drop node v12, support node v18 + +## Version 8 {#v8} + +### [8.0.8](https://github.com/hapijs/code/milestone/37) {#8.0.8} + +### [8.0.7](https://github.com/hapijs/code/milestone/36) {#8.0.7} + +- [#174](https://github.com/hapijs/code/pull/174) Fix equal() type + +### [8.0.6](https://github.com/hapijs/code/milestone/35) {#8.0.6} + +- [#173](https://github.com/hapijs/code/pull/173) Fix equal() types +- [#172](https://github.com/hapijs/code/issues/172) equal(value: T) type should be Loosely<T> when options ignore symbols or properties +- [#171](https://github.com/hapijs/code/pull/171) Fix typings for throw() and reject() + +### [8.0.5](https://github.com/hapijs/code/milestone/34) {#8.0.5} + +- [#168](https://github.com/hapijs/code/pull/168) Don't narrow generic on type specific assertions +- [#167](https://github.com/hapijs/code/issues/167) compilation errors for primitive type assertions + +### [8.0.4](https://github.com/hapijs/code/milestone/33) {#8.0.4} + +- [#165](https://github.com/hapijs/code/pull/165) Fix aliases for reject() +- [#163](https://github.com/hapijs/code/pull/163) Improve typings + +### [8.0.3](https://github.com/hapijs/code/milestone/32) {#8.0.3} + +- [#161](https://github.com/hapijs/code/pull/161) Fix reject(s) return type +- [#160](https://github.com/hapijs/code/issues/160) The type `.rejects` returns should return a Promise + +### [8.0.2](https://github.com/hapijs/code/milestone/31) {#8.0.2} + +- [#158](https://github.com/hapijs/code/pull/158) upgrade lab to v24 and devDependency of typescript + +### [8.0.1](https://github.com/hapijs/code/milestone/30) {#8.0.1} + +- [#155](https://github.com/hapijs/code/issues/155) Fix function string in node 13 +- [#154](https://github.com/hapijs/code/issues/154) Update hoek + +### [8.0.0](https://github.com/hapijs/code/milestone/29) {#8.0.0} + +- [#153](https://github.com/hapijs/code/issues/153) Support only node 12 + +## Version 7 {#v7} + +### [7.0.0](https://github.com/hapijs/code/milestone/27) {#7.0.0} + +- [#151](https://github.com/hapijs/code/issues/151) Add types +- [#150](https://github.com/hapijs/code/issues/150) Drop node 8 + +## Version 6 {#v6} + +### [6.0.0](https://github.com/hapijs/code/milestone/26) {#6.0.0} + +- [#142](https://github.com/hapijs/code/issues/142) Deep comparison includes symbols +- [#141](https://github.com/hapijs/code/issues/141) Support deep comparison key skipping +- [#140](https://github.com/hapijs/code/issues/140) Use deepFunction flag for deep comparison + +## Version 5 {#v5} + +### [5.3.1](https://github.com/hapijs/code/milestone/25) {#5.3.1} + +- [#136](https://github.com/hapijs/code/issues/136) Better handling of thrown stack parsing + +### [5.3.0](https://github.com/hapijs/code/milestone/24) {#5.3.0} + +- [#135](https://github.com/hapijs/code/issues/135) Change module namespace + +### [5.2.3](https://github.com/hapijs/code/milestone/23) {#5.2.3} + +- [#130](https://github.com/hapijs/code/issues/130) Remove engines + +### [5.2.2](https://github.com/hapijs/code/milestone/22) {#5.2.2} + +- [#129](https://github.com/hapijs/code/issues/129) Update hoek v6 + +### [5.2.0](https://github.com/hapijs/code/milestone/21) {#5.2.0} + +- [#124](https://github.com/hapijs/code/pull/124) Return error when asserting for thrown. Closes #123 +- [#123](https://github.com/hapijs/code/issues/123) Assertions on error properties +- [#121](https://github.com/hapijs/code/pull/121) Invalidates rejection with wrong type or message arguments +- [#119](https://github.com/hapijs/code/issues/119) reject does not fail if argument is of the wrong type + +### [5.1.2](https://github.com/hapijs/code/milestone/20) {#5.1.2} + +- [#117](https://github.com/hapijs/code/issues/117) Update dependencies + +### [5.1.1](https://github.com/hapijs/code/milestone/19) {#5.1.1} + +- [#116](https://github.com/hapijs/code/pull/116) Fix broken API.md anchor +- [#111](https://github.com/hapijs/code/pull/111) fix(length): throw decent error on length check of `null` +- [#110](https://github.com/hapijs/code/issues/110) Cannot read property 'length' of null + +### [5.1.0](https://github.com/hapijs/code/milestone/18) {#5.1.0} + +- [#106](https://github.com/hapijs/code/issues/106) Allow custom validation function for reject + +### [5.0.0](https://github.com/hapijs/code/milestone/17) {#5.0.0} + +- [#105](https://github.com/hapijs/code/pull/105) Add promises rejection support +- [#104](https://github.com/hapijs/code/issues/104) Add test for async functions +- [#103](https://github.com/hapijs/code/issues/103) Expected async function to be a function + +## Version 4 {#v4} + +### [4.1.0](https://github.com/hapijs/code/milestone/16) {#4.1.0} + +- [#102](https://github.com/hapijs/code/pull/102) please publish new version +- [#101](https://github.com/hapijs/code/pull/101) print expected value on equals assertion +- [#94](https://github.com/hapijs/code/pull/94) Reference value NaN assertion. + +### [4.0.0](https://github.com/hapijs/code/milestone/15) {#4.0.0} + +- [#91](https://github.com/hapijs/code/issues/91) New release? +- [#89](https://github.com/hapijs/code/pull/89) Docs: Modified match API documentation +- [#87](https://github.com/hapijs/code/pull/87) fix tests for Node v6.5.0 +- [#86](https://github.com/hapijs/code/issues/86) Tests failing on node 6.5.0 +- [#84](https://github.com/hapijs/code/pull/84) Enhancement: Added validation to `include` +- [#83](https://github.com/hapijs/code/issues/83) Include should validate number of arguments +- [#82](https://github.com/hapijs/code/pull/82) fix broken test from Node v6.4.0 update +- [#81](https://github.com/hapijs/code/issues/81) Fix broken test +- [#77](https://github.com/hapijs/code/pull/77) Invalidate array of objects with only a partial object value + +## Version 3 {#v3} + +### [3.0.1](https://github.com/hapijs/code/milestone/14) {#3.0.1} + +- [#75](https://github.com/hapijs/code/issues/75) Add .npmignore file + +### [3.0.0](https://github.com/hapijs/code/milestone/13) {#3.0.0} + +- [#73](https://github.com/hapijs/code/pull/73) change default comparison behavior +- [#72](https://github.com/hapijs/code/pull/72) Fix link to hoek documentation +- [#68](https://github.com/hapijs/code/issues/68) Default to deep copy + +## Version 2 {#v2} + +### [2.3.0](https://github.com/hapijs/code/milestone/12) {#2.3.0} + +- [#71](https://github.com/hapijs/code/pull/71) Fix at location information. Closes #70 +- [#70](https://github.com/hapijs/code/issues/70) expect(err).to.not.exist() reports wrong 'at' information + +### [2.2.0](https://github.com/hapijs/code/milestone/11) {#2.2.0} + +- [#64](https://github.com/hapijs/code/pull/64) Add documentation to error() (fixes #63) +- [#63](https://github.com/hapijs/code/issues/63) Document new error() method +- [#62](https://github.com/hapijs/code/pull/62) Add error type (fixes #61) +- [#61](https://github.com/hapijs/code/issues/61) Proposal: error type + +### [2.1.1](https://github.com/hapijs/code/milestone/10) {#2.1.1} + +- [#58](https://github.com/hapijs/code/pull/58) handle errors without proper stacks +- [#57](https://github.com/hapijs/code/issues/57) Problem with internals.at +- [#56](https://github.com/hapijs/code/pull/56) minor typo fix +- [#55](https://github.com/hapijs/code/pull/55) Update dep format for markdown-toc +- [#54](https://github.com/hapijs/code/pull/54) Readme tweaks + +### [2.1.0](https://github.com/hapijs/code/milestone/9) {#2.1.0} + +- [#51](https://github.com/hapijs/code/pull/51) add fail method +- [#48](https://github.com/hapijs/code/pull/48) customize error message for once flag +- [#47](https://github.com/hapijs/code/issues/47) once flag should change error message + +### [2.0.1](https://github.com/hapijs/code/milestone/8) {#2.0.1} + +- [#45](https://github.com/hapijs/code/issues/45) Update hapijs/hoek to 3.0.0 from 2.16.3 + +### [2.0.0](https://github.com/hapijs/code/milestone/7) {#2.0.0} + +- [#44](https://github.com/hapijs/code/pull/44) es6 style. Closes #43 +- [#43](https://github.com/hapijs/code/issues/43) node v4, es6 +- [#38](https://github.com/hapijs/code/pull/38) markdown fixes +- [#37](https://github.com/hapijs/code/pull/37) fixed markdown link for equal + +## Version 1 {#v1} + +### [1.5.0](https://github.com/hapijs/code/milestone/6) {#1.5.0} + +- [#36](https://github.com/hapijs/code/pull/36) Display error when should not exist. Closes #35 +- [#35](https://github.com/hapijs/code/issues/35) Throw original error when not.exist(err) is asserted +- [#32](https://github.com/hapijs/code/pull/32) Added new global setting to ignore prototypes. + +### [1.4.1](https://github.com/hapijs/code/milestone/5) {#1.4.1} + +- [#31](https://github.com/hapijs/code/pull/31) Handle multi-line errors +- [#30](https://github.com/hapijs/code/issues/30) `settings.truncateMessages = false` causes issues with deep object comparisons +- [#29](https://github.com/hapijs/code/pull/29) Fixed the description for the empty() assertion in README.md + +### [1.4.0](https://github.com/hapijs/code/milestone/4) {#1.4.0} + +- [#28](https://github.com/hapijs/code/pull/28) Release code 1.4.0 +- [#27](https://github.com/hapijs/code/pull/27) Add documentation for global settings +- [#26](https://github.com/hapijs/code/pull/26) Add configuration settings, including disabling message truncating +- [#25](https://github.com/hapijs/code/pull/25) Allow prototypes to be ignored in deep.equal() +- [#24](https://github.com/hapijs/code/issues/24) Allow prototypes to be ignored in deep comparisons +- [#23](https://github.com/hapijs/code/pull/23) readme typo and better message +- [#18](https://github.com/hapijs/code/pull/18) Remove Makefile in favor of npm scripts +- [#17](https://github.com/hapijs/code/pull/17) Verify deep.equal() functionality after changes to Hoek.deepEqual() +- [#15](https://github.com/hapijs/code/issues/15) .to.deep.equal() performs unexpectedly with empty object +- [#14](https://github.com/hapijs/code/issues/14) do not truncate values in assertions + +### [1.3.0](https://github.com/hapijs/code/milestone/3) {#1.3.0} + +- [#13](https://github.com/hapijs/code/pull/13) code 1.3.0 +- [#11](https://github.com/hapijs/code/issues/11) Object [object Object] has no method 'startWith' +- [#10](https://github.com/hapijs/code/pull/10) Reset flags after each assertion +- [#6](https://github.com/hapijs/code/pull/6) Add startsWith and endsWith for URLs. + +### [1.2.1](https://github.com/hapijs/code/milestone/2) {#1.2.1} + +- [#5](https://github.com/hapijs/code/issues/5) throw('') matches any message + +### [1.2.0](https://github.com/hapijs/code/milestone/1) {#1.2.0} + +- [#2](https://github.com/hapijs/code/issues/2) between() diff --git a/generated/markdown/content/6/api.md b/generated/markdown/content/6/api.md new file mode 100644 index 00000000..4cece2d9 --- /dev/null +++ b/generated/markdown/content/6/api.md @@ -0,0 +1,36 @@ +## Usage + +**content** allows to parse HTTP `Content-*` headers, currently based on the rules established in both [RFC 7231 Section 3.1.1.1](https://tools.ietf.org/html/rfc7231#section-3.1.1.1) and [RFC 6266 Section 4.1](http://tools.ietf.org/html/rfc6266#section-4.1). + +### `type(header)` + +Generates an object containing the associated mime-type, charset and the boundary (if specified). + +```js +Content.type('application/json; some=property; and="another"'); +// { mime: 'application/json' } + +Content.type('text/html; charset=utf-8'); +// { mime: 'text/html', charset: 'utf-8' } + +Content.type('multipart/form-data; boundary=asdf'); +// { mime: 'multipart/form-data', boundary: 'asdf' } +``` + +If the header is invalid (malformed) or missing required data, such as a `multipart/form-data` header missing its `boundary`, it returns an HTTP `Bad Request` error. + +### `disposition(header)` + +Generates an object containing the details related to the `Content-Disposition` header for the `form-data` content type with support for `utf8` encoding. + +```js +Content.disposition('form-data; name="file"; filename=file.jpg'); +// { name: 'file', filename: 'file.jpg' } + +Content.disposition( + 'form-data; name="file"; filename*=utf-8\'en\'with%20space', +); +// { name: 'file', filename: 'with space' } +``` + +If the header is invalid (malformed, invalid or missing properties) or is empty/missing, it returns an explanatory error. diff --git a/generated/markdown/content/changelog.md b/generated/markdown/content/changelog.md new file mode 100644 index 00000000..a7cbf301 --- /dev/null +++ b/generated/markdown/content/changelog.md @@ -0,0 +1,68 @@ +## Version 6 {#v6} + +### [6.0.0](https://github.com/hapijs/content/milestone/16) {#6.0.0} + +- [#35](https://github.com/hapijs/content/pull/35) Support node v18 and drop node v12 +- [#34](https://github.com/hapijs/content/pull/34) support parsing charset + +## Version 5 {#v5} + +### [5.0.2](https://github.com/hapijs/content/milestone/14) {#5.0.2} + +- [#22](https://github.com/hapijs/content/issues/22) Block **proto** name + +### [5.0.1](https://github.com/hapijs/content/milestone/13) {#5.0.1} + +- [#21](https://github.com/hapijs/content/issues/21) Explicitly handle **proto** + +### [5.0.0](https://github.com/hapijs/content/milestone/12) {#5.0.0} + +- [#20](https://github.com/hapijs/content/issues/20) Only node 12 + +## Version 4 {#v4} + +### [4.1.1](https://github.com/hapijs/content/milestone/11) {#4.1.1} + +- [#24](https://github.com/hapijs/content/issues/24) Backport #21, #22 + +### [4.1.0](https://github.com/hapijs/content/milestone/8) {#4.1.0} + +- [#13](https://github.com/hapijs/content/issues/13) Change module namespace + +### [4.0.6](https://github.com/hapijs/content/milestone/7) {#4.0.6} + +- [#9](https://github.com/hapijs/content/issues/9) Remove engines + +### [4.0.5](https://github.com/hapijs/content/milestone/6) {#4.0.5} + +- [#7](https://github.com/hapijs/content/pull/7) Throw on .type() if header is completely missing + +### [4.0.4](https://github.com/hapijs/content/milestone/5) {#4.0.4} + +- [#5](https://github.com/hapijs/content/issues/5) Skip processing parameters when content type is not multipart + +### [4.0.3](https://github.com/hapijs/content/milestone/4) {#4.0.3} + +- [#4](https://github.com/hapijs/content/issues/4) Throw directly from header processing + +### [4.0.2](https://github.com/hapijs/content/milestone/3) {#4.0.2} + +- [#3](https://github.com/hapijs/content/issues/3) Update deps + +### [4.0.1](https://github.com/hapijs/content/milestone/2) {#4.0.1} + +- [#2](https://github.com/hapijs/content/issues/2) Update deps + +### [4.0.0](https://github.com/hapijs/content/milestone/1) {#4.0.0} + +- [#1](https://github.com/hapijs/content/issues/1) Throw errors + +## Version 3 {#v3} + +### [3.1.1](https://github.com/hapijs/content/milestone/10) {#3.1.1} + +- [#23](https://github.com/hapijs/content/issues/23) Backport #21, #22 + +### [3.1.0](https://github.com/hapijs/content/milestone/9) {#3.1.0} + +- [#12](https://github.com/hapijs/content/issues/12) Commercial version of v3 branch diff --git a/generated/markdown/cookie/12/api.md b/generated/markdown/cookie/12/api.md new file mode 100644 index 00000000..99a76f61 --- /dev/null +++ b/generated/markdown/cookie/12/api.md @@ -0,0 +1,236 @@ +## Usage + +Cookie authentication provides simple cookie-based session management. The user has to be +authenticated via other means, typically a web form, and upon successful authentication +the browser receives a reply with a session cookie. The cookie uses [Iron](https://github.com/hapijs/iron) to encrypt and sign the session content. + +Subsequent requests containing the session cookie are authenticated and validated via the provided `validate` in case the cookie's encrypted content requires validation on each request. + +It is important to remember a couple of things: + +1. Each cookie operates as a bearer token and anyone in possession of the cookie content can use it to impersonate its true owner. +2. Cookies have a practical maximum length. All of the data you store in a cookie is sent to the browser. If your cookie is too long, browsers may not set it. Read more [here](http://webdesign.about.com/od/cookies/f/web-cookies-size-limit.htm) and [here](http://www.ietf.org/rfc/rfc2965.txt). If you need to store more data, store a small amount of identifying data in the cookie and use that as a key to a server-side cache system. + +The `'cookie`' scheme takes the following options: + +- `cookie` - an object with the following: + - `name` - the cookie name. Defaults to `'sid'`. + - `password` - used for Iron cookie encoding. Should be at least 32 characters long. + - `ttl` - sets the cookie expires time in milliseconds. Defaults to single browser session (ends + when browser closes). Required when `keepAlive` is `true`. + - `domain` - sets the cookie Domain value. Defaults to none. + - `path` - sets the cookie path value. Defaults to none. + - `clearInvalid` - if `true`, any authentication cookie that fails validation will be marked as + expired in the response and cleared. Defaults to `false`. + - `isSameSite` - if `false` omitted. Other options `Strict` or `Lax`. Defaults to `Strict`. + - `isSecure` - if `false`, the cookie is allowed to be transmitted over insecure connections which + exposes it to attacks. Defaults to `true`. + - `isHttpOnly` - if `false`, the cookie will not include the 'HttpOnly' flag. Defaults to `true`. +- `keepAlive` - if `true`, automatically sets the session cookie after validation to extend the + current session for a new `ttl` duration. Defaults to `false`. +- `redirectTo` - optional login URI or function `function(request)` that returns a URI to redirect unauthenticated requests to. Note that it will only + trigger when the authentication mode is `'required'`. To enable or disable redirections for a specific route, + set the route `plugins` config (`{ options: { plugins: { cookie: { redirectTo: false } } } }`). + Defaults to no redirection. +- `appendNext` - if `redirectTo` is `true`, can be a boolean, string, or object. Defaults to `false`. + - if set to `true`, a string, or an object, appends the current request path to the query component + of the `redirectTo` URI + - set to a string value or set the `name` property in an object to define the parameter name. + defaults to `'next'` + - set the `raw` property of the object to `true` to determine the current request path based on + the raw node.js request object received from the HTTP server callback instead of the processed + hapi request object +- `async validate` - an optional session validation function used to validate the content of the + session cookie on each request. Used to verify that the internal session state is still valid + (e.g. user account still exists). The function has the signature `function(request, session)` + where: + - `request` - is the Hapi request object of the request which is being authenticated. + - `session` - is the session object set via `request.cookieAuth.set()`. + + Must return an object that contains: + - `isValid` - `true` if the content of the session is valid, otherwise `false`. + - `credentials` - a credentials object passed back to the application in + `request.auth.credentials`. If value is `null` or `undefined`, defaults to `session`. If + set, will override the current cookie as if `request.cookieAuth.set()` was called. + +- `requestDecoratorName` - _USE WITH CAUTION_ an optional name to use with decorating the `request` object. Defaults to `'cookieAuth'`. Using multiple decorator names for separate authentication strategies could allow a developer to call the methods for the wrong strategy. Potentially resulting in unintended authorized access. + +When the cookie scheme is enabled on a route, the `request.cookieAuth` objects is decorated with +the following methods: + +- `set(session)` - sets the current session. Must be called after a successful login to begin the + session. `session` must be a non-null object, which is set on successful subsequent + authentications in `request.auth.credentials` where: + - `session` - the session object. +- `set(key, value)` - sets a specific object key on the current session (which must already exist) + where: + - `key` - session key string. + - `value` - value to assign key. +- `clear([key])` - clears the current session or session key where: + - `key` - optional key string to remove a specific property of the session. If none provided, + defaults to removing the entire session which is used to log the user out. +- `ttl(msecs)` - sets the ttl of the current active session where: + - `msecs` - the new ttl in milliseconds. + +Because this scheme decorates the `request` object with session-specific methods, it cannot be +registered more than once. + +```javascript +'use strict'; + +const Hapi = require('@hapi/hapi'); + +const internals = {}; + +// Simulate database for demo + +internals.users = [ + { + id: 1, + name: 'john', + password: 'password', + }, +]; + +internals.renderHtml = { + login: (message) => { + return ` + Login page + ${message ? '

    ' + message + '


    ' : ''} +
    + Username:
    + Password:
    +
    + + `; + }, + home: (name) => { + return ` + Login page +

    Welcome ${name}! You are logged in!

    +
    + +
    + + `; + }, +}; + +internals.server = async function () { + const server = Hapi.server({ port: 8000 }); + + await server.register(require('@hapi/cookie')); + + server.auth.strategy('session', 'cookie', { + cookie: { + name: 'sid-example', + + // Don't forget to change it to your own secret password! + password: 'password-should-be-32-characters', + + // For working via HTTP in localhost + isSecure: false, + }, + + redirectTo: '/login', + + validate: async (request, session) => { + const account = internals.users.find((user) => user.id === session.id); + + if (!account) { + // Must return { isValid: false } for invalid cookies + return { isValid: false }; + } + + return { isValid: true, credentials: account }; + }, + }); + + server.auth.default('session'); + + server.route([ + { + method: 'GET', + path: '/', + options: { + handler: (request, h) => { + return internals.renderHtml.home(request.auth.credentials.name); + }, + }, + }, + { + method: 'GET', + path: '/login', + options: { + auth: { + mode: 'try', + }, + plugins: { + cookie: { + redirectTo: false, + }, + }, + handler: async (request, h) => { + if (request.auth.isAuthenticated) { + return h.redirect('/'); + } + + return internals.renderHtml.login(); + }, + }, + }, + { + method: 'POST', + path: '/login', + options: { + auth: { + mode: 'try', + }, + handler: async (request, h) => { + const { username, password } = request.payload; + if (!username || !password) { + return internals.renderHtml.login('Missing username or password'); + } + + // Try to find user with given credentials + + const account = internals.users.find( + (user) => user.name === username && user.password === password, + ); + + if (!account) { + return internals.renderHtml.login('Invalid username or password'); + } + + request.cookieAuth.set({ id: account.id }); + return h.redirect('/'); + }, + }, + }, + { + method: 'GET', + path: '/logout', + options: { + handler: (request, h) => { + request.cookieAuth.clear(); + return h.redirect('/'); + }, + }, + }, + ]); + + await server.start(); + console.log(`Server started at: ${server.info.uri}`); +}; + +internals.start = async function () { + try { + await internals.server(); + } catch (err) { + console.error(err.stack); + process.exit(1); + } +}; + +internals.start(); +``` diff --git a/generated/markdown/cookie/changelog.md b/generated/markdown/cookie/changelog.md new file mode 100644 index 00000000..ef38a310 --- /dev/null +++ b/generated/markdown/cookie/changelog.md @@ -0,0 +1,211 @@ +## Version 12 {#v12} + +### [12.0.1](https://github.com/hapijs/cookie/milestone/37) {#12.0.1} + +- [#248](https://github.com/hapijs/cookie/pull/248) chore: bump hoek + +### [12.0.0](https://github.com/hapijs/cookie/milestone/36) {#12.0.0} + +- [#246](https://github.com/hapijs/cookie/pull/246) Support for hapi v21, node v18, ESM tests +- [#244](https://github.com/hapijs/cookie/pull/244) Drop support for node v12 and hapi v18 +- [#236](https://github.com/hapijs/cookie/pull/236) Rename plugin options to be consistent across the hapi ecosystem +- [#235](https://github.com/hapijs/cookie/pull/235) Remove old repository name + +## Version 11 {#v11} + +### [11.0.2](https://github.com/hapijs/cookie/milestone/34) {#11.0.2} + +- [#232](https://github.com/hapijs/cookie/pull/232) update to hapi v20 +- [#231](https://github.com/hapijs/cookie/pull/231) migrate to new travis format +- [#229](https://github.com/hapijs/cookie/pull/229) change joi to validate and update lab + +### [11.0.1](https://github.com/hapijs/cookie/milestone/33) {#11.0.1} + +- [#228](https://github.com/hapijs/cookie/issues/228) Non system error in validateFunc will be swallowed + +### [11.0.0](https://github.com/hapijs/cookie/milestone/32) {#11.0.0} + +- [#227](https://github.com/hapijs/cookie/issues/227) Only node 12 + +## Version 10 {#v10} + +### [10.1.2](https://github.com/hapijs/cookie/milestone/31) {#10.1.2} + +- [#222](https://github.com/hapijs/cookie/issues/222) Update joi + +### [10.1.1](https://github.com/hapijs/cookie/milestone/30) {#10.1.1} + +- [#221](https://github.com/hapijs/cookie/issues/221) Update deps + +### [10.1.0](https://github.com/hapijs/cookie/milestone/29) {#10.1.0} + +- [#213](https://github.com/hapijs/cookie/issues/213) Change module namespace + +### [10.0.0](https://github.com/hapijs/cookie/milestone/28) {#10.0.0} + +- [#210](https://github.com/hapijs/cookie/issues/210) Move all cookie settings to `cookie` +- [#209](https://github.com/hapijs/cookie/issues/209) 10.0.0 Release notes +- [#208](https://github.com/hapijs/cookie/issues/208) Remove ignoreIfDecorated +- [#207](https://github.com/hapijs/cookie/issues/207) No override of default cookie settings +- [#205](https://github.com/hapijs/cookie/pull/205) Upgrade to hapi 18 +- [#204](https://github.com/hapijs/cookie/issues/204) Update for hapi 18 +- [#193](https://github.com/hapijs/cookie/issues/193) Support password rotation + +## Version 9 {#v9} + +### [9.1.0](https://github.com/hapijs/cookie/milestone/27) {#9.1.0} + +- [#196](https://github.com/hapijs/cookie/pull/196) referenced the raw request when setting next + +### [9.0.0](https://github.com/hapijs/cookie/milestone/24) {#9.0.0} + +- [#186](https://github.com/hapijs/cookie/pull/186) Respect auth mode for redirects + +## Version 8 {#v8} + +### [8.1.0](https://github.com/hapijs/cookie/milestone/23) {#8.1.0} + +- [#176](https://github.com/hapijs/cookie/pull/176) Use options key for route configuration +- [#164](https://github.com/hapijs/cookie/pull/164) Issue 163 + +### [8.0.1](https://github.com/hapijs/cookie/milestone/25) {#8.0.1} + +- [#183](https://github.com/hapijs/cookie/pull/183) Fix redirectTo function w/ blank to behave like blank redirectTo (fix) +- [#170](https://github.com/hapijs/cookie/pull/170) Drop session from cache in examples + +### [8.0.0](https://github.com/hapijs/cookie/milestone/22) {#8.0.0} + +- [#179](https://github.com/hapijs/cookie/issues/179) Update lead maintainer +- [#174](https://github.com/hapijs/cookie/pull/174) Upgraded module to hapi v17 + +## Version 7 {#v7} + +### [7.1.0](https://github.com/hapijs/cookie/milestone/26) {#7.1.0} + +- [#151](https://github.com/hapijs/cookie/pull/151) referenced the raw request when setting next + +### [7.0.0](https://github.com/hapijs/cookie/milestone/21) {#7.0.0} + +- [#152](https://github.com/hapijs/cookie/pull/152) Do not redecorate the request object if already decorated +- [#148](https://github.com/hapijs/cookie/pull/148) Allow redirectTo to be a function +- [#142](https://github.com/hapijs/cookie/pull/142) Add isSameSite to schema +- [#138](https://github.com/hapijs/cookie/pull/138) Options aren't required +- [#134](https://github.com/hapijs/cookie/pull/134) add note to readme about the 'ttl' option +- [#130](https://github.com/hapijs/cookie/pull/130) Test on node v6, update dependencies +- [#127](https://github.com/hapijs/cookie/pull/127) fix typo in readme +- [#124](https://github.com/hapijs/cookie/pull/124) Allow null to be passed for the ttl +- [#115](https://github.com/hapijs/cookie/pull/115) update readme with information/warning about cookie length + +## Version 6 {#v6} + +### [6.1.1](https://github.com/hapijs/cookie/milestone/20) {#6.1.1} + +- [#118](https://github.com/hapijs/cookie/pull/118) decorator fix + +### [6.1.0](https://github.com/hapijs/cookie/milestone/19) {#6.1.0} + +- [#114](https://github.com/hapijs/cookie/pull/114) support many strategies + +### [6.0.0](https://github.com/hapijs/cookie/milestone/18) {#6.0.0} + +- [#107](https://github.com/hapijs/cookie/pull/107) Use server.decorate + +## Version 5 {#v5} + +### [5.0](https://github.com/hapijs/cookie/milestone/17) {#5.0} + +- [#103](https://github.com/hapijs/cookie/pull/103) move away from request.auth.session +- [#101](https://github.com/hapijs/cookie/issues/101) Switch to use a request decoration instead of request.auth.session + +## Version 4 {#v4} + +### [4.0.0](https://github.com/hapijs/cookie/milestone/16) {#4.0.0} + +- [#102](https://github.com/hapijs/cookie/pull/102) node 4 update +- [#93](https://github.com/hapijs/cookie/issues/93) Node >= 4 / es6 updates + +## Version 3 {#v3} + +### [3.1.0](https://github.com/hapijs/cookie/milestone/15) {#3.1.0} + +- [#83](https://github.com/hapijs/cookie/pull/83) allow buffer as password +- [#80](https://github.com/hapijs/cookie/issues/80) Buffer type should be allowed for "password" option + +### [3.0.0](https://github.com/hapijs/cookie/milestone/14) {#3.0.0} + +- [#75](https://github.com/hapijs/cookie/pull/75) validateFunc according to signature function +- [#74](https://github.com/hapijs/cookie/pull/74) Updated docs +- [#72](https://github.com/hapijs/cookie/pull/72) Pass request object to validation function + +## Version 2 {#v2} + +### [2.2.0](https://github.com/hapijs/cookie/milestone/13) {#2.2.0} + +- [#69](https://github.com/hapijs/cookie/pull/69) 2.2.0 update +- [#68](https://github.com/hapijs/cookie/pull/68) Fix support for custom appendNext param +- [#67](https://github.com/hapijs/cookie/issues/67) `appendNext` no longer accepts a string +- [#65](https://github.com/hapijs/cookie/pull/65) allow null setting for domain +- [#64](https://github.com/hapijs/cookie/issues/64) domain is now required as a string, and null does not pass validation + +### [2.1.0](https://github.com/hapijs/cookie/milestone/12) {#2.1.0} + +- [#63](https://github.com/hapijs/cookie/pull/63) Version 2.1.0 +- [#62](https://github.com/hapijs/cookie/pull/62) Allow environment variables to configure cookie scheme + +### [2.0.0](https://github.com/hapijs/cookie/milestone/10) {#2.0.0} + +- [#45](https://github.com/hapijs/cookie/pull/45) Version 2.0.0 +- [#43](https://github.com/hapijs/cookie/pull/43) Use request.route.settings.plugin +- [#40](https://github.com/hapijs/cookie/issues/40) Invalid cookie should still return 401 +- [#39](https://github.com/hapijs/cookie/issues/39) hapi 8.0 API + +## Version 1 {#v1} + +### [1.4.2](https://github.com/hapijs/cookie/milestone/11) {#1.4.2} + +- [#42](https://github.com/hapijs/cookie/issues/42) Invalid cookie blocks scheme from redirecting + +### [1.4.1](https://github.com/hapijs/cookie/milestone/9) {#1.4.1} + +- [#37](https://github.com/hapijs/cookie/pull/37) Fix clearInvalid (for issue #34) +- [#34](https://github.com/hapijs/cookie/issues/34) Bad cookie value even with clearInvalid true + +### [1.4.0](https://github.com/hapijs/cookie/milestone/8) {#1.4.0} + +- [#35](https://github.com/hapijs/cookie/issues/35) Session keepAlive and ttl override +- [#30](https://github.com/hapijs/cookie/pull/30) add set/clear key for cookie +- [#29](https://github.com/hapijs/cookie/pull/29) Fix for handling multiple strategies +- [#26](https://github.com/hapijs/cookie/issues/26) Update key in auth.credentials +- [#22](https://github.com/hapijs/cookie/pull/22) Exposed path option for session cookie +- [#21](https://github.com/hapijs/cookie/issues/21) Expose 'path' in cookieOptions + +### [1.3.2](https://github.com/hapijs/cookie/milestone/7) {#1.3.2} + +- [#20](https://github.com/hapijs/cookie/pull/20) Update LICENSE +- [#19](https://github.com/hapijs/cookie/issues/19) Update License + +### [1.3.1](https://github.com/hapijs/cookie/milestone/6) {#1.3.1} + +- [#16](https://github.com/hapijs/cookie/issues/16) Fix hapi dev dep + +### [1.3.0](https://github.com/hapijs/cookie/milestone/5) {#1.3.0} + +- [#15](https://github.com/hapijs/cookie/issues/15) Skip redirection on try + +### [1.2.0](https://github.com/hapijs/cookie/milestone/4) {#1.2.0} + +- [#11](https://github.com/hapijs/cookie/issues/11) No way to use with 'try' mode if 'redirectTo' is set +- [#10](https://github.com/hapijs/cookie/issues/10) validateFunc credentials override session + +### [1.1.0](https://github.com/hapijs/cookie/milestone/3) {#1.1.0} + +- [#9](https://github.com/hapijs/cookie/pull/9) hapi 6.0 + +### [1.0.3](https://github.com/hapijs/cookie/milestone/2) {#1.0.3} + +- [#6](https://github.com/hapijs/cookie/issues/6) Bring coverage back to 100% + +### [1.0.2](https://github.com/hapijs/cookie/milestone/1) {#1.0.2} + +- [#5](https://github.com/hapijs/cookie/issues/5) Bring coverage back to 100% after lab fix +- [#4](https://github.com/hapijs/cookie/issues/4) fix peerDependencies for hapi diff --git a/generated/markdown/crumb/9/api.md b/generated/markdown/crumb/9/api.md new file mode 100644 index 00000000..3ecb71d2 --- /dev/null +++ b/generated/markdown/crumb/9/api.md @@ -0,0 +1,71 @@ +### About + +Crumb is used to diminish CSRF attacks using a random unique token that is validated on the server side. + +Crumb may be used whenever you want to prevent malicious code to execute system commands, that are performed by HTTP requests. For example, if users are able to publish code on your website, malicious code added by a user could force every other user who opens the page, to load and execute code from a third party website e.g. via an HTML image tag. With Crumb implemented into your hapi.js application, you are able to verify requests with unique tokens and prevent the execution of malicious requests. + +### CORS + +Crumb has been refactored to securely work with CORS, as [OWASP](https://www.owasp.org/index.php/HTML5_Security_Cheat_Sheet#Cross_Origin_Resource_Sharing) recommends using CSRF protection with CORS. + +**It is highly discouraged to have a production servers `cors.origin` setting set to "[\*]" or "true" with Crumb as it will leak the crumb token to potentially malicious sites** + +## Usage + +```js +const Hapi = require('@hapi/hapi'); +const Crumb = require('@hapi/crumb'); + +const server = new Hapi.Server({ port: 8000 }); + +(async () => { + await server.register({ + plugin: Crumb, + + // plugin options + options: {}, + }); + + server.route({ + path: '/login', + method: 'GET', + options: { + plugins: { + // route specific options + crumb: {}, + }, + handler(request, h) { + // this requires to have a view engine configured + return h.view('some-view'); + }, + }, + }); +})(); +``` + +For a complete example see [the examples folder](https://github.com/hapijs/crumb/tree/master/example). + +## Options + +The following options are available when registering the plugin. + +### Registration options + +- `key` - the name of the cookie to store the csrf crumb into. Defaults to `crumb`. +- `size` - the length of the crumb to generate. Defaults to `43`, which is 256 bits, see [cryptile](https://hapi.dev/module/cryptiles) for more information. +- `autoGenerate` - whether to automatically generate a new crumb for requests. Defaults to `true`. +- `addToViewContext` - whether to automatically add the crumb to view contexts as the given key. Defaults to `true`. +- `cookieOptions` - storage options for the cookie containing the crumb, see the [server.state()]() documentation of hapi for more information. Default to `cookieOptions.path=/` . **Note that the cookie is not set as secure by default. It should be set as 'secure:true' for production use.** +- `headerName` - specify the name of the custom CSRF header. Defaults to `X-CSRF-Token`. +- `restful` - RESTful mode that validates crumb tokens from _"X-CSRF-Token"_ request header for **POST**, **PUT**, **PATCH** and **DELETE** server routes. Disables payload/query crumb validation. Defaults to `false`. +- `skip` - a function with the signature of `function (request, h) {}`, which when provided, is called for every request. If the provided function returns true, validation and generation of crumb is skipped. Defaults to `false`. +- `enforce` - defaults to true, using enforce with false will set the CSRF header cookie but won't execute the validation +- `logUnauthorized` - whether to add to the request log with tag 'crumb' and data 'validation failed' (defaults to false) + +### Routes configuration + +Additionally, some configuration can be passed on a per-route basis. Disable Crumb for a particular route by passing `false` instead of a configuration object. + +- `key` - the key used in the view contexts and payloads for the crumb. Defaults to `plugin.key`. +- `source` - can be either `payload` or `query` specifying how the crumb will be sent in requests. Defaults to `payload`. +- `restful` - an override for the server's 'restful' setting. Defaults to `plugin.restful`. diff --git a/generated/markdown/crumb/changelog.md b/generated/markdown/crumb/changelog.md new file mode 100644 index 00000000..7f73b8a0 --- /dev/null +++ b/generated/markdown/crumb/changelog.md @@ -0,0 +1,127 @@ +## Version 9 {#v9} + +### [9.0.1](https://github.com/hapijs/crumb/milestone/22) {#9.0.1} + +- [#163](https://github.com/hapijs/crumb/pull/163) chore: bump hoek + +### [9.0.0](https://github.com/hapijs/crumb/milestone/21) {#9.0.0} + +- [#162](https://github.com/hapijs/crumb/pull/162) Support for hapi v21, node v18, ESM tests + +## Version 8 {#v8} + +### [8.0.1](https://github.com/hapijs/crumb/milestone/19) {#8.0.1} + +- [#153](https://github.com/hapijs/crumb/pull/153) upgrade lab to v24 +- [#150](https://github.com/hapijs/crumb/pull/150) update dependencies +- [#149](https://github.com/hapijs/crumb/pull/149) migrate to new travis format +- [#147](https://github.com/hapijs/crumb/pull/147) upgrade to use the latest lab and joi to validate + +### [8.0.0](https://github.com/hapijs/crumb/milestone/18) {#8.0.0} + +- [#144](https://github.com/hapijs/crumb/issues/144) Drop hapi v17 and v18 +- [#143](https://github.com/hapijs/crumb/issues/143) Change plugin name to @hapi/crubm +- [#142](https://github.com/hapijs/crumb/issues/142) Only node 12 + +## Version 7 {#v7} + +### [7.3.2](https://github.com/hapijs/crumb/milestone/17) {#7.3.2} + +- [#135](https://github.com/hapijs/crumb/issues/135) Update joi +- [#131](https://github.com/hapijs/crumb/pull/131) validate crumb when autoGenerate is false and crumb not defined on route + +### [7.3.1](https://github.com/hapijs/crumb/milestone/16) {#7.3.1} + +- [#134](https://github.com/hapijs/crumb/issues/134) Update deps + +### [7.3.0](https://github.com/hapijs/crumb/milestone/15) {#7.3.0} + +- [#129](https://github.com/hapijs/crumb/issues/129) Change module namespace + +### [7.1.1](https://github.com/hapijs/crumb/milestone/14) {#7.1.1} + +### [7.1.0](https://github.com/hapijs/crumb/milestone/13) {#7.1.0} + +- [#112](https://github.com/hapijs/crumb/pull/112) adds logUnauthorized option - addresses #56 +- [#111](https://github.com/hapijs/crumb/pull/111) Remove new Buffer usage +- [#103](https://github.com/hapijs/crumb/pull/103) Add an option to specify the CSRF header name +- [#56](https://github.com/hapijs/crumb/issues/56) Provide more relevant feedback + +### [7.0.0](https://github.com/hapijs/crumb/milestone/12) {#7.0.0} + +- [#107](https://github.com/hapijs/crumb/pull/107) Update contact details/maintainer +- [#106](https://github.com/hapijs/crumb/pull/106) Upgrade Crumb to Hapi 17 +- [#105](https://github.com/hapijs/crumb/issues/105) hapi v17 support +- [#101](https://github.com/hapijs/crumb/issues/101) Enable Crumb for specific routes only +- [#99](https://github.com/hapijs/crumb/pull/99) Add sentence to README about how to disable the plugin for a particular route. +- [#98](https://github.com/hapijs/crumb/pull/98) Make both examples runnable with a package.json and proper dependencies +- [#97](https://github.com/hapijs/crumb/issues/97) Example won't launch: `Server.views is not a function` +- [#93](https://github.com/hapijs/crumb/pull/93) Documentation Improvement + +## Version 6 {#v6} + +### [6.0.3](https://github.com/hapijs/crumb/milestone/11) {#6.0.3} + +- [#91](https://github.com/hapijs/crumb/pull/91) Cors origin +- [#90](https://github.com/hapijs/crumb/issues/90) Generate function never called when Vision route has CORS enabled +- [#89](https://github.com/hapijs/crumb/issues/89) Generate is running a second time and 500-ing hapi +- [#87](https://github.com/hapijs/crumb/pull/87) remove arrow function to fix context +- [#54](https://github.com/hapijs/crumb/issues/54) Getting 403 forbidden because token has changed + +### [6.0.2](https://github.com/hapijs/crumb/milestone/10) {#6.0.2} + +- [#84](https://github.com/hapijs/crumb/pull/84) #80: fixes crumb route settings bug +- [#82](https://github.com/hapijs/crumb/pull/82) Test on node v6, update dependencies +- [#80](https://github.com/hapijs/crumb/issues/80) 6.0.1 update breaks route-restful option + +### [6.0.1](https://github.com/hapijs/crumb/milestone/9) {#6.0.1} + +- [#79](https://github.com/hapijs/crumb/pull/79) Fixes #74 -- restful configured through routes is not superceded by global config +- [#78](https://github.com/hapijs/crumb/pull/78) Purpose readme contribution +- [#69](https://github.com/hapijs/crumb/pull/69) Update restful example to respond with JSON. Closes #64 + +### [6.0.0](https://github.com/hapijs/crumb/milestone/8) {#6.0.0} + +- [#70](https://github.com/hapijs/crumb/pull/70) Hapi12 +- [#68](https://github.com/hapijs/crumb/issues/68) Heroku disallows host binding but Crumb requires it +- [#67](https://github.com/hapijs/crumb/issues/67) ES6 style changes and node v4 +- [#61](https://github.com/hapijs/crumb/issues/61) Ignore CORS + +## Version 5 {#v5} + +### [5.0.0](https://github.com/hapijs/crumb/milestone/7) {#5.0.0} + +- [#63](https://github.com/hapijs/crumb/pull/63) Update 9 +- [#58](https://github.com/hapijs/crumb/issues/58) update to hapi 9/10 +- [#51](https://github.com/hapijs/crumb/issues/51) crumb request.plugins.crumb: undefined + +## Version 4 {#v4} + +### [4.04](https://github.com/hapijs/crumb/milestone/6) {#4.04} + +- [#53](https://github.com/hapijs/crumb/pull/53) correct linting issues +- [#52](https://github.com/hapijs/crumb/pull/52) Updated joi to 6.x.x + +### [4.0.3](https://github.com/hapijs/crumb/milestone/5) {#4.0.3} + +- [#49](https://github.com/hapijs/crumb/pull/49) Return error during plugin registration for invalid options. + +### [4.0.2](https://github.com/hapijs/crumb/milestone/4) {#4.0.2} + +- [#46](https://github.com/hapijs/crumb/pull/46) fix internals.originParser + tests to add protocol in all origin/allowOrigins values + +### [4.0.1](https://github.com/hapijs/crumb/milestone/3) {#4.0.1} + +- [#34](https://github.com/hapijs/crumb/issues/34) Host header cannot include URI scheme + +### [4.0.0](https://github.com/hapijs/crumb/milestone/2) {#4.0.0} + +- [#37](https://github.com/hapijs/crumb/pull/37) hapi8. Closes #35. internals bug. Closes #33 +- [#35](https://github.com/hapijs/crumb/issues/35) hapi 8.0 API +- [#33](https://github.com/hapijs/crumb/issues/33) Don't use internals for plugin state + +## Version 1 {#v1} + +### [1.1.2](https://github.com/hapijs/crumb/milestone/1) {#1.1.2} + +- [#11](https://github.com/hapijs/crumb/issues/11) Support hapi 3.0 diff --git a/generated/markdown/cryptiles/6/api.md b/generated/markdown/cryptiles/6/api.md new file mode 100644 index 00000000..a2884d41 --- /dev/null +++ b/generated/markdown/cryptiles/6/api.md @@ -0,0 +1,21 @@ +## Methods + +### `randomString(size: number): string` + +Returns a cryptographically strong pseudo-random data string. Takes a size argument for the length of the string. + +### `randomAlphanumString(size: number): string` + +Returns a cryptographically strong pseudo-random alphanumeric data string. Takes a size argument for the length of the string. + +### `randomDigits(size: number): string` + +Returns a cryptographically strong pseudo-random data string consisting of only numerical digits (0-9). Takes a size argument for the length of the string. + +### `randomBits(bits: number): Buffer` + +Returns a Buffer of cryptographically strong pseudo-random bits. Takes a bits argument for the number of bits to generate. + +### `fixedTimeComparison(a: string, b: string): boolean` + +Performs a constant-time comparison of two strings to prevent timing attacks. Returns `true` if the strings are equal, `false` otherwise. Safe to use with strings of different lengths. diff --git a/generated/markdown/cryptiles/changelog.md b/generated/markdown/cryptiles/changelog.md new file mode 100644 index 00000000..6adf88b1 --- /dev/null +++ b/generated/markdown/cryptiles/changelog.md @@ -0,0 +1,123 @@ +## Version 6 {#v6} + +### [6.0.2](https://github.com/hapijs/cryptiles/milestone/31) {#6.0.2} + +- [#63](https://github.com/hapijs/cryptiles/pull/63) fix: 🐛 Add timing-safe comparison tests and update API docs + +### [6.0.1](https://github.com/hapijs/cryptiles/milestone/30) {#6.0.1} + +- [#60](https://github.com/hapijs/cryptiles/pull/60) chore: bump packages + +### [6.0.0](https://github.com/hapijs/cryptiles/milestone/29) {#6.0.0} + +- [#58](https://github.com/hapijs/cryptiles/pull/58) Support node v18 and drop node v12 + +## Version 5 {#v5} + +### [5.1.0](https://github.com/hapijs/cryptiles/milestone/27) {#5.1.0} + +- [#51](https://github.com/hapijs/cryptiles/issues/51) Add randomAlphanumString() + +### [5.0.0](https://github.com/hapijs/cryptiles/milestone/26) {#5.0.0} + +- [#50](https://github.com/hapijs/cryptiles/issues/50) Only node 12 + +## Version 4 {#v4} + +### [4.2.1](https://github.com/hapijs/cryptiles/milestone/24) {#4.2.1} + +- [#45](https://github.com/hapijs/cryptiles/pull/45) Added TS declarations + +### [4.2.0](https://github.com/hapijs/cryptiles/milestone/20) {#4.2.0} + +- [#40](https://github.com/hapijs/cryptiles/issues/40) Change module namespace + +### [4.1.3](https://github.com/hapijs/cryptiles/milestone/18) {#4.1.3} + +- [#36](https://github.com/hapijs/cryptiles/issues/36) Remove engines + +### [4.1.2](https://github.com/hapijs/cryptiles/milestone/17) {#4.1.2} + +- [#34](https://github.com/hapijs/cryptiles/issues/34) randomDigits() generates biased random digits + +### [4.1.1](https://github.com/hapijs/cryptiles/milestone/16) {#4.1.1} + +- [#33](https://github.com/hapijs/cryptiles/pull/33) fix(fixedTimeComparison): use Buffer.from + +### [4.1.0](https://github.com/hapijs/cryptiles/milestone/15) {#4.1.0} + +- [#32](https://github.com/hapijs/cryptiles/issues/32) Add fixedTimeComparison() + +### [4.0.2](https://github.com/hapijs/cryptiles/milestone/14) {#4.0.2} + +- [#31](https://github.com/hapijs/cryptiles/issues/31) Update deps + +### [4.0.1](https://github.com/hapijs/cryptiles/milestone/13) {#4.0.1} + +- [#28](https://github.com/hapijs/cryptiles/issues/28) Update deps + +### [4.0.0](https://github.com/hapijs/cryptiles/milestone/12) {#4.0.0} + +- [#27](https://github.com/hapijs/cryptiles/issues/27) Throw errors +- [#24](https://github.com/hapijs/cryptiles/issues/24) Use crypto.timingSafeEqual for fixedTimeComparison + +## Version 3 {#v3} + +### [3.2.0](https://github.com/hapijs/cryptiles/milestone/22) {#3.2.0} + +- [#39](https://github.com/hapijs/cryptiles/issues/39) Commercial version of v3 branch + +### [3.1.4](https://github.com/hapijs/cryptiles/milestone/21) {#3.1.4} + +- [#37](https://github.com/hapijs/cryptiles/issues/37) Remove engines + +### [3.1.3](https://github.com/hapijs/cryptiles/milestone/19) {#3.1.3} + +- [#35](https://github.com/hapijs/cryptiles/issues/35) randomDigits() generates biased random digits + +### [3.1.2](https://github.com/hapijs/cryptiles/milestone/11) {#3.1.2} + +- [#26](https://github.com/hapijs/cryptiles/issues/26) Update deps. + +### [3.1.1](https://github.com/hapijs/cryptiles/milestone/10) {#3.1.1} + +- [#23](https://github.com/hapijs/cryptiles/issues/23) Support node 4 + +### [3.1.0](https://github.com/hapijs/cryptiles/milestone/9) {#3.1.0} + +- [#22](https://github.com/hapijs/cryptiles/issues/22) Generate random digits + +### [3.0.2](https://github.com/hapijs/cryptiles/milestone/8) {#3.0.2} + +- [#21](https://github.com/hapijs/cryptiles/issues/21) Update deps + +### [3.0.1](https://github.com/hapijs/cryptiles/milestone/7) {#3.0.1} + +- [#19](https://github.com/hapijs/cryptiles/pull/19) Test on node v6, update dependencies + +### [3.0.0](https://github.com/hapijs/cryptiles/milestone/6) {#3.0.0} + +- [#18](https://github.com/hapijs/cryptiles/pull/18) es6. Closes #17 +- [#17](https://github.com/hapijs/cryptiles/issues/17) ES6 style changes and node v4 + +## Version 2 {#v2} + +### [2.0.5](https://github.com/hapijs/cryptiles/milestone/5) {#2.0.5} + +- [#16](https://github.com/hapijs/cryptiles/issues/16) Update hapi style + +### [2.0.4](https://github.com/hapijs/cryptiles/milestone/4) {#2.0.4} + +- [#10](https://github.com/hapijs/cryptiles/issues/10) Move to hapijs + +### [2.0.3](https://github.com/hapijs/cryptiles/milestone/3) {#2.0.3} + +- [#9](https://github.com/hapijs/cryptiles/issues/9) lab 4.0 + +### [2.0.2](https://github.com/hapijs/cryptiles/milestone/2) {#2.0.2} + +- [#8](https://github.com/hapijs/cryptiles/issues/8) Update contact + +### [2.0.1](https://github.com/hapijs/cryptiles/milestone/1) {#2.0.1} + +- [#5](https://github.com/hapijs/cryptiles/issues/5) Bring coverage back to 100% after lab partial condition result coverage diff --git a/generated/markdown/eslint-plugin/6/api.md b/generated/markdown/eslint-plugin/6/api.md new file mode 100644 index 00000000..738df485 --- /dev/null +++ b/generated/markdown/eslint-plugin/6/api.md @@ -0,0 +1,196 @@ +## Configurations + +This ESLint plugin exposes two configurations: + +- `@hapi/recommended` +- `@hapi/module` + +### `@hapi/recommended` + +An ESLint configuration containing hapi style guide rules and config. To use in your project, add +[`@hapi/eslint-plugin`](https://github.com/hapijs/eslint-plugin) to your `package.json`, then in your ESLint configuration add: + +```json +{ + "extends": "plugin:@hapi/recommended" +} +``` + +### `@hapi/module` + +The ESLint configuration used by [`@hapi/lab`](https://hapi.dev/module/lab/) when you use the linting feature through either the [`-L`](https://hapi.dev/module/lab/api/#command-line) command argument or the `lint: true` configuration. + +To use it in your project, there are multiple dependencies you need to add to your `package.json`: + +- [`@hapi/eslint-plugin`](https://github.com/hapijs/eslint-plugin) +- [`@babel/core`](https://www.npmjs.com/package/@babel/core) +- [`@babel/eslint-parser`](https://www.npmjs.com/package/@babel/eslint-parser) + +Then in your ESLint configuration add: + +```json +{ + "extends": "plugin:@hapi/module" +} +``` + +## Rules + +This plugin includes the following ESLint rules: + +### capitalize-modules + +Enforces capitalization of imported module variables. + +#### `global-scope-only` + +If the string `'global-scope-only'` is passed as the first option to this rule, +then it will only be enforced on assignments in the module's top level scope. + +### for-loop + +Enforces `for` loop iterator variable rules and restricts loop nesting depth. + +This rule enforces the following: + +- Restrict iterator variable names. `for` loop iterator variables should be named `i`. Nested loops should use the variables `j`, `k`, and so on. +- Restrict loop nesting. You can restrict the maximum nesting of `for` loops. By default, this limit is three. +- Prevent postfix increment and decrement operators. The hapi style guide does not allow postfix increment and decrement operators in `for` loop updates. The prefix version of these operators should be used instead. +- Single variable declaration in initialization section. A single `var i = 0;` is allowed in the initialization section. This only applies to variable declarations, not assignments to existing variables. This means that `for (i = 0, j = 0)` is allowed if `i` and `j` are existing variables. Variable declarations involving destructuring are not allowed. + +#### Rule options + +This rule can be configured by providing a single options object. The object supports the following keys. + +##### `maxDepth` + +A number representing the maximum allowed nesting of `for` loops. Defaults to three. + +##### `startIterator` + +The first variable iterator name to use. This defaults to `'i'`. + +### no-var + +Enforces the usage of var declarations only in try-catch scope. + +### scope-start + +Enforces a new line at the beginning of function scope. + +#### `allow-one-liners` + +If the string `'allow-one-liners'` is passed as the first option to this rule, +then functions whose bodies contain zero or one statements are allowed to be +written on a single line. This defaults to `true` for arrow functions, and +`false` otherwise. + +#### `max-in-one-liner` + +The second option to this rule dictates the maximum number of statements allowed +in the bodies of one line function. This must be used in conjunction with +`allow-one-liners`. Defaults to one. + +### no-arrowception + +Prevents arrow functions that implicitly create additional arrow functions. + +This rule prevents the pattern () => () => () => ...;. + +Functions can still be returned by arrow functions whose bodies use curly braces and an explicit return. + +This rule does not accept any configuration options. + +## Config + +| Rule | Option | +| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **'@hapi/capitalize-modules'** | ['warn', 'global-scope-only'] | +| **'@hapi/for-loop'** | ['warn', { maxDepth: 3, startIterator: 'i' }] | +| **'@hapi/no-var'** | 'error' | +| **'@hapi/scope-start'** | 'warn' | +| **'@hapi/no-arrowception'** | 'error' | +| **'camelcase'** | 'off' | +| **'consistent-return'** | 'off' | +| **'vars-on-top'** | 'off' | +| **'new-cap'** | 'off | +| **'no-console'** | 'off' | +| **'no-constant-condition'** | 'error' | +| **'no-empty'** | 'off' | +| **'no-native-reassign'** | 'off' | +| **'no-underscore-dangle'** | 'off' | +| **'no-undef'** | ['error', { typeof: false }] | +| **'no-process-exit'** | 'off' | +| **'no-unused-expressions'** | 'off' | +| **'no-regex-spaces'** | 'off' | +| **'no-catch-shadow'** | 'off' | +| **'no-lonely-if'** | 'off' | +| **'brace-style'** | ['warn', 'stroustrup'] | +| **'no-shadow'** | ['warn', { allow: ['err', 'done'] }] | +| **'no-unused-vars'** | ['warn', { vars: 'all', varsIgnorePattern: '^internals$', args: 'none' }] | +| **'one-var'** | ['error', 'never'] | +| **'handle-callback-err'** | ['error', '^(e\|err\|error)$'] | +| **'array-bracket-spacing'** | 'warn' | +| **'dot-notation'** | 'warn' | +| **'eol-last'** | 'warn' | +| **'no-trailing-spaces'** | 'warn' | +| **'no-eq-null'** | 'warn' | +| **'no-extend-native'** | 'warn' | +| **'no-redeclare'** | 'warn' | +| **'no-loop-func'** | 'warn' | +| **'yoda'** | ['warn', 'never'] | +| **'sort-vars'** | 'warn' | +| **'arrow-parens'** | ['error', 'always'] | +| **'arrow-spacing'** | ['error', { before: true, after: true }] | +| **'quotes'** | ['error', 'single', { allowTemplateLiterals: true }] | +| **'consistent-this'** | ['error', 'self'] | +| **'new-parens'** | 'error' | +| **'no-array-constructor'** | 'error' | +| **'no-confusing-arrow'** | 'error' | +| **'no-new-object'** | 'error' | +| **'no-spaced-func'** | 'error' | +| **'no-mixed-spaces-and-tabs'** | 'error' | +| **'key-spacing'** | 'error' | +| **'keyword-spacing'** | ['error', { before: true, after: true }] | +| **'semi'** | ['error', 'always'] | +| **'semi-spacing'** | ['error', { before: false, after: true }] | +| **'space-before-blocks'** | 'error' | +| **'space-infix-ops'** | 'error' | +| **'space-unary-ops'** | ['warn', { words: true, nonwords: false }] | +| **'strict'** | ['error', 'global'] | +| **'eqeqeq'** | 'error' | +| **'curly'** | ['error', 'all'] | +| **'no-eval'** | 'error' | +| **'no-else-return'** | 'error' | +| **'no-return-assign'** | 'error' | +| **'no-new-wrappers'** | 'error' | +| **'comma-dangle'** | ['error', 'never'] | +| **'no-sparse-arrays'** | 'error' | +| **'no-ex-assign'** | 'error' | +| **'prefer-arrow-callback'** | 'error' | +| **'prefer-const'** | ['error', { destructuring: 'all' }] | +| **'indent'** | ['error', 4, { SwitchCase: 1 }] | +| **'space-before-function-paren'** | ['error', { anonymous: 'always', named: 'never' }] | +| **'func-style'** | ['error', 'expression'] | +| **'object-curly-spacing'** | ['error', 'always'] | +| **'object-shorthand'** | ['error', 'properties'] | +| **'no-unsafe-finally'** | 'error' | +| **'no-useless-computed-key'** | 'error' | +| **'require-await'** | 'error' | +| **'constructor-super'** | 'error' | +| **'no-buffer-constructor'** | 'error' | +| **'no-mixed-requires'** | 'error' | +| **'no-new-require'** | 'error' | +| **'no-caller'** | 'error' | +| **'no-const-assign'** | 'error' | +| **'no-dupe-class-members'** | 'error' | +| **'no-class-assign'** | 'warn' | +| **'no-new-symbol'** | 'error | +| **'no-this-before-super'** | 'error' | +| **'prefer-rest-params'** | 'error' | +| **'prefer-spread'** | 'error' | +| **'no-useless-call'** | 'error' | +| **'rest-spread-spacing'** | ['error', 'never'] | +| **'no-extra-semi'** | 'error' | +| **'no-dupe-keys'** | 'error' | +| **'padding-line-between-statements'** | [
    'error',
    { blankLine: 'always', prev: 'directive', next: '\*' },
    { blankLine: 'any', prev: 'directive', next: 'directive' },
    { blankLine: 'always', prev: 'cjs-import', next: '\*' },
    { blankLine: 'any', prev: 'cjs-import', next: 'cjs-import' },
    { blankLine: 'always', prev: 'cjs-export', next: '\*' },
    { blankLine: 'always', prev: 'multiline-block-like', next: '\*' },
    { blankLine: 'always', prev: 'class', next: '\*' }
    ] | diff --git a/generated/markdown/eslint-plugin/7/api.md b/generated/markdown/eslint-plugin/7/api.md new file mode 100644 index 00000000..738df485 --- /dev/null +++ b/generated/markdown/eslint-plugin/7/api.md @@ -0,0 +1,196 @@ +## Configurations + +This ESLint plugin exposes two configurations: + +- `@hapi/recommended` +- `@hapi/module` + +### `@hapi/recommended` + +An ESLint configuration containing hapi style guide rules and config. To use in your project, add +[`@hapi/eslint-plugin`](https://github.com/hapijs/eslint-plugin) to your `package.json`, then in your ESLint configuration add: + +```json +{ + "extends": "plugin:@hapi/recommended" +} +``` + +### `@hapi/module` + +The ESLint configuration used by [`@hapi/lab`](https://hapi.dev/module/lab/) when you use the linting feature through either the [`-L`](https://hapi.dev/module/lab/api/#command-line) command argument or the `lint: true` configuration. + +To use it in your project, there are multiple dependencies you need to add to your `package.json`: + +- [`@hapi/eslint-plugin`](https://github.com/hapijs/eslint-plugin) +- [`@babel/core`](https://www.npmjs.com/package/@babel/core) +- [`@babel/eslint-parser`](https://www.npmjs.com/package/@babel/eslint-parser) + +Then in your ESLint configuration add: + +```json +{ + "extends": "plugin:@hapi/module" +} +``` + +## Rules + +This plugin includes the following ESLint rules: + +### capitalize-modules + +Enforces capitalization of imported module variables. + +#### `global-scope-only` + +If the string `'global-scope-only'` is passed as the first option to this rule, +then it will only be enforced on assignments in the module's top level scope. + +### for-loop + +Enforces `for` loop iterator variable rules and restricts loop nesting depth. + +This rule enforces the following: + +- Restrict iterator variable names. `for` loop iterator variables should be named `i`. Nested loops should use the variables `j`, `k`, and so on. +- Restrict loop nesting. You can restrict the maximum nesting of `for` loops. By default, this limit is three. +- Prevent postfix increment and decrement operators. The hapi style guide does not allow postfix increment and decrement operators in `for` loop updates. The prefix version of these operators should be used instead. +- Single variable declaration in initialization section. A single `var i = 0;` is allowed in the initialization section. This only applies to variable declarations, not assignments to existing variables. This means that `for (i = 0, j = 0)` is allowed if `i` and `j` are existing variables. Variable declarations involving destructuring are not allowed. + +#### Rule options + +This rule can be configured by providing a single options object. The object supports the following keys. + +##### `maxDepth` + +A number representing the maximum allowed nesting of `for` loops. Defaults to three. + +##### `startIterator` + +The first variable iterator name to use. This defaults to `'i'`. + +### no-var + +Enforces the usage of var declarations only in try-catch scope. + +### scope-start + +Enforces a new line at the beginning of function scope. + +#### `allow-one-liners` + +If the string `'allow-one-liners'` is passed as the first option to this rule, +then functions whose bodies contain zero or one statements are allowed to be +written on a single line. This defaults to `true` for arrow functions, and +`false` otherwise. + +#### `max-in-one-liner` + +The second option to this rule dictates the maximum number of statements allowed +in the bodies of one line function. This must be used in conjunction with +`allow-one-liners`. Defaults to one. + +### no-arrowception + +Prevents arrow functions that implicitly create additional arrow functions. + +This rule prevents the pattern () => () => () => ...;. + +Functions can still be returned by arrow functions whose bodies use curly braces and an explicit return. + +This rule does not accept any configuration options. + +## Config + +| Rule | Option | +| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **'@hapi/capitalize-modules'** | ['warn', 'global-scope-only'] | +| **'@hapi/for-loop'** | ['warn', { maxDepth: 3, startIterator: 'i' }] | +| **'@hapi/no-var'** | 'error' | +| **'@hapi/scope-start'** | 'warn' | +| **'@hapi/no-arrowception'** | 'error' | +| **'camelcase'** | 'off' | +| **'consistent-return'** | 'off' | +| **'vars-on-top'** | 'off' | +| **'new-cap'** | 'off | +| **'no-console'** | 'off' | +| **'no-constant-condition'** | 'error' | +| **'no-empty'** | 'off' | +| **'no-native-reassign'** | 'off' | +| **'no-underscore-dangle'** | 'off' | +| **'no-undef'** | ['error', { typeof: false }] | +| **'no-process-exit'** | 'off' | +| **'no-unused-expressions'** | 'off' | +| **'no-regex-spaces'** | 'off' | +| **'no-catch-shadow'** | 'off' | +| **'no-lonely-if'** | 'off' | +| **'brace-style'** | ['warn', 'stroustrup'] | +| **'no-shadow'** | ['warn', { allow: ['err', 'done'] }] | +| **'no-unused-vars'** | ['warn', { vars: 'all', varsIgnorePattern: '^internals$', args: 'none' }] | +| **'one-var'** | ['error', 'never'] | +| **'handle-callback-err'** | ['error', '^(e\|err\|error)$'] | +| **'array-bracket-spacing'** | 'warn' | +| **'dot-notation'** | 'warn' | +| **'eol-last'** | 'warn' | +| **'no-trailing-spaces'** | 'warn' | +| **'no-eq-null'** | 'warn' | +| **'no-extend-native'** | 'warn' | +| **'no-redeclare'** | 'warn' | +| **'no-loop-func'** | 'warn' | +| **'yoda'** | ['warn', 'never'] | +| **'sort-vars'** | 'warn' | +| **'arrow-parens'** | ['error', 'always'] | +| **'arrow-spacing'** | ['error', { before: true, after: true }] | +| **'quotes'** | ['error', 'single', { allowTemplateLiterals: true }] | +| **'consistent-this'** | ['error', 'self'] | +| **'new-parens'** | 'error' | +| **'no-array-constructor'** | 'error' | +| **'no-confusing-arrow'** | 'error' | +| **'no-new-object'** | 'error' | +| **'no-spaced-func'** | 'error' | +| **'no-mixed-spaces-and-tabs'** | 'error' | +| **'key-spacing'** | 'error' | +| **'keyword-spacing'** | ['error', { before: true, after: true }] | +| **'semi'** | ['error', 'always'] | +| **'semi-spacing'** | ['error', { before: false, after: true }] | +| **'space-before-blocks'** | 'error' | +| **'space-infix-ops'** | 'error' | +| **'space-unary-ops'** | ['warn', { words: true, nonwords: false }] | +| **'strict'** | ['error', 'global'] | +| **'eqeqeq'** | 'error' | +| **'curly'** | ['error', 'all'] | +| **'no-eval'** | 'error' | +| **'no-else-return'** | 'error' | +| **'no-return-assign'** | 'error' | +| **'no-new-wrappers'** | 'error' | +| **'comma-dangle'** | ['error', 'never'] | +| **'no-sparse-arrays'** | 'error' | +| **'no-ex-assign'** | 'error' | +| **'prefer-arrow-callback'** | 'error' | +| **'prefer-const'** | ['error', { destructuring: 'all' }] | +| **'indent'** | ['error', 4, { SwitchCase: 1 }] | +| **'space-before-function-paren'** | ['error', { anonymous: 'always', named: 'never' }] | +| **'func-style'** | ['error', 'expression'] | +| **'object-curly-spacing'** | ['error', 'always'] | +| **'object-shorthand'** | ['error', 'properties'] | +| **'no-unsafe-finally'** | 'error' | +| **'no-useless-computed-key'** | 'error' | +| **'require-await'** | 'error' | +| **'constructor-super'** | 'error' | +| **'no-buffer-constructor'** | 'error' | +| **'no-mixed-requires'** | 'error' | +| **'no-new-require'** | 'error' | +| **'no-caller'** | 'error' | +| **'no-const-assign'** | 'error' | +| **'no-dupe-class-members'** | 'error' | +| **'no-class-assign'** | 'warn' | +| **'no-new-symbol'** | 'error | +| **'no-this-before-super'** | 'error' | +| **'prefer-rest-params'** | 'error' | +| **'prefer-spread'** | 'error' | +| **'no-useless-call'** | 'error' | +| **'rest-spread-spacing'** | ['error', 'never'] | +| **'no-extra-semi'** | 'error' | +| **'no-dupe-keys'** | 'error' | +| **'padding-line-between-statements'** | [
    'error',
    { blankLine: 'always', prev: 'directive', next: '\*' },
    { blankLine: 'any', prev: 'directive', next: 'directive' },
    { blankLine: 'always', prev: 'cjs-import', next: '\*' },
    { blankLine: 'any', prev: 'cjs-import', next: 'cjs-import' },
    { blankLine: 'always', prev: 'cjs-export', next: '\*' },
    { blankLine: 'always', prev: 'multiline-block-like', next: '\*' },
    { blankLine: 'always', prev: 'class', next: '\*' }
    ] | diff --git a/generated/markdown/eslint-plugin/changelog.md b/generated/markdown/eslint-plugin/changelog.md new file mode 100644 index 00000000..86c9621f --- /dev/null +++ b/generated/markdown/eslint-plugin/changelog.md @@ -0,0 +1,70 @@ +## Version 7 {#v7} + +### [7.0.0](https://github.com/hapijs/eslint-plugin/milestone/14) {#7.0.0} + +- [#33](https://github.com/hapijs/eslint-plugin/pull/33) feat: target ESLint v9 + +## Version 6 {#v6} + +### [6.0.0](https://github.com/hapijs/eslint-plugin/milestone/12) {#6.0.0} + +- [#31](https://github.com/hapijs/eslint-plugin/pull/31) Drop support for node v12, support node v18, upgrade eslint + +## Version 5 {#v5} + +### [5.1.0](https://github.com/hapijs/eslint-plugin/milestone/10) {#5.1.0} + +- [#27](https://github.com/hapijs/eslint-plugin/pull/27) Migrate lab internal eslint config +- [#26](https://github.com/hapijs/eslint-plugin/issues/26) Update to @babel/eslint-parser +- [#24](https://github.com/hapijs/eslint-plugin/pull/24) upgrade lab to v24 + +### [5.0.0](https://github.com/hapijs/eslint-plugin/milestone/9) {#5.0.0} + +- [#23](https://github.com/hapijs/eslint-plugin/pull/23) Rename to eslint-plugin +- [#21](https://github.com/hapijs/eslint-plugin/issues/21) Change package name to @hapi/eslint-plugin + +## Version 4 {#v4} + +### [4.3.6](https://github.com/hapijs/eslint-plugin/milestone/8) {#4.3.6} + +- [#22](https://github.com/hapijs/eslint-plugin/pull/22) Update rules for modern eslint +- [#20](https://github.com/hapijs/eslint-plugin/pull/20) Merge eslint-config-hapi and rules +- [#19](https://github.com/hapijs/eslint-plugin/pull/19) update to travis templates and test on node 14 +- [#17](https://github.com/hapijs/eslint-plugin/pull/17) Create API.md +- [#16](https://github.com/hapijs/eslint-plugin/pull/16) Update README.md +- [#15](https://github.com/hapijs/eslint-plugin/pull/15) fix(package.json): repository url + +### [4.3.5](https://github.com/hapijs/eslint-plugin/milestone/7) {#4.3.5} + +- [#14](https://github.com/hapijs/eslint-plugin/issues/14) Cleanup + +### [4.3.4](https://github.com/hapijs/eslint-plugin/milestone/6) {#4.3.4} + +- [#11](https://github.com/hapijs/eslint-plugin/issues/11) eslint 6 support + +### [4.3.3](https://github.com/hapijs/eslint-plugin/milestone/5) {#4.3.3} + +- [#10](https://github.com/hapijs/eslint-plugin/issues/10) Fix names + +### [4.2.0](https://github.com/hapijs/eslint-plugin/milestone/4) {#4.2.0} + +- [#9](https://github.com/hapijs/eslint-plugin/issues/9) Change module namespace + +## Version 3 {#v3} + +### [3.0.0](https://github.com/hapijs/eslint-plugin/milestone/3) {#3.0.0} + +- [#6](https://github.com/hapijs/eslint-plugin/issues/6) Remove no-shadow-relaxed + +## Version v2 {#vv2} + +### [v2.0.0](https://github.com/hapijs/eslint-plugin/milestone/2) {#v2.0.0} + +- [#5](https://github.com/hapijs/eslint-plugin/issues/5) Add rule no-arrowception +- [#4](https://github.com/hapijs/eslint-plugin/issues/4) Update to hapi-scope-start@2.0.0 + +## Version v1 {#vv1} + +### [v1.2.0](https://github.com/hapijs/eslint-plugin/milestone/1) {#v1.2.0} + +- [#3](https://github.com/hapijs/eslint-plugin/pull/3) Add no-shadow-relaxed rule to plugin diff --git a/generated/markdown/file/3/api.md b/generated/markdown/file/3/api.md new file mode 100644 index 00000000..c46b9778 --- /dev/null +++ b/generated/markdown/file/3/api.md @@ -0,0 +1,14 @@ +## Methods + +### `uniqueFilename(path, extension)` + +Generate a random file name within a given path and optional extension. + +- `path` - The file path within to generate a temporary file. +- `extension` - File extension. + +```javascript +const File = require('@hapi/file'); + +const fileName = File.uniqueFilename('/root', '.txt'); //results in 'C:\root\1580115599192-8540-61d96458412e09d9.txt' +``` diff --git a/generated/markdown/file/changelog.md b/generated/markdown/file/changelog.md new file mode 100644 index 00000000..d29b0811 --- /dev/null +++ b/generated/markdown/file/changelog.md @@ -0,0 +1,11 @@ +## Version 3 {#v3} + +### [3.0.0](https://github.com/hapijs/file/milestone/3) {#3.0.0} + +- [#14](https://github.com/hapijs/file/pull/14) Support node v18 and drop node v12 + +## Version 2 {#v2} + +### [2.0.0](https://github.com/hapijs/file/milestone/1) {#2.0.0} + +- [#4](https://github.com/hapijs/file/issues/4) Only node 12 diff --git a/generated/markdown/glue/9/api.md b/generated/markdown/glue/9/api.md new file mode 100644 index 00000000..98d5dcb0 --- /dev/null +++ b/generated/markdown/glue/9/api.md @@ -0,0 +1,195 @@ +## Introduction + +### A server composer for hapi.js. + +Glue provides configuration based composition of hapi's Server object. Specifically it wraps + +- `server = Hapi.server(Options)` +- `server.register(Plugins, Options)` + +calling each based on the configuration generated from the glue manifest. + +### hapi version dependency + +Version 9 supports hapi **v20 and v21** as a peer dependency. +Version 8 supports hapi **v20** +Version 7 supports hapi **v19** +Version 6 supports hapi **v18** +Version 5 supports hapi **v17** + +As of glue v9, hapi is treated as a peer dependency. It's recommended to include hapi in your package dependencies alongside of glue, however if you're using npm v7+ then peer dependencies are automatically installed. + +## Interface + +Glue exports a single function `compose` accepting a JSON `manifest` specifying the hapi server options and plugin registrations and returns a [hapi](https://hapi.dev/api) server object. +To start the server use the returned object to call `await server.start()`. + +### `await compose(manifest, [options])` + +Composes a hapi server object where: + +- `manifest` - an object having: + - `server` - an object containing the options passed to [hapi's](https://hapijs.com/api) `new Hapi.Server([options])` + - If `server.cache` is specified, glue will parse the entry and replace any prototype function field (eg. `provider`) specified as string by calling `require()` with that string. + - `register` - an object containing two properties: the `plugins` to be registered and `options` to pass to `server.register` + - `plugins` - an array of entries to register with [hapi's](https://hapijs.com/api) `await server.register(plugins, [options])` + - each entry may be one of three alternatives: + 1. A string to be `require()`d during composition. + + ```js + { + register: { + plugins: ['myplugin']; + } + } + ``` + + 2. An object containing the `plugin` property which is a string to be `require`d during composition + + ```js + { + register: { + plugins: [{ plugin: 'myplugin' }]; + } + } + ``` + + 3. An object containing the `plugin` property which is the plugin object to be passed directly to `await server.register`\*[]: + + ```js + { + register: { + plugins: [{ plugin: require('myplugin') }]; + } + } + ``` + + - object entries may also contain the `options` property, which contains the plugin-level options passed to the plugin at registration time. + + ```js + { + register: { + plugins: [{ plugin: 'myplugin', options: { host: 'my-host.com' } }]; + } + } + ``` + + - object entries may also contain override registration-options such as `routes`. + + ```js + { + register: { + plugins: [{ plugin: 'myplugin', routes: { prefix: '/test/' } }]; + } + } + ``` + + - `options` - optional registration-options object passed to `server.register()`. + +- `options` - an object containing the following `compose` options: + - `relativeTo` - a file-system path string that is used to resolve loading modules with `require`. Used in `server.cache` and `register.plugins[]` + - `preRegister` - an async function that is called prior to registering plugins with the server. The function signature is `async function (server)` where: + - `server` - is the hapi server object. + +`compose` returns the hapi server object. Call `await server.start()` to actually start the server. + +### Notes + +If you are developing a plugin, ensure your plugin dependencies are properly managed to guarantee that all dependencies are loaded before your plugin registration completes. See [hapi's](https://hapi.dev/api) `server.dependency(dependencies, [after])` for more information. + +## Usage + +```javascript +'use strict'; + +const Glue = require('@hapi/glue'); + +const manifest = { + server: { + cache: 'redis', + port: 8000, + }, + register: { + plugins: [ + './awesome-plugin.js', + { + plugin: require('myplugin'), + options: { + uglify: true, + }, + }, + { + plugin: './ui-user', + }, + { + plugin: './ui-admin', + options: { + sessiontime: 500, + }, + routes: { + prefix: '/admin', + }, + }, + ], + options: { + once: false, + }, + }, +}; + +const options = { + relativeTo: __dirname, +}; + +const startServer = async function () { + try { + const server = await Glue.compose(manifest, options); + await server.start(); + console.log('hapi days!'); + } catch (err) { + console.error(err); + process.exit(1); + } +}; + +startServer(); +``` + +The above is translated into the following equivalent hapi API calls. + +```javascript +'use strict'; + +const Hapi = require('@hapi/hapi'); + +const startServer = async function () { + try { + const server = Hapi.server({ cache: [{ provider: require('redis') }], port: 8000 }); + const plugins = []; + const registerOptions = { once: false }; + let pluginPath; + + pluginPath = Path.join(__dirname, './awesome-plugin.js'); + plugins.push({ plugin: require(pluginPath) }); + + plugins.push({ plugin: require('myplugin'), options:{ uglify: true } }); + + pluginPath = Path.join(__dirname, './ui-user'); + plugins.push({ plugin: require(pluginPath) }); + + pluginPath = Path.join(__dirname, './ui-admin'); + plugins.push({ plugin: require(pluginPath), options: { sessiontime: 500 }, routes: { prefix: '/admin' } }); + + await server.register(plugins, registerOptions); + + await server.start(); + console.log('hapi days!'); + } + catch (err) + console.error(err); + process.exit(1); + } +}; + +startServer(); +``` diff --git a/generated/markdown/glue/changelog.md b/generated/markdown/glue/changelog.md new file mode 100644 index 00000000..5adb3c5c --- /dev/null +++ b/generated/markdown/glue/changelog.md @@ -0,0 +1,142 @@ +## Version 9 {#v9} + +### [9.0.1](https://github.com/hapijs/glue/milestone/29) {#9.0.1} + +- [#149](https://github.com/hapijs/glue/pull/149) chore: bump hoek + +### [9.0.0](https://github.com/hapijs/glue/milestone/28) {#9.0.0} + +- [#148](https://github.com/hapijs/glue/pull/148) Support for node v18 and hapi v21, ESM support + +## Version 8 {#v8} + +### [8.0.0](https://github.com/hapijs/glue/milestone/26) {#8.0.0} + +- [#142](https://github.com/hapijs/glue/pull/142) fix: 🐛 bump hapi 20 dependency + +## Version 7 {#v7} + +### [7.0.0](https://github.com/hapijs/glue/milestone/25) {#7.0.0} + +- [#138](https://github.com/hapijs/glue/issues/138) Only node 12 + +## Version 6 {#v6} + +### [6.2.0](https://github.com/hapijs/glue/milestone/23) {#6.2.0} + +- [#133](https://github.com/hapijs/glue/issues/133) Update joi +- [#129](https://github.com/hapijs/glue/pull/129) #128 Add support for constructor property and additional options in server cache configuration +- [#128](https://github.com/hapijs/glue/issues/128) Server cache options in hapi 18 cannot be passed + +### [6.1.1](https://github.com/hapijs/glue/milestone/20) {#6.1.1} + +- [#132](https://github.com/hapijs/glue/issues/132) Update deps + +### [6.1.0](https://github.com/hapijs/glue/milestone/19) {#6.1.0} + +- [#126](https://github.com/hapijs/glue/issues/126) Change module namespace + +### [6.0.0](https://github.com/hapijs/glue/milestone/18) {#6.0.0} + +- [#124](https://github.com/hapijs/glue/pull/124) Updates to hapi 18; refactors cache.engine to cache.provider +- [#121](https://github.com/hapijs/glue/pull/121) Updating package dependencies. + +## Version 5 {#v5} + +### [5.1.0](https://github.com/hapijs/glue/milestone/21) {#5.1.0} + +- [#127](https://github.com/hapijs/glue/issues/127) Change module namespace for v5 branch + +### [5.0.0](https://github.com/hapijs/glue/milestone/17) {#5.0.0} + +- [#104](https://github.com/hapijs/glue/pull/104) Update to hapi v17. +- [#102](https://github.com/hapijs/glue/issues/102) Hapi 17 + +## Version 4 {#v4} + +### [4.2.1](https://github.com/hapijs/glue/milestone/16) {#4.2.1} + +- [#98](https://github.com/hapijs/glue/issues/98) Promises aren't quite right + +### [4.2.0](https://github.com/hapijs/glue/milestone/15) {#4.2.0} + +- [#95](https://github.com/hapijs/glue/pull/95) This is for issue #89 +- [#89](https://github.com/hapijs/glue/issues/89) Plugin as function + +### [4.1.0](https://github.com/hapijs/glue/milestone/14) {#4.1.0} + +- [#85](https://github.com/hapijs/glue/pull/85) Hapi v16 +- [#84](https://github.com/hapijs/glue/pull/84) Refactors Joi.array() to utilize .items() +- [#83](https://github.com/hapijs/glue/issues/83) Joi.array() does not accept arguments +- [#82](https://github.com/hapijs/glue/issues/82) Add Hapi 16 support + +### [4.0.0](https://github.com/hapijs/glue/milestone/13) {#4.0.0} + +- [#74](https://github.com/hapijs/glue/issues/74) Support hapi 15 +- [#72](https://github.com/hapijs/glue/issues/72) Make compose callback always execute async + +## Version 3 {#v3} + +### [3.4.0](https://github.com/hapijs/glue/milestone/12) {#3.4.0} + +- [#73](https://github.com/hapijs/glue/issues/73) Add Hapi 14.x.x to dependencies +- [#71](https://github.com/hapijs/glue/issues/71) using Hoek.clone makes some plugins stop working + +### [3.3.0](https://github.com/hapijs/glue/milestone/11) {#3.3.0} + +- [#64](https://github.com/hapijs/glue/pull/64) add plugin-specific registration options to schema + +### [3.2.1](https://github.com/hapijs/glue/milestone/10) {#3.2.1} + +- [#68](https://github.com/hapijs/glue/pull/68) Test on node v6, update dependencies + +### [3.2.0](https://github.com/hapijs/glue/milestone/9) {#3.2.0} + +- [#62](https://github.com/hapijs/glue/pull/62) Support hapi 13 + +### [3.1.0](https://github.com/hapijs/glue/milestone/8) {#3.1.0} + +- [#57](https://github.com/hapijs/glue/pull/57) Remove boom dependency +- [#54](https://github.com/hapijs/glue/pull/54) compose() returns a Promise if no callback is provided +- [#53](https://github.com/hapijs/glue/pull/53) Support hapi v12 +- [#52](https://github.com/hapijs/glue/issues/52) Support promises + +### [3.0.0](https://github.com/hapijs/glue/milestone/7) {#3.0.0} + +- [#47](https://github.com/hapijs/glue/issues/47) when is glue 3.x going to be completed? +- [#44](https://github.com/hapijs/glue/pull/44) Don't force object for plugin options +- [#42](https://github.com/hapijs/glue/pull/42) update to es6 based hapi style guide and lab 7 + Dependencies update +- [#41](https://github.com/hapijs/glue/issues/41) update to es6 based hapi style guide and lab 7 +- [#40](https://github.com/hapijs/glue/issues/40) Breaking changes on 2.3.0 and 2.4.0 +- [#31](https://github.com/hapijs/glue/issues/31) Prefix is passed only when plugin in manifest is an array + +## Version 2 {#v2} + +### [2.3.0](https://github.com/hapijs/glue/milestone/5) {#2.3.0} + +- [#32](https://github.com/hapijs/glue/pull/32) Support Hapi 10 + +### [2.2.0](https://github.com/hapijs/glue/milestone/4) {#2.2.0} + +- [#28](https://github.com/hapijs/glue/pull/28) README: Use the svg Travis image +- [#26](https://github.com/hapijs/glue/pull/26) Fix typos in docs + +### [2.1.1](https://github.com/hapijs/glue/milestone/3) {#2.1.1} + +- [#25](https://github.com/hapijs/glue/pull/25) Linting update + +### [2.1.0](https://github.com/hapijs/glue/milestone/2) {#2.1.0} + +- [#22](https://github.com/hapijs/glue/pull/22) Add usage section to README file. +- [#20](https://github.com/hapijs/glue/pull/20) Added ability to pass array of plugins + +### [2.0.0](https://github.com/hapijs/glue/milestone/1) {#2.0.0} + +- [#8](https://github.com/hapijs/glue/pull/8) Update Hapi dependency +- [#7](https://github.com/hapijs/glue/issues/7) Publish 2.0.0 +- [#6](https://github.com/hapijs/glue/issues/6) revamp test code to only test functionality relevant to glue +- [#5](https://github.com/hapijs/glue/issues/5) Improve validation and documentation of manifest plugins entry +- [#4](https://github.com/hapijs/glue/pull/4) Update to hapi@8.0.0-rc7 +- [#3](https://github.com/hapijs/glue/issues/3) add support for preConnection and preRegister options handlers +- [#2](https://github.com/hapijs/glue/issues/2) manifest limitation on server options +- [#1](https://github.com/hapijs/glue/issues/1) hapi 8.0 API diff --git a/generated/markdown/h2o2/10/api.md b/generated/markdown/h2o2/10/api.md new file mode 100644 index 00000000..966a82d5 --- /dev/null +++ b/generated/markdown/h2o2/10/api.md @@ -0,0 +1,211 @@ +## Introduction + +**h2o2** adds proxying functionality to a hapi server. + +## Manual loading + +```javascript +const Hapi = require('@hapi/hapi'); +const H2o2 = require('@hapi/h2o2'); + +const start = async function () { + const server = Hapi.server(); + + await server.register(H2o2); + await server.start(); + + console.log(`Server started at: ${server.info.uri}`); +}; + +start(); +``` + +## Options + +The plugin can be registered with an optional object specifying defaults to be applied to the proxy handler object. + +The proxy handler object has the following properties: + +- `host` - upstream service host to proxy requests to. It will have the same path as the client request. +- `port` - upstream service port. +- `protocol` - protocol to use when making the request to the proxied host: + - 'http' + - 'https' +- `uri` - absolute URI used instead of host, port, protocol, path, and query. Cannot be used with `host`, `port`, `protocol`, or `mapUri`. +- `httpClient` - an http client that abides by the Wreck interface. Defaults to [`wreck`](https://github.com/hapijs/wreck). +- `passThrough` - if set to `true`, it forwards the headers from the client to the upstream service, headers sent from the upstream service will also be forwarded to the client. Defaults to `false`. +- `localStatePassThrough` - if set to`false`, any locally defined state is removed from incoming requests before being sent to the upstream service. This value can be overridden on a per state basis via the `server.state()` `passThrough` option. Defaults to `false` +- `acceptEncoding` - if set to `false`, does not pass-through the 'Accept-Encoding' HTTP header which is useful for the `onResponse` post-processing to avoid receiving an encoded response. Can only be used together with `passThrough`. Defaults to `true` (passing header). +- `rejectUnauthorized` - sets the `rejectUnauthorized` property on the https [agent](http://nodejs.org/api/https.html#https_https_request_options_callback) making the request. This value is only used when the proxied server uses TLS/SSL. If set it will override the node.js `rejectUnauthorized` property. If `false` then ssl errors will be ignored. When `true` the server certificate is verified and an 500 response will be sent when verification fails. This shouldn't be used alongside the `agent` setting as the `agent` will be used instead. Defaults to the https agent default value of `true`. +- `xforward` - if set to `true`, sets the 'X-Forwarded-For', 'X-Forwarded-Port', 'X-Forwarded-Proto', 'X-Forwarded-Host' headers when making a request to the proxied upstream endpoint. Defaults to `false`. +- `redirects` - the maximum number of HTTP redirections allowed to be followed automatically by the handler. Set to `false` or `0` to disable all redirections (the response will contain the redirection received from the upstream service). If redirections are enabled, no redirections (301, 302, 307, 308) will be passed along to the client, and reaching the maximum allowed redirections will return an error response. Defaults to `false`. +- `timeout` - number of milliseconds before aborting the upstream request. Defaults to `180000` (3 minutes). +- `mapUri` - a function used to map the request URI to the proxied URI. Cannot be used together with `host`, `port`, `protocol`, or `uri`. The function signature is `function (request)` where: + - `request` - is the incoming [request object](http://hapijs.com/api#request-object). The response from this function should be an object with the following properties: + - `uri` - the absolute proxy URI. + - `headers` - optional object where each key is an HTTP request header and the value is the header content. +- `onRequest` - a custom function which is passed the upstream request. Function signature is `function (req)` where: + - `req` - the [wreck] (https://github.com/hapijs/wreck) request to the upstream server. +- `onResponse` - a custom function for processing the response from the upstream service before sending to the client. Useful for custom error handling of responses from the proxied endpoint or other payload manipulation. Function signature is `function (err, res, request, h, settings, ttl)` where: + - `err` - internal or upstream error returned from attempting to contact the upstream proxy. + - `res` - the node response object received from the upstream service. `res` is a readable stream (use the [wreck](https://github.com/hapijs/wreck) module `read` method to easily convert it to a Buffer or string). Note that it is your responsibility to close the `res` stream. + - `request` - is the incoming [request object](http://hapijs.com/api#request-object). + - `h` - the [response toolkit](https://hapijs.com/api#response-toolkit). + - `settings` - the proxy handler configuration. + - `ttl` - the upstream TTL in milliseconds if `proxy.ttl` it set to `'upstream'` and the upstream response included a valid 'Cache-Control' header with 'max-age'. +- `ttl` - if set to `'upstream'`, applies the upstream response caching policy to the response using the `response.ttl()` method (or passed as an argument to the `onResponse` method if provided). +- `agent` - a node [http(s) agent](http://nodejs.org/api/http.html#http_class_http_agent) to be used for connections to upstream server. +- `maxSockets` - sets the maximum number of sockets available per outgoing proxy host connection. `false` means use the **wreck** module default value (`Infinity`). Does not affect non-proxy outgoing client connections. Defaults to `Infinity`. +- `secureProtocol` - [TLS](http://nodejs.org/api/tls.html) flag indicating the SSL method to use, e.g. `SSLv3_method` + to force SSL version 3. The possible values depend on your installation of OpenSSL. Read the official OpenSSL docs for possible [SSL_METHODS](https://www.openssl.org/docs/man1.0.2/ssl/ssl.html). +- `ciphers` - [TLS](https://nodejs.org/api/tls.html#tls_modifying_the_default_tls_cipher_suite) list of TLS ciphers to override node's default. + The possible values depend on your installation of OpenSSL. Read the official OpenSSL docs for possible [TLS_CIPHERS](https://www.openssl.org/docs/man1.0.2/apps/ciphers.html#CIPHER-LIST-FORMAT). +- `downstreamResponseTime` - logs the time spent processing the downstream request using [process.hrtime](https://nodejs.org/api/process.html#process_process_hrtime_time). Defaults to `false`. + +## Usage + +As one of the handlers for hapi, it is used through the route configuration object. + +### `h.proxy(options)` + +Proxies the request to an upstream endpoint where: + +- `options` - an object including the same keys and restrictions defined by the + [route `proxy` handler options](#options). + +No return value. + +The [response flow control rules](http://hapijs.com/api#flow-control) **do not** apply. + +```js +const handler = function (request, h) { + return h.proxy({ host: 'example.com', port: 80, protocol: 'http' }); +}; +``` + +### Using the `host`, `port`, `protocol` options + +Setting these options will send the request to certain route to a specific upstream service with the same path as the original request. Cannot be used with `uri`, `mapUri`. + +```javascript +server.route({ + method: 'GET', + path: '/', + handler: { + proxy: { + host: '10.33.33.1', + port: '443', + protocol: 'https', + }, + }, +}); +``` + +### Using the `uri` option + +Setting this option will send the request to an absolute URI instead of the incoming host, port, protocol, path and query. Cannot be used with `host`, `port`, `protocol`, `mapUri`. + +```javascript +server.route({ + method: 'GET', + path: '/', + handler: { + proxy: { + uri: 'https://some.upstream.service.com/that/has?what=you&want=todo', + }, + }, +}); +``` + +### Custom `uri` template values + +When using the `uri` option, there are optional **default** template values that can be injected from the incoming `request`: + +- `{protocol}` +- `{host}` +- `{port}` +- `{path}` +- `{query}` + +```javascript +server.route({ + method: 'GET', + path: '/foo', + handler: { + proxy: { + uri: '{protocol}://{host}:{port}/go/to/{path}', + }, + }, +}); +``` + +Requests to `http://127.0.0.1:8080/foo/` would be proxied to an upstream destination of `http://127.0.0.1:8080/go/to/foo` + +Additionally, you can capture request.params and query values and inject them into the upstream uri value using a similar replacement strategy: + +```javascript +server.route({ + method: 'GET', + path: '/foo/{bar}', + handler: { + proxy: { + uri: 'https://some.upstream.service.com/some/path/to/{bar}{query}', + }, + }, +}); +``` + +**Note** The default variables of `{protocol}`, `{host}`, `{port}`, `{path}`, `{query}` take precedence - it's best to treat those as reserved when naming your own `request.params`. + +### Using the `mapUri` and `onResponse` options + +Setting both options with custom functions will allow you to map the original request to an upstream service and to processing the response from the upstream service, before sending it to the client. Cannot be used together with `host`, `port`, `protocol`, or `uri`. + +```javascript +server.route({ + method: 'GET', + path: '/', + handler: { + proxy: { + mapUri: function (request) { + console.log('doing some additional stuff before redirecting'); + return { + uri: 'https://some.upstream.service.com/', + }; + }, + onResponse: async function (err, res, request, h, settings, ttl) { + console.log('receiving the response from the upstream.'); + const payload = await Wreck.read(res, { json: true }); + + console.log('some payload manipulation if you want to.'); + const response = h.response(payload); + response.headers = res.headers; + return response; + }, + }, + }, +}); +``` + +### Using a custom http client + +By default, `h2o2` uses Wreck to perform requests. A custom http client can be provided by passing a client to `httpClient`, as long as it abides by the [`wreck`](https://github.com/hapijs/wreck) interface. The two functions that `h2o2` utilizes are `request()` and `parseCacheControl()`. + +```javascript +server.route({ + method: 'GET', + path: '/', + handler: { + proxy: { + httpClient: { + request(method, uri, options) { + return axios({ + method, + url: 'https://some.upstream.service.com/', + }); + }, + }, + }, + }, +}); +``` diff --git a/generated/markdown/h2o2/changelog.md b/generated/markdown/h2o2/changelog.md new file mode 100644 index 00000000..1a2a81ee --- /dev/null +++ b/generated/markdown/h2o2/changelog.md @@ -0,0 +1,115 @@ +## Version 10 {#v10} + +### [10.0.3](https://github.com/hapijs/h2o2/milestone/23) {#10.0.3} + +- [#137](https://github.com/hapijs/h2o2/pull/137) Fix mapUri type definition + +### [10.0.2](https://github.com/hapijs/h2o2/milestone/22) {#10.0.2} + +- [#136](https://github.com/hapijs/h2o2/pull/136) chore: add typings from DT + +### [10.0.1](https://github.com/hapijs/h2o2/milestone/21) {#10.0.1} + +- [#135](https://github.com/hapijs/h2o2/pull/135) chore: bump hoek +- [#133](https://github.com/hapijs/h2o2/pull/133) Support delete payload forwarding + +### [10.0.0](https://github.com/hapijs/h2o2/milestone/20) {#10.0.0} + +- [#132](https://github.com/hapijs/h2o2/pull/132) Support for hapi v21, node v18, ESM tests +- [#131](https://github.com/hapijs/h2o2/pull/131) add dispatcher and use shared config +- [#128](https://github.com/hapijs/h2o2/pull/128) Add querystring support for uri mapping + +## Version 9 {#v9} + +### [9.1.0](https://github.com/hapijs/h2o2/milestone/18) {#9.1.0} + +- [#125](https://github.com/hapijs/h2o2/pull/125) propagate request abortion to upstream server + +### [9.0.2](https://github.com/hapijs/h2o2/milestone/17) {#9.0.2} + +- [#121](https://github.com/hapijs/h2o2/pull/121) migrate to new travis format +- [#120](https://github.com/hapijs/h2o2/pull/120) upgrade to hapi 20 +- [#119](https://github.com/hapijs/h2o2/pull/119) update lab and switch joi to validate +- [#117](https://github.com/hapijs/h2o2/pull/117) Update onResponse for Wreck's async/await syntax + +### [9.0.1](https://github.com/hapijs/h2o2/milestone/16) {#9.0.1} + +- [#113](https://github.com/hapijs/h2o2/issues/113) Require hapi 19 + +### [9.0.0](https://github.com/hapijs/h2o2/milestone/15) {#9.0.0} + +- [#112](https://github.com/hapijs/h2o2/issues/112) Change plugin name to @hapi/h2o2 +- [#111](https://github.com/hapijs/h2o2/issues/111) Drop hapi v17 +- [#110](https://github.com/hapijs/h2o2/issues/110) Only node 12 + +## Version 8 {#v8} + +### [8.3.2](https://github.com/hapijs/h2o2/milestone/14) {#8.3.2} + +- [#102](https://github.com/hapijs/h2o2/issues/102) Update joi + +### [8.3.1](https://github.com/hapijs/h2o2/milestone/13) {#8.3.1} + +- [#101](https://github.com/hapijs/h2o2/issues/101) Update deps + +### [8.3.0](https://github.com/hapijs/h2o2/milestone/12) {#8.3.0} + +- [#95](https://github.com/hapijs/h2o2/issues/95) Move agents from internals to server +- [#94](https://github.com/hapijs/h2o2/issues/94) Change module namespace + +## Version 5 {#v5} + +### [5.3.0](https://github.com/hapijs/h2o2/milestone/11) {#5.3.0} + +- [#45](https://github.com/hapijs/h2o2/pull/45) Fix the `uri` vs. `address` variable usage for multiple replacements +- [#44](https://github.com/hapijs/h2o2/pull/44) Allow request.params variable replacement in the uri template + +### [5.2.0](https://github.com/hapijs/h2o2/milestone/10) {#5.2.0} + +- [#42](https://github.com/hapijs/h2o2/pull/42) Added X-Forwarded-Host to forward headers +- [#41](https://github.com/hapijs/h2o2/pull/41) X-Forwarded-Proto being set to upstream protocol + +### [5.1](https://github.com/hapijs/h2o2/milestone/9) {#5.1} + +- [#24](https://github.com/hapijs/h2o2/pull/24) Update deps + +### [5.0.0](https://github.com/hapijs/h2o2/milestone/8) {#5.0.0} + +- [#20](https://github.com/hapijs/h2o2/pull/20) Migrate to new versions of modules and ES6. + +## Version 4 {#v4} + +### [4.0.2](https://github.com/hapijs/h2o2/milestone/7) {#4.0.2} + +- [#18](https://github.com/hapijs/h2o2/pull/18) Update Wreck dependency + +### [4.0.1](https://github.com/hapijs/h2o2/milestone/6) {#4.0.1} + +- [#11](https://github.com/hapijs/h2o2/pull/11) Bump Joi to v6.x.x + +### [4.0.0](https://github.com/hapijs/h2o2/milestone/5) {#4.0.0} + +- [#8](https://github.com/hapijs/h2o2/pull/8) passThrough changes + +## Version 3 {#v3} + +### [3.0.0](https://github.com/hapijs/h2o2/milestone/4) {#3.0.0} + +- [#7](https://github.com/hapijs/h2o2/pull/7) Move maxSockets to a handler config instead of server +- [#6](https://github.com/hapijs/h2o2/issues/6) Replace server maxSockets settings with per handler configuration + +## Version 2 {#v2} + +### [2.0.1](https://github.com/hapijs/h2o2/milestone/3) {#2.0.1} + +- [#4](https://github.com/hapijs/h2o2/issues/4) Change localStatePassThrough default to true + +### [2.0.0](https://github.com/hapijs/h2o2/milestone/2) {#2.0.0} + +- [#3](https://github.com/hapijs/h2o2/issues/3) Change handler function to hapi 7.0 API + +## Version 1 {#v1} + +### [1.0.1](https://github.com/hapijs/h2o2/milestone/1) {#1.0.1} + +- [#1](https://github.com/hapijs/h2o2/issues/1) Use joi.assert() diff --git a/generated/markdown/hapi/20/api.md b/generated/markdown/hapi/20/api.md new file mode 100644 index 00000000..211792d0 --- /dev/null +++ b/generated/markdown/hapi/20/api.md @@ -0,0 +1,4947 @@ +## Server + +The server object is the main application container. The server manages all incoming requests +along with all the facilities provided by the framework. Each server supports a single connection +(e.g. listen to port `80`). + +### `server([options])` + +Creates a new server object where: + +- `options` - (optional) a [server configuration object](#server.options). + +```js +const Hapi = require('@hapi/hapi'); + +const server = Hapi.server({ load: { sampleInterval: 1000 } }); +``` + +### Server options + +The server options control the behavior of the server object. Note that the options object is +deeply cloned (with the exception of [`listener`](#server.options.listener) which is shallowly +copied) and should not contain any values that are unsafe to perform deep copy on. + +All options are optionals. + +#### `server.options.address` + +Default value: `'0.0.0.0'` (all available network interfaces). + +Sets the hostname or IP address the server will listen on. If not configured, defaults to +[`host`](#server.options.host) if present, otherwise to all available network interfaces. Set to +`'127.0.0.1'` or `'localhost'` to restrict the server to only those coming from the same host. + +#### `server.options.app` + +Default value: `{}`. + +Provides application-specific configuration which can later be accessed via +[`server.settings.app`](#server.settings). The framework does not interact with this object. It is +simply a reference made available anywhere a `server` reference is provided. + +Note the difference between `server.settings.app` which is used to store static configuration +values and [`server.app`](#server.app) which is meant for storing run-time state. + +#### `server.options.autoListen` + +Default value: `true`. + +Used to disable the automatic initialization of the [`listener`](#server.options.listener). When +`false`, indicates that the [`listener`](#server.options.listener) will be started manually outside +the framework. + +Cannot be set to `false` along with a [`port`](#server.options.port) value. + +#### `server.options.cache` + +Default value: `{ provider: { constructor: require('@hapi/catbox-memory'), options: { partition: 'hapi-cache' } } }`. + +Sets up server-side caching providers. Every server includes a default cache for storing +application state. By default, a simple memory-based cache is created which has limited capacity +and capabilities. + +**hapi** uses [**catbox**](https://hapi.dev/family/catbox/api) for its cache implementation which +includes support for common storage solutions (e.g. Redis, MongoDB, Memcached, Riak, among others). +Caching is only utilized if [methods](#server.methods) and [plugins](#plugins) explicitly store +their state in the cache. + +The server cache configuration only defines the storage container itself. The configuration can be +assigned one or more (array): + +- a class or prototype function (usually obtained by calling `require()` on a **catbox** strategy + such as `require('@hapi/catbox-redis')`). A new **catbox** [client](https://hapi.dev/family/catbox/api#client) + will be created internally using this constructor. + +- a configuration object with the following: + - `engine` - a **catbox** engine object instance. + + - `name` - an identifier used later when provisioning or configuring caching for + [server methods](#server.methods) or [plugins](#plugins). Each cache name must be unique. + A single item may omit the `name` option which defines the default cache. If every cache + includes a `name`, a default memory cache is provisioned as well. + + - `provider` - a class, a constructor function, or an object with the following: + - `constructor` - a class or a prototype function. + + - `options` - (optional) a settings object passed as-is to the `constructor` with the following: + - `partition` - (optional) string used to isolate cached data. Defaults to `'hapi-cache'`. + - other constructor-specific options passed to the `constructor` on instantiation. + + - `shared` - if `true`, allows multiple cache users to share the same segment (e.g. + multiple methods using the same cache storage container). Default to `false`. + + - One (and only one) of `engine` or `provider` is required per configuration object. + +#### `server.options.compression` + +Default value: `{ minBytes: 1024 }`. + +Defines server handling of content encoding requests. If `false`, response content encoding is +disabled and no compression is performed by the server. + +##### `server.options.compression.minBytes` + +Default value: '1024'. + +Sets the minimum response payload size in bytes that is required for content encoding compression. +If the payload size is under the limit, no compression is performed. + +#### `server.options.debug` + +Default value: `{ request: ['implementation'] }`. + +Determines which logged events are sent to the console. This should only be used for development +and does not affect which events are actually logged internally and recorded. Set to `false` to +disable all console logging, or to an object with: + +- `log` - a string array of server log tags to be displayed via `console.error()` when + the events are logged via [`server.log()`](#server.log()) as well as + internally generated [server logs](#server-logs). Defaults to no output. + +- `request` - a string array of request log tags to be displayed via `console.error()` when + the events are logged via [`request.log()`](#request.log()) as well as + internally generated [request logs](#request-logs). For example, to display all errors, + set the option to `['error']`. To turn off all console debug messages set it to `false`. + To display all request logs, set it to `'*'`. + Defaults to uncaught errors thrown in external code (these errors are handled + automatically and result in an Internal Server Error response) or runtime errors due to + developer error. + +For example, to display all errors, set the `log` or `request` to `['error']`. To turn off all +output set the `log` or `request` to `false`. To display all server logs, set the `log` or +`request` to `'*'`. To disable all debug information, set `debug` to `false`. + +#### `server.options.host` + +Default value: the operating system hostname and if not available, to `'localhost'`. + +The public hostname or IP address. Used to set [`server.info.host`](#server.info) and +[`server.info.uri`](#server.info) and as [`address`](#server.options.address) if none is provided. + +#### `server.options.info.remote` + +Default value: `false`. + +If `true`, the `request.info.remoteAddress` and `request.info.remotePort` are populated when the request is received which can consume more resource (but is ok if the information is needed, especially for aborted requests). When `false`, the fields are only populated upon demand (but will be `undefined` if accessed after the request is aborted). + +#### `server.options.listener` + +Default value: none. + +An optional node HTTP (or HTTPS) [`http.Server`](https://nodejs.org/api/http.html#http_class_http_server) +object (or an object with a compatible interface). + +If the `listener` needs to be manually started, set [`autoListen`](#server.options.autolisten) to +`false`. + +If the `listener` uses TLS, set [`tls`](#server.options.tls) to `true`. + +#### `server.options.load` + +Default value: `{ sampleInterval: 0, maxHeapUsedBytes: 0, maxRssBytes: 0, maxEventLoopDelay: 0 }`. + +Server excessive load handling limits where: + +- `sampleInterval` - the frequency of sampling in milliseconds. When set to `0`, the other load options are ignored. Defaults to `0` (no sampling). + +- `maxHeapUsedBytes` - maximum V8 heap size over which incoming requests are rejected with an HTTP Server Timeout (503) response. Defaults to `0` (no limit). + +- `maxRssBytes` - maximum process RSS size over which incoming requests are rejected with an HTTP Server Timeout (503) response. Defaults to `0` (no limit). + +- `maxEventLoopDelay` - maximum event loop delay duration in milliseconds over which incoming requests are rejected with an HTTP Server Timeout (503) response. Defaults to `0` (no limit). + +#### `server.options.mime` + +Default value: none. + +Options passed to the [**mimos**](https://hapi.dev/family/mimos/api) module when generating the mime database used by the server (and accessed via [`server.mime`](#server.mime)): + +- `override` - an object hash that is merged into the built in mime information specified [here](https://github.com/jshttp/mime-db). Each key value pair represents a single mime object. Each override value must contain: + - `key` - the lower-cased mime-type string (e.g. `'application/javascript'`). + + - `value` - an object following the specifications outlined [here](https://github.com/jshttp/mime-db#data-structure). Additional values include: + - `type` - specify the `type` value of result objects, defaults to `key`. + + - `predicate` - method with signature `function(mime)` when this mime type is found in the database, this function will execute to allows customizations. + +```js +const options = { + mime: { + override: { + 'node/module': { + source: 'iana', + compressible: true, + extensions: ['node', 'module', 'npm'], + type: 'node/module', + }, + 'application/javascript': { + source: 'iana', + charset: 'UTF-8', + compressible: true, + extensions: ['js', 'javascript'], + type: 'text/javascript', + }, + 'text/html': { + predicate: function (mime) { + if (someCondition) { + mime.foo = 'test'; + } else { + mime.foo = 'bar'; + } + return mime; + }, + }, + }, + }, +}; +``` + +#### `server.options.operations` + +Default value: `{ cleanStop: true }`. + +Defines server handling of server operations: + +- `cleanStop` - if `true`, the server keeps track of open connections and properly closes them + when the server is stopped. Under normal load, this should not interfere with server performance. + However, under severe load connection monitoring can consume additional resources and aggravate + the situation. If the server is never stopped, or if it is forced to stop without waiting for + open connection to close, setting this to `false` can save resources that are not being utilized + anyway. Defaults to `true`. + +#### `server.options.plugins` + +Default value: `{}`. + +Plugin-specific configuration which can later be accessed via [`server.settings.plugins`](#server.settings). +`plugins` is an object where each key is a plugin name and the value is the configuration. +Note the difference between [`server.settings.plugins`](#server.settings) which is used to store +static configuration values and [`server.plugins`](#server.plugins) which is meant for storing +run-time state. + +#### `server.options.port` + +Default value: `0` (an ephemeral port). + +The TCP port the server will listen to. Defaults the next available port when the server is started +(and assigned to [`server.info.port`](#server.info)). + +If `port` is a string containing a '/' character, it is used as a UNIX domain socket path. +If it starts with '\\.\pipe', it is used as a Windows named pipe. + +#### `server.options.query` + +Default value: `{}`. + +Defines server handling of the request path query component. + +##### `server.options.query.parser` + +Default value: none. + +Sets a query parameters parser method using the signature `function(query)` where: + +- `query` - an object containing the incoming [`request.query`](#request.query) parameters. +- the method must return an object where each key is a parameter and matching value is the + parameter value. If the method throws, the error is used as the response or returned when + [`request.setUrl()`](#request.setUrl()) is called. + +```js +const Qs = require('qs'); + +const options = { + query: { + parser: (query) => Qs.parse(query), + }, +}; +``` + +#### `server.options.router` + +Default value: `{ isCaseSensitive: true, stripTrailingSlash: false }`. + +Controls how incoming request URIs are matched against the routing table: + +- `isCaseSensitive` - determines whether the paths '/example' and '/EXAMPLE' are considered + different resources. Defaults to `true`. + +- `stripTrailingSlash` - removes trailing slashes on incoming paths. Defaults to `false`. + +#### `server.options.routes` + +Default value: none. + +A [route options](#route-options) object used as the default configuration for every route. + +#### `server.options.state` + +Default value: + +```js +{ + strictHeader: true, + ignoreErrors: false, + isSecure: true, + isHttpOnly: true, + isSameSite: 'Strict', + encoding: 'none' +} +``` + +Sets the default configuration for every state (cookie) set explicitly via +[`server.state()`](#server.state()) or implicitly (without definition) using the +[state configuration](#server.state()) object. + +#### `server.options.tls` + +Default value: none. + +Used to create an HTTPS connection. The `tls` object is passed unchanged to the node +HTTPS server as described in the [node HTTPS documentation](https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener). + +Set to `true` when passing a [`listener`](#server.options.listener) object that has been configured +to use TLS directly. + +#### `server.options.uri` + +Default value: constructed from runtime server information. + +The full public URI without the path (e.g. 'http://example.com:8080'). If present, used as the +server [`server.info.uri`](#server.info), otherwise constructed from the server settings. + +### Server properties + +#### `server.app` + +Access: read / write. + +Provides a safe place to store server-specific run-time application data without potential +conflicts with the framework internals. The data can be accessed whenever the server is +accessible. Initialized with an empty object. + +```js +const server = Hapi.server(); + +server.app.key = 'value'; + +const handler = function (request, h) { + return request.server.app.key; // 'value' +}; +``` + +#### `server.auth.api` + +Access: authentication strategy specific. + +An object where each key is an authentication strategy name and the value is the exposed strategy +API. Available only when the authentication scheme exposes an API by returning an `api` key in the +object returned from its implementation function. + +```js +const server = Hapi.server({ port: 80 }); + +const scheme = function (server, options) { + return { + api: { + settings: { + x: 5, + }, + }, + authenticate: function (request, h) { + const authorization = request.headers.authorization; + if (!authorization) { + throw Boom.unauthorized(null, 'Custom'); + } + + return h.authenticated({ credentials: { user: 'john' } }); + }, + }; +}; + +server.auth.scheme('custom', scheme); +server.auth.strategy('default', 'custom'); + +console.log(server.auth.api.default.settings.x); // 5 +``` + +#### `server.auth.settings.default` + +Access: read only. + +Contains the default authentication configuration if a default strategy was set via +[`server.auth.default()`](#server.auth.default()). + +#### `server.decorations` + +Access: read only. + +Provides access to the decorations already applied to various framework interfaces. The object must +not be modified directly, but only through [`server.decorate`](#server.decorate()). +Contains: + +- `request` - decorations on the [request object](#request). +- `response` - decorations on the [response object](#response-object). +- `toolkit` - decorations on the [response toolkit](#response-toolkit). +- `server` - decorations on the [server](#server) object. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +const success = function () { + return this.response({ status: 'ok' }); +}; + +server.decorate('toolkit', 'success', success); +console.log(server.decorations.toolkit); // ['success'] +``` + +#### `server.events` + +Access: **podium** public interface. + +The server events emitter. Utilizes the [**podium**](https://hapi.dev/family/podium/api) with support +for event criteria validation, channels, and filters. + +Use the following methods to interact with `server.events`: + +- [`server.event(events)`](#server.event()) - register application events. +- [`server.events.emit(criteria, data)`](#server.events.emit()) - emit server events. +- [`server.events.on(criteria, listener)`](#server.events.on()) - subscribe to all events. +- [`server.events.once(criteria, listener)`](#server.events.once()) - subscribe to + +Other methods include: `server.events.removeListener(name, listener)`, +`server.events.removeAllListeners(name)`, and `server.events.hasListeners(name)`. + +##### `'log'` Event + +The `'log'` event type emits internal server events generated by the framework as well as +application events logged with [`server.log()`](#server.log()). + +The `'log'` event handler uses the function signature `function(event, tags)` where: + +- `event` - an object with the following properties: + - `timestamp` - the event timestamp. + - `tags` - an array of tags identifying the event (e.g. `['error', 'http']`). + - `channel` - set to `'internal'` for internally generated events, otherwise `'app'` for events + generated by [`server.log()`](#server.log()). + - `data` - event-specific information. Available when event data was provided and is not an + error. Errors are passed via `error`. + - `error` - the error object related to the event if applicable. Cannot appear together with + `data`. + +- `tags` - an object where each `event.tag` is a key and the value is `true`. Useful for quick + identification of events. + +```js +server.events.on('log', (event, tags) => { + if (tags.error) { + console.log( + `Server error: ${event.error ? event.error.message : 'unknown'}`, + ); + } +}); +``` + +The internally generated events are (identified by their `tags`): + +- `load` - logs the current server load measurements when the server rejects a request due to + [high load](#server.options.load). The event data contains the process load metrics. + +- `connection` `client` `error` - a `clientError` event was received from the HTTP or HTTPS + listener. The event data is the error object received. + +##### `'cachePolicy'` Event + +The `'cachePolicy'` event type is emitted when a server [cache policy](https://hapi.dev/module/catbox/api#policy) +is created via [`server.cache()`](#server.cache()) or a [`server.method()`](#server.method()) with caching enabled is registered. +The `'cachePolicy'` event handler uses the function signature `function(cachePolicy, cache, segment)` where: + +- `cachePolicy` - the catbox [cache policy](https://hapi.dev/module/catbox/api#policy). +- `cache` - the [cache provision](#server.options.cache) name used when the policy was created or `undefined` if the default cache was used. +- `segment` - the segment name used when the policy was created. + +```js +server.events.on('cachePolicy', (cachePolicy, cache, segment) => { + console.log( + `New cache policy created using cache: ${cache === undefined ? 'default' : cache} and segment: ${segment}`, + ); +}); +``` + +##### `'request'` Event + +The `'request'` event type emits internal request events generated by the framework as well as +application events logged with [`request.log()`](#request.log()). + +The `'request'` event handler uses the function signature `function(request, event, tags)` where: + +- `request` - the [request object](#request). + +- `event` - an object with the following properties: + - `timestamp` - the event timestamp. + - `tags` - an array of tags identifying the event (e.g. `['error', 'http']`). + - `channel` - one of + - `'app'` - events generated by [`request.log()`](#request.log()). + - `'error'` - emitted once per request if the response had a `500` status code. + - `'internal'` - internally generated events. + - `request` - the request [identifier](#request.info.id). + - `data` - event-specific information. Available when event data was provided and is not an + error. Errors are passed via `error`. + - `error` - the error object related to the event if applicable. Cannot appear together with + `data`. + +- `tags` - an object where each `event.tag` is a key and the value is `true`. Useful for quick + identification of events. + +```js +server.events.on('request', (request, event, tags) => { + if (tags.error) { + console.log( + `Request ${event.request} error: ${event.error ? event.error.message : 'unknown'}`, + ); + } +}); +``` + +To listen to only one of the channels, use the event criteria object: + +```js +server.events.on( + { name: 'request', channels: 'error' }, + (request, event, tags) => { + console.log(`Request ${event.request} failed`); + }, +); +``` + +The internally generated events are (identified by their `tags`): + +- `accept-encoding` `error` - a request received contains an invalid Accept-Encoding header. +- `auth` `unauthenticated` - no authentication scheme included with the request. +- `auth` `unauthenticated` `response` `{strategy}` - the authentication strategy listed returned a non-error response (e.g. a redirect to a login page). +- `auth` `unauthenticated` `error` `{strategy}` - the request failed to pass the listed authentication strategy (invalid credentials). +- `auth` `unauthenticated` `missing` `{strategy}` - the request failed to pass the listed authentication strategy (no credentials found). +- `auth` `unauthenticated` `try` `{strategy}` - the request failed to pass the listed authentication strategy in `'try'` mode and will continue. +- `auth` `scope` `error` - the request authenticated but failed to meet the scope requirements. +- `auth` `entity` `user` `error` - the request authenticated but included an application entity when a user entity was required. +- `auth` `entity` `app` `error` - the request authenticated but included a user entity when an application entity was required. +- `ext` `error` - an `onPostResponse` extension handler errored. +- `handler` `error` - the route handler returned an error. Includes the execution duration and the error message. +- `pre` `error` - a pre method was executed and returned an error. Includes the execution duration, assignment key, and error. +- `internal` `error` - an HTTP 500 error response was assigned to the request. +- `internal` `implementation` `error` - an incorrectly implemented [lifecycle method](#lifecycle-methods). +- `request` `abort` `error` - the request aborted. +- `request` `closed` `error` - the request closed prematurely. +- `request` `error` - the request stream emitted an error. Includes the error. +- `request` `server` `timeout` `error` - the request took too long to process by the server. Includes the timeout configuration value and the duration. +- `state` `error` - the request included an invalid cookie or cookies. Includes the cookies and error details. +- `state` `response` `error` - the response included an invalid cookie which prevented generating a valid header. Includes the error. +- `payload` `error` - failed processing the request payload. Includes the error. +- `response` `error` - failed writing the response to the client. Includes the error. +- `response` `error` `close` - failed writing the response to the client due to prematurely closed connection. +- `response` `error` `aborted` - failed writing the response to the client due to prematurely aborted connection. +- `response` `error` `cleanup` - failed freeing response resources. +- `validation` `error` `{input}` - input (i.e. payload, query, params, headers) validation failed. Includes the error. Only emitted when `failAction` is set to `'log'`. +- `validation` `response` `error` - response validation failed. Includes the error message. Only emitted when `failAction` is set to `'log'`. + +##### `'response'` Event + +The `'response'` event type is emitted after the response is sent back to the client (or when the +client connection closed and no response sent, in which case [`request.response`](#request.response) +is `null`). A single event is emitted per request. The `'response'` event handler uses the function +signature `function(request)` where: + +- `request` - the [request object](#request). + +```js +server.events.on('response', (request) => { + console.log(`Response sent for request: ${request.info.id}`); +}); +``` + +##### `'route'` Event + +The `'route'` event type is emitted when a route is added via [`server.route()`](#server.route()). +The `'route'` event handler uses the function signature `function(route)` where: + +- `route` - the [route information](#request.route). The `route` object must not be modified. + +```js +server.events.on('route', (route) => { + console.log(`New route added: ${route.path}`); +}); +``` + +##### `'start'` Event + +The `'start'` event type is emitted when the server is started using [`server.start()`](#server.start()). +The `'start'` event handler uses the function signature `function()`. + +```js +server.events.on('start', () => { + console.log('Server started'); +}); +``` + +##### `'closing'` Event + +The `'closing'` event type is emitted when the server is stopped using [`server.stop()`](#server.stop()). It is triggered when incoming requests are no longer accepted but before all underlying active connections have been closed, and thus before the [`'stop'`](#server.events.stop) event is triggered. +The `'closing'` event handler uses the function signature `function()`. + +```js +server.events.on('closing', () => { + console.log('Server is closing'); +}); +``` + +##### `'stop'` Event + +The `'stop'` event type is emitted when the server is stopped using [`server.stop()`](#server.stop()). +The `'stop'` event handler uses the function signature `function()`. + +```js +server.events.on('stop', () => { + console.log('Server stopped'); +}); +``` + +#### `server.info` + +Access: read only. + +An object containing information about the server where: + +- `id` - a unique server identifier (using the format '{hostname}:{pid}:{now base36}'). + +- `created` - server creation timestamp. + +- `started` - server start timestamp (`0` when stopped). + +- `port` - the connection port based on the following rules: + - before the server has been started: the configured [`port`](#server.options.port) value. + - after the server has been started: the actual port assigned when no port is configured or was + set to `0`. + +- `host` - The [`host`](#server.options.host) configuration value. + +- `address` - the active IP address the connection was bound to after starting. Set to `undefined` + until the server has been started or when using a non TCP port (e.g. UNIX domain socket). + +- `protocol` - the protocol used: + - `'http'` - HTTP. + - `'https'` - HTTPS. + - `'socket'` - UNIX domain socket or Windows named pipe. + +- `uri` - a string representing the connection (e.g. 'http://example.com:8080' or + 'socket:/unix/domain/socket/path'). Contains the [`uri`](#server.options.uri) value if set, + otherwise constructed from the available settings. If no [`port`](#server.options.port) is + configured or is set to `0`, the `uri` will not include a port component until the server is + started. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +console.log(server.info.port); // 80 +``` + +#### `server.listener` + +Access: read only and listener public interface. + +The node HTTP server object. + +```js +const Hapi = require('@hapi/hapi'); +const SocketIO = require('socket.io'); + +const server = Hapi.server({ port: 80 }); + +const io = SocketIO.listen(server.listener); +io.sockets.on('connection', (socket) => { + socket.emit({ msg: 'welcome' }); +}); +``` + +#### `server.load` + +Access: read only. + +An object containing the process load metrics (when [`load.sampleInterval`](#server.options.load) +is enabled): + +- `eventLoopDelay` - event loop delay milliseconds. +- `heapUsed` - V8 heap usage. +- `rss` - RSS memory usage. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ load: { sampleInterval: 1000 } }); + +console.log(server.load.rss); +``` + +#### `server.methods` + +Access: read only. + +Server methods are functions registered with the server and used throughout the application as a +common utility. Their advantage is in the ability to configure them to use the built-in cache and +share across multiple request handlers without having to create a common module. + +`sever.methods` is an object which provides access to the methods registered via +[server.method()](#server.method()) where each server method name is an object +property. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server(); + +server.method('add', (a, b) => a + b); +const result = server.methods.add(1, 2); // 3 +``` + +#### `server.mime` + +Access: read only and **mimos** public interface. + +Provides access to the server MIME database used for setting content-type information. The object +must not be modified directly but only through the [`mime`](#server.options.mime) server setting. + +```js +const Hapi = require('@hapi/hapi'); + +const options = { + mime: { + override: { + 'node/module': { + source: 'steve', + compressible: false, + extensions: ['node', 'module', 'npm'], + type: 'node/module', + }, + }, + }, +}; + +const server = Hapi.server(options); +console.log(server.mime.path('code.js').type); // 'application/javascript' +console.log(server.mime.path('file.npm').type); // 'node/module' +``` + +#### `server.plugins` + +Access: read / write. + +An object containing the values exposed by each registered plugin where each key is a plugin name +and the values are the exposed properties by each plugin using +[`server.expose()`](#server.expose()). Plugins may set the value of the +`server.plugins[name]` object directly or via the `server.expose()` method. + +```js +exports.plugin = { + name: 'example', + register: function (server, options) { + server.expose('key', 'value'); + server.plugins.example.other = 'other'; + + console.log(server.plugins.example.key); // 'value' + console.log(server.plugins.example.other); // 'other' + }, +}; +``` + +#### `server.realm` + +Access: read only. + +The realm object contains sandboxed server settings specific to each plugin or authentication +strategy. When registering a plugin or an authentication scheme, a `server` object reference is +provided with a new `server.realm` container specific to that registration. It allows each plugin +to maintain its own settings without leaking and affecting other plugins. + +For example, a plugin can set a default file path for local resources without breaking other +plugins' configured paths. When calling [`server.bind()`](#server.bind()), the active realm's +`settings.bind` property is set which is then used by routes and extensions added at the same level +(server root or plugin). + +The `server.realm` object contains: + +- `modifiers` - when the server object is provided as an argument to the plugin `register()` + method, `modifiers` provides the registration preferences passed the + [`server.register()`](#server.register()) method and includes: + - `route` - routes preferences: + - `prefix` - the route path prefix used by any calls to [`server.route()`](#server.route()) + from the server. Note that if a prefix is used and the route path is set to `'/'`, the + resulting path will not include the trailing slash. + - `vhost` - the route virtual host settings used by any calls to + [`server.route()`](#server.route()) from the server. + +- `parent` - the realm of the parent server object, or `null` for the root server. + +- `plugin` - the active plugin name (empty string if at the server root). + +- `pluginOptions` - the plugin options passed at registration. + +- `plugins` - plugin-specific state to be shared only among activities sharing the same active + state. `plugins` is an object where each key is a plugin name and the value is the plugin state. + +- `settings` - settings overrides: + - `files.relativeTo` + - `bind` + +The `server.realm` object should be considered read-only and must not be changed directly except +for the `plugins` property which can be directly manipulated by each plugin, setting its properties +inside `plugins[name]`. + +```js +exports.register = function (server, options) { + console.log(server.realm.modifiers.route.prefix); +}; +``` + +#### `server.registrations` + +Access: read only. + +An object of the currently registered plugins where each key is a registered plugin name and the +value is an object containing: + +- `version` - the plugin version. +- `name` - the plugin name. +- `options` - (optional) options passed to the plugin during registration. + +#### `server.settings` + +Access: read only. + +The server configuration object after defaults applied. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ + app: { + key: 'value', + }, +}); + +console.log(server.settings.app); // { key: 'value' } +``` + +#### `server.states` + +Access: read only and **statehood** public interface. + +The server cookies manager. + +#### `server.states.settings` + +Access: read only. + +The server cookies manager settings. The settings are based on the values configured in +[`server.options.state`](#server.options.state). + +#### `server.states.cookies` + +Access: read only. + +An object containing the configuration of each cookie added via [`server.state()`](#server.state()) +where each key is the cookie name and value is the configuration object. + +#### `server.states.names` + +Access: read only. + +An array containing the names of all configured cookies. + +#### `server.type` + +Access: read only. + +A string indicating the listener type where: + +- `'socket'` - UNIX domain socket or Windows named pipe. +- `'tcp'` - an HTTP listener. + +#### `server.version` + +Access: read only. + +The **hapi** module version number. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server(); + +console.log(server.version); // '17.0.0' +``` + +### `server.auth.default(options)` + +Sets a default strategy which is applied to every route where: + +- `options` - one of: + - a string with the default strategy name + - an authentication configuration object using the same format as the + [route `auth` handler options](#route.options.auth). + +Return value: none. + +The default does not apply when a route config specifies `auth` as `false`, or has an +authentication strategy configured (contains the [`strategy`](#route.options.auth.strategy) or +[`strategies`](#route.options.auth.strategies) authentication settings). Otherwise, the route +authentication config is applied to the defaults. + +Note that if the route has authentication configured, the default only applies at the time of +adding the route, not at runtime. This means that calling `server.auth.default()` after adding a +route with some authentication config will have no impact on the routes added prior. However, the +default will apply to routes added before `server.auth.default()` is called if those routes lack +any authentication config. + +The default auth strategy configuration can be accessed via [`server.auth.settings.default`](#server.auth.settings.default). +To obtain the active authentication configuration of a route, use `server.auth.lookup(request.route)`. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +server.auth.scheme('custom', scheme); +server.auth.strategy('default', 'custom'); +server.auth.default('default'); + +server.route({ + method: 'GET', + path: '/', + handler: function (request, h) { + return request.auth.credentials.user; + }, +}); +``` + +### `server.auth.scheme(name, scheme)` + +Registers an authentication scheme where: + +- `name` - the scheme name. +- `scheme` - the method implementing the scheme with signature `function(server, options)` where: + - `server` - a reference to the server object the scheme is added to. Each auth strategy is given its own [`server.realm`](#server.realm) whose parent is the realm of the `server` in the call to [`server.auth.strategy()`](#server.auth.strategy()). + - `options` - (optional) the scheme `options` argument passed to + [`server.auth.strategy()`](#server.auth.strategy()) when instantiation a strategy. + +Return value: none. + +The `scheme` function must return an [authentication scheme object](#authentication-scheme) when +invoked. + +#### Authentication scheme + +An authentication scheme is an object with the following properties: + +- `api` - (optional) object which is exposed via the [`server.auth.api`](#server.auth.api) object. + +- `async authenticate(request, h)` - (required) a [lifecycle method](#lifecycle-methods) function + called for each incoming request configured with the authentication scheme. The method is + provided with two special toolkit methods for returning an authenticated or an unauthenticate + result: + - [`h.authenticated()`](#h.authenticated()) - indicate request authenticated successfully. + - [`h.unauthenticated()`](#h.unauthenticated()) - indicate request failed to authenticate. + +- `async payload(request, h)` - (optional) a [lifecycle method](#lifecycle-methods) to authenticate + the request payload. + +- `async response(request, h)` - (optional) a [lifecycle method](#lifecycle-methods) to decorate + the response with authentication headers before the response headers or payload is written. + +- `async verify(auth)` - (optional) a method used to verify the authentication credentials provided + are still valid (e.g. not expired or revoked after the initial authentication) where: + - `auth` - the [`request.auth`](#request.auth) object containing the `credentials` and + `artifacts` objects returned by the scheme's `authenticate()` method. + - the method throws an `Error` when the credentials passed are no longer valid (e.g. expired or + revoked). Note that the method does not have access to the original request, only to the + credentials and artifacts produced by the `authenticate()` method. + +- `options` - (optional) an object with the following keys: + - `payload` - if `true`, requires payload validation as part of the scheme and forbids routes + from disabling payload auth validation. Defaults to `false`. + +When the scheme `authenticate()` method implementation throws an error or calls +[`h.unauthenticated()`](#h.unauthenticated()), the specifics of the error affect whether additional +authentication strategies will be attempted (if configured for the route). If the error includes a +message, no additional strategies will be attempted. If the `err` does not include a message but +does include the scheme name (e.g. `Boom.unauthorized(null, 'Custom')`), additional strategies will +be attempted in the order of preference (defined in the route configuration). If authentication +fails, the scheme names will be present in the 'WWW-Authenticate' header. + +When the scheme `payload()` method throws an error with a message, it means payload validation +failed due to bad payload. If the error has no message but includes a scheme name (e.g. +`Boom.unauthorized(null, 'Custom')`), authentication may still be successful if the route +[`auth.payload`](#route.options.auth.payload) configuration is set to `'optional'`. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +const scheme = function (server, options) { + return { + authenticate: function (request, h) { + const req = request.raw.req; + const authorization = req.headers.authorization; + if (!authorization) { + throw Boom.unauthorized(null, 'Custom'); + } + + return h.authenticated({ credentials: { user: 'john' } }); + }, + }; +}; + +server.auth.scheme('custom', scheme); +``` + +### `server.auth.strategy(name, scheme, [options])` + +Registers an authentication strategy where: + +- `name` - the strategy name. +- `scheme` - the scheme name (must be previously registered using + [`server.auth.scheme()`](#server.auth.scheme())). +- `options` - scheme options based on the scheme requirements. + +Return value: none. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +server.auth.scheme('custom', scheme); +server.auth.strategy('default', 'custom'); + +server.route({ + method: 'GET', + path: '/', + options: { + auth: 'default', + handler: function (request, h) { + return request.auth.credentials.user; + }, + }, +}); +``` + +### `await server.auth.test(strategy, request)` + +Tests a request against an authentication strategy where: + +- `strategy` - the strategy name registered with [`server.auth.strategy()`](#server.auth.strategy()). +- `request` - the [request object](#request). + +Return value: an object containing the authentication `credentials` and `artifacts` if authentication +was successful, otherwise throws an error. + +Note that the `test()` method does not take into account the route authentication configuration. It +also does not perform payload authentication. It is limited to the basic strategy authentication +execution. It does not include verifying scope, entity, or other route properties. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +server.auth.scheme('custom', scheme); +server.auth.strategy('default', 'custom'); + +server.route({ + method: 'GET', + path: '/', + handler: async function (request, h) { + try { + const { credentials, artifacts } = await request.server.auth.test( + 'default', + request, + ); + return { status: true, user: credentials.name }; + } catch (err) { + return { status: false }; + } + }, +}); +``` + +### `await server.auth.verify(request)` + +Verify a request's authentication credentials against an authentication strategy where: + +- `request` - the [request object](#request). + +Return value: nothing if verification was successful, otherwise throws an error. + +Note that the `verify()` method does not take into account the route authentication configuration +or any other information from the request other than the `request.auth` object. It also does not +perform payload authentication. It is limited to verifying that the previously valid credentials +are still valid (e.g. have not been revoked or expired). It does not include verifying scope, +entity, or other route properties. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +server.auth.scheme('custom', scheme); +server.auth.strategy('default', 'custom'); + +server.route({ + method: 'GET', + path: '/', + handler: async function (request, h) { + try { + const credentials = await request.server.auth.verify(request); + return { status: true, user: credentials.name }; + } catch (err) { + return { status: false }; + } + }, +}); +``` + +### `server.bind(context)` + +Sets a global context used as the default bind object when adding a route or an extension where: + +- `context` - the object used to bind `this` in [lifecycle methods](#lifecycle-methods) such as + the [route handler](#route.options.handler) and [extension methods](#server.ext()). The context + is also made available as [`h.context`](#h.context). + +Return value: none. + +When setting a context inside a plugin, the context is applied only to methods set up by the +plugin. Note that the context applies only to routes and extensions added after it has been set. +Ignored if the method being bound is an arrow function. + +```js +const handler = function (request, h) { + return this.message; // Or h.context.message +}; + +exports.plugin = { + name: 'example', + register: function (server, options) { + const bind = { + message: 'hello', + }; + + server.bind(bind); + server.route({ method: 'GET', path: '/', handler }); + }, +}; +``` + +### `server.cache(options)` + +Provisions a cache segment within the server cache facility where: + +- `options` - [**catbox** policy](https://hapi.dev/family/catbox/api#policy) configuration where: + - `expiresIn` - relative expiration expressed in the number of milliseconds since the item was + saved in the cache. Cannot be used together with `expiresAt`. + + - `expiresAt` - time of day expressed in 24h notation using the 'HH:MM' format, at which point + all cache records expire. Uses local time. Cannot be used together with `expiresIn`. + + - `generateFunc` - a function used to generate a new cache item if one is not found in the + cache when calling `get()`. The method's signature is `async function(id, flags)` where: + + - `id` - the `id` string or object provided to the `get()` method. + - `flags` - an object used to pass back additional flags to the cache where: + - `ttl` - the cache ttl value in milliseconds. Set to `0` to skip storing in the + cache. Defaults to the cache global policy. + + - `staleIn` - number of milliseconds to mark an item stored in cache as stale and attempt to + regenerate it when `generateFunc` is provided. Must be less than `expiresIn`. + + - `staleTimeout` - number of milliseconds to wait before checking if an item is stale. + + - `generateTimeout` - number of milliseconds to wait before returning a timeout error when the + `generateFunc` function takes too long to return a value. When the value is eventually + returned, it is stored in the cache for future requests. Required if `generateFunc` is + present. Set to `false` to disable timeouts which may cause all `get()` requests to get stuck + forever. + + - `generateOnReadError` - if `false`, an upstream cache read error will stop the `cache.get()` + method from calling the generate function and will instead pass back the cache error. Defaults + to `true`. + + - `generateIgnoreWriteError` - if `false`, an upstream cache write error when calling + `cache.get()` will be passed back with the generated value when calling. Defaults to `true`. + + - `dropOnError` - if `true`, an error or timeout in the `generateFunc` causes the stale value + to be evicted from the cache. Defaults to `true`. + + - `pendingGenerateTimeout` - number of milliseconds while `generateFunc` call is in progress + for a given id, before a subsequent `generateFunc` call is allowed. Defaults to `0` (no + blocking of concurrent `generateFunc` calls beyond `staleTimeout`). + + - `cache` - the cache name configured in [`server.cache`](#server.options.cache). Defaults to + the default cache. + + - `segment` - string segment name, used to isolate cached items within the cache partition. + When called within a plugin, defaults to '!name' where 'name' is the plugin name. When called + within a server method, defaults to '#name' where 'name' is the server method name. Required + when called outside of a plugin. + + - `shared` - if `true`, allows multiple cache provisions to share the same segment. Default to + `false`. + +Return value: a [**catbox** policy](https://hapi.dev/family/catbox/api#policy) object. + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + const cache = server.cache({ + segment: 'countries', + expiresIn: 60 * 60 * 1000, + }); + await cache.set('norway', { capital: 'oslo' }); + const value = await cache.get('norway'); +} +``` + +### `await server.cache.provision(options)` + +Provisions a server cache as described in [`server.cache`](#server.options.cache) where: + +- `options` - same as the server [`cache`](#server.options.cache) configuration options. + +Return value: none. + +Note that if the server has been initialized or started, the cache will be automatically started +to match the state of any other provisioned server cache. + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + await server.initialize(); + await server.cache.provision({ + provider: require('@hapi/catbox-memory'), + name: 'countries', + }); + + const cache = server.cache({ cache: 'countries', expiresIn: 60 * 60 * 1000 }); + await cache.set('norway', { capital: 'oslo' }); + const value = await cache.get('norway'); +} +``` + +### `server.control(server)` + +Links another server to the initialize/start/stop state of the current server by calling the +controlled server `initialize()`/`start()`/`stop()` methods whenever the current server methods +are called, where: + +- `server` - the **hapi** server object to be controlled. + +### `server.decoder(encoding, decoder)` + +Registers a custom content decoding compressor to extend the built-in support for `'gzip'` and +'`deflate`' where: + +- `encoding` - the decoder name string. + +- `decoder` - a function using the signature `function(options)` where `options` are the encoding + specific options configured in the route [`payload.compression`](#route.options.payload.compression) + configuration option, and the return value is an object compatible with the output of node's + [`zlib.createGunzip()`](https://nodejs.org/api/zlib.html#zlib_zlib_creategunzip_options). + +Return value: none. + +```js +const Zlib = require('zlib'); +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ + port: 80, + routes: { payload: { compression: { special: { chunkSize: 16 * 1024 } } } }, +}); + +server.decoder('special', (options) => Zlib.createGunzip(options)); +``` + +### `server.decorate(type, property, method, [options])` + +Extends various framework interfaces with custom methods where: + +- `type` - the interface being decorated. Supported types: + - `'handler'` - adds a new handler type to be used in [routes handlers](#route.options.handler). + - `'request'` - adds methods to the [Request object](#request). + - `'response'` - adds methods to the [Response object](#response-object). + - `'server'` - adds methods to the [Server](#server) object. + - `'toolkit'` - adds methods to the [response toolkit](#response-toolkit). + +- `property` - the object decoration key name or symbol. + +- `method` - the extension function or other value. + +- `options` - (optional) supports the following optional settings: + - `apply` - when the `type` is `'request'`, if `true`, the `method` function is invoked using + the signature `function(request)` where `request` is the current request object and the + returned value is assigned as the decoration. + - `extend` - if `true`, overrides an existing decoration. The `method` must be a function with + the signature `function(existing)` where: + - `existing` - is the previously set decoration method value. + - must return the new decoration function or value. + - cannot be used to extend handler decorations. + +Return value: none. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +const success = function () { + return this.response({ status: 'ok' }); +}; + +server.decorate('toolkit', 'success', success); + +server.route({ + method: 'GET', + path: '/', + handler: function (request, h) { + return h.success(); + }, +}); +``` + +When registering a handler decoration, the `method` must be a function using the signature +`function(route, options)` where: + +- `route` - the [route information](#request.route). +- `options` - the configuration object provided in the handler config. + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ host: 'localhost', port: 8000 }); + + // Defines new handler for routes on this server + + const handler = function (route, options) { + return function (request, h) { + return 'new handler: ' + options.msg; + }; + }; + + server.decorate('handler', 'test', handler); + + server.route({ + method: 'GET', + path: '/', + handler: { test: { msg: 'test' } }, + }); + + await server.start(); +} +``` + +The `method` function can have a `defaults` object or function property. If the property is set to +an object, that object is used as the default route config for routes using this handler. If the +property is set to a function, the function uses the signature `function(method)` and returns the +route default configuration. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ host: 'localhost', port: 8000 }); + +const handler = function (route, options) { + return function (request, h) { + return 'new handler: ' + options.msg; + }; +}; + +// Change the default payload processing for this handler + +handler.defaults = { + payload: { + output: 'stream', + parse: false, + }, +}; + +server.decorate('handler', 'test', handler); +``` + +### `server.dependency(dependencies, [after])` + +Used within a plugin to declare a required dependency on other [plugins](#plugins) required for +the current plugin to operate (plugins listed must be registered before the server is initialized +or started) where: + +- `dependencies` - one of: + - a single plugin name string. + - an array of plugin name strings. + - an object where each key is a plugin name and each matching value is a + [version range string](https://www.npmjs.com/package/semver) which must match the registered + plugin version. + +- `after` - (optional) a function that is called after all the specified dependencies have been + registered and before the server starts. The function is only called if the server is initialized + or started. The function signature is `async function(server)` where: + + - `server` - the server the `dependency()` method was called on. + +Return value: none. + +The `after` method is identical to setting a server extension point on `'onPreStart'`. + +If a circular dependency is detected, an exception is thrown (e.g. two plugins each has an `after` +function to be called after the other). + +```js +const after = function (server) { + // Additional plugin registration logic +}; + +exports.plugin = { + name: 'example', + register: function (server, options) { + server.dependency('yar', after); + }, +}; +``` + +Dependencies can also be set via the plugin `dependencies` property (does not support setting +`after`): + +```js +exports.plugin = { + name: 'test', + version: '1.0.0', + dependencies: { + yar: '1.x.x', + }, + register: function (server, options) {}, +}; +``` + +The `dependencies` configuration accepts one of: + +- a single plugin name string. +- an array of plugin name strings. +- an object where each key is a plugin name and each matching value is a + [version range string](https://www.npmjs.com/package/semver) which must match the registered + plugin version. + +### `server.encoder(encoding, encoder)` + +Registers a custom content encoding compressor to extend the built-in support for `'gzip'` and +'`deflate`' where: + +- `encoding` - the encoder name string. + +- `encoder` - a function using the signature `function(options)` where `options` are the encoding + specific options configured in the route [`compression`](#route.options.compression) option, and + the return value is an object compatible with the output of node's + [`zlib.createGzip()`](https://nodejs.org/api/zlib.html#zlib_zlib_creategzip_options). + +Return value: none. + +```js +const Zlib = require('zlib'); +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ + port: 80, + routes: { compression: { special: { chunkSize: 16 * 1024 } } }, +}); + +server.encoder('special', (options) => Zlib.createGzip(options)); +``` + +### `server.event(events)` + +Register custom application events where: + +- `events` - must be one of: + - an event name string. + + - an event options object with the following optional keys (unless noted otherwise): + - `name` - the event name string (required). + + - `channels` - a string or array of strings specifying the event channels available. Defaults to no channel restrictions (event updates can specify a channel or not). + + - `clone` - if `true`, the `data` object passed to [`server.events.emit()`](#server.events.emit()) is cloned before it is passed to the listeners (unless an override specified by each listener). Defaults to `false` (`data` is passed as-is). + + - `spread` - if `true`, the `data` object passed to [`server.event.emit()`](#server.event.emit()) must be an array and the `listener` method is called with each array element passed as a separate argument (unless an override specified by each listener). This should only be used when the emitted data structure is known and predictable. Defaults to `false` (`data` is emitted as a single argument regardless of its type). + + - `tags` - if `true` and the `criteria` object passed to [`server.event.emit()`](#server.event.emit()) includes `tags`, the tags are mapped to an object (where each tag string is the key and the value is `true`) which is appended to the arguments list at the end. A configuration override can be set by each listener. Defaults to `false`. + + - `shared` - if `true`, the same event `name` can be registered multiple times where the second registration is ignored. Note that if the registration config is changed between registrations, only the first configuration is used. Defaults to `false` (a duplicate registration will throw an error). + + - a [**podium**](https://hapi.dev/family/podium/api) emitter object. + + - an array containing any of the above. + +Return value: none. + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + server.event('test'); + server.events.on('test', (update) => console.log(update)); + await server.events.emit('test', 'hello'); +} +``` + +### `await server.events.emit(criteria, data)` + +Emits a custom application event to all the subscribed listeners where: + +- `criteria` - the event update criteria which must be one of: + - the event name string. + - an object with the following optional keys (unless noted otherwise): + - `name` - the event name string (required). + - `channel` - the channel name string. + - `tags` - a tag string or array of tag strings. + +- `data` - the value emitted to the subscribers. If `data` is a function, the function signature is `function()` and it called once to generate (return value) the actual data emitted to the listeners. If no listeners match the event, the `data` function is not invoked. + +Return value: none. + +Note that events must be registered before they can be emitted or subscribed to by calling [`server.event(events)`](#server.event()). This is done to detect event name misspelling and invalid event activities. + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + server.event('test'); + server.events.on('test', (update) => console.log(update)); + await server.events.emit('test', 'hello'); // await is optional +} +``` + +### `server.events.on(criteria, listener)` + +Subscribe to an event where: + +- `criteria` - the subscription criteria which must be one of: + - event name string which can be any of the [built-in server events](#server.events) or a + custom application event registered with [`server.event()`](#server.event()). + + - a criteria object with the following optional keys (unless noted otherwise): + - `name` - (required) the event name string. + + - `channels` - a string or array of strings specifying the event channels to subscribe to. + If the event registration specified a list of allowed channels, the `channels` array must + match the allowed channels. If `channels` are specified, event updates without any + channel designation will not be included in the subscription. Defaults to no channels + filter. + + - `clone` - if `true`, the `data` object passed to [`server.event.emit()`](#server.event.emit()) + is cloned before it is passed to the `listener` method. Defaults to the event + registration option (which defaults to `false`). + + - `count` - a positive integer indicating the number of times the `listener` can be called + after which the subscription is automatically removed. A count of `1` is the same as + calling `server.events.once()`. Defaults to no limit. + + - `filter` - the event tags (if present) to subscribe to which can be one of: + - a tag string. + - an array of tag strings. + - an object with the following: + - `tags` - a tag string or array of tag strings. + - `all` - if `true`, all `tags` must be present for the event update to match the + subscription. Defaults to `false` (at least one matching tag). + + - `spread` - if `true`, and the `data` object passed to [`server.event.emit()`](#server.event.emit()) + is an array, the `listener` method is called with each array element passed as a separate + argument. This should only be used when the emitted data structure is known and + predictable. Defaults to the event registration option (which defaults to `false`). + + - `tags` - if `true` and the `criteria` object passed to [`server.event.emit()`](#server.event.emit()) + includes `tags`, the tags are mapped to an object (where each tag string is the key and + the value is `true`) which is appended to the arguments list at the end. Defaults to the + event registration option (which defaults to `false`). + +- `listener` - the handler method set to receive event updates. The function signature depends on + the event argument, and the `spread` and `tags` options. + +Return value: none. + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + server.event('test'); + server.events.on('test', (update) => console.log(update)); + await server.events.emit('test', 'hello'); +} +``` + +### `server.events.once(criteria, listener)` + +Same as calling [`server.events.on()`](#server.events.on()) with the `count` option set to `1`. + +Return value: none. + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + server.event('test'); + server.events.once('test', (update) => console.log(update)); + await server.events.emit('test', 'hello'); + await server.events.emit('test', 'hello'); // Ignored +} +``` + +### `await server.events.once(criteria)` + +Same as calling [`server.events.on()`](#server.events.on()) with the `count` option set to `1`. + +Return value: a promise that resolves when the event is emitted. + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + server.event('test'); + const pending = server.events.once('test'); + await server.events.emit('test', 'hello'); + const update = await pending; +} +``` + +### `server.expose(key, value, [options])` + +Used within a plugin to expose a property via [`server.plugins[name]`](#server.plugins) where: + +- `key` - the key assigned ([`server.plugins[name][key]`](#server.plugins)). +- `value` - the value assigned. +- `options` - optional settings: + - `scope` - controls how to handle the presence of a plugin scope in the name (e.g. `@hapi/test`): + - `false` - the scope is removed (e.g. `@hapi/test` is changed to `test` under `server.plugins`). This is the default. + - `true` - the scope is retained as-is (e.g. `@hapi/test` is used as `server.plugins['@hapi/test']`). + - `'underscore'` - the scope is rewritten (e.g. `@hapi/test` is used as `server.plugins.hapi__test`). + +Return value: none. + +```js +exports.plugin = + name: 'example', + register: function (server, options) { + + server.expose('util', () => console.log('something')); + } +}; +``` + +### `server.expose(obj)` + +Merges an object into to the existing content of [`server.plugins[name]`](#server.plugins) where: + +- `obj` - the object merged into the exposed properties container. + +Return value: none. + +```js +exports.plugin = { + name: 'example', + register: function (server, options) { + server.expose({ util: () => console.log('something') }); + }, +}; +``` + +Note that all the properties of `obj` are deeply cloned into [`server.plugins[name]`](#server.plugins), +so avoid using this method for exposing large objects that may be expensive to clone or singleton +objects such as database client objects. Instead favor [`server.expose(key, value)`](#server.expose()), +which only copies a reference to `value`. + +### `server.ext(events)` + +Registers an extension function in one of the [request lifecycle](#request-lifecycle) extension +points where: + +- `events` - an object or array of objects with the following: + - `type` - (required) the extension point event name. The available extension points include + the [request extension points](#request-lifecycle) as well as the following server extension + points: + - `'onPreStart'` - called before the connection listeners are started. + - `'onPostStart'` - called after the connection listeners are started. + - `'onPreStop'` - called before the connection listeners are stopped. + - `'onPostStop'` - called after the connection listeners are stopped. + + - `method` - (required) a function or an array of functions to be executed at a specified point + during request processing. The required extension function signature is: + - server extension points: `async function(server)` where: + - `server` - the server object. + - `this` - the object provided via `options.bind` or the current active context set + with [`server.bind()`](#server.bind()). + + - request extension points: a [lifecycle method](#lifecycle-methods). + + - `options` - (optional) an object with the following: + - `before` - a string or array of strings of plugin names this method must execute before + (on the same event). Otherwise, extension methods are executed in the order added. + + - `after` - a string or array of strings of plugin names this method must execute after (on + the same event). Otherwise, extension methods are executed in the order added. + + - `bind` - a context object passed back to the provided method (via `this`) when called. + Ignored if the method is an arrow function. + + - `sandbox` - if set to `'plugin'` when adding a [request extension points](#request-lifecycle) + the extension is only added to routes defined by the current plugin. Not allowed when + configuring route-level extensions, or when adding server extensions. Defaults to + `'server'` which applies to any route added to the server the extension is added to. + + - `timeout` - number of milliseconds to wait for the `method` to complete before returning + a timeout error. Defaults to no timeout. + +Return value: none. + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + + server.ext({ + type: 'onRequest', + method: function (request, h) { + // Change all requests to '/test' + + request.setUrl('/test'); + return h.continue; + }, + }); + + server.route({ method: 'GET', path: '/test', handler: () => 'ok' }); + await server.start(); + + // All requests will get routed to '/test' +} +``` + +### `server.ext(event, [method, [options]])` + +Registers a single extension event using the same properties as used in [`server.ext(events)`](#server.ext()), but passed as arguments. + +The `method` may be omitted (if `options` isn't present) or passed `null` which will cause the function to return a promise. The promise is resolved with the `request` object on the first invocation of the extension point. This is primarily used for writing tests without having to write custom handlers just to handle a single event. + +Return value: a promise if `method` is omitted, otherwise `undefined`. + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + + server.ext('onRequest', function (request, h) { + // Change all requests to '/test' + + request.setUrl('/test'); + return h.continue; + }); + + server.route({ method: 'GET', path: '/test', handler: () => 'ok' }); + await server.start(); + + // All requests will get routed to '/test' +} +``` + +### `await server.initialize()` + +Initializes the server (starts the caches, finalizes plugin registration) but does not start +listening on the connection port. + +Return value: none. + +Note that if the method fails and throws an error, the server is considered to be in an undefined +state and should be shut down. In most cases it would be impossible to fully recover as the various +plugins, caches, and other event listeners will get confused by repeated attempts to start the +server or make assumptions about the healthy state of the environment. It is recommended to abort +the process when the server fails to start properly. If you must try to resume after an error, call +[`server.stop()`](#server.stop()) first to reset the server state. + +```js +const Hapi = require('@hapi/hapi'); +const Hoek = require('@hapi/hoek'); + +async function example() { + const server = Hapi.server({ port: 80 }); + await server.initialize(); +} +``` + +### `await server.inject(options)` + +Injects a request into the server simulating an incoming HTTP request without making an actual +socket connection. Injection is useful for testing purposes as well as for invoking routing logic +internally without the overhead and limitations of the network stack. + +The method utilizes the [**shot**](https://hapi.dev/family/shot/api) module for performing +injections, with some additional options and response properties: + +- `options` - can be assigned a string with the requested URI, or an object with: + - `method` - (optional) the request HTTP method (e.g. `'POST'`). Defaults to `'GET'`. + + - `url` - (required) the request URL. If the URI includes an authority + (e.g. `'example.com:8080'`), it is used to automatically set an HTTP 'Host' header, unless + one was specified in `headers`. + + - `authority` - (optional) a string specifying the HTTP 'Host' header value. Only used if 'Host' + is not specified in `headers` and the `url` does not include an authority component. + Default is inferred from runtime server information. + + - `headers` - (optional) an object with optional request headers where each key is the header + name and the value is the header content. Defaults to no additions to the default **shot** + headers. + + - `payload` - (optional) an string, buffer or object containing the request payload. In case of + an object it will be converted to a string for you. Defaults to no payload. Note that payload + processing defaults to `'application/json'` if no 'Content-Type' header provided. + + - `auth` - (optional) an object containing parsed authentication credentials where: + - `strategy` - (required) the authentication strategy name matching the provided + credentials. + + - `credentials` - (required) a credentials object containing authentication information. + The `credentials` are used to bypass the default authentication strategies, and are + validated directly as if they were received via an authentication scheme. + + - `artifacts` - (optional) an artifacts object containing authentication artifact + information. The `artifacts` are used to bypass the default authentication strategies, + and are validated directly as if they were received via an authentication scheme. + Defaults to no artifacts. + + - `payload` - (optional) disables payload authentication when set to false. + Only required when an authentication strategy requires payload authentication. + Defaults to `true`. + + - `app` - (optional) sets the initial value of `request.app`, defaults to `{}`. + + - `plugins` - (optional) sets the initial value of `request.plugins`, defaults to `{}`. + + - `allowInternals` - (optional) allows access to routes with `config.isInternal` set to `true`. + Defaults to `false`. + + - `remoteAddress` - (optional) sets the remote address for the incoming connection. + + - `simulate` - (optional) an object with options used to simulate client request stream + conditions for testing: + - `error` - if `true`, emits an `'error'` event after payload transmission (if any). + Defaults to `false`. + + - `close` - if `true`, emits a `'close'` event after payload transmission (if any). + Defaults to `false`. + + - `end` - if `false`, does not end the stream. Defaults to `true`. + + - `split` - indicates whether the request payload will be split into chunks. Defaults to + `undefined`, meaning payload will not be chunked. + + - `validate` - (optional) if `false`, the `options` inputs are not validated. This is + recommended for run-time usage of `inject()` to make it perform faster where input validation + can be tested separately. + +Return value: a response object with the following properties: + +- `statusCode` - the HTTP status code. + +- `headers` - an object containing the headers set. + +- `payload` - the response payload string. + +- `rawPayload` - the raw response payload buffer. + +- `raw` - an object with the injection request and response objects: + - `req` - the simulated node request object. + - `res` - the simulated node response object. + +- `result` - the raw handler response (e.g. when not a stream or a view) before it is + serialized for transmission. If not available, the value is set to `payload`. Useful for + inspection and reuse of the internal objects returned (instead of parsing the response + string). + +- `request` - the [request object](#request). + +Throws a Boom error if the request processing fails. The partial response object is exposed on +the `data` property. + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + server.route({ method: 'GET', path: '/', handler: () => 'Success!' }); + + const res = await server.inject('/'); + console.log(res.result); // 'Success!' +} +``` + +### `server.log(tags, [data, [timestamp]])` + +Logs server events that cannot be associated with a specific request. When called the server emits +a `'log'` event which can be used by other listeners or [plugins](#plugins) to record the +information or output to the console. The arguments are: + +- `tags` - (required) a string or an array of strings (e.g. `['error', 'database', 'read']`) used + to identify the event. Tags are used instead of log levels and provide a much more expressive + mechanism for describing and filtering events. Any logs generated by the server internally + include the `'hapi'` tag along with event-specific information. + +- `data` - (optional) an message string or object with the application data being logged. If `data` + is a function, the function signature is `function()` and it called once to generate (return + value) the actual data emitted to the listeners. If no listeners match the event, the `data` + function is not invoked. + +- `timestamp` - (optional) an timestamp expressed in milliseconds. Defaults to `Date.now()` (now). + +Return value: none. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +server.events.on('log', (event, tags) => { + if (tags.error) { + console.log(event); + } +}); + +server.log(['test', 'error'], 'Test event'); +``` + +### `server.lookup(id)` + +Looks up a route configuration where: + +- `id` - the [route identifier](#route.options.id). + +Return value: the [route information](#request.route) if found, otherwise `null`. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server(); +server.route({ + method: 'GET', + path: '/', + options: { + id: 'root', + handler: () => 'ok', + }, +}); + +const route = server.lookup('root'); +``` + +### `server.match(method, path, [host])` + +Looks up a route configuration where: + +- `method` - the HTTP method (e.g. 'GET', 'POST'). +- `path` - the requested path (must begin with '/'). +- `host` - (optional) hostname (to match against routes with `vhost`). + +Return value: the [route information](#request.route) if found, otherwise `null`. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server(); +server.route({ + method: 'GET', + path: '/', + options: { + id: 'root', + handler: () => 'ok', + }, +}); + +const route = server.match('get', '/'); +``` + +### `server.method(name, method, [options])` + +Registers a [server method](#server.methods) where: + +- `name` - a unique method name used to invoke the method via [`server.methods[name]`](#server.method). + +- `method` - the method function with a signature `async function(...args, [flags])` where: + - `...args` - the method function arguments (can be any number of arguments or none). + - `flags` - when caching is enabled, an object used to set optional method result flags. This + parameter is provided automatically and can only be accessed/modified within the method + function. It cannot be passed as an argument. + - `ttl` - `0` if result is valid but cannot be cached. Defaults to cache policy. + +- `options` - (optional) configuration object: + - `bind` - a context object passed back to the method function (via `this`) when called. + Defaults to active context (set via [`server.bind()`](#server.bind()) when the method is + registered. Ignored if the method is an arrow function. + + - `cache` - the same cache configuration used in [`server.cache()`](#server.cache()). The + `generateTimeout` option is required, and the `generateFunc` options is not allowed. + + - `generateKey` - a function used to generate a unique key (for caching) from the arguments + passed to the method function (the `flags` argument is not passed as input). The server + will automatically generate a unique key if the function's arguments are all of types + `'string'`, `'number'`, or `'boolean'`. However if the method uses other types of arguments, + a key generation function must be provided which takes the same arguments as the function and + returns a unique string (or `null` if no key can be generated). + +Return value: none. + +Method names can be nested (e.g. `utils.users.get`) which will automatically create the full path +under [`server.methods`](#server.methods) (e.g. accessed via `server.methods.utils.users.get`). + +When configured with caching enabled, `server.methods[name].cache` is assigned an object with the +following properties and methods: - `await drop(...args)` - a function that can be used to clear the cache for a given key. - `stats` - an object with cache statistics, see **catbox** for stats documentation. + +Simple arguments example: + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + + const add = (a, b) => a + b; + server.method('sum', add, { + cache: { expiresIn: 2000, generateTimeout: 100 }, + }); + + console.log(await server.methods.sum(4, 5)); // 9 +} +``` + +Object argument example: + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + + const addArray = function (array) { + let sum = 0; + array.forEach((item) => { + sum += item; + }); + + return sum; + }; + + const options = { + cache: { expiresIn: 2000, generateTimeout: 100 }, + generateKey: (array) => array.join(','), + }; + + server.method('sumObj', addArray, options); + + console.log(await server.methods.sumObj([5, 6])); // 11 +} +``` + +### `server.method(methods)` + +Registers a server method function as described in [`server.method()`](#server.method()) using a +configuration object where: + +- `methods` - an object or an array of objects where each one contains: + - `name` - the method name. + - `method` - the method function. + - `options` - (optional) settings. + +Return value: none. + +```js +const add = function (a, b) { + return a + b; +}; + +server.method({ + name: 'sum', + method: add, + options: { + cache: { + expiresIn: 2000, + generateTimeout: 100, + }, + }, +}); +``` + +### `server.path(relativeTo)` + +Sets the path prefix used to locate static resources (files and view templates) when relative paths +are used where: + +- `relativeTo` - the path prefix added to any relative file path starting with `'.'`. + +Return value: none. + +Note that setting a path within a plugin only applies to resources accessed by plugin methods. +If no path is set, the server default [route configuration](#server.options.routes) +[`files.relativeTo`](#route.options.files) settings is used. The path only applies to routes added +after it has been set. + +```js +exports.plugin = { + name: 'example', + register: function (server, options) { + // Assuming the Inert plugin was registered previously + + server.path(__dirname + '../static'); + server.route({ + path: '/file', + method: 'GET', + handler: { file: './test.html' }, + }); + }, +}; +``` + +### `await server.register(plugins, [options])` + +Registers a plugin where: + +- `plugins` - one or an array of: + - a [plugin object](#plugins). + + - an object with the following: + - `plugin` - a [plugin object](#plugins). + - `options` - (optional) options passed to the plugin during registration. + - `once`, `routes` - (optional) plugin-specific registration options as defined below. + +- `options` - (optional) registration options (different from the options passed to the + registration function): + - `once` - if `true`, subsequent registrations of the same plugin are skipped without error. + Cannot be used with plugin options. Defaults to `false`. + If not set to `true`, an error will be thrown the second time a plugin is registered on the server. + + - `routes` - modifiers applied to each route added by the plugin: + - `prefix` - string added as prefix to any route path (must begin with `'/'`). If a plugin + registers a child plugin the `prefix` is passed on to the child or is added in front of + the child-specific prefix. + - `vhost` - virtual host string (or array of strings) applied to every route. The + outer-most `vhost` overrides the any nested configuration. + +Return value: none. + +```js +async function example() { + await server.register({ + plugin: require('plugin_name'), + options: { message: 'hello' }, + }); +} +``` + +### `server.route(route)` + +Adds a route where: + +- `route` - a route configuration object or an array of configuration objects where each object + contains: + - `path` - (required) the absolute path used to match incoming requests (must begin with '/'). + Incoming requests are compared to the configured paths based on the server's + [`router`](#server.options.router) configuration. The path can include named parameters + enclosed in `{}` which will be matched against literal values in the request as described in + [Path parameters](#path-parameters). + + - `method` - (required) the HTTP method. Typically one of 'GET', 'POST', 'PUT', 'PATCH', + 'DELETE', or 'OPTIONS'. Any HTTP method is allowed, except for 'HEAD'. Use `'*'` to match + against any HTTP method (only when an exact match was not found, and any match with a + specific method will be given a higher priority over a wildcard match). Can be assigned an + array of methods which has the same result as adding the same route with different methods + manually. + + - `vhost` - (optional) a domain string or an array of domain strings for limiting the route to + only requests with a matching host header field. Matching is done against the hostname part + of the header only (excluding the port). Defaults to all hosts. + + - `handler` - (required when [`handler`](#route.options.handler) is not set) the route + handler function called to generate the response after successful authentication and + validation. + + - `options` - additional [route options](#route-options). The `options` value can be an object + or a function that returns an object using the signature `function(server)` where `server` is + the server the route is being added to and `this` is bound to the current + [realm](#server.realm)'s `bind` option. + + - `rules` - route custom rules object. The object is passed to each rules processor registered + with [`server.rules()`](#server.rules()). Cannot be used if + [`route.options.rules`](#route.options.rules) is defined. + +Return value: none. + +Note that the `options` object is deeply cloned (with the exception of `bind` which is shallowly +copied) and cannot contain any values that are unsafe to perform deep copy on. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +// Handler in top level + +server.route({ method: 'GET', path: '/status', handler: () => 'ok' }); + +// Handler in config + +const user = { + cache: { expiresIn: 5000 }, + handler: function (request, h) { + return { name: 'John' }; + }, +}; + +server.route({ method: 'GET', path: '/user', options: user }); + +// An array of routes + +server.route([ + { + method: 'GET', + path: '/1', + handler: function (request, h) { + return 'ok'; + }, + }, + { + method: 'GET', + path: '/2', + handler: function (request, h) { + return 'ok'; + }, + }, +]); +``` + +#### Path parameters + +Parameterized paths are processed by matching the named parameters to the content of the incoming +request path at that path segment. For example, `'/book/{id}/cover'` will match `'/book/123/cover'` and +`request.params.id` will be set to `'123'`. Each path segment (everything between the opening `'/'` +and the closing `'/'` unless it is the end of the path) can only include one named parameter. A +parameter can cover the entire segment (`'/{param}'`) or part of the segment (`'/file.{ext}'`). A path +parameter may only contain letters, numbers and underscores, e.g. `'/{file-name}'` is invalid +and `'/{file_name}'` is valid. + +An optional `'?'` suffix following the parameter name indicates an optional parameter (only allowed +if the parameter is at the ends of the path or only covers part of the segment as in +`'/a{param?}/b'`). For example, the route `'/book/{id?}'` matches `'/book/'` with the value of +`request.params.id` set to an empty string `''`. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +const getAlbum = function (request, h) { + return ( + 'You asked for ' + + (request.params.song ? request.params.song + ' from ' : '') + + request.params.album + ); +}; + +server.route({ + path: '/{album}/{song?}', + method: 'GET', + handler: getAlbum, +}); +``` + +In addition to the optional `?` suffix, a parameter name can also specify the number of matching +segments using the `*` suffix, followed by a number greater than 1. If the number of expected parts +can be anything, then use `*` without a number (matching any number of segments can only be used in +the last path segment). + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +const getPerson = function (request, h) { + const nameParts = request.params.name.split('/'); + return { first: nameParts[0], last: nameParts[1] }; +}; + +server.route({ + path: '/person/{name*2}', // Matches '/person/john/doe' + method: 'GET', + handler: getPerson, +}); +``` + +#### Path matching order + +The router iterates through the routing table on each incoming request and executes the first (and +only the first) matching route. Route matching is done based on the combination of the request path +and the HTTP verb (e.g. 'GET, 'POST'). The query is excluded from the routing logic. Requests are +matched in a deterministic order where the order in which routes are added does not matter. + +Routes are matched based on the specificity of the route which is evaluated at each segment of the +incoming request path. Each request path is split into its segment (the parts separated by `'/'`). +The segments are compared to the routing table one at a time and are matched against the most +specific path until a match is found. If no match is found, the next match is tried. + +When matching routes, string literals (no path parameter) have the highest priority, followed by +mixed parameters (`'/a{p}b'`), parameters (`'/{p}'`), and then wildcard (`/{p*}`). + +Note that mixed parameters are slower to compare as they cannot be hashed and require an array +iteration over all the regular expressions representing the various mixed parameter at each +routing table node. + +#### Catch all route + +If the application needs to override the default Not Found (404) error response, it can add a +catch-all route for a specific method or all methods. Only one catch-all route can be defined. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +const handler = function (request, h) { + return h.response('The page was not found').code(404); +}; + +server.route({ method: '*', path: '/{p*}', handler }); +``` + +### `server.rules(processor, [options])` + +Defines a route rules processor for converting route rules object into route configuration where: + +- `processor` - a function using the signature `function(rules, info)` where: + - `rules` - the [custom object](#route.options.rules) defined in your routes configuration for you to use its values. + - `info` - an object with the following properties: + - `method` - the route method. + - `path` - the route path. + - `vhost` - the route virtual host (if any defined). + - returns a route config object. + +- `options` - optional settings: + - `validate` - rules object validation: + - `schema` - **joi** schema. + - `options` - optional **joi** validation options. Defaults to `{ allowUnknown: true }`. + +Note that the root server and each plugin server instance can only register one rules processor. +If a route is added after the rules are configured, it will not include the rules config. Routes +added by plugins apply the rules to each of the parent realms' rules from the root to the route's +realm. This means the processor defined by the plugin overrides the config generated by the root +processor if they overlap. Similarly, the route's own config overrides the config produced by the rules processors. + +```js +const validateSchema = { + auth: Joi.string(), + myCustomPre: Joi.array().min(2).items(Joi.string()), + payload: Joi.object(), +}; + +const myPreHelper = (name) => { + return { + method: (request, h) => { + return `hello ${name || 'world'}!`; + }, + assign: 'myPreHelper', + }; +}; + +const processor = (rules, info) => { + if (!rules) { + return null; + } + + const options = {}; + + if (rules.auth) { + options.auth = { + strategy: rules.auth, + validate: { + entity: 'user', + }, + }; + } + + if (rules.myCustomPre) { + options.pre = [myPreHelper(...rules.myCustomPre)]; + } + + if (rules.payload) { + options.validate = { payload: Joi.object(rules.payload) }; + } + + return options; +}; + +server.rules(processor, { + validate: { schema: validateSchema }, +}); + +server.route({ + method: 'GET', + path: '/', + rules: { + auth: 'jwt', + myCustomPre: ['arg1', 'arg2'], + payload: { a: Joi.boolean(), b: Joi.string() }, + }, + options: { + id: 'my-route', + }, +}); +``` + +### `await server.start()` + +Starts the server by listening for incoming requests on the configured port (unless the connection +was configured with [`autoListen`](#server.options.autoListen) set to `false`). + +Return value: none. + +Note that if the method fails and throws an error, the server is considered to be in an undefined +state and should be shut down. In most cases it would be impossible to fully recover as the various +plugins, caches, and other event listeners will get confused by repeated attempts to start the +server or make assumptions about the healthy state of the environment. It is recommended to abort +the process when the server fails to start properly. If you must try to resume after an error, call +[`server.stop()`](#server.stop()) first to reset the server state. + +If a started server is started again, the second call to `server.start()` is ignored. No events +will be emitted and no extension points invoked. + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + await server.start(); + console.log('Server started at: ' + server.info.uri); +} +``` + +### `server.state(name, [options])` + +[HTTP state management](https://tools.ietf.org/html/rfc6265) uses client cookies to persist a state +across multiple requests. Registers a cookie definitions where: + +- `name` - the cookie name string. + +- `options` - are the optional cookie settings: + - `ttl` - time-to-live in milliseconds. Defaults to `null` (session time-life - cookies are deleted when the browser is closed). + + - `isSecure` - sets the 'Secure' flag. Defaults to `true`. + + - `isHttpOnly` - sets the 'HttpOnly' flag. Defaults to `true`. + + - `isSameSite` - sets the ['SameSite' flag](https://www.owasp.org/index.php/SameSite). The value must be one of: + - `false` - no flag. + - `'Strict'` - sets the value to `'Strict'` (this is the default value). + - `'Lax'` - sets the value to `'Lax'`. + - `'None'` - sets the value to `'None'`. + + - `path` - the path scope. Defaults to `null` (no path). + + - `domain` - the domain scope. Defaults to `null` (no domain). + + - `autoValue` - if present and the cookie was not received from the client or explicitly set by the route handler, the cookie is automatically added to the response with the provided value. The value can be a function with signature `async function(request)` where: + - `request` - the [request object](#request). + + - `encoding` - encoding performs on the provided value before serialization. Options are: + - `'none'` - no encoding. When used, the cookie value must be a string. This is the default value. + - `'base64'` - string value is encoded using Base64. + - `'base64json'` - object value is JSON-stringified then encoded using Base64. + - `'form'` - object value is encoded using the _x-www-form-urlencoded_ method. + - `'iron'` - Encrypts and sign the value using [**iron**](https://hapi.dev/family/iron/api). + + - `sign` - an object used to calculate an HMAC for cookie integrity validation. This does not provide privacy, only a mean to verify that the cookie value was generated by the server. Redundant when `'iron'` encoding is used. Options are: + - `integrity` - algorithm options. Defaults to [`require('iron').defaults.integrity`](https://hapi.dev/family/iron/api/#options). + - `password` - password used for HMAC key generation (must be at least 32 characters long). + + - `password` - password used for `'iron'` encoding (must be at least 32 characters long). + + - `iron` - options for `'iron'` encoding. Defaults to [`require('iron').defaults`](https://hapi.dev/family/iron/api/#options). + + - `ignoreErrors` - if `true`, errors are ignored and treated as missing cookies. + + - `clearInvalid` - if `true`, automatically instruct the client to remove invalid cookies. Defaults to `false`. + + - `strictHeader` - if `false`, allows any cookie value including values in violation of [RFC 6265](https://tools.ietf.org/html/rfc6265). Defaults to `true`. + + - `passThrough` - used by proxy plugins (e.g. [**h2o2**](https://hapi.dev/family/h2o2/api)). + + - `contextualize` - a function using the signature `async function(definition, request)` used to override a request-specific cookie settings where: + - `definition` - a copy of the `options` to be used for formatting the cookie that can be manipulated by the function to customize the request cookie header. Note that changing the `definition.contextualize` property will be ignored. + - `request` - the current request object. + +Return value: none. + +State defaults can be modified via the [server.options.state](#server.options.state) configuration +option. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +// Set cookie definition + +server.state('session', { + ttl: 24 * 60 * 60 * 1000, // One day + isSecure: true, + path: '/', + encoding: 'base64json', +}); + +// Set state in route handler + +const handler = function (request, h) { + let session = request.state.session; + if (!session) { + session = { user: 'joe' }; + } + + session.last = Date.now(); + + return h.response('Success').state('session', session); +}; +``` + +Registered cookies are automatically parsed when received. Parsing rules depends on the route +[`state.parse`](#route.options.state) configuration. If an incoming registered cookie fails parsing, +it is not included in [`request.state`](#request.state), regardless of the +[`state.failAction`](#route.options.state.failAction) setting. When [`state.failAction`](#route.options.state.failAction) +is set to `'log'` and an invalid cookie value is received, the server will emit a +[`'request'` event](#server.events.request). To capture these errors subscribe to the `'request'` +event on the `'internal'` channel and filter on `'error'` and `'state'` tags: + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +server.events.on( + { name: 'request', channels: 'internal' }, + (request, event, tags) => { + if (tags.error && tags.state) { + console.error(event); + } + }, +); +``` + +### `server.states.add(name, [options])` + +Access: read only. + +Same as calling [`server.state()`](#server.state()). + +### `await server.states.format(cookies)` + +Formats an HTTP 'Set-Cookie' header based on the [`server.options.state`](#server.options.state) +where: + +- `cookies` - a single object or an array of object where each contains: + - `name` - the cookie name. + - `value` - the cookie value. + - `options` - cookie configuration to override the server settings. + +Return value: a header string. + +Note that this utility uses the server configuration but does not change the server state. It is +provided for manual cookie formatting (e.g. when headers are set manually). + +### `await server.states.parse(header)` + +Parses an HTTP 'Cookies' header based on the [`server.options.state`](#server.options.state) where: + +- `header` - the HTTP header. + +Return value: an object where each key is a cookie name and value is the parsed cookie. + +Note that this utility uses the server configuration but does not change the server state. It is +provided for manual cookie parsing (e.g. when server parsing is disabled). + +### `await server.stop([options])` + +Stops the server's listener by refusing to accept any new connections or requests (existing +connections will continue until closed or timeout), where: + +- `options` - (optional) object with: + - `timeout` - sets the timeout in millisecond before forcefully terminating any open + connections that arrived before the server stopped accepting new connections. The timeout + only applies to waiting for existing connections to close, and not to any + [`'onPreStop'` or `'onPostStop'` server extensions](#server.ext.args()) which can + delay or block the stop operation indefinitely. Ignored if + [`server.options.operations.cleanStop`](#server.options.operations) is `false`. Note that if + the server is set as a [group controller](#server.control()), the timeout is per controlled + server and the controlling server itself. Defaults to `5000` (5 seconds). + +Return value: none. + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + await server.start(); + await server.stop({ timeout: 60 * 1000 }); + console.log('Server stopped'); +} +``` + +### `server.table([host])` + +Returns a copy of the routing table where: + +- `host` - (optional) host to filter routes matching a specific virtual host. Defaults to all + virtual hosts. + +Return value: an array of routes where each route contains: + +- `settings` - the route config with defaults applied. +- `method` - the HTTP method in lower case. +- `path` - the route path. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); +server.route({ method: 'GET', path: '/example', handler: () => 'ok' }); + +const table = server.table(); +``` + +### `server.validator(validator)` + +Registers a server validation module used to compile raw validation rules into validation schemas for all routes where: + +- `validator` - the validation module (e.g. **joi**). + +Return value: none. + +Note: the validator is only used when validation rules are not pre-compiled schemas. When a validation rules is a function or schema object, the rule is used as-is and the validator is not used. When setting a validator inside a plugin, the validator is only applied to routes set up by the plugin and plugins registered by it. + +```js +const Hapi = require('@hapi/hapi'); +const Joi = require('joi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + server.validator(Joi); +} +``` + +## Route options + +Each route can be customized to change the default behavior of the request lifecycle. + +### `route.options.app` + +Application-specific route configuration state. Should not be used by [plugins](#plugins) which +should use `options.plugins[name]` instead. + +### `route.options.auth` + +Route authentication configuration. Value can be: + +- `false` to disable authentication if a default strategy is set. + +- a string with the name of an authentication strategy registered with + [`server.auth.strategy()`](#server.auth.strategy()). The strategy will be + set to `'required'` mode. + +- an [authentication configuration object](#authentication-options). + +#### `route.options.auth.access` + +Default value: none. + +An object or array of objects specifying the route access rules. Each rule is evaluated against an +incoming request and access is granted if at least one of the rules matches. Each rule object must +include at least one of [`scope`](#route.options.auth.access.scope) or +[`entity`](#route.options.auth.access.entity). + +#### `route.options.auth.access.scope` + +Default value: `false` (no scope requirements). + +The application scope required to access the route. Value can be a scope string or an +array of scope strings. When authenticated, the credentials object `scope` property must contain +at least one of the scopes defined to access the route. + +If a scope string begins with a `+` character, that scope is required. If a scope string begins +with a `!` character, that scope is forbidden. For example, the scope `['!a', '+b', 'c', 'd']` +means the incoming request credentials' `scope` must not include 'a', must include 'b', and must +include one of 'c' or 'd'. + +You may also access properties on the request object (`query`, `params`, `payload`, and +`credentials`) to populate a dynamic scope by using the '{' and '}' characters around the property +name, such as `'user-{params.id}'`. + +#### `route.options.auth.access.entity` + +Default value: `'any'`. + +The required authenticated entity type. If set, must match the `entity` value of the request +authenticated credentials. Available values: + +- `'any'` - the authentication can be on behalf of a user or application. +- `'user'` - the authentication must be on behalf of a user which is identified by the presence of + a `'user'` attribute in the `credentials` object returned by the authentication strategy. +- `'app'` - the authentication must be on behalf of an application which is identified by the lack + of presence of a `user` attribute in the `credentials` object returned by the authentication + strategy. + +#### `route.options.auth.mode` + +Default value: `'required'`. + +The authentication mode. Available values: + +- `'required'` - authentication is required. +- `'optional'` - authentication is optional - the request must include valid credentials or no + credentials at all. +- `'try'` - similar to `'optional'`, any request credentials are attempted authentication, but if + the credentials are invalid, the request proceeds regardless of the authentication error. + +#### `route.options.auth.payload` + +Default value: `false`, unless the scheme requires payload authentication. + +If set, the incoming request payload is authenticated after it is processed. Requires a strategy +with payload authentication support (e.g. [Hawk](https://hapi.dev/family/hawk/api)). Cannot be +set to a value other than `'required'` when the scheme sets the authentication `options.payload` to +`true`. + +Available values: + +- `false` - no payload authentication. +- `'required'` - payload authentication required. +- `'optional'` - payload authentication performed only when the client includes payload + authentication information (e.g. `hash` attribute in Hawk). + +#### `route.options.auth.strategies` + +Default value: the default strategy set via [`server.auth.default()`](#server.auth.default()). + +An array of string strategy names in the order they should be attempted. Cannot be used together +with [`strategy`](#route.options.auth.strategy). + +#### `route.options.auth.strategy` + +Default value: the default strategy set via [`server.auth.default()`](#server.auth.default()). + +A string strategy names. Cannot be used together with [`strategies`](#route.options.auth.strategies). + +### `route.options.bind` + +Default value: `null`. + +An object passed back to the provided `handler` (via `this`) when called. Ignored if the method is +an arrow function. + +### `route.options.cache` + +Default value: `{ privacy: 'default', statuses: [200], otherwise: 'no-cache' }`. + +If the route method is 'GET', the route can be configured to include HTTP caching directives in the +response. Caching can be customized using an object with the following options: + +- `privacy` - determines the privacy flag included in client-side caching using the 'Cache-Control' + header. Values are: + - `'default'` - no privacy flag. + - `'public'` - mark the response as suitable for public caching. + - `'private'` - mark the response as suitable only for private caching. + +- `expiresIn` - relative expiration expressed in the number of milliseconds since the + item was saved in the cache. Cannot be used together with `expiresAt`. + +- `expiresAt` - time of day expressed in 24h notation using the 'HH:MM' format, at which + point all cache records for the route expire. Cannot be used together with `expiresIn`. + +- `statuses` - an array of HTTP response status code numbers (e.g. `200`) which are allowed to + include a valid caching directive. + +- `otherwise` - a string with the value of the 'Cache-Control' header when caching is disabled. + +The default `Cache-Control: no-cache` header can be disabled by setting `cache` to `false`. + +### `route.options.compression` + +An object where each key is a content-encoding name and each value is an object with the desired +encoder settings. Note that decoder settings are set in [`compression`](#route.options.payload.compression). + +### `route.options.cors` + +Default value: `false` (no CORS headers). + +The [Cross-Origin Resource Sharing](https://www.w3.org/TR/cors/) protocol allows browsers to make +cross-origin API calls. CORS is required by web applications running inside a browser which are +loaded from a different domain than the API server. To enable, set `cors` to `true`, or to an +object with the following options: + +- `origin` - an array of allowed origin servers strings ('Access-Control-Allow-Origin'). The array + can contain any combination of fully qualified origins along with origin strings containing a + wildcard `'*'` character, or a single `'*'` origin string. If set to `'ignore'`, any incoming + Origin header is ignored (present or not) and the 'Access-Control-Allow-Origin' header is set to + `'*'`. Defaults to any origin `['*']`. + +- `maxAge` - number of seconds the browser should cache the CORS response + ('Access-Control-Max-Age'). The greater the value, the longer it will take before the browser + checks for changes in policy. Defaults to `86400` (one day). + +- `headers` - a strings array of allowed headers ('Access-Control-Allow-Headers'). Defaults to + `['Accept', 'Authorization', 'Content-Type', 'If-None-Match']`. + +- `additionalHeaders` - a strings array of additional headers to `headers`. Use this to keep the + default headers in place. + +- `exposedHeaders` - a strings array of exposed headers ('Access-Control-Expose-Headers'). + Defaults to `['WWW-Authenticate', 'Server-Authorization']`. + +- `additionalExposedHeaders` - a strings array of additional headers to `exposedHeaders`. Use this + to keep the default headers in place. + +- `credentials` - if `true`, allows user credentials to be sent + ('Access-Control-Allow-Credentials'). Defaults to `false`. + +### `route.options.description` + +Default value: none. + +Route description used for generating documentation (string). + +This setting is not available when setting server route defaults using +[`server.options.routes`](#server.options.routes). + +### `route.options.ext` + +Default value: none. + +Route-level [request extension points](#request-lifecycle) by setting the option to an object with +a key for each of the desired extension points (`'onRequest'` is not allowed), and the value is the +same as the [`server.ext(events)`](#server.ext()) `event` argument. + +### `route.options.files` + +Default value: `{ relativeTo: '.' }`. + +Defines the behavior for accessing files: + +- `relativeTo` - determines the folder relative paths are resolved against. + +### `route.options.handler` + +Default value: none. + +The route handler function performs the main business logic of the route and sets the response. +`handler` can be assigned: + +- a [lifecycle method](#lifecycle-methods). + +- an object with a single property using the name of a handler type registered with the + [`server.decorate()`](#server.decorate()) method. The matching property value is passed + as options to the registered handler generator. + +```js +const handler = function (request, h) { + return 'success'; +}; +``` + +Note: handlers using a fat arrow style function cannot be bound to any `bind` property. Instead, +the bound context is available under [`h.context`](#h.context). + +### `route.options.id` + +Default value: none. + +An optional unique identifier used to look up the route using [`server.lookup()`](#server.lookup()). +Cannot be assigned to routes added with an array of methods. + +### `route.options.isInternal` + +Default value: `false`. + +If `true`, the route cannot be accessed through the HTTP listener but only through the +[`server.inject()`](#server.inject()) interface with the `allowInternals` option set to `true`. +Used for internal routes that should not be accessible to the outside world. + +### `route.options.json` + +Default value: none. + +Optional arguments passed to `JSON.stringify()` when converting an object or error response to a +string payload or escaping it after stringification. Supports the following: + +- `replacer` - the replacer function or array. Defaults to no action. + +- `space` - number of spaces to indent nested object keys. Defaults to no indentation. + +- `suffix` - string suffix added after conversion to JSON string. Defaults to no suffix. + +- `escape` - calls [`Hoek.jsonEscape()`](https://hapi.dev/family/hoek/api/#escapejsonstring) + after conversion to JSON string. Defaults to `false`. + +### `route.options.jsonp` + +Default value: none. + +Enables JSONP support by setting the value to the query parameter name containing the function name +used to wrap the response payload. + +For example, if the value is `'callback'`, a request comes in with `'callback=me'`, and the JSON +response is `'{ "a":"b" }'`, the payload will be `'me({ "a":"b" });'`. Cannot be used with stream +responses. + +The 'Content-Type' response header is set to `'text/javascript'` and the 'X-Content-Type-Options' +response header is set to `'nosniff'`, and will override those headers even if explicitly set by +[`response.type()`](#response.type()). + +### `route.options.log` + +Default value: `{ collect: false }`. + +Request logging options: + +- `collect` - if `true`, request-level logs (both internal and application) are collected and + accessible via [`request.logs`](#request.logs). + +### `route.options.notes` + +Default value: none. + +Route notes used for generating documentation (string or array of strings). + +This setting is not available when setting server route defaults using +[`server.options.routes`](#server.options.routes). + +### `route.options.payload` + +Determines how the request payload is processed. + +#### `route.options.payload.allow` + +Default value: allows parsing of the following mime types: + +- application/json +- application/\*+json +- application/octet-stream +- application/x-www-form-urlencoded +- multipart/form-data +- text/\* + +A string or an array of strings with the allowed mime types for the endpoint. Use this settings to +limit the set of allowed mime types. Note that allowing additional mime types not listed above will +not enable them to be parsed, and if [`parse`](#route.options.payload.parse) is `true`, the request +will result in an error response. + +#### `route.options.payload.compression` + +Default value: none. + +An object where each key is a content-encoding name and each value is an object with the desired +decoder settings. Note that encoder settings are set in [`compression`](#server.options.compression). + +#### `route.options.payload.defaultContentType` + +Default value: `'application/json'`. + +The default content type if the 'Content-Type' request header is missing. + +#### `route.options.payload.failAction` + +Default value: `'error'` (return a Bad Request (400) error response). + +A [`failAction` value](#lifecycle-failAction) which determines how to handle payload parsing +errors. + +#### `route.options.payload.maxBytes` + +Default value: `1048576` (1MB). + +Limits the size of incoming payloads to the specified byte count. Allowing very large payloads may +cause the server to run out of memory. + +#### `route.options.payload.maxParts` + +Default value: `1000`. + +Limits the number of parts allowed in multipart payloads. + +#### `route.options.payload.multipart` + +Default value: `false`. + +Overrides payload processing for multipart requests. Value can be one of: + +- `false` - disable multipart processing (this is the default value). + +- `true` - enable multipart processing using the [`output`](#route.options.payload.output) value. + +- an object with the following required options: + - `output` - same as the [`output`](#route.options.payload.output) option with an additional + value option: + - `annotated` - wraps each multipart part in an object with the following keys: + - `headers` - the part headers. + - `filename` - the part file name. + - `payload` - the processed part payload. + +#### `route.options.payload.output` + +Default value: `'data'`. + +The processed payload format. The value must be one of: + +- `'data'` - the incoming payload is read fully into memory. If [`parse`](#route.options.payload.parse) + is `true`, the payload is parsed (JSON, form-decoded, multipart) based on the 'Content-Type' + header. If [`parse`](#route.options.payload.parse) is `false`, a raw `Buffer` is returned. + +- `'stream'` - the incoming payload is made available via a `Stream.Readable` interface. If the + payload is 'multipart/form-data' and [`parse`](#route.options.payload.parse) is `true`, field + values are presented as text while files are provided as streams. File streams from a + 'multipart/form-data' upload will also have a `hapi` property containing the `filename` and + `headers` properties. Note that payload streams for multipart payloads are a synthetic interface + created on top of the entire multipart content loaded into memory. To avoid loading large + multipart payloads into memory, set [`parse`](#route.options.payload.parse) to `false` and handle + the multipart payload in the handler using a streaming parser (e.g. [**pez**](https://hapi.dev/family/pez/api)). + +- `'file'` - the incoming payload is written to temporary file in the directory specified by the + [`uploads`](#route.options.payload.uploads) settings. If the payload is 'multipart/form-data' and + [`parse`](#route.options.payload.parse) is `true`, field values are presented as text while files + are saved to disk. Note that it is the sole responsibility of the application to clean up the + files generated by the framework. This can be done by keeping track of which files are used (e.g. + using the `request.app` object), and listening to the server `'response'` event to perform + cleanup. + +#### `route.options.payload.override` + +Default value: none. + +A mime type string overriding the 'Content-Type' header value received. + +#### `route.options.payload.parse` + +Default value: `true`. + +Determines if the incoming payload is processed or presented raw. Available values: + +- `true` - if the request 'Content-Type' matches the allowed mime types set by + [`allow`](#route.options.payload.allow) (for the whole payload as well as parts), the payload is + converted into an object when possible. If the format is unknown, a Bad Request (400) error + response is sent. Any known content encoding is decoded. + +- `false` - the raw payload is returned unmodified. + +- `'gunzip'` - the raw payload is returned unmodified after any known content encoding is decoded. + +#### `route.options.payload.protoAction` + +Default value: `'error'`. + +Sets handling of incoming payload that may contain a prototype poisoning security attack. Available +values: + +- `'error'` - returns a `400` bad request error when the payload contains a prototype. + +- `'remove'` - sanitizes the payload to remove the prototype. + +- `'ignore'` - disables the protection and allows the payload to pass as received. Use this option + only when you are sure that such incoming data cannot pose any risks to your application. + +#### `route.options.payload.timeout` + +Default value: to `10000` (10 seconds). + +Payload reception timeout in milliseconds. Sets the maximum time allowed for the client to transmit +the request payload (body) before giving up and responding with a Request Timeout (408) error +response. + +Set to `false` to disable. + +#### `route.options.payload.uploads` + +Default value: `os.tmpdir()`. + +The directory used for writing file uploads. + +### `route.options.plugins` + +Default value: `{}`. + +Plugin-specific configuration. `plugins` is an object where each key is a plugin name and the value +is the plugin configuration. + +### `route.options.pre` + +Default value: none. + +The `pre` option allows defining methods for performing actions before the handler is called. These +methods allow breaking the handler logic into smaller, reusable components that can be shared +across routes, as well as provide a cleaner error handling of prerequisite operations (e.g. load +required reference data from a database). + +`pre` is assigned an ordered array of methods which are called serially in order. If the `pre` +array contains another array of methods as one of its elements, those methods are called in +parallel. Note that during parallel execution, if any of the methods error, return a +[takeover response](#takeover-response), or abort signal, the other parallel methods will continue +to execute but will be ignored once completed. + +`pre` can be assigned a mixed array of: + +- an array containing the elements listed below, which are executed in parallel. + +- an object with: + - `method` - a [lifecycle method](#lifecycle-methods). + - `assign` - key name used to assign the response of the method to in [`request.pre`](#request.pre) + and [`request.preResponses`](#request.preResponses). + - `failAction` - A [`failAction` value](#lifecycle-failAction) which determine what to do when + a pre-handler method throws an error. If `assign` is specified and the `failAction` setting + is not `'error'`, the error will be assigned. + +- a method function - same as including an object with a single `method` key. + +Note that pre-handler methods do not behave the same way other [lifecycle methods](#lifecycle-methods) +do when a value is returned. Instead of the return value becoming the new response payload, the +value is used to assign the corresponding [`request.pre`](#request.pre) and +[`request.preResponses`](#request.preResponses) properties. Otherwise, the handling of errors, +[takeover response](#takeover-response) response, or abort signal behave the same as any other +[lifecycle methods](#lifecycle-methods). + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +const pre1 = function (request, h) { + return 'Hello'; +}; + +const pre2 = function (request, h) { + return 'World'; +}; + +const pre3 = function (request, h) { + return request.pre.m1 + ' ' + request.pre.m2; +}; + +server.route({ + method: 'GET', + path: '/', + options: { + pre: [ + [ + // m1 and m2 executed in parallel + { method: pre1, assign: 'm1' }, + { method: pre2, assign: 'm2' }, + ], + { method: pre3, assign: 'm3' }, + ], + handler: function (request, h) { + return request.pre.m3 + '!\n'; + }, + }, +}); +``` + +### `route.options.response` + +Processing rules for the outgoing response. + +#### `route.options.response.disconnectStatusCode` + +Default value: `499`. + +The default HTTP status code used to set a response error when the request is closed or aborted +before the response is fully transmitted. Value can be any integer greater or equal to `400`. The +default value `499` is based on the non-standard nginx "CLIENT CLOSED REQUEST" error. The value is +only used for logging as the request has already ended. + +#### `route.options.response.emptyStatusCode` + +Default value: `204`. + +The default HTTP status code when the payload is considered empty. Value can be `200` or `204`. +Note that a `200` status code is converted to a `204` only at the time of response transmission +(the response status code will remain `200` throughout the request lifecycle unless manually set). + +#### `route.options.response.failAction` + +Default value: `'error'` (return an Internal Server Error (500) error response). + +A [`failAction` value](#lifecycle-failAction) which defines what to do when a response fails +payload validation. + +#### `route.options.response.modify` + +Default value: `false`. + +If `true`, applies the validation rule changes to the response payload. + +#### `route.options.response.options` + +Default value: none. + +[**joi**](https://joi.dev/api) options object pass to the validation function. Useful to set global options such as `stripUnknown` or `abortEarly`. If a custom validation function is defined via [`schema`](#route.options.response.schema) or [`status`](#route.options.response.status) then `options` can an arbitrary object that will be passed to this function as the second argument. + +#### `route.options.response.ranges` + +Default value: `true`. + +If `false`, payload [range](https://tools.ietf.org/html/rfc7233#section-3) support is disabled. + +#### `route.options.response.sample` + +Default value: `100` (all responses). + +The percent of response payloads validated (0 - 100). Set to `0` to disable all validation. + +#### `route.options.response.schema` + +Default value: `true` (no validation). + +The default response payload validation rules (for all non-error responses) expressed as one of: + +- `true` - any payload allowed (no validation). + +- `false` - no payload allowed. + +- a [**joi**](https://joi.dev/api) validation object. The [`options`](#route.options.response.options) + along with the request context (`{ headers, params, query, payload, state, app, auth }`) are passed to + the validation function. + +- a validation function using the signature `async function(value, options)` where: + - `value` - the pending response payload. + - `options` - The [`options`](#route.options.response.options) along with the request context + (`{ headers, params, query, payload, state, app, auth }`). + + - if the function returns a value and [`modify`](#route.options.response.modify) is `true`, + the value is used as the new response. If the original response is an error, the return + value is used to override the original error `output.payload`. If an error is thrown, the + error is processed according to [`failAction`](#route.options.response.failAction). + +#### `route.options.response.status` + +Default value: none. + +Validation schemas for specific HTTP status codes. Responses (excluding errors) not matching the +listed status codes are validated using the default [`schema`](#route.options.response.schema). + +`status` is set to an object where each key is a 3 digit HTTP status code and the value has the +same definition as [`schema`](#route.options.response.schema). + +### `route.options.rules` + +Default value: none. + +A custom rules object passed to each rules processor registered with [`server.rules()`](#server.rules()). + +### `route.options.security` + +Default value: `false` (security headers disabled). + +Sets common security headers. To enable, set `security` to `true` or to an object with the +following options: + +- `hsts` - controls the 'Strict-Transport-Security' header, where: + - `true` - the header will be set to `max-age=15768000`. This is the default value. + - a number - the maxAge parameter will be set to the provided value. + + - an object with the following fields: + - `maxAge` - the max-age portion of the header, as a number. Default is `15768000`. + - `includeSubDomains` - a boolean specifying whether to add the `includeSubDomains` flag to + the header. + - `preload` - a boolean specifying whether to add the `'preload'` flag (used to submit + domains inclusion in Chrome's HTTP Strict Transport Security (HSTS) preload list) to the + header. + +- `xframe` - controls the 'X-Frame-Options' header, where: + - `true` - the header will be set to `'DENY'`. This is the default value. + - `'deny'` - the headers will be set to `'DENY'`. + - `'sameorigin'` - the headers will be set to `'SAMEORIGIN'`. + + - an object for specifying the 'allow-from' rule, where: + - `rule` - one of: + - `'deny'` + - `'sameorigin'` + - `'allow-from'` + - `source` - when `rule` is `'allow-from'` this is used to form the rest of the header, + otherwise this field is ignored. If `rule` is `'allow-from'` but `source` is unset, the + rule will be automatically changed to `'sameorigin'`. + +- `xss` - boolean that controls the 'X-XSS-PROTECTION' header for Internet Explorer. Defaults to + `true` which sets the header to equal `'1; mode=block'`. + - Note: this setting can create a security vulnerability in versions of Internet Exploere below + 8, as well as unpatched versions of IE8. See [here](https://hackademix.net/2009/11/21/ies-xss-filter-creates-xss-vulnerabilities/) + and [here](https://technet.microsoft.com/library/security/ms10-002) for more information. If + you actively support old versions of IE, it may be wise to explicitly set this flag to + `false`. + +- `noOpen` - boolean controlling the 'X-Download-Options' header for Internet Explorer, preventing + downloads from executing in your context. Defaults to `true` setting the header to `'noopen'`. + +- `noSniff` - boolean controlling the 'X-Content-Type-Options' header. Defaults to `true` setting + the header to its only and default option, `'nosniff'`. + +- `referrer` - controls the ['Referrer-Policy'](https://www.w3.org/TR/referrer-policy/) header, which has the following possible values. + - `false` - the 'Referrer-Policy' header will not be sent to clients with responses. This is the default value. + - `''` - instructs clients that the Referrer-Policy will be [defined elsewhere](https://www.w3.org/TR/referrer-policy/#referrer-policy-empty-string), such as in a meta html tag. + - `'no-referrer'` - instructs clients to never include the referrer header when making requests. + - `'no-referrer-when-downgrade'` - instructs clients to never include the referrer when navigating from HTTPS to HTTP. + - `'same-origin'` - instructs clients to only include the referrer on the current site origin. + - `'origin'` - instructs clients to include the referrer but strip off path information so that the value is the current origin only. + - `'strict-origin'` - same as `'origin'` but instructs clients to omit the referrer header when going from HTTPS to HTTP. + - `'origin-when-cross-origin'` - instructs clients to include the full path in the referrer header for same-origin requests but only the origin components of the URL are included for cross origin requests. + - `'strict-origin-when-cross-origin'` - same as `'origin-when-cross-origin'` but the client is instructed to omit the referrer when going from HTTPS to HTTP. + - `'unsafe-url'` - instructs the client to always include the referrer with the full URL. + +### `route.options.state` + +Default value: `{ parse: true, failAction: 'error' }`. + +HTTP state management (cookies) allows the server to store information on the client which is sent +back to the server with every request (as defined in [RFC 6265](https://tools.ietf.org/html/rfc6265)). +`state` supports the following options: + +- `parse` - determines if incoming 'Cookie' headers are parsed and stored in the + [`request.state`](#request.state) object. + +- `failAction` - A [`failAction` value](#lifecycle-failAction) which determines how to handle + cookie parsing errors. Defaults to `'error'` (return a Bad Request (400) error response). + +### `route.options.tags` + +Default value: none. + +Route tags used for generating documentation (array of strings). + +This setting is not available when setting server route defaults using +[`server.options.routes`](#server.options.routes). + +### `route.options.timeout` + +Default value: `{ server: false }`. + +Timeouts for processing durations. + +#### `route.options.timeout.server` + +Default value: `false`. + +Response timeout in milliseconds. Sets the maximum time allowed for the server to respond to an +incoming request before giving up and responding with a Service Unavailable (503) error response. + +#### `route.options.timeout.socket` + +Default value: none (use node default of 2 minutes). + +By default, node sockets automatically timeout after 2 minutes. Use this option to override this +behavior. Set to `false` to disable socket timeouts. + +### `route.options.validate` + +Default value: `{ headers: true, params: true, query: true, payload: true, state: true, failAction: 'error' }`. + +Request input validation rules for various request components. + +#### `route.options.validate.errorFields` + +Default value: none. + +An optional object with error fields copied into every validation error response. + +#### `route.options.validate.failAction` + +Default value: `'error'` (return a Bad Request (400) error response). + +A [`failAction` value](#lifecycle-failAction) which determines how to handle failed validations. +When set to a function, the `err` argument includes the type of validation error under +`err.output.payload.validation.source`. + +#### `route.options.validate.headers` + +Default value: `true` (no validation). + +Validation rules for incoming request headers: + +- `true` - any headers allowed (no validation performed). + +- a [**joi**](https://joi.dev/api) validation object. + +- a validation function using the signature `async function(value, options)` where: + - `value` - the [`request.headers`](#request.headers) object containing the request headers. + - `options` - [`options`](#route.options.validate.options). + - if a value is returned, the value is used as the new [`request.headers`](#request.headers) + value and the original value is stored in [`request.orig.headers`](#request.orig). + Otherwise, the headers are left unchanged. If an error is thrown, the error is handled + according to [`failAction`](#route.options.validate.failAction). + +Note that all header field names must be in lowercase to match the headers normalized by node. + +#### `route.options.validate.options` + +Default value: none. + +An options object passed to the [**joi**](https://joi.dev/api) rules or the custom +validation methods. Used for setting global options such as `stripUnknown` or `abortEarly`. + +If a custom validation function (see `headers`, `params`, `query`, or `payload` above) is defined +then `options` can an arbitrary object that will be passed to this function as the second +parameter. + +The values of the other inputs (i.e. `headers`, `query`, `params`, `payload`, `state`, `app`, and `auth`) +are added to the `options` object under the validation `context` (accessible in rules as +`Joi.ref('$query.key')`). + +Note that validation is performed in order (i.e. headers, params, query, and payload) and if type +casting is used (e.g. converting a string to a number), the value of inputs not yet validated will +reflect the raw, unvalidated and unmodified values. + +If the validation rules for `headers`, `params`, `query`, and `payload` are defined at both the +server [`routes`](#server.options.routes) level and at the route level, the individual route +settings override the routes defaults (the rules are not merged). + +#### `route.options.validate.params` + +Default value: `true` (no validation). + +Validation rules for incoming request path parameters, after matching the path against the route, +extracting any parameters, and storing them in [`request.params`](#request.params), where: + +- `true` - any path parameter value allowed (no validation performed). + +- a [**joi**](https://joi.dev/api) validation object. + +- a validation function using the signature `async function(value, options)` where: + - `value` - the [`request.params`](#request.params) object containing the request path + parameters. + - `options` - [`options`](#route.options.validate.options). + - if a value is returned, the value is used as the new [`request.params`](#request.params) + value and the original value is stored in [`request.orig.params`](#request.orig). Otherwise, + the path parameters are left unchanged. If an error is thrown, the error is handled according + to [`failAction`](#route.options.validate.failAction). + +Note that failing to match the validation rules to the route path parameters definition will cause +all requests to fail. + +#### `route.options.validate.payload` + +Default value: `true` (no validation). + +Validation rules for incoming request payload (request body), where: + +- `true` - any payload allowed (no validation performed). + +- `false` - no payload allowed. + +- a [**joi**](https://joi.dev/api) validation object. + - Note that empty payloads are represented by a `null` value. If a validation schema is + provided and empty payload are allowed, the schema must be explicitly defined by setting the + rule to a **joi** schema with `null` allowed (e.g. + `Joi.object({ /* keys here */ }).allow(null)`). + +- a validation function using the signature `async function(value, options)` where: + - `value` - the [`request.payload`](#request.payload) object containing the request payload. + - `options` - [`options`](#route.options.validate.options). + - if a value is returned, the value is used as the new [`request.payload`](#request.payload) + value and the original value is stored in [`request.orig.payload`](#request.orig). Otherwise, + the payload is left unchanged. If an error is thrown, the error is handled according to + [`failAction`](#route.options.validate.failAction). + +Note that validating large payloads and modifying them will cause memory duplication of the payload +(since the original is kept), as well as the significant performance cost of validating large +amounts of data. + +#### `route.options.validate.query` + +Default value: `true` (no validation). + +Validation rules for incoming request URI query component (the key-value part of the URI between +'?' and '#'). The query is parsed into its individual key-value pairs, decoded, and stored in +[`request.query`](#request.query) prior to validation. Where: + +- `true` - any query parameter value allowed (no validation performed). + +- `false` - no query parameter value allowed. + +- a [**joi**](https://joi.dev/api) validation object. + +- a validation function using the signature `async function(value, options)` where: + - `value` - the [`request.query`](#request.query) object containing the request query + parameters. + - `options` - [`options`](#route.options.validate.options). + - if a value is returned, the value is used as the new [`request.query`](#request.query) value + and the original value is stored in [`request.orig.query`](#request.orig). Otherwise, the + query parameters are left unchanged. If an error is thrown, the error is handled according to + [`failAction`](#route.options.validate.failAction). + +Note that changes to the query parameters will not be reflected in [`request.url`](#request.url). + +#### `route.options.validate.state` + +Default value: `true` (no validation). + +Validation rules for incoming cookies. The `cookie` header is parsed and decoded into the +[`request.state`](#request.state) prior to validation. Where: + +- `true` - any cookie value allowed (no validation performed). + +- `false` - no cookies allowed. + +- a [**joi**](https://joi.dev/api) validation object. + +- a validation function using the signature `async function(value, options)` where: + - `value` - the [`request.state`](#request.state) object containing all parsed cookie values. + - `options` - [`options`](#route.options.validate.options). + - if a value is returned, the value is used as the new [`request.state`](#request.state) value + and the original value is stored in [`request.orig.state`](#request.orig). Otherwise, the + cookie values are left unchanged. If an error is thrown, the error is handled according to + [`failAction`](#route.options.validate.failAction). + +#### `route.options.validate.validator` + +Default value: `null` (no default validator). + +Sets a server validation module used to compile raw validation rules into validation schemas (e.g. **joi**). + +Note: the validator is only used when validation rules are not pre-compiled schemas. When a validation rules is a function or schema object, the rule is used as-is and the validator is not used. + +## Request lifecycle + +Each incoming request passes through the request lifecycle. The specific steps vary based on the +server and route configurations, but the order in which the applicable steps are executed is always +the same. The following is the complete list of steps a request can go through: + +- _**onRequest**_ + - always called when `onRequest` extensions exist. + - the request path and method can be modified via the [`request.setUrl()`](#request.setUrl()) and [`request.setMethod()`](#request.setMethod()) methods. Changes to the request path or method will impact how the request is routed and can be used for rewrite rules. + - [`request.payload`](#request.payload) is `undefined` and can be overridden with any non-`undefined` value to bypass payload processing. + - [`request.route`](#request.route) is unassigned. + - [`request.url`](#request.url) can be `null` if the incoming request path is invalid. + - [`request.path`](#request.path) can be an invalid path. + - JSONP configuration is ignored for any response returned from the extension point since no + route is matched yet and the JSONP configuration is unavailable. + +- _**Route lookup**_ + - lookup based on `request.path` and `request.method`. + - skips to _**onPreResponse**_ if no route is found or if the path violates the HTTP + specification. + +- _**JSONP processing**_ + - based on the route [`jsonp`](#route.options.jsonp) option. + - parses JSONP parameter from [`request.query`](#request.query). + - skips to _**Response validation**_ on error. + +- _**Cookies processing**_ + - based on the route [`state`](#route.options.state) option. + - error handling based on [`failAction`](#route.options.state.failAction). + +- _**onPreAuth**_ + - called regardless if authentication is performed. + +- _**Authentication**_ + - based on the route [`auth`](#route.options.auth) option. + +- _**Payload processing**_ + - based on the route [`payload`](#route.options.payload) option and if [`request.payload`](#request.payload) has not been overridden in _**onRequest**_. + - error handling based on [`failAction`](#route.options.payload.failAction). + +- _**Payload authentication**_ + - based on the route [`auth`](#route.options.auth) option. + +- _**onCredentials**_ + - called only if authentication is performed. + +- _**Authorization**_ + - based on the route authentication [`access`](#route.options.auth.access) option. + +- _**onPostAuth**_ + - called regardless if authentication is performed. + +- _**Headers validation**_ + - based on the route [`validate.headers`](#route.options.validate.headers) option. + - error handling based on [`failAction`](#route.options.validate.failAction). + +- _**Path parameters validation**_ + - based on the route [`validate.params`](#route.options.validate.params) option. + - error handling based on [`failAction`](#route.options.validate.failAction). + +- _**JSONP cleanup**_ + - based on the route [`jsonp`](#route.options.jsonp) option. + - remove the JSONP parameter from [`request.query`](#request.query). + +- _**Query validation**_ + - based on the route [`validate.query`](#route.options.validate.query) option. + - error handling based on [`failAction`](#route.options.validate.failAction). + +- _**Payload validation**_ + - based on the route [`validate.payload`](#route.options.validate.payload) option. + - error handling based on [`failAction`](#route.options.validate.failAction). + +- _**State validation**_ + - based on the route [`validate.state`](#route.options.validate.state) option. + - error handling based on [`failAction`](#route.options.validate.failAction). + +- _**onPreHandler**_ + +- _**Pre-handler methods**_ + - based on the route [`pre`](#route.options.pre) option. + - error handling based on each pre-handler method's `failAction` setting. + +- _**Route handler**_ + - executes the route [`handler`](#route.options.handler). + +- _**onPostHandler**_ + - the response contained in [`request.response`](#request.response) may be modified (but not + assigned a new value). To return a different response type (for example, replace an error + with an HTML response), return a new response value. + +- _**Response validation**_ + - error handling based on [`failAction`](#route.options.response.failAction). + +- _**onPreResponse**_ + - always called, unless the request is aborted. + - the response contained in [`request.response`](#request.response) may be modified (but not + assigned a new value). To return a different response type (for example, replace an error + with an HTML response), return a new response value. Note that any errors generated will not + be passed back to _**onPreResponse**_ to prevent an infinite loop. + +- _**Response transmission**_ + - may emit a [`'request'` event](#server.events.request) on the `'error'` channel. + +- _**Finalize request**_ + - emits `'response'` event. + +- _**onPostResponse**_ + - return value is ignored since the response is already set. + - emits a [`'request'` event](#server.events.request) on the `'error'` channel if an error is returned. + - all extension handlers are executed even if some error. + - note that since the handlers are executed in serial (each is `await`ed), care must be taken to avoid blocking execution if other extension handlers expect to be called immediately when the response is sent. If an _**onPostResponse**_ handler is performing IO, it should defer that activity to another tick and return immediately (either without a return value or without a promise that is solve to resolve). + +### Lifecycle methods + +Lifecycle methods are the interface between the framework and the application. Many of the request +lifecycle steps: [extensions](#server.ext()), [authentication](#authentication-scheme), +[handlers](#route.options.handler), [pre-handler methods](#route.options.pre), and +[`failAction` function values](#lifecycle-failAction) are lifecyle methods provided by the +developer and executed by the framework. + +Each lifecycle method is a function with the signature `await function(request, h, [err])` where: + +- `request` - the [request object](#request). +- `h` - the [response toolkit](#response-toolkit) the handler must call to set a response and + return control back to the framework. +- `err` - an error object available only when the method is used as a + [`failAction` value](#lifecycle-failAction). + +Each lifecycle method must return a value or a promise that resolves into a value. If a lifecycle +method returns without a value or resolves to an `undefined` value, an Internal Server Error (500) +error response is sent. + +The return value must be one of: + +- Plain value: + - `null` + - string + - number + - boolean +- `Buffer` object +- `Error` object + - plain `Error`. + - a [`Boom`](https://hapi.dev/family/boom/api) object. +- `Stream` object + - must be compatible with the "streams2" API and not be in `objectMode`. + - if the stream object has a `statusCode` property, that status code will be used as + the default response code based on the [`passThrough`](#response.settings.passThrough) + option. + - if the stream object has a `headers` property, the headers will be included in the response + based on the [`passThrough`](#response.settings.passThrough) option. + - if the stream object has a function property `setCompressor(compressor)` and the response + passes through a compressor, a reference to the compressor stream will be passed to the + response stream via this method. +- any object or array + - must not include circular references. +- a toolkit signal: + - [`h.abandon`](#h.abandon) - abort processing the request. + - [`h.close`](#h.close) - abort processing the request and call `end()` to ensure the response + is closed. + - [`h.continue`](#h.continue) - continue processing the request lifecycle without changing the + response. +- a toolkit method response: + - [`h.response()`](#h.response()) - wraps a plain response in a [response object](#response-object). + - [`h.redirect()`](#h.redirect()) - wraps a plain response with a redirection directive. + - [`h.authenticated()`](#h.authenticated()) - indicate request authenticated successfully + (auth scheme only). + - [`h.unauthenticated()`](#h.unauthenticated()) - indicate request failed to authenticate + (auth scheme only). +- a promise object that resolve to any of the above values + +Any error thrown by a lifecycle method will be used as the [response object](#response-object). While errors and valid +values can be returned, it is recommended to throw errors. Throwing non-error values will generate +a Bad Implementation (500) error response. + +```js +const handler = function (request, h) { + if (request.query.forbidden) { + throw Boom.badRequest(); + } + + return 'success'; +}; +``` + +If the route has a [`bind`](#route.options.bind) option or [`server.bind()`](#server.bind()) was +called, the lifecycle method will be bound to the provided context via `this` as well as accessible +via [`h.context`](#h.context). + +#### Lifecycle workflow + +The flow between each lifecycle step depends on the value returned by each lifecycle method as +follows: + +- an error: + - the lifecycle skips to the _**Response validation**_ step. + - if returned by the _**onRequest**_ step it skips to the _**onPreResponse**_ step. + - if returned by the _**Response validation**_ step it skips to the _**onPreResponse**_ step. + - if returned by the _**onPreResponse**_ step it skips to the _**Response transmission**_ step. + +- an abort signal ([`h.abandon`](#h.abandon) or [`h.close`](#h.close)): + - skips to the _**Finalize request**_ step. + +- a [`h.continue`](#h.continue) signal: + - continues processing the request lifecycle without changing the request response. + - cannot be used by the [`authenticate()`](#authentication-scheme) scheme method. + +- a [takeover response](#takeover-response): + - overrides the request response with the provided value and skips to the + _**Response validation**_ step. + - if returned by the _**Response validation**_ step it skips to the _**onPreResponse**_ step. + - if returned by the _**onPreResponse**_ step it skips to the _**Response transmission**_ step. + +- any other response: + - overrides the request response with the provided value and continues processing the request + lifecycle. + - cannot be returned from any step prior to the _**Pre-handler methods**_ step. + +The [`authenticate()`](#authentication-scheme) method has access to two additional return values: - [`h.authenticated()`](#h.authenticated()) - indicate request authenticated successfully. - [`h.unauthenticated()`](#h.unauthenticated()) - indicate request failed to authenticate. + +Note that these rules apply somewhat differently when used in a [pre-handler method](#route.options.pre). + +#### Takeover response + +A takeover response is a [`response object`](#response-object) on which [`response.takeover()`](#response.takever()) +was called to signal that the [lifecycle method](#lifecycle-methods) return value should be set as +the response and skip to immediately validate and trasmit the value, bypassing other lifecycle +steps. + +#### `failAction` configuration + +Various configuration options allows defining how errors are handled. For example, when invalid +payload is received or malformed cookie, instead of returning an error, the framework can be +configured to perform another action. When supported the `failAction` option supports the following +values: + +- `'error'` - return the error object as the response. +- `'log'` - report the error but continue processing the request. +- `'ignore'` - take no action and continue processing the request. + +- a [lifecycle method](#lifecycle-methods) with the signature `async function(request, h, err)` + where: + - `request` - the [request object](#request). + - `h` - the [response toolkit](#response-toolkit). + - `err` - the error object. + +#### Errors + +**hapi** uses the [**boom**](https://hapi.dev/family/boom/api) error library for all its internal +error generation. **boom** provides an expressive interface to return HTTP errors. Any error +thrown by a [lifecycle method](#lifecycle-methods) is converted into a **boom** object and defaults to status +code `500` if the error is not already a **boom** object. + +When the error is sent back to the client, the response contains a JSON object with the +`statusCode`, `error`, and `message` keys. + +```js +const Hapi = require('@hapi/hapi'); +const Boom = require('@hapi/boom'); + +const server = Hapi.server(); + +server.route({ + method: 'GET', + path: '/badRequest', + handler: function (request, h) { + throw Boom.badRequest('Unsupported parameter'); // 400 + }, +}); + +server.route({ + method: 'GET', + path: '/internal', + handler: function (request, h) { + throw new Error('unexpect error'); // 500 + }, +}); +``` + +##### Error transformation + +Errors can be customized by changing their `output` content. The **boom** error object includes the +following properties: + +- `isBoom` - if `true`, indicates this is a `Boom` object instance. + +- `message` - the error message. + +- `output` - the formatted response. Can be directly manipulated after object construction to + return a custom error response. Allowed root keys: + - `statusCode` - the HTTP status code (typically 4xx or 5xx). + + - `headers` - an object containing any HTTP headers where each key is a header name and value + is the header content. + + - `payload` - the formatted object used as the response payload. Can be directly + manipulated but any changes will be lost + if `reformat()` is called. Any content allowed and by default includes the following content: + - `statusCode` - the HTTP status code, derived from `error.output.statusCode`. + + - `error` - the HTTP status message (e.g. 'Bad Request', 'Internal Server Error') derived + from `statusCode`. + + - `message` - the error message derived from `error.message`. + +- inherited `Error` properties. + +It also supports the following method: + +- `reformat()` - rebuilds `error.output` using the other object properties. + +```js +const Boom = require('@hapi/boom'); + +const handler = function (request, h) { + + const error = Boom.badRequest('Cannot feed after midnight'); + error.output.statusCode = 499; // Assign a custom error code + error.reformat(); + error.output.payload.custom = 'abc_123'; // Add custom key + throw error; +}); +``` + +When a different error representation is desired, such as an HTML page or a different payload +format, the `'onPreResponse'` extension point may be used to identify errors and replace them with +a different [response object](#response-object), as in this example using [Vision's](https://hapi.dev/family/vision/api) +`.view()` [response toolkit](#response-toolkit) property. + +```js +const Hapi = require('@hapi/hapi'); +const Vision = require('@hapi/vision'); + +const server = Hapi.server({ port: 80 }); +server.register(Vision, (err) => { + server.views({ + engines: { + html: require('handlebars'), + }, + }); +}); + +const preResponse = function (request, h) { + const response = request.response; + if (!response.isBoom) { + return h.continue; + } + + // Replace error with friendly HTML + + const error = response; + const ctx = { + message: + error.output.statusCode === 404 + ? 'page not found' + : 'something went wrong', + }; + + return h.view('error', ctx).code(error.output.statusCode); +}; + +server.ext('onPreResponse', preResponse); +``` + +### Response Toolkit + +Access: read only. + +The response toolkit is a collection of properties and utilities passed to every +[lifecycle method](#lifecycle-methods). It is somewhat hard to define as it provides both +utilities for manipulating responses as well as other information. Since the toolkit is passed +as a function argument, developers can name it whatever they want. For the purpose of this document +the `h` notation is used. It is named in the spirit of the RethinkDB `r` method, with `h` for +**h**api. + +#### Toolkit properties + +##### `h.abandon` + +Access: read only. + +A response symbol. When returned by a lifecycle method, the request lifecycle skips to the +finalizing step without further interaction with the node response stream. It is the developer's +responsibility to write and end the response directly via [`request.raw.res`](#request.raw). + +##### `h.close` + +Access: read only. + +A response symbol. When returned by a lifecycle method, the request lifecycle skips to the +finalizing step after calling `request.raw.res.end())` to close the the node response stream. + +##### `h.context` + +Access: read / write (will impact the shared context if the object is modified). + +A response symbol. Provides access to the route or server context set via the route +[`bind`](#route.options.bind) option or [`server.bind()`](#server.bind()). + +##### `h.continue` + +Access: read only. + +A response symbol. When returned by a lifecycle method, the request lifecycle continues without +changing the response. + +##### `h.realm` + +Access: read only. + +The [server realm](#server.realm) associated with the matching route. Defaults to the root server +realm in the _**onRequest**_ step. + +##### `h.request` + +Access: read only and public request interface. + +The [request] object. This is a duplication of the `request` lifecycle method argument used by +[toolkit decorations](#server.decorate()) to access the current request. + +#### `h.authenticated(data)` + +Used by the [authentication] method to pass back valid credentials where: + +- `data` - an object with: + - `credentials` - (required) object representing the authenticated entity. + - `artifacts` - (optional) authentication artifacts object specific to the authentication + scheme. + +Return value: an internal authentication object. + +#### `h.entity(options)` + +Sets the response 'ETag' and 'Last-Modified' headers and checks for any conditional request headers +to decide if the response is going to qualify for an HTTP 304 (Not Modified). If the entity values +match the request conditions, `h.entity()` returns a [response object](#response-object) for the lifecycle method to +return as its value which will set a 304 response. Otherwise, it sets the provided entity headers +and returns `undefined`. The method arguments are: + +- `options` - a required configuration object with: + - `etag` - the ETag string. Required if `modified` is not present. Defaults to no header. + - `modified` - the Last-Modified header value. Required if `etag` is not present. Defaults to + no header. + - `vary` - same as the [`response.etag()`](#response.etag()) option. Defaults to `true`. + +Return value: - a [response object](#response-object) if the response is unmodified. - `undefined` if the response has changed. + +If `undefined` is returned, the developer must return a valid lifecycle method value. If a response +is returned, it should be used as the return value (but may be customize using the response +methods). + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +server.route({ + method: 'GET', + path: '/', + options: { + cache: { expiresIn: 5000 }, + handler: function (request, h) { + const response = h.entity({ etag: 'abc' }); + if (response) { + response.header('X', 'y'); + return response; + } + + return 'ok'; + }, + }, +}); +``` + +#### `h.redirect(uri)` + +Redirects the client to the specified uri. Same as calling `h.response().redirect(uri)`. + +Returns a [response object](#response-object). + +```js +const handler = function (request, h) { + return h.redirect('http://example.com'); +}; +``` + +#### `h.response([value])` + +Wraps the provided value and returns a [`response`](#response-object) object which allows +customizing the response (e.g. setting the HTTP status code, custom headers, etc.), where: + +- `value` - (optional) return value. Defaults to `null`. + +Returns a [response object](#response-object). + +```js +// Detailed notation + +const handler = function (request, h) { + const response = h.response('success'); + response.type('text/plain'); + response.header('X-Custom', 'some-value'); + return response; +}; + +// Chained notation + +const handler = function (request, h) { + return h + .response('success') + .type('text/plain') + .header('X-Custom', 'some-value'); +}; +``` + +#### `h.state(name, value, [options])` + +Sets a response cookie using the same arguments as [`response.state()`](#response.state()). + +Return value: none. + +```js +const ext = function (request, h) { + h.state('cookie-name', 'value'); + return h.continue; +}; +``` + +#### `h.unauthenticated(error, [data])` + +Used by the [authentication] method to indicate authentication failed and pass back the credentials +received where: + +- `error` - (required) the authentication error. +- `data` - (optional) an object with: + - `credentials` - (required) object representing the authenticated entity. + - `artifacts` - (optional) authentication artifacts object specific to the authentication + scheme. + +The method is used to pass both the authentication error and the credentials. For example, if a +request included expired credentials, it allows the method to pass back the user information +(combined with a `'try'` authentication [`mode`](#route.options.auth.mode)) for error customization. + +There is no difference between throwing the error or passing it with the `h.unauthenticated()` +method if no credentials are passed, but it might still be helpful for code clarity. + +#### `h.unstate(name, [options])` + +Clears a response cookie using the same arguments as [`response.unstate()`](#response.unstate()). + +```js +const ext = function (request, h) { + h.unstate('cookie-name'); + return h.continue; +}; +``` + +### Response object + +The response object contains the request response value along with various HTTP headers and flags. +When a [lifecycle method](#lifecycle-methods) returns a value, the value is wrapped in a response +object along with some default flags (e.g. `200` status code). In order to customize a response +before it is returned, the [`h.response()`](#h.response()) method is provided. + +#### Response properties + +##### `response.app` + +Access: read / write. + +Default value: `{}`. + +Application-specific state. Provides a safe place to store application data without potential +conflicts with the framework. Should not be used by [plugins](#plugins) which should use +[`plugins[name]`](#response.plugins). + +##### `response.contentType` + +Access: read. + +Default value: none. + +Provides a preview of the response HTTP Content-Type header based on the implicit response type, any explicit Content-Type header set, and any content character-set defined. The returned value is only a preview as the content type can change later both internally and by user code (it represents current response state). The value is `null` if no implicit type can be determined. + +##### `response.events` + +Access: read only and the public **podium** interface. + +The `response.events` object supports the following events: + +- `'peek'` - emitted for each chunk of data written back to the client connection. The event method + signature is `function(chunk, encoding)`. + +- `'finish'` - emitted when the response finished writing but before the client response connection + is ended. The event method signature is `function ()`. + +```js +const Crypto = require('crypto'); +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +const preResponse = function (request, h) { + const response = request.response; + if (response.isBoom) { + return null; + } + + const hash = Crypto.createHash('sha1'); + response.events.on('peek', (chunk) => { + hash.update(chunk); + }); + + response.events.once('finish', () => { + console.log(hash.digest('hex')); + }); + + return h.continue; +}; + +server.ext('onPreResponse', preResponse); +``` + +##### `response.headers` + +Access: read only. + +Default value: `{}`. + +An object containing the response headers where each key is a header field name and the value is +the string header value or array of string. + +Note that this is an incomplete list of headers to be included with the response. Additional +headers will be added once the response is prepared for transmission. + +##### `response.plugins` + +Access: read / write. + +Default value: `{}`. + +Plugin-specific state. Provides a place to store and pass request-level plugin data. `plugins` is +an object where each key is a plugin name and the value is the state. + +##### `response.settings` + +Access: read only. + +Object containing the response handling flags. + +###### `response.settings.passThrough` + +Access: read only. + +Defaults value: `true`. + +If `true` and [`source`](#response.source) is a `Stream`, copies the `statusCode` and `headers` +properties of the stream object to the outbound response. + +###### `response.settings.stringify` + +Access: read only. + +Default value: `null` (use route defaults). + +Override the route [`json`](#route.options.json) options used when [`source`](#response.source) +value requires stringification. + +###### `response.settings.ttl` + +Access: read only. + +Default value: `null` (use route defaults). + +If set, overrides the route [`cache`](#route.options.cache) with an expiration value in +milliseconds. + +###### `response.settings.varyEtag` + +Default value: `false`. + +If `true`, a suffix will be automatically added to the 'ETag' header at transmission time +(separated by a `'-'` character) when the HTTP 'Vary' header is present. + +##### `response.source` + +Access: read only. + +The raw value returned by the [lifecycle method](#lifecycle-methods). + +##### `response.statusCode` + +Access: read only. + +Default value: `200`. + +The HTTP response status code. + +##### `response.variety` + +Access: read only. + +A string indicating the type of [`source`](#response.source) with available values: + +- `'plain'` - a plain response such as string, number, `null`, or simple object. +- `'buffer'` - a `Buffer`. +- `'stream'` - a `Stream`. + +#### `response.bytes(length)` + +Sets the HTTP 'Content-Length' header (to avoid chunked transfer encoding) where: + +- `length` - the header value. Must match the actual payload size. + +Return value: the current response object. + +#### `response.charset(charset)` + +Sets the 'Content-Type' HTTP header 'charset' property where: + +- `charset` - the charset property value. When `charset` value is falsy, it will prevent hapi from using its default charset setting. + +Return value: the current response object. + +#### `response.code(statusCode)` + +Sets the HTTP status code where: + +- `statusCode` - the HTTP status code (e.g. 200). + +Return value: the current response object. + +#### `response.message(httpMessage)` + +Sets the HTTP status message where: + +- `httpMessage` - the HTTP status message (e.g. 'Ok' for status code 200). + +Return value: the current response object. + +#### `response.compressed(encoding)` + +Sets the HTTP 'content-encoding' header where: + +- `encoding` - the header value string. + +Return value: the current response object. + +Note that setting content encoding via this method does not set a 'vary' HTTP header with 'accept-encoding' value. To vary the response, use the `response.header()` method instead. + +#### `response.created(uri)` + +Sets the HTTP status code to Created (201) and the HTTP 'Location' header where: + +- `uri` - an absolute or relative URI used as the 'Location' header value. + +Return value: the current response object. + +#### `response.encoding(encoding)` + +Sets the string encoding scheme used to serial data into the HTTP payload where: + +- `encoding` - the encoding property value (see [node Buffer encoding](https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings)). + +Return value: the current response object. + +#### `response.etag(tag, options)` + +Sets the representation [entity tag](https://tools.ietf.org/html/rfc7232#section-2.3) where: + +- `tag` - the entity tag string without the double-quote. + +- `options` - (optional) settings where: + - `weak` - if `true`, the tag will be prefixed with the `'W/'` weak signifier. Weak tags will + fail to match identical tags for the purpose of determining 304 response status. Defaults to + `false`. + + - `vary` - if `true` and content encoding is set or applied to the response (e.g 'gzip' or + 'deflate'), the encoding name will be automatically added to the tag at transmission time + (separated by a `'-'` character). Ignored when `weak` is `true`. Defaults to `true`. + +Return value: the current response object. + +#### `response.header(name, value, options)` + +Sets an HTTP header where: + +- `name` - the header name. + +- `value` - the header value. + +- `options` - (optional) object where: + - `append` - if `true`, the value is appended to any existing header value using `separator`. + Defaults to `false`. + + - `separator` - string used as separator when appending to an existing value. Defaults to `','`. + + - `override` - if `false`, the header value is not set if an existing value present. Defaults + to `true`. + + - `duplicate` - if `false`, the header value is not modified if the provided value is already + included. Does not apply when `append` is `false` or if the `name` is `'set-cookie'`. + Defaults to `true`. + +Return value: the current response object. + +#### `response.location(uri)` + +Sets the HTTP 'Location' header where: + +- `uri` - an absolute or relative URI used as the 'Location' header value. + +Return value: the current response object. + +#### `response.redirect(uri)` + +Sets an HTTP redirection response (302) and decorates the response with additional methods, where: + +- `uri` - an absolute or relative URI used to redirect the client to another resource. + +Return value: the current response object. + +Decorates the response object with the [`response.temporary()`](#response.temporary()), +[`response.permanent()`](#response.permanent()), and [`response.rewritable()`](#response.rewritable()) +methods to easily change the default redirection code (302). + +| | Permanent | Temporary | +| -------------- | --------- | --------- | +| Rewritable | 301 | 302 | +| Non-rewritable | 308 | 307 | + +#### `response.replacer(method)` + +Sets the `JSON.stringify()` `replacer` argument where: + +- `method` - the replacer function or array. Defaults to none. + +Return value: the current response object. + +#### `response.spaces(count)` + +Sets the `JSON.stringify()` `space` argument where: + +- `count` - the number of spaces to indent nested object keys. Defaults to no indentation. + +Return value: the current response object. + +#### `response.state(name, value, [options])` + +Sets an HTTP cookie where: + +- `name` - the cookie name. + +- `value` - the cookie value. If no `options.encoding` is defined, must be a string. See + [`server.state()`](#server.state()) for supported `encoding` values. + +- `options` - (optional) configuration. If the state was previously registered with the server + using [`server.state()`](#server.state()), the specified keys in `options` are merged with the + default server definition. + +Return value: the current response object. + +#### `response.suffix(suffix)` + +Sets a string suffix when the response is process via `JSON.stringify()` where: + +- `suffix` - the string suffix. + +Return value: the current response object. + +#### `response.ttl(msec)` + +Overrides the default route cache expiration rule for this response instance where: + +- `msec` - the time-to-live value in milliseconds. + +Return value: the current response object. + +#### `response.type(mimeType)` + +Sets the HTTP 'Content-Type' header where: + +- `mimeType` - is the mime type. + +Return value: the current response object. + +Should only be used to override the built-in default for each response type. + +#### `response.unstate(name, [options])` + +Clears the HTTP cookie by setting an expired value where: + +- `name` - the cookie name. +- `options` - (optional) configuration for expiring cookie. If the state was previously registered + with the server using [`server.state()`](#serverstatename-options), the specified `options` are + merged with the server definition. + +Return value: the current response object. + +#### `response.vary(header)` + +Adds the provided header to the list of inputs affected the response generation via the HTTP 'Vary' +header where: + +- `header` - the HTTP request header name. + +Return value: the current response object. + +#### `response.takeover()` + +Marks the response object as a [takeover response](#takeover-response). + +Return value: the current response object. + +#### `response.temporary(isTemporary)` + +Sets the status code to `302` or `307` (based on the [`response.rewritable()`](#response.rewriteable()) +setting) where: + +- `isTemporary` - if `false`, sets status to permanent. Defaults to `true`. + +Return value: the current response object. + +Only available after calling the [`response.redirect()`](#response.redirect()) method. + +#### `response.permanent(isPermanent)` + +Sets the status code to `301` or `308` (based on the [`response.rewritable()`](#response.rewritable()) +setting) where: + +- `isPermanent` - if `false`, sets status to temporary. Defaults to `true`. + +Return value: the current response object. + +Only available after calling the [`response.redirect()`](#response.redirect()) method. + +#### `response.rewritable(isRewritable)` + +Sets the status code to `301`/`302` for rewritable (allows changing the request method from 'POST' +to 'GET') or `307`/`308` for non-rewritable (does not allow changing the request method from 'POST' +to 'GET'). Exact code based on the [`response.temporary()`](#response.temporary()) or +[`response.permanent()`](#response.permanent()) setting. Arguments: + +- `isRewritable` - if `false`, sets to non-rewritable. Defaults to `true`. + +Return value: the current response object. + +Only available after calling the [`response.redirect()`](#response.redirect()) method. + +## Request + +The request object is created internally for each incoming request. It is not the same object +received from the node HTTP server callback (which is available via [`request.raw.req`](#request.raw)). +The request properties change throughout the [request lifecycle](#request-lifecycle). + +### Request properties + +#### `request.app` + +Access: read / write. + +Application-specific state. Provides a safe place to store application data without potential +conflicts with the framework. Should not be used by [plugins](#plugins) which should use +`plugins[name]`. + +#### `request.auth` + +Access: read only. + +Authentication information: + +- `artifacts` - an artifact object received from the authentication strategy and used in + authentication-related actions. + +- `credentials` - the `credential` object received during the authentication process. The + presence of an object does not mean successful authentication. + +- `error` - the authentication error if failed and mode set to `'try'`. + +- `isAuthenticated` - `true` if the request has been successfully authenticated, otherwise `false`. + +- `isAuthorized` - `true` is the request has been successfully authorized against the route + authentication [`access`](#route.options.auth.access) configuration. If the route has not + access rules defined or if the request failed authorization, set to `false`. + +- `isInjected` - `true` if the request has been authenticated via the + [`server.inject()`](#server.inject()) `auth` option, otherwise `undefined`. + +- `mode` - the route authentication mode. + +- `strategy` - the name of the strategy used. + +#### `request.events` + +Access: read only and the public **podium** interface. + +The `request.events` supports the following events: + +- `'peek'` - emitted for each chunk of payload data read from the client connection. The event + method signature is `function(chunk, encoding)`. + +- `'finish'` - emitted when the request payload finished reading. The event method signature is + `function ()`. + +- `'disconnect'` - emitted when a request errors or aborts unexpectedly. + +```js +const Crypto = require('crypto'); +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +const onRequest = function (request, h) { + const hash = Crypto.createHash('sha1'); + request.events.on('peek', (chunk) => { + hash.update(chunk); + }); + + request.events.once('finish', () => { + console.log(hash.digest('hex')); + }); + + request.events.once('disconnect', () => { + console.error('request aborted'); + }); + + return h.continue; +}; + +server.ext('onRequest', onRequest); +``` + +#### `request.headers` + +Access: read only. + +The raw request headers (references `request.raw.req.headers`). + +#### `request.info` + +Access: read only. + +Request information: + +- `acceptEncoding` - the request preferred encoding. + +- `completed` - request processing completion timestamp (`0` is still processing). + +- `cors` - request CORS information (available only after the `'onRequest'` extension point as CORS + is configured per-route and no routing decisions are made at that point in the request + lifecycle), where: + - `isOriginMatch` - `true` if the request 'Origin' header matches the configured CORS + restrictions. Set to `false` if no 'Origin' header is found or if it does not match. + +- `host` - content of the HTTP 'Host' header (e.g. 'example.com:8080'). + +- `hostname` - the hostname part of the 'Host' header (e.g. 'example.com'). + +- `id` - a unique request identifier (using the format '{now}:{server.info.id}:{5 digits counter}'). + +- `received` - request reception timestamp. + +- `referrer` - content of the HTTP 'Referrer' (or 'Referer') header. + +- `remoteAddress` - remote client IP address. + +- `remotePort` - remote client port. + +- `responded` - request response timestamp (`0` is not responded yet or response failed when `completed` is set). + +Note that the `request.info` object is not meant to be modified. + +#### `request.isInjected` + +Access: read only. + +`true` if the request was created via [`server.inject()`](#server.inject()), and `false` otherwise. + +#### `request.logs` + +Access: read only. + +An array containing the logged request events. + +Note that this array will be empty if route [`log.collect`](#route.options.log) is set to `false`. + +#### `request.method` + +Access: read only. + +The request method in lower case (e.g. `'get'`, `'post'`). + +#### `request.mime` + +Access: read only. + +The parsed content-type header. Only available when payload parsing enabled and no payload error occurred. + +#### `request.orig` + +Access: read only. + +An object containing the values of `params`, `query`, `payload` and `state` before any validation modifications made. Only set when input validation is performed. + +#### `request.params` + +Access: read only. + +An object where each key is a path parameter name with matching value as described in [Path parameters](#path-parameters). + +#### `request.paramsArray` + +Access: read only. + +An array containing all the path `params` values in the order they appeared in the path. + +#### `request.path` + +Access: read only. + +The request URI's [pathname](https://nodejs.org/api/url.html#url_urlobject_pathname) component. + +#### `request.payload` + +Access: read only / write in `'onRequest'` extension method. + +The request payload based on the route `payload.output` and `payload.parse` settings. Set to `undefined` in `'onRequest'` extension methods and can be overridden to any non-`undefined` value to bypass payload processing. + +#### `request.plugins` + +Access: read / write. + +Plugin-specific state. Provides a place to store and pass request-level plugin data. The `plugins` is an object where each key is a plugin name and the value is the state. + +#### `request.pre` + +Access: read only. + +An object where each key is the name assigned by a [route pre-handler methods](#route.options.pre) function. The values are the raw values provided to the continuation function as argument. For the wrapped response object, use `responses`. + +#### `request.response` + +Access: read / write (see limitations below). + +The response object when set. The object can be modified but must not be assigned another object. To replace the response with another from within an [extension point](#server.ext()), return a new response value. Contains an error when a request terminates prematurely when the client disconnects. + +#### `request.preResponses` + +Access: read only. + +Same as `pre` but represented as the response object created by the pre method. + +#### `request.query` + +Access: read only. + +An object where each key is a query parameter name and each matching value is the parameter value or an array of values if a parameter repeats. Can be modified indirectly via [request.setUrl](#request.setUrl()). + +#### `request.raw` + +Access: read only. + +An object containing the Node HTTP server objects. **Direct interaction with these raw objects is not recommended.** + +- `req` - the node request object. +- `res` - the node response object. + +#### `request.route` + +Access: read only. + +The request route information object, where: + +- `method` - the route HTTP method. +- `path` - the route path. +- `vhost` - the route vhost option if configured. +- `realm` - the [active realm](#server.realm) associated with the route. +- `settings` - the [route options](#route-options) object with all defaults applied. +- `fingerprint` - the route internal normalized string representing the normalized path. + +#### `request.server` + +Access: read only and the public server interface. + +The server object. + +#### `request.state` + +Access: read only. + +An object containing parsed HTTP state information (cookies) where each key is the cookie name and value is the matching cookie content after processing using any registered cookie definition. + +#### `request.url` + +Access: read only. + +The parsed request URI. + +### `request.generateResponse(source, [options])` + +Returns a [`response`](#response-object) which you can pass to [h.response()](#h.response()) where: + +- `source` - the value to set as the source of [h.response()](#h.response()), optional. +- `options` - optional object with the following optional properties: + - `variety` - a sting name of the response type (e.g. `'file'`). + - `prepare` - a function with the signature `async function(response)` used to prepare the response after it is returned by a [lifecycle method](#lifecycle-methods) such as setting a file descriptor, where: + - `response` - the response object being prepared. + - must return the prepared response object (`response`). + - may throw an error which is used as the prepared response. + - `marshal` - a function with the signature `async function(response)` used to prepare the response for transmission to the client before it is sent, where: + - `response` - the response object being marshaled. + - must return the prepared value (not as response object) which can be any value accepted by the [`h.response()`](#h.response()) `value` argument. + - may throw an error which is used as the marshaled value. + - `close` - a function with the signature `function(response)` used to close the resources opened by the response object (e.g. file handlers), where: + - `response` - the response object being marshaled. + - should not throw errors (which are logged but otherwise ignored). + +### `request.active()` + +Returns `true` when the request is active and processing should continue and `false` when the request terminated early or completed its lifecycle. Useful when request processing is a resource-intensive operation and should be terminated early if the request is no longer active (e.g. client disconnected or aborted early). + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +server.route({ + method: 'POST', + path: '/worker', + handler: function (request, h) { + // Do some work... + + // Check if request is still active + if (!request.active()) { + return h.close; + } + + // Do some more work... + + return null; + }, +}); +``` + +### `request.log(tags, [data])` + +Logs request-specific events. When called, the server emits a [`'request'` event](#server.events.request) +on the `'app'` channel which can be used by other listeners or [plugins](#plugins). The arguments +are: + +- `tags` - a string or an array of strings (e.g. `['error', 'database', 'read']`) used to identify + the event. Tags are used instead of log levels and provide a much more expressive mechanism for + describing and filtering events. +- `data` - (optional) an message string or object with the application data being logged. If `data` + is a function, the function signature is `function()` and it called once to generate (return + value) the actual data emitted to the listeners. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80, routes: { log: { collect: true } } }); + +server.events.on( + { name: 'request', channels: 'app' }, + (request, event, tags) => { + if (tags.error) { + console.log(event); + } + }, +); + +const handler = function (request, h) { + request.log(['test', 'error'], 'Test event'); + return null; +}; +``` + +Note that any logs generated by the server internally will be emitted using the +[`'request'` event](#server.events.request) on the `'internal'` channel. + +```js +server.events.on( + { name: 'request', channels: 'internal' }, + (request, event, tags) => { + console.log(event); + }, +); +``` + +### `request.route.auth.access(request)` + +Validates a request against the route's authentication [`access`](#route.options.auth.access) +configuration, where: + +- `request` - the [request object](#request). + +Return value: `true` if the `request` would have passed the route's access requirements. + +Note that the route's authentication mode and strategies are ignored. The only match is made +between the `request.auth.credentials` scope and entity information and the route +[`access`](#route.options.auth.access) configuration. + +If the route uses dynamic scopes, the scopes are constructed against the [`request.query`](#request.query), +[`request.params`](#request.params), [`request.payload`](#request.payload), and +[`request.auth.credentials`](#request.auth) which may or may not match between the route and the +request's route. If this method is called using a request that has not been authenticated (yet or +not at all), it will return `false` if the route requires any authentication. + +### `request.setMethod(method)` + +Changes the request method before the router begins processing the request where: + +- `method` - is the request HTTP method (e.g. `'GET'`). + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +const onRequest = function (request, h) { + // Change all requests to 'GET' + request.setMethod('GET'); + return h.continue; +}; + +server.ext('onRequest', onRequest); +``` + +Can only be called from an `'onRequest'` extension method. + +### `request.setUrl(url, [stripTrailingSlash]` + +Changes the request URI before the router begins processing the request where: + +- `url` - the new request URI. `url` can be a string or an instance of + [`Url.URL`](https://nodejs.org/dist/latest-v10.x/docs/api/url.html#url_class_url) in which case + `url.href` is used. +- `stripTrailingSlash` - if `true`, strip the trailing slash from the path. Defaults to `false`. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +const onRequest = function (request, h) { + // Change all requests to '/test' + request.setUrl('/test'); + return h.continue; +}; + +server.ext('onRequest', onRequest); +``` + +Can only be called from an `'onRequest'` extension method. + +## Plugins + +Plugins provide a way to organize application code by splitting the server logic into smaller +components. Each plugin can manipulate the server through the standard server interface, but with +the added ability to sandbox certain properties. For example, setting a file path in one plugin +doesn't affect the file path set in another plugin. + +A plugin is an object with the following properties: + +- `register` - (required) the registration function with the signature + `async function(server, options)` where: + - `server` - the server object with a plugin-specific [`server.realm`](#server.realm). + - `options` - any options passed to the plugin during registration via [`server.register()`](#server.register()). + +- `name` - (required) the plugin name string. The name is used as a unique key. Published plugins + (e.g. published in the npm registry) should use the same name as the name field in their + 'package.json' file. Names must be unique within each application. + +- `version` - (optional) plugin version string. The version is only used informatively to enable + other plugins to find out the versions loaded. The version should be the same as the one + specified in the plugin's 'package.json' file. + +- `multiple` - (optional) if `true`, allows the plugin to be registered multiple times with the same server. + Defaults to `false`. + +- `dependencies` - (optional) a string or an array of strings indicating a plugin dependency. Same + as setting dependencies via [`server.dependency()`](#server.dependency()). + +- `requirements` - (optional) object declaring the plugin supported [semver range](https://semver.org/) for: + - `node` runtime [semver range](https://nodejs.org/en/about/releases/) string. + - `hapi` framework [semver range](#server.version) string. + +- `once` - (optional) if `true`, will only register the plugin once per server. If set, overrides + the `once` option passed to [`server.register()`](#server.register()). Defaults to no override. + +```js +const plugin = { + name: 'test', + version: '1.0.0', + register: function (server, options) { + server.route({ + method: 'GET', + path: '/test', + handler: function (request, h) { + return 'ok'; + }, + }); + }, +}; +``` + +Alternatively, the `name` and `version` can be included via the `pkg` property containing the +'package.json' file for the module which already has the name and version included: + +```js +const plugin = { + pkg: require('./package.json'), + register: function (server, options) { + server.route({ + method: 'GET', + path: '/test', + handler: function (request, h) { + return 'ok'; + }, + }); + }, +}; +``` diff --git a/generated/markdown/hapi/21/api.md b/generated/markdown/hapi/21/api.md new file mode 100644 index 00000000..9cd5d3a5 --- /dev/null +++ b/generated/markdown/hapi/21/api.md @@ -0,0 +1,4939 @@ +## Server + +The server object is the main application container. The server manages all incoming requests +along with all the facilities provided by the framework. Each server supports a single connection +(e.g. listen to port `80`). + +### `server([options])` + +Creates a new server object where: + +- `options` - (optional) a [server configuration object](#server.options). + +```js +const Hapi = require('@hapi/hapi'); + +const server = Hapi.server({ load: { sampleInterval: 1000 } }); +``` + +### Server options + +The server options control the behavior of the server object. Note that the options object is +deeply cloned (with the exception of [`listener`](#server.options.listener) which is shallowly +copied) and should not contain any values that are unsafe to perform deep copy on. + +All options are optionals. + +#### `server.options.address` + +Default value: `'::'` if IPv6 is available, otherwise `'0.0.0.0'` (i.e. all available network interfaces). + +Sets the hostname or IP address the server will listen on. If not configured, defaults to +[`host`](#server.options.host) if present, otherwise to all available network interfaces. Set to +`'127.0.0.1'`, `'::1'`, or `'localhost'` to restrict the server to only those coming from the same host. + +#### `server.options.app` + +Default value: `{}`. + +Provides application-specific configuration which can later be accessed via +[`server.settings.app`](#server.settings). The framework does not interact with this object. It is +simply a reference made available anywhere a `server` reference is provided. + +Note the difference between `server.settings.app` which is used to store static configuration +values and [`server.app`](#server.app) which is meant for storing run-time state. + +#### `server.options.autoListen` + +Default value: `true`. + +Used to disable the automatic initialization of the [`listener`](#server.options.listener). When +`false`, indicates that the [`listener`](#server.options.listener) will be started manually outside +the framework. + +Cannot be set to `false` along with a [`port`](#server.options.port) value. + +#### `server.options.cache` + +Default value: `{ provider: { constructor: require('@hapi/catbox-memory'), options: { partition: 'hapi-cache' } } }`. + +Sets up server-side caching providers. Every server includes a default cache for storing +application state. By default, a simple memory-based cache is created which has limited capacity +and capabilities. + +**hapi** uses [**catbox**](https://hapi.dev/family/catbox/api) for its cache implementation which +includes support for common storage solutions (e.g. Redis, MongoDB, Memcached, Riak, among others). +Caching is only utilized if [methods](#server.methods) and [plugins](#plugins) explicitly store +their state in the cache. + +The server cache configuration only defines the storage container itself. The configuration can be +assigned one or more (array): + +- a class or prototype function (usually obtained by calling `require()` on a **catbox** strategy + such as `require('@hapi/catbox-redis')`). A new **catbox** [client](https://hapi.dev/family/catbox/api#client) + will be created internally using this constructor. + +- a configuration object with the following: + - `engine` - a **catbox** engine object instance. + + - `name` - an identifier used later when provisioning or configuring caching for + [server methods](#server.methods) or [plugins](#plugins). Each cache name must be unique. + A single item may omit the `name` option which defines the default cache. If every cache + includes a `name`, a default memory cache is provisioned as well. + + - `provider` - a class, a constructor function, or an object with the following: + - `constructor` - a class or a prototype function. + + - `options` - (optional) a settings object passed as-is to the `constructor` with the following: + - `partition` - (optional) string used to isolate cached data. Defaults to `'hapi-cache'`. + - other constructor-specific options passed to the `constructor` on instantiation. + + - `shared` - if `true`, allows multiple cache users to share the same segment (e.g. + multiple methods using the same cache storage container). Default to `false`. + + - One (and only one) of `engine` or `provider` is required per configuration object. + +#### `server.options.compression` + +Default value: `{ minBytes: 1024 }`. + +Defines server handling of content encoding requests. If `false`, response content encoding is +disabled and no compression is performed by the server. + +##### `server.options.compression.minBytes` + +Default value: '1024'. + +Sets the minimum response payload size in bytes that is required for content encoding compression. +If the payload size is under the limit, no compression is performed. + +#### `server.options.debug` + +Default value: `{ request: ['implementation'] }`. + +Determines which logged events are sent to the console. This should only be used for development +and does not affect which events are actually logged internally and recorded. Set to `false` to +disable all console logging, or to an object with: + +- `log` - a string array of server log tags to be displayed via `console.error()` when + the events are logged via [`server.log()`](#server.log()) as well as + internally generated [server logs](#server-logs). Defaults to no output. + +- `request` - a string array of request log tags to be displayed via `console.error()` when + the events are logged via [`request.log()`](#request.log()) as well as + internally generated [request logs](#request-logs). For example, to display all errors, + set the option to `['error']`. To turn off all console debug messages set it to `false`. + To display all request logs, set it to `'*'`. + Defaults to uncaught errors thrown in external code (these errors are handled + automatically and result in an Internal Server Error response) or runtime errors due to + developer error. + +For example, to display all errors, set the `log` or `request` to `['error']`. To turn off all +output set the `log` or `request` to `false`. To display all server logs, set the `log` or +`request` to `'*'`. To disable all debug information, set `debug` to `false`. + +#### `server.options.host` + +Default value: the operating system hostname and if not available, to `'localhost'`. + +The public hostname or IP address. Used to set [`server.info.host`](#server.info) and +[`server.info.uri`](#server.info) and as [`address`](#server.options.address) if none is provided. + +#### `server.options.info.remote` + +Default value: `false`. + +If `true`, the `request.info.remoteAddress` and `request.info.remotePort` are populated when the request is received which can consume more resource (but is ok if the information is needed, especially for aborted requests). When `false`, the fields are only populated upon demand (but will be `undefined` if accessed after the request is aborted). + +#### `server.options.listener` + +Default value: none. + +An optional node HTTP (or HTTPS) [`http.Server`](https://nodejs.org/api/http.html#http_class_http_server) +object (or an object with a compatible interface). + +If the `listener` needs to be manually started, set [`autoListen`](#server.options.autolisten) to +`false`. + +If the `listener` uses TLS, set [`tls`](#server.options.tls) to `true`. + +#### `server.options.load` + +Default value: `{ sampleInterval: 0, maxHeapUsedBytes: 0, maxRssBytes: 0, maxEventLoopDelay: 0, maxEventLoopUtilization: 0 }`. + +Server excessive load handling limits where: + +- `sampleInterval` - the frequency of sampling in milliseconds. When set to `0`, the other load options are ignored. Defaults to `0` (no sampling). + +- `maxHeapUsedBytes` - maximum V8 heap size over which incoming requests are rejected with an HTTP Server Timeout (503) response. Defaults to `0` (no limit). + +- `maxRssBytes` - maximum process RSS size over which incoming requests are rejected with an HTTP Server Timeout (503) response. Defaults to `0` (no limit). + +- `maxEventLoopDelay` - maximum event loop delay duration in milliseconds over which incoming requests are rejected with an HTTP Server Timeout (503) response. Defaults to `0` (no limit). + +- `maxEventLoopUtilization` - maximum event loop utilization value over which incoming requests are rejected with an HTTP Server Timeout (503) response. Defaults to `0` (no limit). + +#### `server.options.mime` + +Default value: none. + +Options passed to the [**mimos**](https://hapi.dev/family/mimos/api) module when generating the mime database used by the server (and accessed via [`server.mime`](#server.mime)): + +- `override` - an object hash that is merged into the built in mime information specified [here](https://github.com/jshttp/mime-db). Each key value pair represents a single mime object. Each override value must contain: + - `key` - the lower-cased mime-type string (e.g. `'application/javascript'`). + + - `value` - an object following the specifications outlined [here](https://github.com/jshttp/mime-db#data-structure). Additional values include: + - `type` - specify the `type` value of result objects, defaults to `key`. + + - `predicate` - method with signature `function(mime)` when this mime type is found in the database, this function will execute to allows customizations. + +```js +const options = { + mime: { + override: { + 'node/module': { + source: 'iana', + compressible: true, + extensions: ['node', 'module', 'npm'], + type: 'node/module', + }, + 'application/javascript': { + source: 'iana', + charset: 'UTF-8', + compressible: true, + extensions: ['js', 'javascript'], + type: 'text/javascript', + }, + 'text/html': { + predicate: function (mime) { + if (someCondition) { + mime.foo = 'test'; + } else { + mime.foo = 'bar'; + } + return mime; + }, + }, + }, + }, +}; +``` + +#### `server.options.operations` + +Default value: `{ cleanStop: true }`. + +Defines server handling of server operations: + +- `cleanStop` - if `true`, the server keeps track of open connections and properly closes them + when the server is stopped. Under normal load, this should not interfere with server performance. + However, under severe load connection monitoring can consume additional resources and aggravate + the situation. If the server is never stopped, or if it is forced to stop without waiting for + open connection to close, setting this to `false` can save resources that are not being utilized + anyway. Defaults to `true`. + +#### `server.options.plugins` + +Default value: `{}`. + +Plugin-specific configuration which can later be accessed via [`server.settings.plugins`](#server.settings). +`plugins` is an object where each key is a plugin name and the value is the configuration. +Note the difference between [`server.settings.plugins`](#server.settings) which is used to store +static configuration values and [`server.plugins`](#server.plugins) which is meant for storing +run-time state. + +#### `server.options.port` + +Default value: `0` (an ephemeral port). + +The TCP port the server will listen to. Defaults the next available port when the server is started +(and assigned to [`server.info.port`](#server.info)). + +If `port` is a string containing a '/' character, it is used as a UNIX domain socket path. +If it starts with '\\.\pipe', it is used as a Windows named pipe. + +#### `server.options.query` + +Default value: `{}`. + +Defines server handling of the request path query component. + +##### `server.options.query.parser` + +Default value: none. + +Sets a query parameters parser method using the signature `function(query)` where: + +- `query` - an object containing the incoming [`request.query`](#request.query) parameters. +- the method must return an object where each key is a parameter and matching value is the + parameter value. If the method throws, the error is used as the response or returned when + [`request.setUrl()`](#request.setUrl()) is called. + +```js +const Qs = require('qs'); + +const options = { + query: { + parser: (query) => Qs.parse(query), + }, +}; +``` + +#### `server.options.router` + +Default value: `{ isCaseSensitive: true, stripTrailingSlash: false }`. + +Controls how incoming request URIs are matched against the routing table: + +- `isCaseSensitive` - determines whether the paths '/example' and '/EXAMPLE' are considered + different resources. Defaults to `true`. + +- `stripTrailingSlash` - removes trailing slashes on incoming paths. Defaults to `false`. + +#### `server.options.routes` + +Default value: none. + +A [route options](#route-options) object used as the default configuration for every route. + +#### `server.options.state` + +Default value: + +```js +{ + strictHeader: true, + ignoreErrors: false, + isSecure: true, + isHttpOnly: true, + isSameSite: 'Strict', + isPartitioned: false, + encoding: 'none' +} +``` + +Sets the default configuration for every state (cookie) set explicitly via +[`server.state()`](#server.state()) or implicitly (without definition) using the +[state configuration](#server.state()) object. + +#### `server.options.tls` + +Default value: none. + +Used to create an HTTPS connection. The `tls` object is passed unchanged to the node +HTTPS server as described in the [node HTTPS documentation](https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener). + +Set to `true` when passing a [`listener`](#server.options.listener) object that has been configured +to use TLS directly. + +#### `server.options.uri` + +Default value: constructed from runtime server information. + +The full public URI without the path (e.g. 'http://example.com:8080'). If present, used as the +server [`server.info.uri`](#server.info), otherwise constructed from the server settings. + +### Server properties + +#### `server.app` + +Access: read / write. + +Provides a safe place to store server-specific run-time application data without potential +conflicts with the framework internals. The data can be accessed whenever the server is +accessible. Initialized with an empty object. + +```js +const server = Hapi.server(); + +server.app.key = 'value'; + +const handler = function (request, h) { + return request.server.app.key; // 'value' +}; +``` + +#### `server.auth.api` + +Access: authentication strategy specific. + +An object where each key is an authentication strategy name and the value is the exposed strategy +API. Available only when the authentication scheme exposes an API by returning an `api` key in the +object returned from its implementation function. + +```js +const server = Hapi.server({ port: 80 }); + +const scheme = function (server, options) { + return { + api: { + settings: { + x: 5, + }, + }, + authenticate: function (request, h) { + const authorization = request.headers.authorization; + if (!authorization) { + throw Boom.unauthorized(null, 'Custom'); + } + + return h.authenticated({ credentials: { user: 'john' } }); + }, + }; +}; + +server.auth.scheme('custom', scheme); +server.auth.strategy('default', 'custom'); + +console.log(server.auth.api.default.settings.x); // 5 +``` + +#### `server.auth.settings.default` + +Access: read only. + +Contains the default authentication configuration if a default strategy was set via +[`server.auth.default()`](#server.auth.default()). + +#### `server.decorations` + +Access: read only. + +Provides access to the decorations already applied to various framework interfaces. The object must +not be modified directly, but only through [`server.decorate`](#server.decorate()). +Contains: + +- `request` - decorations on the [request object](#request). +- `response` - decorations on the [response object](#response-object). +- `toolkit` - decorations on the [response toolkit](#response-toolkit). +- `server` - decorations on the [server](#server) object. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +const success = function () { + return this.response({ status: 'ok' }); +}; + +server.decorate('toolkit', 'success', success); +console.log(server.decorations.toolkit); // ['success'] +``` + +#### `server.events` + +Access: **podium** public interface. + +The server events emitter. Utilizes the [**podium**](https://hapi.dev/family/podium/api) with support +for event criteria validation, channels, and filters. + +Use the following methods to interact with `server.events`: + +- [`server.event(events)`](#server.event()) - register application events. +- [`server.events.emit(criteria, data)`](#server.events.emit()) - emit server events. +- [`server.events.on(criteria, listener, context)`](#server.events.on()) - subscribe to all events. +- [`server.events.once(criteria, listener, context)`](#server.events.once()) - subscribe to a single event. + +Other methods include: `server.events.removeListener(name, listener)`, +`server.events.removeAllListeners(name)`, and `server.events.hasListeners(name)`. + +##### `'log'` Event + +The `'log'` event type emits internal server events generated by the framework as well as +application events logged with [`server.log()`](#server.log()). + +The `'log'` event handler uses the function signature `function(event, tags)` where: + +- `event` - an object with the following properties: + - `timestamp` - the event timestamp. + - `tags` - an array of tags identifying the event (e.g. `['error', 'http']`). + - `channel` - set to `'internal'` for internally generated events, otherwise `'app'` for events + generated by [`server.log()`](#server.log()). + - `data` - event-specific information. Available when event data was provided and is not an + error. Errors are passed via `error`. + - `error` - the error object related to the event if applicable. Cannot appear together with + `data`. + +- `tags` - an object where each `event.tag` is a key and the value is `true`. Useful for quick + identification of events. + +```js +server.events.on('log', (event, tags) => { + if (tags.error) { + console.log( + `Server error: ${event.error ? event.error.message : 'unknown'}`, + ); + } +}); +``` + +The internally generated events are (identified by their `tags`): + +- `load` - logs the current server load measurements when the server rejects a request due to + [high load](#server.options.load). The event data contains the process load metrics. + +- `connection` `client` `error` - a `clientError` event was received from the HTTP or HTTPS + listener. The event data is the error object received. + +##### `'cachePolicy'` Event + +The `'cachePolicy'` event type is emitted when a server [cache policy](https://hapi.dev/module/catbox/api#policy) +is created via [`server.cache()`](#server.cache()) or a [`server.method()`](#server.method()) with caching enabled is registered. +The `'cachePolicy'` event handler uses the function signature `function(cachePolicy, cache, segment)` where: + +- `cachePolicy` - the catbox [cache policy](https://hapi.dev/module/catbox/api#policy). +- `cache` - the [cache provision](#server.options.cache) name used when the policy was created or `undefined` if the default cache was used. +- `segment` - the segment name used when the policy was created. + +```js +server.events.on('cachePolicy', (cachePolicy, cache, segment) => { + console.log( + `New cache policy created using cache: ${cache === undefined ? 'default' : cache} and segment: ${segment}`, + ); +}); +``` + +##### `'request'` Event + +The `'request'` event type emits internal request events generated by the framework as well as +application events logged with [`request.log()`](#request.log()). + +The `'request'` event handler uses the function signature `function(request, event, tags)` where: + +- `request` - the [request object](#request). + +- `event` - an object with the following properties: + - `timestamp` - the event timestamp. + - `tags` - an array of tags identifying the event (e.g. `['error', 'http']`). + - `channel` - one of + - `'app'` - events generated by [`request.log()`](#request.log()). + - `'error'` - emitted once per request if the response had a `500` status code. + - `'internal'` - internally generated events. + - `request` - the request [identifier](#request.info.id). + - `data` - event-specific information. Available when event data was provided and is not an + error. Errors are passed via `error`. + - `error` - the error object related to the event if applicable. Cannot appear together with + `data`. + +- `tags` - an object where each `event.tag` is a key and the value is `true`. Useful for quick + identification of events. + +```js +server.events.on('request', (request, event, tags) => { + if (tags.error) { + console.log( + `Request ${event.request} error: ${event.error ? event.error.message : 'unknown'}`, + ); + } +}); +``` + +To listen to only one of the channels, use the event criteria object: + +```js +server.events.on( + { name: 'request', channels: 'error' }, + (request, event, tags) => { + console.log(`Request ${event.request} failed`); + }, +); +``` + +The internally generated events are (identified by their `tags`): + +- `accept-encoding` `error` - a request received contains an invalid Accept-Encoding header. +- `auth` `unauthenticated` - no authentication scheme included with the request. +- `auth` `unauthenticated` `response` `{strategy}` - the authentication strategy listed returned a non-error response (e.g. a redirect to a login page). +- `auth` `unauthenticated` `error` `{strategy}` - the request failed to pass the listed authentication strategy (invalid credentials). +- `auth` `unauthenticated` `missing` `{strategy}` - the request failed to pass the listed authentication strategy (no credentials found). +- `auth` `unauthenticated` `try` `{strategy}` - the request failed to pass the listed authentication strategy in `'try'` mode and will continue. +- `auth` `scope` `error` - the request authenticated but failed to meet the scope requirements. +- `auth` `entity` `user` `error` - the request authenticated but included an application entity when a user entity was required. +- `auth` `entity` `app` `error` - the request authenticated but included a user entity when an application entity was required. +- `ext` `error` - an `onPostResponse` extension handler errored. +- `handler` `error` - the route handler returned an error. Includes the execution duration and the error message. +- `pre` `error` - a pre method was executed and returned an error. Includes the execution duration, assignment key, and error. +- `internal` `error` - an HTTP 500 error response was assigned to the request. +- `internal` `implementation` `error` - an incorrectly implemented [lifecycle method](#lifecycle-methods). +- `request` `error` `abort` - the request aborted. +- `request` `error` `close` - the request closed prematurely. +- `request` `error` - the request stream emitted an error. Includes the error. +- `request` `server` `timeout` `error` - the request took too long to process by the server. Includes the timeout configuration value and the duration. +- `state` `error` - the request included an invalid cookie or cookies. Includes the cookies and error details. +- `state` `response` `error` - the response included an invalid cookie which prevented generating a valid header. Includes the error. +- `payload` `error` - failed processing the request payload. Includes the error. +- `response` `error` - failed writing the response to the client. Includes the error. +- `response` `error` `close` - failed writing the response to the client due to prematurely closed connection. +- `response` `error` `aborted` - failed writing the response to the client due to prematurely aborted connection. +- `response` `error` `cleanup` - failed freeing response resources. +- `validation` `error` `{input}` - input (i.e. payload, query, params, headers) validation failed. Includes the error. Only emitted when `failAction` is set to `'log'`. +- `validation` `response` `error` - response validation failed. Includes the error message. Only emitted when `failAction` is set to `'log'`. + +##### `'response'` Event + +The `'response'` event type is emitted after the response is sent back to the client (or when the +client connection closed and no response sent, in which case [`request.response`](#request.response) +is `null`). A single event is emitted per request. The `'response'` event handler uses the function +signature `function(request)` where: + +- `request` - the [request object](#request). + +```js +server.events.on('response', (request) => { + console.log(`Response sent for request: ${request.info.id}`); +}); +``` + +##### `'route'` Event + +The `'route'` event type is emitted when a route is added via [`server.route()`](#server.route()). +The `'route'` event handler uses the function signature `function(route)` where: + +- `route` - the [route information](#request.route). The `route` object must not be modified. + +```js +server.events.on('route', (route) => { + console.log(`New route added: ${route.path}`); +}); +``` + +##### `'start'` Event + +The `'start'` event type is emitted when the server is started using [`server.start()`](#server.start()). +The `'start'` event handler uses the function signature `function()`. + +```js +server.events.on('start', () => { + console.log('Server started'); +}); +``` + +##### `'closing'` Event + +The `'closing'` event type is emitted when the server is stopped using [`server.stop()`](#server.stop()). It is triggered when incoming requests are no longer accepted but before all underlying active connections have been closed, and thus before the [`'stop'`](#server.events.stop) event is triggered. +The `'closing'` event handler uses the function signature `function()`. + +```js +server.events.on('closing', () => { + console.log('Server is closing'); +}); +``` + +##### `'stop'` Event + +The `'stop'` event type is emitted when the server is stopped using [`server.stop()`](#server.stop()). +The `'stop'` event handler uses the function signature `function()`. + +```js +server.events.on('stop', () => { + console.log('Server stopped'); +}); +``` + +#### `server.info` + +Access: read only. + +An object containing information about the server where: + +- `id` - a unique server identifier (using the format '{hostname}:{pid}:{now base36}'). + +- `created` - server creation timestamp. + +- `started` - server start timestamp (`0` when stopped). + +- `port` - the connection port based on the following rules: + - before the server has been started: the configured [`port`](#server.options.port) value. + - after the server has been started: the actual port assigned when no port is configured or was + set to `0`. + +- `host` - The [`host`](#server.options.host) configuration value. + +- `address` - the active IP address the connection was bound to after starting. Set to `undefined` + until the server has been started or when using a non TCP port (e.g. UNIX domain socket). + +- `protocol` - the protocol used: + - `'http'` - HTTP. + - `'https'` - HTTPS. + - `'socket'` - UNIX domain socket or Windows named pipe. + +- `uri` - a string representing the connection (e.g. 'http://example.com:8080' or + 'socket:/unix/domain/socket/path'). Contains the [`uri`](#server.options.uri) value if set, + otherwise constructed from the available settings. If no [`port`](#server.options.port) is + configured or is set to `0`, the `uri` will not include a port component until the server is + started. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +console.log(server.info.port); // 80 +``` + +#### `server.listener` + +Access: read only and listener public interface. + +The node HTTP server object. + +```js +const Hapi = require('@hapi/hapi'); +const SocketIO = require('socket.io'); + +const server = Hapi.server({ port: 80 }); + +const io = SocketIO.listen(server.listener); +io.sockets.on('connection', (socket) => { + socket.emit({ msg: 'welcome' }); +}); +``` + +#### `server.load` + +Access: read only. + +An object containing the process load metrics (when [`load.sampleInterval`](#server.options.load) +is enabled): + +- `eventLoopDelay` - event loop delay milliseconds. +- `eventLoopUtilization` - current event loop utilization value. +- `heapUsed` - V8 heap usage. +- `rss` - RSS memory usage. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ load: { sampleInterval: 1000 } }); + +console.log(server.load.rss); +``` + +#### `server.methods` + +Access: read only. + +Server methods are functions registered with the server and used throughout the application as a +common utility. Their advantage is in the ability to configure them to use the built-in cache and +share across multiple request handlers without having to create a common module. + +`sever.methods` is an object which provides access to the methods registered via +[server.method()](#server.method()) where each server method name is an object +property. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server(); + +server.method('add', (a, b) => a + b); +const result = server.methods.add(1, 2); // 3 +``` + +#### `server.mime` + +Access: read only and **mimos** public interface. + +Provides access to the server MIME database used for setting content-type information. The object +must not be modified directly but only through the [`mime`](#server.options.mime) server setting. + +```js +const Hapi = require('@hapi/hapi'); + +const options = { + mime: { + override: { + 'node/module': { + source: 'steve', + compressible: false, + extensions: ['node', 'module', 'npm'], + type: 'node/module', + }, + }, + }, +}; + +const server = Hapi.server(options); +console.log(server.mime.path('code.js').type); // 'application/javascript' +console.log(server.mime.path('file.npm').type); // 'node/module' +``` + +#### `server.plugins` + +Access: read / write. + +An object containing the values exposed by each registered plugin where each key is a plugin name +and the values are the exposed properties by each plugin using +[`server.expose()`](#server.expose()). Plugins may set the value of the +`server.plugins[name]` object directly or via the `server.expose()` method. + +```js +exports.plugin = { + name: 'example', + register: function (server, options) { + server.expose('key', 'value'); + server.plugins.example.other = 'other'; + + console.log(server.plugins.example.key); // 'value' + console.log(server.plugins.example.other); // 'other' + }, +}; +``` + +#### `server.realm` + +Access: read only. + +The realm object contains sandboxed server settings specific to each plugin or authentication +strategy. When registering a plugin or an authentication scheme, a `server` object reference is +provided with a new `server.realm` container specific to that registration. It allows each plugin +to maintain its own settings without leaking and affecting other plugins. + +For example, a plugin can set a default file path for local resources without breaking other +plugins' configured paths. When calling [`server.bind()`](#server.bind()), the active realm's +`settings.bind` property is set which is then used by routes and extensions added at the same level +(server root or plugin). + +The `server.realm` object contains: + +- `modifiers` - when the server object is provided as an argument to the plugin `register()` + method, `modifiers` provides the registration preferences passed the + [`server.register()`](#server.register()) method and includes: + - `route` - routes preferences: + - `prefix` - the route path prefix used by any calls to [`server.route()`](#server.route()) + from the server. Note that if a prefix is used and the route path is set to `'/'`, the + resulting path will not include the trailing slash. + - `vhost` - the route virtual host settings used by any calls to + [`server.route()`](#server.route()) from the server. + +- `parent` - the realm of the parent server object, or `null` for the root server. + +- `plugin` - the active plugin name (empty string if at the server root). + +- `pluginOptions` - the plugin options passed at registration. + +- `plugins` - plugin-specific state to be shared only among activities sharing the same active + state. `plugins` is an object where each key is a plugin name and the value is the plugin state. + +- `settings` - settings overrides: + - `files.relativeTo` + - `bind` + +The `server.realm` object should be considered read-only and must not be changed directly except +for the `plugins` property which can be directly manipulated by each plugin, setting its properties +inside `plugins[name]`. + +```js +exports.register = function (server, options) { + console.log(server.realm.modifiers.route.prefix); +}; +``` + +#### `server.registrations` + +Access: read only. + +An object of the currently registered plugins where each key is a registered plugin name and the +value is an object containing: + +- `version` - the plugin version. +- `name` - the plugin name. +- `options` - (optional) options passed to the plugin during registration. + +#### `server.settings` + +Access: read only. + +The server configuration object after defaults applied. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ + app: { + key: 'value', + }, +}); + +console.log(server.settings.app); // { key: 'value' } +``` + +#### `server.states` + +Access: read only and **statehood** public interface. + +The server cookies manager. + +#### `server.states.settings` + +Access: read only. + +The server cookies manager settings. The settings are based on the values configured in +[`server.options.state`](#server.options.state). + +#### `server.states.cookies` + +Access: read only. + +An object containing the configuration of each cookie added via [`server.state()`](#server.state()) +where each key is the cookie name and value is the configuration object. + +#### `server.states.names` + +Access: read only. + +An array containing the names of all configured cookies. + +#### `server.type` + +Access: read only. + +A string indicating the listener type where: + +- `'socket'` - UNIX domain socket or Windows named pipe. +- `'tcp'` - an HTTP listener. + +#### `server.version` + +Access: read only. + +The **hapi** module version number. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server(); + +console.log(server.version); // '17.0.0' +``` + +### `server.auth.default(options)` + +Sets a default strategy which is applied to every route where: + +- `options` - one of: + - a string with the default strategy name + - an authentication configuration object using the same format as the + [route `auth` handler options](#route.options.auth). + +Return value: none. + +The default does not apply when a route config specifies `auth` as `false`, or has an +authentication strategy configured (contains the [`strategy`](#route.options.auth.strategy) or +[`strategies`](#route.options.auth.strategies) authentication settings). Otherwise, the route +authentication config is applied to the defaults. + +Note that if the route has authentication configured, the default only applies at the time of +adding the route, not at runtime. This means that calling `server.auth.default()` after adding a +route with some authentication config will have no impact on the routes added prior. However, the +default will apply to routes added before `server.auth.default()` is called if those routes lack +any authentication config. + +The default auth strategy configuration can be accessed via [`server.auth.settings.default`](#server.auth.settings.default). +To obtain the active authentication configuration of a route, use `server.auth.lookup(request.route)`. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +server.auth.scheme('custom', scheme); +server.auth.strategy('default', 'custom'); +server.auth.default('default'); + +server.route({ + method: 'GET', + path: '/', + handler: function (request, h) { + return request.auth.credentials.user; + }, +}); +``` + +### `server.auth.scheme(name, scheme)` + +Registers an authentication scheme where: + +- `name` - the scheme name. +- `scheme` - the method implementing the scheme with signature `function(server, options)` where: + - `server` - a reference to the server object the scheme is added to. Each auth strategy is given its own [`server.realm`](#server.realm) whose parent is the realm of the `server` in the call to [`server.auth.strategy()`](#server.auth.strategy()). + - `options` - (optional) the scheme `options` argument passed to + [`server.auth.strategy()`](#server.auth.strategy()) when instantiation a strategy. + +Return value: none. + +The `scheme` function must return an [authentication scheme object](#authentication-scheme) when +invoked. + +#### Authentication scheme + +An authentication scheme is an object with the following properties: + +- `api` - (optional) object which is exposed via the [`server.auth.api`](#server.auth.api) object. + +- `async authenticate(request, h)` - (required) a [lifecycle method](#lifecycle-methods) function + called for each incoming request configured with the authentication scheme. The method is + provided with two special toolkit methods for returning an authenticated or an unauthenticate + result: + - [`h.authenticated()`](#h.authenticated()) - indicate request authenticated successfully. + - [`h.unauthenticated()`](#h.unauthenticated()) - indicate request failed to authenticate. + +- `async payload(request, h)` - (optional) a [lifecycle method](#lifecycle-methods) to authenticate + the request payload. + +- `async response(request, h)` - (optional) a [lifecycle method](#lifecycle-methods) to decorate + the response with authentication headers before the response headers or payload is written. + +- `async verify(auth)` - (optional) a method used to verify the authentication credentials provided + are still valid (e.g. not expired or revoked after the initial authentication) where: + - `auth` - the [`request.auth`](#request.auth) object containing the `credentials` and + `artifacts` objects returned by the scheme's `authenticate()` method. + - the method throws an `Error` when the credentials passed are no longer valid (e.g. expired or + revoked). Note that the method does not have access to the original request, only to the + credentials and artifacts produced by the `authenticate()` method. + +- `options` - (optional) an object with the following keys: + - `payload` - if `true`, requires payload validation as part of the scheme and forbids routes + from disabling payload auth validation. Defaults to `false`. + +When the scheme `authenticate()` method implementation throws an error or calls +[`h.unauthenticated()`](#h.unauthenticated()), the specifics of the error affect whether additional +authentication strategies will be attempted (if configured for the route). If the error includes a +message, no additional strategies will be attempted. If the `err` does not include a message but +does include the scheme name (e.g. `Boom.unauthorized(null, 'Custom')`), additional strategies will +be attempted in the order of preference (defined in the route configuration). If authentication +fails, the scheme names will be present in the 'WWW-Authenticate' header. + +When the scheme `payload()` method throws an error with a message, it means payload validation +failed due to bad payload. If the error has no message but includes a scheme name (e.g. +`Boom.unauthorized(null, 'Custom')`), authentication may still be successful if the route +[`auth.payload`](#route.options.auth.payload) configuration is set to `'optional'`. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +const scheme = function (server, options) { + return { + authenticate: function (request, h) { + const req = request.raw.req; + const authorization = req.headers.authorization; + if (!authorization) { + throw Boom.unauthorized(null, 'Custom'); + } + + return h.authenticated({ credentials: { user: 'john' } }); + }, + }; +}; + +server.auth.scheme('custom', scheme); +``` + +### `server.auth.strategy(name, scheme, [options])` + +Registers an authentication strategy where: + +- `name` - the strategy name. +- `scheme` - the scheme name (must be previously registered using + [`server.auth.scheme()`](#server.auth.scheme())). +- `options` - scheme options based on the scheme requirements. + +Return value: none. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +server.auth.scheme('custom', scheme); +server.auth.strategy('default', 'custom'); + +server.route({ + method: 'GET', + path: '/', + options: { + auth: 'default', + handler: function (request, h) { + return request.auth.credentials.user; + }, + }, +}); +``` + +### `await server.auth.test(strategy, request)` + +Tests a request against an authentication strategy where: + +- `strategy` - the strategy name registered with [`server.auth.strategy()`](#server.auth.strategy()). +- `request` - the [request object](#request). + +Return value: an object containing the authentication `credentials` and `artifacts` if authentication +was successful, otherwise throws an error. + +Note that the `test()` method does not take into account the route authentication configuration. It +also does not perform payload authentication. It is limited to the basic strategy authentication +execution. It does not include verifying scope, entity, or other route properties. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +server.auth.scheme('custom', scheme); +server.auth.strategy('default', 'custom'); + +server.route({ + method: 'GET', + path: '/', + handler: async function (request, h) { + try { + const { credentials, artifacts } = await request.server.auth.test( + 'default', + request, + ); + return { status: true, user: credentials.name }; + } catch (err) { + return { status: false }; + } + }, +}); +``` + +### `await server.auth.verify(request)` + +Verify a request's authentication credentials against an authentication strategy where: + +- `request` - the [request object](#request). + +Return value: nothing if verification was successful, otherwise throws an error. + +Note that the `verify()` method does not take into account the route authentication configuration +or any other information from the request other than the `request.auth` object. It also does not +perform payload authentication. It is limited to verifying that the previously valid credentials +are still valid (e.g. have not been revoked or expired). It does not include verifying scope, +entity, or other route properties. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +server.auth.scheme('custom', scheme); +server.auth.strategy('default', 'custom'); + +server.route({ + method: 'GET', + path: '/', + handler: async function (request, h) { + try { + const credentials = await request.server.auth.verify(request); + return { status: true, user: credentials.name }; + } catch (err) { + return { status: false }; + } + }, +}); +``` + +### `server.bind(context)` + +Sets a global context used as the default bind object when adding a route or an extension where: + +- `context` - the object used to bind `this` in [lifecycle methods](#lifecycle-methods) such as + the [route handler](#route.options.handler) and [extension methods](#server.ext()). The context + is also made available as [`h.context`](#h.context). + +Return value: none. + +When setting a context inside a plugin, the context is applied only to methods set up by the +plugin. Note that the context applies only to routes and extensions added after it has been set. +Ignored if the method being bound is an arrow function. + +```js +const handler = function (request, h) { + return this.message; // Or h.context.message +}; + +exports.plugin = { + name: 'example', + register: function (server, options) { + const bind = { + message: 'hello', + }; + + server.bind(bind); + server.route({ method: 'GET', path: '/', handler }); + }, +}; +``` + +### `server.cache(options)` + +Provisions a cache segment within the server cache facility where: + +- `options` - [**catbox** policy](https://hapi.dev/family/catbox/api#policy) configuration where: + - `expiresIn` - relative expiration expressed in the number of milliseconds since the item was + saved in the cache. Cannot be used together with `expiresAt`. + + - `expiresAt` - time of day expressed in 24h notation using the 'HH:MM' format, at which point + all cache records expire. Uses local time. Cannot be used together with `expiresIn`. + + - `generateFunc` - a function used to generate a new cache item if one is not found in the + cache when calling `get()`. The method's signature is `async function(id, flags)` where: + + - `id` - the `id` string or object provided to the `get()` method. + - `flags` - an object used to pass back additional flags to the cache where: + - `ttl` - the cache ttl value in milliseconds. Set to `0` to skip storing in the + cache. Defaults to the cache global policy. + + - `staleIn` - number of milliseconds to mark an item stored in cache as stale and attempt to + regenerate it when `generateFunc` is provided. Must be less than `expiresIn`. + + - `staleTimeout` - number of milliseconds to wait before checking if an item is stale. + + - `generateTimeout` - number of milliseconds to wait before returning a timeout error when the + `generateFunc` function takes too long to return a value. When the value is eventually + returned, it is stored in the cache for future requests. Required if `generateFunc` is + present. Set to `false` to disable timeouts which may cause all `get()` requests to get stuck + forever. + + - `generateOnReadError` - if `false`, an upstream cache read error will stop the `cache.get()` + method from calling the generate function and will instead pass back the cache error. Defaults + to `true`. + + - `generateIgnoreWriteError` - if `false`, an upstream cache write error when calling + `cache.get()` will be passed back with the generated value when calling. Defaults to `true`. + + - `dropOnError` - if `true`, an error or timeout in the `generateFunc` causes the stale value + to be evicted from the cache. Defaults to `true`. + + - `pendingGenerateTimeout` - number of milliseconds while `generateFunc` call is in progress + for a given id, before a subsequent `generateFunc` call is allowed. Defaults to `0` (no + blocking of concurrent `generateFunc` calls beyond `staleTimeout`). + + - `cache` - the cache name configured in [`server.cache`](#server.options.cache). Defaults to + the default cache. + + - `segment` - string segment name, used to isolate cached items within the cache partition. + When called within a plugin, defaults to '!name' where 'name' is the plugin name. When called + within a server method, defaults to '#name' where 'name' is the server method name. Required + when called outside of a plugin. + + - `shared` - if `true`, allows multiple cache provisions to share the same segment. Default to + `false`. + +Return value: a [**catbox** policy](https://hapi.dev/family/catbox/api#policy) object. + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + const cache = server.cache({ + segment: 'countries', + expiresIn: 60 * 60 * 1000, + }); + await cache.set('norway', { capital: 'oslo' }); + const value = await cache.get('norway'); +} +``` + +### `await server.cache.provision(options)` + +Provisions a server cache as described in [`server.cache`](#server.options.cache) where: + +- `options` - same as the server [`cache`](#server.options.cache) configuration options. + +Return value: none. + +Note that if the server has been initialized or started, the cache will be automatically started +to match the state of any other provisioned server cache. + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + await server.initialize(); + await server.cache.provision({ + provider: require('@hapi/catbox-memory'), + name: 'countries', + }); + + const cache = server.cache({ cache: 'countries', expiresIn: 60 * 60 * 1000 }); + await cache.set('norway', { capital: 'oslo' }); + const value = await cache.get('norway'); +} +``` + +### `server.control(server)` + +Links another server to the initialize/start/stop state of the current server by calling the +controlled server `initialize()`/`start()`/`stop()` methods whenever the current server methods +are called, where: + +- `server` - the **hapi** server object to be controlled. + +### `server.decoder(encoding, decoder)` + +Registers a custom content decoding compressor to extend the built-in support for `'gzip'` and +'`deflate`' where: + +- `encoding` - the decoder name string. + +- `decoder` - a function using the signature `function(options)` where `options` are the encoding + specific options configured in the route [`payload.compression`](#route.options.payload.compression) + configuration option, and the return value is an object compatible with the output of node's + [`zlib.createGunzip()`](https://nodejs.org/api/zlib.html#zlib_zlib_creategunzip_options). + +Return value: none. + +```js +const Zlib = require('zlib'); +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ + port: 80, + routes: { payload: { compression: { special: { chunkSize: 16 * 1024 } } } }, +}); + +server.decoder('special', (options) => Zlib.createGunzip(options)); +``` + +### `server.decorate(type, property, method, [options])` + +Extends various framework interfaces with custom methods where: + +- `type` - the interface being decorated. Supported types: + - `'handler'` - adds a new handler type to be used in [routes handlers](#route.options.handler). + - `'request'` - adds methods to the [Request object](#request). + - `'response'` - adds methods to the [Response object](#response-object). + - `'server'` - adds methods to the [Server](#server) object. + - `'toolkit'` - adds methods to the [response toolkit](#response-toolkit). + +- `property` - the object decoration key name or symbol. + +- `method` - the extension function or other value. + +- `options` - (optional) supports the following optional settings: + - `apply` - when the `type` is `'request'`, if `true`, the `method` function is invoked using + the signature `function(request)` where `request` is the current request object and the + returned value is assigned as the decoration. + - `extend` - if `true`, overrides an existing decoration. The `method` must be a function with + the signature `function(existing)` where: + - `existing` - is the previously set decoration method value. + - must return the new decoration function or value. + - cannot be used to extend handler decorations. + +Return value: none. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +const success = function () { + return this.response({ status: 'ok' }); +}; + +server.decorate('toolkit', 'success', success); + +server.route({ + method: 'GET', + path: '/', + handler: function (request, h) { + return h.success(); + }, +}); +``` + +When registering a handler decoration, the `method` must be a function using the signature +`function(route, options)` where: + +- `route` - the [route information](#request.route). +- `options` - the configuration object provided in the handler config. + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ host: 'localhost', port: 8000 }); + + // Defines new handler for routes on this server + + const handler = function (route, options) { + return function (request, h) { + return 'new handler: ' + options.msg; + }; + }; + + server.decorate('handler', 'test', handler); + + server.route({ + method: 'GET', + path: '/', + handler: { test: { msg: 'test' } }, + }); + + await server.start(); +} +``` + +The `method` function can have a `defaults` object or function property. If the property is set to +an object, that object is used as the default route config for routes using this handler. If the +property is set to a function, the function uses the signature `function(method)` and returns the +route default configuration. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ host: 'localhost', port: 8000 }); + +const handler = function (route, options) { + return function (request, h) { + return 'new handler: ' + options.msg; + }; +}; + +// Change the default payload processing for this handler + +handler.defaults = { + payload: { + output: 'stream', + parse: false, + }, +}; + +server.decorate('handler', 'test', handler); +``` + +### `server.dependency(dependencies, [after])` + +Used within a plugin to declare a required dependency on other [plugins](#plugins) required for +the current plugin to operate (plugins listed must be registered before the server is initialized +or started) where: + +- `dependencies` - one of: + - a single plugin name string. + - an array of plugin name strings. + - an object where each key is a plugin name and each matching value is a + [version range string](https://www.npmjs.com/package/semver) which must match the registered + plugin version. + +- `after` - (optional) a function that is called after all the specified dependencies have been + registered and before the server starts. The function is only called if the server is initialized + or started. The function signature is `async function(server)` where: + + - `server` - the server the `dependency()` method was called on. + +Return value: none. + +The `after` method is identical to setting a server extension point on `'onPreStart'`. + +If a circular dependency is detected, an exception is thrown (e.g. two plugins each has an `after` +function to be called after the other). + +```js +const after = function (server) { + // Additional plugin registration logic +}; + +exports.plugin = { + name: 'example', + register: function (server, options) { + server.dependency('yar', after); + }, +}; +``` + +Dependencies can also be set via the plugin `dependencies` property (does not support setting +`after`): + +```js +exports.plugin = { + name: 'test', + version: '1.0.0', + dependencies: { + yar: '1.x.x', + }, + register: function (server, options) {}, +}; +``` + +The `dependencies` configuration accepts one of: + +- a single plugin name string. +- an array of plugin name strings. +- an object where each key is a plugin name and each matching value is a + [version range string](https://www.npmjs.com/package/semver) which must match the registered + plugin version. + +### `server.encoder(encoding, encoder)` + +Registers a custom content encoding compressor to extend the built-in support for `'gzip'` and +'`deflate`' where: + +- `encoding` - the encoder name string. + +- `encoder` - a function using the signature `function(options)` where `options` are the encoding + specific options configured in the route [`compression`](#route.options.compression) option, and + the return value is an object compatible with the output of node's + [`zlib.createGzip()`](https://nodejs.org/api/zlib.html#zlib_zlib_creategzip_options). + +Return value: none. + +```js +const Zlib = require('zlib'); +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ + port: 80, + routes: { compression: { special: { chunkSize: 16 * 1024 } } }, +}); + +server.encoder('special', (options) => Zlib.createGzip(options)); +``` + +### `server.event(events)` + +Register custom application events where: + +- `events` - must be one of: + - an event name string. + + - an event options object with the following optional keys (unless noted otherwise): + - `name` - the event name string (required). + + - `channels` - a string or array of strings specifying the event channels available. Defaults to no channel restrictions (event updates can specify a channel or not). + + - `clone` - if `true`, the `data` object passed to [`server.events.emit()`](#server.events.emit()) is cloned before it is passed to the listeners (unless an override specified by each listener). Defaults to `false` (`data` is passed as-is). + + - `spread` - if `true`, the `data` object passed to [`server.event.emit()`](#server.event.emit()) must be an array and the `listener` method is called with each array element passed as a separate argument (unless an override specified by each listener). This should only be used when the emitted data structure is known and predictable. Defaults to `false` (`data` is emitted as a single argument regardless of its type). + + - `tags` - if `true` and the `criteria` object passed to [`server.event.emit()`](#server.event.emit()) includes `tags`, the tags are mapped to an object (where each tag string is the key and the value is `true`) which is appended to the arguments list at the end. A configuration override can be set by each listener. Defaults to `false`. + + - `shared` - if `true`, the same event `name` can be registered multiple times where the second registration is ignored. Note that if the registration config is changed between registrations, only the first configuration is used. Defaults to `false` (a duplicate registration will throw an error). + + - an array containing any of the above. + +Return value: none. + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + server.event('test'); + server.events.on('test', (update) => console.log(update)); + await server.events.gauge('test', 'hello'); +} +``` + +### `server.events.emit(criteria, data)` + +Emits a custom application event to all the subscribed listeners where: + +- `criteria` - the event update criteria which must be one of: + - the event name string. + - an object with the following optional keys (unless noted otherwise): + - `name` - the event name string (required). + - `channel` - the channel name string. + - `tags` - a tag string or array of tag strings. + +- `data` - the value emitted to the subscribers. If `data` is a function, the function signature is `function()` and it called once to generate (return value) the actual data emitted to the listeners. If no listeners match the event, the `data` function is not invoked. + +Return value: none. + +Note that events must be registered before they can be emitted or subscribed to by calling [`server.event(events)`](#server.event()). This is done to detect event name misspelling and invalid event activities. + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + server.event('test'); + server.events.on('test', (update) => console.log(update)); + server.events.emit('test', 'hello'); +} +``` + +### `server.events.on(criteria, listener, context)` + +Subscribe to an event where: + +- `criteria` - the subscription criteria which must be one of: + - event name string which can be any of the [built-in server events](#server.events) or a + custom application event registered with [`server.event()`](#server.event()). + + - a criteria object with the following optional keys (unless noted otherwise): + - `name` - (required) the event name string. + + - `channels` - a string or array of strings specifying the event channels to subscribe to. + If the event registration specified a list of allowed channels, the `channels` array must + match the allowed channels. If `channels` are specified, event updates without any + channel designation will not be included in the subscription. Defaults to no channels + filter. + + - `clone` - if `true`, the `data` object passed to [`server.event.emit()`](#server.event.emit()) + is cloned before it is passed to the `listener` method. Defaults to the event + registration option (which defaults to `false`). + + - `count` - a positive integer indicating the number of times the `listener` can be called + after which the subscription is automatically removed. A count of `1` is the same as + calling `server.events.once()`. Defaults to no limit. + + - `filter` - the event tags (if present) to subscribe to which can be one of: + - a tag string. + - an array of tag strings. + - an object with the following: + - `tags` - a tag string or array of tag strings. + - `all` - if `true`, all `tags` must be present for the event update to match the + subscription. Defaults to `false` (at least one matching tag). + + - `spread` - if `true`, and the `data` object passed to [`server.event.emit()`](#server.event.emit()) + is an array, the `listener` method is called with each array element passed as a separate + argument. This should only be used when the emitted data structure is known and + predictable. Defaults to the event registration option (which defaults to `false`). + + - `tags` - if `true` and the `criteria` object passed to [`server.event.emit()`](#server.event.emit()) + includes `tags`, the tags are mapped to an object (where each tag string is the key and + the value is `true`) which is appended to the arguments list at the end. Defaults to the + event registration option (which defaults to `false`). + +- `listener` - the handler method set to receive event updates. The function signature depends on + the event argument, and the `spread` and `tags` options. +- `context` - an object that binds to the listener handler. + +Return value: none. + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + server.event('test'); + server.events.on('test', (update) => console.log(update)); + server.events.emit('test', 'hello'); +} +``` + +### `server.events.once(criteria, listener, context)` + +Same as calling [`server.events.on()`](#server.events.on()) with the `count` option set to `1`. + +Return value: none. + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + server.event('test'); + server.events.once('test', (update) => console.log(update)); + server.events.emit('test', 'hello'); + server.events.emit('test', 'hello'); // Ignored +} +``` + +### `await server.events.once(criteria)` + +Same as calling [`server.events.on()`](#server.events.on()) with the `count` option set to `1`. + +Return value: a promise that resolves when the event is emitted. + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + server.event('test'); + const pending = server.events.once('test'); + server.events.emit('test', 'hello'); + const update = await pending; +} +``` + +### `await server.events.gauge(criteria, data)` + +Behaves identically to [`server.events.emit()`](#server.events.emit()), but also returns an array of the results of all the event listeners that run. The return value is that of `Promise.allSettled()`, where each item in the resulting array is `{ status: 'fulfilled', value }` in the case of a successful handler, or `{ status: 'rejected', reason }` in the case of a handler that throws. + +Please note that system errors such as a `TypeError` are not handled specially, and it's recommended to scrutinize any rejections using something like [bounce](https://hapi.dev/module/bounce/). + +### `server.expose(key, value, [options])` + +Used within a plugin to expose a property via [`server.plugins[name]`](#server.plugins) where: + +- `key` - the key assigned ([`server.plugins[name][key]`](#server.plugins)). +- `value` - the value assigned. +- `options` - optional settings: + - `scope` - controls how to handle the presence of a plugin scope in the name (e.g. `@hapi/test`): + - `false` - the scope is removed (e.g. `@hapi/test` is changed to `test` under `server.plugins`). This is the default. + - `true` - the scope is retained as-is (e.g. `@hapi/test` is used as `server.plugins['@hapi/test']`). + - `'underscore'` - the scope is rewritten (e.g. `@hapi/test` is used as `server.plugins.hapi__test`). + +Return value: none. + +```js +exports.plugin = + name: 'example', + register: function (server, options) { + + server.expose('util', () => console.log('something')); + } +}; +``` + +### `server.expose(obj)` + +Merges an object into to the existing content of [`server.plugins[name]`](#server.plugins) where: + +- `obj` - the object merged into the exposed properties container. + +Return value: none. + +```js +exports.plugin = { + name: 'example', + register: function (server, options) { + server.expose({ util: () => console.log('something') }); + }, +}; +``` + +Note that all the properties of `obj` are deeply cloned into [`server.plugins[name]`](#server.plugins), +so avoid using this method for exposing large objects that may be expensive to clone or singleton +objects such as database client objects. Instead favor [`server.expose(key, value)`](#server.expose()), +which only copies a reference to `value`. + +### `server.ext(events)` + +Registers an extension function in one of the [request lifecycle](#request-lifecycle) extension +points where: + +- `events` - an object or array of objects with the following: + - `type` - (required) the extension point event name. The available extension points include + the [request extension points](#request-lifecycle) as well as the following server extension + points: + - `'onPreStart'` - called before the connection listeners are started. + - `'onPostStart'` - called after the connection listeners are started. + - `'onPreStop'` - called before the connection listeners are stopped. + - `'onPostStop'` - called after the connection listeners are stopped. + + - `method` - (required) a function or an array of functions to be executed at a specified point + during request processing. The required extension function signature is: + - server extension points: `async function(server)` where: + - `server` - the server object. + - `this` - the object provided via `options.bind` or the current active context set + with [`server.bind()`](#server.bind()). + + - request extension points: a [lifecycle method](#lifecycle-methods). + + - `options` - (optional) an object with the following: + - `before` - a string or array of strings of plugin names this method must execute before + (on the same event). Otherwise, extension methods are executed in the order added. + + - `after` - a string or array of strings of plugin names this method must execute after (on + the same event). Otherwise, extension methods are executed in the order added. + + - `bind` - a context object passed back to the provided method (via `this`) when called. + Ignored if the method is an arrow function. + + - `sandbox` - if set to `'plugin'` when adding a [request extension points](#request-lifecycle) + the extension is only added to routes defined by the current plugin. Not allowed when + configuring route-level extensions, or when adding server extensions. Defaults to + `'server'` which applies to any route added to the server the extension is added to. + + - `timeout` - number of milliseconds to wait for the `method` to complete before returning + a timeout error. Defaults to no timeout. + +Return value: none. + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + + server.ext({ + type: 'onRequest', + method: function (request, h) { + // Change all requests to '/test' + + request.setUrl('/test'); + return h.continue; + }, + }); + + server.route({ method: 'GET', path: '/test', handler: () => 'ok' }); + await server.start(); + + // All requests will get routed to '/test' +} +``` + +### `server.ext(event, [method, [options]])` + +Registers a single extension event using the same properties as used in [`server.ext(events)`](#server.ext()), but passed as arguments. + +The `method` may be omitted (if `options` isn't present) or passed `null` which will cause the function to return a promise. The promise is resolved with the `request` object on the first invocation of the extension point. This is primarily used for writing tests without having to write custom handlers just to handle a single event. + +Return value: a promise if `method` is omitted, otherwise `undefined`. + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + + server.ext('onRequest', function (request, h) { + // Change all requests to '/test' + + request.setUrl('/test'); + return h.continue; + }); + + server.route({ method: 'GET', path: '/test', handler: () => 'ok' }); + await server.start(); + + // All requests will get routed to '/test' +} +``` + +### `await server.initialize()` + +Initializes the server (starts the caches, finalizes plugin registration) but does not start +listening on the connection port. + +Return value: none. + +Note that if the method fails and throws an error, the server is considered to be in an undefined +state and should be shut down. In most cases it would be impossible to fully recover as the various +plugins, caches, and other event listeners will get confused by repeated attempts to start the +server or make assumptions about the healthy state of the environment. It is recommended to abort +the process when the server fails to start properly. If you must try to resume after an error, call +[`server.stop()`](#server.stop()) first to reset the server state. + +```js +const Hapi = require('@hapi/hapi'); +const Hoek = require('@hapi/hoek'); + +async function example() { + const server = Hapi.server({ port: 80 }); + await server.initialize(); +} +``` + +### `await server.inject(options)` + +Injects a request into the server simulating an incoming HTTP request without making an actual +socket connection. Injection is useful for testing purposes as well as for invoking routing logic +internally without the overhead and limitations of the network stack. + +The method utilizes the [**shot**](https://hapi.dev/family/shot/api) module for performing +injections, with some additional options and response properties: + +- `options` - can be assigned a string with the requested URI, or an object with: + - `method` - (optional) the request HTTP method (e.g. `'POST'`). Defaults to `'GET'`. + + - `url` - (required) the request URL. If the URI includes an authority + (e.g. `'example.com:8080'`), it is used to automatically set an HTTP 'Host' header, unless + one was specified in `headers`. + + - `authority` - (optional) a string specifying the HTTP 'Host' header value. Only used if 'Host' + is not specified in `headers` and the `url` does not include an authority component. + Default is inferred from runtime server information. + + - `headers` - (optional) an object with optional request headers where each key is the header + name and the value is the header content. Defaults to no additions to the default **shot** + headers. + + - `payload` - (optional) an string, buffer or object containing the request payload. In case of + an object it will be converted to a string for you. Defaults to no payload. Note that payload + processing defaults to `'application/json'` if no 'Content-Type' header provided. + + - `auth` - (optional) an object containing parsed authentication credentials where: + - `strategy` - (required) the authentication strategy name matching the provided + credentials. + + - `credentials` - (required) a credentials object containing authentication information. + The `credentials` are used to bypass the default authentication strategies, and are + validated directly as if they were received via an authentication scheme. + + - `artifacts` - (optional) an artifacts object containing authentication artifact + information. The `artifacts` are used to bypass the default authentication strategies, + and are validated directly as if they were received via an authentication scheme. + Defaults to no artifacts. + + - `payload` - (optional) disables payload authentication when set to false. + Only required when an authentication strategy requires payload authentication. + Defaults to `true`. + + - `app` - (optional) sets the initial value of `request.app`, defaults to `{}`. + + - `plugins` - (optional) sets the initial value of `request.plugins`, defaults to `{}`. + + - `allowInternals` - (optional) allows access to routes with `options.isInternal` set to `true`. + Defaults to `false`. + + - `remoteAddress` - (optional) sets the remote address for the incoming connection. + + - `simulate` - (optional) an object with options used to simulate client request stream + conditions for testing: + - `error` - if `true`, emits an `'error'` event after payload transmission (if any). + Defaults to `false`. + + - `close` - if `true`, emits a `'close'` event after payload transmission (if any). + Defaults to `false`. + + - `end` - if `false`, does not end the stream. Defaults to `true`. + + - `split` - indicates whether the request payload will be split into chunks. Defaults to + `undefined`, meaning payload will not be chunked. + + - `validate` - (optional) if `false`, the `options` inputs are not validated. This is + recommended for run-time usage of `inject()` to make it perform faster where input validation + can be tested separately. + +Return value: a response object with the following properties: + +- `statusCode` - the HTTP status code. + +- `headers` - an object containing the headers set. + +- `payload` - the response payload string. + +- `rawPayload` - the raw response payload buffer. + +- `raw` - an object with the injection request and response objects: + - `req` - the simulated node request object. + - `res` - the simulated node response object. + +- `result` - the raw handler response (e.g. when not a stream or a view) before it is + serialized for transmission. If not available, the value is set to `payload`. Useful for + inspection and reuse of the internal objects returned (instead of parsing the response + string). + +- `request` - the [request object](#request). + +Throws a Boom error if the request processing fails. The partial response object is exposed on +the `data` property. + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + server.route({ method: 'GET', path: '/', handler: () => 'Success!' }); + + const res = await server.inject('/'); + console.log(res.result); // 'Success!' +} +``` + +### `server.log(tags, [data, [timestamp]])` + +Logs server events that cannot be associated with a specific request. When called the server emits +a `'log'` event which can be used by other listeners or [plugins](#plugins) to record the +information or output to the console. The arguments are: + +- `tags` - (required) a string or an array of strings (e.g. `['error', 'database', 'read']`) used + to identify the event. Tags are used instead of log levels and provide a much more expressive + mechanism for describing and filtering events. Any logs generated by the server internally + include the `'hapi'` tag along with event-specific information. + +- `data` - (optional) an message string or object with the application data being logged. If `data` + is a function, the function signature is `function()` and it called once to generate (return + value) the actual data emitted to the listeners. If no listeners match the event, the `data` + function is not invoked. + +- `timestamp` - (optional) an timestamp expressed in milliseconds. Defaults to `Date.now()` (now). + +Return value: none. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +server.events.on('log', (event, tags) => { + if (tags.error) { + console.log(event); + } +}); + +server.log(['test', 'error'], 'Test event'); +``` + +### `server.lookup(id)` + +Looks up a route configuration where: + +- `id` - the [route identifier](#route.options.id). + +Return value: the [route information](#request.route) if found, otherwise `null`. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server(); +server.route({ + method: 'GET', + path: '/', + options: { + id: 'root', + handler: () => 'ok', + }, +}); + +const route = server.lookup('root'); +``` + +### `server.match(method, path, [host])` + +Looks up a route configuration where: + +- `method` - the HTTP method (e.g. 'GET', 'POST'). +- `path` - the requested path (must begin with '/'). +- `host` - (optional) hostname (to match against routes with `vhost`). + +Return value: the [route information](#request.route) if found, otherwise `null`. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server(); +server.route({ + method: 'GET', + path: '/', + options: { + id: 'root', + handler: () => 'ok', + }, +}); + +const route = server.match('get', '/'); +``` + +### `server.method(name, method, [options])` + +Registers a [server method](#server.methods) where: + +- `name` - a unique method name used to invoke the method via [`server.methods[name]`](#server.method). + +- `method` - the method function with a signature `async function(...args, [flags])` where: + - `...args` - the method function arguments (can be any number of arguments or none). + - `flags` - when caching is enabled, an object used to set optional method result flags. This + parameter is provided automatically and can only be accessed/modified within the method + function. It cannot be passed as an argument. + - `ttl` - `0` if result is valid but cannot be cached. Defaults to cache policy. + +- `options` - (optional) configuration object: + - `bind` - a context object passed back to the method function (via `this`) when called. + Defaults to active context (set via [`server.bind()`](#server.bind()) when the method is + registered. Ignored if the method is an arrow function. + + - `cache` - the same cache configuration used in [`server.cache()`](#server.cache()). The + `generateTimeout` option is required, and the `generateFunc` options is not allowed. + + - `generateKey` - a function used to generate a unique key (for caching) from the arguments + passed to the method function (the `flags` argument is not passed as input). The server + will automatically generate a unique key if the function's arguments are all of types + `'string'`, `'number'`, or `'boolean'`. However if the method uses other types of arguments, + a key generation function must be provided which takes the same arguments as the function and + returns a unique string (or `null` if no key can be generated). + +Return value: none. + +Method names can be nested (e.g. `utils.users.get`) which will automatically create the full path +under [`server.methods`](#server.methods) (e.g. accessed via `server.methods.utils.users.get`). + +When configured with caching enabled, `server.methods[name].cache` is assigned an object with the +following properties and methods: - `await drop(...args)` - a function that can be used to clear the cache for a given key. - `stats` - an object with cache statistics, see **catbox** for stats documentation. + +Simple arguments example: + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + + const add = (a, b) => a + b; + server.method('sum', add, { + cache: { expiresIn: 2000, generateTimeout: 100 }, + }); + + console.log(await server.methods.sum(4, 5)); // 9 +} +``` + +Object argument example: + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + + const addArray = function (array) { + let sum = 0; + array.forEach((item) => { + sum += item; + }); + + return sum; + }; + + const options = { + cache: { expiresIn: 2000, generateTimeout: 100 }, + generateKey: (array) => array.join(','), + }; + + server.method('sumObj', addArray, options); + + console.log(await server.methods.sumObj([5, 6])); // 11 +} +``` + +### `server.method(methods)` + +Registers a server method function as described in [`server.method()`](#server.method()) using a +configuration object where: + +- `methods` - an object or an array of objects where each one contains: + - `name` - the method name. + - `method` - the method function. + - `options` - (optional) settings. + +Return value: none. + +```js +const add = function (a, b) { + return a + b; +}; + +server.method({ + name: 'sum', + method: add, + options: { + cache: { + expiresIn: 2000, + generateTimeout: 100, + }, + }, +}); +``` + +### `server.path(relativeTo)` + +Sets the path prefix used to locate static resources (files and view templates) when relative paths +are used where: + +- `relativeTo` - the path prefix added to any relative file path starting with `'.'`. + +Return value: none. + +Note that setting a path within a plugin only applies to resources accessed by plugin methods. +If no path is set, the server default [route configuration](#server.options.routes) +[`files.relativeTo`](#route.options.files) settings is used. The path only applies to routes added +after it has been set. + +```js +exports.plugin = { + name: 'example', + register: function (server, options) { + // Assuming the Inert plugin was registered previously + + server.path(__dirname + '../static'); + server.route({ + path: '/file', + method: 'GET', + handler: { file: './test.html' }, + }); + }, +}; +``` + +### `await server.register(plugins, [options])` + +Registers a plugin where: + +- `plugins` - one or an array of: + - a [plugin object](#plugins). + + - an object with the following: + - `plugin` - a [plugin object](#plugins). + - `options` - (optional) options passed to the plugin during registration. + - `once`, `routes` - (optional) plugin-specific registration options as defined below. + +- `options` - (optional) registration options (different from the options passed to the + registration function): + - `once` - if `true`, subsequent registrations of the same plugin are skipped without error. + Cannot be used with plugin options. Defaults to `false`. + If not set to `true`, an error will be thrown the second time a plugin is registered on the server. + + - `routes` - modifiers applied to each route added by the plugin: + - `prefix` - string added as prefix to any route path (must begin with `'/'`). If a plugin + registers a child plugin the `prefix` is passed on to the child or is added in front of + the child-specific prefix. + - `vhost` - virtual host string (or array of strings) applied to every route. The + outer-most `vhost` overrides the any nested configuration. + +Return value: a reference to the `server`. + +```js +async function example() { + await server.register({ + plugin: require('plugin_name'), + options: { message: 'hello' }, + }); +} +``` + +### `server.route(route)` + +Adds a route where: + +- `route` - a route configuration object or an array of configuration objects where each object + contains: + - `path` - (required) the absolute path used to match incoming requests (must begin with '/'). + Incoming requests are compared to the configured paths based on the server's + [`router`](#server.options.router) configuration. The path can include named parameters + enclosed in `{}` which will be matched against literal values in the request as described in + [Path parameters](#path-parameters). + + - `method` - (required) the HTTP method. Typically one of 'GET', 'POST', 'PUT', 'PATCH', + 'DELETE', or 'OPTIONS'. Any HTTP method is allowed, except for 'HEAD'. Use `'*'` to match + against any HTTP method (only when an exact match was not found, and any match with a + specific method will be given a higher priority over a wildcard match). Can be assigned an + array of methods which has the same result as adding the same route with different methods + manually. + + - `vhost` - (optional) a domain string or an array of domain strings for limiting the route to + only requests with a matching host header field. Matching is done against the hostname part + of the header only (excluding the port). Defaults to all hosts. + + - `handler` - (required when [`handler`](#route.options.handler) is not set) the route + handler function called to generate the response after successful authentication and + validation. + + - `options` - additional [route options](#route-options). The `options` value can be an object + or a function that returns an object using the signature `function(server)` where `server` is + the server the route is being added to and `this` is bound to the current + [realm](#server.realm)'s `bind` option. + + - `rules` - route custom rules object. The object is passed to each rules processor registered + with [`server.rules()`](#server.rules()). Cannot be used if + [`route.options.rules`](#route.options.rules) is defined. + +Return value: none. + +Note that the `options` object is deeply cloned (with the exception of `bind` which is shallowly +copied) and cannot contain any values that are unsafe to perform deep copy on. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +// Handler in top level + +server.route({ method: 'GET', path: '/status', handler: () => 'ok' }); + +// Handler in config + +const user = { + cache: { expiresIn: 5000 }, + handler: function (request, h) { + return { name: 'John' }; + }, +}; + +server.route({ method: 'GET', path: '/user', options: user }); + +// An array of routes + +server.route([ + { + method: 'GET', + path: '/1', + handler: function (request, h) { + return 'ok'; + }, + }, + { + method: 'GET', + path: '/2', + handler: function (request, h) { + return 'ok'; + }, + }, +]); +``` + +#### Path parameters + +Parameterized paths are processed by matching the named parameters to the content of the incoming +request path at that path segment. For example, `'/book/{id}/cover'` will match `'/book/123/cover'` and +`request.params.id` will be set to `'123'`. Each path segment (everything between the opening `'/'` +and the closing `'/'` unless it is the end of the path) can only include one named parameter. A +parameter can cover the entire segment (`'/{param}'`) or part of the segment (`'/file.{ext}'`). A path +parameter may only contain letters, numbers and underscores, e.g. `'/{file-name}'` is invalid +and `'/{file_name}'` is valid. + +An optional `'?'` suffix following the parameter name indicates an optional parameter (only allowed +if the parameter is at the ends of the path or only covers part of the segment as in +`'/a{param?}/b'`). For example, the route `'/book/{id?}'` matches `'/book/'` with the value of +`request.params.id` set to an empty string `''`. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +const getAlbum = function (request, h) { + return ( + 'You asked for ' + + (request.params.song ? request.params.song + ' from ' : '') + + request.params.album + ); +}; + +server.route({ + path: '/{album}/{song?}', + method: 'GET', + handler: getAlbum, +}); +``` + +In addition to the optional `?` suffix, a parameter name can also specify the number of matching +segments using the `*` suffix, followed by a number greater than 1. If the number of expected parts +can be anything, then use `*` without a number (matching any number of segments can only be used in +the last path segment). + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +const getPerson = function (request, h) { + const nameParts = request.params.name.split('/'); + return { first: nameParts[0], last: nameParts[1] }; +}; + +server.route({ + path: '/person/{name*2}', // Matches '/person/john/doe' + method: 'GET', + handler: getPerson, +}); +``` + +#### Path matching order + +The router iterates through the routing table on each incoming request and executes the first (and +only the first) matching route. Route matching is done based on the combination of the request path +and the HTTP verb (e.g. 'GET, 'POST'). The query is excluded from the routing logic. Requests are +matched in a deterministic order where the order in which routes are added does not matter. + +Routes are matched based on the specificity of the route which is evaluated at each segment of the +incoming request path. Each request path is split into its segment (the parts separated by `'/'`). +The segments are compared to the routing table one at a time and are matched against the most +specific path until a match is found. If no match is found, the next match is tried. + +When matching routes, string literals (no path parameter) have the highest priority, followed by +mixed parameters (`'/a{p}b'`), parameters (`'/{p}'`), and then wildcard (`/{p*}`). + +Note that mixed parameters are slower to compare as they cannot be hashed and require an array +iteration over all the regular expressions representing the various mixed parameter at each +routing table node. + +#### Catch all route + +If the application needs to override the default Not Found (404) error response, it can add a +catch-all route for a specific method or all methods. Only one catch-all route can be defined. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +const handler = function (request, h) { + return h.response('The page was not found').code(404); +}; + +server.route({ method: '*', path: '/{p*}', handler }); +``` + +### `server.rules(processor, [options])` + +Defines a route rules processor for converting route rules object into route configuration where: + +- `processor` - a function using the signature `function(rules, info)` where: + - `rules` - the [custom object](#route.options.rules) defined in your routes configuration for you to use its values. + - `info` - an object with the following properties: + - `method` - the route method. + - `path` - the route path. + - `vhost` - the route virtual host (if any defined). + - returns a route config object. + +- `options` - optional settings: + - `validate` - rules object validation: + - `schema` - **joi** schema. + - `options` - optional **joi** validation options. Defaults to `{ allowUnknown: true }`. + +Note that the root server and each plugin server instance can only register one rules processor. +If a route is added after the rules are configured, it will not include the rules config. Routes +added by plugins apply the rules to each of the parent realms' rules from the root to the route's +realm. This means the processor defined by the plugin overrides the config generated by the root +processor if they overlap. Similarly, the route's own config overrides the config produced by the rules processors. + +```js +const validateSchema = { + auth: Joi.string(), + myCustomPre: Joi.array().min(2).items(Joi.string()), + payload: Joi.object(), +}; + +const myPreHelper = (name) => { + return { + method: (request, h) => { + return `hello ${name || 'world'}!`; + }, + assign: 'myPreHelper', + }; +}; + +const processor = (rules, info) => { + if (!rules) { + return null; + } + + const options = {}; + + if (rules.auth) { + options.auth = { + strategy: rules.auth, + validate: { + entity: 'user', + }, + }; + } + + if (rules.myCustomPre) { + options.pre = [myPreHelper(...rules.myCustomPre)]; + } + + if (rules.payload) { + options.validate = { payload: Joi.object(rules.payload) }; + } + + return options; +}; + +server.rules(processor, { + validate: { schema: validateSchema }, +}); + +server.route({ + method: 'GET', + path: '/', + rules: { + auth: 'jwt', + myCustomPre: ['arg1', 'arg2'], + payload: { a: Joi.boolean(), b: Joi.string() }, + }, + options: { + id: 'my-route', + }, +}); +``` + +### `await server.start()` + +Starts the server by listening for incoming requests on the configured port (unless the connection +was configured with [`autoListen`](#server.options.autoListen) set to `false`). + +Return value: none. + +Note that if the method fails and throws an error, the server is considered to be in an undefined +state and should be shut down. In most cases it would be impossible to fully recover as the various +plugins, caches, and other event listeners will get confused by repeated attempts to start the +server or make assumptions about the healthy state of the environment. It is recommended to abort +the process when the server fails to start properly. If you must try to resume after an error, call +[`server.stop()`](#server.stop()) first to reset the server state. + +If a started server is started again, the second call to `server.start()` is ignored. No events +will be emitted and no extension points invoked. + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + await server.start(); + console.log('Server started at: ' + server.info.uri); +} +``` + +### `server.state(name, [options])` + +[HTTP state management](https://tools.ietf.org/html/rfc6265) uses client cookies to persist a state +across multiple requests. Registers a cookie definitions where: + +- `name` - the cookie name string. + +- `options` - are the optional cookie settings: + - `ttl` - time-to-live in milliseconds. Defaults to `null` (session time-life - cookies are deleted when the browser is closed). + + - `isSecure` - sets the 'Secure' flag. Defaults to `true`. + + - `isHttpOnly` - sets the 'HttpOnly' flag. Defaults to `true`. + + - `isSameSite` - sets the ['SameSite' flag](https://www.owasp.org/index.php/SameSite). The value must be one of: + - `false` - no flag. + - `'Strict'` - sets the value to `'Strict'` (this is the default value). + - `'Lax'` - sets the value to `'Lax'`. + - `'None'` - sets the value to `'None'`. + + - `isPartitioned` - sets the ['Partitioned' flag](https://developers.google.com/privacy-sandbox/3pcd/chips). Defaults to `false`. Requires `isSecure` to be `true` and `isSameSite` to be `'None'`. + + - `path` - the path scope. Defaults to `null` (no path). + + - `domain` - the domain scope. Defaults to `null` (no domain). + + - `autoValue` - if present and the cookie was not received from the client or explicitly set by the route handler, the cookie is automatically added to the response with the provided value. The value can be a function with signature `async function(request)` where: + - `request` - the [request object](#request). + + - `encoding` - encoding performs on the provided value before serialization. Options are: + - `'none'` - no encoding. When used, the cookie value must be a string. This is the default value. + - `'base64'` - string value is encoded using Base64. + - `'base64json'` - object value is JSON-stringified then encoded using Base64. + - `'form'` - object value is encoded using the _x-www-form-urlencoded_ method. + - `'iron'` - Encrypts and sign the value using [**iron**](https://hapi.dev/family/iron/api). + + - `sign` - an object used to calculate an HMAC for cookie integrity validation. This does not provide privacy, only a mean to verify that the cookie value was generated by the server. Redundant when `'iron'` encoding is used. Options are: + - `integrity` - algorithm options. Defaults to [`require('iron').defaults.integrity`](https://hapi.dev/family/iron/api/#options). + - `password` - password used for HMAC key generation (must be at least 32 characters long). + + - `password` - password used for `'iron'` encoding (must be at least 32 characters long). + + - `iron` - options for `'iron'` encoding. Defaults to [`require('iron').defaults`](https://hapi.dev/family/iron/api/#options). + + - `ignoreErrors` - if `true`, errors are ignored and treated as missing cookies. + + - `clearInvalid` - if `true`, automatically instruct the client to remove invalid cookies. Defaults to `false`. + + - `strictHeader` - if `false`, allows any cookie value including values in violation of [RFC 6265](https://tools.ietf.org/html/rfc6265). Defaults to `true`. + + - `passThrough` - used by proxy plugins (e.g. [**h2o2**](https://hapi.dev/family/h2o2/api)). + + - `contextualize` - a function using the signature `async function(definition, request)` used to override a request-specific cookie settings where: + - `definition` - a copy of the `options` to be used for formatting the cookie that can be manipulated by the function to customize the request cookie header. Note that changing the `definition.contextualize` property will be ignored. + - `request` - the current request object. + +Return value: none. + +State defaults can be modified via the [server.options.state](#server.options.state) configuration +option. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +// Set cookie definition + +server.state('session', { + ttl: 24 * 60 * 60 * 1000, // One day + isSecure: true, + path: '/', + encoding: 'base64json', +}); + +// Set state in route handler + +const handler = function (request, h) { + let session = request.state.session; + if (!session) { + session = { user: 'joe' }; + } + + session.last = Date.now(); + + return h.response('Success').state('session', session); +}; +``` + +Registered cookies are automatically parsed when received. Parsing rules depends on the route +[`state.parse`](#route.options.state) configuration. If an incoming registered cookie fails parsing, +it is not included in [`request.state`](#request.state), regardless of the +[`state.failAction`](#route.options.state.failAction) setting. When [`state.failAction`](#route.options.state.failAction) +is set to `'log'` and an invalid cookie value is received, the server will emit a +[`'request'` event](#server.events.request). To capture these errors subscribe to the `'request'` +event on the `'internal'` channel and filter on `'error'` and `'state'` tags: + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +server.events.on( + { name: 'request', channels: 'internal' }, + (request, event, tags) => { + if (tags.error && tags.state) { + console.error(event); + } + }, +); +``` + +### `server.states.add(name, [options])` + +Access: read only. + +Same as calling [`server.state()`](#server.state()). + +### `await server.states.format(cookies)` + +Formats an HTTP 'Set-Cookie' header based on the [`server.options.state`](#server.options.state) +where: + +- `cookies` - a single object or an array of object where each contains: + - `name` - the cookie name. + - `value` - the cookie value. + - `options` - cookie configuration to override the server settings. + +Return value: a header string. + +Note that this utility uses the server configuration but does not change the server state. It is +provided for manual cookie formatting (e.g. when headers are set manually). + +### `await server.states.parse(header)` + +Parses an HTTP 'Cookies' header based on the [`server.options.state`](#server.options.state) where: + +- `header` - the HTTP header. + +Return value: an object where each key is a cookie name and value is the parsed cookie. + +Note that this utility uses the server configuration but does not change the server state. It is +provided for manual cookie parsing (e.g. when server parsing is disabled). + +### `await server.stop([options])` + +Stops the server's listener by refusing to accept any new connections or requests (existing +connections will continue until closed or timeout), where: + +- `options` - (optional) object with: + - `timeout` - sets the timeout in millisecond before forcefully terminating any open + connections that arrived before the server stopped accepting new connections. The timeout + only applies to waiting for existing connections to close, and not to any + [`'onPreStop'` or `'onPostStop'` server extensions](#server.ext.args()) which can + delay or block the stop operation indefinitely. Ignored if + [`server.options.operations.cleanStop`](#server.options.operations) is `false`. Note that if + the server is set as a [group controller](#server.control()), the timeout is per controlled + server and the controlling server itself. Defaults to `5000` (5 seconds). + +Return value: none. + +```js +const Hapi = require('@hapi/hapi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + await server.start(); + await server.stop({ timeout: 60 * 1000 }); + console.log('Server stopped'); +} +``` + +### `server.table([host])` + +Returns a copy of the routing table where: + +- `host` - (optional) host to filter routes matching a specific virtual host. Defaults to all + virtual hosts. + +Return value: an array of routes where each route contains: + +- `settings` - the route config with defaults applied. +- `method` - the HTTP method in lower case. +- `path` - the route path. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); +server.route({ method: 'GET', path: '/example', handler: () => 'ok' }); + +const table = server.table(); +``` + +### `server.validator(validator)` + +Registers a server validation module used to compile raw validation rules into validation schemas for all routes where: + +- `validator` - the validation module (e.g. **joi**). + +Return value: none. + +Note: the validator is only used when validation rules are not pre-compiled schemas. When a validation rules is a function or schema object, the rule is used as-is and the validator is not used. When setting a validator inside a plugin, the validator is only applied to routes set up by the plugin and plugins registered by it. + +```js +const Hapi = require('@hapi/hapi'); +const Joi = require('joi'); + +async function example() { + const server = Hapi.server({ port: 80 }); + server.validator(Joi); +} +``` + +## Route options + +Each route can be customized to change the default behavior of the request lifecycle. + +### `route.options.app` + +Application-specific route configuration state. Should not be used by [plugins](#plugins) which +should use `options.plugins[name]` instead. + +### `route.options.auth` + +Route authentication configuration. Value can be: + +- `false` to disable authentication if a default strategy is set. + +- a string with the name of an authentication strategy registered with + [`server.auth.strategy()`](#server.auth.strategy()). The strategy will be + set to `'required'` mode. + +- an [authentication configuration object](#authentication-options). + +#### `route.options.auth.access` + +Default value: none. + +An object or array of objects specifying the route access rules. Each rule is evaluated against an +incoming request and access is granted if at least one of the rules matches. Each rule object must +include at least one of [`scope`](#route.options.auth.access.scope) or +[`entity`](#route.options.auth.access.entity). + +#### `route.options.auth.access.scope` + +Default value: `false` (no scope requirements). + +The application scope required to access the route. Value can be a scope string or an +array of scope strings. When authenticated, the credentials object `scope` property must contain +at least one of the scopes defined to access the route. + +If a scope string begins with a `+` character, that scope is required. If a scope string begins +with a `!` character, that scope is forbidden. For example, the scope `['!a', '+b', 'c', 'd']` +means the incoming request credentials' `scope` must not include 'a', must include 'b', and must +include one of 'c' or 'd'. + +You may also access properties on the request object (`query`, `params`, `payload`, and +`credentials`) to populate a dynamic scope by using the '{' and '}' characters around the property +name, such as `'user-{params.id}'`. + +#### `route.options.auth.access.entity` + +Default value: `'any'`. + +The required authenticated entity type. If set, must match the `entity` value of the request +authenticated credentials. Available values: + +- `'any'` - the authentication can be on behalf of a user or application. +- `'user'` - the authentication must be on behalf of a user which is identified by the presence of + a `'user'` attribute in the `credentials` object returned by the authentication strategy. +- `'app'` - the authentication must be on behalf of an application which is identified by the lack + of presence of a `user` attribute in the `credentials` object returned by the authentication + strategy. + +#### `route.options.auth.mode` + +Default value: `'required'`. + +The authentication mode. Available values: + +- `'required'` - authentication is required. +- `'optional'` - authentication is optional - the request must include valid credentials or no + credentials at all. +- `'try'` - similar to `'optional'`, any request credentials are attempted authentication, but if + the credentials are invalid, the request proceeds regardless of the authentication error. + +#### `route.options.auth.payload` + +Default value: `false`, unless the scheme requires payload authentication. + +If set, the incoming request payload is authenticated after it is processed. Requires a strategy +with payload authentication support (e.g. [Hawk](https://hapi.dev/family/hawk/api)). Cannot be +set to a value other than `'required'` when the scheme sets the authentication `options.payload` to +`true`. + +Available values: + +- `false` - no payload authentication. +- `'required'` - payload authentication required. +- `'optional'` - payload authentication performed only when the client includes payload + authentication information (e.g. `hash` attribute in Hawk). + +#### `route.options.auth.strategies` + +Default value: the default strategy set via [`server.auth.default()`](#server.auth.default()). + +An array of string strategy names in the order they should be attempted. Cannot be used together +with [`strategy`](#route.options.auth.strategy). + +#### `route.options.auth.strategy` + +Default value: the default strategy set via [`server.auth.default()`](#server.auth.default()). + +A string strategy names. Cannot be used together with [`strategies`](#route.options.auth.strategies). + +### `route.options.bind` + +Default value: `null`. + +An object passed back to the provided `handler` (via `this`) when called. Ignored if the method is +an arrow function. + +### `route.options.cache` + +Default value: `{ privacy: 'default', statuses: [200], otherwise: 'no-cache' }`. + +If the route method is 'GET', the route can be configured to include HTTP caching directives in the +response. Caching can be customized using an object with the following options: + +- `privacy` - determines the privacy flag included in client-side caching using the 'Cache-Control' + header. Values are: + - `'default'` - no privacy flag. + - `'public'` - mark the response as suitable for public caching. + - `'private'` - mark the response as suitable only for private caching. + +- `expiresIn` - relative expiration expressed in the number of milliseconds since the + item was saved in the cache. Cannot be used together with `expiresAt`. + +- `expiresAt` - time of day expressed in 24h notation using the 'HH:MM' format, at which + point all cache records for the route expire. Cannot be used together with `expiresIn`. + +- `statuses` - an array of HTTP response status code numbers (e.g. `200`) which are allowed to + include a valid caching directive. + +- `otherwise` - a string with the value of the 'Cache-Control' header when caching is disabled. + +The default `Cache-Control: no-cache` header can be disabled by setting `cache` to `false`. + +### `route.options.compression` + +An object where each key is a content-encoding name and each value is an object with the desired +encoder settings. Note that decoder settings are set in [`compression`](#route.options.payload.compression). + +### `route.options.cors` + +Default value: `false` (no CORS headers). + +The [Cross-Origin Resource Sharing](https://www.w3.org/TR/cors/) protocol allows browsers to make +cross-origin API calls. CORS is required by web applications running inside a browser which are +loaded from a different domain than the API server. To enable, set `cors` to `true`, or to an +object with the following options: + +- `origin` - an array of allowed origin servers strings ('Access-Control-Allow-Origin'). The array + can contain any combination of fully qualified origins along with origin strings containing a + wildcard `'*'` character, or a single `'*'` origin string. If set to `'ignore'`, any incoming + Origin header is ignored (present or not) and the 'Access-Control-Allow-Origin' header is set to + `'*'`. Defaults to any origin `['*']`. + +- `maxAge` - number of seconds the browser should cache the CORS response + ('Access-Control-Max-Age'). The greater the value, the longer it will take before the browser + checks for changes in policy. Defaults to `86400` (one day). + +- `headers` - a strings array of allowed headers ('Access-Control-Allow-Headers'). Defaults to + `['Accept', 'Authorization', 'Content-Type', 'If-None-Match']`. + +- `additionalHeaders` - a strings array of additional headers to `headers`. Use this to keep the + default headers in place. + +- `exposedHeaders` - a strings array of exposed headers ('Access-Control-Expose-Headers'). + Defaults to `['WWW-Authenticate', 'Server-Authorization']`. + +- `additionalExposedHeaders` - a strings array of additional headers to `exposedHeaders`. Use this + to keep the default headers in place. + +- `credentials` - if `true`, allows user credentials to be sent + ('Access-Control-Allow-Credentials'). Defaults to `false`. + +- `preflightStatusCode` - the status code used for CORS preflight responses, either `200` or `204`. + Defaults to `200`. + +### `route.options.description` + +Default value: none. + +Route description used for generating documentation (string). + +This setting is not available when setting server route defaults using +[`server.options.routes`](#server.options.routes). + +### `route.options.ext` + +Default value: none. + +Route-level [request extension points](#request-lifecycle) by setting the option to an object with +a key for each of the desired extension points (`'onRequest'` is not allowed), and the value is the +same as the [`server.ext(events)`](#server.ext()) `event` argument. + +### `route.options.files` + +Default value: `{ relativeTo: '.' }`. + +Defines the behavior for accessing files: + +- `relativeTo` - determines the folder relative paths are resolved against. + +### `route.options.handler` + +Default value: none. + +The route handler function performs the main business logic of the route and sets the response. +`handler` can be assigned: + +- a [lifecycle method](#lifecycle-methods). + +- an object with a single property using the name of a handler type registered with the + [`server.decorate()`](#server.decorate()) method. The matching property value is passed + as options to the registered handler generator. + +```js +const handler = function (request, h) { + return 'success'; +}; +``` + +Note: handlers using a fat arrow style function cannot be bound to any `bind` property. Instead, +the bound context is available under [`h.context`](#h.context). + +### `route.options.id` + +Default value: none. + +An optional unique identifier used to look up the route using [`server.lookup()`](#server.lookup()). +Cannot be assigned to routes added with an array of methods. + +### `route.options.isInternal` + +Default value: `false`. + +If `true`, the route cannot be accessed through the HTTP listener but only through the +[`server.inject()`](#server.inject()) interface with the `allowInternals` option set to `true`. +Used for internal routes that should not be accessible to the outside world. + +### `route.options.json` + +Default value: none. + +Optional arguments passed to `JSON.stringify()` when converting an object or error response to a +string payload or escaping it after stringification. Supports the following: + +- `replacer` - the replacer function or array. Defaults to no action. + +- `space` - number of spaces to indent nested object keys. Defaults to no indentation. + +- `suffix` - string suffix added after conversion to JSON string. Defaults to no suffix. + +- `escape` - calls [`Hoek.jsonEscape()`](https://hapi.dev/family/hoek/api/#escapejsonstring) + after conversion to JSON string. Defaults to `false`. + +### `route.options.log` + +Default value: `{ collect: false }`. + +Request logging options: + +- `collect` - if `true`, request-level logs (both internal and application) are collected and + accessible via [`request.logs`](#request.logs). + +### `route.options.notes` + +Default value: none. + +Route notes used for generating documentation (string or array of strings). + +This setting is not available when setting server route defaults using +[`server.options.routes`](#server.options.routes). + +### `route.options.payload` + +Determines how the request payload is processed. + +#### `route.options.payload.allow` + +Default value: allows parsing of the following mime types: + +- application/json +- application/\*+json +- application/octet-stream +- application/x-www-form-urlencoded +- multipart/form-data +- text/\* + +A string or an array of strings with the allowed mime types for the endpoint. Use this settings to +limit the set of allowed mime types. Note that allowing additional mime types not listed above will +not enable them to be parsed, and if [`parse`](#route.options.payload.parse) is `true`, the request +will result in an error response. + +#### `route.options.payload.compression` + +Default value: none. + +An object where each key is a content-encoding name and each value is an object with the desired +decoder settings. Note that encoder settings are set in [`compression`](#server.options.compression). + +#### `route.options.payload.defaultContentType` + +Default value: `'application/json'`. + +The default content type if the 'Content-Type' request header is missing. + +#### `route.options.payload.failAction` + +Default value: `'error'` (return a Bad Request (400) error response). + +A [`failAction` value](#lifecycle-failAction) which determines how to handle payload parsing +errors. + +#### `route.options.payload.maxBytes` + +Default value: `1048576` (1MB). + +Limits the size of incoming payloads to the specified byte count. Allowing very large payloads may +cause the server to run out of memory. + +#### `route.options.payload.maxParts` + +Default value: `1000`. + +Limits the number of parts allowed in multipart payloads. + +#### `route.options.payload.multipart` + +Default value: `false`. + +Overrides payload processing for multipart requests. Value can be one of: + +- `false` - disable multipart processing (this is the default value). + +- `true` - enable multipart processing using the [`output`](#route.options.payload.output) value. + +- an object with the following required options: + - `output` - same as the [`output`](#route.options.payload.output) option with an additional + value option: + - `annotated` - wraps each multipart part in an object with the following keys: + - `headers` - the part headers. + - `filename` - the part file name. + - `payload` - the processed part payload. + +#### `route.options.payload.output` + +Default value: `'data'`. + +The processed payload format. The value must be one of: + +- `'data'` - the incoming payload is read fully into memory. If [`parse`](#route.options.payload.parse) + is `true`, the payload is parsed (JSON, form-decoded, multipart) based on the 'Content-Type' + header. If [`parse`](#route.options.payload.parse) is `false`, a raw `Buffer` is returned. + +- `'stream'` - the incoming payload is made available via a `Stream.Readable` interface. If the + payload is 'multipart/form-data' and [`parse`](#route.options.payload.parse) is `true`, field + values are presented as text while files are provided as streams. File streams from a + 'multipart/form-data' upload will also have a `hapi` property containing the `filename` and + `headers` properties. Note that payload streams for multipart payloads are a synthetic interface + created on top of the entire multipart content loaded into memory. To avoid loading large + multipart payloads into memory, set [`parse`](#route.options.payload.parse) to `false` and handle + the multipart payload in the handler using a streaming parser (e.g. [**pez**](https://hapi.dev/family/pez/api)). + +- `'file'` - the incoming payload is written to temporary file in the directory specified by the + [`uploads`](#route.options.payload.uploads) settings. If the payload is 'multipart/form-data' and + [`parse`](#route.options.payload.parse) is `true`, field values are presented as text while files + are saved to disk. Note that it is the sole responsibility of the application to clean up the + files generated by the framework. This can be done by keeping track of which files are used (e.g. + using the `request.app` object), and listening to the server `'response'` event to perform + cleanup. + +#### `route.options.payload.override` + +Default value: none. + +A mime type string overriding the 'Content-Type' header value received. + +#### `route.options.payload.parse` + +Default value: `true`. + +Determines if the incoming payload is processed or presented raw. Available values: + +- `true` - if the request 'Content-Type' matches the allowed mime types set by + [`allow`](#route.options.payload.allow) (for the whole payload as well as parts), the payload is + converted into an object when possible. If the format is unknown, a Bad Request (400) error + response is sent. Any known content encoding is decoded. + +- `false` - the raw payload is returned unmodified. + +- `'gunzip'` - the raw payload is returned unmodified after any known content encoding is decoded. + +#### `route.options.payload.protoAction` + +Default value: `'error'`. + +Sets handling of incoming payload that may contain a prototype poisoning security attack. Available +values: + +- `'error'` - returns a `400` bad request error when the payload contains a prototype. + +- `'remove'` - sanitizes the payload to remove the prototype. + +- `'ignore'` - disables the protection and allows the payload to pass as received. Use this option + only when you are sure that such incoming data cannot pose any risks to your application. + +#### `route.options.payload.timeout` + +Default value: to `10000` (10 seconds). + +Payload reception timeout in milliseconds. Sets the maximum time allowed for the client to transmit +the request payload (body) before giving up and responding with a Request Timeout (408) error +response. + +Set to `false` to disable. + +#### `route.options.payload.uploads` + +Default value: `os.tmpdir()`. + +The directory used for writing file uploads. + +### `route.options.plugins` + +Default value: `{}`. + +Plugin-specific configuration. `plugins` is an object where each key is a plugin name and the value +is the plugin configuration. + +### `route.options.pre` + +Default value: none. + +The `pre` option allows defining methods for performing actions before the handler is called. These +methods allow breaking the handler logic into smaller, reusable components that can be shared +across routes, as well as provide a cleaner error handling of prerequisite operations (e.g. load +required reference data from a database). + +`pre` is assigned an ordered array of methods which are called serially in order. If the `pre` +array contains another array of methods as one of its elements, those methods are called in +parallel. Note that during parallel execution, if any of the methods error, return a +[takeover response](#takeover-response), or abort signal, the other parallel methods will continue +to execute but will be ignored once completed. + +`pre` can be assigned a mixed array of: + +- an array containing the elements listed below, which are executed in parallel. + +- an object with: + - `method` - a [lifecycle method](#lifecycle-methods). + - `assign` - key name used to assign the response of the method to in [`request.pre`](#request.pre) + and [`request.preResponses`](#request.preResponses). + - `failAction` - A [`failAction` value](#lifecycle-failAction) which determine what to do when + a pre-handler method throws an error. If `assign` is specified and the `failAction` setting + is not `'error'`, the error will be assigned. + +- a method function - same as including an object with a single `method` key. + +Note that pre-handler methods do not behave the same way other [lifecycle methods](#lifecycle-methods) +do when a value is returned. Instead of the return value becoming the new response payload, the +value is used to assign the corresponding [`request.pre`](#request.pre) and +[`request.preResponses`](#request.preResponses) properties. Otherwise, the handling of errors, +[takeover response](#takeover-response) response, or abort signal behave the same as any other +[lifecycle methods](#lifecycle-methods). + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +const pre1 = function (request, h) { + return 'Hello'; +}; + +const pre2 = function (request, h) { + return 'World'; +}; + +const pre3 = function (request, h) { + return request.pre.m1 + ' ' + request.pre.m2; +}; + +server.route({ + method: 'GET', + path: '/', + options: { + pre: [ + [ + // m1 and m2 executed in parallel + { method: pre1, assign: 'm1' }, + { method: pre2, assign: 'm2' }, + ], + { method: pre3, assign: 'm3' }, + ], + handler: function (request, h) { + return request.pre.m3 + '!\n'; + }, + }, +}); +``` + +### `route.options.response` + +Processing rules for the outgoing response. + +#### `route.options.response.disconnectStatusCode` + +Default value: `499`. + +The default HTTP status code used to set a response error when the request is closed or aborted +before the response is fully transmitted. Value can be any integer greater or equal to `400`. The +default value `499` is based on the non-standard nginx "CLIENT CLOSED REQUEST" error. The value is +only used for logging as the request has already ended. + +#### `route.options.response.emptyStatusCode` + +Default value: `204`. + +The default HTTP status code when the payload is considered empty. Value can be `200` or `204`. +Note that a `200` status code is converted to a `204` only at the time of response transmission +(the response status code will remain `200` throughout the request lifecycle unless manually set). + +#### `route.options.response.failAction` + +Default value: `'error'` (return an Internal Server Error (500) error response). + +A [`failAction` value](#lifecycle-failAction) which defines what to do when a response fails +payload validation. + +#### `route.options.response.modify` + +Default value: `false`. + +If `true`, applies the validation rule changes to the response payload. + +#### `route.options.response.options` + +Default value: none. + +[**joi**](https://joi.dev/api) options object pass to the validation function. Useful to set global options such as `stripUnknown` or `abortEarly`. If a custom validation function is defined via [`schema`](#route.options.response.schema) or [`status`](#route.options.response.status) then `options` can an arbitrary object that will be passed to this function as the second argument. + +#### `route.options.response.ranges` + +Default value: `true`. + +If `false`, payload [range](https://tools.ietf.org/html/rfc7233#section-3) support is disabled. + +#### `route.options.response.sample` + +Default value: `100` (all responses). + +The percent of response payloads validated (0 - 100). Set to `0` to disable all validation. + +#### `route.options.response.schema` + +Default value: `true` (no validation). + +The default response payload validation rules (for all non-error responses) expressed as one of: + +- `true` - any payload allowed (no validation). + +- `false` - no payload allowed. + +- a [**joi**](https://joi.dev/api) validation object. The [`options`](#route.options.response.options) + along with the request context (`{ headers, params, query, payload, state, app, auth }`) are passed to + the validation function. + +- a validation function using the signature `async function(value, options)` where: + - `value` - the pending response payload. + - `options` - The [`options`](#route.options.response.options) along with the request context + (`{ headers, params, query, payload, state, app, auth }`). + + - if the function returns a value and [`modify`](#route.options.response.modify) is `true`, + the value is used as the new response. If the original response is an error, the return + value is used to override the original error `output.payload`. If an error is thrown, the + error is processed according to [`failAction`](#route.options.response.failAction). + +#### `route.options.response.status` + +Default value: none. + +Validation schemas for specific HTTP status codes. Responses (excluding errors) not matching the +listed status codes are validated using the default [`schema`](#route.options.response.schema). + +`status` is set to an object where each key is a 3 digit HTTP status code and the value has the +same definition as [`schema`](#route.options.response.schema). + +### `route.options.rules` + +Default value: none. + +A custom rules object passed to each rules processor registered with [`server.rules()`](#server.rules()). + +### `route.options.security` + +Default value: `false` (security headers disabled). + +Sets common security headers. To enable, set `security` to `true` or to an object with the +following options: + +- `hsts` - controls the 'Strict-Transport-Security' header, where: + - `true` - the header will be set to `max-age=15768000`. This is the default value. + - a number - the maxAge parameter will be set to the provided value. + + - an object with the following fields: + - `maxAge` - the max-age portion of the header, as a number. Default is `15768000`. + - `includeSubDomains` - a boolean specifying whether to add the `includeSubDomains` flag to + the header. + - `preload` - a boolean specifying whether to add the `'preload'` flag (used to submit + domains inclusion in Chrome's HTTP Strict Transport Security (HSTS) preload list) to the + header. + +- `xframe` - controls the 'X-Frame-Options' header, where: + - `true` - the header will be set to `'DENY'`. This is the default value. + - `'deny'` - the headers will be set to `'DENY'`. + - `'sameorigin'` - the headers will be set to `'SAMEORIGIN'`. + + - an object for specifying the 'allow-from' rule, where: + - `rule` - one of: + - `'deny'` + - `'sameorigin'` + - `'allow-from'` + - `source` - when `rule` is `'allow-from'` this is used to form the rest of the header, + otherwise this field is ignored. If `rule` is `'allow-from'` but `source` is unset, the + rule will be automatically changed to `'sameorigin'`. + +- `xss` - controls the 'X-XSS-Protection' header, where: + - `'disabled'` - the header will be set to `'0'`. This is the default value. + - `'enabled'` - the header will be set to `'1; mode=block'`. + - `false` - the header will be omitted. + + Note: when enabled, this setting can create a security vulnerabilities in versions of Internet Explorer + below 8, unpatched versions of IE8, and browsers that employ an XSS filter/auditor. See + [here](https://hackademix.net/2009/11/21/ies-xss-filter-creates-xss-vulnerabilities/), + [here](https://technet.microsoft.com/library/security/ms10-002), and + [here](https://blog.innerht.ml/the-misunderstood-x-xss-protection/) for more information. + +- `noOpen` - boolean controlling the 'X-Download-Options' header for Internet Explorer, preventing + downloads from executing in your context. Defaults to `true` setting the header to `'noopen'`. + +- `noSniff` - boolean controlling the 'X-Content-Type-Options' header. Defaults to `true` setting + the header to its only and default option, `'nosniff'`. + +- `referrer` - controls the ['Referrer-Policy'](https://www.w3.org/TR/referrer-policy/) header, which has the following possible values. + - `false` - the 'Referrer-Policy' header will not be sent to clients with responses. This is the default value. + - `''` - instructs clients that the Referrer-Policy will be [defined elsewhere](https://www.w3.org/TR/referrer-policy/#referrer-policy-empty-string), such as in a meta html tag. + - `'no-referrer'` - instructs clients to never include the referrer header when making requests. + - `'no-referrer-when-downgrade'` - instructs clients to never include the referrer when navigating from HTTPS to HTTP. + - `'same-origin'` - instructs clients to only include the referrer on the current site origin. + - `'origin'` - instructs clients to include the referrer but strip off path information so that the value is the current origin only. + - `'strict-origin'` - same as `'origin'` but instructs clients to omit the referrer header when going from HTTPS to HTTP. + - `'origin-when-cross-origin'` - instructs clients to include the full path in the referrer header for same-origin requests but only the origin components of the URL are included for cross origin requests. + - `'strict-origin-when-cross-origin'` - same as `'origin-when-cross-origin'` but the client is instructed to omit the referrer when going from HTTPS to HTTP. + - `'unsafe-url'` - instructs the client to always include the referrer with the full URL. + +### `route.options.state` + +Default value: `{ parse: true, failAction: 'error' }`. + +HTTP state management (cookies) allows the server to store information on the client which is sent +back to the server with every request (as defined in [RFC 6265](https://tools.ietf.org/html/rfc6265)). +`state` supports the following options: + +- `parse` - determines if incoming 'Cookie' headers are parsed and stored in the + [`request.state`](#request.state) object. + +- `failAction` - A [`failAction` value](#lifecycle-failAction) which determines how to handle + cookie parsing errors. Defaults to `'error'` (return a Bad Request (400) error response). + +### `route.options.tags` + +Default value: none. + +Route tags used for generating documentation (array of strings). + +This setting is not available when setting server route defaults using +[`server.options.routes`](#server.options.routes). + +### `route.options.timeout` + +Default value: `{ server: false }`. + +Timeouts for processing durations. + +#### `route.options.timeout.server` + +Default value: `false`. + +Response timeout in milliseconds. Sets the maximum time allowed for the server to respond to an +incoming request before giving up and responding with a Service Unavailable (503) error response. + +#### `route.options.timeout.socket` + +Default value: none (use node default of 2 minutes). + +By default, node sockets automatically timeout after 2 minutes. Use this option to override this +behavior. Set to `false` to disable socket timeouts. + +### `route.options.validate` + +Default value: `{ headers: true, params: true, query: true, payload: true, state: true, failAction: 'error' }`. + +Request input validation rules for various request components. + +#### `route.options.validate.errorFields` + +Default value: none. + +An optional object with error fields copied into every validation error response. + +#### `route.options.validate.failAction` + +Default value: `'error'` (return a Bad Request (400) error response). + +A [`failAction` value](#lifecycle-failAction) which determines how to handle failed validations. +When set to a function, the `err` argument includes the type of validation error under +`err.output.payload.validation.source`. The default error that would otherwise have been logged +or returned can be accessed under `err.data.defaultError`. + +#### `route.options.validate.headers` + +Default value: `true` (no validation). + +Validation rules for incoming request headers: + +- `true` - any headers allowed (no validation performed). + +- a [**joi**](https://joi.dev/api) validation object. + +- a validation function using the signature `async function(value, options)` where: + - `value` - the [`request.headers`](#request.headers) object containing the request headers. + - `options` - [`options`](#route.options.validate.options). + - if a value is returned, the value is used as the new [`request.headers`](#request.headers) + value and the original value is stored in [`request.orig.headers`](#request.orig). + Otherwise, the headers are left unchanged. If an error is thrown, the error is handled + according to [`failAction`](#route.options.validate.failAction). + +Note that all header field names must be in lowercase to match the headers normalized by node. + +#### `route.options.validate.options` + +Default value: none. + +An options object passed to the [**joi**](https://joi.dev/api) rules or the custom +validation methods. Used for setting global options such as `stripUnknown` or `abortEarly`. + +If a custom validation function (see `headers`, `params`, `query`, or `payload` above) is defined +then `options` can an arbitrary object that will be passed to this function as the second +parameter. + +The values of the other inputs (i.e. `headers`, `query`, `params`, `payload`, `state`, `app`, and `auth`) +are added to the `options` object under the validation `context` (accessible in rules as +`Joi.ref('$query.key')`). + +Note that validation is performed in order (i.e. headers, params, query, and payload) and if type +casting is used (e.g. converting a string to a number), the value of inputs not yet validated will +reflect the raw, unvalidated and unmodified values. + +If the validation rules for `headers`, `params`, `query`, and `payload` are defined at both the +server [`routes`](#server.options.routes) level and at the route level, the individual route +settings override the routes defaults (the rules are not merged). + +#### `route.options.validate.params` + +Default value: `true` (no validation). + +Validation rules for incoming request path parameters, after matching the path against the route, +extracting any parameters, and storing them in [`request.params`](#request.params), where: + +- `true` - any path parameter value allowed (no validation performed). + +- a [**joi**](https://joi.dev/api) validation object. + +- a validation function using the signature `async function(value, options)` where: + - `value` - the [`request.params`](#request.params) object containing the request path + parameters. + - `options` - [`options`](#route.options.validate.options). + - if a value is returned, the value is used as the new [`request.params`](#request.params) + value and the original value is stored in [`request.orig.params`](#request.orig). Otherwise, + the path parameters are left unchanged. If an error is thrown, the error is handled according + to [`failAction`](#route.options.validate.failAction). + +Note that failing to match the validation rules to the route path parameters definition will cause +all requests to fail. + +#### `route.options.validate.payload` + +Default value: `true` (no validation). + +Validation rules for incoming request payload (request body), where: + +- `true` - any payload allowed (no validation performed). + +- `false` - no payload allowed. + +- a [**joi**](https://joi.dev/api) validation object. + - Note that empty payloads are represented by a `null` value. If a validation schema is + provided and empty payload are allowed, the schema must be explicitly defined by setting the + rule to a **joi** schema with `null` allowed (e.g. + `Joi.object({ /* keys here */ }).allow(null)`). + +- a validation function using the signature `async function(value, options)` where: + - `value` - the [`request.payload`](#request.payload) object containing the request payload. + - `options` - [`options`](#route.options.validate.options). + - if a value is returned, the value is used as the new [`request.payload`](#request.payload) + value and the original value is stored in [`request.orig.payload`](#request.orig). Otherwise, + the payload is left unchanged. If an error is thrown, the error is handled according to + [`failAction`](#route.options.validate.failAction). + +Note that validating large payloads and modifying them will cause memory duplication of the payload +(since the original is kept), as well as the significant performance cost of validating large +amounts of data. + +#### `route.options.validate.query` + +Default value: `true` (no validation). + +Validation rules for incoming request URI query component (the key-value part of the URI between +'?' and '#'). The query is parsed into its individual key-value pairs, decoded, and stored in +[`request.query`](#request.query) prior to validation. Where: + +- `true` - any query parameter value allowed (no validation performed). + +- `false` - no query parameter value allowed. + +- a [**joi**](https://joi.dev/api) validation object. + +- a validation function using the signature `async function(value, options)` where: + - `value` - the [`request.query`](#request.query) object containing the request query + parameters. + - `options` - [`options`](#route.options.validate.options). + - if a value is returned, the value is used as the new [`request.query`](#request.query) value + and the original value is stored in [`request.orig.query`](#request.orig). Otherwise, the + query parameters are left unchanged. If an error is thrown, the error is handled according to + [`failAction`](#route.options.validate.failAction). + +Note that changes to the query parameters will not be reflected in [`request.url`](#request.url). + +#### `route.options.validate.state` + +Default value: `true` (no validation). + +Validation rules for incoming cookies. The `cookie` header is parsed and decoded into the +[`request.state`](#request.state) prior to validation. Where: + +- `true` - any cookie value allowed (no validation performed). + +- `false` - no cookies allowed. + +- a [**joi**](https://joi.dev/api) validation object. + +- a validation function using the signature `async function(value, options)` where: + - `value` - the [`request.state`](#request.state) object containing all parsed cookie values. + - `options` - [`options`](#route.options.validate.options). + - if a value is returned, the value is used as the new [`request.state`](#request.state) value + and the original value is stored in [`request.orig.state`](#request.orig). Otherwise, the + cookie values are left unchanged. If an error is thrown, the error is handled according to + [`failAction`](#route.options.validate.failAction). + +#### `route.options.validate.validator` + +Default value: `null` (no default validator). + +Sets a server validation module used to compile raw validation rules into validation schemas (e.g. **joi**). + +Note: the validator is only used when validation rules are not pre-compiled schemas. When a validation rules is a function or schema object, the rule is used as-is and the validator is not used. + +## Request lifecycle + +Each incoming request passes through the request lifecycle. The specific steps vary based on the +server and route configurations, but the order in which the applicable steps are executed is always +the same. The following is the complete list of steps a request can go through: + +- _**onRequest**_ + - always called when `onRequest` extensions exist. + - the request path and method can be modified via the [`request.setUrl()`](#request.setUrl()) and [`request.setMethod()`](#request.setMethod()) methods. Changes to the request path or method will impact how the request is routed and can be used for rewrite rules. + - [`request.payload`](#request.payload) is `undefined` and can be overridden with any non-`undefined` value to bypass payload processing. + - [`request.route`](#request.route) is unassigned. + - [`request.url`](#request.url) can be `null` if the incoming request path is invalid. + - [`request.path`](#request.path) can be an invalid path. + +- _**Route lookup**_ + - lookup based on `request.path` and `request.method`. + - skips to _**onPreResponse**_ if no route is found or if the path violates the HTTP + specification. + +- _**Cookies processing**_ + - based on the route [`state`](#route.options.state) option. + - error handling based on [`failAction`](#route.options.state.failAction). + +- _**onPreAuth**_ + - called regardless if authentication is performed. + +- _**Authentication**_ + - based on the route [`auth`](#route.options.auth) option. + +- _**Payload processing**_ + - based on the route [`payload`](#route.options.payload) option and if [`request.payload`](#request.payload) has not been overridden in _**onRequest**_. + - error handling based on [`failAction`](#route.options.payload.failAction). + +- _**Payload authentication**_ + - based on the route [`auth`](#route.options.auth) option. + +- _**onCredentials**_ + - called only if authentication is performed. + +- _**Authorization**_ + - based on the route authentication [`access`](#route.options.auth.access) option. + +- _**onPostAuth**_ + - called regardless if authentication is performed. + +- _**Headers validation**_ + - based on the route [`validate.headers`](#route.options.validate.headers) option. + - error handling based on [`failAction`](#route.options.validate.failAction). + +- _**Path parameters validation**_ + - based on the route [`validate.params`](#route.options.validate.params) option. + - error handling based on [`failAction`](#route.options.validate.failAction). + +- _**Query validation**_ + - based on the route [`validate.query`](#route.options.validate.query) option. + - error handling based on [`failAction`](#route.options.validate.failAction). + +- _**Payload validation**_ + - based on the route [`validate.payload`](#route.options.validate.payload) option. + - error handling based on [`failAction`](#route.options.validate.failAction). + +- _**State validation**_ + - based on the route [`validate.state`](#route.options.validate.state) option. + - error handling based on [`failAction`](#route.options.validate.failAction). + +- _**onPreHandler**_ + +- _**Pre-handler methods**_ + - based on the route [`pre`](#route.options.pre) option. + - error handling based on each pre-handler method's `failAction` setting. + +- _**Route handler**_ + - executes the route [`handler`](#route.options.handler). + +- _**onPostHandler**_ + - the response contained in [`request.response`](#request.response) may be modified (but not + assigned a new value). To return a different response type (for example, replace an error + with an HTML response), return a new response value. + +- _**Response validation**_ + - error handling based on [`failAction`](#route.options.response.failAction). + +- _**onPreResponse**_ + - always called, unless the request is aborted. + - the response contained in [`request.response`](#request.response) may be modified (but not + assigned a new value). To return a different response type (for example, replace an error + with an HTML response), return a new response value. Note that any errors generated will not + be passed back to _**onPreResponse**_ to prevent an infinite loop. + +- _**Response transmission**_ + - may emit a [`'request'` event](#server.events.request) on the `'error'` channel. + +- _**Finalize request**_ + - emits `'response'` event. + +- _**onPostResponse**_ + - return value is ignored since the response is already set. + - emits a [`'request'` event](#server.events.request) on the `'error'` channel if an error is returned. + - all extension handlers are executed even if some error. + - note that since the handlers are executed in serial (each is `await`ed), care must be taken to avoid blocking execution if other extension handlers expect to be called immediately when the response is sent. If an _**onPostResponse**_ handler is performing IO, it should defer that activity to another tick and return immediately (either without a return value or without a promise that is solve to resolve). + +### Lifecycle methods + +Lifecycle methods are the interface between the framework and the application. Many of the request +lifecycle steps: [extensions](#server.ext()), [authentication](#authentication-scheme), +[handlers](#route.options.handler), [pre-handler methods](#route.options.pre), and +[`failAction` function values](#lifecycle-failAction) are lifecyle methods provided by the +developer and executed by the framework. + +Each lifecycle method is a function with the signature `await function(request, h, [err])` where: + +- `request` - the [request object](#request). +- `h` - the [response toolkit](#response-toolkit) the handler must call to set a response and + return control back to the framework. +- `err` - an error object available only when the method is used as a + [`failAction` value](#lifecycle-failAction). + +Each lifecycle method must return a value or a promise that resolves into a value. If a lifecycle +method returns without a value or resolves to an `undefined` value, an Internal Server Error (500) +error response is sent. + +The return value must be one of: + +- Plain value: + - `null` + - string + - number + - boolean +- `Buffer` object +- `Error` object + - plain `Error`. + - a [`Boom`](https://hapi.dev/family/boom/api) object. +- `Stream` object + - must be compatible with the "streams2" API and not be in `objectMode`. + - if the stream object has a `statusCode` property, that status code will be used as + the default response code based on the [`passThrough`](#response.settings.passThrough) + option. + - if the stream object has a `headers` property, the headers will be included in the response + based on the [`passThrough`](#response.settings.passThrough) option. + - if the stream object has a function property `setCompressor(compressor)` and the response + passes through a compressor, a reference to the compressor stream will be passed to the + response stream via this method. +- any object or array + - must not include circular references. +- a toolkit signal: + - [`h.abandon`](#h.abandon) - abort processing the request. + - [`h.close`](#h.close) - abort processing the request and call `end()` to ensure the response + is closed. + - [`h.continue`](#h.continue) - continue processing the request lifecycle without changing the + response. +- a toolkit method response: + - [`h.response()`](#h.response()) - wraps a plain response in a [response object](#response-object). + - [`h.redirect()`](#h.redirect()) - wraps a plain response with a redirection directive. + - [`h.authenticated()`](#h.authenticated()) - indicate request authenticated successfully + (auth scheme only). + - [`h.unauthenticated()`](#h.unauthenticated()) - indicate request failed to authenticate + (auth scheme only). +- a promise object that resolve to any of the above values + +Any error thrown by a lifecycle method will be used as the [response object](#response-object). While errors and valid +values can be returned, it is recommended to throw errors. Throwing non-error values will generate +a Bad Implementation (500) error response. + +```js +const handler = function (request, h) { + if (request.query.forbidden) { + throw Boom.badRequest(); + } + + return 'success'; +}; +``` + +If the route has a [`bind`](#route.options.bind) option or [`server.bind()`](#server.bind()) was +called, the lifecycle method will be bound to the provided context via `this` as well as accessible +via [`h.context`](#h.context). + +#### Lifecycle workflow + +The flow between each lifecycle step depends on the value returned by each lifecycle method as +follows: + +- an error: + - the lifecycle skips to the _**Response validation**_ step. + - if returned by the _**onRequest**_ step it skips to the _**onPreResponse**_ step. + - if returned by the _**Response validation**_ step it skips to the _**onPreResponse**_ step. + - if returned by the _**onPreResponse**_ step it skips to the _**Response transmission**_ step. + +- an abort signal ([`h.abandon`](#h.abandon) or [`h.close`](#h.close)): + - skips to the _**Finalize request**_ step. + +- a [`h.continue`](#h.continue) signal: + - continues processing the request lifecycle without changing the request response. + - cannot be used by the [`authenticate()`](#authentication-scheme) scheme method. + +- a [takeover response](#takeover-response): + - overrides the request response with the provided value and skips to the + _**Response validation**_ step. + - if returned by the _**Response validation**_ step it skips to the _**onPreResponse**_ step. + - if returned by the _**onPreResponse**_ step it skips to the _**Response transmission**_ step. + +- any other response: + - overrides the request response with the provided value and continues processing the request + lifecycle. + - cannot be returned from any step prior to the _**Pre-handler methods**_ step. + +The [`authenticate()`](#authentication-scheme) method has access to two additional return values: - [`h.authenticated()`](#h.authenticated()) - indicate request authenticated successfully. - [`h.unauthenticated()`](#h.unauthenticated()) - indicate request failed to authenticate. + +Note that these rules apply somewhat differently when used in a [pre-handler method](#route.options.pre). + +#### Takeover response + +A takeover response is a [`response object`](#response-object) on which [`response.takeover()`](#response.takever()) +was called to signal that the [lifecycle method](#lifecycle-methods) return value should be set as +the response and skip to immediately validate and trasmit the value, bypassing other lifecycle +steps. + +#### `failAction` configuration + +Various configuration options allows defining how errors are handled. For example, when invalid +payload is received or malformed cookie, instead of returning an error, the framework can be +configured to perform another action. When supported the `failAction` option supports the following +values: + +- `'error'` - return the error object as the response. +- `'log'` - report the error but continue processing the request. +- `'ignore'` - take no action and continue processing the request. + +- a [lifecycle method](#lifecycle-methods) with the signature `async function(request, h, err)` + where: + - `request` - the [request object](#request). + - `h` - the [response toolkit](#response-toolkit). + - `err` - the error object. + +#### Errors + +**hapi** uses the [**boom**](https://hapi.dev/family/boom/api) error library for all its internal +error generation. **boom** provides an expressive interface to return HTTP errors. Any error +thrown by a [lifecycle method](#lifecycle-methods) is converted into a **boom** object and defaults to status +code `500` if the error is not already a **boom** object. + +When the error is sent back to the client, the response contains a JSON object with the +`statusCode`, `error`, and `message` keys. + +```js +const Hapi = require('@hapi/hapi'); +const Boom = require('@hapi/boom'); + +const server = Hapi.server(); + +server.route({ + method: 'GET', + path: '/badRequest', + handler: function (request, h) { + throw Boom.badRequest('Unsupported parameter'); // 400 + }, +}); + +server.route({ + method: 'GET', + path: '/internal', + handler: function (request, h) { + throw new Error('unexpect error'); // 500 + }, +}); +``` + +##### Error transformation + +Errors can be customized by changing their `output` content. The **boom** error object includes the +following properties: + +- `isBoom` - if `true`, indicates this is a `Boom` object instance. + +- `message` - the error message. + +- `output` - the formatted response. Can be directly manipulated after object construction to + return a custom error response. Allowed root keys: + - `statusCode` - the HTTP status code (typically 4xx or 5xx). + + - `headers` - an object containing any HTTP headers where each key is a header name and value + is the header content. + + - `payload` - the formatted object used as the response payload. Can be directly + manipulated but any changes will be lost + if `reformat()` is called. Any content allowed and by default includes the following content: + - `statusCode` - the HTTP status code, derived from `error.output.statusCode`. + + - `error` - the HTTP status message (e.g. 'Bad Request', 'Internal Server Error') derived + from `statusCode`. + + - `message` - the error message derived from `error.message`. + +- inherited `Error` properties. + +It also supports the following method: + +- `reformat()` - rebuilds `error.output` using the other object properties. + +```js +const Boom = require('@hapi/boom'); + +const handler = function (request, h) { + + const error = Boom.badRequest('Cannot feed after midnight'); + error.output.statusCode = 499; // Assign a custom error code + error.reformat(); + error.output.payload.custom = 'abc_123'; // Add custom key + throw error; +}); +``` + +When a different error representation is desired, such as an HTML page or a different payload +format, the `'onPreResponse'` extension point may be used to identify errors and replace them with +a different [response object](#response-object), as in this example using [Vision's](https://hapi.dev/family/vision/api) +`.view()` [response toolkit](#response-toolkit) property. + +```js +const Hapi = require('@hapi/hapi'); +const Vision = require('@hapi/vision'); + +const server = Hapi.server({ port: 80 }); +server.register(Vision, (err) => { + server.views({ + engines: { + html: require('handlebars'), + }, + }); +}); + +const preResponse = function (request, h) { + const response = request.response; + if (!response.isBoom) { + return h.continue; + } + + // Replace error with friendly HTML + + const error = response; + const ctx = { + message: + error.output.statusCode === 404 + ? 'page not found' + : 'something went wrong', + }; + + return h.view('error', ctx).code(error.output.statusCode); +}; + +server.ext('onPreResponse', preResponse); +``` + +### Response Toolkit + +Access: read only. + +The response toolkit is a collection of properties and utilities passed to every +[lifecycle method](#lifecycle-methods). It is somewhat hard to define as it provides both +utilities for manipulating responses as well as other information. Since the toolkit is passed +as a function argument, developers can name it whatever they want. For the purpose of this document +the `h` notation is used. It is named in the spirit of the RethinkDB `r` method, with `h` for +**h**api. + +#### Toolkit properties + +##### `h.abandon` + +Access: read only. + +A response symbol. When returned by a lifecycle method, the request lifecycle skips to the +finalizing step without further interaction with the node response stream. It is the developer's +responsibility to write and end the response directly via [`request.raw.res`](#request.raw). + +##### `h.close` + +Access: read only. + +A response symbol. When returned by a lifecycle method, the request lifecycle skips to the +finalizing step after calling `request.raw.res.end())` to close the node response stream. + +##### `h.context` + +Access: read / write (will impact the shared context if the object is modified). + +A response symbol. Provides access to the route or server context set via the route +[`bind`](#route.options.bind) option or [`server.bind()`](#server.bind()). + +##### `h.continue` + +Access: read only. + +A response symbol. When returned by a lifecycle method, the request lifecycle continues without +changing the response. + +##### `h.realm` + +Access: read only. + +The [server realm](#server.realm) associated with the matching route. Defaults to the root server +realm in the _**onRequest**_ step. + +##### `h.request` + +Access: read only and public request interface. + +The [request] object. This is a duplication of the `request` lifecycle method argument used by +[toolkit decorations](#server.decorate()) to access the current request. + +#### `h.authenticated(data)` + +Used by the [authentication] method to pass back valid credentials where: + +- `data` - an object with: + - `credentials` - (required) object representing the authenticated entity. + - `artifacts` - (optional) authentication artifacts object specific to the authentication + scheme. + +Return value: an internal authentication object. + +#### `h.entity(options)` + +Sets the response 'ETag' and 'Last-Modified' headers and checks for any conditional request headers +to decide if the response is going to qualify for an HTTP 304 (Not Modified). If the entity values +match the request conditions, `h.entity()` returns a [response object](#response-object) for the lifecycle method to +return as its value which will set a 304 response. Otherwise, it sets the provided entity headers +and returns `undefined`. The method arguments are: + +- `options` - a required configuration object with: + - `etag` - the ETag string. Required if `modified` is not present. Defaults to no header. + - `modified` - the Last-Modified header value. Required if `etag` is not present. Defaults to + no header. + - `vary` - same as the [`response.etag()`](#response.etag()) option. Defaults to `true`. + +Return value: - a [response object](#response-object) if the response is unmodified. - `undefined` if the response has changed. + +If `undefined` is returned, the developer must return a valid lifecycle method value. If a response +is returned, it should be used as the return value (but may be customize using the response +methods). + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +server.route({ + method: 'GET', + path: '/', + options: { + cache: { expiresIn: 5000 }, + handler: function (request, h) { + const response = h.entity({ etag: 'abc' }); + if (response) { + response.header('X', 'y'); + return response; + } + + return 'ok'; + }, + }, +}); +``` + +#### `h.redirect(uri)` + +Redirects the client to the specified uri. Same as calling `h.response().redirect(uri)`. + +Returns a [response object](#response-object). + +```js +const handler = function (request, h) { + return h.redirect('http://example.com'); +}; +``` + +#### `h.response([value])` + +Wraps the provided value and returns a [`response`](#response-object) object which allows +customizing the response (e.g. setting the HTTP status code, custom headers, etc.), where: + +- `value` - (optional) return value. Defaults to `null`. + +Returns a [response object](#response-object). + +```js +// Detailed notation + +const handler = function (request, h) { + const response = h.response('success'); + response.type('text/plain'); + response.header('X-Custom', 'some-value'); + return response; +}; + +// Chained notation + +const handler = function (request, h) { + return h + .response('success') + .type('text/plain') + .header('X-Custom', 'some-value'); +}; +``` + +#### `h.state(name, value, [options])` + +Sets a response cookie using the same arguments as [`response.state()`](#response.state()). + +Return value: none. + +```js +const ext = function (request, h) { + h.state('cookie-name', 'value'); + return h.continue; +}; +``` + +#### `h.unauthenticated(error, [data])` + +Used by the [authentication] method to indicate authentication failed and pass back the credentials +received where: + +- `error` - (required) the authentication error. +- `data` - (optional) an object with: + - `credentials` - (required) object representing the authenticated entity. + - `artifacts` - (optional) authentication artifacts object specific to the authentication + scheme. + +The method is used to pass both the authentication error and the credentials. For example, if a +request included expired credentials, it allows the method to pass back the user information +(combined with a `'try'` authentication [`mode`](#route.options.auth.mode)) for error customization. + +There is no difference between throwing the error or passing it with the `h.unauthenticated()` +method if no credentials are passed, but it might still be helpful for code clarity. + +#### `h.unstate(name, [options])` + +Clears a response cookie using the same arguments as [`response.unstate()`](#response.unstate()). + +```js +const ext = function (request, h) { + h.unstate('cookie-name'); + return h.continue; +}; +``` + +### Response object + +The response object contains the request response value along with various HTTP headers and flags. +When a [lifecycle method](#lifecycle-methods) returns a value, the value is wrapped in a response +object along with some default flags (e.g. `200` status code). In order to customize a response +before it is returned, the [`h.response()`](#h.response()) method is provided. + +#### Response properties + +##### `response.app` + +Access: read / write. + +Default value: `{}`. + +Application-specific state. Provides a safe place to store application data without potential +conflicts with the framework. Should not be used by [plugins](#plugins) which should use +[`plugins[name]`](#response.plugins). + +##### `response.contentType` + +Access: read. + +Default value: none. + +Provides a preview of the response HTTP Content-Type header based on the implicit response type, any explicit Content-Type header set, and any content character-set defined. The returned value is only a preview as the content type can change later both internally and by user code (it represents current response state). The value is `null` if no implicit type can be determined. + +##### `response.events` + +Access: read only and the public **podium** interface. + +The `response.events` object supports the following events: + +- `'peek'` - emitted for each chunk of data written back to the client connection. The event method + signature is `function(chunk, encoding)`. + +- `'finish'` - emitted when the response finished writing but before the client response connection + is ended. The event method signature is `function ()`. + +```js +const Crypto = require('crypto'); +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +const preResponse = function (request, h) { + const response = request.response; + if (response.isBoom) { + return null; + } + + const hash = Crypto.createHash('sha1'); + response.events.on('peek', (chunk) => { + hash.update(chunk); + }); + + response.events.once('finish', () => { + console.log(hash.digest('hex')); + }); + + return h.continue; +}; + +server.ext('onPreResponse', preResponse); +``` + +##### `response.headers` + +Access: read only. + +Default value: `{}`. + +An object containing the response headers where each key is a header field name and the value is +the string header value or array of string. + +Note that this is an incomplete list of headers to be included with the response. Additional +headers will be added once the response is prepared for transmission. + +##### `response.plugins` + +Access: read / write. + +Default value: `{}`. + +Plugin-specific state. Provides a place to store and pass request-level plugin data. `plugins` is +an object where each key is a plugin name and the value is the state. + +##### `response.settings` + +Access: read only. + +Object containing the response handling flags. + +###### `response.settings.passThrough` + +Access: read only. + +Defaults value: `true`. + +If `true` and [`source`](#response.source) is a `Stream`, copies the `statusCode` and `headers` +properties of the stream object to the outbound response. + +###### `response.settings.stringify` + +Access: read only. + +Default value: `null` (use route defaults). + +Override the route [`json`](#route.options.json) options used when [`source`](#response.source) +value requires stringification. + +###### `response.settings.ttl` + +Access: read only. + +Default value: `null` (use route defaults). + +If set, overrides the route [`cache`](#route.options.cache) with an expiration value in +milliseconds. + +###### `response.settings.varyEtag` + +Default value: `false`. + +If `true`, a suffix will be automatically added to the 'ETag' header at transmission time +(separated by a `'-'` character) when the HTTP 'Vary' header is present. + +##### `response.source` + +Access: read only. + +The raw value returned by the [lifecycle method](#lifecycle-methods). + +##### `response.statusCode` + +Access: read only. + +Default value: `200`. + +The HTTP response status code. + +##### `response.variety` + +Access: read only. + +A string indicating the type of [`source`](#response.source) with available values: + +- `'plain'` - a plain response such as string, number, `null`, or simple object. +- `'buffer'` - a `Buffer`. +- `'stream'` - a `Stream`. + +#### `response.bytes(length)` + +Sets the HTTP 'Content-Length' header (to avoid chunked transfer encoding) where: + +- `length` - the header value. Must match the actual payload size. + +Return value: the current response object. + +#### `response.charset(charset)` + +Sets the 'Content-Type' HTTP header 'charset' property where: + +- `charset` - the charset property value. When `charset` value is falsy, it will prevent hapi from using its default charset setting. + +Return value: the current response object. + +#### `response.code(statusCode)` + +Sets the HTTP status code where: + +- `statusCode` - the HTTP status code (e.g. 200). + +Return value: the current response object. + +#### `response.message(httpMessage)` + +Sets the HTTP status message where: + +- `httpMessage` - the HTTP status message (e.g. 'Ok' for status code 200). + +Return value: the current response object. + +#### `response.compressed(encoding)` + +Sets the HTTP 'content-encoding' header where: + +- `encoding` - the header value string. + +Return value: the current response object. + +Note that setting content encoding via this method does not set a 'vary' HTTP header with 'accept-encoding' value. To vary the response, use the `response.header()` method instead. + +#### `response.created(uri)` + +Sets the HTTP status code to Created (201) and the HTTP 'Location' header where: + +- `uri` - an absolute or relative URI used as the 'Location' header value. + +Return value: the current response object. + +#### `response.encoding(encoding)` + +Sets the string encoding scheme used to serial data into the HTTP payload where: + +- `encoding` - the encoding property value (see [node Buffer encoding](https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings)). + +Return value: the current response object. + +#### `response.etag(tag, options)` + +Sets the representation [entity tag](https://tools.ietf.org/html/rfc7232#section-2.3) where: + +- `tag` - the entity tag string without the double-quote. + +- `options` - (optional) settings where: + - `weak` - if `true`, the tag will be prefixed with the `'W/'` weak signifier. Weak tags will + fail to match identical tags for the purpose of determining 304 response status. Defaults to + `false`. + + - `vary` - if `true` and content encoding is set or applied to the response (e.g 'gzip' or + 'deflate'), the encoding name will be automatically added to the tag at transmission time + (separated by a `'-'` character). Ignored when `weak` is `true`. Defaults to `true`. + +Return value: the current response object. + +#### `response.header(name, value, options)` + +Sets an HTTP header where: + +- `name` - the header name. + +- `value` - the header value. + +- `options` - (optional) object where: + - `append` - if `true`, the value is appended to any existing header value using `separator`. + Defaults to `false`. + + - `separator` - string used as separator when appending to an existing value. Defaults to `','`. + + - `override` - if `false`, the header value is not set if an existing value present. Defaults + to `true`. + + - `duplicate` - if `false`, the header value is not modified if the provided value is already + included. Does not apply when `append` is `false` or if the `name` is `'set-cookie'`. + Defaults to `true`. + +Return value: the current response object. + +#### `response.location(uri)` + +Sets the HTTP 'Location' header where: + +- `uri` - an absolute or relative URI used as the 'Location' header value. + +Return value: the current response object. + +#### `response.redirect(uri)` + +Sets an HTTP redirection response (302) and decorates the response with additional methods, where: + +- `uri` - an absolute or relative URI used to redirect the client to another resource. + +Return value: the current response object. + +Decorates the response object with the [`response.temporary()`](#response.temporary()), +[`response.permanent()`](#response.permanent()), and [`response.rewritable()`](#response.rewritable()) +methods to easily change the default redirection code (302). + +| | Permanent | Temporary | +| -------------- | --------- | --------- | +| Rewritable | 301 | 302 | +| Non-rewritable | 308 | 307 | + +#### `response.replacer(method)` + +Sets the `JSON.stringify()` `replacer` argument where: + +- `method` - the replacer function or array. Defaults to none. + +Return value: the current response object. + +#### `response.spaces(count)` + +Sets the `JSON.stringify()` `space` argument where: + +- `count` - the number of spaces to indent nested object keys. Defaults to no indentation. + +Return value: the current response object. + +#### `response.state(name, value, [options])` + +Sets an HTTP cookie where: + +- `name` - the cookie name. + +- `value` - the cookie value. If no `options.encoding` is defined, must be a string. See + [`server.state()`](#server.state()) for supported `encoding` values. + +- `options` - (optional) configuration. If the state was previously registered with the server + using [`server.state()`](#server.state()), the specified keys in `options` are merged with the + default server definition. + +Return value: the current response object. + +#### `response.suffix(suffix)` + +Sets a string suffix when the response is process via `JSON.stringify()` where: + +- `suffix` - the string suffix. + +Return value: the current response object. + +#### `response.ttl(msec)` + +Overrides the default route cache expiration rule for this response instance where: + +- `msec` - the time-to-live value in milliseconds. + +Return value: the current response object. + +#### `response.type(mimeType)` + +Sets the HTTP 'Content-Type' header where: + +- `mimeType` - is the mime type. + +Return value: the current response object. + +Should only be used to override the built-in default for each response type. + +#### `response.unstate(name, [options])` + +Clears the HTTP cookie by setting an expired value where: + +- `name` - the cookie name. +- `options` - (optional) configuration for expiring cookie. If the state was previously registered + with the server using [`server.state()`](#serverstatename-options), the specified `options` are + merged with the server definition. + +Return value: the current response object. + +#### `response.vary(header)` + +Adds the provided header to the list of inputs affected the response generation via the HTTP 'Vary' +header where: + +- `header` - the HTTP request header name. + +Return value: the current response object. + +#### `response.takeover()` + +Marks the response object as a [takeover response](#takeover-response). + +Return value: the current response object. + +#### `response.temporary(isTemporary)` + +Sets the status code to `302` or `307` (based on the [`response.rewritable()`](#response.rewriteable()) +setting) where: + +- `isTemporary` - if `false`, sets status to permanent. Defaults to `true`. + +Return value: the current response object. + +Only available after calling the [`response.redirect()`](#response.redirect()) method. + +#### `response.permanent(isPermanent)` + +Sets the status code to `301` or `308` (based on the [`response.rewritable()`](#response.rewritable()) +setting) where: + +- `isPermanent` - if `false`, sets status to temporary. Defaults to `true`. + +Return value: the current response object. + +Only available after calling the [`response.redirect()`](#response.redirect()) method. + +#### `response.rewritable(isRewritable)` + +Sets the status code to `301`/`302` for rewritable (allows changing the request method from 'POST' +to 'GET') or `307`/`308` for non-rewritable (does not allow changing the request method from 'POST' +to 'GET'). Exact code based on the [`response.temporary()`](#response.temporary()) or +[`response.permanent()`](#response.permanent()) setting. Arguments: + +- `isRewritable` - if `false`, sets to non-rewritable. Defaults to `true`. + +Return value: the current response object. + +Only available after calling the [`response.redirect()`](#response.redirect()) method. + +## Request + +The request object is created internally for each incoming request. It is not the same object +received from the node HTTP server callback (which is available via [`request.raw.req`](#request.raw)). +The request properties change throughout the [request lifecycle](#request-lifecycle). + +### Request properties + +#### `request.app` + +Access: read / write. + +Application-specific state. Provides a safe place to store application data without potential +conflicts with the framework. Should not be used by [plugins](#plugins) which should use +`plugins[name]`. + +#### `request.auth` + +Access: read only. + +Authentication information: + +- `artifacts` - an artifact object received from the authentication strategy and used in + authentication-related actions. + +- `credentials` - the `credential` object received during the authentication process. The + presence of an object does not mean successful authentication. + +- `error` - the authentication error if failed and mode set to `'try'`. + +- `isAuthenticated` - `true` if the request has been successfully authenticated, otherwise `false`. + +- `isAuthorized` - `true` is the request has been successfully authorized against the route + authentication [`access`](#route.options.auth.access) configuration. If the route has not + access rules defined or if the request failed authorization, set to `false`. + +- `isInjected` - `true` if the request has been authenticated via the + [`server.inject()`](#server.inject()) `auth` option, otherwise `undefined`. + +- `mode` - the route authentication mode. + +- `strategy` - the name of the strategy used. + +#### `request.events` + +Access: read only and the public **podium** interface. + +The `request.events` supports the following events: + +- `'peek'` - emitted for each chunk of payload data read from the client connection. The event + method signature is `function(chunk, encoding)`. + +- `'finish'` - emitted when the request payload finished reading. The event method signature is + `function ()`. + +- `'disconnect'` - emitted when a request errors or aborts unexpectedly. + +```js +const Crypto = require('crypto'); +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +const onRequest = function (request, h) { + const hash = Crypto.createHash('sha1'); + request.events.on('peek', (chunk) => { + hash.update(chunk); + }); + + request.events.once('finish', () => { + console.log(hash.digest('hex')); + }); + + request.events.once('disconnect', () => { + console.error('request aborted'); + }); + + return h.continue; +}; + +server.ext('onRequest', onRequest); +``` + +#### `request.headers` + +Access: read only. + +The raw request headers (references `request.raw.req.headers`). + +#### `request.info` + +Access: read only. + +Request information: + +- `acceptEncoding` - the request preferred encoding. + +- `completed` - request processing completion timestamp (`0` is still processing). + +- `cors` - request CORS information (available only after the `'onRequest'` extension point as CORS + is configured per-route and no routing decisions are made at that point in the request + lifecycle), where: + - `isOriginMatch` - `true` if the request 'Origin' header matches the configured CORS + restrictions. Set to `false` if no 'Origin' header is found or if it does not match. + +- `host` - content of the HTTP 'Host' header (e.g. 'example.com:8080'). + +- `hostname` - the hostname part of the 'Host' header (e.g. 'example.com'). + +- `id` - a unique request identifier (using the format '{now}:{server.info.id}:{5 digits counter}'). + +- `received` - request reception timestamp. + +- `referrer` - content of the HTTP 'Referrer' (or 'Referer') header. + +- `remoteAddress` - remote client IP address. + +- `remotePort` - remote client port. + +- `responded` - request response timestamp (`0` is not responded yet or response failed when `completed` is set). + +Note that the `request.info` object is not meant to be modified. + +#### `request.isInjected` + +Access: read only. + +`true` if the request was created via [`server.inject()`](#server.inject()), and `false` otherwise. + +#### `request.logs` + +Access: read only. + +An array containing the logged request events. + +Note that this array will be empty if route [`log.collect`](#route.options.log) is set to `false`. + +#### `request.method` + +Access: read only. + +The request method in lower case (e.g. `'get'`, `'post'`). + +#### `request.mime` + +Access: read only. + +The parsed content-type header. Only available when payload parsing enabled and no payload error occurred. + +#### `request.orig` + +Access: read only. + +An object containing the values of `params`, `query`, `payload` and `state` before any validation modifications made. Only set when input validation is performed. + +#### `request.params` + +Access: read only. + +An object where each key is a path parameter name with matching value as described in [Path parameters](#path-parameters). + +#### `request.paramsArray` + +Access: read only. + +An array containing all the path `params` values in the order they appeared in the path. + +#### `request.path` + +Access: read only. + +The request URI's [pathname](https://nodejs.org/api/url.html#url_urlobject_pathname) component. + +#### `request.payload` + +Access: read only / write in `'onRequest'` extension method. + +The request payload based on the route `payload.output` and `payload.parse` settings. Set to `undefined` in `'onRequest'` extension methods and can be overridden to any non-`undefined` value to bypass payload processing. + +#### `request.plugins` + +Access: read / write. + +Plugin-specific state. Provides a place to store and pass request-level plugin data. The `plugins` is an object where each key is a plugin name and the value is the state. + +#### `request.pre` + +Access: read only. + +An object where each key is the name assigned by a [route pre-handler methods](#route.options.pre) function. The values are the raw values provided to the continuation function as argument. For the wrapped response object, use `responses`. + +#### `request.response` + +Access: read / write (see limitations below). + +The response object when set. The object can be modified but must not be assigned another object. To replace the response with another from within an [extension point](#server.ext()), return a new response value. Contains an error when a request terminates prematurely when the client disconnects. + +#### `request.preResponses` + +Access: read only. + +Same as `pre` but represented as the response object created by the pre method. + +#### `request.query` + +Access: read only. + +An object where each key is a query parameter name and each matching value is the parameter value or an array of values if a parameter repeats. Can be modified indirectly via [request.setUrl](#request.setUrl()). + +#### `request.raw` + +Access: read only. + +An object containing the Node HTTP server objects. **Direct interaction with these raw objects is not recommended.** + +- `req` - the node request object. +- `res` - the node response object. + +#### `request.route` + +Access: read only. + +The request route information object, where: + +- `method` - the route HTTP method. +- `path` - the route path. +- `vhost` - the route vhost option if configured. +- `realm` - the [active realm](#server.realm) associated with the route. +- `settings` - the [route options](#route-options) object with all defaults applied. +- `fingerprint` - the route internal normalized string representing the normalized path. + +#### `request.server` + +Access: read only and the public server interface. + +The server object. + +#### `request.state` + +Access: read only. + +An object containing parsed HTTP state information (cookies) where each key is the cookie name and value is the matching cookie content after processing using any registered cookie definition. + +#### `request.url` + +Access: read only. + +The parsed request URI. + +### `request.generateResponse(source, [options])` + +Returns a [`response`](#response-object) which you can pass to [h.response()](#h.response()) where: + +- `source` - the value to set as the source of [h.response()](#h.response()), optional. +- `options` - optional object with the following optional properties: + - `variety` - a sting name of the response type (e.g. `'file'`). + - `prepare` - a function with the signature `async function(response)` used to prepare the response after it is returned by a [lifecycle method](#lifecycle-methods) such as setting a file descriptor, where: + - `response` - the response object being prepared. + - must return the prepared response object (`response`). + - may throw an error which is used as the prepared response. + - `marshal` - a function with the signature `async function(response)` used to prepare the response for transmission to the client before it is sent, where: + - `response` - the response object being marshaled. + - must return the prepared value (not as response object) which can be any value accepted by the [`h.response()`](#h.response()) `value` argument. + - may throw an error which is used as the marshaled value. + - `close` - a function with the signature `function(response)` used to close the resources opened by the response object (e.g. file handlers), where: + - `response` - the response object being marshaled. + - should not throw errors (which are logged but otherwise ignored). + +### `request.active()` + +Returns `true` when the request is active and processing should continue and `false` when the request terminated early or completed its lifecycle. Useful when request processing is a resource-intensive operation and should be terminated early if the request is no longer active (e.g. client disconnected or aborted early). + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +server.route({ + method: 'POST', + path: '/worker', + handler: function (request, h) { + // Do some work... + + // Check if request is still active + if (!request.active()) { + return h.close; + } + + // Do some more work... + + return null; + }, +}); +``` + +### `request.log(tags, [data])` + +Logs request-specific events. When called, the server emits a [`'request'` event](#server.events.request) +on the `'app'` channel which can be used by other listeners or [plugins](#plugins). The arguments +are: + +- `tags` - a string or an array of strings (e.g. `['error', 'database', 'read']`) used to identify + the event. Tags are used instead of log levels and provide a much more expressive mechanism for + describing and filtering events. +- `data` - (optional) an message string or object with the application data being logged. If `data` + is a function, the function signature is `function()` and it called once to generate (return + value) the actual data emitted to the listeners. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80, routes: { log: { collect: true } } }); + +server.events.on( + { name: 'request', channels: 'app' }, + (request, event, tags) => { + if (tags.error) { + console.log(event); + } + }, +); + +const handler = function (request, h) { + request.log(['test', 'error'], 'Test event'); + return null; +}; +``` + +Note that any logs generated by the server internally will be emitted using the +[`'request'` event](#server.events.request) on the `'internal'` channel. + +```js +server.events.on( + { name: 'request', channels: 'internal' }, + (request, event, tags) => { + console.log(event); + }, +); +``` + +### `request.route.auth.access(request)` + +Validates a request against the route's authentication [`access`](#route.options.auth.access) +configuration, where: + +- `request` - the [request object](#request). + +Return value: `true` if the `request` would have passed the route's access requirements. + +Note that the route's authentication mode and strategies are ignored. The only match is made +between the `request.auth.credentials` scope and entity information and the route +[`access`](#route.options.auth.access) configuration. + +If the route uses dynamic scopes, the scopes are constructed against the [`request.query`](#request.query), +[`request.params`](#request.params), [`request.payload`](#request.payload), and +[`request.auth.credentials`](#request.auth) which may or may not match between the route and the +request's route. If this method is called using a request that has not been authenticated (yet or +not at all), it will return `false` if the route requires any authentication. + +### `request.setMethod(method)` + +Changes the request method before the router begins processing the request where: + +- `method` - is the request HTTP method (e.g. `'GET'`). + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +const onRequest = function (request, h) { + // Change all requests to 'GET' + request.setMethod('GET'); + return h.continue; +}; + +server.ext('onRequest', onRequest); +``` + +Can only be called from an `'onRequest'` extension method. + +### `request.setUrl(url, [stripTrailingSlash]` + +Changes the request URI before the router begins processing the request where: + +- `url` - the new request URI. `url` can be a string or an instance of + [`Url.URL`](https://nodejs.org/dist/latest-v10.x/docs/api/url.html#url_class_url) in which case + `url.href` is used. +- `stripTrailingSlash` - if `true`, strip the trailing slash from the path. Defaults to `false`. + +```js +const Hapi = require('@hapi/hapi'); +const server = Hapi.server({ port: 80 }); + +const onRequest = function (request, h) { + // Change all requests to '/test' + request.setUrl('/test'); + return h.continue; +}; + +server.ext('onRequest', onRequest); +``` + +Can only be called from an `'onRequest'` extension method. + +## Plugins + +Plugins provide a way to organize application code by splitting the server logic into smaller +components. Each plugin can manipulate the server through the standard server interface, but with +the added ability to sandbox certain properties. For example, setting a file path in one plugin +doesn't affect the file path set in another plugin. + +A plugin is an object with the following properties: + +- `register` - (required) the registration function with the signature + `async function(server, options)` where: + - `server` - the server object with a plugin-specific [`server.realm`](#server.realm). + - `options` - any options passed to the plugin during registration via [`server.register()`](#server.register()). + +- `name` - (required) the plugin name string. The name is used as a unique key. Published plugins + (e.g. published in the npm registry) should use the same name as the name field in their + 'package.json' file. Names must be unique within each application. + +- `version` - (optional) plugin version string. The version is only used informatively to enable + other plugins to find out the versions loaded. The version should be the same as the one + specified in the plugin's 'package.json' file. + +- `multiple` - (optional) if `true`, allows the plugin to be registered multiple times with the same server. + Defaults to `false`. + +- `dependencies` - (optional) a string or an array of strings indicating a plugin dependency. Same + as setting dependencies via [`server.dependency()`](#server.dependency()). + +- `requirements` - (optional) object declaring the plugin supported [semver range](https://semver.org/) for: + - `node` runtime [semver range](https://nodejs.org/en/about/releases/) string. + - `hapi` framework [semver range](#server.version) string. + +- `once` - (optional) if `true`, will only register the plugin once per server. If set, overrides + the `once` option passed to [`server.register()`](#server.register()). Defaults to no override. + +```js +const plugin = { + name: 'test', + version: '1.0.0', + register: function (server, options) { + server.route({ + method: 'GET', + path: '/test', + handler: function (request, h) { + return 'ok'; + }, + }); + }, +}; +``` + +Alternatively, the `name` and `version` can be included via the `pkg` property containing the +'package.json' file for the module which already has the name and version included: + +```js +const plugin = { + pkg: require('./package.json'), + register: function (server, options) { + server.route({ + method: 'GET', + path: '/test', + handler: function (request, h) { + return 'ok'; + }, + }); + }, +}; +``` diff --git a/generated/markdown/hapi/changelog.md b/generated/markdown/hapi/changelog.md new file mode 100644 index 00000000..690ce110 --- /dev/null +++ b/generated/markdown/hapi/changelog.md @@ -0,0 +1,3030 @@ +## Version 21 {#v21} + +### [21.4.8](https://github.com/hapijs/hapi/milestone/329) {#21.4.8} + +- [#4568](https://github.com/hapijs/hapi/pull/4568) chore: bump deps + +### [21.4.7](https://github.com/hapijs/hapi/milestone/328) {#21.4.7} + +- [#4559](https://github.com/hapijs/hapi/pull/4559) fix: 🐛 request.url getter fails when using IPv6 and HTTP2 [#4560] + +### [21.4.6](https://github.com/hapijs/hapi/milestone/327) {#21.4.6} + +- [#4564](https://github.com/hapijs/hapi/pull/4564) Fix invalid hostname parsing for ipv6 formatted host header + +### [21.4.5](https://github.com/hapijs/hapi/milestone/326) {#21.4.5} + +- [#4562](https://github.com/hapijs/hapi/pull/4562) fix: auth typings and reduced type ambiguity +- [#4561](https://github.com/hapijs/hapi/issues/4561) Possible typing regression between v21.3.12 and v21.4.4 + +### [21.4.4](https://github.com/hapijs/hapi/milestone/325) {#21.4.4} + +- [#4557](https://github.com/hapijs/hapi/pull/4557) chore: update deps + +### [21.4.3](https://github.com/hapijs/hapi/milestone/324) {#21.4.3} + +- [#4553](https://github.com/hapijs/hapi/pull/4553) chore: bump dependencies +- [#4552](https://github.com/hapijs/hapi/pull/4552) Handle stream.destroy() called before stream end + +### [21.4.2](https://github.com/hapijs/hapi/milestone/323) {#21.4.2} + +- [#4550](https://github.com/hapijs/hapi/pull/4550) Correct type for state object + +### [21.4.1](https://github.com/hapijs/hapi/milestone/322) {#21.4.1} + +### [21.4.0](https://github.com/hapijs/hapi/milestone/321) {#21.4.0} + +- [#4545](https://github.com/hapijs/hapi/pull/4545) feat: add support for cookie partition +- [#4543](https://github.com/hapijs/hapi/pull/4543) Update event tags in documentation +- [#4542](https://github.com/hapijs/hapi/issues/4542) `request` `closed` `error` tags +- [#4540](https://github.com/hapijs/hapi/pull/4540) fix: 🐛 less ambigious plugin types +- [#4538](https://github.com/hapijs/hapi/pull/4538) fix: 🐛 typings around server.decorate +- [#4523](https://github.com/hapijs/hapi/pull/4523) fix: 🐛 accurate auth typings +- [#4515](https://github.com/hapijs/hapi/pull/4515) fix: 🐛 allow typed server methods access cache methods + +### [21.3.12](https://github.com/hapijs/hapi/milestone/320) {#21.3.12} + +- [#4533](https://github.com/hapijs/hapi/pull/4533) chore: bump hoek + +### [21.3.11](https://github.com/hapijs/hapi/milestone/319) {#21.3.11} + +- [#4532](https://github.com/hapijs/hapi/pull/4532) chore: bump all modules to their latest compatible version +- [#4531](https://github.com/hapijs/hapi/issues/4531) Asserts (and probably other Bounce.isSystem) loose stack trace +- [#4530](https://github.com/hapijs/hapi/pull/4530) Don't destroy incoming requests during the stopping phase +- [#4488](https://github.com/hapijs/hapi/pull/4488) Improve expect 100-continue handling + +### [21.3.10](https://github.com/hapijs/hapi/milestone/318) {#21.3.10} + +- [#4507](https://github.com/hapijs/hapi/pull/4507) fix: 🐛 route payload options missing types +- [#4501](https://github.com/hapijs/hapi/issues/4501) Missing maxParts type in route.d.ts + +### [21.3.9](https://github.com/hapijs/hapi/milestone/317) {#21.3.9} + +- [#4496](https://github.com/hapijs/hapi/pull/4496) types: allow server.match to receive lowercased methods + +### [21.3.8](https://github.com/hapijs/hapi/milestone/316) {#21.3.8} + +- [#4493](https://github.com/hapijs/hapi/pull/4493) Cleanup http methods typings +- [#4492](https://github.com/hapijs/hapi/issues/4492) HTTP_METHODS_PARTIAL_LOWERCASE is missing `head` + +### [21.3.7](https://github.com/hapijs/hapi/milestone/315) {#21.3.7} + +- [#4490](https://github.com/hapijs/hapi/pull/4490) Make content encoder and options explicitly typed and extensible + +### [21.3.6](https://github.com/hapijs/hapi/milestone/314) {#21.3.6} + +- [#4486](https://github.com/hapijs/hapi/pull/4486) Revert "fix(types): enhance reusability of pres" + +### [21.3.5](https://github.com/hapijs/hapi/milestone/313) {#21.3.5} + +- [#4471](https://github.com/hapijs/hapi/pull/4471) Don't return error response when clientError is a pipelined HPE_INVALID_METHOD +- [#4363](https://github.com/hapijs/hapi/issues/4363) Server crash: Error: Unknown error + +### [21.3.4](https://github.com/hapijs/hapi/milestone/312) {#21.3.4} + +- [#4470](https://github.com/hapijs/hapi/pull/4470) fix(types): enhance reusability of pres + +### [21.3.3](https://github.com/hapijs/hapi/milestone/311) {#21.3.3} + +- [#4473](https://github.com/hapijs/hapi/pull/4473) Node 20 fixes +- [#4460](https://github.com/hapijs/hapi/pull/4460) FIX add compressed to ResponseObject type +- [#4446](https://github.com/hapijs/hapi/pull/4446) failAction loses stacktrace context + +### [21.3.2](https://github.com/hapijs/hapi/milestone/310) {#21.3.2} + +- [#4449](https://github.com/hapijs/hapi/pull/4449) chore: use new statehood types + +### [21.3.1](https://github.com/hapijs/hapi/milestone/309) {#21.3.1} + +- [#4413](https://github.com/hapijs/hapi/pull/4413) Pass ServerApplicationState to server extensions + +### [21.3.0](https://github.com/hapijs/hapi/milestone/308) {#21.3.0} + +- [#4425](https://github.com/hapijs/hapi/issues/4425) Add option to limit maxParts in multipart payloads + +### [21.2.2](https://github.com/hapijs/hapi/milestone/306) {#21.2.2} + +- [#4417](https://github.com/hapijs/hapi/pull/4417) chore: bump hoek + +### [21.2.1](https://github.com/hapijs/hapi/milestone/304) {#21.2.1} + +- [#4422](https://github.com/hapijs/hapi/pull/4422) Update README.md +- [#4421](https://github.com/hapijs/hapi/pull/4421) adding colin to tsc members +- [#4415](https://github.com/hapijs/hapi/pull/4415) Correct the ResponseObject type + +### [21.2.0](https://github.com/hapijs/hapi/milestone/303) {#21.2.0} + +- [#4407](https://github.com/hapijs/hapi/pull/4407) Add type for preflight status code in cors options +- [#4402](https://github.com/hapijs/hapi/pull/4402) Updates to TypeScript definitions +- [#4401](https://github.com/hapijs/hapi/pull/4401) update types for xss +- [#4400](https://github.com/hapijs/hapi/pull/4400) Enhance plugin types + +### [21.1.0](https://github.com/hapijs/hapi/milestone/302) {#21.1.0} + +- [#4398](https://github.com/hapijs/hapi/pull/4398) Move TypeScript definition from DT (as-is) +- [#4396](https://github.com/hapijs/hapi/pull/4396) Fix handling of no remoteAddress available +- [#4391](https://github.com/hapijs/hapi/pull/4391) Fix node version requirement + +### [21.0.0](https://github.com/hapijs/hapi/milestone/300) {#21.0.0} + +- [#4386](https://github.com/hapijs/hapi/issues/4386) 21.0.0 Release Notes +- [#4366](https://github.com/hapijs/hapi/pull/4366) Allow matching prereleases when validating plugin version requirements +- [#4361](https://github.com/hapijs/hapi/pull/4361) Upgrade production deps for hapi v21 and node v18 +- [#4357](https://github.com/hapijs/hapi/pull/4357) Change default host to be IPv6-friendly +- [#4352](https://github.com/hapijs/hapi/pull/4352) Change XSS header default to '0' +- [#4351](https://github.com/hapijs/hapi/pull/4351) Change default CORS preflight status code w/ configuration +- [#4350](https://github.com/hapijs/hapi/pull/4350) Make default error available in validation failAction +- [#4349](https://github.com/hapijs/hapi/pull/4349) Enforce that response streams are always Stream.Readable +- [#4348](https://github.com/hapijs/hapi/pull/4348) Ignore return value from generateResponse() prepare method +- [#4346](https://github.com/hapijs/hapi/pull/4346) Drop node v12 support +- [#4288](https://github.com/hapijs/hapi/issues/4288) Add support for event loop utilization based load limit +- [#4271](https://github.com/hapijs/hapi/pull/4271) Remove JSONP support +- [#4229](https://github.com/hapijs/hapi/issues/4229) failAction: detailedError to log, defaultError to response + +## Version 20 {#v20} + +### [20.3.0](https://github.com/hapijs/hapi/milestone/307) {#20.3.0} + +### [20.2.2](https://github.com/hapijs/hapi/milestone/299) {#20.2.2} + +- [#4347](https://github.com/hapijs/hapi/issues/4347) Update hapijs/statehood to 7.0.4 from 7.0.3 +- [#4345](https://github.com/hapijs/hapi/pull/4345) Fix memory leaks from teamwork long standing notes +- [#4314](https://github.com/hapijs/hapi/pull/4314) Fix tests for node v17 +- [#4302](https://github.com/hapijs/hapi/pull/4302) Soft deprecate returning a new object from generateResponse() + +### [20.2.1](https://github.com/hapijs/hapi/milestone/298) {#20.2.1} + +- [#4295](https://github.com/hapijs/hapi/pull/4295) Revised request / inject abort handling +- [#4294](https://github.com/hapijs/hapi/issues/4294) Server crashes if a requested aborted during sending a response. +- [#4289](https://github.com/hapijs/hapi/pull/4289) Update server load default options on documentation +- [#4286](https://github.com/hapijs/hapi/pull/4286) Initialize server settings defaults + +### [20.2.0](https://github.com/hapijs/hapi/milestone/297) {#20.2.0} + +- [#4283](https://github.com/hapijs/hapi/pull/4283) Fix tests for node@16 error format change +- [#4281](https://github.com/hapijs/hapi/pull/4281) Fix handling of auth scheme/strategy realms +- [#4274](https://github.com/hapijs/hapi/pull/4274) Add optional payload authentication skip on credentials injection + +### [20.1.5](https://github.com/hapijs/hapi/milestone/296) {#20.1.5} + +- [#4264](https://github.com/hapijs/hapi/pull/4264) Fix req end during response transmission +- [#4262](https://github.com/hapijs/hapi/issues/4262) Streaming uploads cause truncated responses in node 16 + +### [20.1.4](https://github.com/hapijs/hapi/milestone/295) {#20.1.4} + +- [#4257](https://github.com/hapijs/hapi/pull/4257) Add response lifecycle tracking and checks +- [#4256](https://github.com/hapijs/hapi/issues/4256) inert + hapi may be leaking file descriptors + +### [20.1.3](https://github.com/hapijs/hapi/milestone/294) {#20.1.3} + +- [#4250](https://github.com/hapijs/hapi/pull/4250) Update to mimos v6 + +### [20.1.2](https://github.com/hapijs/hapi/milestone/293) {#20.1.2} + +- [#4239](https://github.com/hapijs/hapi/pull/4239) Fix abort test timing to be consistent from node v12 through v16 +- [#4231](https://github.com/hapijs/hapi/pull/4231) Update dependencies version range +- [#4225](https://github.com/hapijs/hapi/pull/4225) Future-proof hapi for node v16, rely on res close rather than req +- [#4095](https://github.com/hapijs/hapi/pull/4095) Rely on stream.destroy() whenever available + +### [20.1.1](https://github.com/hapijs/hapi/milestone/291) {#20.1.1} + +- [#4234](https://github.com/hapijs/hapi/pull/4234) Allow for res to have already closed during transmission + +### [20.1.0](https://github.com/hapijs/hapi/milestone/290) {#20.1.0} + +- [#4221](https://github.com/hapijs/hapi/pull/4221) Fix tests for citgm +- [#4219](https://github.com/hapijs/hapi/pull/4219) Add policy event +- [#4203](https://github.com/hapijs/hapi/pull/4203) Add closing event +- [#4194](https://github.com/hapijs/hapi/issues/4194) Add a 'closing' event +- [#4104](https://github.com/hapijs/hapi/issues/4104) Track cache policies + +### [20.0.3](https://github.com/hapijs/hapi/milestone/289) {#20.0.3} + +- [#4191](https://github.com/hapijs/hapi/pull/4191) Preserve original response status on error after write, fix status message +- [#4182](https://github.com/hapijs/hapi/issues/4182) server.inject does not reflect actual HTTP response in case of stream error + +### [20.0.2](https://github.com/hapijs/hapi/milestone/288) {#20.0.2} + +- [#4167](https://github.com/hapijs/hapi/pull/4167) upgrade to labv24 +- [#4089](https://github.com/hapijs/hapi/pull/4089) [default-scope] Accept default scope as a valid route scope +- [#4083](https://github.com/hapijs/hapi/issues/4083) Default auth scope not compatible with route auth scope + +### [20.0.1](https://github.com/hapijs/hapi/milestone/287) {#20.0.1} + +- [#4162](https://github.com/hapijs/hapi/pull/4162) Use response instead of request when marshalling +- [#4161](https://github.com/hapijs/hapi/pull/4161) fix: check if \_isPayloadSupported is set +- [#4156](https://github.com/hapijs/hapi/pull/4156) update handlebars dependency version + +### [20.0.0](https://github.com/hapijs/hapi/milestone/286) {#20.0.0} + +- [#4140](https://github.com/hapijs/hapi/pull/4140) update to travis templates +- [#4139](https://github.com/hapijs/hapi/pull/4139) update most out of date dependencies +- [#4138](https://github.com/hapijs/hapi/issues/4138) 20.0.0 Release Notes +- [#4134](https://github.com/hapijs/hapi/pull/4134) headers: avoid sending null content-type +- [#4133](https://github.com/hapijs/hapi/issues/4133) Content-type header is null when empty response is returned +- [#4132](https://github.com/hapijs/hapi/pull/4132) README needs this change to parse the slogan for site +- [#4130](https://github.com/hapijs/hapi/pull/4130) fixed teamwork version +- [#4123](https://github.com/hapijs/hapi/pull/4123) Removing the route timeout validation +- [#4122](https://github.com/hapijs/hapi/issues/4122) Payload timeout must be shorter than socket timeout +- [#4117](https://github.com/hapijs/hapi/pull/4117) Implement `isInjected` read-only request property to indicate request… +- [#4116](https://github.com/hapijs/hapi/issues/4116) Improved injected request detection +- [#4115](https://github.com/hapijs/hapi/pull/4115) Replace joi with validate +- [#4113](https://github.com/hapijs/hapi/issues/4113) The future of the hapi project + +## Version 19 {#v19} + +### [19.2.0](https://github.com/hapijs/hapi/milestone/278) {#19.2.0} + +- [#4077](https://github.com/hapijs/hapi/issues/4077) Decorate response object +- [#4073](https://github.com/hapijs/hapi/pull/4073) Add new ext onPostResponse +- [#4072](https://github.com/hapijs/hapi/issues/4072) Response Event For Aborted Requests Has Status Code Of 200 +- [#4051](https://github.com/hapijs/hapi/issues/4051) Expose (likely?) Content-Type on response object +- [#4041](https://github.com/hapijs/hapi/issues/4041) How to access catbox client instances through the framework? + +### [19.1.1](https://github.com/hapijs/hapi/milestone/277) {#19.1.1} + +- [#4043](https://github.com/hapijs/hapi/issues/4043) Update deps +- [#4027](https://github.com/hapijs/hapi/issues/4027) Problem with settings global request.payload.multipart to true in Hapi v19 + +### [19.1.0](https://github.com/hapijs/hapi/milestone/276) {#19.1.0} + +- [#4034](https://github.com/hapijs/hapi/issues/4034) request.info.remoteAddress / request.info.remotePort undefined after connection closed (request aborted) + +### [19.0.5](https://github.com/hapijs/hapi/milestone/275) {#19.0.5} + +- [#4026](https://github.com/hapijs/hapi/issues/4026) Update deps + +### [19.0.4](https://github.com/hapijs/hapi/milestone/274) {#19.0.4} + +- [#4022](https://github.com/hapijs/hapi/issues/4022) Revert #4021 + +### [19.0.3](https://github.com/hapijs/hapi/milestone/273) {#19.0.3} + +- [#4021](https://github.com/hapijs/hapi/issues/4021) Retain '' result in inject in 204 response + +### [19.0.2](https://github.com/hapijs/hapi/milestone/272) {#19.0.2} + +- [#4020](https://github.com/hapijs/hapi/pull/4020) support JSON.stringify() of request.info +- [#4019](https://github.com/hapijs/hapi/issues/4019) Feature request: custom toJSON() method for request.info + +### [19.0.1](https://github.com/hapijs/hapi/milestone/271) {#19.0.1} + +- [#4018](https://github.com/hapijs/hapi/issues/4018) Override request.url in setUrl() + +### [19.0.0](https://github.com/hapijs/hapi/milestone/254) {#19.0.0} + +- [#4017](https://github.com/hapijs/hapi/issues/4017) 19.0.0 Release Notes +- [#4015](https://github.com/hapijs/hapi/issues/4015) Do not override request.payload if set manually in onRequest +- [#4013](https://github.com/hapijs/hapi/issues/4013) Use private class fields +- [#4012](https://github.com/hapijs/hapi/issues/4012) Drop node 10 +- [#4011](https://github.com/hapijs/hapi/issues/4011) Change scoped plugins name handling +- [#4006](https://github.com/hapijs/hapi/issues/4006) server.validator() +- [#4002](https://github.com/hapijs/hapi/pull/4002) fix(auth): properly populate request.auth on failed auth +- [#4000](https://github.com/hapijs/hapi/issues/4000) auth scheme artifacts are dropped when mode is not 'try' +- [#3996](https://github.com/hapijs/hapi/pull/3996) Decorate requests with symbols with apply=true +- [#3995](https://github.com/hapijs/hapi/issues/3995) Fix ? in fragment part +- [#3987](https://github.com/hapijs/hapi/issues/3987) Support SameSite=None for cookies +- [#3977](https://github.com/hapijs/hapi/issues/3977) Remove request queue (options.load.concurrent) +- [#3976](https://github.com/hapijs/hapi/issues/3976) Update hapijs/joi to 16.0.1 from 15.1.1 +- [#3920](https://github.com/hapijs/hapi/issues/3920) Change routes.payload.multipart to false by default +- [#3919](https://github.com/hapijs/hapi/issues/3919) Change emptyStatusCode to 204 by default +- [#3910](https://github.com/hapijs/hapi/issues/3910) Drop support for node v8 + +## Version 18 {#v18} + +### [18.4.2](https://github.com/hapijs/hapi/milestone/279) {#18.4.2} + +- [#4110](https://github.com/hapijs/hapi/issues/4110) Update deps + +### [18.4.1](https://github.com/hapijs/hapi/milestone/270) {#18.4.1} + +- [#4046](https://github.com/hapijs/hapi/issues/4046) Update deps + +### [18.4.0](https://github.com/hapijs/hapi/milestone/269) {#18.4.0} + +- [#3975](https://github.com/hapijs/hapi/issues/3975) Support joi v16 +- [#3974](https://github.com/hapijs/hapi/issues/3974) Handle errors thrown during error response transmit +- [#3971](https://github.com/hapijs/hapi/pull/3971) Fix some corner case client errors +- [#3965](https://github.com/hapijs/hapi/issues/3965) Multiple leading slashes in path causes hostname to be parsed incorrectly +- [#3964](https://github.com/hapijs/hapi/issues/3964) Custom "content-encoding" without vary header +- [#3956](https://github.com/hapijs/hapi/issues/3956) ETags behind gateway that compresses responses +- [#3946](https://github.com/hapijs/hapi/pull/3946) Add support for Chrome Apps and WebExtensions + +### [18.3.2](https://github.com/hapijs/hapi/milestone/267) {#18.3.2} + +- [#3968](https://github.com/hapijs/hapi/pull/3968) v18.3.2 +- [#3967](https://github.com/hapijs/hapi/issues/3967) Update deps + +### [18.3.1](https://github.com/hapijs/hapi/milestone/266) {#18.3.1} + +- [#3943](https://github.com/hapijs/hapi/issues/3943) Revise list of hop-by-hop headers + +### [18.3.0](https://github.com/hapijs/hapi/milestone/264) {#18.3.0} + +- [#3945](https://github.com/hapijs/hapi/issues/3945) Support ext method timeout +- [#3944](https://github.com/hapijs/hapi/issues/3944) server.stop timeout does not apply to onPreStop extension point + +### [18.2.0](https://github.com/hapijs/hapi/milestone/259) {#18.2.0} + +- [#3941](https://github.com/hapijs/hapi/issues/3941) Change module namespace + +### [18.1.0](https://github.com/hapijs/hapi/milestone/257) {#18.1.0} + +- [#3922](https://github.com/hapijs/hapi/issues/3922) Update hapijs/bourne to 1.1.1 from 1.0.0 +- [#3917](https://github.com/hapijs/hapi/issues/3917) Expose bourne options + +### [18.0.1](https://github.com/hapijs/hapi/milestone/253) {#18.0.1} + +- [#3914](https://github.com/hapijs/hapi/issues/3914) Update hapijs/statehood to 6.0.9 from 6.0.8 +- [#3912](https://github.com/hapijs/hapi/issues/3912) Update hapijs/subtext to 6.0.12 from 6.0.11 +- [#3909](https://github.com/hapijs/hapi/issues/3909) Route validation should throw AssertionError + +### [18.0.0](https://github.com/hapijs/hapi/milestone/251) {#18.0.0} + +- [#3908](https://github.com/hapijs/hapi/issues/3908) Update hapijs/vise to 3.0.2 from 3.0.1 +- [#3907](https://github.com/hapijs/hapi/issues/3907) Update hapijs/teamwork to 3.0.3 from 3.0.2 +- [#3906](https://github.com/hapijs/hapi/issues/3906) Update hapijs/joi to 14.3.1 from 14.0.4 +- [#3905](https://github.com/hapijs/hapi/issues/3905) Update hapijs/boom to 7.3.0 from 7.2.2 +- [#3904](https://github.com/hapijs/hapi/issues/3904) Update hapijs/catbox to 10.0.6 from 10.0.5 +- [#3901](https://github.com/hapijs/hapi/issues/3901) Change request.info.responded to indicate success and add request.info.completed +- [#3900](https://github.com/hapijs/hapi/pull/3900) fix(transmit test): add missing await on team.work +- [#3898](https://github.com/hapijs/hapi/issues/3898) Error tag incorrectly set (node 11) +- [#3897](https://github.com/hapijs/hapi/pull/3897) Return credentials and artifacts from server.auth.test() +- [#3891](https://github.com/hapijs/hapi/issues/3891) No Content-Type header when returning a stream +- [#3887](https://github.com/hapijs/hapi/issues/3887) Change inject auth to object and require strategy name +- [#3884](https://github.com/hapijs/hapi/issues/3884) "Cannot set headers after they are sent to the client" after returning h.abandon +- [#3882](https://github.com/hapijs/hapi/pull/3882) Add validation for cookies (alt impl) +- [#3879](https://github.com/hapijs/hapi/pull/3879) Set cookie autoValue only when no value received +- [#3878](https://github.com/hapijs/hapi/issues/3878) Aborted requests show status code 200 in response event +- [#3876](https://github.com/hapijs/hapi/issues/3876) Rework cache provisioning apis +- [#3875](https://github.com/hapijs/hapi/issues/3875) Update hapijs/bounce to 1.2.3 from 1.2.2 +- [#3874](https://github.com/hapijs/hapi/issues/3874) Update hapijs/hoek to 6.1.2 from 6.0.2 +- [#3873](https://github.com/hapijs/hapi/issues/3873) Update hapijs/podium to 3.2.0 from 3.1.4 +- [#3871](https://github.com/hapijs/hapi/issues/3871) 18.0.0 Release Notes +- [#3870](https://github.com/hapijs/hapi/issues/3870) Update hapijs/catbox-memory to 4.0.1 from 3.1.3 +- [#3832](https://github.com/hapijs/hapi/issues/3832) Feature: built in cookie validation +- [#3831](https://github.com/hapijs/hapi/issues/3831) State autoValue function overwrites existing cookie value +- [#3822](https://github.com/hapijs/hapi/pull/3822) Use WHATWG URL for request.url + +## Version 17 {#v17} + +### [17.9.4](https://github.com/hapijs/hapi/milestone/292) {#17.9.4} + +- [#4226](https://github.com/hapijs/hapi/issues/4226) v17 fails to include response payload in POST requests + +### [17.9.3](https://github.com/hapijs/hapi/milestone/280) {#17.9.3} + +- [#4109](https://github.com/hapijs/hapi/issues/4109) Update deps + +### [17.9.2](https://github.com/hapijs/hapi/milestone/265) {#17.9.2} + +- [#4047](https://github.com/hapijs/hapi/issues/4047) Update deps +- [#4025](https://github.com/hapijs/hapi/issues/4025) Update deps + +### [17.9.0](https://github.com/hapijs/hapi/milestone/261) {#17.9.0} + +- [#3942](https://github.com/hapijs/hapi/issues/3942) Change module namespace v17 + +### [17.8.5](https://github.com/hapijs/hapi/milestone/260) {#17.8.5} + +- [#3903](https://github.com/hapijs/hapi/pull/3903) Handle signals in onRequest. Closes #3884 + +### [17.8.4](https://github.com/hapijs/hapi/milestone/258) {#17.8.4} + +- [#3921](https://github.com/hapijs/hapi/issues/3921) Update hapijs/bourne to 1.1.1 from 1.0.0 + +### [17.8.3](https://github.com/hapijs/hapi/milestone/256) {#17.8.3} + +- [#3915](https://github.com/hapijs/hapi/issues/3915) Shrinkwrap typo + +### [17.8.2](https://github.com/hapijs/hapi/milestone/255) {#17.8.2} + +- [#3913](https://github.com/hapijs/hapi/issues/3913) Update hapijs/statehood to 6.0.9 from 6.0.8 +- [#3911](https://github.com/hapijs/hapi/issues/3911) Update hapijs/subtext to 6.0.12 from 6.0.11 + +### [17.8.1](https://github.com/hapijs/hapi/milestone/252) {#17.8.1} + +- [#3886](https://github.com/hapijs/hapi/issues/3886) Protect against invalid strategy name in server.auth.verify() + +### [17.8.0](https://github.com/hapijs/hapi/milestone/250) {#17.8.0} + +- [#3885](https://github.com/hapijs/hapi/issues/3885) Support credentials verficiation + +### [17.7.0](https://github.com/hapijs/hapi/milestone/247) {#17.7.0} + +- [#3867](https://github.com/hapijs/hapi/issues/3867) Specify node, hapi, and plugin version requirements + +### [17.6.4](https://github.com/hapijs/hapi/milestone/245) {#17.6.4} + +- [#3863](https://github.com/hapijs/hapi/issues/3863) Remove engines + +### [17.6.3](https://github.com/hapijs/hapi/milestone/244) {#17.6.3} + +- [#3860](https://github.com/hapijs/hapi/issues/3860) Update hapijs/subtext to 6.0.10 from 6.0.9 + +### [17.6.2](https://github.com/hapijs/hapi/milestone/243) {#17.6.2} + +- [#3857](https://github.com/hapijs/hapi/issues/3857) Include shrinkwrap file in dist + +### [17.6.1](https://github.com/hapijs/hapi/milestone/242) {#17.6.1} + +- [#3856](https://github.com/hapijs/hapi/issues/3856) Update hapijs/vise to 3.0.1 from 3.0.0 +- [#3855](https://github.com/hapijs/hapi/issues/3855) Update hapijs/topo to 3.0.2 from 3.0.1 +- [#3854](https://github.com/hapijs/hapi/issues/3854) Update hapijs/subtext to 6.0.9 from 6.0.7 +- [#3853](https://github.com/hapijs/hapi/issues/3853) Update hapijs/statehood to 6.0.7 from 6.0.6 +- [#3852](https://github.com/hapijs/hapi/issues/3852) Update hapijs/shot to 4.0.6 from 4.0.5 +- [#3851](https://github.com/hapijs/hapi/issues/3851) Update hapijs/podium to 3.1.4 from 3.1.2 +- [#3850](https://github.com/hapijs/hapi/issues/3850) Update jshttp/mime-db to 1.37.0 from 1.35.0 +- [#3849](https://github.com/hapijs/hapi/issues/3849) Update hapijs/nigel to 3.0.3 from 3.0.1 +- [#3848](https://github.com/hapijs/hapi/issues/3848) Update hapijs/mimos to 4.0.1 from 4.0.0 +- [#3847](https://github.com/hapijs/hapi/issues/3847) Update hapijs/joi to 14.0.3 from 13.5.2 +- [#3846](https://github.com/hapijs/hapi/issues/3846) Update hueniverse/iron to 5.0.5 from 5.0.3 +- [#3845](https://github.com/hapijs/hapi/issues/3845) Update hapijs/heavy to 6.1.1 from 6.1.0 +- [#3844](https://github.com/hapijs/hapi/issues/3844) Update hapijs/catbox-memory to 3.1.3 from 3.1.2 +- [#3843](https://github.com/hapijs/hapi/issues/3843) Update hapijs/catbox to 10.0.4 from 10.0.3 +- [#3842](https://github.com/hapijs/hapi/issues/3842) Update hapijs/call to 5.0.2 from 5.0.1 +- [#3841](https://github.com/hapijs/hapi/issues/3841) Update hapijs/bounce to 1.2.1 from 1.2.0 +- [#3840](https://github.com/hapijs/hapi/issues/3840) Update hapijs/boom to 7.2.1 from 7.2.0 +- [#3839](https://github.com/hapijs/hapi/issues/3839) Update hapijs/b64 to 4.1.1 from 4.0.0 +- [#3838](https://github.com/hapijs/hapi/issues/3838) Update hapijs/ammo to 3.0.2 from 3.0.1 +- [#3837](https://github.com/hapijs/hapi/issues/3837) Update hapijs/accept to 3.1.2 from 3.0.2 +- [#3836](https://github.com/hapijs/hapi/issues/3836) Update hapijs/wreck to 14.1.2 from 14.0.2 +- [#3835](https://github.com/hapijs/hapi/issues/3835) Update hapijs/pez to 4.0.4 from 4.0.2 +- [#3834](https://github.com/hapijs/hapi/issues/3834) Update hapijs/nigel to 3.0.3 from 3.0.1 + +### [17.6.0](https://github.com/hapijs/hapi/milestone/241) {#17.6.0} + +- [#3827](https://github.com/hapijs/hapi/issues/3827) Expose request active status +- [#3826](https://github.com/hapijs/hapi/issues/3826) Update hapijs/catbox to 10.0.3 from 10.0.2 + +### [17.5.5](https://github.com/hapijs/hapi/milestone/240) {#17.5.5} + +- [#3821](https://github.com/hapijs/hapi/issues/3821) onPreResponse not called when error returned/rethrown from failAction of error resp validation + +### [17.5.4](https://github.com/hapijs/hapi/milestone/239) {#17.5.4} + +- [#3813](https://github.com/hapijs/hapi/issues/3813) redirecting in onRequest throws Cannot read property 'isOriginMatch' of null + +### [17.5.3](https://github.com/hapijs/hapi/milestone/238) {#17.5.3} + +- [#3808](https://github.com/hapijs/hapi/issues/3808) Update jshttp/mime-db to 1.35.0 from 1.33.0 +- [#3807](https://github.com/hapijs/hapi/issues/3807) Update hapijs/joi to 13.5.2 from 13.2.0 +- [#3792](https://github.com/hapijs/hapi/issues/3792) Global cors and security options not respected in 404 +- [#3782](https://github.com/hapijs/hapi/issues/3782) Content type on empty string payloads +- [#3728](https://github.com/hapijs/hapi/issues/3728) request.response should be null when response failed to transmit + +### [17.5.2](https://github.com/hapijs/hapi/milestone/237) {#17.5.2} + +- [#3801](https://github.com/hapijs/hapi/issues/3801) Update hapijs/cryptiles to 4.1.2 from 4.1.1 + +### [17.5.1](https://github.com/hapijs/hapi/milestone/236) {#17.5.1} + +- [#3796](https://github.com/hapijs/hapi/pull/3796) do not attach request decorations to a shared prototype, alternative approach. +- [#3718](https://github.com/hapijs/hapi/issues/3718) Request decorations leak across server instances in same process + +### [17.5.0](https://github.com/hapijs/hapi/milestone/235) {#17.5.0} + +- [#3791](https://github.com/hapijs/hapi/pull/3791) support symbol properties in server.decorate() + +### [17.4.0](https://github.com/hapijs/hapi/milestone/234) {#17.4.0} + +- [#3786](https://github.com/hapijs/hapi/issues/3786) Update hapijs/joi to 13.2.0 from 13.1.2 +- [#3785](https://github.com/hapijs/hapi/issues/3785) Update hapijs/ammo to 3.0.1 from 3.0.0 +- [#3784](https://github.com/hapijs/hapi/issues/3784) Update arb/big-time to 2.0.1 from 2.0.0 +- [#3775](https://github.com/hapijs/hapi/pull/3775) Add support for Referrer-Policy header + +### [17.3.1](https://github.com/hapijs/hapi/milestone/233) {#17.3.1} + +- [#3766](https://github.com/hapijs/hapi/pull/3766) Add PATCH to `created` status, better error msg +- [#3765](https://github.com/hapijs/hapi/pull/3765) Respect a response status schema of true + +### [17.3.0](https://github.com/hapijs/hapi/milestone/232) {#17.3.0} + +- [#3772](https://github.com/hapijs/hapi/issues/3772) Update hapijs/catbox-memory to 3.1.2 from 3.1.1 +- [#3771](https://github.com/hapijs/hapi/issues/3771) Update hapijs/nigel to 3.0.1 from 3.0.2 +- [#3770](https://github.com/hapijs/hapi/issues/3770) Update hapijs/pez to 4.0.2 from 4.0.1 +- [#3769](https://github.com/hapijs/hapi/issues/3769) Update hapijs/statehood to 6.0.6 from 6.0.5 +- [#3768](https://github.com/hapijs/hapi/issues/3768) Update hapijs/content to 4.0.5 from 4.0.4 +- [#3767](https://github.com/hapijs/hapi/issues/3767) server.control() + +### [17.2.3](https://github.com/hapijs/hapi/milestone/231) {#17.2.3} + +- [#3760](https://github.com/hapijs/hapi/issues/3760) Fix checksums + +### [17.2.2](https://github.com/hapijs/hapi/milestone/230) {#17.2.2} + +- [#3758](https://github.com/hapijs/hapi/issues/3758) Request log with function data sends incorrect data +- [#3741](https://github.com/hapijs/hapi/pull/3741) Replace new Buffer() + +### [17.2.1](https://github.com/hapijs/hapi/milestone/229) {#17.2.1} + +- [#3756](https://github.com/hapijs/hapi/issues/3756) Update hapijs/shot to 4.0.5 from 4.0.3 +- [#3755](https://github.com/hapijs/hapi/issues/3755) Update hapijs/joi to 13.1.2 from 13.0.1 +- [#3754](https://github.com/hapijs/hapi/issues/3754) Update jshttp/mime-db to 1.33.0 from 1.31.0 +- [#3753](https://github.com/hapijs/hapi/issues/3753) Update hapijs/hoek to 5.0.3 from 5.0.2 +- [#3752](https://github.com/hapijs/hapi/issues/3752) Update hapijs/content to 4.0.4 from 4.0.3 +- [#3751](https://github.com/hapijs/hapi/issues/3751) Update hueniverse/bounce to 1.2.0 from 1.0.3 +- [#3750](https://github.com/hapijs/hapi/issues/3750) Update hapijs/boom to 7.2.0 from 7.1.1 +- [#3717](https://github.com/hapijs/hapi/pull/3717) Prefer user added encoding over built-in +- [#3701](https://github.com/hapijs/hapi/issues/3701) Enable registered encoders to have higher priority than built-in + +### [17.2.0](https://github.com/hapijs/hapi/milestone/228) {#17.2.0} + +- [#3715](https://github.com/hapijs/hapi/issues/3715) Basic concurrent load queue +- [#3714](https://github.com/hapijs/hapi/issues/3714) Update hapijs/heavy to 6.1.0 from 6.0.0 +- [#3712](https://github.com/hapijs/hapi/issues/3712) Missing return in dispatch() +- [#3711](https://github.com/hapijs/hapi/issues/3711) Cache stop() errors are not handled +- [#3708](https://github.com/hapijs/hapi/issues/3708) Errors in "onPostStart" ext leave listener active forever +- [#3702](https://github.com/hapijs/hapi/pull/3702) Fix server method registered as object without options + +### [17.1.1](https://github.com/hapijs/hapi/milestone/227) {#17.1.1} + +- [#3688](https://github.com/hapijs/hapi/issues/3688) Hapi v17.0.2 cors origin + +### [17.1.0](https://github.com/hapijs/hapi/milestone/226) {#17.1.0} + +- [#3691](https://github.com/hapijs/hapi/issues/3691) Route rules +- [#3689](https://github.com/hapijs/hapi/pull/3689) Include method name in error +- [#3125](https://github.com/hapijs/hapi/issues/3125) Allow decoration overrides with parent access support + +### [17.0.2](https://github.com/hapijs/hapi/milestone/225) {#17.0.2} + +- [#3686](https://github.com/hapijs/hapi/issues/3686) Log errors thrown in custom response close method +- [#3679](https://github.com/hapijs/hapi/pull/3679) [enhancement] https accept-encoding header brotli for chrome +- [#3675](https://github.com/hapijs/hapi/issues/3675) Optimize accept-encoding for the most common headers +- [#3674](https://github.com/hapijs/hapi/issues/3674) Update hapijs/cryptiles to 4.1.1 from 4.1.0 + +### [17.0.1](https://github.com/hapijs/hapi/milestone/224) {#17.0.1} + +- [#3668](https://github.com/hapijs/hapi/issues/3668) Bypass authorization when authentication bypassed + +### [17.0.0](https://github.com/hapijs/hapi/milestone/221) {#17.0.0} + +- [#3665](https://github.com/hapijs/hapi/issues/3665) Rename route 'config' with 'options' +- [#3663](https://github.com/hapijs/hapi/pull/3663) Loosen sample and modify peer validator in the routeBase schema +- [#3662](https://github.com/hapijs/hapi/issues/3662) prerequisite returning empty string yields null on the pre object of request +- [#3658](https://github.com/hapijs/hapi/issues/3658) 17.0.0 Release Notes +- [#3657](https://github.com/hapijs/hapi/issues/3657) Update hapijs/vise to 3.0.0 from 2.0.2 +- [#3656](https://github.com/hapijs/hapi/issues/3656) Update hapijs/topo to 3.0.0 from 2.0.2 +- [#3655](https://github.com/hapijs/hapi/issues/3655) Update hapijs/podium to 3.1.2 from 1.3.0 +- [#3653](https://github.com/hapijs/hapi/issues/3653) Update hapijs/nigel to 3.0.0 from 2.0.2 +- [#3652](https://github.com/hapijs/hapi/issues/3652) Update hapijs/mimos to 4.0.0 from 3.0.3 +- [#3651](https://github.com/hapijs/hapi/issues/3651) Update jshttp/mime-db to 1.31.0 from 1.29.0 +- [#3650](https://github.com/hapijs/hapi/issues/3650) Update hueniverse/iron to 5.0.4 from 4.0.5 +- [#3649](https://github.com/hapijs/hapi/issues/3649) Update hapijs/hoek to 5.0.2 from 4.2.0 +- [#3648](https://github.com/hapijs/hapi/issues/3648) Update hapijs/cryptiles to 4.1.0 from 3.1.2 +- [#3647](https://github.com/hapijs/hapi/issues/3647) Update hapijs/content to 4.0.3 from 3.0.6 +- [#3646](https://github.com/hapijs/hapi/issues/3646) Update hapijs/catbox-memory to 3.1.1 from 2.0.4 +- [#3645](https://github.com/hapijs/hapi/issues/3645) Update hapijs/catbox to 10.0.2 from 7.1.5 +- [#3644](https://github.com/hapijs/hapi/issues/3644) Update hapijs/call to 5.0.1 from 4.0.2 +- [#3643](https://github.com/hapijs/hapi/issues/3643) Update hapijs/boom to 7.1.1 from 5.2.0 +- [#3642](https://github.com/hapijs/hapi/issues/3642) Update hapijs/b64 to 4.0.0 from 3.0.2 +- [#3641](https://github.com/hapijs/hapi/issues/3641) Update hapijs/ammo to 3.0.0 from 2.0.4 +- [#3640](https://github.com/hapijs/hapi/issues/3640) Update hapijs/accept to 3.0.2 from 2.1.4 +- [#3639](https://github.com/hapijs/hapi/issues/3639) Update hapijs/statehood to 6.0.5 from 5.0.3 +- [#3638](https://github.com/hapijs/hapi/issues/3638) Update hapijs/shot to 4.0.3 from 3.4.2 +- [#3637](https://github.com/hapijs/hapi/issues/3637) Update hapijs/heavy to 6.0.0 from 4.0.4 +- [#3636](https://github.com/hapijs/hapi/issues/3636) Update hapijs/wreck to 14.0.2 from 13.0.3 +- [#3635](https://github.com/hapijs/hapi/issues/3635) Expose payload and credentials to dynamic scopes +- [#3634](https://github.com/hapijs/hapi/issues/3634) onCredentials ext point +- [#3633](https://github.com/hapijs/hapi/issues/3633) Separate authorization (403) from authentication (401) +- [#3632](https://github.com/hapijs/hapi/pull/3632) Add negative test on registering plugin twice without `once` +- [#3631](https://github.com/hapijs/hapi/issues/3631) When event data is an error, field name is error +- [#3630](https://github.com/hapijs/hapi/issues/3630) Replace events 'internal` bool with 'channel' property +- [#3629](https://github.com/hapijs/hapi/issues/3629) Remove request.getLog() method +- [#3628](https://github.com/hapijs/hapi/issues/3628) Combine all request events into single event +- [#3627](https://github.com/hapijs/hapi/issues/3627) Remove server argument from 'route' event +- [#3626](https://github.com/hapijs/hapi/issues/3626) Update hapijs/subtext to 6.0.7 from 6.0.3 +- [#3625](https://github.com/hapijs/hapi/issues/3625) Update hapijs/pez to 4.0.1 from 2.1.5 +- [#3624](https://github.com/hapijs/hapi/issues/3624) Send 400 bad request on parse error +- [#3621](https://github.com/hapijs/hapi/issues/3621) Remove certain passThrough headers +- [#3618](https://github.com/hapijs/hapi/issues/3618) Replace plugin interface to object +- [#3616](https://github.com/hapijs/hapi/issues/3616) Change validation errors +- [#3615](https://github.com/hapijs/hapi/issues/3615) Normalize server methods to always return plain value +- [#3614](https://github.com/hapijs/hapi/issues/3614) Remove envelope from server.table() +- [#3613](https://github.com/hapijs/hapi/issues/3613) Combine server.handler() with server.decorate() +- [#3612](https://github.com/hapijs/hapi/issues/3612) Remove mode support from server.auth.strategy() +- [#3609](https://github.com/hapijs/hapi/issues/3609) Update hapijs/joi to 13.0.1 from 11.1.0 +- [#3607](https://github.com/hapijs/hapi/issues/3607) Normalize failAction across the entire framework +- [#3605](https://github.com/hapijs/hapi/issues/3605) Remove source argument from validation failAction method +- [#3604](https://github.com/hapijs/hapi/issues/3604) request.auth.strategy is not documented +- [#3602](https://github.com/hapijs/hapi/pull/3602) exclude connection header in response passThrough +- [#3599](https://github.com/hapijs/hapi/issues/3599) Provide a way to flush compression stream on demand +- [#3598](https://github.com/hapijs/hapi/pull/3598) Implement wildcardIgnoresOrigin CORS option +- [#3597](https://github.com/hapijs/hapi/issues/3597) Rename reply interface to toolkit +- [#3596](https://github.com/hapijs/hapi/issues/3596) Move request.id to request.info.id +- [#3595](https://github.com/hapijs/hapi/issues/3595) Explicit Context +- [#3594](https://github.com/hapijs/hapi/issues/3594) Support compression minimum length +- [#3592](https://github.com/hapijs/hapi/issues/3592) Change reply interface from function to object +- [#3591](https://github.com/hapijs/hapi/issues/3591) Normalize lifecycle +- [#3590](https://github.com/hapijs/hapi/issues/3590) Remove HTML escaping of joi errors +- [#3589](https://github.com/hapijs/hapi/issues/3589) Move request and server events to `events` getter +- [#3583](https://github.com/hapijs/hapi/issues/3583) Reduce request internal logging +- [#3580](https://github.com/hapijs/hapi/issues/3580) Remove server methods string handlers shortcut +- [#3579](https://github.com/hapijs/hapi/pull/3579) v17 rc 4 +- [#3574](https://github.com/hapijs/hapi/issues/3574) Move all server events to server.events +- [#3573](https://github.com/hapijs/hapi/issues/3573) Remove domains +- [#3572](https://github.com/hapijs/hapi/issues/3572) Remove support for multiple connection in a single server +- [#3571](https://github.com/hapijs/hapi/issues/3571) Drop support for request tails +- [#3567](https://github.com/hapijs/hapi/issues/3567) response validate options for 'modify' and 'sample' is too strict +- [#3509](https://github.com/hapijs/hapi/issues/3509) Return 413 when payload is too big +- [#3434](https://github.com/hapijs/hapi/issues/3434) Validate params rules against path params +- [#3423](https://github.com/hapijs/hapi/issues/3423) CDN friendly CORS: remove "Vary: Origin" for wildcard CORS origins +- [#3334](https://github.com/hapijs/hapi/issues/3334) Handle multiple parallel registrations +- [#3297](https://github.com/hapijs/hapi/issues/3297) Pass plugin's server rather than root server to route config function +- [#3152](https://github.com/hapijs/hapi/issues/3152) reply.code(value) ignored when payload is empty and emptyStatusCode is set +- [#3150](https://github.com/hapijs/hapi/issues/3150) server.method doesn't resolve promise with cache options +- [#3066](https://github.com/hapijs/hapi/issues/3066) Allow access to parent realm + +## Version 16 {#v16} + +### [16.8.3](https://github.com/hapijs/hapi/milestone/281) {#16.8.3} + +- [#4108](https://github.com/hapijs/hapi/issues/4108) Support node 12 + +### [16.8.2](https://github.com/hapijs/hapi/milestone/268) {#16.8.2} + +- [#4048](https://github.com/hapijs/hapi/issues/4048) Update deps + +### [16.8.1](https://github.com/hapijs/hapi/milestone/263) {#16.8.1} + +- [#3960](https://github.com/hapijs/hapi/issues/3960) Send 400 bad request on parse error + +### [16.8.0](https://github.com/hapijs/hapi/milestone/262) {#16.8.0} + +- [#3937](https://github.com/hapijs/hapi/issues/3937) 16.8.0-Commercial Release Notes +- [#3933](https://github.com/hapijs/hapi/issues/3933) v16 commercial license version +- [#3932](https://github.com/hapijs/hapi/issues/3932) Discontinued support for hapi v16 +- [#3899](https://github.com/hapijs/hapi/issues/3899) v16: look into compatibility with node 10 + +### [16.7.0](https://github.com/hapijs/hapi/milestone/249) {#16.7.0} + +- [#3869](https://github.com/hapijs/hapi/issues/3869) Specify node, hapi, and plugin version requirements (#3867) + +### [16.6.5](https://github.com/hapijs/hapi/milestone/248) {#16.6.5} + +- [#3866](https://github.com/hapijs/hapi/issues/3866) Remove engines + +### [16.6.4](https://github.com/hapijs/hapi/milestone/246) {#16.6.4} + +- [#3862](https://github.com/hapijs/hapi/issues/3862) Remove support for node 4 +- [#3861](https://github.com/hapijs/hapi/issues/3861) Remove shrinkwrap + +### [16.6.2](https://github.com/hapijs/hapi/milestone/223) {#16.6.2} + +- [#3586](https://github.com/hapijs/hapi/issues/3586) Remove per-response events emitter validation + +### [16.6.1](https://github.com/hapijs/hapi/milestone/222) {#16.6.1} + +- [#3585](https://github.com/hapijs/hapi/issues/3585) Update hapijs/joi to 11.1.0 from 10.6.0 +- [#3582](https://github.com/hapijs/hapi/pull/3582) Support joi 11 paths arrays. Fixes #3581. + +### [16.6.0](https://github.com/hapijs/hapi/milestone/220) {#16.6.0} + +- [#3570](https://github.com/hapijs/hapi/issues/3570) Update hapijs/content to 3.0.6 from 3.0.5 +- [#3560](https://github.com/hapijs/hapi/pull/3560) fix response.message(httpMessage) +- [#3506](https://github.com/hapijs/hapi/pull/3506) Add json escape option + +### [16.5.2](https://github.com/hapijs/hapi/milestone/219) {#16.5.2} + +- [#3561](https://github.com/hapijs/hapi/issues/3561) Aborted responses return 200 code in inject + +### [16.5.1](https://github.com/hapijs/hapi/milestone/218) {#16.5.1} + +- [#3552](https://github.com/hapijs/hapi/issues/3552) Updating from 16.4.3 to 16.5.0: Podium.decorate is not a function error +- [#3528](https://github.com/hapijs/hapi/issues/3528) "disconnect" event on the "request" object is never emitted + +### [16.5.0](https://github.com/hapijs/hapi/milestone/217) {#16.5.0} + +- [#3551](https://github.com/hapijs/hapi/issues/3551) Update hapijs/statehood to 5.0.3 from 5.0.2 +- [#3550](https://github.com/hapijs/hapi/issues/3550) Update hapijs/content to 3.0.5 from 3.0.4 +- [#3548](https://github.com/hapijs/hapi/issues/3548) Update hapijs/boom to 5.2.0 from 5.1.0 +- [#3545](https://github.com/hapijs/hapi/issues/3545) Update hapijs/joi to 10.6.0 from 10.5.2 +- [#3544](https://github.com/hapijs/hapi/issues/3544) Update jshttp/mime-db to 1.29.0 from 1.28.0 +- [#3543](https://github.com/hapijs/hapi/issues/3543) Update hapijs/catbox to 7.1.5 from 7.1.4 +- [#3542](https://github.com/hapijs/hapi/issues/3542) Update hapijs/podium to 1.3.0 from 1.2.5 +- [#3541](https://github.com/hapijs/hapi/issues/3541) Update hapijs/hoek to 4.2.0 from 4.1.1 +- [#3539](https://github.com/hapijs/hapi/pull/3539) Add payload fail action custom handler +- [#3533](https://github.com/hapijs/hapi/issues/3533) Update hapijs/subtext to 5.0.0 from 4.4.1 +- [#3532](https://github.com/hapijs/hapi/issues/3532) Remove joi validation when creating request podium events +- [#3531](https://github.com/hapijs/hapi/pull/3531) Return 413 when payload too large. +- [#3526](https://github.com/hapijs/hapi/pull/3526) Consider wildcard filtering for debug options +- [#3523](https://github.com/hapijs/hapi/pull/3523) Update lab and fix indentation +- [#3520](https://github.com/hapijs/hapi/pull/3520) Fixed validation of server's Joi options +- [#3519](https://github.com/hapijs/hapi/pull/3519) allow decoration of reply with non functions +- [#3516](https://github.com/hapijs/hapi/issues/3516) Invalid cookie header despite strictHeader: false, ignoreErrors: true +- [#3483](https://github.com/hapijs/hapi/issues/3483) Filename detecting problem on uploading file with apostrophes +- [#3480](https://github.com/hapijs/hapi/issues/3480) RST packet instead of a FIN packet to close the response on Heroku +- [#3464](https://github.com/hapijs/hapi/issues/3464) Throwing inside response event breaks new events + +### [16.4.3](https://github.com/hapijs/hapi/milestone/216) {#16.4.3} + +- [#3514](https://github.com/hapijs/hapi/issues/3514) TypeError: Cannot set property 'hostname' of undefined + +### [16.4.2](https://github.com/hapijs/hapi/milestone/215) {#16.4.2} + +- [#3517](https://github.com/hapijs/hapi/issues/3517) Restore npm-shrinkwrap.json file + +### [16.4.1](https://github.com/hapijs/hapi/milestone/214) {#16.4.1} + +- [#3512](https://github.com/hapijs/hapi/issues/3512) Remove npm-shrinkwrap + +### [16.4.0](https://github.com/hapijs/hapi/milestone/213) {#16.4.0} + +- [#3511](https://github.com/hapijs/hapi/issues/3511) Update hapijs/joi to 10.5.2 from 10.5.1 +- [#3505](https://github.com/hapijs/hapi/issues/3505) Remove isemail deps from shrinkwrap +- [#3486](https://github.com/hapijs/hapi/pull/3486) Provide cover for unhandled rejections +- [#3429](https://github.com/hapijs/hapi/issues/3429) Better support for async handlers + +### [16.3.1](https://github.com/hapijs/hapi/milestone/212) {#16.3.1} + +- [#3510](https://github.com/hapijs/hapi/issues/3510) Update hapijs/shot to 3.4.2 from 3.4.0 +- [#3507](https://github.com/hapijs/hapi/pull/3507) Node 8 fixes + +### [16.3.0](https://github.com/hapijs/hapi/milestone/211) {#16.3.0} + +- [#3461](https://github.com/hapijs/hapi/pull/3461) explicitly destroy sockets on clientError +- [#3441](https://github.com/hapijs/hapi/pull/3441) Fix several request.url property issues on setUrl() +- [#3409](https://github.com/hapijs/hapi/pull/3409) Adding server.inspect to list decorated framework interfaces + +### [16.2.0](https://github.com/hapijs/hapi/milestone/210) {#16.2.0} + +- [#3502](https://github.com/hapijs/hapi/issues/3502) Update hapijs/wreck to 12.2.2 from 10.0.0 +- [#3501](https://github.com/hapijs/hapi/issues/3501) Update hapijs/subtext to 4.4.1 from 4.3.0 +- [#3500](https://github.com/hapijs/hapi/issues/3500) Update hapijs/statehood to 5.0.2 from 5.0.1 +- [#3499](https://github.com/hapijs/hapi/issues/3499) Update hapijs/pez to 2.1.5 from 2.1.4 +- [#3498](https://github.com/hapijs/hapi/issues/3498) Update jshttp/mime-db to 1.28.0 from 1.25.0 +- [#3497](https://github.com/hapijs/hapi/issues/3497) Update hapijs/joi to 10.5.1 from 10.1.0 +- [#3496](https://github.com/hapijs/hapi/issues/3496) Update hueniverse/iron to 4.0.5 from 4.0.4 +- [#3495](https://github.com/hapijs/hapi/issues/3495) Update hapijs/hoek to 4.1.1 from 4.1.0 +- [#3494](https://github.com/hapijs/hapi/issues/3494) Update hapijs/heavy to 4.0.4 from 4.0.3 +- [#3493](https://github.com/hapijs/hapi/issues/3493) Update hapijs/cryptiles to 3.1.2 from 3.1.1 +- [#3492](https://github.com/hapijs/hapi/issues/3492) Update hapijs/content to 3.0.4 from 3.0.3 +- [#3491](https://github.com/hapijs/hapi/issues/3491) Update hapijs/catbox to 7.1.3 from 7.1.4 +- [#3490](https://github.com/hapijs/hapi/issues/3490) Update hapijs/call to 4.0.2 from 4.0.0 +- [#3489](https://github.com/hapijs/hapi/issues/3489) Update hapijs/boom to 5.1.0 from 4.2.0 +- [#3488](https://github.com/hapijs/hapi/issues/3488) Update hapijs/ammo to 2.0.4 from 2.0.3 +- [#3487](https://github.com/hapijs/hapi/issues/3487) Update hapijs/accept to 2.1.4 from 2.1.3 +- [#3472](https://github.com/hapijs/hapi/pull/3472) Send connection close when there is unconsumed payload +- [#3470](https://github.com/hapijs/hapi/pull/3470) Defer 100-continue signalling until payload parsing +- [#3451](https://github.com/hapijs/hapi/issues/3451) Have access to request.app in Joi validation context +- [#3448](https://github.com/hapijs/hapi/pull/3448) Bind request continuation methods to current domain +- [#3447](https://github.com/hapijs/hapi/issues/3447) one server is always leaked +- [#3431](https://github.com/hapijs/hapi/issues/3431) when failAction is log or ignored, the error is assigned to request.preResponse but not request.pre +- [#3427](https://github.com/hapijs/hapi/issues/3427) reply.entity() will always return null for correct etags + +### [16.1.1](https://github.com/hapijs/hapi/milestone/209) {#16.1.1} + +- [#3466](https://github.com/hapijs/hapi/issues/3466) Non-handling of accept-encoding header when the value does not conform to the specification +- [#3446](https://github.com/hapijs/hapi/pull/3446) remove extra closure + +### [16.1.0](https://github.com/hapijs/hapi/milestone/208) {#16.1.0} + +- [#3416](https://github.com/hapijs/hapi/issues/3416) Update hapijs/joi to 10.1.0 from 10.0.1 +- [#3415](https://github.com/hapijs/hapi/issues/3415) Allow creating multiple connections in a single server.connection() call + +### [16.0.3](https://github.com/hapijs/hapi/milestone/207) {#16.0.3} + +- [#3414](https://github.com/hapijs/hapi/issues/3414) Connectionless plugin fails inside connection-full plugin + +### [16.0.2](https://github.com/hapijs/hapi/milestone/206) {#16.0.2} + +- [#3411](https://github.com/hapijs/hapi/issues/3411) Falsey payload returns null + +### [16.0.1](https://github.com/hapijs/hapi/milestone/205) {#16.0.1} + +- [#3401](https://github.com/hapijs/hapi/pull/3401) Attempt to fix #3399 where it crashes on route prerequisites when no domain is present +- [#3399](https://github.com/hapijs/hapi/issues/3399) Regression on 16, lib/handlers.js + +### [16.0.0](https://github.com/hapijs/hapi/milestone/204) {#16.0.0} + +- [#3398](https://github.com/hapijs/hapi/issues/3398) 16.0.0 Release Notes +- [#3397](https://github.com/hapijs/hapi/issues/3397) Update hapijs/ammo to 2.0.3 from 2.0.2 +- [#3396](https://github.com/hapijs/hapi/issues/3396) Update hapijs/call to 4.0.0 from 3.0.3 +- [#3395](https://github.com/hapijs/hapi/issues/3395) Update hapijs/catbox to 7.1.3 from 7.1.2 +- [#3394](https://github.com/hapijs/hapi/issues/3394) Update hapijs/heavy to 4.0.3 from 4.0.2 +- [#3393](https://github.com/hapijs/hapi/issues/3393) Update hapijs/podium to 1.2.5 from 1.2.3 +- [#3392](https://github.com/hapijs/hapi/issues/3392) Update hapijs/shot to 3.4.0 from 3.3.2 +- [#3391](https://github.com/hapijs/hapi/issues/3391) Update hapijs/statehood to 5.0.1 from 5.0.0 +- [#3390](https://github.com/hapijs/hapi/issues/3390) Update jshttp/mime-db to 1.25.0 from 1.23.0 +- [#3389](https://github.com/hapijs/hapi/issues/3389) Update hapijs/content to 3.0.3 from 3.0.2 +- [#3388](https://github.com/hapijs/hapi/issues/3388) Update hapijs/pez to 2.1.4 from 2.1.2 +- [#3387](https://github.com/hapijs/hapi/issues/3387) Update hapijs/accept to 2.1.3 from 2.1.2 +- [#3386](https://github.com/hapijs/hapi/issues/3386) Update hapijs/catbox-memory to 2.0.4 from 2.0.3 +- [#3385](https://github.com/hapijs/hapi/issues/3385) Update hapijs/joi to 10.0.1 from 9.0.4 +- [#3384](https://github.com/hapijs/hapi/issues/3384) Update hapijs/cryptiles to 3.1.1 from 3.0.2 +- [#3383](https://github.com/hapijs/hapi/issues/3383) Update hapijs/boom to 4.2.0 from 4.0.0 +- [#3381](https://github.com/hapijs/hapi/issues/3381) problems with Promise error handling in plugin registration +- [#3380](https://github.com/hapijs/hapi/pull/3380) Ensure Boom objects can be reused - Fix for issue #3378 +- [#3378](https://github.com/hapijs/hapi/issues/3378) Server fails to reuse Boom object +- [#3372](https://github.com/hapijs/hapi/pull/3372) Allow HTTPS long poll requests +- [#3369](https://github.com/hapijs/hapi/issues/3369) Deprecation Warning in Node v7.0.0 for call to os.tmpDir +- [#3368](https://github.com/hapijs/hapi/pull/3368) change deprecated os.tmpDir call to os.tmpdir +- [#3359](https://github.com/hapijs/hapi/issues/3359) Shrinkwrap fails with hapi version 15.1.1 +- [#3358](https://github.com/hapijs/hapi/pull/3358) fix server not propagating errors on prehandler(promise) + handler error (#3242) +- [#3347](https://github.com/hapijs/hapi/issues/3347) Major performance issue with hapi.js 15.x +- [#3242](https://github.com/hapijs/hapi/issues/3242) Using promises in prehandlers causes exceptions to be swallowed in handlers. + +## Version 15 {#v15} + +### [15.2.0](https://github.com/hapijs/hapi/milestone/203) {#15.2.0} + +- [#3366](https://github.com/hapijs/hapi/issues/3366) Update hapijs/subtext to 4.3.0 from 4.2.2 +- [#3355](https://github.com/hapijs/hapi/issues/3355) Update hapijs/wreck to 10.0.0 from 9.0.0 +- [#3354](https://github.com/hapijs/hapi/issues/3354) Update hapijs/subtext to 4.2.2 from 4.2.1 +- [#3352](https://github.com/hapijs/hapi/issues/3352) npm shrinkwrap produces error with hapi +- [#3351](https://github.com/hapijs/hapi/pull/3351) Fix subtext shrinkwrap +- [#3051](https://github.com/hapijs/hapi/issues/3051) payload output inconsistent for single payload vs multipart + +### [15.1.0](https://github.com/hapijs/hapi/milestone/202) {#15.1.0} + +- [#3350](https://github.com/hapijs/hapi/issues/3350) Conditional plugin connection-less mode +- [#3342](https://github.com/hapijs/hapi/pull/3342) Update hapijs/shot to 3.3.2 from 3.3.1 +- [#3341](https://github.com/hapijs/hapi/issues/3341) Update hapijs/shot to 3.3.2 from 3.3.1 +- [#3339](https://github.com/hapijs/hapi/pull/3339) Restore npm-shrinkwrap.json to package. Closes #3338 +- [#3338](https://github.com/hapijs/hapi/issues/3338) `npm-shrinkwrap.json` not included in published `hapi` package + +### [15.0.3](https://github.com/hapijs/hapi/milestone/201) {#15.0.3} + +- [#3332](https://github.com/hapijs/hapi/issues/3332) Update hapijs/podium to 1.2.3 from 1.2.1 +- [#3330](https://github.com/hapijs/hapi/issues/3330) Events not emitted when route handler throws + +### [15.0.2](https://github.com/hapijs/hapi/milestone/200) {#15.0.2} + +- [#3325](https://github.com/hapijs/hapi/issues/3325) Allow initializing server without connections +- [#3324](https://github.com/hapijs/hapi/issues/3324) Verify plugin dependencies for connections added after initialize() or start() + +### [15.0.1](https://github.com/hapijs/hapi/milestone/199) {#15.0.1} + +### [15.0.0](https://github.com/hapijs/hapi/milestone/198) {#15.0.0} + +- [#3323](https://github.com/hapijs/hapi/issues/3323) 15.0.0 Release Notes +- [#3322](https://github.com/hapijs/hapi/pull/3322) Bump hapijs/boom version to 4.0.0 from 3.2.2 +- [#3320](https://github.com/hapijs/hapi/issues/3320) Update hapijs/boom to 4.0.0 from 3.2.2 +- [#3318](https://github.com/hapijs/hapi/issues/3318) Update hapijs/statehood to 5.0.0 from 4.0.3 +- [#3317](https://github.com/hapijs/hapi/issues/3317) Update hueniverse/iron to 4.0.3 from 4.0.2 +- [#3316](https://github.com/hapijs/hapi/issues/3316) Update hapijs/wreck to 9.0.0 from 8.0.1 +- [#3315](https://github.com/hapijs/hapi/issues/3315) Update hapijs/call to 3.0.3 from 3.0.2 +- [#3314](https://github.com/hapijs/hapi/issues/3314) Update hapijs/ammo to 2.0.2 from 2.0.1 +- [#3313](https://github.com/hapijs/hapi/issues/3313) Expose request to server.encode() and decode() generators +- [#3308](https://github.com/hapijs/hapi/pull/3308) Response validation custom handler +- [#3307](https://github.com/hapijs/hapi/issues/3307) Update hapijs/shot to 3.3.1 from 3.1.1 +- [#3306](https://github.com/hapijs/hapi/issues/3306) Disable request getLog() by default +- [#3304](https://github.com/hapijs/hapi/issues/3304) Errors when reply.continue() is called with an non-auth argument +- [#3303](https://github.com/hapijs/hapi/issues/3303) Error when reply() is called with a third argument (non-auth) +- [#3302](https://github.com/hapijs/hapi/issues/3302) Access to scope errors list from a Forbidden error +- [#3300](https://github.com/hapijs/hapi/issues/3300) Support custom content-type payload decoders +- [#3299](https://github.com/hapijs/hapi/issues/3299) Update hapijs/subtext to 4.2.0 from 4.0.5 +- [#3298](https://github.com/hapijs/hapi/issues/3298) Allow extending server encoding support +- [#3296](https://github.com/hapijs/hapi/issues/3296) Custom events +- [#3295](https://github.com/hapijs/hapi/issues/3295) server.register callback handling does not enforce process.nextTick +- [#3294](https://github.com/hapijs/hapi/issues/3294) Replace node's EventEmitter interface +- [#3292](https://github.com/hapijs/hapi/issues/3292) The "Vary: accept-encoding" header is not always set +- [#3291](https://github.com/hapijs/hapi/pull/3291) Ensure that 206 responses are never compressed +- [#3275](https://github.com/hapijs/hapi/issues/3275) Support for route authorization +- [#3243](https://github.com/hapijs/hapi/issues/3243) Content type charset handling +- [#3237](https://github.com/hapijs/hapi/issues/3237) Set response status message. +- [#3227](https://github.com/hapijs/hapi/pull/3227) Set route validation bind context +- [#3214](https://github.com/hapijs/hapi/issues/3214) Support failAction function on validation response failures +- [#3201](https://github.com/hapijs/hapi/pull/3201) handle more types of promise rejection, for #3102 +- [#3194](https://github.com/hapijs/hapi/issues/3194) output validation error pass source along +- [#3179](https://github.com/hapijs/hapi/pull/3179) Send correct response for HEAD requests +- [#3122](https://github.com/hapijs/hapi/issues/3122) Logging improvement +- [#3102](https://github.com/hapijs/hapi/issues/3102) Rejected promises are returned as successful status codes +- [#3065](https://github.com/hapijs/hapi/issues/3065) Move HTTP response header validation to node +- [#3061](https://github.com/hapijs/hapi/issues/3061) Bug with using Joi.object() for route validation +- [#3055](https://github.com/hapijs/hapi/issues/3055) Allow onPreResponse to override response and execute other extensions +- [#3030](https://github.com/hapijs/hapi/issues/3030) Server stop timeout and multiple connections + +## Version 14 {#v14} + +### [14.2.0](https://github.com/hapijs/hapi/milestone/197) {#14.2.0} + +- [#3286](https://github.com/hapijs/hapi/issues/3286) Support unmodified early return + +### [14.1.0](https://github.com/hapijs/hapi/milestone/196) {#14.1.0} + +- [#3277](https://github.com/hapijs/hapi/issues/3277) Route config function + +### [14.0.0](https://github.com/hapijs/hapi/milestone/195) {#14.0.0} + +- [#3272](https://github.com/hapijs/hapi/issues/3272) 14.0.0 Release Notes +- [#3271](https://github.com/hapijs/hapi/issues/3271) hapi 13.5.1 (and 13.5.2) break if routes still use joi 8.x + +## Version 13 {#v13} + +### [13.5.2](https://github.com/hapijs/hapi/milestone/194) {#13.5.2} + +- [#3249](https://github.com/hapijs/hapi/issues/3249) Update hapijs/catbox to 7.1.2 from 7.1.1 + +### [13.5.1](https://github.com/hapijs/hapi/milestone/193) {#13.5.1} + +- [#3270](https://github.com/hapijs/hapi/issues/3270) Update hapijs/topo to 2.0.2 from 2.0.1 +- [#3269](https://github.com/hapijs/hapi/issues/3269) Update hapijs/wreck to 8.0.1 from 7.2.1 +- [#3268](https://github.com/hapijs/hapi/issues/3268) Update hapijs/vise to 2.0.2 from 2.0.1 +- [#3267](https://github.com/hapijs/hapi/issues/3267) Update hapijs/nigel to 2.0.2 from 2.0.1 +- [#3266](https://github.com/hapijs/hapi/issues/3266) Update hapijs/b64 to 3.0.2 from 3.0.1 +- [#3265](https://github.com/hapijs/hapi/issues/3265) Update hapijs/pez to 2.1.2 from 2.1.1 +- [#3264](https://github.com/hapijs/hapi/issues/3264) Update hapijs/context to 3.0.2 from 3.0.1 +- [#3263](https://github.com/hapijs/hapi/issues/3263) Update hapijs/subtext to 4.0.5 from 4.0.3 +- [#3262](https://github.com/hapijs/hapi/issues/3262) Update hapijs/statehood to 4.0.3 from 4.0.1 +- [#3261](https://github.com/hapijs/hapi/issues/3261) Update hapijs/shot to 3.1.1 from 3.1.0 +- [#3260](https://github.com/hapijs/hapi/issues/3260) Update hapijs/peekaboo to 2.0.2 from 2.0.1 +- [#3259](https://github.com/hapijs/hapi/issues/3259) Update hapijs/mimos to 3.0.3 from 3.0.2 +- [#3258](https://github.com/hapijs/hapi/issues/3258) Update hapijs/kilt to 2.0.2 from 2.0.1 +- [#3257](https://github.com/hapijs/hapi/issues/3257) Update moment/moment to 2.14.1 from 2.13.0 +- [#3256](https://github.com/hapijs/hapi/issues/3256) Update hapijs/isemail to 2.2.1 from 2.1.0 +- [#3255](https://github.com/hapijs/hapi/issues/3255) Update hapijs/joi to 9.0.4 from 8.1.0 +- [#3254](https://github.com/hapijs/hapi/issues/3254) Update hapijs/items to 2.1.1 from 2.1.0 +- [#3253](https://github.com/hapijs/hapi/issues/3253) Update hueniverse/iron to 4.0.2 from 4.0.1 +- [#3252](https://github.com/hapijs/hapi/issues/3252) Update hapijs/heavy to 4.0.2 from 4.0.1 +- [#3251](https://github.com/hapijs/hapi/issues/3251) Update hapijs/cryptiles to 3.0.2 from 3.0.1 +- [#3250](https://github.com/hapijs/hapi/issues/3250) Update hapijs/catbox-memory to 2.0.3 from 2.0.2 +- [#3248](https://github.com/hapijs/hapi/issues/3248) Update hapijs/call to 3.0.3 from 3.0.2 +- [#3247](https://github.com/hapijs/hapi/issues/3247) Update hapijs/ammo to 2.0.2 from 2.0.1 +- [#3246](https://github.com/hapijs/hapi/issues/3246) Update hapijs/hoek to 4.0.2 from 4.0.0 +- [#3245](https://github.com/hapijs/hapi/issues/3245) Update hapijs/boom to 3.2.2 from 3.2.0 +- [#3244](https://github.com/hapijs/hapi/issues/3244) Update hapijs/accept to 2.1.2 from 2.1.1 + +### [13.5.0](https://github.com/hapijs/hapi/milestone/192) {#13.5.0} + +- [#3206](https://github.com/hapijs/hapi/issues/3206) override default cache headers for error pages +- [#3178](https://github.com/hapijs/hapi/pull/3178) Handle thrown error from res.setHeader() and res.writeHead() +- [#3174](https://github.com/hapijs/hapi/pull/3174) Fixes #3155 - Calling reply without a payload on a JSONP route throws + +### [13.4.2](https://github.com/hapijs/hapi/milestone/191) {#13.4.2} + +- [#3228](https://github.com/hapijs/hapi/issues/3228) Update hapijs/call to 3.0.2 from 3.0.1 +- [#3216](https://github.com/hapijs/hapi/pull/3216) Update hapijs/shot to 3.1.0 from 3.0.1 + +### [13.4.1](https://github.com/hapijs/hapi/milestone/190) {#13.4.1} + +- [#3173](https://github.com/hapijs/hapi/issues/3173) Update hapijs/nigel to 2.0.1 from 2.0.0 +- [#3172](https://github.com/hapijs/hapi/issues/3172) Update hapijs/b64 to 3.0.1 from 3.0.0 +- [#3171](https://github.com/hapijs/hapi/issues/3171) Update hapijs/pez to 2.1.1 from 2.1.0 +- [#3170](https://github.com/hapijs/hapi/issues/3170) Update hapijs/subtext to 4.0.3 from 4.0.1 +- [#3169](https://github.com/hapijs/hapi/issues/3169) Update hapijs/statehood to 4.0.1 from 4.0.0 +- [#3168](https://github.com/hapijs/hapi/issues/3168) Update hapijs/peekaboo to 2.0.1 from 2.0.0 +- [#3167](https://github.com/hapijs/hapi/issues/3167) Update hapijs/mimos to 3.0.1 from 3.0.0 +- [#3166](https://github.com/hapijs/hapi/issues/3166) Update hapijs/kilt to 2.0.1 from 2.0.0 +- [#3165](https://github.com/hapijs/hapi/issues/3165) Update hapijs/isemail to 2.1.0 from 2.1.2 +- [#3164](https://github.com/hapijs/hapi/issues/3164) Update hueniverse/iron to 4.0.1 from 4.0.0 +- [#3163](https://github.com/hapijs/hapi/issues/3163) Update hapijs/cryptiles to 3.0.1 from 3.0.0 +- [#3162](https://github.com/hapijs/hapi/issues/3162) Update hapijs/catbox-memory to 2.0.2 from 2.0.1 +- [#3161](https://github.com/hapijs/hapi/issues/3161) Update hapijs/catbox to 7.1.1 from 7.1.0 +- [#3160](https://github.com/hapijs/hapi/issues/3160) Update hapijs/call to 3.0.1 from 3.0.0 +- [#3159](https://github.com/hapijs/hapi/issues/3159) Update hapijs/boom to 3.2.0 from 3.1.3 +- [#3158](https://github.com/hapijs/hapi/issues/3158) Update hapijs/ammo to 2.0.1 from 2.0.0 +- [#3157](https://github.com/hapijs/hapi/issues/3157) Update hapijs/topo to 2.0.1 from 2.0.0 +- [#3156](https://github.com/hapijs/hapi/issues/3156) Update hapijs/wreck to 7.2.1 from 7.2.0 +- [#3121](https://github.com/hapijs/hapi/pull/3121) allow array as valid validate config on headers, params, query and payload +- [#3119](https://github.com/hapijs/hapi/issues/3119) Support [] as payload validation + +### [13.4.0](https://github.com/hapijs/hapi/milestone/189) {#13.4.0} + +- [#3147](https://github.com/hapijs/hapi/issues/3147) Pass original validation error if boom +- [#3146](https://github.com/hapijs/hapi/issues/3146) Update hapijs/wreck to 7.2.0 from 7.0.2 +- [#3145](https://github.com/hapijs/hapi/issues/3145) Update hapijs/vise to 2.0.1 from 2.0.0 +- [#3144](https://github.com/hapijs/hapi/issues/3144) Update hapijs/content to 3.0.1 from 3.0.0 +- [#3143](https://github.com/hapijs/hapi/issues/3143) Update jshttp/mime-db to 1.23.0 from 1.22.0 +- [#3142](https://github.com/hapijs/hapi/issues/3142) Update moment/moment to 2.13.0 from 2.12.0 +- [#3141](https://github.com/hapijs/hapi/issues/3141) Update hapijs/joi to 8.1.0 from 8.0.4 +- [#3140](https://github.com/hapijs/hapi/issues/3140) Update hapijs/items to 2.1.0 from 2.0.0 +- [#3139](https://github.com/hapijs/hapi/issues/3139) Update hapijs/hoek to 4.0.0 from 3.0.4 +- [#3138](https://github.com/hapijs/hapi/issues/3138) Update hapijs/heavy to 4.0.1 from 4.0.0 +- [#3137](https://github.com/hapijs/hapi/issues/3137) Update hapijs/boom to 3.1.3 from 3.1.2 +- [#3136](https://github.com/hapijs/hapi/issues/3136) Update hapijs/accept to 2.1.1 from 2.1.0 +- [#3115](https://github.com/hapijs/hapi/issues/3115) Update hapijs/pez to 2.1.0 from 2.0.1 +- [#3111](https://github.com/hapijs/hapi/pull/3111) Update hapijs/subtext to 4.0.1 from 4.0.0 + +### [13.3.0](https://github.com/hapijs/hapi/milestone/188) {#13.3.0} + +- [#3107](https://github.com/hapijs/hapi/issues/3107) Permit validation on any payload type +- [#3068](https://github.com/hapijs/hapi/pull/3068) Fast server shutdown + +### [13.2.2](https://github.com/hapijs/hapi/milestone/187) {#13.2.2} + +- [#3101](https://github.com/hapijs/hapi/issues/3101) Auth entity error reports the wrong credential type used + +### [13.2.1](https://github.com/hapijs/hapi/milestone/186) {#13.2.1} + +- [#3044](https://github.com/hapijs/hapi/pull/3044) Enable disabling cache-control headers +- [#2979](https://github.com/hapijs/hapi/issues/2979) `.charset(charset)` doesn't work on its own in ext + +### [13.1.0](https://github.com/hapijs/hapi/milestone/185) {#13.1.0} + +- [#3083](https://github.com/hapijs/hapi/issues/3083) Allow provisioning server cache after construction +- [#3082](https://github.com/hapijs/hapi/issues/3082) Update hapijs/wreck to 7.0.2 from 7.0.0 +- [#3081](https://github.com/hapijs/hapi/issues/3081) Update hapijs/shot to 3.0.1 from 3.0.0 +- [#3080](https://github.com/hapijs/hapi/issues/3080) Update jshttp/mime-db to 1.22.0 from 1.20.0 +- [#3079](https://github.com/hapijs/hapi/issues/3079) Update moment/momemt to 2.12.0 from 2.11.0 +- [#3078](https://github.com/hapijs/hapi/issues/3078) Update hapijs/joi to 8.0.4 from 7.1.0 +- [#3077](https://github.com/hapijs/hapi/issues/3077) Update hapijs/boom to 3.1.2 from 3.1.1 +- [#3069](https://github.com/hapijs/hapi/pull/3069) Pass through cookie options when calling reply.unstate() +- [#3057](https://github.com/hapijs/hapi/pull/3057) Don't re-initialize the server +- [#3042](https://github.com/hapijs/hapi/issues/3042) Moment - Regular Expression Denial of Service +- [#3015](https://github.com/hapijs/hapi/issues/3015) Can not change/remove the "accept-ranges" response header +- [#3014](https://github.com/hapijs/hapi/pull/3014) Update JSON response stringify for better performance + +### [13.0.0](https://github.com/hapijs/hapi/milestone/184) {#13.0.0} + +- [#3040](https://github.com/hapijs/hapi/issues/3040) 13.0.0 Release Notes +- [#3039](https://github.com/hapijs/hapi/issues/3039) Update hueniverse/iron to 4.0.0 from 3.0.1 +- [#3038](https://github.com/hapijs/hapi/issues/3038) Update hapijs/statehood to 4.0.0 from 3.1.0 + +## Version 12 {#v12} + +### [12.1.0](https://github.com/hapijs/hapi/milestone/183) {#12.1.0} + +- [#3018](https://github.com/hapijs/hapi/issues/3018) Allow auth strategies to expose an api + +### [12.0.1](https://github.com/hapijs/hapi/milestone/182) {#12.0.1} + +- [#3013](https://github.com/hapijs/hapi/pull/3013) Fix hapijs/shot dependency + +### [12.0.0](https://github.com/hapijs/hapi/milestone/178) {#12.0.0} + +- [#3012](https://github.com/hapijs/hapi/issues/3012) Update hapijs/catbox to 7.1.0 from 7.0.0 +- [#3011](https://github.com/hapijs/hapi/issues/3011) Update hapijs/shot to 3.0.0 from 2.0.1 +- [#3010](https://github.com/hapijs/hapi/issues/3010) Update jshttp/mime-db to 1.20.0 from 1.19.0 +- [#3009](https://github.com/hapijs/hapi/issues/3009) Update moment/moment to 2.11.0 from 2.10.6 +- [#3008](https://github.com/hapijs/hapi/issues/3008) Update hapijs/isemail to 2.1.0 from 2.0.0 +- [#3007](https://github.com/hapijs/hapi/issues/3007) Update hapijs/joi to 7.1.0 from 7.0.0 +- [#3006](https://github.com/hapijs/hapi/issues/3006) Update hapijs/hoek to 3.0.4 from 3.0.0 +- [#3005](https://github.com/hapijs/hapi/issues/3005) Update hapijs/boom to 3.1.1 from 3.0.0 +- [#3004](https://github.com/hapijs/hapi/issues/3004) Update hapijs/accept to 2.1.0 from 2.0.0 +- [#3002](https://github.com/hapijs/hapi/issues/3002) Remove request.session and request.auth.session placeholders +- [#3001](https://github.com/hapijs/hapi/issues/3001) Update hapijs/statehood to 3.1.0 from 3.0.0 +- [#3000](https://github.com/hapijs/hapi/issues/3000) Return a promise when callback missing +- [#2999](https://github.com/hapijs/hapi/issues/2999) Support required scope with + prefix +- [#2998](https://github.com/hapijs/hapi/issues/2998) Support multiple access combinations per route +- [#2994](https://github.com/hapijs/hapi/issues/2994) Dynamic scope does not work with auth.default() +- [#2993](https://github.com/hapijs/hapi/issues/2993) Support forbidden scope with ! prefix +- [#2992](https://github.com/hapijs/hapi/issues/2992) Normalize auth scope and entity settings under new access option +- [#2988](https://github.com/hapijs/hapi/pull/2988) Handle invalid date exceptions +- [#2985](https://github.com/hapijs/hapi/issues/2985) 12.0.0. Release Notes +- [#2983](https://github.com/hapijs/hapi/issues/2983) Update hapijs/subtext to 4.0.0 from 3.0.1 +- [#2972](https://github.com/hapijs/hapi/pull/2972) Add validation check for stripUnknown route response option +- [#2966](https://github.com/hapijs/hapi/issues/2966) request.raw.res.end() method is called twice +- [#2957](https://github.com/hapijs/hapi/issues/2957) nameless cookie causing hapi fail parsing +- [#2936](https://github.com/hapijs/hapi/issues/2936) Expose origin matching status +- [#2886](https://github.com/hapijs/hapi/issues/2886) Add entire auth object to validation context options + +## Version 11 {#v11} + +### [11.1.4](https://github.com/hapijs/hapi/milestone/181) {#11.1.4} + +- [#2990](https://github.com/hapijs/hapi/pull/2990) Fix cors config cascade. Closes #2980 +- [#2980](https://github.com/hapijs/hapi/issues/2980) Route level CORS config overrides connection level defaults + +### [11.1.3](https://github.com/hapijs/hapi/milestone/179) {#11.1.3} + +- [#2987](https://github.com/hapijs/hapi/issues/2987) Catch invalid date exceptions + +### [11.1.2](https://github.com/hapijs/hapi/milestone/177) {#11.1.2} + +- [#2953](https://github.com/hapijs/hapi/pull/2953) Tests for issue #2950 +- [#2950](https://github.com/hapijs/hapi/issues/2950) Access-Control-Expose-Headers response header duplicate values +- [#2940](https://github.com/hapijs/hapi/pull/2940) Fails to set a global route auth config + +### [11.1.1](https://github.com/hapijs/hapi/milestone/176) {#11.1.1} + +- [#2944](https://github.com/hapijs/hapi/pull/2944) Update hapijs/subtext to 3.0.1 from 3.0.0 +- [#2931](https://github.com/hapijs/hapi/pull/2931) Lookup route during OPTIONS by using request.info.hostname. Closes #2930 +- [#2930](https://github.com/hapijs/hapi/issues/2930) Route not correctly looked up during CORS OPTIONS request when using vhost + +### [11.1.0](https://github.com/hapijs/hapi/milestone/174) {#11.1.0} + +- [#2929](https://github.com/hapijs/hapi/issues/2929) Allow setting request app and plugins via inject +- [#2928](https://github.com/hapijs/hapi/issues/2928) Support per-request decoration + +### [11.0.5](https://github.com/hapijs/hapi/milestone/173) {#11.0.5} + +- [#2894](https://github.com/hapijs/hapi/issues/2894) CORS headers to include 'Origin' + +### [11.0.4](https://github.com/hapijs/hapi/milestone/172) {#11.0.4} + +- [#2923](https://github.com/hapijs/hapi/issues/2923) Update hapijs/vise to 2.0.0 from 1.0.0 +- [#2922](https://github.com/hapijs/hapi/issues/2922) Update hapijs/nigel to 2.0.0 from 1.0.1 +- [#2921](https://github.com/hapijs/hapi/issues/2921) Update hapijs/pez to 2.0.1 from 1.0.0 +- [#2920](https://github.com/hapijs/hapi/issues/2920) Update hapijs/context to 3.0.0 from 1.0.2 +- [#2919](https://github.com/hapijs/hapi/issues/2919) Update hapijs/subtext to 3.0.0 from 2.0.2 +- [#2918](https://github.com/hapijs/hapi/issues/2918) Update hapijs/statehood to 3.0.0 from 2.1.1 +- [#2917](https://github.com/hapijs/hapi/issues/2917) Update hapijs/shot to 2.0.1 from 1.7.0 +- [#2916](https://github.com/hapijs/hapi/issues/2916) Update hapijs/qs to 6.0.0 from 5.2.0 +- [#2915](https://github.com/hapijs/hapi/issues/2915) Update hapijs/peekaboo to 2.0.0 from 1.0.0 +- [#2914](https://github.com/hapijs/hapi/issues/2914) Update hapijs/mimos to 3.0.0 from 2.0.2 +- [#2913](https://github.com/hapijs/hapi/issues/2913) Update hapijs/kilt to 2.0.0 from 1.1.1 +- [#2912](https://github.com/hapijs/hapi/issues/2912) Update hueniverse/iron to 3.0.1 from 2.1.3 +- [#2911](https://github.com/hapijs/hapi/issues/2911) Update hapijs/heavy to 4.0.0 from 3.0.1 +- [#2910](https://github.com/hapijs/hapi/issues/2910) Update hapijs/cryptiles to 3.0.0 from 2.0.5 +- [#2909](https://github.com/hapijs/hapi/issues/2909) Update hapijs/catbox-memory to 2.0.1 from 1.1.2 +- [#2908](https://github.com/hapijs/hapi/issues/2908) Update hapijs/isemail to 2.0.0 from 1.2.0 +- [#2907](https://github.com/hapijs/hapi/issues/2907) Update hapijs/topo to 2.0.0 from 1.1.0 +- [#2906](https://github.com/hapijs/hapi/issues/2906) Update hapijs/joi to 7.0.0 from 6.8.1 +- [#2905](https://github.com/hapijs/hapi/issues/2905) Update hapijs/catbox to 7.0.0 from 6.0.0 +- [#2904](https://github.com/hapijs/hapi/issues/2904) Update hapijs/call to 3.0.0 from 2.0.2 +- [#2903](https://github.com/hapijs/hapi/issues/2903) Update hapijs/ammo to 2.0.0 from 1.0.1 +- [#2902](https://github.com/hapijs/hapi/issues/2902) Update hapijs/accept to 2.0.0 from 1.1.0 +- [#2901](https://github.com/hapijs/hapi/issues/2901) Update hapijs/wreck to 7.0.0 from 6.2.0 +- [#2900](https://github.com/hapijs/hapi/issues/2900) Update hapijs/b64 to 3.0.0 from 2.0.1 +- [#2899](https://github.com/hapijs/hapi/issues/2899) Update hapijs/items to 2.0.0 from 1.1.0 +- [#2898](https://github.com/hapijs/hapi/issues/2898) Update hapijs/boom to 3.0.0 from 2.9.0 +- [#2897](https://github.com/hapijs/hapi/issues/2897) Update hapijs/hoek to 3.0.1 from 2.16.3 + +### [11.0.3](https://github.com/hapijs/hapi/milestone/171) {#11.0.3} + +- [#2885](https://github.com/hapijs/hapi/pull/2885) Update hapijs/subtext to 2.0.2 from 2.0.1 +- [#2877](https://github.com/hapijs/hapi/issues/2877) Replace all functions inside functions with arrow functions +- [#2875](https://github.com/hapijs/hapi/issues/2875) Style change: replace for(i, il) with length in test +- [#2874](https://github.com/hapijs/hapi/issues/2874) Replace var with let +- [#2873](https://github.com/hapijs/hapi/issues/2873) Use const where possible +- [#2872](https://github.com/hapijs/hapi/issues/2872) Add strict mode +- [#2870](https://github.com/hapijs/hapi/pull/2870) Fix empty content-length handling for gzip and 204 responses +- [#2869](https://github.com/hapijs/hapi/issues/2869) Gzip compression is skipped when content-length is unknown +- [#2868](https://github.com/hapijs/hapi/issues/2868) CORS: Is 404 on OPTIONS request the right thing to do? +- [#2867](https://github.com/hapijs/hapi/issues/2867) Skip extensions for notFound and badRequest +- [#2862](https://github.com/hapijs/hapi/issues/2862) Update hapijs/subtext to 2.0.2 from 2.0.0 + +### [11.0.2](https://github.com/hapijs/hapi/milestone/170) {#11.0.2} + +- [#2866](https://github.com/hapijs/hapi/pull/2866) Fixed an issue with mixed-case headers not being matched correctly in CORS +- [#2852](https://github.com/hapijs/hapi/issues/2852) request.params undefined when route not found + +### [11.0.1](https://github.com/hapijs/hapi/milestone/169) {#11.0.1} + +- [#2859](https://github.com/hapijs/hapi/pull/2859) Add error messages to 404's caused by cors closes #2857 +- [#2858](https://github.com/hapijs/hapi/pull/2858) Add 'Accept' to default header per #2855 + +### [11.0.0](https://github.com/hapijs/hapi/milestone/168) {#11.0.0} + +- [#2850](https://github.com/hapijs/hapi/issues/2850) 11.0.0 Release Notes +- [#2849](https://github.com/hapijs/hapi/issues/2849) Add 204 to statuses cached by default +- [#2848](https://github.com/hapijs/hapi/issues/2848) Allow response validation of non-objects +- [#2847](https://github.com/hapijs/hapi/issues/2847) Update hapijs/qs to 5.2.0 from 4.0.0 +- [#2845](https://github.com/hapijs/hapi/issues/2845) Allow empty response to default to 204 +- [#2840](https://github.com/hapijs/hapi/issues/2840) CORS route-specific override can conflict with connection defaults +- [#2814](https://github.com/hapijs/hapi/issues/2814) Remove server.after() +- [#2807](https://github.com/hapijs/hapi/issues/2807) Remove id from request received event + +## Version 10 {#v10} + +### [10.5.0](https://github.com/hapijs/hapi/milestone/167) {#10.5.0} + +- [#2844](https://github.com/hapijs/hapi/issues/2844) Server new route event +- [#2829](https://github.com/hapijs/hapi/pull/2829) Expanded `registrations` API. Added test. Updated docs. +- [#2491](https://github.com/hapijs/hapi/issues/2491) CORS pre-fetch not respecting per-route config + +### [10.4.1](https://github.com/hapijs/hapi/milestone/164) {#10.4.1} + +- [#2836](https://github.com/hapijs/hapi/issues/2836) Update hapijs/heavy to 3.0.1 from 3.0.0 + +### [10.4.0](https://github.com/hapijs/hapi/milestone/163) {#10.4.0} + +- [#2828](https://github.com/hapijs/hapi/issues/2828) Update hapijs/shot to 1.7.0 from 1.6.1 +- [#2827](https://github.com/hapijs/hapi/issues/2827) Enhance server.ext() to accept an array of event objects +- [#2826](https://github.com/hapijs/hapi/issues/2826) Update hapijs/topo to 1.1.0 from 1.0.3 +- [#2824](https://github.com/hapijs/hapi/issues/2824) request.info.host - Host header wrong in server.inject +- [#2823](https://github.com/hapijs/hapi/issues/2823) Skip empty extension points in request lifecycle +- [#2822](https://github.com/hapijs/hapi/issues/2822) Plugin schema too restrictive +- [#2819](https://github.com/hapijs/hapi/issues/2819) Replace single connection server decorations with assertions +- [#2818](https://github.com/hapijs/hapi/issues/2818) Support plugin level once attribute +- [#2566](https://github.com/hapijs/hapi/issues/2566) Lifecycle hooks on routes + +### [10.3.0](https://github.com/hapijs/hapi/milestone/162) {#10.3.0} + +- [#2754](https://github.com/hapijs/hapi/issues/2754) Add connections inside a plugin + +### [10.2.1](https://github.com/hapijs/hapi/milestone/161) {#10.2.1} + +- [#2817](https://github.com/hapijs/hapi/issues/2817) Multiple connectionless plugin exceptions + +### [10.2.0](https://github.com/hapijs/hapi/milestone/160) {#10.2.0} + +- [#2815](https://github.com/hapijs/hapi/issues/2815) Cleanup after() options +- [#2813](https://github.com/hapijs/hapi/issues/2813) Update server root methods when adding 2nd connection +- [#2812](https://github.com/hapijs/hapi/issues/2812) Prevent adding server extensions once initialize() is called +- [#2811](https://github.com/hapijs/hapi/issues/2811) Support connectionless plugins +- [#2809](https://github.com/hapijs/hapi/issues/2809) Return plugin dependency errors via callback instead of throwing +- [#2808](https://github.com/hapijs/hapi/issues/2808) Pass start() and initialize() errors via callback, not throw +- [#2806](https://github.com/hapijs/hapi/issues/2806) Update hapijs/isemail to 1.2.0 from 1.1.1 +- [#2805](https://github.com/hapijs/hapi/issues/2805) Update hapijs/joi to 6.8.0 from 6.6.1 +- [#2804](https://github.com/hapijs/hapi/issues/2804) Apply arguments schema more consistently +- [#2796](https://github.com/hapijs/hapi/pull/2796) don't duplicate accept-encoding in vary header +- [#2790](https://github.com/hapijs/hapi/pull/2790) Add cache stats to server methods +- [#2788](https://github.com/hapijs/hapi/issues/2788) Option to turn off domains +- [#2777](https://github.com/hapijs/hapi/issues/2777) Public API for Registered Plugins +- [#2773](https://github.com/hapijs/hapi/pull/2773) Detects and rejects malformed response headers +- [#2763](https://github.com/hapijs/hapi/issues/2763) get cache stats for a server method? +- [#2761](https://github.com/hapijs/hapi/issues/2761) Conditional register() for skipping already registered plugins +- [#2736](https://github.com/hapijs/hapi/issues/2736) Stopping the server while starting it +- [#2733](https://github.com/hapijs/hapi/issues/2733) CORS Headers +- [#2352](https://github.com/hapijs/hapi/issues/2352) setting undefined headers on transmit +- [#1850](https://github.com/hapijs/hapi/issues/1850) Set per-plugin registration options when registering an array of plugins + +### [10.1.0](https://github.com/hapijs/hapi/milestone/159) {#10.1.0} + +- [#2787](https://github.com/hapijs/hapi/issues/2787) Update hapijs/wreck to 6.2.0 from 6.1.0 +- [#2786](https://github.com/hapijs/hapi/issues/2786) Update hapijs/b64 to 2.0.1 from 2.0.0 +- [#2785](https://github.com/hapijs/hapi/issues/2785) Update hapijs/shot to 1.6.1 from 1.6.0 +- [#2784](https://github.com/hapijs/hapi/issues/2784) Update jshttp/mime-db to 1.19.0 from 1.18.0 +- [#2783](https://github.com/hapijs/hapi/issues/2783) Update hapijs/hoek to 2.16.3 from 2.14.0 +- [#2782](https://github.com/hapijs/hapi/issues/2782) Update hapijs/cryptiles to 2.0.5 from 2.0.4 +- [#2776](https://github.com/hapijs/hapi/pull/2776) Add preload flag to HSTS header and fix casing for includeSubDomains. +- [#2505](https://github.com/hapijs/hapi/issues/2505) request.state occasionally null + +### [10.0.1](https://github.com/hapijs/hapi/milestone/158) {#10.0.1} + +- [#2779](https://github.com/hapijs/hapi/issues/2779) Flaky test? "Request does not return an error when server is responding when the timeout occurs" + +### [10.0.0](https://github.com/hapijs/hapi/milestone/157) {#10.0.0} + +- [#2765](https://github.com/hapijs/hapi/issues/2765) node v4 +- [#2764](https://github.com/hapijs/hapi/issues/2764) 10.0.0 Release Notes + +## Version 9 {#v9} + +### [9.5.1](https://github.com/hapijs/hapi/milestone/180) {#9.5.1} + +- [#2989](https://github.com/hapijs/hapi/issues/2989) Handle Date parsing error + +### [9.5.0](https://github.com/hapijs/hapi/milestone/175) {#9.5.0} + +### [9.4.1](https://github.com/hapijs/hapi/milestone/166) {#9.4.1} + +- [#2835](https://github.com/hapijs/hapi/issues/2835) hapi-lts requiring node 4 and no updates to hapi 9? + +### [9.4.0](https://github.com/hapijs/hapi/milestone/165) {#9.4.0} + +- [#2834](https://github.com/hapijs/hapi/issues/2834) 9.4.0 LTS + +### [9.3.1](https://github.com/hapijs/hapi/milestone/156) {#9.3.1} + +- [#2760](https://github.com/hapijs/hapi/issues/2760) Decorators fail with nested require calls + +### [9.3.0](https://github.com/hapijs/hapi/milestone/155) {#9.3.0} + +- [#2757](https://github.com/hapijs/hapi/issues/2757) Require allowInternals option on server.inject() to call isInternal routes + +### [9.2.0](https://github.com/hapijs/hapi/milestone/154) {#9.2.0} + +- [#2756](https://github.com/hapijs/hapi/issues/2756) Expose route active authentication configuration +- [#2755](https://github.com/hapijs/hapi/issues/2755) Update jshttp/mime-db to 1.18.0 from 1.17.0 + +### [9.1.0](https://github.com/hapijs/hapi/milestone/153) {#9.1.0} + +- [#2750](https://github.com/hapijs/hapi/issues/2750) Route config for internal access only routes + +### [9.0.4](https://github.com/hapijs/hapi/milestone/152) {#9.0.4} + +- [#2739](https://github.com/hapijs/hapi/pull/2739) Updated error when calling server.start with no callback +- [#2727](https://github.com/hapijs/hapi/issues/2727) Decorations not propagated to sibling plugins + +### [9.0.3](https://github.com/hapijs/hapi/milestone/151) {#9.0.3} + +- [#2725](https://github.com/hapijs/hapi/pull/2725) Update hapijs/catbox-memory to 1.1.2 from 1.1.1 +- [#2723](https://github.com/hapijs/hapi/issues/2723) Tape and server.inject problem + +### [9.0.2](https://github.com/hapijs/hapi/milestone/150) {#9.0.2} + +- [#2717](https://github.com/hapijs/hapi/issues/2717) Update jshttp/mime-db to 1.17.0 from 1.16.0 +- [#2714](https://github.com/hapijs/hapi/issues/2714) Setting server method cache generateTimeout to false results in error + +### [9.0.1](https://github.com/hapijs/hapi/milestone/149) {#9.0.1} + +- [#2699](https://github.com/hapijs/hapi/issues/2699) npm install hapi misses wreck sub-dependency + +### [9.0.0](https://github.com/hapijs/hapi/milestone/141) {#9.0.0} + +- [#2718](https://github.com/hapijs/hapi/issues/2718) Breaking change with query string validation from 8.6.0 to 9.0.2 +- [#2698](https://github.com/hapijs/hapi/issues/2698) Update hapijs/content to 1.0.2 from 1.0.1 +- [#2697](https://github.com/hapijs/hapi/issues/2697) Update moment/moment to 2.10.6 from 2.10.3 +- [#2696](https://github.com/hapijs/hapi/issues/2696) Update hapijs/joi to 6.6.1 from 6.4.1 +- [#2695](https://github.com/hapijs/hapi/issues/2695) Update hueniverse/iron to 2.1.3 from 2.1.2 +- [#2694](https://github.com/hapijs/hapi/issues/2694) Update hapijs/call to 2.0.2 from 2.0.1 +- [#2693](https://github.com/hapijs/hapi/issues/2693) Update hapijs/boom to 2.8.0 from 2.7.2 +- [#2692](https://github.com/hapijs/hapi/issues/2692) Update hapijs/ammo to 1.0.1 from 1.0.0 +- [#2691](https://github.com/hapijs/hapi/issues/2691) Update hapijs/accept to 1.1.0 from 1.0.0 +- [#2689](https://github.com/hapijs/hapi/issues/2689) Update hapijs/subtext from 1.1.1 to 2.0.0 +- [#2688](https://github.com/hapijs/hapi/issues/2688) Add server.initialize() +- [#2687](https://github.com/hapijs/hapi/issues/2687) Set plugin options in realm +- [#2686](https://github.com/hapijs/hapi/issues/2686) Require callback in start() and end() +- [#2685](https://github.com/hapijs/hapi/issues/2685) Allow server.ext() to extend server actions (start, stop) +- [#2684](https://github.com/hapijs/hapi/issues/2684) Update hapijs/catbox to 6.0.0 from 4.3.0 +- [#2683](https://github.com/hapijs/hapi/issues/2683) Update jshttp/mime-db to 1.16.0 from 1.14.0 +- [#2682](https://github.com/hapijs/hapi/issues/2682) 9.0.0 Release Notes +- [#2681](https://github.com/hapijs/hapi/issues/2681) Remove server files settings +- [#2675](https://github.com/hapijs/hapi/pull/2675) Update hapijs/shot to 1.6.0 from 1.5.3 +- [#2673](https://github.com/hapijs/hapi/issues/2673) 304 response sends: no-cache regardless of routes.cache settings +- [#2665](https://github.com/hapijs/hapi/issues/2665) Server breaks when using cached server method +- [#2662](https://github.com/hapijs/hapi/pull/2662) Added schema validation when creating a server method using object +- [#2661](https://github.com/hapijs/hapi/pull/2661) No longer removing response validation from route object if sample = 0 +- [#2645](https://github.com/hapijs/hapi/pull/2645) Add failing test for #2628 +- [#2641](https://github.com/hapijs/hapi/issues/2641) Vary accept-encoding header not always set for compressible content +- [#2628](https://github.com/hapijs/hapi/issues/2628) Multiple etag problems with directory handler causing browser use outdated cached content. +- [#2626](https://github.com/hapijs/hapi/issues/2626) Remove inert, h2o2, and vision from core +- [#2616](https://github.com/hapijs/hapi/issues/2616) Strange behaviour with throw in handlers +- [#2576](https://github.com/hapijs/hapi/issues/2576) Parsing requests with no payload +- [#2520](https://github.com/hapijs/hapi/issues/2520) API wart: server.dependency after method lacks options +- [#2517](https://github.com/hapijs/hapi/issues/2517) Means to force plugin registration to complete prior to server.inject +- [#2516](https://github.com/hapijs/hapi/issues/2516) Assert when server.start() is called before server.register() is done +- [#2449](https://github.com/hapijs/hapi/issues/2449) Isn't there any api document to disable compression? (gzip) +- [#2432](https://github.com/hapijs/hapi/issues/2432) TLS certificate errors are not surfaced in logs +- [#2389](https://github.com/hapijs/hapi/issues/2389) Support plugin shutdown + +## Version 8 {#v8} + +### [8.8.1](https://github.com/hapijs/hapi/milestone/148) {#8.8.1} + +- [#2671](https://github.com/hapijs/hapi/pull/2671) Update hapijs/topo to 1.0.3 from 1.0.2 +- [#2670](https://github.com/hapijs/hapi/issues/2670) Update hapijs/topo to 1.0.3 from 1.0.2 +- [#2664](https://github.com/hapijs/hapi/pull/2664) allow for proto inherit with Server ("instanceof" instead of "===") +- [#2663](https://github.com/hapijs/hapi/issues/2663) internals.Server does not allow proto inheritance +- [#2657](https://github.com/hapijs/hapi/issues/2657) `server.ext` dependencies not ordered using `before` as array +- [#2642](https://github.com/hapijs/hapi/pull/2642) Failing test for `server.ext` with complex deps. +- [#2631](https://github.com/hapijs/hapi/pull/2631) Update hapijs/inert to 2.1.6 from 2.1.5 + +### [8.8.0](https://github.com/hapijs/hapi/milestone/147) {#8.8.0} + +- [#2627](https://github.com/hapijs/hapi/issues/2627) Update hapijs/subtext to 1.1.1 from 1.1.0 +- [#2625](https://github.com/hapijs/hapi/issues/2625) Update hapijs/wreck to 6.0.0 from 5.5.1 +- [#2623](https://github.com/hapijs/hapi/issues/2623) Update hapijs/qs to 4.0.0 from 2.4.2 +- [#2622](https://github.com/hapijs/hapi/issues/2622) Support qs options in payload and query parsing +- [#2613](https://github.com/hapijs/hapi/issues/2613) Update jshttp/mime-db to 1.14.0 from 1.11.0 +- [#2612](https://github.com/hapijs/hapi/issues/2612) Update hapijs/vision to 2.0.1 from 2.0.0 +- [#2480](https://github.com/hapijs/hapi/issues/2480) Ability to pass options to qs for payload parsing + +### [8.7.0](https://github.com/hapijs/hapi/milestone/146) {#8.7.0} + +- [#2587](https://github.com/hapijs/hapi/issues/2587) Update hapijs/catbox to 4.3.0 from 4.2.2 + +### [8.6.1](https://github.com/hapijs/hapi/milestone/145) {#8.6.1} + +- [#2586](https://github.com/hapijs/hapi/issues/2586) Update hapijs/shot to 1.5.1 from 1.5.0 +- [#2584](https://github.com/hapijs/hapi/issues/2584) Update jshttp/mime-db to 1.11.0 from 1.10.0 +- [#2583](https://github.com/hapijs/hapi/issues/2583) Update hapijs/statehood to 2.1.1 from 2.0.0 + +### [8.6.0](https://github.com/hapijs/hapi/milestone/144) {#8.6.0} + +- [#2573](https://github.com/hapijs/hapi/pull/2573) allow returning a response object inside a promise +- [#2570](https://github.com/hapijs/hapi/pull/2570) Added "error" event listener + +### [8.5.3](https://github.com/hapijs/hapi/milestone/143) {#8.5.3} + +- [#2571](https://github.com/hapijs/hapi/issues/2571) Update hapijs/h2o2 to 4.0.1 from 4.0.0 +- [#2569](https://github.com/hapijs/hapi/pull/2569) Make sure auth filter passes on request auth artifacts when injecting, too + +### [8.5.2](https://github.com/hapijs/hapi/milestone/142) {#8.5.2} + +- [#2564](https://github.com/hapijs/hapi/issues/2564) Auth error log should not report missing or try as error + +### [8.5.1](https://github.com/hapijs/hapi/milestone/140) {#8.5.1} + +- [#2555](https://github.com/hapijs/hapi/pull/2555) fix dynamic scopes +- [#2554](https://github.com/hapijs/hapi/issues/2554) Dynamic scope uses undefined request.payload +- [#2553](https://github.com/hapijs/hapi/issues/2553) Update hapijs/hoek to 2.14.0 from 2.13.0 + +### [8.5.0](https://github.com/hapijs/hapi/milestone/139) {#8.5.0} + +- [#2552](https://github.com/hapijs/hapi/issues/2552) Update hapijs/wreck to 5.5.1 from 5.2.0 +- [#2551](https://github.com/hapijs/hapi/issues/2551) Update jshttp/mime-db to 1.10.0 from 1.9.1 +- [#2550](https://github.com/hapijs/hapi/issues/2550) Update moment/moment to 2.10.3 from 2.9.0 +- [#2549](https://github.com/hapijs/hapi/issues/2549) Update hapijs/joi to 6.4.1 from 6.0.8 +- [#2548](https://github.com/hapijs/hapi/issues/2548) Update hapijs/hoek to 2.13.0 from 2.11.1 +- [#2547](https://github.com/hapijs/hapi/issues/2547) Update hapijs/boom to 2.7.2 from 2.6.1 +- [#2546](https://github.com/hapijs/hapi/issues/2546) Update hapijs/inert to 2.1.5 from 2.1.4 +- [#2545](https://github.com/hapijs/hapi/issues/2545) Update isaacs/node-lru-cache to 2.6.4 from 2.5.0 +- [#2544](https://github.com/hapijs/hapi/pull/2544) Retain content-length header for HEAD requests +- [#2538](https://github.com/hapijs/hapi/pull/2538) closes #2480: Ability to pass options to qs for payload parsing +- [#2532](https://github.com/hapijs/hapi/pull/2532) Dynamic authentication scopes +- [#2509](https://github.com/hapijs/hapi/issues/2509) Update jshttp/mime-db to 1.9.1 from 1.7.0 +- [#2503](https://github.com/hapijs/hapi/issues/2503) Update hapijs/shot to 1.5.0 from 1.4.2 +- [#2502](https://github.com/hapijs/hapi/pull/2502) Fix Hapi Issue #2501, pass on auth artifacts object in server.inject +- [#2501](https://github.com/hapijs/hapi/issues/2501) server.inject does not allow me to set auth artifacts, only auth credentials +- [#2481](https://github.com/hapijs/hapi/issues/2481) Feature: server.decorate('request' ... ) +- [#2472](https://github.com/hapijs/hapi/issues/2472) Update hapijs/qs to 2.4.2 from 2.4.0 + +### [8.4.0](https://github.com/hapijs/hapi/milestone/138) {#8.4.0} + +- [#2470](https://github.com/hapijs/hapi/issues/2470) JSONP requests not always returning wrapped response +- [#2469](https://github.com/hapijs/hapi/issues/2469) Update hapijs/qs to 2.4.0 from 2.3.3 +- [#2468](https://github.com/hapijs/hapi/issues/2468) Proxy handler not forwarding request payload +- [#2465](https://github.com/hapijs/hapi/issues/2465) Update hapijs/catbox to 4.2.2 from 4.2.1 +- [#2464](https://github.com/hapijs/hapi/issues/2464) Update hapijs/joi to 6.0.8 from 6.0.5 +- [#2463](https://github.com/hapijs/hapi/pull/2463) Update shrinkwrap to joi 6.0.7 + +### [8.3.1](https://github.com/hapijs/hapi/milestone/137) {#8.3.1} + +- [#2461](https://github.com/hapijs/hapi/issues/2461) Missing dependency in 8.3 + +### [8.3.0](https://github.com/hapijs/hapi/milestone/136) {#8.3.0} + +- [#2459](https://github.com/hapijs/hapi/issues/2459) Fix for node 0.10 for changes in #2429 +- [#2457](https://github.com/hapijs/hapi/issues/2457) Update hapijs/inert to 2.1.4 from 2.1.3 +- [#2455](https://github.com/hapijs/hapi/issues/2455) Update hapijs/shot to 1.4.2 from 1.4.1 +- [#2454](https://github.com/hapijs/hapi/issues/2454) Update moment/moment to 2.9.0 from 2.8.4 +- [#2453](https://github.com/hapijs/hapi/issues/2453) Update hapijs/joi to 6.0.5 from 5.0.2 +- [#2452](https://github.com/hapijs/hapi/issues/2452) Update hapijs/hoek to 2.11.1 from 2.10.0 +- [#2446](https://github.com/hapijs/hapi/issues/2446) Update hapijs/wreck to 5.2.0 from 5.0.1 +- [#2439](https://github.com/hapijs/hapi/pull/2439) pass context to response schema validation +- [#2429](https://github.com/hapijs/hapi/pull/2429) Fix for #2427 +- [#2427](https://github.com/hapijs/hapi/issues/2427) Issue uploading file with io.js or node > 0.11.6 +- [#2423](https://github.com/hapijs/hapi/pull/2423) Update mime-db to 1.7.0 from 1.6.1 +- [#2420](https://github.com/hapijs/hapi/issues/2420) Update hapijs/shot to 1.4.1 from 1.4.0 +- [#2418](https://github.com/hapijs/hapi/pull/2418) Add regex to allow leading $ and \_ +- [#2411](https://github.com/hapijs/hapi/issues/2411) Update jshttp/mime-db to 1.7.0 from 1.6.1 +- [#2405](https://github.com/hapijs/hapi/pull/2405) Support inline dependencies on plugins +- [#2402](https://github.com/hapijs/hapi/pull/2402) Improved validation of route method label +- [#2401](https://github.com/hapijs/hapi/issues/2401) Method name RegExp +- [#2382](https://github.com/hapijs/hapi/pull/2382) Return explicit error when trying to stream a non-Readable stream +- [#2368](https://github.com/hapijs/hapi/issues/2368) response.streamify assumes stream has attribute \_readableState +- [#2332](https://github.com/hapijs/hapi/issues/2332) Replacing plugin.dependency() with attributes key +- [#2326](https://github.com/hapijs/hapi/issues/2326) request-error logged before `onPostHandler` or `onPreResponse` + +### [8.2.0](https://github.com/hapijs/hapi/milestone/135) {#8.2.0} + +- [#2398](https://github.com/hapijs/hapi/issues/2398) Update hapijs/inert to 2.1.3 from 2.1.2 +- [#2397](https://github.com/hapijs/hapi/pull/2397) throw when attaching route handlers without a connection +- [#2396](https://github.com/hapijs/hapi/pull/2396) Inert 2.1.3 update +- [#2395](https://github.com/hapijs/hapi/issues/2395) Update jshttp/mime-db to 1.6.1 from 1.5.0 +- [#2392](https://github.com/hapijs/hapi/issues/2392) No Payload Validation +- [#2374](https://github.com/hapijs/hapi/issues/2374) Server methods context not available in route prerequisites +- [#2373](https://github.com/hapijs/hapi/issues/2373) Update hapijs/inert to 2.1.2 from 2.1.0 +- [#2372](https://github.com/hapijs/hapi/pull/2372) inert 2.1.2 +- [#2370](https://github.com/hapijs/hapi/pull/2370) Add xss protection to validation response +- [#2367](https://github.com/hapijs/hapi/issues/2367) Update hapijs/inert to 2.1.0 from 2.0.0 +- [#2366](https://github.com/hapijs/hapi/issues/2366) Update hapijs/catbox to 4.2.1 from 4.2.0 +- [#2363](https://github.com/hapijs/hapi/pull/2363) Refuse to handle incoming request after server is stopped +- [#2362](https://github.com/hapijs/hapi/pull/2362) Don't respond to connections until listening is started +- [#2359](https://github.com/hapijs/hapi/pull/2359) Remove '{}' payload from cors OPTIONS response +- [#2355](https://github.com/hapijs/hapi/pull/2355) Fix table labels +- [#2354](https://github.com/hapijs/hapi/pull/2354) Update API.md for inert 2.1.0 +- [#2347](https://github.com/hapijs/hapi/issues/2347) Improve error message when validation.payload is set but type is GET +- [#2309](https://github.com/hapijs/hapi/pull/2309) Fixes #2308 by logging boom error object instead of just message +- [#2308](https://github.com/hapijs/hapi/issues/2308) Logging boom errors from handlers should send boom error to log not just message + +### [8.1.0](https://github.com/hapijs/hapi/milestone/133) {#8.1.0} + +- [#2335](https://github.com/hapijs/hapi/issues/2335) Expose the request object in inject() +- [#2331](https://github.com/hapijs/hapi/pull/2331) Revise range tests to not depend on the inert module +- [#2324](https://github.com/hapijs/hapi/pull/2324) Remove catch call for promise replies +- [#2323](https://github.com/hapijs/hapi/issues/2323) Promise support +- [#2316](https://github.com/hapijs/hapi/issues/2316) Update jshttp/mime-db to 1.5.0 from 1.3.1 +- [#2302](https://github.com/hapijs/hapi/pull/2302) allow replying with a stream as returned by node core http client methods +- [#2301](https://github.com/hapijs/hapi/issues/2301) can't reply with stream returned by node core http client methods +- [#2300](https://github.com/hapijs/hapi/pull/2300) Bumped mime-db version +- [#2291](https://github.com/hapijs/hapi/issues/2291) external listener protocol issue +- [#2277](https://github.com/hapijs/hapi/pull/2277) Fix invalid response for empty reply() (v8.x regression) + +### [8.0.0](https://github.com/hapijs/hapi/milestone/127) {#8.0.0} + +- [#2271](https://github.com/hapijs/hapi/issues/2271) Update jshttp/mime-db to 1.3.0 from 1.2.0 +- [#2270](https://github.com/hapijs/hapi/issues/2270) Update hapijs/boom to 2.6.1 from 2.6.0 +- [#2269](https://github.com/hapijs/hapi/issues/2269) Update hapijs/shot to 1.4.0 from 1.3.5 +- [#2268](https://github.com/hapijs/hapi/issues/2268) Update hapijs/joi to 5.0.2 from 5.0.0 +- [#2264](https://github.com/hapijs/hapi/issues/2264) How to blacklist all routes to use a plugin config? +- [#2262](https://github.com/hapijs/hapi/issues/2262) Change server.table() result from object to array +- [#2255](https://github.com/hapijs/hapi/issues/2255) Throw when calling reply() with objectMode stream +- [#2249](https://github.com/hapijs/hapi/issues/2249) Add 'uri' connection option +- [#2247](https://github.com/hapijs/hapi/issues/2247) Split debug settings per event type +- [#2246](https://github.com/hapijs/hapi/issues/2246) plugin dependencies error message changed +- [#2244](https://github.com/hapijs/hapi/pull/2244) Fix reply.continue() in prerequisite. Closes #2243 +- [#2243](https://github.com/hapijs/hapi/issues/2243) Fix reply.continue() in prerequisite. +- [#2242](https://github.com/hapijs/hapi/issues/2242) Uncaught error: Cannot read property 'isBoom' of null in hapi/lib/handler.js +- [#2241](https://github.com/hapijs/hapi/issues/2241) Remove string notation method logging when cache not setup +- [#2240](https://github.com/hapijs/hapi/issues/2240) Cached method in string notation bypasses cache +- [#2238](https://github.com/hapijs/hapi/issues/2238) Conditional Validation Rules based on Auth +- [#2237](https://github.com/hapijs/hapi/issues/2237) Support bare server (no files, proxy, views) +- [#2235](https://github.com/hapijs/hapi/issues/2235) Expose realm as public interface +- [#2234](https://github.com/hapijs/hapi/issues/2234) Support views in auth schemes +- [#2233](https://github.com/hapijs/hapi/issues/2233) Populate connection.info.uri before start when port 0 +- [#2231](https://github.com/hapijs/hapi/issues/2231) Change request.route to a wrapper object containing settings +- [#2230](https://github.com/hapijs/hapi/issues/2230) Replace server.config with server.realm.modifiers +- [#2229](https://github.com/hapijs/hapi/issues/2229) plugin.expose() only sets server.plugins, not connection.plugins +- [#2228](https://github.com/hapijs/hapi/issues/2228) Update hapijs/joi to 5.0.0 from 4.9.0 +- [#2227](https://github.com/hapijs/hapi/issues/2227) Update moment to 2.8.4 +- [#2226](https://github.com/hapijs/hapi/issues/2226) When using string shorthand in pre it does not provide reply interface +- [#2224](https://github.com/hapijs/hapi/issues/2224) Cleanup connection.info settings and introduce 'address' config +- [#2220](https://github.com/hapijs/hapi/issues/2220) A method to test a string against the routes table +- [#2219](https://github.com/hapijs/hapi/issues/2219) Update hapijs/hoek to 2.10.0 from 2.9.0 +- [#2217](https://github.com/hapijs/hapi/issues/2217) Disable scope checking on a route +- [#2216](https://github.com/hapijs/hapi/issues/2216) Invalid deep cloning of bind context +- [#2215](https://github.com/hapijs/hapi/issues/2215) Revert change to trailing slash behavior +- [#2209](https://github.com/hapijs/hapi/issues/2209) Not possible to add route in plugins +- [#2206](https://github.com/hapijs/hapi/issues/2206) Change server.bind() and server.path() to apply only to routes that follow +- [#2205](https://github.com/hapijs/hapi/issues/2205) Rename plugin register() `route` option to `routes` +- [#2203](https://github.com/hapijs/hapi/issues/2203) Move connection route config to route with connections defaults +- [#2201](https://github.com/hapijs/hapi/issues/2201) Rename cacheControlStatus to cache.statuses +- [#2200](https://github.com/hapijs/hapi/issues/2200) Validation failAction and custom function are not protected +- [#2199](https://github.com/hapijs/hapi/pull/2199) add missing variety handler for promises returning a object +- [#2198](https://github.com/hapijs/hapi/issues/2198) Update hapijs/call to 2.0.1 from 1.0.0 +- [#2195](https://github.com/hapijs/hapi/issues/2195) Override timeout values at a route level +- [#2192](https://github.com/hapijs/hapi/issues/2192) Rename connection to listener or similar +- [#2191](https://github.com/hapijs/hapi/issues/2191) Change defaults for router +- [#2190](https://github.com/hapijs/hapi/issues/2190) Log heavy load reason when check() is false +- [#2186](https://github.com/hapijs/hapi/issues/2186) 8.0.0 Release Notes +- [#2185](https://github.com/hapijs/hapi/issues/2185) Update hapijs/catbox to 4.2.0 from 4.1.0 +- [#2181](https://github.com/hapijs/hapi/issues/2181) Remove server method cache key 'h' prefix +- [#2179](https://github.com/hapijs/hapi/issues/2179) server.register() doesn't work with direct require of plugins (-rc1) +- [#2178](https://github.com/hapijs/hapi/issues/2178) Update hapijs/mimos to 2.0.2 from 1.0.1 +- [#2177](https://github.com/hapijs/hapi/issues/2177) Return select() on server.connection() +- [#2175](https://github.com/hapijs/hapi/issues/2175) Update jshttp/mime-db to 1.2.0 from 1.1.2 +- [#2174](https://github.com/hapijs/hapi/issues/2174) Update hapijs/qs to 2.3.3 from 2.3.2 +- [#2173](https://github.com/hapijs/hapi/issues/2173) Update hapijs/catbox-memory to 1.1.1 from 1.1.0 +- [#2172](https://github.com/hapijs/hapi/issues/2172) Update hapijs/boom to 2.6.0 from 2.5.1 +- [#2170](https://github.com/hapijs/hapi/issues/2170) Spin off range header parser +- [#2167](https://github.com/hapijs/hapi/issues/2167) Add response 'close' processor +- [#2166](https://github.com/hapijs/hapi/issues/2166) ETag vary modification not applied to content-encoding set elsewhere +- [#2165](https://github.com/hapijs/hapi/issues/2165) Expose request.paramsArray +- [#2164](https://github.com/hapijs/hapi/issues/2164) Bypass compression on empty payload +- [#2163](https://github.com/hapijs/hapi/issues/2163) ETag vary modification is incorrect +- [#2160](https://github.com/hapijs/hapi/issues/2160) Add cors.override setting +- [#2158](https://github.com/hapijs/hapi/issues/2158) How to get default auth strategy from server object? +- [#2157](https://github.com/hapijs/hapi/issues/2157) Link mentions of methods to their reference +- [#2156](https://github.com/hapijs/hapi/issues/2156) Rewrite reply() interface section +- [#2155](https://github.com/hapijs/hapi/issues/2155) Cleanup and document all internal request logs +- [#2154](https://github.com/hapijs/hapi/issues/2154) Rename response object option marshall to marshal +- [#2153](https://github.com/hapijs/hapi/issues/2153) Change etag based on vary header by default +- [#2152](https://github.com/hapijs/hapi/issues/2152) Change server method generateKey() to only take the arguments +- [#2150](https://github.com/hapijs/hapi/pull/2150) argument Object Optimizations +- [#2149](https://github.com/hapijs/hapi/issues/2149) Support server methods without callback +- [#2148](https://github.com/hapijs/hapi/issues/2148) Optimize use of arguments +- [#2146](https://github.com/hapijs/hapi/issues/2146) Deep copy app and plugins configurations +- [#2145](https://github.com/hapijs/hapi/issues/2145) Split request log events into request and request-internal +- [#2144](https://github.com/hapijs/hapi/issues/2144) Rename server event internalError to `request-error` +- [#2143](https://github.com/hapijs/hapi/issues/2143) Replace log 'hapi' tag with event.internal flag +- [#2142](https://github.com/hapijs/hapi/issues/2142) Rename request.responses to request.preResponses +- [#2137](https://github.com/hapijs/hapi/issues/2137) Remove auth authenticate() `log` option in result +- [#2136](https://github.com/hapijs/hapi/pull/2136) Here comes 8 +- [#2135](https://github.com/hapijs/hapi/issues/2135) Remove Hapi.version +- [#2131](https://github.com/hapijs/hapi/issues/2131) Simplify server.register() to only accept register() or { register, options } +- [#2129](https://github.com/hapijs/hapi/issues/2129) Support promises in server.method() +- [#2128](https://github.com/hapijs/hapi/issues/2128) Change server.method() object key from fn to method +- [#2126](https://github.com/hapijs/hapi/issues/2126) Change server.cache() to take only options +- [#2125](https://github.com/hapijs/hapi/issues/2125) Remove .hapi references +- [#2124](https://github.com/hapijs/hapi/issues/2124) Server-level connection defaults +- [#2122](https://github.com/hapijs/hapi/issues/2122) Pass the reply() interface everywhere a response can be returned +- [#2118](https://github.com/hapijs/hapi/issues/2118) Cleanup register() to accept a plugin or { plugin, options } +- [#2117](https://github.com/hapijs/hapi/issues/2117) Update hapijs/joi to 4.8.0 from 4.7.0 +- [#2116](https://github.com/hapijs/hapi/issues/2116) Move peek logic to Peekaboo +- [#2113](https://github.com/hapijs/hapi/issues/2113) Missing host will default to hostname or 'localhost' instead of '0.0.0.0' pre start() +- [#2112](https://github.com/hapijs/hapi/issues/2112) Switch unix domain socket and windows named pipe to use options.port +- [#2111](https://github.com/hapijs/hapi/issues/2111) CORS matchOrigin should echo origin when config doesn't specify +- [#2109](https://github.com/hapijs/hapi/issues/2109) Remove request aborted listener +- [#2104](https://github.com/hapijs/hapi/issues/2104) Apply `reply.continue()` to auth interfaces +- [#2103](https://github.com/hapijs/hapi/issues/2103) Change ext continuation method from `reply()` to `reply.continue()` +- [#2099](https://github.com/hapijs/hapi/issues/2099) ETags never match with varyEtag setting +- [#2097](https://github.com/hapijs/hapi/issues/2097) Support Promises in reply() interface +- [#2096](https://github.com/hapijs/hapi/issues/2096) Skip onPreResponse when connection closes prematurely +- [#2095](https://github.com/hapijs/hapi/issues/2095) Rework composer format +- [#2093](https://github.com/hapijs/hapi/pull/2093) Include ETag and Last-Modified in 304 response +- [#2092](https://github.com/hapijs/hapi/issues/2092) Change default port to 0 +- [#2090](https://github.com/hapijs/hapi/issues/2090) Remove plugin.version +- [#2089](https://github.com/hapijs/hapi/issues/2089) Server method `generateKey` no longer supports returning null as valid no caching indicator +- [#2086](https://github.com/hapijs/hapi/issues/2086) Remove bin/hapi +- [#2085](https://github.com/hapijs/hapi/issues/2085) Remove server.compose() +- [#2084](https://github.com/hapijs/hapi/issues/2084) Remove Hapi.state.prepareValue() +- [#2083](https://github.com/hapijs/hapi/issues/2083) Remove Hapi.error +- [#2082](https://github.com/hapijs/hapi/issues/2082) Remove Hapi.createServer() +- [#2080](https://github.com/hapijs/hapi/issues/2080) app config no longer copied over to server.app or connection.app +- [#2077](https://github.com/hapijs/hapi/issues/2077) Rename .server -> .connection and .pack -> .server +- [#2076](https://github.com/hapijs/hapi/issues/2076) Move files.etagsCacheMaxSize to pack level +- [#2074](https://github.com/hapijs/hapi/issues/2074) server.auth.default is not exposed at plugin.auth.default +- [#2073](https://github.com/hapijs/hapi/issues/2073) Split process load from server load limits +- [#2072](https://github.com/hapijs/hapi/issues/2072) Remove debug from server configuration +- [#2071](https://github.com/hapijs/hapi/issues/2071) Move proxy handler to use local maxSocket config +- [#2066](https://github.com/hapijs/hapi/issues/2066) Configure auth scheme to require payload validation +- [#2065](https://github.com/hapijs/hapi/issues/2065) failing to generate a method key should generate an error somewhere +- [#2053](https://github.com/hapijs/hapi/issues/2053) Change plugin.servers to plugin.connections +- [#2052](https://github.com/hapijs/hapi/issues/2052) Remove plugin.length +- [#2048](https://github.com/hapijs/hapi/issues/2048) New Event for request.log +- [#2040](https://github.com/hapijs/hapi/issues/2040) Improve request ID generator to prevent collisions +- [#2003](https://github.com/hapijs/hapi/issues/2003) Stop cache client when pack stops +- [#1994](https://github.com/hapijs/hapi/issues/1994) Pass meta data from a joi object to a failAction +- [#1977](https://github.com/hapijs/hapi/issues/1977) Throw when route() is called with multiple arguments +- [#1971](https://github.com/hapijs/hapi/issues/1971) Allow plugins to extend Server +- [#1965](https://github.com/hapijs/hapi/issues/1965) Need to know when response was sent in `server.on(tail)` +- [#1963](https://github.com/hapijs/hapi/issues/1963) Extensible reply() interface +- [#1945](https://github.com/hapijs/hapi/issues/1945) IE <=8 doesn't accept application/javascript as a mimetype +- [#1939](https://github.com/hapijs/hapi/issues/1939) Reverse Routing a URL +- [#1926](https://github.com/hapijs/hapi/issues/1926) Remove special handling of the HTTP Location header +- [#1902](https://github.com/hapijs/hapi/issues/1902) reply.redirect() and reply.file() not working in server extensions +- [#1866](https://github.com/hapijs/hapi/issues/1866) Throw error when trying to reply twice +- [#1864](https://github.com/hapijs/hapi/issues/1864) Feature Request: Validation of non-200/ok responses. +- [#1815](https://github.com/hapijs/hapi/issues/1815) spdy support +- [#1723](https://github.com/hapijs/hapi/issues/1723) Allow response object stripping according to schema +- [#1686](https://github.com/hapijs/hapi/issues/1686) Don't report request closed on redirect payload write +- [#1672](https://github.com/hapijs/hapi/issues/1672) Enable starting the server listener externally + +## Version 7 {#v7} + +### [7.5.3](https://github.com/hapijs/hapi/milestone/134) {#7.5.3} + +- [#2290](https://github.com/hapijs/hapi/issues/2290) Update hapijs/inert to 1.1.1 from 1.1.0 + +### [7.5.2](https://github.com/hapijs/hapi/milestone/132) {#7.5.2} + +- [#2123](https://github.com/hapijs/hapi/issues/2123) Upgrade hoek to 2.9.0 + +### [7.5.1](https://github.com/hapijs/hapi/milestone/131) {#7.5.1} + +- [#2120](https://github.com/hapijs/hapi/issues/2120) TypeError: Cannot read property 'get' of undefined + +### [7.5.0](https://github.com/hapijs/hapi/milestone/130) {#7.5.0} + +- [#2105](https://github.com/hapijs/hapi/pull/2105) Added ability to pass option into unstate. +- [#2068](https://github.com/hapijs/hapi/issues/2068) it is not possible to unstate a cookie that was stated with options +- [#1916](https://github.com/hapijs/hapi/issues/1916) Temp file is not deleted when request is aborted by client + +### [7.4.0](https://github.com/hapijs/hapi/milestone/129) {#7.4.0} + +- [#2108](https://github.com/hapijs/hapi/issues/2108) Upgrade qs to version 2.3.2 +- [#2107](https://github.com/hapijs/hapi/issues/2107) Upgrade mime-db to 1.1.2 +- [#2100](https://github.com/hapijs/hapi/pull/2100) Global view context. +- [#2027](https://github.com/hapijs/hapi/issues/2027) JPG vs jpg + +### [7.3.0](https://github.com/hapijs/hapi/milestone/128) {#7.3.0} + +- [#2098](https://github.com/hapijs/hapi/issues/2098) Catbox 4.1 + +### [7.2.0](https://github.com/hapijs/hapi/milestone/126) {#7.2.0} + +- [#2069](https://github.com/hapijs/hapi/pull/2069) Isolate server in its own pack +- [#2061](https://github.com/hapijs/hapi/pull/2061) Second phase of server/pack/plugin refactor +- [#2057](https://github.com/hapijs/hapi/pull/2057) Pack refactor +- [#2056](https://github.com/hapijs/hapi/issues/2056) Enhance Pack to have the full plugin API directly +- [#2055](https://github.com/hapijs/hapi/issues/2055) Move plugin dependency validation to start() +- [#2054](https://github.com/hapijs/hapi/issues/2054) Move composer logic to glue + +### [7.1.1](https://github.com/hapijs/hapi/milestone/125) {#7.1.1} + +- [#2046](https://github.com/hapijs/hapi/issues/2046) Fix shrinkwrap + +### [7.1.0](https://github.com/hapijs/hapi/milestone/124) {#7.1.0} + +- [#2039](https://github.com/hapijs/hapi/issues/2039) Added npm-shrinkwrap + +### [7.0.1](https://github.com/hapijs/hapi/milestone/123) {#7.0.1} + +- [#2038](https://github.com/hapijs/hapi/issues/2038) Move cli logic to rejoice +- [#2036](https://github.com/hapijs/hapi/issues/2036) Move lru-cache to inert +- [#2035](https://github.com/hapijs/hapi/pull/2035) lab 5.0 features. Closes #2034 +- [#2034](https://github.com/hapijs/hapi/issues/2034) Lab 5.0 +- [#2029](https://github.com/hapijs/hapi/pull/2029) Fixes #2028. Updated error message for invalid scope to explain that any of the specified are sufficient +- [#2028](https://github.com/hapijs/hapi/issues/2028) Improve error message when auth scope is insufficient +- [#2024](https://github.com/hapijs/hapi/pull/2024) Resolve undefined environment variables to the empty string in the cli. + +### [7.0.0](https://github.com/hapijs/hapi/milestone/117) {#7.0.0} + +- [#2023](https://github.com/hapijs/hapi/issues/2023) 7.0.0 Release Notes +- [#2022](https://github.com/hapijs/hapi/issues/2022) Spin off file and directory to inert +- [#2021](https://github.com/hapijs/hapi/issues/2021) Override server files.relativeTo config per route +- [#2020](https://github.com/hapijs/hapi/issues/2020) h2o2 2.0 +- [#2019](https://github.com/hapijs/hapi/issues/2019) Catbox 4.0 +- [#2017](https://github.com/hapijs/hapi/pull/2017) Initial 7.0 changes +- [#2016](https://github.com/hapijs/hapi/issues/2016) Remove $env support from pack.compose() +- [#2011](https://github.com/hapijs/hapi/issues/2011) Hapi should not override `cache-control` header if it's manually set by user's code +- [#2007](https://github.com/hapijs/hapi/issues/2007) Remove server views config +- [#1960](https://github.com/hapijs/hapi/issues/1960) Remove support for tos authentication setting +- [#1955](https://github.com/hapijs/hapi/pull/1955) Use environment variables in CLI configuration json file +- [#1954](https://github.com/hapijs/hapi/issues/1954) Remove support for catbox getOrGenerate() +- [#1941](https://github.com/hapijs/hapi/issues/1941) Remove route from handler registration arguments +- [#1913](https://github.com/hapijs/hapi/issues/1913) Change proxy localStatePassThrough setting default to false + +## Version 6 {#v6} + +### [6.11.1](https://github.com/hapijs/hapi/milestone/122) {#6.11.1} + +- [#2010](https://github.com/hapijs/hapi/pull/2010) Heavy +- [#2009](https://github.com/hapijs/hapi/issues/2009) Setting event loop delay max lower than sample interval leads to false positive +- [#2008](https://github.com/hapijs/hapi/issues/2008) Break load handler implementation into separate module +- [#2002](https://github.com/hapijs/hapi/pull/2002) show route method in error message + +### [6.11.0](https://github.com/hapijs/hapi/milestone/121) {#6.11.0} + +- [#2005](https://github.com/hapijs/hapi/pull/2005) Replace negotiator +- [#2004](https://github.com/hapijs/hapi/issues/2004) Default accept-encoding '\*' to 'identity', not 'gzip' +- [#2001](https://github.com/hapijs/hapi/pull/2001) Keep the options of server.inject untouched #2000 +- [#1995](https://github.com/hapijs/hapi/issues/1995) Adding route with multiple methods overrides route config +- [#1984](https://github.com/hapijs/hapi/issues/1984) All non 200 responses get cache-control=no-cache header +- [#1845](https://github.com/hapijs/hapi/issues/1845) Replace negotiator + +### [6.10.0](https://github.com/hapijs/hapi/milestone/120) {#6.10.0} + +- [#1998](https://github.com/hapijs/hapi/pull/1998) Migrate payload parsing to subtext with multipart support via pez +- [#1997](https://github.com/hapijs/hapi/issues/1997) Allow payload parsing timeout override per route +- [#1996](https://github.com/hapijs/hapi/issues/1996) Apply payload failAction to maxBytes and invalid content type +- [#1993](https://github.com/hapijs/hapi/pull/1993) Replaced optimist with bossy +- [#1928](https://github.com/hapijs/hapi/pull/1928) Handle empty or falsy charset in response +- [#1923](https://github.com/hapijs/hapi/issues/1923) Replace multiparty +- [#1843](https://github.com/hapijs/hapi/issues/1843) Replace optimist + +### [6.9.0](https://github.com/hapijs/hapi/milestone/119) {#6.9.0} + +- [#1973](https://github.com/hapijs/hapi/issues/1973) Move proxy decorations to h2o2 +- [#1972](https://github.com/hapijs/hapi/issues/1972) Move view decorations to vision +- [#1969](https://github.com/hapijs/hapi/issues/1969) Move mime to mimos +- [#1968](https://github.com/hapijs/hapi/pull/1968) Vision / Mimos +- [#1967](https://github.com/hapijs/hapi/issues/1967) Move views code to vision +- [#1959](https://github.com/hapijs/hapi/pull/1959) Fix server/plugin ext views conflict +- [#1958](https://github.com/hapijs/hapi/pull/1958) Move proxy handler to h2o2 +- [#1957](https://github.com/hapijs/hapi/issues/1957) Move proxy handler to h2o2 +- [#1956](https://github.com/hapijs/hapi/pull/1956) Fix Content-Type overriding +- [#1944](https://github.com/hapijs/hapi/pull/1944) Move router to Call +- [#1943](https://github.com/hapijs/hapi/issues/1943) Move routing login out to call +- [#1934](https://github.com/hapijs/hapi/pull/1934) Fix non-spec compliant Last-Modified header in response +- [#1932](https://github.com/hapijs/hapi/pull/1932) handle empty CORS expose-headers header response +- [#1924](https://github.com/hapijs/hapi/issues/1924) Unable to provide views override in onPreResponse + +### [6.8.1](https://github.com/hapijs/hapi/milestone/118) {#6.8.1} + +- [#1922](https://github.com/hapijs/hapi/issues/1922) Handle server methods without cache as special case + +### [6.8.0](https://github.com/hapijs/hapi/milestone/116) {#6.8.0} + +- [#1935](https://github.com/hapijs/hapi/issues/1935) server.method breaking change +- [#1919](https://github.com/hapijs/hapi/pull/1919) Log method pre string notation +- [#1917](https://github.com/hapijs/hapi/issues/1917) Log cache info when using server method short hand calls +- [#1915](https://github.com/hapijs/hapi/pull/1915) Issue/1911 +- [#1914](https://github.com/hapijs/hapi/issues/1914) catbox 3.2 +- [#1911](https://github.com/hapijs/hapi/issues/1911) Exclude configured cookies from proxy passthrough +- [#1905](https://github.com/hapijs/hapi/pull/1905) Replaced mime-type with mime. +- [#1890](https://github.com/hapijs/hapi/issues/1890) Use mime-db +- [#1889](https://github.com/hapijs/hapi/pull/1889) Upgrade to wreck v5 +- [#1888](https://github.com/hapijs/hapi/issues/1888) Upgrade to Wreck v5 +- [#1828](https://github.com/hapijs/hapi/issues/1828) Disable compression on file types already compressed (png, jpg) + +### [6.7.1](https://github.com/hapijs/hapi/milestone/115) {#6.7.1} + +- [#1885](https://github.com/hapijs/hapi/issues/1885) Handler timeout with onPreResponse asserts on bad protect + +### [6.7.0](https://github.com/hapijs/hapi/milestone/114) {#6.7.0} + +- [#1884](https://github.com/hapijs/hapi/issues/1884) Improve protect logging +- [#1881](https://github.com/hapijs/hapi/pull/1881) update qs dependency + +### [6.6.0](https://github.com/hapijs/hapi/milestone/113) {#6.6.0} + +- [#1878](https://github.com/hapijs/hapi/issues/1878) Rename private route members +- [#1877](https://github.com/hapijs/hapi/issues/1877) Move state.js to statehood module +- [#1875](https://github.com/hapijs/hapi/issues/1875) Session scope does not match one to many auth.scope on route. +- [#1871](https://github.com/hapijs/hapi/issues/1871) Switch to wreck +- [#1863](https://github.com/hapijs/hapi/pull/1863) Allow agent to be set on proxy options and passed into Nipple. +- [#1858](https://github.com/hapijs/hapi/pull/1858) Fix typo in defaults.js +- [#1856](https://github.com/hapijs/hapi/pull/1856) Allow view options override on handler object + +### [6.5.1](https://github.com/hapijs/hapi/milestone/112) {#6.5.1} + +- [#1857](https://github.com/hapijs/hapi/issues/1857) Manifest validation tests server config before defaults applies + +### [6.5.0](https://github.com/hapijs/hapi/milestone/111) {#6.5.0} + +- [#1851](https://github.com/hapijs/hapi/pull/1851) Updated route documentation. +- [#1844](https://github.com/hapijs/hapi/issues/1844) Replace async +- [#1842](https://github.com/hapijs/hapi/pull/1842) Lab 4.00 +- [#1840](https://github.com/hapijs/hapi/issues/1840) No longer possible to load caches using CLI? +- [#1835](https://github.com/hapijs/hapi/issues/1835) server.state ttl must be a number +- [#1832](https://github.com/hapijs/hapi/issues/1832) Replace mime with mime-type +- [#1822](https://github.com/hapijs/hapi/pull/1822) Added joi validation to manifest. +- [#1795](https://github.com/hapijs/hapi/issues/1795) request.server.\_views in plugin +- [#1722](https://github.com/hapijs/hapi/issues/1722) Validate compose manifest + +### [6.4.0](https://github.com/hapijs/hapi/milestone/110) {#6.4.0} + +- [#1831](https://github.com/hapijs/hapi/issues/1831) Upgrade to qs 1.0.0 +- [#1810](https://github.com/hapijs/hapi/pull/1810) set X-Content-Type-Options to nosnif for jsonp responses + +### [6.3.0](https://github.com/hapijs/hapi/milestone/109) {#6.3.0} + +- [#1827](https://github.com/hapijs/hapi/issues/1827) Cannot call setTimeout with non-integer msec value +- [#1826](https://github.com/hapijs/hapi/issues/1826) Support cache generateTimeout setting + +### [6.2.2](https://github.com/hapijs/hapi/milestone/108) {#6.2.2} + +- [#1820](https://github.com/hapijs/hapi/issues/1820) Rename spumko to hapijs + +### [6.2.1](https://github.com/hapijs/hapi/milestone/107) {#6.2.1} + +- [#1801](https://github.com/hapijs/hapi/issues/1801) Stale dependencies + +### [6.2.0](https://github.com/hapijs/hapi/milestone/106) {#6.2.0} + +- [#1790](https://github.com/hapijs/hapi/issues/1790) Expose authentication mode +- [#1767](https://github.com/hapijs/hapi/issues/1767) plugin.location + +### [6.1.0](https://github.com/hapijs/hapi/milestone/105) {#6.1.0} + +- [#1788](https://github.com/hapijs/hapi/issues/1788) Last-Modified comparison needs to account for 1 second precision +- [#1783](https://github.com/hapijs/hapi/issues/1783) Change etag when content-encoding is used +- [#1782](https://github.com/hapijs/hapi/issues/1782) server.inject() res.result does not reflect actual payload sent on 304/204 +- [#1781](https://github.com/hapijs/hapi/issues/1781) Send empty payload on 204 +- [#1778](https://github.com/hapijs/hapi/pull/1778) Do not create a duplicate Content-Type header on proxy passthrough +- [#1777](https://github.com/hapijs/hapi/issues/1777) Duplicated "Content-Type" header on proxy requests +- [#1776](https://github.com/hapijs/hapi/issues/1776) Proxy pass-through with onResponse fails to preserve vary header values +- [#1774](https://github.com/hapijs/hapi/pull/1774) Style fixes +- [#1773](https://github.com/hapijs/hapi/issues/1773) Windows path fails on trailing slash on view helpers +- [#1772](https://github.com/hapijs/hapi/issues/1772) HEAD requests should retail etag header +- [#1771](https://github.com/hapijs/hapi/issues/1771) Open open one file stream when using precompressed file +- [#1769](https://github.com/hapijs/hapi/issues/1769) Plugin X missing dependency Y in server if manifest.plugins key order not carefully managed +- [#1766](https://github.com/hapijs/hapi/pull/1766) prepend jsonp callbacks with a comment to prevent the rosetta-flash vulnerability +- [#1763](https://github.com/hapijs/hapi/pull/1763) fixes #1755 - stripTrailingSlash doesn't work when query variables are used +- [#1762](https://github.com/hapijs/hapi/pull/1762) fix content-type overriding issue #1760. +- [#1760](https://github.com/hapijs/hapi/issues/1760) How can I set Content-Type header to the content generated from reply.view? +- [#1756](https://github.com/hapijs/hapi/pull/1756) Follow coding conventions concerning semicolons; Don't initialize variab... +- [#1755](https://github.com/hapijs/hapi/issues/1755) Server Options for Router: stripTrailingSlash doesn't work with query string +- [#1754](https://github.com/hapijs/hapi/issues/1754) File handler to handle 206 Partial Content? +- [#1752](https://github.com/hapijs/hapi/pull/1752) Adding helpful error message when pack.register is missing a callback +- [#1751](https://github.com/hapijs/hapi/issues/1751) Calling pack.register without a callback has an unfriendly error +- [#1745](https://github.com/hapijs/hapi/pull/1745) Add joi validation of pack options +- [#1733](https://github.com/hapijs/hapi/pull/1733) log function should only emit once if \_server object +- [#1728](https://github.com/hapijs/hapi/issues/1728) 6.x breaks plugin modules exporting functions +- [#1721](https://github.com/hapijs/hapi/issues/1721) Validate pack options +- [#1676](https://github.com/hapijs/hapi/issues/1676) Problem serving precompressed files with directory handler +- [#1407](https://github.com/hapijs/hapi/issues/1407) Skip opening file or rendering view on head or 304 + +### [6.0.2](https://github.com/hapijs/hapi/milestone/104) {#6.0.2} + +- [#1720](https://github.com/hapijs/hapi/issues/1720) No way to handle root routes with `route: {prefix: '...'}` +- [#1719](https://github.com/hapijs/hapi/pull/1719) Fixes undefined error in `plugin.dependency` + +### [6.0.1](https://github.com/hapijs/hapi/milestone/103) {#6.0.1} + +- [#1710](https://github.com/hapijs/hapi/issues/1710) Buffer based passwords fail schema validation (6.0 regression) + +### [6.0.0](https://github.com/hapijs/hapi/milestone/102) {#6.0.0} + +- [#1841](https://github.com/hapijs/hapi/issues/1841) Missing plugin error on migrating from 5.0 provides no useful information +- [#1708](https://github.com/hapijs/hapi/issues/1708) Hapi 6.0 no longer invalidates auth strategy on registration of route +- [#1707](https://github.com/hapijs/hapi/issues/1707) 6.0.0 Release Notes +- [#1703](https://github.com/hapijs/hapi/issues/1703) Catbox 3.0 and drop internal require support +- [#1701](https://github.com/hapijs/hapi/issues/1701) MODULE_NOT_FOUND on Windows when requirePath is absolute +- [#1700](https://github.com/hapijs/hapi/issues/1700) Change the order of actions when starting a pack +- [#1696](https://github.com/hapijs/hapi/issues/1696) Non-Error auth err responses are ignored in try mode +- [#1695](https://github.com/hapijs/hapi/issues/1695) Preserve auth error on try +- [#1694](https://github.com/hapijs/hapi/issues/1694) Minor error tweaks +- [#1693](https://github.com/hapijs/hapi/issues/1693) Enhance setting authentication defaults +- [#1692](https://github.com/hapijs/hapi/issues/1692) Allow testing a request against any configured authentication strategy +- [#1691](https://github.com/hapijs/hapi/pull/1691) V6.0 +- [#1688](https://github.com/hapijs/hapi/issues/1688) Bring back reply.redirect() +- [#1687](https://github.com/hapijs/hapi/issues/1687) Don't log auth non-error responses with 'error' tag +- [#1679](https://github.com/hapijs/hapi/issues/1679) Allow cookie-specific settings for failAction, strictHeader, and clearInvalid +- [#1678](https://github.com/hapijs/hapi/issues/1678) Expose the location header logic +- [#1677](https://github.com/hapijs/hapi/issues/1677) Enhance manifest format to support registration options (select, prefix, vhost) +- [#1675](https://github.com/hapijs/hapi/issues/1675) Remove pack.list +- [#1674](https://github.com/hapijs/hapi/issues/1674) Make plugin register() and dependency() selectable +- [#1673](https://github.com/hapijs/hapi/issues/1673) Make plugin.events selectable +- [#1668](https://github.com/hapijs/hapi/issues/1668) Delete 'Accept-Encoding' header on proxy requests +- [#1666](https://github.com/hapijs/hapi/issues/1666) Allow loading different plugins (or same plugins) to different servers in pack +- [#1665](https://github.com/hapijs/hapi/issues/1665) duplicate require calls in hapi/lib/views.js +- [#1664](https://github.com/hapijs/hapi/issues/1664) Upgrading plugins to hapi 6.0 (preview) +- [#1663](https://github.com/hapijs/hapi/issues/1663) Allow register to pre-select servers +- [#1662](https://github.com/hapijs/hapi/issues/1662) Config clones bind, app, and plugins +- [#1661](https://github.com/hapijs/hapi/issues/1661) View manager clones engines including modules +- [#1659](https://github.com/hapijs/hapi/issues/1659) plugin.view() modifies options' basePath +- [#1658](https://github.com/hapijs/hapi/issues/1658) Set route path prefix when loading plugin +- [#1656](https://github.com/hapijs/hapi/issues/1656) Remove pack.require() and plugin.require() +- [#1655](https://github.com/hapijs/hapi/issues/1655) Remove support for string view engine config +- [#1653](https://github.com/hapijs/hapi/issues/1653) Move Composer into Pack.compose() +- [#1652](https://github.com/hapijs/hapi/issues/1652) Remove composer support for multiple packs +- [#1651](https://github.com/hapijs/hapi/issues/1651) 6.0.0 Breaking Changes +- [#1499](https://github.com/hapijs/hapi/issues/1499) Composer not resolving plugins correctly +- [#1490](https://github.com/hapijs/hapi/issues/1490) Feature Request: composer.log +- [#1471](https://github.com/hapijs/hapi/issues/1471) pack.requirePath vs view engine loader +- [#981](https://github.com/hapijs/hapi/issues/981) Scope plugin routes to a virtual host + +## Version 5 {#v5} + +### [5.1.0](https://github.com/hapijs/hapi/milestone/101) {#5.1.0} + +- [#1581](https://github.com/hapijs/hapi/issues/1581) Authentication throws are treated as valid reply() +- [#1579](https://github.com/hapijs/hapi/issues/1579) Add option to remove trailing slashes to router +- [#1574](https://github.com/hapijs/hapi/issues/1574) Document the best way to implement a 404 from the directory handler when using path callback +- [#1573](https://github.com/hapijs/hapi/issues/1573) Server throttling controls do not log execution +- [#1508](https://github.com/hapijs/hapi/issues/1508) Escaped error message with regex validation +- [#1477](https://github.com/hapijs/hapi/issues/1477) proxy xforward option will set bad headers in some cases + +### [5.0.0](https://github.com/hapijs/hapi/milestone/100) {#5.0.0} + +- [#1645](https://github.com/hapijs/hapi/issues/1645) 5.0.0 Release Notes +- [#1644](https://github.com/hapijs/hapi/issues/1644) request.params contains empty strings for missing optional params +- [#1643](https://github.com/hapijs/hapi/issues/1643) Expose cross inputs as validation context +- [#1642](https://github.com/hapijs/hapi/pull/1642) Cjihrig header validation +- [#1641](https://github.com/hapijs/hapi/pull/1641) Upgrade to joi 4.x +- [#1640](https://github.com/hapijs/hapi/issues/1640) Rename route `config.validate.path` to `config.validate.params` +- [#1639](https://github.com/hapijs/hapi/issues/1639) Response validation modifies payload +- [#1622](https://github.com/hapijs/hapi/pull/1622) Extend Hapi cli to enable loading a module before loading hapi +- [#1589](https://github.com/hapijs/hapi/pull/1589) Added validation for request headers. +- [#1588](https://github.com/hapijs/hapi/issues/1588) Validation for cookies and other headers + +## Version 4 {#v4} + +### [4.1.4](https://github.com/hapijs/hapi/milestone/99) {#4.1.4} + +- [#1638](https://github.com/hapijs/hapi/issues/1638) Unahndled Exception when a request is aborted + +### [4.1.3](https://github.com/hapijs/hapi/milestone/98) {#4.1.3} + +### [4.1.2](https://github.com/hapijs/hapi/milestone/97) {#4.1.2} + +- [#1635](https://github.com/hapijs/hapi/pull/1635) Remove reference to request in domain. Closes #1634 +- [#1634](https://github.com/hapijs/hapi/issues/1634) Request domain leaks request object + +### [4.1.1](https://github.com/hapijs/hapi/milestone/96) {#4.1.1} + +- [#1633](https://github.com/hapijs/hapi/pull/1633) Rework domains to single entry +- [#1632](https://github.com/hapijs/hapi/pull/1632) Clean response objects for aborted requests +- [#1619](https://github.com/hapijs/hapi/pull/1619) Avoid async operations while protect is running + +### [4.1.0](https://github.com/hapijs/hapi/milestone/93) {#4.1.0} + +- [#1583](https://github.com/hapijs/hapi/pull/1583) Support JSON-derived media types +- [#1461](https://github.com/hapijs/hapi/pull/1461) Security headers + +### [4.0.3](https://github.com/hapijs/hapi/milestone/95) {#4.0.3} + +- [#1604](https://github.com/hapijs/hapi/issues/1604) response emitter fails to retain custom event listeners once sent +- [#1597](https://github.com/hapijs/hapi/issues/1597) Template helpers fail on relative paths + +### [4.0.2](https://github.com/hapijs/hapi/milestone/94) {#4.0.2} + +- [#1598](https://github.com/hapijs/hapi/issues/1598) Throws when response does not have \_close() + +### [4.0.1](https://github.com/hapijs/hapi/milestone/92) {#4.0.1} + +- [#1594](https://github.com/hapijs/hapi/issues/1594) Can jsonp be optional? +- [#1591](https://github.com/hapijs/hapi/issues/1591) Find better way to drain non file/socket stream than read() +- [#1590](https://github.com/hapijs/hapi/issues/1590) RSS leak occurs when request does not read entire stream response +- [#1575](https://github.com/hapijs/hapi/issues/1575) Precompile joi response validation +- [#1569](https://github.com/hapijs/hapi/issues/1569) Move ext topo sort to its own module +- [#1567](https://github.com/hapijs/hapi/pull/1567) allow defaultExtension +- [#1566](https://github.com/hapijs/hapi/issues/1566) Precompile joi validation + +### [4.0.0](https://github.com/hapijs/hapi/milestone/91) {#4.0.0} + +- [#1560](https://github.com/hapijs/hapi/issues/1560) 4.0.0 +- [#1559](https://github.com/hapijs/hapi/issues/1559) joi 3.0 +- [#1558](https://github.com/hapijs/hapi/issues/1558) Change Hapi.utils.version() to Hapi.version and remove Hoek alias +- [#1554](https://github.com/hapijs/hapi/pull/1554) coverage, closes #1524 +- [#1551](https://github.com/hapijs/hapi/pull/1551) add an insecureAgent when maxSockets is set, closes #1512 +- [#1548](https://github.com/hapijs/hapi/pull/1548) wip: fix windows bugs +- [#1547](https://github.com/hapijs/hapi/pull/1547) Make certain that path is relative before joining it to relativeTo +- [#1524](https://github.com/hapijs/hapi/issues/1524) Coverage after lab partial condition result coverage +- [#1521](https://github.com/hapijs/hapi/pull/1521) Allow plugins to register handler types + +## Version 3 {#v3} + +### [3.1.0](https://github.com/hapijs/hapi/milestone/90) {#3.1.0} + +- [#1541](https://github.com/hapijs/hapi/issues/1541) Clarify that statusCode key of stream response passed in response +- [#1540](https://github.com/hapijs/hapi/issues/1540) Pre-gzipped source stream not properly tested for being the active source +- [#1538](https://github.com/hapijs/hapi/issues/1538) Passing Error objects can leak message in 500 response +- [#1536](https://github.com/hapijs/hapi/issues/1536) maxEventLoopDelay fails to catch when load is too high to reach next sample interval +- [#1535](https://github.com/hapijs/hapi/issues/1535) Cannot set maxSockets to node default +- [#1533](https://github.com/hapijs/hapi/issues/1533) Proxy without passThrough fails to set cache-control header +- [#1532](https://github.com/hapijs/hapi/issues/1532) Multipart payload to files with multiple files skips second file when large +- [#1531](https://github.com/hapijs/hapi/issues/1531) pack.log() doesn't retain server debug false setting +- [#1530](https://github.com/hapijs/hapi/issues/1530) plugin.method() should use method bind before plugin bind +- [#1525](https://github.com/hapijs/hapi/pull/1525) expose filename and headers for streams in a multipart form +- [#1523](https://github.com/hapijs/hapi/issues/1523) Question: How to validate payload with templated response properly ? +- [#1520](https://github.com/hapijs/hapi/issues/1520) server.table() mis-documented, missing args, and route.table() is wrong +- [#1518](https://github.com/hapijs/hapi/issues/1518) Server timeout config allows invalid values +- [#1517](https://github.com/hapijs/hapi/issues/1517) Proxy handler payload config validation using incorrect variable +- [#1515](https://github.com/hapijs/hapi/issues/1515) Coverage to 100% after lab logical statement support +- [#1514](https://github.com/hapijs/hapi/issues/1514) Server allows duplicate lables +- [#1513](https://github.com/hapijs/hapi/issues/1513) Authentication userland code not protected by domain + +### [3.0.2](https://github.com/hapijs/hapi/milestone/89) {#3.0.2} + +- [#1507](https://github.com/hapijs/hapi/issues/1507) request.setUrl('') throws + +### [3.0.1](https://github.com/hapijs/hapi/milestone/88) {#3.0.1} + +- [#1503](https://github.com/hapijs/hapi/issues/1503) plugin.method(name, fn, [options]) fails + +### [3.0.0](https://github.com/hapijs/hapi/milestone/86) {#3.0.0} + +- [#1485](https://github.com/hapijs/hapi/issues/1485) Bring coverage back to 100% after lab fix +- [#1483](https://github.com/hapijs/hapi/issues/1483) server.helper cache hit causing the object type to be different +- [#1479](https://github.com/hapijs/hapi/issues/1479) Less major version drama +- [#1478](https://github.com/hapijs/hapi/issues/1478) Use joi 2.8 alternatives() +- [#1476](https://github.com/hapijs/hapi/pull/1476) add PATCH to default cors methods, closes #1475 +- [#1475](https://github.com/hapijs/hapi/issues/1475) Include PATCH method in options/cors/methods default +- [#1474](https://github.com/hapijs/hapi/issues/1474) v3.0.0 Breaking Changes +- [#1473](https://github.com/hapijs/hapi/issues/1473) Drop dtrace support +- [#1466](https://github.com/hapijs/hapi/issues/1466) Drop support for server helpers +- [#1465](https://github.com/hapijs/hapi/issues/1465) Migrate to catbox 2.0 +- [#1464](https://github.com/hapijs/hapi/issues/1464) When in a route config, Joi.any.rename(, {move:true}) doesnt move item in the payload +- [#1458](https://github.com/hapijs/hapi/pull/1458) Removed Http(s) globalAgent settings + +## Version 2 {#v2} + +### [2.6.0](https://github.com/hapijs/hapi/milestone/85) {#2.6.0} + +- [#1455](https://github.com/hapijs/hapi/issues/1455) Print to console server logs based on debug config +- [#1453](https://github.com/hapijs/hapi/pull/1453) Include prerequisites in default view context. #1452 +- [#1452](https://github.com/hapijs/hapi/issues/1452) Perhaps include `request.pre` in handler view context +- [#1451](https://github.com/hapijs/hapi/issues/1451) Objects created in plugin.dependency or plugin.after are monitored by the wrong domain +- [#1450](https://github.com/hapijs/hapi/issues/1450) Enable handlers to use the prerequisite method string notation +- [#1449](https://github.com/hapijs/hapi/issues/1449) Allow server methods names to include '.' (nested) +- [#1448](https://github.com/hapijs/hapi/issues/1448) Prerequisite string notation parsing errors +- [#1447](https://github.com/hapijs/hapi/issues/1447) Allow prerequisites string notation to use method name without () +- [#1446](https://github.com/hapijs/hapi/issues/1446) Document server method callback 'isUncacheable' argument +- [#1445](https://github.com/hapijs/hapi/issues/1445) Server method bind option +- [#1442](https://github.com/hapijs/hapi/pull/1442) Response 304 +- [#1437](https://github.com/hapijs/hapi/issues/1437) Safari 6 reload bug using directory handler + +### [2.5.0](https://github.com/hapijs/hapi/milestone/84) {#2.5.0} + +- [#1440](https://github.com/hapijs/hapi/issues/1440) Redirecting from within an Auth.Scheme generates a Circular Reference +- [#1439](https://github.com/hapijs/hapi/pull/1439) proper etag formatting +- [#1434](https://github.com/hapijs/hapi/pull/1434) Allow overriding the filename in content-disposition headers +- [#1432](https://github.com/hapijs/hapi/issues/1432) Replace server helpers with server methods +- [#1418](https://github.com/hapijs/hapi/issues/1418) normalise callback API usage OR outsmart callback API inconsistency +- [#1299](https://github.com/hapijs/hapi/issues/1299) thrown errors inside server.inject does not propagate + +### [2.4.0](https://github.com/hapijs/hapi/milestone/83) {#2.4.0} + +- [#1430](https://github.com/hapijs/hapi/issues/1430) Server fails to parse "" cookie value +- [#1428](https://github.com/hapijs/hapi/issues/1428) request.getLog() includes same event multiple times when using multiple tags +- [#1425](https://github.com/hapijs/hapi/pull/1425) return a reference to the server when adding via pack.server +- [#1424](https://github.com/hapijs/hapi/issues/1424) Searching actual working SSE example (#1008 does not work for me) +- [#1419](https://github.com/hapijs/hapi/issues/1419) Send newline \n after all responses + +### [2.3.0](https://github.com/hapijs/hapi/milestone/82) {#2.3.0} + +- [#1341](https://github.com/hapijs/hapi/issues/1341) Cookie validation does not respect the "strict" option +- [#1320](https://github.com/hapijs/hapi/issues/1320) Add support for asynchronous view rendering + +### [2.2.0](https://github.com/hapijs/hapi/milestone/81) {#2.2.0} + +- [#1427](https://github.com/hapijs/hapi/issues/1427) File descriptor leak can cause DoS vulnerability in v2.0 and v2.1 +- [#1414](https://github.com/hapijs/hapi/issues/1414) Sending incorrect status code (200) when file fails to open before transmit +- [#1413](https://github.com/hapijs/hapi/issues/1413) File stream is opened before necessary (e.g. if replaced by another response in ext) +- [#1412](https://github.com/hapijs/hapi/issues/1412) Missing file (404) not captured by onPreResponse +- [#1411](https://github.com/hapijs/hapi/issues/1411) Wasteful encoder prep when response is 304 or head +- [#1410](https://github.com/hapijs/hapi/issues/1410) passThrough statusCode overrides manual code value +- [#1409](https://github.com/hapijs/hapi/issues/1409) Status code set from upstream without passThrough flag +- [#1408](https://github.com/hapijs/hapi/issues/1408) precompressed file handle not closed when using head or 304 +- [#1405](https://github.com/hapijs/hapi/issues/1405) Call parseInt() for Joi-validated integers +- [#1404](https://github.com/hapijs/hapi/issues/1404) Protect JSON.stringify from throwing. +- [#1401](https://github.com/hapijs/hapi/issues/1401) route.payload.allow as Array never matches +- [#1400](https://github.com/hapijs/hapi/issues/1400) Question: Can you get a log of requests that don't pass validation? +- [#1395](https://github.com/hapijs/hapi/issues/1395) JSON circular structure error in authentication error logging +- [#1393](https://github.com/hapijs/hapi/pull/1393) add `gunzip` as third option to `parse`; resolves #1391 +- [#1391](https://github.com/hapijs/hapi/issues/1391) Disable autoparsing without losing gzip +- [#1387](https://github.com/hapijs/hapi/issues/1387) EMFILE error when hapi serves static files over period of time in hapi 2.1.2 +- [#1382](https://github.com/hapijs/hapi/issues/1382) Make joi optional for route validation +- [#1380](https://github.com/hapijs/hapi/pull/1380) Allow bind context for view handler +- [#1379](https://github.com/hapijs/hapi/issues/1379) plugin.bind does not apply to proxy handlers +- [#1378](https://github.com/hapijs/hapi/pull/1378) add failureResponse option to proxy handler +- [#1372](https://github.com/hapijs/hapi/issues/1372) test that handler isn't called when a request is interrupted +- [#1362](https://github.com/hapijs/hapi/issues/1362) (cookies) TypeError: Cannot call method 'match' of undefined +- [#1357](https://github.com/hapijs/hapi/pull/1357) specify hoek minor version +- [#1354](https://github.com/hapijs/hapi/pull/1354) Use configuration objects to register helpers +- [#1333](https://github.com/hapijs/hapi/issues/1333) Clarification on 'stream' changes from 1.20.x to 2.0.x +- [#1328](https://github.com/hapijs/hapi/issues/1328) How to handle custom POST content-types + +### [2.1.2](https://github.com/hapijs/hapi/milestone/80) {#2.1.2} + +- [#1359](https://github.com/hapijs/hapi/issues/1359) Ext reply(null).state() race condition +- [#1351](https://github.com/hapijs/hapi/issues/1351) Prepare for node 0.12 + +### [2.1.1](https://github.com/hapijs/hapi/milestone/79) {#2.1.1} + +- [#1347](https://github.com/hapijs/hapi/issues/1347) Views should not use basePath when path is absolute + +### [2.1.0](https://github.com/hapijs/hapi/milestone/78) {#2.1.0} + +- [#1344](https://github.com/hapijs/hapi/issues/1344) Use the plugin loader when configured to load view engines +- [#1336](https://github.com/hapijs/hapi/issues/1336) Allow custom view layout folder +- [#1335](https://github.com/hapijs/hapi/issues/1335) Allow view layout to contain a string and boolean +- [#1245](https://github.com/hapijs/hapi/issues/1245) Replace request with nipple in tests + +### [2.0.0](https://github.com/hapijs/hapi/milestone/69) {#2.0.0} + +- [#1332](https://github.com/hapijs/hapi/issues/1332) Payload always logging an error regardless of error state +- [#1331](https://github.com/hapijs/hapi/pull/1331) Fix query(string) regression +- [#1327](https://github.com/hapijs/hapi/pull/1327) Better debug support for object data +- [#1324](https://github.com/hapijs/hapi/issues/1324) When no query params are sent, request.params is null instead of {}. +- [#1322](https://github.com/hapijs/hapi/issues/1322) Does Hapi support multiple view templates? +- [#1317](https://github.com/hapijs/hapi/issues/1317) Cannot Parse form-encoded arrays +- [#1314](https://github.com/hapijs/hapi/issues/1314) Replace old payload try mode with failAction +- [#1313](https://github.com/hapijs/hapi/issues/1313) Change redirectToSlash default value to true +- [#1312](https://github.com/hapijs/hapi/issues/1312) Remove special values for server config 'files.relativeTo' +- [#1311](https://github.com/hapijs/hapi/issues/1311) Implement saving payload to file when not using mutlipart +- [#1309](https://github.com/hapijs/hapi/issues/1309) Migrate all the plugins to 2.0 +- [#1304](https://github.com/hapijs/hapi/issues/1304) Request 'peek' event +- [#1301](https://github.com/hapijs/hapi/pull/1301) `querystring` => `qs`, adds support for nested objects +- [#1300](https://github.com/hapijs/hapi/issues/1300) Do not overwrite Access-Control-Allow-Origin +- [#1297](https://github.com/hapijs/hapi/pull/1297) Document validation option in settings +- [#1296](https://github.com/hapijs/hapi/issues/1296) Possible to overwrite plugin options on a per server scope? +- [#1295](https://github.com/hapijs/hapi/issues/1295) Replace route payload.mode with payload.output and payload.parse +- [#1294](https://github.com/hapijs/hapi/issues/1294) Allow 'domain' option in cookie authentication scheme config +- [#1292](https://github.com/hapijs/hapi/issues/1292) Skip loading entire multipart to memory and stream directly to multiparty +- [#1291](https://github.com/hapijs/hapi/issues/1291) Remove server config normalizeRequestPath and default to true +- [#1290](https://github.com/hapijs/hapi/issues/1290) Partial path param match /a{b}c does not apply isCaseSensitive +- [#1289](https://github.com/hapijs/hapi/issues/1289) Problem in very large file upload +- [#1288](https://github.com/hapijs/hapi/issues/1288) Move auth schemes to plugins +- [#1287](https://github.com/hapijs/hapi/issues/1287) Split server.auth() into server.auth.scheme() and server.auth.strategy() +- [#1286](https://github.com/hapijs/hapi/issues/1286) Expose response preview as public API +- [#1285](https://github.com/hapijs/hapi/issues/1285) Change authenticate() callback to reply interface +- [#1284](https://github.com/hapijs/hapi/issues/1284) Expose request.response and change it to direct ref from func +- [#1282](https://github.com/hapijs/hapi/issues/1282) Security tests using reply().setState() which throws +- [#1281](https://github.com/hapijs/hapi/issues/1281) Change authenticate() callback signature +- [#1280](https://github.com/hapijs/hapi/issues/1280) Support node callback pattern (err, result) for reply() +- [#1279](https://github.com/hapijs/hapi/issues/1279) Convert ext method signature to handler +- [#1277](https://github.com/hapijs/hapi/issues/1277) Emit 'internalError' for every 500, not just the one sent back +- [#1276](https://github.com/hapijs/hapi/issues/1276) Retain headers in 304 response +- [#1275](https://github.com/hapijs/hapi/issues/1275) Boom 2.0 +- [#1274](https://github.com/hapijs/hapi/pull/1274) Fixed code example in README to comply with 2.0.x +- [#1272](https://github.com/hapijs/hapi/issues/1272) Redo reply.close() +- [#1270](https://github.com/hapijs/hapi/issues/1270) Apply encoding to Response.Payload operations consistently +- [#1269](https://github.com/hapijs/hapi/issues/1269) Manage state all in the request +- [#1268](https://github.com/hapijs/hapi/issues/1268) Expose more response properties +- [#1267](https://github.com/hapijs/hapi/issues/1267) Add 'app' and 'plugins' to response object +- [#1266](https://github.com/hapijs/hapi/issues/1266) Remove 'response.variety' support +- [#1264](https://github.com/hapijs/hapi/issues/1264) requesting url that is not encoded correctly should return 400, not 404 +- [#1262](https://github.com/hapijs/hapi/issues/1262) Remove response.getTtl() +- [#1261](https://github.com/hapijs/hapi/issues/1261) Rename response.uri() to response.location() +- [#1259](https://github.com/hapijs/hapi/issues/1259) onPreResponse not getting 404 for missing directory files +- [#1258](https://github.com/hapijs/hapi/issues/1258) Default Buffer responses to application/octet-stream +- [#1257](https://github.com/hapijs/hapi/issues/1257) Validate all examples +- [#1256](https://github.com/hapijs/hapi/issues/1256) Remove access to internal response types +- [#1254](https://github.com/hapijs/hapi/issues/1254) File response leaks fd if gzipped stream used instead and the other way. +- [#1253](https://github.com/hapijs/hapi/pull/1253) in directory, fix the listing of subdirs that reside in a subdirs that have spaces +- [#1252](https://github.com/hapijs/hapi/issues/1252) Protect response payload stream wrapper from multiple replays +- [#1251](https://github.com/hapijs/hapi/issues/1251) Replace File from response type to reply.file() helper +- [#1249](https://github.com/hapijs/hapi/issues/1249) Cleanup use of request.\_route.cache and request.route.cache +- [#1248](https://github.com/hapijs/hapi/issues/1248) Review proxy upstream ttl passing +- [#1247](https://github.com/hapijs/hapi/issues/1247) Clean up postResponse in proxy config +- [#1246](https://github.com/hapijs/hapi/issues/1246) Allow zero key helpers with cache +- [#1242](https://github.com/hapijs/hapi/issues/1242) Remove server-side route caching +- [#1241](https://github.com/hapijs/hapi/issues/1241) Add user/private flag to state variable +- [#1239](https://github.com/hapijs/hapi/issues/1239) Disable cache when Authorization header is included +- [#1238](https://github.com/hapijs/hapi/issues/1238) Special handling for '\*' Vary response header +- [#1236](https://github.com/hapijs/hapi/issues/1236) Review lru-cache settings +- [#1235](https://github.com/hapijs/hapi/issues/1235) Vary support in internal routes cache +- [#1234](https://github.com/hapijs/hapi/issues/1234) Move client out to separate module +- [#1233](https://github.com/hapijs/hapi/issues/1233) Clarify server app config usage +- [#1231](https://github.com/hapijs/hapi/issues/1231) request.log() no longer adds 'error' tag if data is Error +- [#1230](https://github.com/hapijs/hapi/issues/1230) Remove plugin permissions +- [#1229](https://github.com/hapijs/hapi/issues/1229) Add req.on('error'/'close') to request object processing +- [#1228](https://github.com/hapijs/hapi/issues/1228) Client request timeout and downstream listener not set when payload is a stream +- [#1223](https://github.com/hapijs/hapi/issues/1223) views.helpersPath requires .js files +- [#1222](https://github.com/hapijs/hapi/issues/1222) Proxy passthrough does not allow for cookie domain modification +- [#1219](https://github.com/hapijs/hapi/issues/1219) `pack.require` doc is somewhat incorrect +- [#1216](https://github.com/hapijs/hapi/issues/1216) Remove support for `notFound` handler string +- [#1215](https://github.com/hapijs/hapi/issues/1215) Content-type charset attribute not added to streams +- [#1214](https://github.com/hapijs/hapi/issues/1214) Allow specifying a list of method in route config +- [#1211](https://github.com/hapijs/hapi/issues/1211) Move all response payload processing to \_prepare +- [#1209](https://github.com/hapijs/hapi/issues/1209) Duplicate parameter error is missing route information +- [#1208](https://github.com/hapijs/hapi/issues/1208) Route error message does not include information about which route failed +- [#1207](https://github.com/hapijs/hapi/issues/1207) Accessing the response stream. +- [#1205](https://github.com/hapijs/hapi/issues/1205) Honor options.bind in ext +- [#1204](https://github.com/hapijs/hapi/issues/1204) Rename handler/ext context to bind +- [#1202](https://github.com/hapijs/hapi/issues/1202) Move handler and ext context to use this +- [#1200](https://github.com/hapijs/hapi/pull/1200) Removing confidence, alce from composer and CLI +- [#1199](https://github.com/hapijs/hapi/issues/1199) Remove confidence and alce dependency +- [#1195](https://github.com/hapijs/hapi/issues/1195) Move request.context to request.reply.context +- [#1194](https://github.com/hapijs/hapi/issues/1194) Remove support for decorating request with reply() +- [#1192](https://github.com/hapijs/hapi/issues/1192) Change pre type to always use handler mode +- [#1191](https://github.com/hapijs/hapi/issues/1191) Cannot use multiple parallel pre methods in handler mode +- [#1190](https://github.com/hapijs/hapi/issues/1190) Move Obj stringify step to \_prepare +- [#1189](https://github.com/hapijs/hapi/issues/1189) Attaching a websocket to a server in a pack +- [#1187](https://github.com/hapijs/hapi/issues/1187) Change pre to use nested arrays instead of mode (serial, parallel) +- [#1185](https://github.com/hapijs/hapi/pull/1185) be more careful about options in \_provisionCache +- [#1183](https://github.com/hapijs/hapi/issues/1183) Remove use of removeAllListeners() +- [#1182](https://github.com/hapijs/hapi/issues/1182) Error transformation does not work when serving static files +- [#1178](https://github.com/hapijs/hapi/issues/1178) 2.0 Breaking Changes +- [#1176](https://github.com/hapijs/hapi/pull/1176) Unify stream and buffer responses +- [#1168](https://github.com/hapijs/hapi/issues/1168) Save stream to file like {mode: 'file' ...} +- [#1155](https://github.com/hapijs/hapi/issues/1155) 404 not being caught by onPreResponse function +- [#1134](https://github.com/hapijs/hapi/issues/1134) Joi 2.0 integration feedback +- [#1059](https://github.com/hapijs/hapi/issues/1059) Allow route prerequisites to takeover() and preempt handler +- [#1049](https://github.com/hapijs/hapi/issues/1049) Validate pre config schema + +## Version 1 {#v1} + +### [1.20.0](https://github.com/hapijs/hapi/milestone/77) {#1.20.0} + +- [#1175](https://github.com/hapijs/hapi/issues/1175) Allow disabling CORS for individual route +- [#1174](https://github.com/hapijs/hapi/issues/1174) Adjust CORS origin header options +- [#1171](https://github.com/hapijs/hapi/pull/1171) Only emit vary origin for CORS wildcard mode + +### [1.19.5](https://github.com/hapijs/hapi/milestone/76) {#1.19.5} + +- [#1169](https://github.com/hapijs/hapi/issues/1169) Remove load samples and add protection against interval sample falling behind +- [#1165](https://github.com/hapijs/hapi/issues/1165) Switch benchmarks to use Hoek.Bench instead of Date.now() + +### [1.19.4](https://github.com/hapijs/hapi/milestone/75) {#1.19.4} + +- [#1163](https://github.com/hapijs/hapi/issues/1163) CORS response doesn't set Vary header in all cases + +### [1.19.3](https://github.com/hapijs/hapi/milestone/74) {#1.19.3} + +- [#1161](https://github.com/hapijs/hapi/issues/1161) Schema issues + +### [1.19.2](https://github.com/hapijs/hapi/milestone/73) {#1.19.2} + +- [#1160](https://github.com/hapijs/hapi/issues/1160) Missing null test + +### [1.19.1](https://github.com/hapijs/hapi/milestone/72) {#1.19.1} + +- [#1159](https://github.com/hapijs/hapi/issues/1159) Allow multiple provisions of the same segment per cache + +### [1.19.0](https://github.com/hapijs/hapi/milestone/71) {#1.19.0} + +- [#1157](https://github.com/hapijs/hapi/issues/1157) route cache config does not allow specifying name +- [#1156](https://github.com/hapijs/hapi/pull/1156) Honor upstream ttl when proxying +- [#1021](https://github.com/hapijs/hapi/issues/1021) Configure proxy handlers to cache according to upstream policy + +### [1.18.0](https://github.com/hapijs/hapi/milestone/70) {#1.18.0} + +- [#1152](https://github.com/hapijs/hapi/pull/1152) Load sampling and limits +- [#1151](https://github.com/hapijs/hapi/issues/1151) Max load configuration +- [#1150](https://github.com/hapijs/hapi/pull/1150) Support multiple cache instances +- [#1149](https://github.com/hapijs/hapi/issues/1149) Allow multiple cache containers +- [#1148](https://github.com/hapijs/hapi/issues/1148) Return 401 when allowEmptyUsername is false and username missing + +### [1.17.0](https://github.com/hapijs/hapi/milestone/68) {#1.17.0} + +- [#1147](https://github.com/hapijs/hapi/pull/1147) Add request.reply.proxy() +- [#1146](https://github.com/hapijs/hapi/issues/1146) Expose proxy functionality as a utility +- [#1145](https://github.com/hapijs/hapi/issues/1145) Proxy errors should use 502 and 504 instead of 500 for most errors +- [#1144](https://github.com/hapijs/hapi/pull/1144) Support pre-compressed files +- [#1142](https://github.com/hapijs/hapi/pull/1142) Fix ext function plugin env binding +- [#1140](https://github.com/hapijs/hapi/issues/1140) Not able to login after attempting without user name +- [#1139](https://github.com/hapijs/hapi/issues/1139) Auth validator does not log useful information +- [#1138](https://github.com/hapijs/hapi/issues/1138) Apply plugin views during onRequest phase when route is not yet setup +- [#1137](https://github.com/hapijs/hapi/issues/1137) generateView at 'onRequest' extension point +- [#1126](https://github.com/hapijs/hapi/issues/1126) serve pre-compressed files when available +- [#1102](https://github.com/hapijs/hapi/issues/1102) How to exclude views from layout +- [#1070](https://github.com/hapijs/hapi/issues/1070) TypeError when validate.\* is set to false + +### [1.16.1](https://github.com/hapijs/hapi/milestone/67) {#1.16.1} + +- [#1136](https://github.com/hapijs/hapi/issues/1136) Handlebars 1.1.x uses prototype for registerPartials which breaks its use in Hapi +- [#1135](https://github.com/hapijs/hapi/issues/1135) Formatting problem in Reference.md + +### [1.16.0](https://github.com/hapijs/hapi/milestone/66) {#1.16.0} + +- [#1133](https://github.com/hapijs/hapi/pull/1133) Joi 2.0 +- [#1132](https://github.com/hapijs/hapi/issues/1132) Migrate to joi 2.0 +- [#1131](https://github.com/hapijs/hapi/issues/1131) Debug mode should log thrown and returned errors similarly +- [#1129](https://github.com/hapijs/hapi/pull/1129) support for iisnode and windows named pipes +- [#1128](https://github.com/hapijs/hapi/issues/1128) Server fails ot start when debug is defined as array +- [#1127](https://github.com/hapijs/hapi/issues/1127) Add ability to listen listen on windows named pipe +- [#1124](https://github.com/hapijs/hapi/pull/1124) Use ALCE for manifest loading. +- [#1123](https://github.com/hapijs/hapi/pull/1123) add ability to listen on unix domain socket + +### [1.15.0](https://github.com/hapijs/hapi/milestone/65) {#1.15.0} + +- [#1122](https://github.com/hapijs/hapi/issues/1122) Turns multipart processing off by default +- [#1119](https://github.com/hapijs/hapi/issues/1119) Would it be worth adding a pretty print option to all JSON payloads? +- [#1116](https://github.com/hapijs/hapi/pull/1116) CORS origin bug fixes and enhancements +- [#1114](https://github.com/hapijs/hapi/issues/1114) What is the best way to access request headers? +- [#1113](https://github.com/hapijs/hapi/pull/1113) updates plugin.views Reference.md entry to a clear and working example +- [#1112](https://github.com/hapijs/hapi/issues/1112) Too strict cookie parsing? +- [#1111](https://github.com/hapijs/hapi/issues/1111) Allow safe CORS origins list +- [#1103](https://github.com/hapijs/hapi/pull/1103) allow arrays of scopes on routes +- [#1101](https://github.com/hapijs/hapi/issues/1101) Multipart configuration options (upload dir, hash) +- [#1094](https://github.com/hapijs/hapi/issues/1094) 404 not being caught by onPreResponse function +- [#1091](https://github.com/hapijs/hapi/pull/1091) Only set access-control-allow-origin if the origin header value matches (or '\*' is allowed) + +### [1.14.0](https://github.com/hapijs/hapi/milestone/64) {#1.14.0} + +- [#1098](https://github.com/hapijs/hapi/issues/1098) Add criteria support to CLI +- [#1097](https://github.com/hapijs/hapi/issues/1097) Initial (internal) confidence integration +- [#1092](https://github.com/hapijs/hapi/issues/1092) Empty path parameter should have empty string value, not undefined +- [#1028](https://github.com/hapijs/hapi/issues/1028) Expose requests content-type/mime & accept +- [#1024](https://github.com/hapijs/hapi/issues/1024) Hapi.Composer.compose() requires "plugins" but won't warn if it's not there +- [#995](https://github.com/hapijs/hapi/issues/995) Block response.created() from methods other than POST and PUT + +### [1.13.0](https://github.com/hapijs/hapi/milestone/63) {#1.13.0} + +- [#1090](https://github.com/hapijs/hapi/pull/1090) Support partial path segment parameter +- [#1061](https://github.com/hapijs/hapi/issues/1061) POST requests with Content-Type=text/plain +- [#1012](https://github.com/hapijs/hapi/issues/1012) Escaped error responses +- [#1000](https://github.com/hapijs/hapi/issues/1000) Routing using file extensions + +### [1.12.0](https://github.com/hapijs/hapi/milestone/62) {#1.12.0} + +- [#1088](https://github.com/hapijs/hapi/pull/1088) Plugin dependencies +- [#1086](https://github.com/hapijs/hapi/issues/1086) Allow plugins to specify code executed once a plugin dependency has been loaded +- [#1085](https://github.com/hapijs/hapi/pull/1085) Validation options +- [#1084](https://github.com/hapijs/hapi/issues/1084) Restructure validation route configuration +- [#1083](https://github.com/hapijs/hapi/issues/1083) Normalize response headers to lowercase field name +- [#1081](https://github.com/hapijs/hapi/issues/1081) Migrate to Iron 1.0 +- [#1077](https://github.com/hapijs/hapi/pull/1077) Add compileMode to schema.js +- [#1076](https://github.com/hapijs/hapi/pull/1076) Test for both formats of Content-Encoding header +- [#1074](https://github.com/hapijs/hapi/pull/1074) Route-specific validation error handler +- [#1055](https://github.com/hapijs/hapi/issues/1055) Migrate to new method of configuring joi +- [#1009](https://github.com/hapijs/hapi/issues/1009) Validation fail response status code +- [#1004](https://github.com/hapijs/hapi/issues/1004) validation fails when using Hapi.types.Object() at the root + +### [1.11.1](https://github.com/hapijs/hapi/milestone/61) {#1.11.1} + +- [#1067](https://github.com/hapijs/hapi/pull/1067) Bug fix for loading ext auth scheme into multiple servers +- [#1065](https://github.com/hapijs/hapi/issues/1065) plugin.auth fails to load the same ext into multiple servers + +### [1.11.0](https://github.com/hapijs/hapi/milestone/60) {#1.11.0} + +- [#1064](https://github.com/hapijs/hapi/pull/1064) Helper cache drop interface +- [#1063](https://github.com/hapijs/hapi/issues/1063) Provide interface to drop internal cache records for helpers + +### [1.10.0](https://github.com/hapijs/hapi/milestone/59) {#1.10.0} + +- [#1058](https://github.com/hapijs/hapi/pull/1058) Closes #1056 and #1057 +- [#1057](https://github.com/hapijs/hapi/issues/1057) '/{p*}' is sorted ahead of '/{a}/b/{p*}' +- [#1056](https://github.com/hapijs/hapi/issues/1056) Allow directory paths to include multiple params and use last for resource selection +- [#1054](https://github.com/hapijs/hapi/pull/1054) Enhance prerequisites configuration options +- [#1030](https://github.com/hapijs/hapi/issues/1030) Problems with routes + +### [1.9.7](https://github.com/hapijs/hapi/milestone/58) {#1.9.7} + +- [#1050](https://github.com/hapijs/hapi/issues/1050) Memory leak due to missing stream destroy +- [#1044](https://github.com/hapijs/hapi/pull/1044) Reverting changes to generic/stream responses + +### [1.9.6](https://github.com/hapijs/hapi/milestone/57) {#1.9.6} + +- [#1037](https://github.com/hapijs/hapi/pull/1037) Stream responses emit response event +- [#1036](https://github.com/hapijs/hapi/issues/1036) Stream responses don't emit response event + +### [1.9.5](https://github.com/hapijs/hapi/milestone/56) {#1.9.5} + +- [#1034](https://github.com/hapijs/hapi/pull/1034) Upping shot dep version +- [#1033](https://github.com/hapijs/hapi/issues/1033) Node 0.11 bug fixes +- [#1032](https://github.com/hapijs/hapi/pull/1032) Updating boom version to 1.0.0 +- [#1019](https://github.com/hapijs/hapi/pull/1019) Depend on Joi v1.1.x + +### [1.9.4](https://github.com/hapijs/hapi/milestone/55) {#1.9.4} + +- [#1029](https://github.com/hapijs/hapi/pull/1029) Using latest hoek and moved to AUTHORS file +- [#1017](https://github.com/hapijs/hapi/issues/1017) Overrides Cache-Control in proxy even when no local policy is defined + +### [1.9.3](https://github.com/hapijs/hapi/milestone/54) {#1.9.3} + +- [#1016](https://github.com/hapijs/hapi/issues/1016) Adding helper with cache to pack with multiple server crash + +### [1.9.2](https://github.com/hapijs/hapi/milestone/53) {#1.9.2} + +- [#1015](https://github.com/hapijs/hapi/issues/1015) Undo #1014 + +### [1.9.1](https://github.com/hapijs/hapi/milestone/52) {#1.9.1} + +- [#1014](https://github.com/hapijs/hapi/issues/1014) plugin.helper should be selectable +- [#1005](https://github.com/hapijs/hapi/pull/1005) Improve server constructor argument validation error reporting +- [#1003](https://github.com/hapijs/hapi/pull/1003) Ensure request.response function exists before response event +- [#1001](https://github.com/hapijs/hapi/pull/1001) Pack event handlers now support correct args + +### [1.9.0](https://github.com/hapijs/hapi/milestone/51) {#1.9.0} + +- [#998](https://github.com/hapijs/hapi/pull/998) Adding dtrace probes +- [#996](https://github.com/hapijs/hapi/pull/996) Remove Directory and View from cacheable responses +- [#994](https://github.com/hapijs/hapi/pull/994) Server level cache +- [#993](https://github.com/hapijs/hapi/pull/993) Plugin context +- [#991](https://github.com/hapijs/hapi/issues/991) Configurable shared context in plugins +- [#987](https://github.com/hapijs/hapi/issues/987) View routes caching empty payload (with redis) +- [#983](https://github.com/hapijs/hapi/issues/983) Response method terms - encoding() vs charset() +- [#980](https://github.com/hapijs/hapi/issues/980) Add interface to register local `require` function with plugin api +- [#979](https://github.com/hapijs/hapi/issues/979) Confusing error message when configuring auth using default strategy when none configured +- [#978](https://github.com/hapijs/hapi/issues/978) Change plugin `ext` permission default to true +- [#976](https://github.com/hapijs/hapi/pull/976) plugin.require support +- [#975](https://github.com/hapijs/hapi/issues/975) Allow plugins to require other plugins +- [#974](https://github.com/hapijs/hapi/pull/974) Pack start/stop events +- [#973](https://github.com/hapijs/hapi/issues/973) Expose pack start/stop events +- [#972](https://github.com/hapijs/hapi/issues/972) Add dtrace probes to hapi +- [#959](https://github.com/hapijs/hapi/pull/959) Adding foundation for dtrace probe support +- [#954](https://github.com/hapijs/hapi/issues/954) Question: Is it OK to use \_cache as general purpose cache? + +### [1.8.3](https://github.com/hapijs/hapi/milestone/50) {#1.8.3} + +- [#971](https://github.com/hapijs/hapi/issues/971) Use instanceof Error + isBoom to replace instanceof Boom +- [#970](https://github.com/hapijs/hapi/pull/970) Removing complexity-report +- [#968](https://github.com/hapijs/hapi/pull/968) Changes to `plugin.hapi` and the `cookie` scheme +- [#967](https://github.com/hapijs/hapi/issues/967) Authentication defaultMode allowed invalid values +- [#966](https://github.com/hapijs/hapi/issues/966) Expose the hapi module on the request object +- [#965](https://github.com/hapijs/hapi/pull/965) Change parameter name pack to plugin to resolve #963 +- [#963](https://github.com/hapijs/hapi/issues/963) Question: should pack.register's register pack parameter should be renamed to plugin? +- [#962](https://github.com/hapijs/hapi/issues/962) Server config schema does not allow single string labels +- [#960](https://github.com/hapijs/hapi/pull/960) Updates to case sensitive routing +- [#958](https://github.com/hapijs/hapi/pull/958) Path params are no longer lowercased in router +- [#955](https://github.com/hapijs/hapi/pull/955) Update Reference.md plugin.lenght to plugin.length +- [#953](https://github.com/hapijs/hapi/issues/953) Path Parameters case changed when setting isCaseSensitive to false +- [#952](https://github.com/hapijs/hapi/issues/952) Document the importance of using hapi.error over separate Boom module +- [#951](https://github.com/hapijs/hapi/pull/951) use .isBoom instead of instanceof Boom +- [#949](https://github.com/hapijs/hapi/pull/949) Error when hawk payload validation is required but the request contains no hash +- [#948](https://github.com/hapijs/hapi/pull/948) reference multiparty instead of formidable +- [#946](https://github.com/hapijs/hapi/pull/946) Updating example to be clearer +- [#944](https://github.com/hapijs/hapi/pull/944) Found some small typos/formatting issues in Reference.md +- [#940](https://github.com/hapijs/hapi/issues/940) Proxy response gets truncated + +### [1.8.2](https://github.com/hapijs/hapi/milestone/49) {#1.8.2} + +- [#943](https://github.com/hapijs/hapi/pull/943) Updating version +- [#942](https://github.com/hapijs/hapi/pull/942) Layouts work correctly in jade +- [#941](https://github.com/hapijs/hapi/pull/941) No longer destroying request socket +- [#939](https://github.com/hapijs/hapi/issues/939) JSON response body truncated +- [#938](https://github.com/hapijs/hapi/pull/938) Fixed the code example to get Hapi's version +- [#936](https://github.com/hapijs/hapi/pull/936) Allow omitting trailing slash when last segment is an optional parameter +- [#935](https://github.com/hapijs/hapi/issues/935) Path matching should allow omitting trailing slash before an optional path parameter +- [#926](https://github.com/hapijs/hapi/issues/926) 'layout' option seems broken when using jade as template engine + +### [1.8.1](https://github.com/hapijs/hapi/milestone/48) {#1.8.1} + +- [#933](https://github.com/hapijs/hapi/pull/933) Updating version to 1.8.1 +- [#928](https://github.com/hapijs/hapi/pull/928) Removing listeners on domain when exiting +- [#927](https://github.com/hapijs/hapi/pull/927) Removing global variable + +### [1.8.0](https://github.com/hapijs/hapi/milestone/47) {#1.8.0} + +- [#925](https://github.com/hapijs/hapi/pull/925) Fixing edge case where bad path can cause issues with url.parse +- [#924](https://github.com/hapijs/hapi/pull/924) Issue/922 +- [#923](https://github.com/hapijs/hapi/pull/923) remove connection event listeners when server stops +- [#922](https://github.com/hapijs/hapi/issues/922) Handling directory routes that end both with and without a trailing slash + +### [1.7.3](https://github.com/hapijs/hapi/milestone/46) {#1.7.3} + +- [#920](https://github.com/hapijs/hapi/pull/920) Upping version to 1.7.3 +- [#919](https://github.com/hapijs/hapi/pull/919) Client now handles downstreamRes close event +- [#918](https://github.com/hapijs/hapi/issues/918) Handle potential edge cases in client errors + +### [1.7.2](https://github.com/hapijs/hapi/milestone/45) {#1.7.2} + +- [#915](https://github.com/hapijs/hapi/issues/915) custom cache engine support + +### [1.7.1](https://github.com/hapijs/hapi/milestone/44) {#1.7.1} + +- [#913](https://github.com/hapijs/hapi/issues/913) Remove duplicated listener + +### [1.7.0](https://github.com/hapijs/hapi/milestone/43) {#1.7.0} + +- [#912](https://github.com/hapijs/hapi/pull/912) Fixing aborted causing duplicate res.ends issue with incoming request +- [#911](https://github.com/hapijs/hapi/issues/911) Allow client.request calls without a callback (ignoring response) +- [#910](https://github.com/hapijs/hapi/issues/910) Client does not destroy request on redirection error +- [#907](https://github.com/hapijs/hapi/pull/907) Adding test +- [#795](https://github.com/hapijs/hapi/issues/795) Request support for HEAD routes + +### [1.6.2](https://github.com/hapijs/hapi/milestone/42) {#1.6.2} + +- [#906](https://github.com/hapijs/hapi/pull/906) Proxy requests are closed when server response already sent + +### [1.6.1](https://github.com/hapijs/hapi/milestone/41) {#1.6.1} + +- [#904](https://github.com/hapijs/hapi/pull/904) Issue/902 +- [#903](https://github.com/hapijs/hapi/pull/903) Fixing issue where timeout occurs after socket close in client +- [#902](https://github.com/hapijs/hapi/issues/902) Handle socket errors after done working with the socket +- [#901](https://github.com/hapijs/hapi/pull/901) Performance tweaks +- [#897](https://github.com/hapijs/hapi/pull/897) Hapi node_modules_path now supports symlinks +- [#896](https://github.com/hapijs/hapi/issues/896) resolve the real path of node_modules_path + +### [1.6.0](https://github.com/hapijs/hapi/milestone/40) {#1.6.0} + +- [#892](https://github.com/hapijs/hapi/issues/892) Expose internal Client to plugins +- [#891](https://github.com/hapijs/hapi/pull/891) Exposing rejectUnauthorized property on proxy + +### [1.5.0](https://github.com/hapijs/hapi/milestone/39) {#1.5.0} + +- [#889](https://github.com/hapijs/hapi/issues/889) Plugin view engine required from hapi's module path, not plugin +- [#887](https://github.com/hapijs/hapi/issues/887) Default auth scheme only works when scheme is added with 'default' name +- [#886](https://github.com/hapijs/hapi/issues/886) Cookie auth -- unknown auth strategy: default + +### [1.4.0](https://github.com/hapijs/hapi/milestone/38) {#1.4.0} + +- [#885](https://github.com/hapijs/hapi/pull/885) Fix plugin.path +- [#883](https://github.com/hapijs/hapi/pull/883) Cleanup pack requirePath +- [#876](https://github.com/hapijs/hapi/issues/876) Leading "."s should be removed before matching against domainLabelLenRegx in state.js +- [#873](https://github.com/hapijs/hapi/issues/873) using a plugin with a package in node_modules doesn't work if cwd other than the main directory +- [#872](https://github.com/hapijs/hapi/issues/872) Test for invalid incoming path without leading '/' +- [#870](https://github.com/hapijs/hapi/issues/870) Response treats objects as errors based on too trivial keys +- [#869](https://github.com/hapijs/hapi/issues/869) Request.\_replyInterface called twice but does not share wasProcessed state +- [#868](https://github.com/hapijs/hapi/issues/868) Potential leak when aborting reading a payload if max size reached +- [#857](https://github.com/hapijs/hapi/issues/857) pack.path sometimes not ending in a '/' + +### [1.3.0](https://github.com/hapijs/hapi/milestone/37) {#1.3.0} + +- [#880](https://github.com/hapijs/hapi/pull/880) Performance and hawk options +- [#879](https://github.com/hapijs/hapi/issues/879) Support all Hawk and Bewit options +- [#878](https://github.com/hapijs/hapi/pull/878) Adding Client request socket timeout +- [#871](https://github.com/hapijs/hapi/issues/871) \* allowed in path but used as special character in route fingerprint +- [#863](https://github.com/hapijs/hapi/pull/863) Absolute paths now work correctly with hapi command +- [#862](https://github.com/hapijs/hapi/pull/862) Minor performance tweaks +- [#861](https://github.com/hapijs/hapi/issues/861) hapi -p argument no longer supports absolute path to node_modules +- [#860](https://github.com/hapijs/hapi/pull/860) Adding hapi bin test and fixing issue with no plugins +- [#859](https://github.com/hapijs/hapi/pull/859) Fixing test +- [#858](https://github.com/hapijs/hapi/pull/858) Added missing done() call in test +- [#856](https://github.com/hapijs/hapi/issues/856) Remove \_log() wrapper + +### [1.2.0](https://github.com/hapijs/hapi/milestone/36) {#1.2.0} + +- [#854](https://github.com/hapijs/hapi/pull/854) Move to use multiparty +- [#853](https://github.com/hapijs/hapi/pull/853) New internal proxy handler +- [#852](https://github.com/hapijs/hapi/issues/852) Replace internal proxy implementation +- [#851](https://github.com/hapijs/hapi/issues/851) warning about formidable during npm install +- [#850](https://github.com/hapijs/hapi/pull/850) Increasing allowed sockets to 10 for client +- [#848](https://github.com/hapijs/hapi/pull/848) Template settings override fix +- [#847](https://github.com/hapijs/hapi/issues/847) POST to routes with payload 'parse' doesn't work with NODE 0.10.0 and 0.10.1 +- [#846](https://github.com/hapijs/hapi/issues/846) Request: View configuration to autoload helepers +- [#845](https://github.com/hapijs/hapi/issues/845) Generic response fails to account for all possible res events +- [#844](https://github.com/hapijs/hapi/issues/844) Proxy to outside site fails due to request's old stream api and node 0.10 wrap() +- [#843](https://github.com/hapijs/hapi/issues/843) Allow setting custom headers via proxy mapUri + +### [1.1.0](https://github.com/hapijs/hapi/milestone/32) {#1.1.0} + +- [#839](https://github.com/hapijs/hapi/pull/839) Cleanup listeners +- [#838](https://github.com/hapijs/hapi/pull/838) Issue/808 +- [#837](https://github.com/hapijs/hapi/pull/837) Issue/812 +- [#835](https://github.com/hapijs/hapi/pull/835) `Pack`: Automatically resolve the `requirePath` if provided +- [#834](https://github.com/hapijs/hapi/issues/834) `Pack` throws an `AssertionError` if the `requirePath` is not absolute +- [#833](https://github.com/hapijs/hapi/pull/833) closes #832 +- [#832](https://github.com/hapijs/hapi/issues/832) Allow route.payload config to be an object with `mode` +- [#831](https://github.com/hapijs/hapi/pull/831) Closes #830 +- [#830](https://github.com/hapijs/hapi/issues/830) Add payload 'try' parsing mode +- [#828](https://github.com/hapijs/hapi/pull/828) Add HttpOnly support to cookie auth +- [#827](https://github.com/hapijs/hapi/pull/827) request debug printout format and condition +- [#824](https://github.com/hapijs/hapi/pull/824) Issue/821 +- [#821](https://github.com/hapijs/hapi/issues/821) Allow to render templates asynchronously +- [#820](https://github.com/hapijs/hapi/pull/820) Clarified the format of payload in server.inject in the Reference doc +- [#812](https://github.com/hapijs/hapi/issues/812) Allow specifying the supported content-type of each route +- [#809](https://github.com/hapijs/hapi/issues/809) Error Stack Trace is not printed to the console +- [#808](https://github.com/hapijs/hapi/issues/808) Add an override config to route.payload +- [#807](https://github.com/hapijs/hapi/issues/807) Allow HttpOnly Flag for authentication cookies +- [#801](https://github.com/hapijs/hapi/issues/801) Switch view from using sync file ready to async + +### [1.0.3](https://github.com/hapijs/hapi/milestone/35) {#1.0.3} + +- [#823](https://github.com/hapijs/hapi/pull/823) Issue/822 +- [#822](https://github.com/hapijs/hapi/issues/822) JSONP doesn't seem to be working +- [#818](https://github.com/hapijs/hapi/pull/818) Tiny composer documentation fix +- [#817](https://github.com/hapijs/hapi/pull/817) Payload bugfix for PATCH method +- [#814](https://github.com/hapijs/hapi/pull/814) Fixed jade compile issues and updated tests to verify fix. +- [#804](https://github.com/hapijs/hapi/issues/804) Remove restriction on params in path for static file handler + +### [1.0.2](https://github.com/hapijs/hapi/milestone/34) {#1.0.2} + +- [#815](https://github.com/hapijs/hapi/issues/815) Using TLS settings with Buffer +- [#813](https://github.com/hapijs/hapi/issues/813) text/\* content-type always echo back the received content + +### [1.0.1](https://github.com/hapijs/hapi/milestone/33) {#1.0.1} + +- [#811](https://github.com/hapijs/hapi/issues/811) Does not work with formidable 1.0.14 + +### [1.0.0](https://github.com/hapijs/hapi/milestone/26) {#1.0.0} + +- [#796](https://github.com/hapijs/hapi/issues/796) Allow unencoded double quote and backslash in the cookie value +- [#793](https://github.com/hapijs/hapi/issues/793) Use new assert with passed parameters instead of concat string +- [#792](https://github.com/hapijs/hapi/issues/792) Allow validation of any type, not just objects (except errors, still ignored) +- [#791](https://github.com/hapijs/hapi/issues/791) Test fails: Auth Hawk includes authorization header in response when the response is a stream +- [#789](https://github.com/hapijs/hapi/issues/789) Streams not properly being closed for static files when browser gets cache hit +- [#788](https://github.com/hapijs/hapi/issues/788) Need more detailed documentation for "next" callback for event handlers +- [#787](https://github.com/hapijs/hapi/issues/787) Expose Plugin File Path +- [#786](https://github.com/hapijs/hapi/issues/786) View handlers uses `request.querystring` instead of `request.query` +- [#784](https://github.com/hapijs/hapi/issues/784) Change server helper options.generateKey to receive the same arguments as the helper method +- [#782](https://github.com/hapijs/hapi/issues/782) Payload parsing should be based on request method, not path method +- [#781](https://github.com/hapijs/hapi/issues/781) Do not set request.state[name] when value is invalid regardless of failAction +- [#780](https://github.com/hapijs/hapi/issues/780) Relative path redirection should have vhost support +- [#779](https://github.com/hapijs/hapi/issues/779) Add server config `location` for Location header prefix +- [#776](https://github.com/hapijs/hapi/issues/776) Streamline request.reply() +- [#775](https://github.com/hapijs/hapi/issues/775) Log cookie errors when failAction set to 'error' +- [#771](https://github.com/hapijs/hapi/issues/771) Multipart upload issue +- [#769](https://github.com/hapijs/hapi/issues/769) View handler example +- [#768](https://github.com/hapijs/hapi/issues/768) Directory handler example +- [#767](https://github.com/hapijs/hapi/issues/767) Verify every example works with 1.0 +- [#765](https://github.com/hapijs/hapi/issues/765) Refactor views manager configuration +- [#761](https://github.com/hapijs/hapi/issues/761) Hapi.Types is undefined +- [#759](https://github.com/hapijs/hapi/pull/759) Feature/misc +- [#758](https://github.com/hapijs/hapi/issues/758) cookie authentication example fails with 1.0.0 +- [#755](https://github.com/hapijs/hapi/pull/755) Views now render without child path +- [#754](https://github.com/hapijs/hapi/issues/754) Allow server config to contain uri and not override it if set +- [#752](https://github.com/hapijs/hapi/issues/752) Shared config for plugins +- [#751](https://github.com/hapijs/hapi/issues/751) Cleanup Unmonitored error +- [#749](https://github.com/hapijs/hapi/issues/749) Debug stack trace +- [#748](https://github.com/hapijs/hapi/issues/748) request.reply.redirect going to '0.0.0.0' +- [#745](https://github.com/hapijs/hapi/issues/745) Basic Authentication callback with no username/password returns 500 +- [#744](https://github.com/hapijs/hapi/issues/744) Basic Authentication +- [#742](https://github.com/hapijs/hapi/issues/742) Remove built-in Oz support +- [#741](https://github.com/hapijs/hapi/issues/741) Remove Raw response type +- [#739](https://github.com/hapijs/hapi/pull/739) Adding server.stop support for destroying connections after a timeout +- [#738](https://github.com/hapijs/hapi/pull/738) Support for Access-Control-Expose-Headers in the CORS options +- [#736](https://github.com/hapijs/hapi/pull/736) Node v0.10 +- [#735](https://github.com/hapijs/hapi/issues/735) 1.0.0 Breaking Changes +- [#651](https://github.com/hapijs/hapi/issues/651) node 0.10 +- [#582](https://github.com/hapijs/hapi/issues/582) Require.js support + +## Version 0 {#v0} + +### [0.16.0](https://github.com/hapijs/hapi/milestone/24) {#0.16.0} + +- [#728](https://github.com/hapijs/hapi/issues/728) Hawk 0.11 +- [#727](https://github.com/hapijs/hapi/pull/727) Fix hawk response header edge cases +- [#726](https://github.com/hapijs/hapi/pull/726) Misc features +- [#725](https://github.com/hapijs/hapi/pull/725) Debug enhancements +- [#724](https://github.com/hapijs/hapi/pull/724) Route validation is now using payload instead of schema +- [#721](https://github.com/hapijs/hapi/issues/721) Rename the route validate.schema to validate.payload +- [#720](https://github.com/hapijs/hapi/issues/720) Auth.responseHeader not called if error returned pre handler +- [#718](https://github.com/hapijs/hapi/issues/718) Automatically set a cookie if none present +- [#716](https://github.com/hapijs/hapi/pull/716) Errors when preparing a response now emit internalError correctly +- [#715](https://github.com/hapijs/hapi/pull/715) Auth api refactor +- [#714](https://github.com/hapijs/hapi/pull/714) Adding remote address and referrer information to request.info +- [#713](https://github.com/hapijs/hapi/issues/713) internalError event not emitted on view error. +- [#711](https://github.com/hapijs/hapi/issues/711) Add environment variable support when using composer +- [#707](https://github.com/hapijs/hapi/issues/707) internalError event returns error handler stack trace not thrown trace +- [#706](https://github.com/hapijs/hapi/issues/706) Hawk's Authorization Response Header +- [#705](https://github.com/hapijs/hapi/issues/705) Hawk's timestamp using Hapi +- [#703](https://github.com/hapijs/hapi/issues/703) taking a look at http data posted before 400 response +- [#702](https://github.com/hapijs/hapi/issues/702) Client IP Address +- [#701](https://github.com/hapijs/hapi/issues/701) A newbie question about Cookie Authentication example +- [#700](https://github.com/hapijs/hapi/pull/700) Adding security tests and fixing security bugs +- [#698](https://github.com/hapijs/hapi/issues/698) Reformat errors ability +- [#697](https://github.com/hapijs/hapi/issues/697) Protect all error responses from echo attacks +- [#696](https://github.com/hapijs/hapi/issues/696) Provide easier debugging defaults +- [#694](https://github.com/hapijs/hapi/issues/694) Normalize handler signature (always bind this, and pass same args) +- [#693](https://github.com/hapijs/hapi/issues/693) file handler includes internal information in the response +- [#692](https://github.com/hapijs/hapi/issues/692) Missing handler error should provide more debug information +- [#686](https://github.com/hapijs/hapi/pull/686) Pack auth api +- [#685](https://github.com/hapijs/hapi/issues/685) How to use State and Cookie Authentication? +- [#684](https://github.com/hapijs/hapi/issues/684) Enable plugin registration of auth schemes +- [#683](https://github.com/hapijs/hapi/pull/683) Pack and cache API refactor +- [#673](https://github.com/hapijs/hapi/issues/673) 0.16.0 Breaking Changes +- [#656](https://github.com/hapijs/hapi/issues/656) Support for virtual hosts +- [#605](https://github.com/hapijs/hapi/issues/605) Plugin-level cache setup +- [#578](https://github.com/hapijs/hapi/issues/578) Graceful Restart + +### [0.15.8](https://github.com/hapijs/hapi/milestone/31) {#0.15.8} + +- [#723](https://github.com/hapijs/hapi/issues/723) Global autoValue cookie overwrites other cookies +- [#722](https://github.com/hapijs/hapi/issues/722) Proxy shares cookies across different sessions + +### [0.15.7](https://github.com/hapijs/hapi/milestone/30) {#0.15.7} + +- [#717](https://github.com/hapijs/hapi/pull/717) Auto cookie value + +### [0.15.6](https://github.com/hapijs/hapi/milestone/29) {#0.15.6} + +- [#687](https://github.com/hapijs/hapi/issues/687) Proxy is double encoding gziped responses + +### [0.15.4](https://github.com/hapijs/hapi/milestone/28) {#0.15.4} + +- [#682](https://github.com/hapijs/hapi/pull/682) Bypass node http bug in writeHead +- [#681](https://github.com/hapijs/hapi/issues/681) CORS headers need to override proxy CORS headers +- [#679](https://github.com/hapijs/hapi/issues/679) Add test for proxy with passThrough and server caching +- [#678](https://github.com/hapijs/hapi/pull/678) Updating tutorials and adding a plugins list doc +- [#674](https://github.com/hapijs/hapi/pull/674) Adding missing branch tests + +### [0.15.3](https://github.com/hapijs/hapi/milestone/27) {#0.15.3} + +- [#677](https://github.com/hapijs/hapi/pull/677) Fix ext() with function array bug + +### [0.15.2](https://github.com/hapijs/hapi/milestone/25) {#0.15.2} + +- [#672](https://github.com/hapijs/hapi/issues/672) Emit 'internalError' on 500 responses +- [#671](https://github.com/hapijs/hapi/issues/671) Emit 'internalError' on 500 responses +- [#670](https://github.com/hapijs/hapi/pull/670) internalError event +- [#669](https://github.com/hapijs/hapi/pull/669) Optimize prerequisites and protect +- [#668](https://github.com/hapijs/hapi/issues/668) Run prerequisites inside a domain +- [#667](https://github.com/hapijs/hapi/issues/667) Ensure all assertions inside request handling result in 500 response +- [#666](https://github.com/hapijs/hapi/issues/666) Asserts throw instead of exit +- [#665](https://github.com/hapijs/hapi/issues/665) 0.15.2 Breaking Changes +- [#644](https://github.com/hapijs/hapi/issues/644) Log but ignore cookie errors + +### [0.15.1](https://github.com/hapijs/hapi/milestone/23) {#0.15.1} + +- [#663](https://github.com/hapijs/hapi/pull/663) Full plugin deps +- [#662](https://github.com/hapijs/hapi/pull/662) Plugin deps +- [#659](https://github.com/hapijs/hapi/pull/659) handler interface api styles +- [#657](https://github.com/hapijs/hapi/issues/657) Route prerequisite detection for route handler request object. +- [#653](https://github.com/hapijs/hapi/pull/653) Add request defensive protection +- [#652](https://github.com/hapijs/hapi/issues/652) Plugin dependencies +- [#650](https://github.com/hapijs/hapi/issues/650) Document plugin API +- [#649](https://github.com/hapijs/hapi/pull/649) Migrate to lab (from mocha) +- [#646](https://github.com/hapijs/hapi/issues/646) Replace mocha with lab +- [#642](https://github.com/hapijs/hapi/pull/642) Adding hawk response auth header +- [#641](https://github.com/hapijs/hapi/issues/641) Question: generic internal error handler +- [#623](https://github.com/hapijs/hapi/issues/623) Hawk 0.10 server response authentication +- [#361](https://github.com/hapijs/hapi/issues/361) Node domains + +### [0.15.0](https://github.com/hapijs/hapi/milestone/22) {#0.15.0} + +- [#638](https://github.com/hapijs/hapi/pull/638) Event tags +- [#637](https://github.com/hapijs/hapi/issues/637) Parsing the request form-encoded payload using qs +- [#636](https://github.com/hapijs/hapi/issues/636) Add event tags object in callback +- [#635](https://github.com/hapijs/hapi/pull/635) Cleanup +- [#634](https://github.com/hapijs/hapi/pull/634) Domains +- [#633](https://github.com/hapijs/hapi/pull/633) pack interface cleanup +- [#632](https://github.com/hapijs/hapi/pull/632) Adding example of cookie failAction +- [#630](https://github.com/hapijs/hapi/pull/630) shot 0.1.0, Buffer response type, encoding +- [#628](https://github.com/hapijs/hapi/issues/628) Support text/\* encoding for incoming payloads +- [#627](https://github.com/hapijs/hapi/issues/627) Allow unknown content-type when not parsing +- [#626](https://github.com/hapijs/hapi/issues/626) shot 0.1.0 +- [#625](https://github.com/hapijs/hapi/issues/625) Buffer response type +- [#622](https://github.com/hapijs/hapi/issues/622) Document response object header method +- [#621](https://github.com/hapijs/hapi/issues/621) Setting charset to UTF-8 +- [#619](https://github.com/hapijs/hapi/pull/619) hawk 0.10, payload cleanup, text/\* parse support +- [#618](https://github.com/hapijs/hapi/issues/618) Support parsing text/\* mime types +- [#617](https://github.com/hapijs/hapi/pull/617) Upgrade to Hawk 0.9.0 +- [#616](https://github.com/hapijs/hapi/pull/616) Cookie Max-Age is in seconds, not msec +- [#615](https://github.com/hapijs/hapi/pull/615) Using path.join where possible +- [#614](https://github.com/hapijs/hapi/issues/614) Cookie MaxAge set incorrectly +- [#613](https://github.com/hapijs/hapi/pull/613) Fix proxy mapUri query bug, allow pack.api to specify key +- [#612](https://github.com/hapijs/hapi/pull/612) Remove monitor +- [#611](https://github.com/hapijs/hapi/pull/611) Adding vhost tests +- [#610](https://github.com/hapijs/hapi/pull/610) Cleaning up test and stream response +- [#609](https://github.com/hapijs/hapi/pull/609) Virtual hosts support +- [#608](https://github.com/hapijs/hapi/issues/608) Random test fails: Response Stream returns a deflated stream reply without a content-length header when accept-encoding is deflate +- [#607](https://github.com/hapijs/hapi/pull/607) Adding basic crumb CSRF information to reference guide +- [#606](https://github.com/hapijs/hapi/pull/606) Handling request and response errors +- [#604](https://github.com/hapijs/hapi/issues/604) Move good log utils back in, turn rest (monitor) to plugin +- [#603](https://github.com/hapijs/hapi/issues/603) Move batch to a plugin +- [#602](https://github.com/hapijs/hapi/pull/602) Relative paths +- [#601](https://github.com/hapijs/hapi/issues/601) Use Path.join where possible +- [#600](https://github.com/hapijs/hapi/issues/600) 0.15.0 Breaking Changes +- [#599](https://github.com/hapijs/hapi/issues/599) proxy with mapUri, example +- [#598](https://github.com/hapijs/hapi/issues/598) Make resources references in a given plugin relative to that plugin +- [#597](https://github.com/hapijs/hapi/issues/597) Create grunt template for scaffolding hapi plugin development +- [#596](https://github.com/hapijs/hapi/pull/596) Adding request payload section +- [#595](https://github.com/hapijs/hapi/pull/595) Fixing gzip stream test to use simple stream +- [#594](https://github.com/hapijs/hapi/pull/594) Adding deflate support to stream response +- [#593](https://github.com/hapijs/hapi/pull/593) Adding graceful shutdown from QUIT signal event +- [#592](https://github.com/hapijs/hapi/pull/592) refactor router +- [#591](https://github.com/hapijs/hapi/pull/591) Fixing test to be isolated +- [#589](https://github.com/hapijs/hapi/pull/589) Sending a gzipped proxy response now works correctly +- [#588](https://github.com/hapijs/hapi/issues/588) Support an array of directories in order of priority +- [#585](https://github.com/hapijs/hapi/pull/585) Server.stop now stops gracefully +- [#583](https://github.com/hapijs/hapi/issues/583) CSRF support +- [#581](https://github.com/hapijs/hapi/issues/581) Enhanced HTML Form support for webdevs +- [#580](https://github.com/hapijs/hapi/issues/580) Command line / ENV param to send Boom.Internal calls to (stdout || stderr) +- [#579](https://github.com/hapijs/hapi/issues/579) Proper Request.flash support in Blammo/yar +- [#566](https://github.com/hapijs/hapi/issues/566) Better documentation for Cookie and Session handling. +- [#565](https://github.com/hapijs/hapi/issues/565) Graceful shutdown +- [#534](https://github.com/hapijs/hapi/issues/534) Document multipart/form-data +- [#495](https://github.com/hapijs/hapi/issues/495) Document new 'try' auth mode +- [#437](https://github.com/hapijs/hapi/issues/437) Support passport.js + +### [0.14.2](https://github.com/hapijs/hapi/milestone/21) {#0.14.2} + +- [#587](https://github.com/hapijs/hapi/pull/587) Composer config options +- [#577](https://github.com/hapijs/hapi/pull/577) Beef up file etag tests +- [#569](https://github.com/hapijs/hapi/issues/569) Minor: Is 'description' still a valid attribute of the 'config' object when doing route configuration? +- [#562](https://github.com/hapijs/hapi/issues/562) getRouteSourceFilePath doesn't work correctly on windows +- [#538](https://github.com/hapijs/hapi/issues/538) Show a color error on config snippet when invalid +- [#536](https://github.com/hapijs/hapi/issues/536) Support other encoding methods (deflate) +- [#378](https://github.com/hapijs/hapi/issues/378) Hawk bewit support as a new authentication scheme + +### [0.14.0](https://github.com/hapijs/hapi/milestone/18) {#0.14.0} + +- [#563](https://github.com/hapijs/hapi/pull/563) Using memory instead of redis for test +- [#561](https://github.com/hapijs/hapi/pull/561) Composer +- [#554](https://github.com/hapijs/hapi/issues/554) Support node server socket timeout override +- [#553](https://github.com/hapijs/hapi/pull/553) Pack server event and socket timeout override +- [#549](https://github.com/hapijs/hapi/issues/549) "Hello static server" sample does not working on windows +- [#543](https://github.com/hapijs/hapi/pull/543) Fix scoping bug when using multiple helper prerequisites +- [#537](https://github.com/hapijs/hapi/pull/537) Update docs/Reference.md +- [#535](https://github.com/hapijs/hapi/issues/535) Optimize Generic gzip to reduce memory copies of payload.join() +- [#533](https://github.com/hapijs/hapi/issues/533) Add make for generating complexity report +- [#532](https://github.com/hapijs/hapi/issues/532) Validate route config schema +- [#531](https://github.com/hapijs/hapi/pull/531) JSONP +- [#529](https://github.com/hapijs/hapi/issues/529) favicon example +- [#527](https://github.com/hapijs/hapi/issues/527) Support Buffer response +- [#523](https://github.com/hapijs/hapi/pull/523) Set CORS origin header to incoming request origin if allowed +- [#522](https://github.com/hapijs/hapi/pull/522) rename helmet to tv +- [#519](https://github.com/hapijs/hapi/issues/519) Add coverage for 304 response logic +- [#516](https://github.com/hapijs/hapi/issues/516) Auth scheme request extension interface +- [#515](https://github.com/hapijs/hapi/issues/515) Option to automatically clear invalid cookies +- [#514](https://github.com/hapijs/hapi/issues/514) Not found (404) handler method is case sensitive +- [#513](https://github.com/hapijs/hapi/issues/513) Add server.api and request.api for storing application-specific state +- [#512](https://github.com/hapijs/hapi/pull/512) Direct use of Boom (0.3.0) +- [#507](https://github.com/hapijs/hapi/issues/507) Fix incorrect use of applyToDefaults in server constructor +- [#506](https://github.com/hapijs/hapi/issues/506) Add route.config.plugins for plugin-specific config +- [#505](https://github.com/hapijs/hapi/issues/505) Allow Location header with custom URI schemes +- [#504](https://github.com/hapijs/hapi/issues/504) Refactor responses to make it easier to create external responses or manipulate +- [#503](https://github.com/hapijs/hapi/issues/503) Expose request private properties +- [#502](https://github.com/hapijs/hapi/issues/502) Remove server config format options +- [#501](https://github.com/hapijs/hapi/pull/501) Response refactor, bug fixes +- [#500](https://github.com/hapijs/hapi/issues/500) Cookie parsing fails if encoding set to 'none' +- [#499](https://github.com/hapijs/hapi/issues/499) Random test fails: Server Timeout doesn't return an error when server is responding when the timeout occurs +- [#498](https://github.com/hapijs/hapi/pull/498) Adding code coverage support using blanket +- [#497](https://github.com/hapijs/hapi/issues/497) Document policy regarding undocumented features +- [#496](https://github.com/hapijs/hapi/pull/496) Distributable cache for files +- [#494](https://github.com/hapijs/hapi/pull/494) fix typo from issue/491 +- [#493](https://github.com/hapijs/hapi/pull/493) Fixing test that would fail periodically +- [#491](https://github.com/hapijs/hapi/issues/491) Example code is wrong +- [#489](https://github.com/hapijs/hapi/issues/489) Setting ttl(0) on cookie with definition with non zero ttl +- [#488](https://github.com/hapijs/hapi/issues/488) Allow setting empty cookie +- [#486](https://github.com/hapijs/hapi/issues/486) Fails sometimes: Payload stream mode doesn't set the request payload when streaming data in and the connection is interrupted +- [#485](https://github.com/hapijs/hapi/issues/485) Add authentication 'try' mode +- [#483](https://github.com/hapijs/hapi/issues/483) CORS support for multiple origins +- [#482](https://github.com/hapijs/hapi/pull/482) Parse cookies before authentication +- [#481](https://github.com/hapijs/hapi/pull/481) Adding log tag filtering information to readme +- [#480](https://github.com/hapijs/hapi/pull/480) Cleaning up this. use +- [#479](https://github.com/hapijs/hapi/issues/479) Review every 'this' to make sure it points to the right context +- [#478](https://github.com/hapijs/hapi/pull/478) Cleanup ext options and error handling +- [#477](https://github.com/hapijs/hapi/issues/477) Return error if received from onRequest +- [#476](https://github.com/hapijs/hapi/issues/476) 0.14.0 Breaking Changes +- [#475](https://github.com/hapijs/hapi/pull/475) Simplify path regex +- [#459](https://github.com/hapijs/hapi/issues/459) Add socket.io example +- [#451](https://github.com/hapijs/hapi/issues/451) JSONP support +- [#441](https://github.com/hapijs/hapi/issues/441) Configuration strict mode checking for any unknown config options +- [#438](https://github.com/hapijs/hapi/pull/438) Adding support for payload authentication validation +- [#428](https://github.com/hapijs/hapi/issues/428) Session authentication strategy +- [#403](https://github.com/hapijs/hapi/issues/403) Try out some new coverage tools +- [#379](https://github.com/hapijs/hapi/issues/379) Hawk payload validation settings +- [#243](https://github.com/hapijs/hapi/issues/243) Rework Readme into tutorial and reference guides + +### [0.13.2](https://github.com/hapijs/hapi/milestone/20) {#0.13.2} + +- [#474](https://github.com/hapijs/hapi/pull/474) 0.13.2 +- [#472](https://github.com/hapijs/hapi/pull/472) Fix matching of wildcard path param with trailing / +- [#471](https://github.com/hapijs/hapi/issues/471) /{p\*} doesn't match /path/ +- [#466](https://github.com/hapijs/hapi/pull/466) Directory listing at top level folders now link correctly +- [#465](https://github.com/hapijs/hapi/issues/465) directory list using the directory handler produces wrong URLs +- [#464](https://github.com/hapijs/hapi/issues/464) index option for directory module doesn't work on subdirs +- [#463](https://github.com/hapijs/hapi/pull/463) Typo: req.session.used -> req.session.user + +### [0.13.1](https://github.com/hapijs/hapi/milestone/19) {#0.13.1} + +- [#467](https://github.com/hapijs/hapi/issues/467) 0.13.1 Change pack package.json version location + +### [0.13.0](https://github.com/hapijs/hapi/milestone/17) {#0.13.0} + +- [#457](https://github.com/hapijs/hapi/issues/457) Remove server creation log messages +- [#456](https://github.com/hapijs/hapi/issues/456) Bypass cache logic when not using cache around handler +- [#455](https://github.com/hapijs/hapi/issues/455) Reintroduce the removed request.reply.close() method +- [#454](https://github.com/hapijs/hapi/issues/454) Support wildcard HTTP method routing +- [#452](https://github.com/hapijs/hapi/issues/452) Test server format.error config option +- [#450](https://github.com/hapijs/hapi/pull/450) typo +- [#448](https://github.com/hapijs/hapi/pull/448) Fixed typos +- [#447](https://github.com/hapijs/hapi/issues/447) Replace config.ext with Server.ext() +- [#446](https://github.com/hapijs/hapi/issues/446) Replace setNotFound with wildcard method support +- [#445](https://github.com/hapijs/hapi/issues/445) Streamline Server API +- [#444](https://github.com/hapijs/hapi/issues/444) Server Packs +- [#443](https://github.com/hapijs/hapi/issues/443) Add a link to find breaking changes by release +- [#440](https://github.com/hapijs/hapi/issues/440) 0.13.0 Breaking Changes + +### [0.12.0](https://github.com/hapijs/hapi/milestone/14) {#0.12.0} + +- [#442](https://github.com/hapijs/hapi/issues/442) 0.12.0 Breaking Changes +- [#435](https://github.com/hapijs/hapi/pull/435) Prerequisite helper shortcut interface +- [#434](https://github.com/hapijs/hapi/pull/434) Bound handler to request, bump to 0.12.0 +- [#431](https://github.com/hapijs/hapi/issues/431) Response validation fails on response errors +- [#427](https://github.com/hapijs/hapi/pull/427) CORS cleanup and Monitor defaults +- [#426](https://github.com/hapijs/hapi/issues/426) CORS off by default, using catch-all instead of synthetic route +- [#425](https://github.com/hapijs/hapi/pull/425) Route sorting rewrite +- [#422](https://github.com/hapijs/hapi/issues/422) Allow raw (direct) responses to bail if header fails +- [#421](https://github.com/hapijs/hapi/issues/421) onPostRoute called before response is sent +- [#420](https://github.com/hapijs/hapi/pull/420) Goodies +- [#416](https://github.com/hapijs/hapi/pull/416) Auth cleanup +- [#409](https://github.com/hapijs/hapi/issues/409) Error: listen EADDRNOTAVAIL when starting hapi server with foreman +- [#407](https://github.com/hapijs/hapi/pull/407) Adding support for basic auth password hashing +- [#406](https://github.com/hapijs/hapi/pull/406) Update auth dependencies +- [#405](https://github.com/hapijs/hapi/issues/405) For basic auth run password through hashPassword function first +- [#402](https://github.com/hapijs/hapi/pull/402) Use fixed time password comparison +- [#401](https://github.com/hapijs/hapi/pull/401) Enable more than one jade template file to be used in hapi. +- [#397](https://github.com/hapijs/hapi/issues/397) Arrange routes in descending order of specificity +- [#396](https://github.com/hapijs/hapi/issues/396) Accept cache mode 'client+server' as 'server+client' +- [#387](https://github.com/hapijs/hapi/issues/387) Create contributing guidelines +- [#377](https://github.com/hapijs/hapi/issues/377) Document and add examples for the authentication interface +- [#376](https://github.com/hapijs/hapi/issues/376) Switch all tests that listen on a port to use automatically allocated port +- [#374](https://github.com/hapijs/hapi/issues/374) Test Content-Length vs. actual payload size mismatch behaviour +- [#373](https://github.com/hapijs/hapi/issues/373) Add support for private cache-control flag +- [#367](https://github.com/hapijs/hapi/issues/367) Potential headers duplication when mixing sources due to case +- [#363](https://github.com/hapijs/hapi/pull/363) Adding server + client timeout feature +- [#360](https://github.com/hapijs/hapi/issues/360) Timeout server response if taking too long with 503 response +- [#359](https://github.com/hapijs/hapi/issues/359) Timeout client connections taking too long and return 408 +- [#358](https://github.com/hapijs/hapi/issues/358) Support other view engines, including multiple engines per server +- [#357](https://github.com/hapijs/hapi/issues/357) Make Views cache usage configurable (per Manager) +- [#347](https://github.com/hapijs/hapi/issues/347) Signed and encrypted state support +- [#325](https://github.com/hapijs/hapi/issues/325) Console output appears even when not configured +- [#307](https://github.com/hapijs/hapi/issues/307) Support multiple authentication strategies per route with preferences +- [#239](https://github.com/hapijs/hapi/issues/239) Test regular and stream payload transmission while request closes + +### [0.11.2](https://github.com/hapijs/hapi/milestone/16) {#0.11.2} + +- [#370](https://github.com/hapijs/hapi/issues/370) Support 'Access-Control-Allow-Credentials' + +### [0.11.1](https://github.com/hapijs/hapi/milestone/15) {#0.11.1} + +- [#366](https://github.com/hapijs/hapi/issues/366) Stream response not calling Headers.cors, location, or cache +- [#365](https://github.com/hapijs/hapi/issues/365) Stream response always passing proxy headers through +- [#364](https://github.com/hapijs/hapi/issues/364) Proxy handler doesn't set default value for passThrough settings + +### [0.11.0](https://github.com/hapijs/hapi/milestone/13) {#0.11.0} + +- [#310](https://github.com/hapijs/hapi/issues/310) Cross-platform monitor +- [#251](https://github.com/hapijs/hapi/issues/251) Support Content-Disposition header in File response +- [#242](https://github.com/hapijs/hapi/issues/242) Cookies support +- [#235](https://github.com/hapijs/hapi/issues/235) View response +- [#169](https://github.com/hapijs/hapi/issues/169) Add response validation settings + +### [0.10.0](https://github.com/hapijs/hapi/milestone/9) {#0.10.0} + +- [#329](https://github.com/hapijs/hapi/pull/329) Add redirection response +- [#326](https://github.com/hapijs/hapi/pull/326) Adding support for hapi-log +- [#322](https://github.com/hapijs/hapi/pull/322) Docs handler refactor +- [#319](https://github.com/hapijs/hapi/issues/319) Doc configuration should let you set the auth mode +- [#314](https://github.com/hapijs/hapi/pull/314) Multiple auth schemes +- [#309](https://github.com/hapijs/hapi/issues/309) Bring monitor/\* to 100% test coverage +- [#303](https://github.com/hapijs/hapi/issues/303) Handle %-encoding of '/' in route and request paths +- [#302](https://github.com/hapijs/hapi/issues/302) Consider object key name sizes in calculating object memory usage in memory cache +- [#270](https://github.com/hapijs/hapi/issues/270) Multiple auth scheme support +- [#253](https://github.com/hapijs/hapi/issues/253) Support redirection responses + +### [0.9.3](https://github.com/hapijs/hapi/milestone/12) {#0.9.3} + +- [#317](https://github.com/hapijs/hapi/pull/317) Test helpers, mongo auth test +- [#312](https://github.com/hapijs/hapi/pull/312) Misc cleanup + +### [0.9.2](https://github.com/hapijs/hapi/milestone/10) {#0.9.2} + +- [#305](https://github.com/hapijs/hapi/pull/305) Hidden files can now optionally be served +- [#301](https://github.com/hapijs/hapi/pull/301) Merge, payload tests +- [#299](https://github.com/hapijs/hapi/pull/299) Fix issue with case-insensitive route conflic +- [#298](https://github.com/hapijs/hapi/pull/298) Prevent use of encoded non-reserved characters in path +- [#297](https://github.com/hapijs/hapi/pull/297) Refactor request path normalization +- [#296](https://github.com/hapijs/hapi/issues/296) Fix route path fingerprint when using cases-insensitive paths +- [#295](https://github.com/hapijs/hapi/issues/295) Prevent directory from showing or serving hidden files (configurable) +- [#294](https://github.com/hapijs/hapi/pull/294) Refactor responses, auth, payload +- [#293](https://github.com/hapijs/hapi/issues/293) Fix multipart parsing +- [#290](https://github.com/hapijs/hapi/issues/290) Improve batch example to include a request +- [#289](https://github.com/hapijs/hapi/issues/289) Add a unique request id for each incoming request +- [#287](https://github.com/hapijs/hapi/issues/287) Forbid using %encoded in route path of unreserved characters +- [#274](https://github.com/hapijs/hapi/issues/274) Add Hawk authentication support +- [#272](https://github.com/hapijs/hapi/issues/272) Normalize %-encoded paths to match incoming requests +- [#271](https://github.com/hapijs/hapi/issues/271) Strict cache mode +- [#254](https://github.com/hapijs/hapi/issues/254) Cleanup handling of response headers / options +- [#241](https://github.com/hapijs/hapi/issues/241) Add static files support + +### [0.9.1](https://github.com/hapijs/hapi/milestone/8) {#0.9.1} + +- [#277](https://github.com/hapijs/hapi/pull/277) Changed matching rule of {param\*}, Oz tests +- [#275](https://github.com/hapijs/hapi/pull/275) Prevent basic routes collision +- [#268](https://github.com/hapijs/hapi/pull/268) Tests, extension auth schemes +- [#265](https://github.com/hapijs/hapi/issues/265) Document new path option {param\*n} +- [#264](https://github.com/hapijs/hapi/issues/264) Bring all individual file test coverage to over 90% +- [#263](https://github.com/hapijs/hapi/issues/263) Add tests to /test/unit/route.js +- [#262](https://github.com/hapijs/hapi/pull/262) Support /path/{param\*} syntax +- [#260](https://github.com/hapijs/hapi/issues/260) Extension auth schemes +- [#258](https://github.com/hapijs/hapi/pull/258) Adding support for etag and last-modified headers +- [#256](https://github.com/hapijs/hapi/issues/256) Don't cache responses other than 200 +- [#255](https://github.com/hapijs/hapi/pull/255) Adding support for gzip responses +- [#232](https://github.com/hapijs/hapi/issues/232) Support sending gzip responses + +### [0.9.0](https://github.com/hapijs/hapi/milestone/3) {#0.9.0} + +- [#250](https://github.com/hapijs/hapi/pull/250) Direct response support +- [#245](https://github.com/hapijs/hapi/pull/245) Basic auth +- [#240](https://github.com/hapijs/hapi/issues/240) Basic auth scheme +- [#238](https://github.com/hapijs/hapi/issues/238) Document new request.reply interface +- [#237](https://github.com/hapijs/hapi/pull/237) Response refactor +- [#234](https://github.com/hapijs/hapi/pull/234) Oz +- [#233](https://github.com/hapijs/hapi/issues/233) Partial/streaming responses +- [#229](https://github.com/hapijs/hapi/pull/229) Initial 0.9.0 +- [#168](https://github.com/hapijs/hapi/issues/168) Move query and schema into a single validation config +- [#167](https://github.com/hapijs/hapi/issues/167) Replace OAuth authentication with OZ + +### [0.8.4](https://github.com/hapijs/hapi/milestone/7) {#0.8.4} + +- [#222](https://github.com/hapijs/hapi/pull/222) Fix bug where /docs crashes if no POST routes are defined +- [#221](https://github.com/hapijs/hapi/pull/221) Adding parsing of multipart form-data content-type +- [#219](https://github.com/hapijs/hapi/issues/219) cannot bind ephemeral ports +- [#186](https://github.com/hapijs/hapi/issues/186) Unsupported content-type: multipart/form-data + +### [0.8.3](https://github.com/hapijs/hapi/milestone/6) {#0.8.3} + +- [#212](https://github.com/hapijs/hapi/pull/212) Adding proxy tests and doing a little refactoring +- [#211](https://github.com/hapijs/hapi/pull/211) Cache tests, Fix response processing header order +- [#201](https://github.com/hapijs/hapi/issues/201) Document proxy handler interface +- [#185](https://github.com/hapijs/hapi/issues/185) Turn cache memory strategy into a useful feature + +### [0.8.2](https://github.com/hapijs/hapi/milestone/5) {#0.8.2} + +- [#210](https://github.com/hapijs/hapi/pull/210) 0.8.2 +- [#209](https://github.com/hapijs/hapi/pull/209) Tests +- [#207](https://github.com/hapijs/hapi/pull/207) Error refactor, custom error support (passThrough) +- [#206](https://github.com/hapijs/hapi/pull/206) Fixing issue with error responses being cached + test + +### [0.8.1](https://github.com/hapijs/hapi/milestone/4) {#0.8.1} + +- [#204](https://github.com/hapijs/hapi/pull/204) Add postResponse method to proxy +- [#200](https://github.com/hapijs/hapi/pull/200) Fix tls config settings +- [#191](https://github.com/hapijs/hapi/issues/191) Pass all TLS options to createServer + +### [0.8.0](https://github.com/hapijs/hapi/milestone/2) {#0.8.0} + +- [#193](https://github.com/hapijs/hapi/issues/193) Support for gzip'd payloads +- [#183](https://github.com/hapijs/hapi/pull/183) Cache segment validation +- [#172](https://github.com/hapijs/hapi/issues/172) Check if Redis and MongoDB are ready before running tests +- [#165](https://github.com/hapijs/hapi/issues/165) Add route response validation to endpoint documentation +- [#164](https://github.com/hapijs/hapi/pull/164) Server helpers, initial response validation, Mongo support + +### [0.6.0](https://github.com/hapijs/hapi/milestone/1) {#0.6.0} + +- [#102](https://github.com/hapijs/hapi/pull/102) v0.6.0 merge +- [#101](https://github.com/hapijs/hapi/pull/101) modified new validation fns to use Utils.assert +- [#100](https://github.com/hapijs/hapi/pull/100) New Query Validation Fns Added +- [#99](https://github.com/hapijs/hapi/pull/99) Simplified request log interface +- [#96](https://github.com/hapijs/hapi/pull/96) Small utils +- [#94](https://github.com/hapijs/hapi/pull/94) debug interface, log interface +- [#93](https://github.com/hapijs/hapi/pull/93) fix error on subsequent url accesses for queryval +- [#92](https://github.com/hapijs/hapi/pull/92) Fix example +- [#91](https://github.com/hapijs/hapi/pull/91) QueryValidation fixes, add default behavior for unspecified params, added small tests +- [#63](https://github.com/hapijs/hapi/pull/63) Added in SSL cert passphrase to https server creation from settings. diff --git a/generated/markdown/heavy/8/api.md b/generated/markdown/heavy/8/api.md new file mode 100644 index 00000000..275bb5a7 --- /dev/null +++ b/generated/markdown/heavy/8/api.md @@ -0,0 +1,37 @@ +## Methods + +### `new Heavy(options)` + +Creates a new heavy instance where: + +- `options` + - `sampleInterval` - frequency of load sampling in milliseconds. Defaults to `0` (no sampling). + - `maxHeapUsedBytes` - maximum V8 heap size bytes. Defaults to `0` (no limit). + - `maxRssBytes` - maximum process RSS size bytes. Defaults to `0` (no limit). + - `maxEventLoopDelay` - maximum event loop delay duration in milliseconds. Defaults to `0` (no limit). + - `maxEventLoopUtilization` - maximum event loop utilization value. Defaults to `0` (no limit). + +Returns a new `Heavy` object. + +### `heavy.start()` + +Starts the sampling operation with `sampleInterval` frequency. When `sampleInterval` is `0`, this operation does nothing. + +### `heavy.stop()` + +Stops the sampling operation. + +### `heavy.check()` + +Verifies the current process load and throws a [server unavailable](https://hapi.dev/module/boom/api?#boomserverunavailablemessage-data) +error when any of the configured limits is exceeded. The current process load is assigned to `error.data`. +When `sampleInterval` is `0`, this operation does nothing. + +### `heavy.load` + +Object with the current process load: + +- `eventLoopDelay` - current event loop delay milliseconds. +- `eventLoopUtilization` - current event loop utilization value. +- `heapUsed` - current V8 heap size bytes. +- `rss` - current process RSS size bytes. diff --git a/generated/markdown/heavy/changelog.md b/generated/markdown/heavy/changelog.md new file mode 100644 index 00000000..fe6596f9 --- /dev/null +++ b/generated/markdown/heavy/changelog.md @@ -0,0 +1,109 @@ +## Version 8 {#v8} + +### [8.0.1](https://github.com/hapijs/heavy/milestone/26) {#8.0.1} + +- [#51](https://github.com/hapijs/heavy/pull/51) chore: bump hoek + +### [8.0.0](https://github.com/hapijs/heavy/milestone/25) {#8.0.0} + +- [#50](https://github.com/hapijs/heavy/pull/50) Support node v18 and drop node v12 +- [#48](https://github.com/hapijs/heavy/pull/48) Add event loop utilization support + +## Version 7 {#v7} + +### [7.0.1](https://github.com/hapijs/heavy/milestone/23) {#7.0.1} + +- [#44](https://github.com/hapijs/heavy/pull/44) upgrade lab to v24 + +### [7.0.0](https://github.com/hapijs/heavy/milestone/22) {#7.0.0} + +- [#36](https://github.com/hapijs/heavy/issues/36) Only node 12 + +## Version 6 {#v6} + +### [6.2.2](https://github.com/hapijs/heavy/milestone/20) {#6.2.2} + +- [#32](https://github.com/hapijs/heavy/issues/32) Update joi + +### [6.2.1](https://github.com/hapijs/heavy/milestone/19) {#6.2.1} + +- [#31](https://github.com/hapijs/heavy/issues/31) Update deps + +### [6.2.0](https://github.com/hapijs/heavy/milestone/16) {#6.2.0} + +- [#29](https://github.com/hapijs/heavy/issues/29) Change module namespace + +### [6.1.2](https://github.com/hapijs/heavy/milestone/15) {#6.1.2} + +- [#26](https://github.com/hapijs/heavy/issues/26) Remove engines + +### [6.1.1](https://github.com/hapijs/heavy/milestone/14) {#6.1.1} + +- [#25](https://github.com/hapijs/heavy/issues/25) Update hoek v6 + +### [6.1.0](https://github.com/hapijs/heavy/milestone/13) {#6.1.0} + +- [#23](https://github.com/hapijs/heavy/issues/23) Allow unknown config keys + +### [6.0.0](https://github.com/hapijs/heavy/milestone/12) {#6.0.0} + +- [#22](https://github.com/hapijs/heavy/issues/22) Throw in check() + +## Version 5 {#v5} + +### [5.0.2](https://github.com/hapijs/heavy/milestone/11) {#5.0.2} + +- [#21](https://github.com/hapijs/heavy/issues/21) Update joi + +### [5.0.1](https://github.com/hapijs/heavy/milestone/10) {#5.0.1} + +- [#20](https://github.com/hapijs/heavy/issues/20) Update deps + +### [5.0.0](https://github.com/hapijs/heavy/milestone/9) {#5.0.0} + +- [#18](https://github.com/hapijs/heavy/issues/18) Refactor for single connection + +## Version 4 {#v4} + +### [4.1.0](https://github.com/hapijs/heavy/milestone/17) {#4.1.0} + +- [#28](https://github.com/hapijs/heavy/issues/28) Commercial version of v4 branch + +### [4.0.4](https://github.com/hapijs/heavy/milestone/8) {#4.0.4} + +- [#16](https://github.com/hapijs/heavy/issues/16) Update deps. + +### [4.0.3](https://github.com/hapijs/heavy/milestone/7) {#4.0.3} + +- [#15](https://github.com/hapijs/heavy/issues/15) Update deps + +### [4.0.2](https://github.com/hapijs/heavy/milestone/6) {#4.0.2} + +- [#13](https://github.com/hapijs/heavy/issues/13) Update deps + +### [4.0.1](https://github.com/hapijs/heavy/milestone/5) {#4.0.1} + +- [#11](https://github.com/hapijs/heavy/pull/11) Update deps + +### [4.0.0](https://github.com/hapijs/heavy/milestone/4) {#4.0.0} + +- [#10](https://github.com/hapijs/heavy/issues/10) ES6 style changes and node v4 + +## Version 3 {#v3} + +### [3.0.1](https://github.com/hapijs/heavy/milestone/3) {#3.0.1} + +- [#8](https://github.com/hapijs/heavy/pull/8) Closes #6, Closes #7 +- [#7](https://github.com/hapijs/heavy/issues/7) bring heavy up to date with standards +- [#6](https://github.com/hapijs/heavy/issues/6) upgrade joi +- [#4](https://github.com/hapijs/heavy/pull/4) Update .travis.yml + +### [3.0.0](https://github.com/hapijs/heavy/milestone/1) {#3.0.0} + +- [#2](https://github.com/hapijs/heavy/issues/2) Update check() to return reason why + +## Version 2 {#v2} + +### [2.0.0](https://github.com/hapijs/heavy/milestone/2) {#2.0.0} + +- [#1](https://github.com/hapijs/heavy/issues/1) Split sampling from policy diff --git a/generated/markdown/hoek/11/api.md b/generated/markdown/hoek/11/api.md new file mode 100644 index 00000000..56e76e07 --- /dev/null +++ b/generated/markdown/hoek/11/api.md @@ -0,0 +1,401 @@ +### Object + +**hoek** provides several helpful methods for objects and arrays. + +#### clone(obj, [options]) + +Clones an object or an array. A _deep copy_ is made (duplicates everything, including values that are +objects, as well as non-enumerable properties) where: + +- `obj` - the object to be cloned. +- `options` - optional settings: + - `symbols` - clone symbol properties. Defaults to `true`. + - `shallow` - one of: + - an array of object key strings (dot-separated or array-based key paths) to shallow copy from `obj` instead of deep. + - `true` to shallow copy all object properties. Used to shallow copy an object with non-enumerable properties and prototype; + +```javascript +const nestedObj = { + w: /^something$/gi, + x: { + a: [1, 2, 3], + b: 123456, + c: new Date(), + }, + y: 'y', + z: new Date(), +}; + +const copy = Hoek.clone(nestedObj); + +copy.x.b = 100; + +console.log(copy.y); // results in 'y' +console.log(nestedObj.x.b); // results in 123456 +console.log(copy.x.b); // results in 100 +``` + +Clones an object or array excluding some keys which are shallow copied: + +```javascript +const nestedObj = { + w: /^something$/gi, + x: { + a: [1, 2, 3], + b: 123456, + c: new Date(), + }, + y: 'y', + z: new Date(), +}; + +const copy = Hoek.clone(nestedObj, { shallow: ['x'] }); + +copy.x.b = 100; + +console.log(copy.y); // results in 'y' +console.log(nestedObj.x.b); // results in 100 +console.log(copy.x.b); // results in 100 +``` + +#### merge(target, source, [options]) + +Merge all the properties of source into target where: + +- `target` - the object onto which the properties of `source` are copied to. +- `source` - the object copied onto `target`. +- `options` - optional settings: + - `nullOverride` - if `true`, a `null` value in the source overrides any existing value in the `defaults`. + If `false`, `null` values in the `source` are ignored. Defaults to `true`. + - `mergeArrays` - if `true`, array values from `source` are appended to existing array values in `target`. + Defaults to `true`. + - `symbols` - clone symbol properties. Defaults to `true`. + +Note that source wins in conflict, and by default null and undefined from source are applied. +Merge is destructive where the target is modified. For non destructive merge, use `applyToDefaults`. + +```javascript +const target = { a: 1, b: 2 }; +const source = { a: 0, c: 5 }; +const source2 = { a: null, c: 5 }; + +Hoek.merge(target, source); // results in {a: 0, b: 2, c: 5} +Hoek.merge(target, source2); // results in {a: null, b: 2, c: 5} +Hoek.merge(target, source2, { nullOverride: false }); // results in {a: 1, b: 2, c: 5} + +const targetArray = [1, 2, 3]; +const sourceArray = [4, 5]; + +Hoek.merge(targetArray, sourceArray); // results in [1, 2, 3, 4, 5] +Hoek.merge(targetArray, sourceArray, { mergeArrays: false }); // results in [4, 5] +``` + +#### applyToDefaults(defaults, source, [options]) + +Apply source to a copy of the defaults where: + +- `defaults` - the default object to clone and then apply `source` onto. +- `source` - the object applied to the `defaults`. +- `options` - optional settings: + - `nullOverride` - if `true`, a `null` value in the source overrides any existing value in the `defaults`. + If `false`, `null` values in the `source` are ignored. Defaults to `false`. + - `shallow` - an array of dot-separated or array-based key paths to shallow copy values in `source`. + +```javascript +const defaults = { host: 'localhost', port: 8000 }; +const source = { port: 8080 }; + +const config = Hoek.applyToDefaults(defaults, source); // results in { host: "localhost", port: 8080 } +``` + +Apply source with a null value to a copy of the defaults + +```javascript +const defaults = { host: 'localhost', port: 8000 }; +const source = { host: null, port: 8080 }; + +const config = Hoek.applyToDefaults(defaults, source, { nullOverride: true }); // results in { host: null, port: 8080 } +``` + +Apply source to a copy of the defaults where the shallow keys specified in the last parameter are shallow copied from source instead of merged + +```javascript +const defaults = { + db: { + server: { + host: 'localhost', + port: 8000, + }, + name: 'example', + }, +}; + +const source = { server: { port: 8080 } }; + +const config = Hoek.applyToDefaults(defaults, source, { + shallow: ['db.server'], +}); // results in { db: { server: { port: 8080 }, name: 'example' } } +const config = Hoek.applyToDefaults(defaults, source, { + shallow: [['db', 'server']], +}); // results in { db: { server: { port: 8080 }, name: 'example' } } +``` + +#### deepEqual(a, b, [options]) + +Performs a deep comparison of the two values including support for circular dependencies, +prototype, and enumerable properties, where: + +- `a` - the first value. +- `b` - the second value. +- `options` - optional settings: + - `deepFunction` - when `true`, function values are deep compared using their source code and + object properties. Defaults to `false`. + - `part` - when `true`, allows a partial match where some of `b` is present in `a`. Defaults to + `false`. + - `prototype` - when `false, prototype comparisons are skipped. Defaults to `true`. + - `skip` - an array of key name strings to skip comparing. The keys can be found in any level + of the object. Note that both values must contain the key - only the value comparison is + skipped. Only applies to plain objects and deep functions (not to map, sets, etc.). Defaults + to no skipping. + - `symbols` - when `false`, symbol properties are ignored. Defaults to `true`. + +```javascript +Hoek.deepEqual( + { a: [1, 2], b: 'string', c: { d: true } }, + { a: [1, 2], b: 'string', c: { d: true } }, +); //results in true +Hoek.deepEqual(Object.create(null), {}, { prototype: false }); //results in true +Hoek.deepEqual(Object.create(null), {}); //results in false +``` + +#### intersect(array1, array2, [options]) + +Find the common unique items betwee two arrays where: + +- `array1` - the first array. +- `array2` - the second array. +- `options` - optional settings: + - `first` - if `true`, return only the first intersecting item. Defaults to `false`. + +```javascript +const array1 = [1, 2, 3]; +const array2 = [1, 4, 5]; + +const newArray = Hoek.intersect(array1, array2); // results in [1] +``` + +#### contain(ref, values, [options]) + +Tests if the reference value contains the provided values where: + +- `ref` - the reference string, array, or object. +- `values` - a single or array of values to find within the `ref` value. If `ref` is an object, `values` can be a key name, + an array of key names, or an object with key-value pairs to compare. +- `options` - an optional object with the following optional settings: + - `deep` - if `true`, performed a deep comparison of the values. + - `once` - if `true`, allows only one occurrence of each value. + - `only` - if `true`, does not allow values not explicitly listed. + - `part` - if `true`, allows partial match of the values (at least one must always match). + - `symbols` - clone symbol properties. Defaults to `true`. + +Note: comparing a string to overlapping values will result in failed comparison (e.g. `contain('abc', ['ab', 'bc'])`). +Also, if an object key's value does not match the provided value, `false` is returned even when `part` is specified. + +```javascript +Hoek.contain('aaa', 'a', { only: true }); // true +Hoek.contain([{ a: 1 }], [{ a: 1 }], { deep: true }); // true +Hoek.contain([1, 2, 2], [1, 2], { once: true }); // false +Hoek.contain({ a: 1, b: 2, c: 3 }, { a: 1, d: 4 }, { part: true }); // true +``` + +#### flatten(array, [target]) + +Flatten an array + +```javascript +const array = [1, [2, 3]]; + +const flattenedArray = Hoek.flatten(array); // results in [1, 2, 3] + +array = [1, [2, 3]]; +target = [4, [5]]; + +flattenedArray = Hoek.flatten(array, target); // results in [4, [5], 1, 2, 3] +``` + +#### reach(obj, chain, [options]) + +Converts an object key chain string or array to reference + +- `options` - optional settings + - `separator` - string to split chain path on, defaults to '.' + - `default` - value to return if the path or value is not present, default is `undefined` + - `strict` - if `true`, will throw an error on missing member, default is `false` + - `functions` - if `true`, allow traversing functions for properties. `false` will throw an + error if a function is part of the chain. Defaults to `true`. + - `iterables` - if `true`, allows traversing Set and Map objects. `false` will result in + `undefined` return value is the chain contains any Set or Map objects. Note that enabling + `iterables` can impact performance by up to 10% for all calls regardless of the presence of + Set or Map objects. Defaults to `false`. + +A chain can be a string that will be split into key names using `separator`, +or an array containing each individual key name. + +A chain including negative numbers will work like negative indices on an array. + +If chain is `null`, `undefined` or `false`, the object itself will be returned. + +```javascript +const chain = 'a.b.c'; +const obj = { a: { b: { c: 1 } } }; + +Hoek.reach(obj, chain); // returns 1 + +const chain = ['a', 'b', -1]; +const obj = { a: { b: [2, 3, 6] } }; + +Hoek.reach(obj, chain); // returns 6 +``` + +#### reachTemplate(obj, template, [options]) + +Replaces string parameters (`{name}`) with their corresponding object key values by applying the +[`reach()`](#reachobj-chain-options) method where: + +- `obj` - the context object used for key lookup. +- `template` - a string containing `{}` parameters. +- `options` - optional [`reach()`](#reachobj-chain-options) options. + +```javascript +const template = '1+{a.b.c}=2'; +const obj = { a: { b: { c: 1 } } }; + +Hoek.reachTemplate(obj, template); // returns '1+1=2' +``` + +#### stringify(...args) + +Converts an object to string using the built-in `JSON.stringify()` method with the difference that any errors are caught +and reported back in the form of the returned string. Used as a shortcut for displaying information to the console (e.g. in +error message) without the need to worry about invalid conversion. + +```javascript +const a = {}; +a.b = a; +Hoek.stringify(a); // Returns '[Cannot display object: Converting circular structure to JSON]' +``` + +### Bench + +Same as Timer with the exception that `ts` stores the internal node clock which is not related to `Date.now()` and cannot be used to display +human-readable timestamps. More accurate for benchmarking or internal timers. + +### Escaping Characters + +**hoek** provides convenient methods for escaping html characters. The escaped characters are as followed: + +```javascript +internals.htmlEscaped = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`', +}; +``` + +#### escapeHtml(string) + +```javascript +const string = ' hey '; +const escapedString = Hoek.escapeHtml(string); // returns <html> hey </html> +``` + +#### escapeHeaderAttribute(attribute) + +Escape attribute value for use in HTTP header + +```javascript +const a = Hoek.escapeHeaderAttribute('I said "go w\\o me"'); //returns I said \"go w\\o me\" +``` + +#### escapeJson(string) + +Unicode escapes the characters `<`, `>`, and `&` to prevent mime-sniffing older browsers mistaking JSON as HTML, and escapes line and paragraph separators for JSONP and script contexts. + +```javascript +const lineSeparator = String.fromCharCode(0x2028); +const a = Hoek.escapeJson('I said - - diff --git a/layouts/error.vue b/layouts/error.vue deleted file mode 100644 index fe61acdd..00000000 --- a/layouts/error.vue +++ /dev/null @@ -1,139 +0,0 @@ - - - - - \ No newline at end of file diff --git a/layouts/home.vue b/layouts/home.vue deleted file mode 100644 index ad91cc7c..00000000 --- a/layouts/home.vue +++ /dev/null @@ -1,75 +0,0 @@ - - - - - diff --git a/layouts/noSide.vue b/layouts/noSide.vue deleted file mode 100644 index 5716682d..00000000 --- a/layouts/noSide.vue +++ /dev/null @@ -1,82 +0,0 @@ - - - - - diff --git a/middleware/README.md b/middleware/README.md deleted file mode 100644 index 01595ded..00000000 --- a/middleware/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# MIDDLEWARE - -**This directory is not required, you can delete it if you don't want to use it.** - -This directory contains your application middleware. -Middleware let you define custom functions that can be run before rendering either a page or a group of pages. - -More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing#middleware). diff --git a/middleware/setCookie.js b/middleware/setCookie.js deleted file mode 100644 index f4a80dff..00000000 --- a/middleware/setCookie.js +++ /dev/null @@ -1,3 +0,0 @@ -export default ({ app }) => { - app.$cookies.set('confirmation', false) -} \ No newline at end of file diff --git a/mixins/CopyCodeSnippet.js b/mixins/CopyCodeSnippet.js deleted file mode 100644 index 2add5a65..00000000 --- a/mixins/CopyCodeSnippet.js +++ /dev/null @@ -1,16 +0,0 @@ -import { setCodeClipboards } from "~/utils/clipboard"; - -export default { - data() { - return { listeners: new Map() }; - }, - beforeDestroy() { - for (let [element, listener] of this.listeners) { - element.removeEventListener('click', listener); - } - this.listeners.clear(); - }, - mounted() { - setCodeClipboards(this.listeners) - } -} diff --git a/netlify.toml b/netlify.toml index fd1d8ccf..0ac9e686 100644 --- a/netlify.toml +++ b/netlify.toml @@ -1,4 +1,4 @@ [[headers]] - for = "/*" - [headers.values] - X-Frame-Options = "SAMEORIGIN" +for = "/*" +[headers.values] +X-Frame-Options = "SAMEORIGIN" diff --git a/nuxt.config.js b/nuxt.config.js deleted file mode 100644 index d47512b9..00000000 --- a/nuxt.config.js +++ /dev/null @@ -1,272 +0,0 @@ -module.exports = { - telemetry: false, - - generate: { - fallback: true, - interval: 2000, - routes: [ - "/tutorials/gettingstarted", - "/tutorials/auth", - "/tutorials/caching", - "/tutorials/community", - "/tutorials/cookies", - "/tutorials/logging", - "/tutorials/plugins", - "/tutorials/routing", - "/tutorials/servermethods", - "/tutorials/servingfiles", - "/tutorials/testing", - "/tutorials/validation", - "/tutorials/views", - "/tutorials/expresstohapi", - "/module/accept", - "/module/accept/api", - "/module/accept/changelog", - "/module/ammo", - "/module/ammo/api", - "/module/ammo/changelog", - "/module/b64", - "/module/b64/api", - "/module/b64/changelog", - "/module/basic", - "/module/basic/api", - "/module/basic/changelog", - "/module/bell", - "/module/bell/api", - "/module/bell/changelog", - "/module/boom", - "/module/boom/api", - "/module/boom/changelog", - "/module/bossy", - "/module/bossy/api", - "/module/bossy/changelog", - "/module/bounce", - "/module/bounce/api", - "/module/bounce/changelog", - "/module/bourne", - "/module/bourne/api", - "/module/bourne/changelog", - "/module/call", - "/module/call/api", - "/module/call/changelog", - "/module/catbox", - "/module/catbox/api", - "/module/catbox/changelog", - "/module/catbox-memcached", - "/module/catbox-memcached/api", - "/module/catbox-memcached/changelog", - "/module/catbox-memory", - "/module/catbox-memory/api", - "/module/catbox-memory/changelog", - "/module/catbox-object", - "/module/catbox-object/api", - "/module/catbox-object/changelog", - "/module/catbox-redis", - "/module/catbox-redis/api", - "/module/catbox-redis/changelog", - "/module/code", - "/module/code/api", - "/module/code/changelog", - "/module/content", - "/module/content/api", - "/module/content/changelog", - "/module/cookie", - "/module/cookie/api", - "/module/cookie/changelog", - "/module/crumb", - "/module/crumb/api", - "/module/crumb/changelog", - "/module/cryptiles", - "/module/cryptiles/api", - "/module/cryptiles/changelog", - "/module/eslint-plugin", - "/module/eslint-plugin/changelog", - "/module/file", - "/module/file/changelog", - "/module/glue", - "/module/glue/api", - "/module/glue/changelog", - "/module/h2o2", - "/module/h2o2/api", - "/module/h2o2/changelog", - "/module/heavy", - "/module/heavy/changelog", - "/module/hoek", - "/module/hoek/api", - "/module/hoek/changelog", - "/module/inert", - "/module/inert/api", - "/module/inert/changelog", - "/module/iron", - "/module/iron/api", - "/module/iron/changelog", - "/module/jwt", - "/module/jwt/changelog", - "/module/lab", - "/module/lab/api", - "/module/lab/changelog", - "/module/log", - "/module/log/api", - "/module/log/changelog", - "/module/mimos", - "/module/mimos/api", - "/module/mimos/changelog", - "/module/nes", - "/module/nes/api", - "/module/nes/changelog", - "/module/nigel", - "/module/nigel/changelog", - "/module/oppsy", - "/module/oppsy/api", - "/module/oppsy/changelog", - "/module/pez", - "/module/pez/changelog", - "/module/podium", - "/module/podium/api", - "/module/podium/changelog", - "/module/scooter", - "/module/scooter/api", - "/module/scooter/changelog", - "/module/shot", - "/module/shot/api", - "/module/shot/changelog", - "/module/somever", - "/module/somever/changelog", - "/module/statehood", - "/module/statehood/changelog", - "/module/subtext", - "/module/subtext/api", - "/module/subtext/changelog", - "/module/teamwork", - "/module/teamwork/changelog", - "/module/topo", - "/module/topo/api", - "/module/topo/changelog", - "/module/vise", - "/module/vise/changelog", - "/module/vision", - "/module/vision/api", - "/module/vision/changelog", - "/module/wreck", - "/module/wreck/api", - "/module/wreck/changelog", - "/module/yar", - "/module/yar/api", - "/module/yar/changelog" - ] - }, - /* - ** Headers of the page - */ - head: { - title: "hapi.dev - The simple, secure framework developers trust", - htmlAttrs: { - lang: "en" - }, - meta: [ - { charset: "utf-8" }, - { name: "viewport", content: "width=device-width, initial-scale=1" }, - { - hid: "description", - name: "description", - content: - "Build powerful, scalable applications, with minimal overhead and full out-of-the-box functionality - your code, your way. Originally developed to handle Walmart’s Black Friday scale, hapi continues to be the proven choice for enterprise-grade backend needs." - }, - { - hid: "keywords", - name: "keywords", - content: "hapi, hapijs, hapi.js, node, node.js, javascript, framework" - } - ], - link: [ - { rel: "icon", type: "image/x-icon", href: "/favicon.png?v=1.0" }, - { - rel: "stylesheet", - href: - "https://fonts.googleapis.com/css?family=Inconsolata:400|Lato:400,900&display=swap" - } - ] - }, - - /* - ** Customize the progress-bar color - */ - loading: { color: "#fff" }, - - /* - ** Global CSS - */ - css: ["bulma"], - - /* - ** Plugins to load before mounting the App - */ - plugins: ["~/plugins/vue-js-modal", "~/plugins/vue-codemirror", "~/plugins/vue-highlightjs"], - - /* - ** Nuxt.js modules - */ - modules: [ - "@nuxtjs/markdownit", - "@nuxtjs/axios", - "@nuxtjs/dotenv", - "@nuxtjs/google-analytics", - "cookie-universal-nuxt", - "@nuxtjs/svg", - "@nuxtjs/pwa" - ], - - // [optional] markdownit options - // See https://github.com/markdown-it/markdown-it - markdownit: { - linkify: true, - html: true, - breaks: true, - injected: true - }, - - axios: { - retry: true - }, - - googleAnalytics: { - id: "UA-144917045-1" - }, - - privateRuntimeConfig: { - GITHUB_TOKEN: process.env.GITHUB_TOKEN - }, - - manifest: { - name: "hapi.dev", - short_name: "hapi", - background_color: "#ffffff", - theme_color: "#ed7d31" - }, - - /* - ** Build configuration - */ - build: { - splitChunks: { - layouts: true - }, - html: { - minify: { - collapseBooleanAttributes: true, - decodeEntities: true, - minifyCSS: false, - minifyJS: false, - processConditionalComments: true, - removeEmptyAttributes: true, - removeRedundantAttributes: true, - trimCustomFragments: true, - useShortDoctype: true - } - } - /* - ** You can extend webpack config here - */ - // extend(config, ctx) {} - } -}; diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 032d617d..00000000 --- a/package-lock.json +++ /dev/null @@ -1,34650 +0,0 @@ -{ - "name": "hapi.dev", - "version": "1.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "hapi.dev", - "version": "1.0.0", - "license": "BSD-3-Clause", - "dependencies": { - "@aitodotai/json-stringify-pretty-compact": "^1.3.0", - "@hapi/hapi": "^20.2.1", - "@hapi/inert": "^6.0.5", - "@nuxtjs/axios": "^5.12.2", - "@nuxtjs/dotenv": "^1.3.0", - "@nuxtjs/google-analytics": "^2.2.0", - "@nuxtjs/hapi": "^3.0.0", - "@nuxtjs/markdownit": "^2.0.0", - "@nuxtjs/pwa": "^3.2.2", - "@nuxtjs/svg": "^0.4.0", - "axios": "^0.26.0", - "bulma": "^0.9.1", - "cookie-universal-nuxt": "^2.0.17", - "cross-env": "^7.0.2", - "fs": "0.0.1-security", - "highlight.js": "^11.4.0", - "js-yaml": "^4.0.0", - "lodash": "^4.17.20", - "markdown-toc": "^1.2.0", - "nuxt": "^2.15.8", - "semver": "^7.3.2", - "vue-codemirror": "^4.0.6", - "vue-highlightjs": "^1.3.3", - "vue-js-modal": "^2.0.1" - }, - "devDependencies": { - "babel-eslint": "^10.0.3", - "eslint": "^8.9.0", - "eslint-config-prettier": "^8.4.0", - "eslint-loader": "^4.0.2", - "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-vue": "^8.4.1", - "nodemon": "^2.0.15", - "prettier": "^2.5.1", - "sass": "^1.49.8", - "sass-loader": "^10.1.1" - } - }, - "node_modules/@aitodotai/json-stringify-pretty-compact": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@aitodotai/json-stringify-pretty-compact/-/json-stringify-pretty-compact-1.3.0.tgz", - "integrity": "sha512-K+whdCBlVjzx8zCK2ZUohGJb5bUOxRpiEAfD1NCUgH0mApdDZD9c7VHXJVzWlt3wfV1X4OFyCRmTqbPd6U87lQ==" - }, - "node_modules/@ampproject/remapping": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz", - "integrity": "sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", - "dependencies": { - "@babel/highlight": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.0.tgz", - "integrity": "sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.17.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.5.tgz", - "integrity": "sha512-/BBMw4EvjmyquN5O+t5eh0+YqB3XXJkYD2cjKpYtWOfFy4lQ4UozNSmxAcWT8r2XtZs0ewG+zrfsqeR15i1ajA==", - "dependencies": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.3", - "@babel/helper-compilation-targets": "^7.16.7", - "@babel/helper-module-transforms": "^7.16.7", - "@babel/helpers": "^7.17.2", - "@babel/parser": "^7.17.3", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.3", - "@babel/types": "^7.17.0", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@babel/core/node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@babel/core/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.3.tgz", - "integrity": "sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg==", - "dependencies": { - "@babel/types": "^7.17.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz", - "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==", - "dependencies": { - "@babel/types": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz", - "integrity": "sha512-C6FdbRaxYjwVu/geKW4ZeQ0Q31AftgRcdSnZ5/jsH6BzCJbtvXvhpfkbkThYSuutZA7nCXpPR6AD9zd1dprMkA==", - "dependencies": { - "@babel/helper-explode-assignable-expression": "^7.16.7", - "@babel/types": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", - "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", - "dependencies": { - "@babel/compat-data": "^7.16.4", - "@babel/helper-validator-option": "^7.16.7", - "browserslist": "^4.17.5", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.17.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.1.tgz", - "integrity": "sha512-JBdSr/LtyYIno/pNnJ75lBcqc3Z1XXujzPanHqjvvrhOA+DTceTFuJi8XjmWTZh4r3fsdfqaCMN0iZemdkxZHQ==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-member-expression-to-functions": "^7.16.7", - "@babel/helper-optimise-call-expression": "^7.16.7", - "@babel/helper-replace-supers": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.0.tgz", - "integrity": "sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "regexpu-core": "^5.0.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz", - "integrity": "sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA==", - "dependencies": { - "@babel/helper-compilation-targets": "^7.13.0", - "@babel/helper-module-imports": "^7.12.13", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/traverse": "^7.13.0", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0-0" - } - }, - "node_modules/@babel/helper-define-polyfill-provider/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@babel/helper-define-polyfill-provider/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/@babel/helper-define-polyfill-provider/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", - "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", - "dependencies": { - "@babel/types": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-explode-assignable-expression": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz", - "integrity": "sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ==", - "dependencies": { - "@babel/types": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", - "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", - "dependencies": { - "@babel/helper-get-function-arity": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/types": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-get-function-arity": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", - "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", - "dependencies": { - "@babel/types": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", - "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", - "dependencies": { - "@babel/types": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz", - "integrity": "sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q==", - "dependencies": { - "@babel/types": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", - "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", - "dependencies": { - "@babel/types": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", - "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-simple-access": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/helper-validator-identifier": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.16.7", - "@babel/types": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz", - "integrity": "sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w==", - "dependencies": { - "@babel/types": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz", - "integrity": "sha512-fm0gH7Flb8H51LqJHy3HJ3wnE1+qtYR2A99K06ahwrawLdOFsCEWjZOrYricXJHoPSudNKxrMBUPEIPxiIIvBw==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-wrap-function": "^7.16.8", - "@babel/types": "^7.16.8" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz", - "integrity": "sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-member-expression-to-functions": "^7.16.7", - "@babel/helper-optimise-call-expression": "^7.16.7", - "@babel/traverse": "^7.16.7", - "@babel/types": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", - "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", - "dependencies": { - "@babel/types": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz", - "integrity": "sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==", - "dependencies": { - "@babel/types": "^7.16.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", - "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", - "dependencies": { - "@babel/types": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", - "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz", - "integrity": "sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw==", - "dependencies": { - "@babel/helper-function-name": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.16.8", - "@babel/types": "^7.16.8" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz", - "integrity": "sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==", - "dependencies": { - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.0", - "@babel/types": "^7.17.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.16.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", - "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.3.tgz", - "integrity": "sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==", - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.7.tgz", - "integrity": "sha512-anv/DObl7waiGEnC24O9zqL0pSuI9hljihqiDuFHC8d7/bjr/4RLGPWuc8rYOff/QPzbEPSkzG8wGG9aDuhHRg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.7.tgz", - "integrity": "sha512-di8vUHRdf+4aJ7ltXhaDbPoszdkh59AQtJM5soLsuHpQJdFQZOA4uGj0V2u/CZ8bJ/u8ULDL5yq6FO/bCXnKHw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", - "@babel/plugin-proposal-optional-chaining": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" - } - }, - "node_modules/@babel/plugin-proposal-async-generator-functions": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz", - "integrity": "sha512-71YHIvMuiuqWJQkebWJtdhQTfd4Q4mF76q2IX37uZPkG9+olBxsX+rH1vkhFto4UeJZ9dPY2s+mDvhDm1u2BGQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-remap-async-to-generator": "^7.16.8", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz", - "integrity": "sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-class-static-block": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.7.tgz", - "integrity": "sha512-dgqJJrcZoG/4CkMopzhPJjGxsIe9A8RlkQLnL/Vhhx8AA9ZuaRwGSlscSh42hazc7WSrya/IK7mTeoF0DP9tEw==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "node_modules/@babel/plugin-proposal-decorators": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.17.2.tgz", - "integrity": "sha512-WH8Z95CwTq/W8rFbMqb9p3hicpt4RX4f0K659ax2VHxgOyT6qQmUaEVEjIh4WR9Eh9NymkVn5vwsrE68fAQNUw==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.17.1", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-replace-supers": "^7.16.7", - "@babel/plugin-syntax-decorators": "^7.17.0", - "charcodes": "^0.2.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-dynamic-import": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz", - "integrity": "sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-export-namespace-from": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz", - "integrity": "sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-json-strings": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz", - "integrity": "sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-json-strings": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz", - "integrity": "sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz", - "integrity": "sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz", - "integrity": "sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.17.3.tgz", - "integrity": "sha512-yuL5iQA/TbZn+RGAfxQXfi7CNLmKi1f8zInn4IgobuCWcAb7i+zj4TYzQ9l8cEzVyJ89PDGuqxK1xZpUDISesw==", - "dependencies": { - "@babel/compat-data": "^7.17.0", - "@babel/helper-compilation-targets": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-optional-catch-binding": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz", - "integrity": "sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz", - "integrity": "sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-private-methods": { - "version": "7.16.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz", - "integrity": "sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.16.10", - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.7.tgz", - "integrity": "sha512-rMQkjcOFbm+ufe3bTZLyOfsOUOxyvLXZJCTARhJr+8UMSoZmqTe1K1BgkFcrW37rAchWg57yI69ORxiWvUINuQ==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-create-class-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-unicode-property-regex": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz", - "integrity": "sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-decorators": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.17.0.tgz", - "integrity": "sha512-qWe85yCXsvDEluNP0OyeQjH63DlhAR3W7K9BxxU1MvbDb48tgBG+Ao6IJJ6smPDrrVzSQZrbF6donpkFBMcs3A==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.7.tgz", - "integrity": "sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz", - "integrity": "sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz", - "integrity": "sha512-MtmUmTJQHCnyJVrScNzNlofQJ3dLFuobYn3mwOTKHnSCMtbNsqvF71GQmJfFjdrXSsAA7iysFmYWw4bXZ20hOg==", - "dependencies": { - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-remap-async-to-generator": "^7.16.8" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz", - "integrity": "sha512-JUuzlzmF40Z9cXyytcbZEZKckgrQzChbQJw/5PuEHYeqzCsvebDx0K0jWnIIVcmmDOAVctCgnYs0pMcrYj2zJg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz", - "integrity": "sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz", - "integrity": "sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-optimise-call-expression": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-replace-supers": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz", - "integrity": "sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.17.3.tgz", - "integrity": "sha512-dDFzegDYKlPqa72xIlbmSkly5MluLoaC1JswABGktyt6NTXSBcUuse/kWE/wvKFWJHPETpi158qJZFS3JmykJg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz", - "integrity": "sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz", - "integrity": "sha512-03DvpbRfvWIXyK0/6QiR1KMTWeT6OcQ7tbhjrXyFS02kjuX/mu5Bvnh5SDSWHxyawit2g5aWhKwI86EE7GUnTw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz", - "integrity": "sha512-8UYLSlyLgRixQvlYH3J2ekXFHDFLQutdy7FfFAMm3CPZ6q9wHCwnUyiXpQCe3gVVnQlHc5nsuiEVziteRNTXEA==", - "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz", - "integrity": "sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz", - "integrity": "sha512-SU/C68YVwTRxqWj5kgsbKINakGag0KTgq9f2iZEXdStoAbOzLHEBRYzImmA6yFo8YZhJVflvXmIHUO7GWHmxxA==", - "dependencies": { - "@babel/helper-compilation-targets": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz", - "integrity": "sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz", - "integrity": "sha512-mBruRMbktKQwbxaJof32LT9KLy2f3gH+27a5XSuXo6h7R3vqltl0PgZ80C8ZMKw98Bf8bqt6BEVi3svOh2PzMw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz", - "integrity": "sha512-KaaEtgBL7FKYwjJ/teH63oAmE3lP34N3kshz8mm4VMAw7U3PxjVwwUmxEFksbgsNUaO3wId9R2AVQYSEGRa2+g==", - "dependencies": { - "@babel/helper-module-transforms": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "babel-plugin-dynamic-import-node": "^2.3.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz", - "integrity": "sha512-oflKPvsLT2+uKQopesJt3ApiaIS2HW+hzHFcwRNtyDGieAeC/dIHZX8buJQ2J2X1rxGPy4eRcUijm3qcSPjYcA==", - "dependencies": { - "@babel/helper-module-transforms": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-simple-access": "^7.16.7", - "babel-plugin-dynamic-import-node": "^2.3.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.7.tgz", - "integrity": "sha512-DuK5E3k+QQmnOqBR9UkusByy5WZWGRxfzV529s9nPra1GE7olmxfqO2FHobEOYSPIjPBTr4p66YDcjQnt8cBmw==", - "dependencies": { - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-module-transforms": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-validator-identifier": "^7.16.7", - "babel-plugin-dynamic-import-node": "^2.3.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz", - "integrity": "sha512-EMh7uolsC8O4xhudF2F6wedbSHm1HHZ0C6aJ7K67zcDNidMzVcxWdGr+htW9n21klm+bOn+Rx4CBsAntZd3rEQ==", - "dependencies": { - "@babel/helper-module-transforms": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz", - "integrity": "sha512-j3Jw+n5PvpmhRR+mrgIh04puSANCk/T/UA3m3P1MjJkhlK906+ApHhDIqBQDdOgL/r1UYpz4GNclTXxyZrYGSw==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz", - "integrity": "sha512-xiLDzWNMfKoGOpc6t3U+etCE2yRnn3SM09BXqWPIZOBpL2gvVrBWUKnsJx0K/ADi5F5YC5f8APFfWrz25TdlGg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz", - "integrity": "sha512-14J1feiQVWaGvRxj2WjyMuXS2jsBkgB3MdSN5HuC2G5nRspa5RK9COcs82Pwy5BuGcjb+fYaUj94mYcOj7rCvw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-replace-supers": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz", - "integrity": "sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz", - "integrity": "sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.7.tgz", - "integrity": "sha512-mF7jOgGYCkSJagJ6XCujSQg+6xC1M77/03K2oBmVJWoFGNUtnVJO4WHKJk3dnPC8HCcj4xBQP1Egm8DWh3Pb3Q==", - "dependencies": { - "regenerator-transform": "^0.14.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz", - "integrity": "sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-runtime": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.17.0.tgz", - "integrity": "sha512-fr7zPWnKXNc1xoHfrIU9mN/4XKX4VLZ45Q+oMhfsYIaHvg7mHgmhfOy/ckRWqDK7XF3QDigRpkh5DKq6+clE8A==", - "dependencies": { - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "babel-plugin-polyfill-corejs2": "^0.3.0", - "babel-plugin-polyfill-corejs3": "^0.5.0", - "babel-plugin-polyfill-regenerator": "^0.3.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz", - "integrity": "sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz", - "integrity": "sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz", - "integrity": "sha512-NJa0Bd/87QV5NZZzTuZG5BPJjLYadeSZ9fO6oOUoL4iQx+9EEuw/eEM92SrsT19Yc2jgB1u1hsjqDtH02c3Drw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz", - "integrity": "sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz", - "integrity": "sha512-p2rOixCKRJzpg9JB4gjnG4gjWkWa89ZoYUnl9snJ1cWIcTH/hvxZqfO+WjG6T8DRBpctEol5jw1O5rA8gkCokQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz", - "integrity": "sha512-TAV5IGahIz3yZ9/Hfv35TV2xEm+kaBDaZQCn2S/hG9/CZ0DktxJv9eKfPc7yYCvOYR4JGx1h8C+jcSOvgaaI/Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz", - "integrity": "sha512-oC5tYYKw56HO75KZVLQ+R/Nl3Hro9kf8iG0hXoaHP7tjAyCpvqBiSNe6vGrZni1Z6MggmUOC6A7VP7AVmw225Q==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-env": { - "version": "7.16.11", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.11.tgz", - "integrity": "sha512-qcmWG8R7ZW6WBRPZK//y+E3Cli151B20W1Rv7ln27vuPaXU/8TKms6jFdiJtF7UDTxcrb7mZd88tAeK9LjdT8g==", - "dependencies": { - "@babel/compat-data": "^7.16.8", - "@babel/helper-compilation-targets": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-validator-option": "^7.16.7", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.16.7", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.16.7", - "@babel/plugin-proposal-async-generator-functions": "^7.16.8", - "@babel/plugin-proposal-class-properties": "^7.16.7", - "@babel/plugin-proposal-class-static-block": "^7.16.7", - "@babel/plugin-proposal-dynamic-import": "^7.16.7", - "@babel/plugin-proposal-export-namespace-from": "^7.16.7", - "@babel/plugin-proposal-json-strings": "^7.16.7", - "@babel/plugin-proposal-logical-assignment-operators": "^7.16.7", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.7", - "@babel/plugin-proposal-numeric-separator": "^7.16.7", - "@babel/plugin-proposal-object-rest-spread": "^7.16.7", - "@babel/plugin-proposal-optional-catch-binding": "^7.16.7", - "@babel/plugin-proposal-optional-chaining": "^7.16.7", - "@babel/plugin-proposal-private-methods": "^7.16.11", - "@babel/plugin-proposal-private-property-in-object": "^7.16.7", - "@babel/plugin-proposal-unicode-property-regex": "^7.16.7", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.16.7", - "@babel/plugin-transform-async-to-generator": "^7.16.8", - "@babel/plugin-transform-block-scoped-functions": "^7.16.7", - "@babel/plugin-transform-block-scoping": "^7.16.7", - "@babel/plugin-transform-classes": "^7.16.7", - "@babel/plugin-transform-computed-properties": "^7.16.7", - "@babel/plugin-transform-destructuring": "^7.16.7", - "@babel/plugin-transform-dotall-regex": "^7.16.7", - "@babel/plugin-transform-duplicate-keys": "^7.16.7", - "@babel/plugin-transform-exponentiation-operator": "^7.16.7", - "@babel/plugin-transform-for-of": "^7.16.7", - "@babel/plugin-transform-function-name": "^7.16.7", - "@babel/plugin-transform-literals": "^7.16.7", - "@babel/plugin-transform-member-expression-literals": "^7.16.7", - "@babel/plugin-transform-modules-amd": "^7.16.7", - "@babel/plugin-transform-modules-commonjs": "^7.16.8", - "@babel/plugin-transform-modules-systemjs": "^7.16.7", - "@babel/plugin-transform-modules-umd": "^7.16.7", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.16.8", - "@babel/plugin-transform-new-target": "^7.16.7", - "@babel/plugin-transform-object-super": "^7.16.7", - "@babel/plugin-transform-parameters": "^7.16.7", - "@babel/plugin-transform-property-literals": "^7.16.7", - "@babel/plugin-transform-regenerator": "^7.16.7", - "@babel/plugin-transform-reserved-words": "^7.16.7", - "@babel/plugin-transform-shorthand-properties": "^7.16.7", - "@babel/plugin-transform-spread": "^7.16.7", - "@babel/plugin-transform-sticky-regex": "^7.16.7", - "@babel/plugin-transform-template-literals": "^7.16.7", - "@babel/plugin-transform-typeof-symbol": "^7.16.7", - "@babel/plugin-transform-unicode-escapes": "^7.16.7", - "@babel/plugin-transform-unicode-regex": "^7.16.7", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.16.8", - "babel-plugin-polyfill-corejs2": "^0.3.0", - "babel-plugin-polyfill-corejs3": "^0.5.0", - "babel-plugin-polyfill-regenerator": "^0.3.0", - "core-js-compat": "^3.20.2", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-env/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/preset-modules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", - "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz", - "integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==", - "dependencies": { - "regenerator-runtime": "^0.13.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", - "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", - "dependencies": { - "@babel/code-frame": "^7.16.7", - "@babel/parser": "^7.16.7", - "@babel/types": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", - "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", - "dependencies": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.3", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.17.3", - "@babel/types": "^7.17.0", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@babel/traverse/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/@babel/types": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", - "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@csstools/convert-colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz", - "integrity": "sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.1.0.tgz", - "integrity": "sha512-C1DfL7XX4nPqGd6jcP01W9pVM1HYCuUkFk1432D7F0v3JSlUIeOYn9oCoi3eoLZ+iwBSb29BMFxxny0YrrEZqg==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.3.1", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.12.1", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", - "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/eslintrc/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/@eslint/eslintrc/node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/eslintrc/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/@eslint/eslintrc/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@gar/promisify": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", - "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==" - }, - "node_modules/@hapi/accept": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@hapi/accept/-/accept-5.0.2.tgz", - "integrity": "sha512-CmzBx/bXUR8451fnZRuZAJRlzgm0Jgu5dltTX/bszmR2lheb9BpyN47Q1RbaGTsvFzn0PXAEs+lXDKfshccYZw==", - "dependencies": { - "@hapi/boom": "9.x.x", - "@hapi/hoek": "9.x.x" - } - }, - "node_modules/@hapi/ammo": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@hapi/ammo/-/ammo-5.0.1.tgz", - "integrity": "sha512-FbCNwcTbnQP4VYYhLNGZmA76xb2aHg9AMPiy18NZyWMG310P5KdFGyA9v2rm5ujrIny77dEEIkMOwl0Xv+fSSA==", - "dependencies": { - "@hapi/hoek": "9.x.x" - } - }, - "node_modules/@hapi/b64": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@hapi/b64/-/b64-5.0.0.tgz", - "integrity": "sha512-ngu0tSEmrezoiIaNGG6rRvKOUkUuDdf4XTPnONHGYfSGRmDqPZX5oJL6HAdKTo1UQHECbdB4OzhWrfgVppjHUw==", - "dependencies": { - "@hapi/hoek": "9.x.x" - } - }, - "node_modules/@hapi/boom": { - "version": "9.1.4", - "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-9.1.4.tgz", - "integrity": "sha512-Ls1oH8jaN1vNsqcaHVYJrKmgMcKsC1wcp8bujvXrHaAqD2iDYq3HoOwsxwo09Cuda5R5nC0o0IxlrlTuvPuzSw==", - "dependencies": { - "@hapi/hoek": "9.x.x" - } - }, - "node_modules/@hapi/bounce": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/bounce/-/bounce-2.0.0.tgz", - "integrity": "sha512-JesW92uyzOOyuzJKjoLHM1ThiOvHPOLDHw01YV8yh5nCso7sDwJho1h0Ad2N+E62bZyz46TG3xhAi/78Gsct6A==", - "dependencies": { - "@hapi/boom": "9.x.x", - "@hapi/hoek": "9.x.x" - } - }, - "node_modules/@hapi/bourne": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-2.0.0.tgz", - "integrity": "sha512-WEezM1FWztfbzqIUbsDzFRVMxSoLy3HugVcux6KDDtTqzPsLE8NDRHfXvev66aH1i2oOKKar3/XDjbvh/OUBdg==" - }, - "node_modules/@hapi/call": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@hapi/call/-/call-8.0.1.tgz", - "integrity": "sha512-bOff6GTdOnoe5b8oXRV3lwkQSb/LAWylvDMae6RgEWWntd0SHtkYbQukDHKlfaYtVnSAgIavJ0kqszF/AIBb6g==", - "dependencies": { - "@hapi/boom": "9.x.x", - "@hapi/hoek": "9.x.x" - } - }, - "node_modules/@hapi/catbox": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/@hapi/catbox/-/catbox-11.1.1.tgz", - "integrity": "sha512-u/8HvB7dD/6X8hsZIpskSDo4yMKpHxFd7NluoylhGrL6cUfYxdQPnvUp9YU2C6F9hsyBVLGulBd9vBN1ebfXOQ==", - "dependencies": { - "@hapi/boom": "9.x.x", - "@hapi/hoek": "9.x.x", - "@hapi/podium": "4.x.x", - "@hapi/validate": "1.x.x" - } - }, - "node_modules/@hapi/catbox-memory": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@hapi/catbox-memory/-/catbox-memory-5.0.1.tgz", - "integrity": "sha512-QWw9nOYJq5PlvChLWV8i6hQHJYfvdqiXdvTupJFh0eqLZ64Xir7mKNi96d5/ZMUAqXPursfNDIDxjFgoEDUqeQ==", - "dependencies": { - "@hapi/boom": "9.x.x", - "@hapi/hoek": "9.x.x" - } - }, - "node_modules/@hapi/content": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@hapi/content/-/content-5.0.2.tgz", - "integrity": "sha512-mre4dl1ygd4ZyOH3tiYBrOUBzV7Pu/EOs8VLGf58vtOEECWed8Uuw6B4iR9AN/8uQt42tB04qpVaMyoMQh0oMw==", - "dependencies": { - "@hapi/boom": "9.x.x" - } - }, - "node_modules/@hapi/cryptiles": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/cryptiles/-/cryptiles-5.1.0.tgz", - "integrity": "sha512-fo9+d1Ba5/FIoMySfMqPBR/7Pa29J2RsiPrl7bkwo5W5o+AN1dAYQRi4SPrPwwVxVGKjgLOEWrsvt1BonJSfLA==", - "dependencies": { - "@hapi/boom": "9.x.x" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@hapi/file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/file/-/file-2.0.0.tgz", - "integrity": "sha512-WSrlgpvEqgPWkI18kkGELEZfXr0bYLtr16iIN4Krh9sRnzBZN6nnWxHFxtsnP684wueEySBbXPDg/WfA9xJdBQ==" - }, - "node_modules/@hapi/hapi": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@hapi/hapi/-/hapi-20.2.1.tgz", - "integrity": "sha512-OXAU+yWLwkMfPFic+KITo+XPp6Oxpgc9WUH+pxXWcTIuvWbgco5TC/jS8UDvz+NFF5IzRgF2CL6UV/KLdQYUSQ==", - "dependencies": { - "@hapi/accept": "^5.0.1", - "@hapi/ammo": "^5.0.1", - "@hapi/boom": "^9.1.0", - "@hapi/bounce": "^2.0.0", - "@hapi/call": "^8.0.0", - "@hapi/catbox": "^11.1.1", - "@hapi/catbox-memory": "^5.0.0", - "@hapi/heavy": "^7.0.1", - "@hapi/hoek": "^9.0.4", - "@hapi/mimos": "^6.0.0", - "@hapi/podium": "^4.1.1", - "@hapi/shot": "^5.0.5", - "@hapi/somever": "^3.0.0", - "@hapi/statehood": "^7.0.3", - "@hapi/subtext": "^7.0.3", - "@hapi/teamwork": "^5.1.0", - "@hapi/topo": "^5.0.0", - "@hapi/validate": "^1.1.1" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@hapi/heavy": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@hapi/heavy/-/heavy-7.0.1.tgz", - "integrity": "sha512-vJ/vzRQ13MtRzz6Qd4zRHWS3FaUc/5uivV2TIuExGTM9Qk+7Zzqj0e2G7EpE6KztO9SalTbiIkTh7qFKj/33cA==", - "dependencies": { - "@hapi/boom": "9.x.x", - "@hapi/hoek": "9.x.x", - "@hapi/validate": "1.x.x" - } - }, - "node_modules/@hapi/hoek": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.1.tgz", - "integrity": "sha512-gfta+H8aziZsm8pZa0vj04KO6biEiisppNgA1kbJvFrrWu9Vm7eaUEy76DIxsuTaWvti5fkJVhllWc6ZTE+Mdw==" - }, - "node_modules/@hapi/inert": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/@hapi/inert/-/inert-6.0.5.tgz", - "integrity": "sha512-eVAdUVhJLmmXLM/Zt7u5H5Vzazs9GKe4zfPK2b97ePHEfs3g/AQkxHfYQjJqMy11hvyB7a21Z6rBEA0R//dtXw==", - "dependencies": { - "@hapi/ammo": "5.x.x", - "@hapi/boom": "9.x.x", - "@hapi/bounce": "2.x.x", - "@hapi/hoek": "9.x.x", - "@hapi/validate": "1.x.x", - "lru-cache": "^6.0.0" - } - }, - "node_modules/@hapi/iron": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@hapi/iron/-/iron-6.0.0.tgz", - "integrity": "sha512-zvGvWDufiTGpTJPG1Y/McN8UqWBu0k/xs/7l++HVU535NLHXsHhy54cfEMdW7EjwKfbBfM9Xy25FmTiobb7Hvw==", - "dependencies": { - "@hapi/b64": "5.x.x", - "@hapi/boom": "9.x.x", - "@hapi/bourne": "2.x.x", - "@hapi/cryptiles": "5.x.x", - "@hapi/hoek": "9.x.x" - } - }, - "node_modules/@hapi/mimos": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@hapi/mimos/-/mimos-6.0.0.tgz", - "integrity": "sha512-Op/67tr1I+JafN3R3XN5DucVSxKRT/Tc+tUszDwENoNpolxeXkhrJ2Czt6B6AAqrespHoivhgZBWYSuANN9QXg==", - "dependencies": { - "@hapi/hoek": "9.x.x", - "mime-db": "1.x.x" - } - }, - "node_modules/@hapi/nigel": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@hapi/nigel/-/nigel-4.0.2.tgz", - "integrity": "sha512-ht2KoEsDW22BxQOEkLEJaqfpoKPXxi7tvabXy7B/77eFtOyG5ZEstfZwxHQcqAiZhp58Ae5vkhEqI03kawkYNw==", - "dependencies": { - "@hapi/hoek": "^9.0.4", - "@hapi/vise": "^4.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@hapi/pez": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@hapi/pez/-/pez-5.0.3.tgz", - "integrity": "sha512-mpikYRJjtrbJgdDHG/H9ySqYqwJ+QU/D7FXsYciS9P7NYBXE2ayKDAy3H0ou6CohOCaxPuTV4SZ0D936+VomHA==", - "dependencies": { - "@hapi/b64": "5.x.x", - "@hapi/boom": "9.x.x", - "@hapi/content": "^5.0.2", - "@hapi/hoek": "9.x.x", - "@hapi/nigel": "4.x.x" - } - }, - "node_modules/@hapi/podium": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@hapi/podium/-/podium-4.1.3.tgz", - "integrity": "sha512-ljsKGQzLkFqnQxE7qeanvgGj4dejnciErYd30dbrYzUOF/FyS/DOF97qcrT3bhoVwCYmxa6PEMhxfCPlnUcD2g==", - "dependencies": { - "@hapi/hoek": "9.x.x", - "@hapi/teamwork": "5.x.x", - "@hapi/validate": "1.x.x" - } - }, - "node_modules/@hapi/shot": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@hapi/shot/-/shot-5.0.5.tgz", - "integrity": "sha512-x5AMSZ5+j+Paa8KdfCoKh+klB78otxF+vcJR/IoN91Vo2e5ulXIW6HUsFTCU+4W6P/Etaip9nmdAx2zWDimB2A==", - "dependencies": { - "@hapi/hoek": "9.x.x", - "@hapi/validate": "1.x.x" - } - }, - "node_modules/@hapi/somever": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@hapi/somever/-/somever-3.0.1.tgz", - "integrity": "sha512-4ZTSN3YAHtgpY/M4GOtHUXgi6uZtG9nEZfNI6QrArhK0XN/RDVgijlb9kOmXwCR5VclDSkBul9FBvhSuKXx9+w==", - "dependencies": { - "@hapi/bounce": "2.x.x", - "@hapi/hoek": "9.x.x" - } - }, - "node_modules/@hapi/statehood": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/@hapi/statehood/-/statehood-7.0.3.tgz", - "integrity": "sha512-pYB+pyCHkf2Amh67QAXz7e/DN9jcMplIL7Z6N8h0K+ZTy0b404JKPEYkbWHSnDtxLjJB/OtgElxocr2fMH4G7w==", - "dependencies": { - "@hapi/boom": "9.x.x", - "@hapi/bounce": "2.x.x", - "@hapi/bourne": "2.x.x", - "@hapi/cryptiles": "5.x.x", - "@hapi/hoek": "9.x.x", - "@hapi/iron": "6.x.x", - "@hapi/validate": "1.x.x" - } - }, - "node_modules/@hapi/subtext": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/@hapi/subtext/-/subtext-7.0.3.tgz", - "integrity": "sha512-CekDizZkDGERJ01C0+TzHlKtqdXZxzSWTOaH6THBrbOHnsr3GY+yiMZC+AfNCypfE17RaIakGIAbpL2Tk1z2+A==", - "dependencies": { - "@hapi/boom": "9.x.x", - "@hapi/bourne": "2.x.x", - "@hapi/content": "^5.0.2", - "@hapi/file": "2.x.x", - "@hapi/hoek": "9.x.x", - "@hapi/pez": "^5.0.1", - "@hapi/wreck": "17.x.x" - } - }, - "node_modules/@hapi/teamwork": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/teamwork/-/teamwork-5.1.0.tgz", - "integrity": "sha512-llqoQTrAJDTXxG3c4Kz/uzhBS1TsmSBa/XG5SPcVXgmffHE1nFtyLIK0hNJHCB3EuBKT84adzd1hZNY9GJLWtg==", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@hapi/topo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", - "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", - "dependencies": { - "@hapi/hoek": "^9.0.0" - } - }, - "node_modules/@hapi/validate": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@hapi/validate/-/validate-1.1.3.tgz", - "integrity": "sha512-/XMR0N0wjw0Twzq2pQOzPBZlDzkekGcoCtzO314BpIEsbXdYGthQUbxgkGDf4nhk1+IPDAsXqWjMohRQYO06UA==", - "dependencies": { - "@hapi/hoek": "^9.0.0", - "@hapi/topo": "^5.0.0" - } - }, - "node_modules/@hapi/vise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@hapi/vise/-/vise-4.0.0.tgz", - "integrity": "sha512-eYyLkuUiFZTer59h+SGy7hUm+qE9p+UemePTHLlIWppEd+wExn3Df5jO04bFQTm7nleF5V8CtuYQYb+VFpZ6Sg==", - "dependencies": { - "@hapi/hoek": "9.x.x" - } - }, - "node_modules/@hapi/wreck": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/@hapi/wreck/-/wreck-17.1.0.tgz", - "integrity": "sha512-nx6sFyfqOpJ+EFrHX+XWwJAxs3ju4iHdbB/bwR8yTNZOiYmuhA8eCe7lYPtYmb4j7vyK/SlbaQsmTtUrMvPEBw==", - "dependencies": { - "@hapi/boom": "9.x.x", - "@hapi/bourne": "2.x.x", - "@hapi/hoek": "9.x.x" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.3.tgz", - "integrity": "sha512-3xSMlXHh03hCcCmFc0rbKp3Ivt2PFEJnQUJDDMTJQ2wkECZWdq4GePs2ctc5H8zV+cHPaq8k2vU8mrQjA6iHdQ==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", - "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.11", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", - "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", - "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@npmcli/fs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", - "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", - "dependencies": { - "@gar/promisify": "^1.0.1", - "semver": "^7.3.5" - } - }, - "node_modules/@npmcli/move-file": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", - "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", - "dependencies": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@npmcli/move-file/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@npmcli/move-file/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@nuxt/babel-preset-app": { - "version": "2.15.8", - "resolved": "https://registry.npmjs.org/@nuxt/babel-preset-app/-/babel-preset-app-2.15.8.tgz", - "integrity": "sha512-z23bY5P7dLTmIbk0ZZ95mcEXIEER/mQCOqEp2vxnzG2nurks+vq6tNcUAXqME1Wl6aXWTXlqky5plBe7RQHzhQ==", - "dependencies": { - "@babel/compat-data": "^7.14.0", - "@babel/core": "^7.14.0", - "@babel/helper-compilation-targets": "^7.13.16", - "@babel/helper-module-imports": "^7.13.12", - "@babel/plugin-proposal-class-properties": "^7.13.0", - "@babel/plugin-proposal-decorators": "^7.13.15", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8", - "@babel/plugin-proposal-optional-chaining": "^7.13.12", - "@babel/plugin-proposal-private-methods": "^7.13.0", - "@babel/plugin-transform-runtime": "^7.13.15", - "@babel/preset-env": "^7.14.1", - "@babel/runtime": "^7.14.0", - "@vue/babel-preset-jsx": "^1.2.4", - "core-js": "^2.6.5", - "core-js-compat": "^3.12.1", - "regenerator-runtime": "^0.13.7" - } - }, - "node_modules/@nuxt/builder": { - "version": "2.15.8", - "resolved": "https://registry.npmjs.org/@nuxt/builder/-/builder-2.15.8.tgz", - "integrity": "sha512-WVhN874LFMdgRiJqpxmeKI+vh5lhCUBVOyR9PhL1m1V/GV3fb+Dqc1BKS6XgayrWAWavPLveCJmQ/FID0puOfQ==", - "dependencies": { - "@nuxt/devalue": "^1.2.5", - "@nuxt/utils": "2.15.8", - "@nuxt/vue-app": "2.15.8", - "@nuxt/webpack": "2.15.8", - "chalk": "^4.1.1", - "chokidar": "^3.5.1", - "consola": "^2.15.3", - "fs-extra": "^9.1.0", - "glob": "^7.1.7", - "hash-sum": "^2.0.0", - "ignore": "^5.1.8", - "lodash": "^4.17.21", - "pify": "^5.0.0", - "serialize-javascript": "^5.0.1", - "upath": "^2.0.1" - } - }, - "node_modules/@nuxt/builder/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@nuxt/builder/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@nuxt/builder/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@nuxt/builder/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/@nuxt/builder/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@nuxt/builder/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@nuxt/cli": { - "version": "2.15.8", - "resolved": "https://registry.npmjs.org/@nuxt/cli/-/cli-2.15.8.tgz", - "integrity": "sha512-KcGIILW/dAjBKea1DHsuLCG1sNzhzETShwT23DhXWO304qL8ljf4ndYKzn2RenzauGRGz7MREta80CbJCkLSHw==", - "dependencies": { - "@nuxt/config": "2.15.8", - "@nuxt/utils": "2.15.8", - "boxen": "^5.0.1", - "chalk": "^4.1.1", - "compression": "^1.7.4", - "connect": "^3.7.0", - "consola": "^2.15.3", - "crc": "^3.8.0", - "defu": "^4.0.1", - "destr": "^1.1.0", - "execa": "^5.0.0", - "exit": "^0.1.2", - "fs-extra": "^9.1.0", - "globby": "^11.0.3", - "hable": "^3.0.0", - "lodash": "^4.17.21", - "minimist": "^1.2.5", - "opener": "1.5.2", - "pretty-bytes": "^5.6.0", - "semver": "^7.3.5", - "serve-static": "^1.14.1", - "std-env": "^2.3.0", - "upath": "^2.0.1", - "wrap-ansi": "^7.0.0" - }, - "bin": { - "nuxt-cli": "bin/nuxt-cli.js" - } - }, - "node_modules/@nuxt/cli/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@nuxt/cli/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@nuxt/cli/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@nuxt/cli/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@nuxt/cli/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/@nuxt/cli/node_modules/defu": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/defu/-/defu-4.0.1.tgz", - "integrity": "sha512-lC+G0KvvWRbisQa50+iFelm3/eMmwo4IlBmfASOVlw9MZpHHyQeVsZxc5j23+TQy5ydgEoTVSrWl7ptou1kzJQ==" - }, - "node_modules/@nuxt/cli/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@nuxt/cli/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@nuxt/cli/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@nuxt/cli/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/@nuxt/components": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@nuxt/components/-/components-2.2.1.tgz", - "integrity": "sha512-r1LHUzifvheTnJtYrMuA+apgsrEJbxcgFKIimeXKb+jl8TnPWdV3egmrxBCaDJchrtY/wmHyP47tunsft7AWwg==", - "dependencies": { - "chalk": "^4.1.2", - "chokidar": "^3.5.2", - "glob": "^7.1.7", - "globby": "^11.0.4", - "scule": "^0.2.1", - "semver": "^7.3.5", - "upath": "^2.0.1", - "vue-template-compiler": "^2.6.14" - }, - "peerDependencies": { - "consola": "*" - } - }, - "node_modules/@nuxt/components/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@nuxt/components/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@nuxt/components/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@nuxt/components/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/@nuxt/components/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@nuxt/components/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@nuxt/config": { - "version": "2.15.8", - "resolved": "https://registry.npmjs.org/@nuxt/config/-/config-2.15.8.tgz", - "integrity": "sha512-KMQbjmUf9RVHeTZEf7zcuFnh03XKZioYhok6GOCY+leu3g5n/UhyPvLnTsgTfsLWohqoRoOm94u4A+tNYwn9VQ==", - "dependencies": { - "@nuxt/utils": "2.15.8", - "consola": "^2.15.3", - "defu": "^4.0.1", - "destr": "^1.1.0", - "dotenv": "^9.0.2", - "lodash": "^4.17.21", - "rc9": "^1.2.0", - "std-env": "^2.3.0", - "ufo": "^0.7.4" - } - }, - "node_modules/@nuxt/config/node_modules/defu": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/defu/-/defu-4.0.1.tgz", - "integrity": "sha512-lC+G0KvvWRbisQa50+iFelm3/eMmwo4IlBmfASOVlw9MZpHHyQeVsZxc5j23+TQy5ydgEoTVSrWl7ptou1kzJQ==" - }, - "node_modules/@nuxt/config/node_modules/dotenv": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-9.0.2.tgz", - "integrity": "sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==", - "engines": { - "node": ">=10" - } - }, - "node_modules/@nuxt/core": { - "version": "2.15.8", - "resolved": "https://registry.npmjs.org/@nuxt/core/-/core-2.15.8.tgz", - "integrity": "sha512-31pipWRvwHiyB5VDqffgSO7JtmHxyzgshIzuZzSinxMbVmK3BKsOwacD/51oEyELgrPlUgLqcY9dg+RURgmHGQ==", - "dependencies": { - "@nuxt/config": "2.15.8", - "@nuxt/server": "2.15.8", - "@nuxt/utils": "2.15.8", - "consola": "^2.15.3", - "fs-extra": "^9.1.0", - "hable": "^3.0.0", - "hash-sum": "^2.0.0", - "lodash": "^4.17.21" - } - }, - "node_modules/@nuxt/devalue": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@nuxt/devalue/-/devalue-1.2.5.tgz", - "integrity": "sha512-Tg86C7tqzvZtZli2BQVqgzZN136mZDTgauvJXagglKkP2xt5Kw3NUIiJyjX0Ww/IZy2xVmD0LN+CEPpij4dB2g==", - "dependencies": { - "consola": "^2.9.0" - } - }, - "node_modules/@nuxt/friendly-errors-webpack-plugin": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@nuxt/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-2.5.2.tgz", - "integrity": "sha512-LLc+90lnxVbpKkMqk5z1EWpXoODhc6gRkqqXJCInJwF5xabHAE7biFvbULfvTRmtaTzAaP8IV4HQDLUgeAUTTw==", - "dependencies": { - "chalk": "^2.3.2", - "consola": "^2.6.0", - "error-stack-parser": "^2.0.0", - "string-width": "^4.2.3" - }, - "engines": { - "node": ">=8.0.0", - "npm": ">=5.0.0" - }, - "peerDependencies": { - "webpack": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0" - } - }, - "node_modules/@nuxt/friendly-errors-webpack-plugin/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@nuxt/friendly-errors-webpack-plugin/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@nuxt/friendly-errors-webpack-plugin/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/@nuxt/friendly-errors-webpack-plugin/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@nuxt/generator": { - "version": "2.15.8", - "resolved": "https://registry.npmjs.org/@nuxt/generator/-/generator-2.15.8.tgz", - "integrity": "sha512-hreLdYbBIe3SWcP8LsMG7OlDTx2ZVucX8+f8Vrjft3Q4r8iCwLMYC1s1N5etxeHAZfS2kZiLmF92iscOdfbgMQ==", - "dependencies": { - "@nuxt/utils": "2.15.8", - "chalk": "^4.1.1", - "consola": "^2.15.3", - "defu": "^4.0.1", - "devalue": "^2.0.1", - "fs-extra": "^9.1.0", - "html-minifier": "^4.0.0", - "node-html-parser": "^3.2.0", - "ufo": "^0.7.4" - } - }, - "node_modules/@nuxt/generator/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@nuxt/generator/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@nuxt/generator/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@nuxt/generator/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/@nuxt/generator/node_modules/defu": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/defu/-/defu-4.0.1.tgz", - "integrity": "sha512-lC+G0KvvWRbisQa50+iFelm3/eMmwo4IlBmfASOVlw9MZpHHyQeVsZxc5j23+TQy5ydgEoTVSrWl7ptou1kzJQ==" - }, - "node_modules/@nuxt/generator/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@nuxt/generator/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@nuxt/loading-screen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nuxt/loading-screen/-/loading-screen-2.0.4.tgz", - "integrity": "sha512-xpEDAoRu75tLUYCkUJCIvJkWJSuwr8pqomvQ+fkXpSrkxZ/9OzlBFjAbVdOAWTMj4aV/LVQso4vcEdircKeFIQ==", - "dependencies": { - "connect": "^3.7.0", - "defu": "^5.0.0", - "get-port-please": "^2.2.0", - "node-res": "^5.0.1", - "serve-static": "^1.14.1" - } - }, - "node_modules/@nuxt/opencollective": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@nuxt/opencollective/-/opencollective-0.3.2.tgz", - "integrity": "sha512-XG7rUdXG9fcafu9KTDIYjJSkRO38EwjlKYIb5TQ/0WDbiTUTtUtgncMscKOYzfsY86kGs05pAuMOR+3Fi0aN3A==", - "dependencies": { - "chalk": "^4.1.0", - "consola": "^2.15.0", - "node-fetch": "^2.6.1" - }, - "bin": { - "opencollective": "bin/opencollective.js" - }, - "engines": { - "node": ">=8.0.0", - "npm": ">=5.0.0" - } - }, - "node_modules/@nuxt/opencollective/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@nuxt/opencollective/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@nuxt/opencollective/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@nuxt/opencollective/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/@nuxt/opencollective/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@nuxt/opencollective/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@nuxt/server": { - "version": "2.15.8", - "resolved": "https://registry.npmjs.org/@nuxt/server/-/server-2.15.8.tgz", - "integrity": "sha512-E4EtXudxtWQBUHMHOxFwm5DlPOkJbW+iF1+zc0dGmXLscep1KWPrlP+4nrpZj8/UKzpupamE8ZTS9I4IbnExVA==", - "dependencies": { - "@nuxt/utils": "2.15.8", - "@nuxt/vue-renderer": "2.15.8", - "@nuxtjs/youch": "^4.2.3", - "compression": "^1.7.4", - "connect": "^3.7.0", - "consola": "^2.15.3", - "etag": "^1.8.1", - "fresh": "^0.5.2", - "fs-extra": "^9.1.0", - "ip": "^1.1.5", - "launch-editor-middleware": "^2.2.1", - "on-headers": "^1.0.2", - "pify": "^5.0.0", - "serve-placeholder": "^1.2.3", - "serve-static": "^1.14.1", - "server-destroy": "^1.0.1", - "ufo": "^0.7.4" - } - }, - "node_modules/@nuxt/telemetry": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/@nuxt/telemetry/-/telemetry-1.3.6.tgz", - "integrity": "sha512-sZpLf/rU3cvN8/alR1HpJIl3mHPA1GOg41GKdOOrtw7Gi/lCEVk4hK+lpXgYInZ2n6i1JyknpKhM9YzX2RU33w==", - "dependencies": { - "arg": "^5.0.0", - "chalk": "^4.1.1", - "ci-info": "^3.1.1", - "consola": "^2.15.3", - "create-require": "^1.1.1", - "defu": "^5.0.0", - "destr": "^1.1.0", - "dotenv": "^9.0.2", - "fs-extra": "^8.1.0", - "git-url-parse": "^11.4.4", - "inquirer": "^7.3.3", - "is-docker": "^2.2.1", - "jiti": "^1.9.2", - "nanoid": "^3.1.23", - "node-fetch": "^2.6.1", - "parse-git-config": "^3.0.0", - "rc9": "^1.2.0", - "std-env": "^2.3.0" - }, - "bin": { - "nuxt-telemetry": "bin/nuxt-telemetry.js" - } - }, - "node_modules/@nuxt/telemetry/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@nuxt/telemetry/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@nuxt/telemetry/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@nuxt/telemetry/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/@nuxt/telemetry/node_modules/dotenv": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-9.0.2.tgz", - "integrity": "sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==", - "engines": { - "node": ">=10" - } - }, - "node_modules/@nuxt/telemetry/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/@nuxt/telemetry/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@nuxt/telemetry/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@nuxt/telemetry/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@nuxt/telemetry/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/@nuxt/utils": { - "version": "2.15.8", - "resolved": "https://registry.npmjs.org/@nuxt/utils/-/utils-2.15.8.tgz", - "integrity": "sha512-e0VBarUbPiQ4ZO1T58puoFIuXme7L5gk1QfwyxOONlp2ryE7aRyZ8X/mryuOiIeyP64c4nwSUtN7q9EUWRb7Lg==", - "dependencies": { - "consola": "^2.15.3", - "create-require": "^1.1.1", - "fs-extra": "^9.1.0", - "hash-sum": "^2.0.0", - "jiti": "^1.9.2", - "lodash": "^4.17.21", - "proper-lockfile": "^4.1.2", - "semver": "^7.3.5", - "serialize-javascript": "^5.0.1", - "signal-exit": "^3.0.3", - "ua-parser-js": "^0.7.28", - "ufo": "^0.7.4" - } - }, - "node_modules/@nuxt/vue-app": { - "version": "2.15.8", - "resolved": "https://registry.npmjs.org/@nuxt/vue-app/-/vue-app-2.15.8.tgz", - "integrity": "sha512-FJf9FSMPsWT3BqkS37zEuPTxLKzSg2EIwp1sP8Eou25eE08qxRfe2PwTVA8HnXUPNdpz2uk/T9DlNw+JraiFRQ==", - "dependencies": { - "node-fetch": "^2.6.1", - "ufo": "^0.7.4", - "unfetch": "^4.2.0", - "vue": "^2.6.12", - "vue-client-only": "^2.0.0", - "vue-meta": "^2.4.0", - "vue-no-ssr": "^1.1.1", - "vue-router": "^3.5.1", - "vue-template-compiler": "^2.6.12", - "vuex": "^3.6.2" - } - }, - "node_modules/@nuxt/vue-renderer": { - "version": "2.15.8", - "resolved": "https://registry.npmjs.org/@nuxt/vue-renderer/-/vue-renderer-2.15.8.tgz", - "integrity": "sha512-54I/k+4G6axP9XVYYdtH6M1S6T49OIkarpF6/yIJj0yi3S/2tdJ9eUyfoLZ9EbquZFDDRHBxSswTtr2l/eakPw==", - "dependencies": { - "@nuxt/devalue": "^1.2.5", - "@nuxt/utils": "2.15.8", - "consola": "^2.15.3", - "defu": "^4.0.1", - "fs-extra": "^9.1.0", - "lodash": "^4.17.21", - "lru-cache": "^5.1.1", - "ufo": "^0.7.4", - "vue": "^2.6.12", - "vue-meta": "^2.4.0", - "vue-server-renderer": "^2.6.12" - } - }, - "node_modules/@nuxt/vue-renderer/node_modules/defu": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/defu/-/defu-4.0.1.tgz", - "integrity": "sha512-lC+G0KvvWRbisQa50+iFelm3/eMmwo4IlBmfASOVlw9MZpHHyQeVsZxc5j23+TQy5ydgEoTVSrWl7ptou1kzJQ==" - }, - "node_modules/@nuxt/vue-renderer/node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/@nuxt/vue-renderer/node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, - "node_modules/@nuxt/webpack": { - "version": "2.15.8", - "resolved": "https://registry.npmjs.org/@nuxt/webpack/-/webpack-2.15.8.tgz", - "integrity": "sha512-CzJYFed23Ow/UK0+cI1FVthDre1p2qc8Q97oizG39d3/SIh3aUHjgj8c60wcR+RSxVO0FzZMXkmq02NmA7vWJg==", - "dependencies": { - "@babel/core": "^7.14.0", - "@nuxt/babel-preset-app": "2.15.8", - "@nuxt/friendly-errors-webpack-plugin": "^2.5.1", - "@nuxt/utils": "2.15.8", - "babel-loader": "^8.2.2", - "cache-loader": "^4.1.0", - "caniuse-lite": "^1.0.30001228", - "consola": "^2.15.3", - "css-loader": "^4.3.0", - "cssnano": "^4.1.11", - "eventsource-polyfill": "^0.9.6", - "extract-css-chunks-webpack-plugin": "^4.9.0", - "file-loader": "^6.2.0", - "glob": "^7.1.7", - "hard-source-webpack-plugin": "^0.13.1", - "hash-sum": "^2.0.0", - "html-webpack-plugin": "^4.5.1", - "lodash": "^4.17.21", - "memory-fs": "^0.5.0", - "optimize-css-assets-webpack-plugin": "^5.0.4", - "pify": "^5.0.0", - "pnp-webpack-plugin": "^1.6.4", - "postcss": "^7.0.32", - "postcss-import": "^12.0.1", - "postcss-import-resolver": "^2.0.0", - "postcss-loader": "^3.0.0", - "postcss-preset-env": "^6.7.0", - "postcss-url": "^8.0.0", - "semver": "^7.3.5", - "std-env": "^2.3.0", - "style-resources-loader": "^1.4.1", - "terser-webpack-plugin": "^4.2.3", - "thread-loader": "^3.0.4", - "time-fix-plugin": "^2.0.7", - "ufo": "^0.7.4", - "url-loader": "^4.1.1", - "vue-loader": "^15.9.7", - "vue-style-loader": "^4.1.3", - "vue-template-compiler": "^2.6.12", - "webpack": "^4.46.0", - "webpack-bundle-analyzer": "^4.4.1", - "webpack-dev-middleware": "^4.2.0", - "webpack-hot-middleware": "^2.25.0", - "webpack-node-externals": "^3.0.0", - "webpackbar": "^4.0.0" - } - }, - "node_modules/@nuxt/webpack/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/@nuxt/webpack/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/@nuxt/webpack/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@nuxtjs/axios": { - "version": "5.13.6", - "resolved": "https://registry.npmjs.org/@nuxtjs/axios/-/axios-5.13.6.tgz", - "integrity": "sha512-XS+pOE0xsDODs1zAIbo95A0LKlilvJi8YW0NoXYuq3/jjxGgWDxizZ6Yx0AIIjZOoGsXJOPc0/BcnSEUQ2mFBA==", - "dependencies": { - "@nuxtjs/proxy": "^2.1.0", - "axios": "^0.21.1", - "axios-retry": "^3.1.9", - "consola": "^2.15.3", - "defu": "^5.0.0" - } - }, - "node_modules/@nuxtjs/axios/node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dependencies": { - "follow-redirects": "^1.14.0" - } - }, - "node_modules/@nuxtjs/dotenv": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@nuxtjs/dotenv/-/dotenv-1.4.1.tgz", - "integrity": "sha512-DpdObsvRwC8d89I9mzz6pBg6e/PEXHazDM57DOI1mmML2ZjHfQ/DvkjlSzUL7T+TnW3b/a4Ks5wQx08DqFBmeQ==", - "dependencies": { - "consola": "^2.10.1", - "dotenv": "^8.1.0" - } - }, - "node_modules/@nuxtjs/google-analytics": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@nuxtjs/google-analytics/-/google-analytics-2.4.0.tgz", - "integrity": "sha512-rDQTwHIjyjVrx8GywHPuWykJ3jRFGaHl5Iqji/y8tQWUc0yGEeHxOoR0yimzxnTS1Ph2/PubQYpgnVeEPEdL/A==", - "dependencies": { - "vue-analytics": "^5.22.1" - } - }, - "node_modules/@nuxtjs/hapi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@nuxtjs/hapi/-/hapi-3.0.0.tgz", - "integrity": "sha512-Grhc/JCCNr/z+NI+MZOQIk2UIEgQzK/e3PhkI6wU0fbaTAgqNUi0PGY2Meor/iJSiKDdOiR+PkXE+B1ClucZ1Q==" - }, - "node_modules/@nuxtjs/markdownit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@nuxtjs/markdownit/-/markdownit-2.0.0.tgz", - "integrity": "sha512-YAEK/s0IzdWK1L74WKTQSMcvNhGgOW0xIWdu5VMxDo1NkNpm/0CbJZgSPt1JYAnT8r8r6wVQ5SY1v/1MZanPlQ==", - "dependencies": { - "@nuxtjs/markdownit-loader": "^1.1.1", - "defu": "^3.2.2", - "raw-loader": "^4.0.2" - } - }, - "node_modules/@nuxtjs/markdownit-loader": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@nuxtjs/markdownit-loader/-/markdownit-loader-1.2.0.tgz", - "integrity": "sha512-D6m4578NavamwD03nOU3H3NkS2zYfFJSMChUczlCGDx05DgAoenY4GdCmML1CnAEH/Cv6Bf230RIwDnD926oyQ==", - "dependencies": { - "highlight.js": "^10.5.0", - "loader-utils": "^1.1.0", - "markdown-it": "^8.3.1" - } - }, - "node_modules/@nuxtjs/markdownit-loader/node_modules/highlight.js": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", - "engines": { - "node": "*" - } - }, - "node_modules/@nuxtjs/markdownit/node_modules/defu": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/defu/-/defu-3.2.2.tgz", - "integrity": "sha512-8UWj5lNv7HD+kB0e9w77Z7TdQlbUYDVWqITLHNqFIn6khrNHv5WQo38Dcm1f6HeNyZf0U7UbPf6WeZDSdCzGDQ==" - }, - "node_modules/@nuxtjs/proxy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@nuxtjs/proxy/-/proxy-2.1.0.tgz", - "integrity": "sha512-/qtoeqXgZ4Mg6LRg/gDUZQrFpOlOdHrol/vQYMnKu3aN3bP90UfOUB3QSDghUUK7OISAJ0xp8Ld78aHyCTcKCQ==", - "dependencies": { - "http-proxy-middleware": "^1.0.6" - } - }, - "node_modules/@nuxtjs/pwa": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/@nuxtjs/pwa/-/pwa-3.3.5.tgz", - "integrity": "sha512-8tTmW8DBspWxlJwTimOHTkwfkwPpL9wIcGmy75Gcmin+c9YtX2Ehxmhgt/TLFOC9XsLAqojqynw3/Agr/9OE1w==", - "dependencies": { - "clone-deep": "^4.0.1", - "defu": "^3.2.2", - "execa": "^5.0.0", - "fs-extra": "^9.1.0", - "hasha": "^5.2.2", - "jimp-compact": "^0.16.1", - "lodash.template": "^4.5.0", - "serve-static": "^1.14.1", - "workbox-cdn": "^5.1.4" - } - }, - "node_modules/@nuxtjs/pwa/node_modules/defu": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/defu/-/defu-3.2.2.tgz", - "integrity": "sha512-8UWj5lNv7HD+kB0e9w77Z7TdQlbUYDVWqITLHNqFIn6khrNHv5WQo38Dcm1f6HeNyZf0U7UbPf6WeZDSdCzGDQ==" - }, - "node_modules/@nuxtjs/svg": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@nuxtjs/svg/-/svg-0.4.0.tgz", - "integrity": "sha512-XF8uvV5YKBPAJr52SFRVkhltAsjCBTwwTc4GTysSm8WPYB2utJLY48qXdVC/J9dNQiMd7NHo1xmEYEqQfzqpqg==", - "dependencies": { - "file-loader": "^6.0.0", - "raw-loader": "^4.0.0", - "svg-sprite-loader": "^5.2.1", - "url-loader": "^4.1.0", - "vue-svg-loader": "^0.16.0" - } - }, - "node_modules/@nuxtjs/youch": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/@nuxtjs/youch/-/youch-4.2.3.tgz", - "integrity": "sha512-XiTWdadTwtmL/IGkNqbVe+dOlT+IMvcBu7TvKI7plWhVQeBCQ9iKhk3jgvVWFyiwL2yHJDlEwOM5v9oVES5Xmw==", - "dependencies": { - "cookie": "^0.3.1", - "mustache": "^2.3.0", - "stack-trace": "0.0.10" - } - }, - "node_modules/@nuxtjs/youch/node_modules/cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/@polka/url": { - "version": "1.0.0-next.21", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", - "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==" - }, - "node_modules/@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, - "dependencies": { - "defer-to-connect": "^1.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@types/cookie": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.3.3.tgz", - "integrity": "sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow==" - }, - "node_modules/@types/html-minifier-terser": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.2.tgz", - "integrity": "sha512-h4lTMgMJctJybDp8CQrxTUiiYmedihHWkjnF/8Pxseu2S6Nlfcy8kwboQ8yejh456rP2yWoEVm1sS/FVsfM48w==" - }, - "node_modules/@types/http-proxy": { - "version": "1.17.8", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.8.tgz", - "integrity": "sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==" - }, - "node_modules/@types/node": { - "version": "17.0.19", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.19.tgz", - "integrity": "sha512-PfeQhvcMR4cPFVuYfBN4ifG7p9c+Dlh3yUZR6k+5yQK7wX3gDgVxBly4/WkBRs9x4dmcy1TVl08SY67wwtEvmA==" - }, - "node_modules/@types/q": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz", - "integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==" - }, - "node_modules/@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==" - }, - "node_modules/@types/tapable": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.8.tgz", - "integrity": "sha512-ipixuVrh2OdNmauvtT51o3d8z12p6LtFW9in7U79der/kwejjdNchQC5UMn5u/KxNoM7VHHOs/l8KS8uHxhODQ==" - }, - "node_modules/@types/uglify-js": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.13.1.tgz", - "integrity": "sha512-O3MmRAk6ZuAKa9CHgg0Pr0+lUOqoMLpc9AS4R8ano2auvsg7IE8syF3Xh/NPr26TWklxYcqoEEFdzLLs1fV9PQ==", - "dependencies": { - "source-map": "^0.6.1" - } - }, - "node_modules/@types/uglify-js/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@types/webpack": { - "version": "4.41.32", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.32.tgz", - "integrity": "sha512-cb+0ioil/7oz5//7tZUSwbrSAN/NWHrQylz5cW8G0dWTcF/g+/dSdMlKVZspBYuMAN1+WnwHrkxiRrLcwd0Heg==", - "dependencies": { - "@types/node": "*", - "@types/tapable": "^1", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "anymatch": "^3.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/@types/webpack-sources": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-3.2.0.tgz", - "integrity": "sha512-Ft7YH3lEVRQ6ls8k4Ff1oB4jN6oy/XmU6tQISKdhfh+1mR+viZFphS6WL0IrtDOzvefmJg5a0s7ZQoRXwqTEFg==", - "dependencies": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.7.3" - } - }, - "node_modules/@types/webpack-sources/node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@types/webpack/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@vue/babel-helper-vue-jsx-merge-props": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.2.1.tgz", - "integrity": "sha512-QOi5OW45e2R20VygMSNhyQHvpdUwQZqGPc748JLGCYEy+yp8fNFNdbNIGAgZmi9e+2JHPd6i6idRuqivyicIkA==" - }, - "node_modules/@vue/babel-plugin-transform-vue-jsx": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.2.1.tgz", - "integrity": "sha512-HJuqwACYehQwh1fNT8f4kyzqlNMpBuUK4rSiSES5D4QsYncv5fxFsLyrxFPG2ksO7t5WP+Vgix6tt6yKClwPzA==", - "dependencies": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/plugin-syntax-jsx": "^7.2.0", - "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1", - "html-tags": "^2.0.0", - "lodash.kebabcase": "^4.1.1", - "svg-tags": "^1.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@vue/babel-preset-jsx": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@vue/babel-preset-jsx/-/babel-preset-jsx-1.2.4.tgz", - "integrity": "sha512-oRVnmN2a77bYDJzeGSt92AuHXbkIxbf/XXSE3klINnh9AXBmVS1DGa1f0d+dDYpLfsAKElMnqKTQfKn7obcL4w==", - "dependencies": { - "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1", - "@vue/babel-plugin-transform-vue-jsx": "^1.2.1", - "@vue/babel-sugar-composition-api-inject-h": "^1.2.1", - "@vue/babel-sugar-composition-api-render-instance": "^1.2.4", - "@vue/babel-sugar-functional-vue": "^1.2.2", - "@vue/babel-sugar-inject-h": "^1.2.2", - "@vue/babel-sugar-v-model": "^1.2.3", - "@vue/babel-sugar-v-on": "^1.2.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@vue/babel-sugar-composition-api-inject-h": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-composition-api-inject-h/-/babel-sugar-composition-api-inject-h-1.2.1.tgz", - "integrity": "sha512-4B3L5Z2G+7s+9Bwbf+zPIifkFNcKth7fQwekVbnOA3cr3Pq71q71goWr97sk4/yyzH8phfe5ODVzEjX7HU7ItQ==", - "dependencies": { - "@babel/plugin-syntax-jsx": "^7.2.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@vue/babel-sugar-composition-api-render-instance": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-composition-api-render-instance/-/babel-sugar-composition-api-render-instance-1.2.4.tgz", - "integrity": "sha512-joha4PZznQMsxQYXtR3MnTgCASC9u3zt9KfBxIeuI5g2gscpTsSKRDzWQt4aqNIpx6cv8On7/m6zmmovlNsG7Q==", - "dependencies": { - "@babel/plugin-syntax-jsx": "^7.2.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@vue/babel-sugar-functional-vue": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-functional-vue/-/babel-sugar-functional-vue-1.2.2.tgz", - "integrity": "sha512-JvbgGn1bjCLByIAU1VOoepHQ1vFsroSA/QkzdiSs657V79q6OwEWLCQtQnEXD/rLTA8rRit4rMOhFpbjRFm82w==", - "dependencies": { - "@babel/plugin-syntax-jsx": "^7.2.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@vue/babel-sugar-inject-h": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-inject-h/-/babel-sugar-inject-h-1.2.2.tgz", - "integrity": "sha512-y8vTo00oRkzQTgufeotjCLPAvlhnpSkcHFEp60+LJUwygGcd5Chrpn5480AQp/thrxVm8m2ifAk0LyFel9oCnw==", - "dependencies": { - "@babel/plugin-syntax-jsx": "^7.2.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@vue/babel-sugar-v-model": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.2.3.tgz", - "integrity": "sha512-A2jxx87mySr/ulAsSSyYE8un6SIH0NWHiLaCWpodPCVOlQVODCaSpiR4+IMsmBr73haG+oeCuSvMOM+ttWUqRQ==", - "dependencies": { - "@babel/plugin-syntax-jsx": "^7.2.0", - "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1", - "@vue/babel-plugin-transform-vue-jsx": "^1.2.1", - "camelcase": "^5.0.0", - "html-tags": "^2.0.0", - "svg-tags": "^1.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@vue/babel-sugar-v-on": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.2.3.tgz", - "integrity": "sha512-kt12VJdz/37D3N3eglBywV8GStKNUhNrsxChXIV+o0MwVXORYuhDTHJRKPgLJRb/EY3vM2aRFQdxJBp9CLikjw==", - "dependencies": { - "@babel/plugin-syntax-jsx": "^7.2.0", - "@vue/babel-plugin-transform-vue-jsx": "^1.2.1", - "camelcase": "^5.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@vue/component-compiler-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.3.0.tgz", - "integrity": "sha512-97sfH2mYNU+2PzGrmK2haqffDpVASuib9/w2/noxiFi31Z54hW+q3izKQXXQZSNhtiUpAI36uSuYepeBe4wpHQ==", - "dependencies": { - "consolidate": "^0.15.1", - "hash-sum": "^1.0.2", - "lru-cache": "^4.1.2", - "merge-source-map": "^1.1.0", - "postcss": "^7.0.36", - "postcss-selector-parser": "^6.0.2", - "source-map": "~0.6.1", - "vue-template-es2015-compiler": "^1.9.0" - }, - "optionalDependencies": { - "prettier": "^1.18.2 || ^2.0.0" - } - }, - "node_modules/@vue/component-compiler-utils/node_modules/hash-sum": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", - "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=" - }, - "node_modules/@vue/component-compiler-utils/node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "node_modules/@vue/component-compiler-utils/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/@vue/component-compiler-utils/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/@vue/component-compiler-utils/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@vue/component-compiler-utils/node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", - "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", - "dependencies": { - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", - "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==" - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", - "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==" - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", - "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==" - }, - "node_modules/@webassemblyjs/helper-code-frame": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", - "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", - "dependencies": { - "@webassemblyjs/wast-printer": "1.9.0" - } - }, - "node_modules/@webassemblyjs/helper-fsm": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", - "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==" - }, - "node_modules/@webassemblyjs/helper-module-context": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", - "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", - "dependencies": { - "@webassemblyjs/ast": "1.9.0" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", - "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==" - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", - "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", - "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", - "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", - "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==" - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", - "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/helper-wasm-section": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-opt": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "@webassemblyjs/wast-printer": "1.9.0" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", - "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", - "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", - "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "node_modules/@webassemblyjs/wast-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", - "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/floating-point-hex-parser": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-code-frame": "1.9.0", - "@webassemblyjs/helper-fsm": "1.9.0", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", - "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" - }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "peerDependencies": { - "ajv": ">=5.0.0" - } - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/alphanum-sort": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", - "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=" - }, - "node_modules/ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "dependencies": { - "string-width": "^4.1.0" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", - "engines": [ - "node >= 0.8.0" - ], - "bin": { - "ansi-html": "bin/ansi-html" - } - }, - "node_modules/ansi-red": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", - "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=", - "dependencies": { - "ansi-wrap": "0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ansi-wrap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" - }, - "node_modules/arg": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.1.tgz", - "integrity": "sha512-e0hDa9H2Z9AwFkk2qDlwhoMYE4eToKarchkQHovNdLTCYMHZHeRjI71crOh+dio4K6u1IcwubQqo79Ga4CyAQA==" - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/asn1.js/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", - "dependencies": { - "object-assign": "^4.1.1", - "util": "0.10.3" - } - }, - "node_modules/assert/node_modules/inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" - }, - "node_modules/assert/node_modules/util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dependencies": { - "inherits": "2.0.1" - } - }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "optional": true - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/autolinker": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-0.28.1.tgz", - "integrity": "sha1-BlK0kYgYefB3XazgzcoyM5QqTkc=", - "dependencies": { - "gulp-header": "^1.7.1" - } - }, - "node_modules/autoprefixer": { - "version": "9.8.8", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.8.tgz", - "integrity": "sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==", - "dependencies": { - "browserslist": "^4.12.0", - "caniuse-lite": "^1.0.30001109", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "picocolors": "^0.2.1", - "postcss": "^7.0.32", - "postcss-value-parser": "^4.1.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "funding": { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - } - }, - "node_modules/autoprefixer/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/autoprefixer/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/autoprefixer/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/axios": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.0.tgz", - "integrity": "sha512-lKoGLMYtHvFrPVt3r+RBMp9nh34N0M8zEfCWqdWZx6phynIEhQqAdydpyBAAG211zlhX9Rgu08cOamy6XjE5Og==", - "dependencies": { - "follow-redirects": "^1.14.8" - } - }, - "node_modules/axios-retry": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.2.4.tgz", - "integrity": "sha512-Co3UXiv4npi6lM963mfnuH90/YFLKWWDmoBYfxkHT5xtkSSWNqK9zdG3fw5/CP/dsoKB5aMMJCsgab+tp1OxLQ==", - "dependencies": { - "@babel/runtime": "^7.15.4", - "is-retry-allowed": "^2.2.0" - } - }, - "node_modules/babel-eslint": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", - "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", - "deprecated": "babel-eslint is now @babel/eslint-parser. This package will no longer receive updates.", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0", - "eslint-visitor-keys": "^1.0.0", - "resolve": "^1.12.0" - }, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "eslint": ">= 4.12.1" - } - }, - "node_modules/babel-loader": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.3.tgz", - "integrity": "sha512-n4Zeta8NC3QAsuyiizu0GkmRcQ6clkV9WFUnUf1iXP//IeSKbWjofW3UHyZVwlOB4y039YQKefawyTn64Zwbuw==", - "dependencies": { - "find-cache-dir": "^3.3.1", - "loader-utils": "^1.4.0", - "make-dir": "^3.1.0", - "schema-utils": "^2.6.5" - }, - "engines": { - "node": ">= 8.9" - }, - "peerDependencies": { - "@babel/core": "^7.0.0", - "webpack": ">=2" - } - }, - "node_modules/babel-loader/node_modules/schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "dependencies": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "dependencies": { - "object.assign": "^4.1.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz", - "integrity": "sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w==", - "dependencies": { - "@babel/compat-data": "^7.13.11", - "@babel/helper-define-polyfill-provider": "^0.3.1", - "semver": "^6.1.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz", - "integrity": "sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ==", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.1", - "core-js-compat": "^3.21.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz", - "integrity": "sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A==", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" - }, - "node_modules/boxen": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", - "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", - "dependencies": { - "ansi-align": "^3.0.0", - "camelcase": "^6.2.0", - "chalk": "^4.1.0", - "cli-boxes": "^2.2.1", - "string-width": "^4.2.2", - "type-fest": "^0.20.2", - "widest-line": "^3.1.0", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/boxen/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/boxen/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/boxen/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/boxen/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/boxen/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/boxen/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/boxen/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/boxen/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/boxen/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/boxen/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/boxen/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "node_modules/browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dependencies": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "node_modules/browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "dependencies": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "node_modules/browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dependencies": { - "pako": "~1.0.5" - } - }, - "node_modules/browserslist": { - "version": "4.19.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.3.tgz", - "integrity": "sha512-XK3X4xtKJ+Txj8G5c30B4gsm71s69lqXlkYui4s6EkKxuv49qjYlY6oVd+IFJ73d4YymtM3+djvvt/R/iJwwDg==", - "dependencies": { - "caniuse-lite": "^1.0.30001312", - "electron-to-chromium": "^1.4.71", - "escalade": "^3.1.1", - "node-releases": "^2.0.2", - "picocolors": "^1.0.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - } - }, - "node_modules/buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "node_modules/buffer-json": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/buffer-json/-/buffer-json-2.0.0.tgz", - "integrity": "sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw==" - }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" - }, - "node_modules/builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" - }, - "node_modules/bulma": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/bulma/-/bulma-0.9.3.tgz", - "integrity": "sha512-0d7GNW1PY4ud8TWxdNcP6Cc8Bu7MxcntD/RRLGWuiw/s0a9P+XlH/6QoOIrmbj6o8WWJzJYhytiu9nFjTszk1g==" - }, - "node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cacache": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", - "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", - "dependencies": { - "@npmcli/fs": "^1.0.0", - "@npmcli/move-file": "^1.0.1", - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^8.0.1", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/cacache/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cacache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cache-loader": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cache-loader/-/cache-loader-4.1.0.tgz", - "integrity": "sha512-ftOayxve0PwKzBF/GLsZNC9fJBXl8lkZE3TOsjkboHfVHVkL39iUEs1FO07A33mizmci5Dudt38UZrrYXDtbhw==", - "dependencies": { - "buffer-json": "^2.0.0", - "find-cache-dir": "^3.0.0", - "loader-utils": "^1.2.3", - "mkdirp": "^0.5.1", - "neo-async": "^2.6.1", - "schema-utils": "^2.0.0" - }, - "engines": { - "node": ">= 8.9.0" - }, - "peerDependencies": { - "webpack": "^4.0.0" - } - }, - "node_modules/cache-loader/node_modules/schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "dependencies": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cacheable-request/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cacheable-request/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cacheable-request/node_modules/normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", - "dependencies": { - "callsites": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", - "dependencies": { - "caller-callsite": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", - "engines": { - "node": ">=4" - } - }, - "node_modules/camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "dependencies": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "dependencies": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001312", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz", - "integrity": "sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - } - }, - "node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/chalk/node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/charcodes": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/charcodes/-/charcodes-0.2.0.tgz", - "integrity": "sha512-Y4kiDb+AM4Ecy58YkuZrrSRJBDQdQ2L+NyS1vHHFtNtUjgutcZfx3yp1dAONI/oPaPmyGfCLx5CxL+zauIMyKQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "engines": { - "node": ">=6.0" - } - }, - "node_modules/ci-info": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", - "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==" - }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clean-css": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", - "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/clean-css/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-boxes": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - } - }, - "node_modules/coa": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", - "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", - "dependencies": { - "@types/q": "^1.5.1", - "chalk": "^2.4.1", - "q": "^1.1.2" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/coa/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/coa/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/coa/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/coa/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/codemirror": { - "version": "5.65.2", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.2.tgz", - "integrity": "sha512-SZM4Zq7XEC8Fhroqe3LxbEEX1zUPWH1wMr5zxiBuiUF64iYOUH/JI88v4tBag8MiBS8B8gRv8O1pPXGYXQ4ErA==" - }, - "node_modules/coffee-script": { - "version": "1.12.7", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz", - "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==", - "deprecated": "CoffeeScript on NPM has moved to \"coffeescript\" (no hyphen)", - "bin": { - "cake": "bin/cake", - "coffee": "bin/coffee" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", - "dependencies": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" - } - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "node_modules/color-string": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.0.tgz", - "integrity": "sha512-9Mrz2AQLefkH1UvASKj6v6hj/7eWgjnT/cVsR8CumieLoT+g900exWeNogqtweI8dxloXN9BDQTYro1oWu/5CQ==", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "node_modules/colorette": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", - "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==" - }, - "node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" - }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" - }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/concat-stream/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/concat-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/concat-stream/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/concat-with-sourcemaps": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz", - "integrity": "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==", - "dependencies": { - "source-map": "^0.6.1" - } - }, - "node_modules/concat-with-sourcemaps/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/configstore": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "dev": true, - "dependencies": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/configstore/node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/connect": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", - "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", - "dependencies": { - "debug": "2.6.9", - "finalhandler": "1.1.2", - "parseurl": "~1.3.3", - "utils-merge": "1.0.1" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/consola": { - "version": "2.15.3", - "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", - "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==" - }, - "node_modules/console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==" - }, - "node_modules/consolidate": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.15.1.tgz", - "integrity": "sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==", - "dependencies": { - "bluebird": "^3.1.1" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=" - }, - "node_modules/convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dependencies": { - "safe-buffer": "~5.1.1" - } - }, - "node_modules/convert-source-map/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-universal": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/cookie-universal/-/cookie-universal-2.1.5.tgz", - "integrity": "sha512-nqOOmEkovCQxNYGIyzhcwsmh4c7xnxe7RWdiYFOoml9MP4L32IlU3LdPC7r7nQEnnM+9Uxlk/UhtvBl5is6M/w==", - "dependencies": { - "@types/cookie": "^0.3.3", - "cookie": "^0.4.0" - } - }, - "node_modules/cookie-universal-nuxt": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/cookie-universal-nuxt/-/cookie-universal-nuxt-2.1.5.tgz", - "integrity": "sha512-P0WCTKIyemWNtHi9lxrS5cxZmieOIEjt28B7Alu6cdSB9RqtUtpkqYyV9PRK6oJrT5eIPDYjHsJQlh6SUrFJOg==", - "dependencies": { - "@types/cookie": "^0.3.3", - "cookie-universal": "^2.1.5" - } - }, - "node_modules/copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dependencies": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/core-js": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", - "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", - "deprecated": "core-js@<3.4 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Please, upgrade your dependencies to the actual version of core-js.", - "hasInstallScript": true - }, - "node_modules/core-js-compat": { - "version": "3.21.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.21.1.tgz", - "integrity": "sha512-gbgX5AUvMb8gwxC7FLVWYT7Kkgu/y7+h/h1X43yJkNqhlK2fuYyQimqvKGNZFAY6CKii/GFKJ2cp/1/42TN36g==", - "dependencies": { - "browserslist": "^4.19.1", - "semver": "7.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-compat/node_modules/semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "node_modules/cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dependencies": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cosmiconfig/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dependencies": { - "buffer": "^5.1.0" - } - }, - "node_modules/crc/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "node_modules/create-ecdh/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" - }, - "node_modules/cross-env": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", - "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "bin": { - "cross-env": "src/bin/cross-env.js", - "cross-env-shell": "src/bin/cross-env-shell.js" - }, - "engines": { - "node": ">=10.14", - "npm": ">=6", - "yarn": ">=1" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dependencies": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - }, - "engines": { - "node": "*" - } - }, - "node_modules/crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/css-blank-pseudo": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz", - "integrity": "sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w==", - "dependencies": { - "postcss": "^7.0.5" - }, - "bin": { - "css-blank-pseudo": "cli.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/css-blank-pseudo/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/css-blank-pseudo/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/css-blank-pseudo/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/css-color-names": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", - "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", - "engines": { - "node": "*" - } - }, - "node_modules/css-declaration-sorter": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", - "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", - "dependencies": { - "postcss": "^7.0.1", - "timsort": "^0.3.0" - }, - "engines": { - "node": ">4" - } - }, - "node_modules/css-declaration-sorter/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/css-declaration-sorter/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/css-declaration-sorter/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/css-has-pseudo": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz", - "integrity": "sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ==", - "dependencies": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^5.0.0-rc.4" - }, - "bin": { - "css-has-pseudo": "cli.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/css-has-pseudo/node_modules/cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/css-has-pseudo/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/css-has-pseudo/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/css-has-pseudo/node_modules/postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "dependencies": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/css-has-pseudo/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/css-loader": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-4.3.0.tgz", - "integrity": "sha512-rdezjCjScIrsL8BSYszgT4s476IcNKt6yX69t0pHjJVnPUTDpn4WfIpDQTN3wCJvUvfsz/mFjuGOekf3PY3NUg==", - "dependencies": { - "camelcase": "^6.0.0", - "cssesc": "^3.0.0", - "icss-utils": "^4.1.1", - "loader-utils": "^2.0.0", - "postcss": "^7.0.32", - "postcss-modules-extract-imports": "^2.0.0", - "postcss-modules-local-by-default": "^3.0.3", - "postcss-modules-scope": "^2.2.0", - "postcss-modules-values": "^3.0.0", - "postcss-value-parser": "^4.1.0", - "schema-utils": "^2.7.1", - "semver": "^7.3.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.27.0 || ^5.0.0" - } - }, - "node_modules/css-loader/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/css-loader/node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/css-loader/node_modules/loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/css-loader/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/css-loader/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/css-loader/node_modules/schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "dependencies": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/css-loader/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/css-prefers-color-scheme": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz", - "integrity": "sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg==", - "dependencies": { - "postcss": "^7.0.5" - }, - "bin": { - "css-prefers-color-scheme": "cli.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/css-prefers-color-scheme/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/css-prefers-color-scheme/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/css-prefers-color-scheme/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/css-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", - "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^3.2.1", - "domutils": "^1.7.0", - "nth-check": "^1.0.2" - } - }, - "node_modules/css-select-base-adapter": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", - "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" - }, - "node_modules/css-tree": { - "version": "1.0.0-alpha.37", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", - "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", - "dependencies": { - "mdn-data": "2.0.4", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/css-tree/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/css-what": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", - "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/cssdb": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-4.4.0.tgz", - "integrity": "sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ==" - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cssnano": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.11.tgz", - "integrity": "sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==", - "dependencies": { - "cosmiconfig": "^5.0.0", - "cssnano-preset-default": "^4.0.8", - "is-resolvable": "^1.0.0", - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/cssnano-preset-default": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz", - "integrity": "sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==", - "dependencies": { - "css-declaration-sorter": "^4.0.1", - "cssnano-util-raw-cache": "^4.0.1", - "postcss": "^7.0.0", - "postcss-calc": "^7.0.1", - "postcss-colormin": "^4.0.3", - "postcss-convert-values": "^4.0.1", - "postcss-discard-comments": "^4.0.2", - "postcss-discard-duplicates": "^4.0.2", - "postcss-discard-empty": "^4.0.1", - "postcss-discard-overridden": "^4.0.1", - "postcss-merge-longhand": "^4.0.11", - "postcss-merge-rules": "^4.0.3", - "postcss-minify-font-values": "^4.0.2", - "postcss-minify-gradients": "^4.0.2", - "postcss-minify-params": "^4.0.2", - "postcss-minify-selectors": "^4.0.2", - "postcss-normalize-charset": "^4.0.1", - "postcss-normalize-display-values": "^4.0.2", - "postcss-normalize-positions": "^4.0.2", - "postcss-normalize-repeat-style": "^4.0.2", - "postcss-normalize-string": "^4.0.2", - "postcss-normalize-timing-functions": "^4.0.2", - "postcss-normalize-unicode": "^4.0.1", - "postcss-normalize-url": "^4.0.1", - "postcss-normalize-whitespace": "^4.0.2", - "postcss-ordered-values": "^4.1.2", - "postcss-reduce-initial": "^4.0.3", - "postcss-reduce-transforms": "^4.0.2", - "postcss-svgo": "^4.0.3", - "postcss-unique-selectors": "^4.0.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/cssnano-preset-default/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/cssnano-preset-default/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/cssnano-preset-default/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cssnano-util-get-arguments": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", - "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/cssnano-util-get-match": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", - "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/cssnano-util-raw-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", - "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", - "dependencies": { - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/cssnano-util-raw-cache/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/cssnano-util-raw-cache/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/cssnano-util-raw-cache/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cssnano-util-same-parent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", - "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/cssnano/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/cssnano/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/cssnano/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "dependencies": { - "css-tree": "^1.1.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/csso/node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" - }, - "node_modules/csso/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cuint": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", - "integrity": "sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs=" - }, - "node_modules/cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=" - }, - "node_modules/de-indent": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", - "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=" - }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/deepmerge": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.3.2.tgz", - "integrity": "sha1-FmNpFinU2/42T6EqKk8KqGqjoFA=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true - }, - "node_modules/define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dependencies": { - "object-keys": "^1.0.12" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/defu": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/defu/-/defu-5.0.1.tgz", - "integrity": "sha512-EPS1carKg+dkEVy3qNTqIdp2qV7mUP08nIsupfwQpz++slCVRw7qbQyWvSTig+kFPwz2XXp5/kIIkH+CwrJKkQ==" - }, - "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/destr": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/destr/-/destr-1.1.0.tgz", - "integrity": "sha512-Ev/sqS5AzzDwlpor/5wFCDu0dYMQu/0x2D6XfAsQ0E7uQmamIgYJ6Dppo2T2EOFVkeVYWjc+PCLKaqZZ57qmLg==" - }, - "node_modules/destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "node_modules/detect-indent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", - "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=", - "engines": { - "node": ">=4" - } - }, - "node_modules/devalue": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/devalue/-/devalue-2.0.1.tgz", - "integrity": "sha512-I2TiqT5iWBEyB8GRfTDP0hiLZ0YeDJZ+upDxjBfOC2lebO5LezQMv7QvIUTzdb64jQyAKLf1AHADtGN+jw6v8Q==" - }, - "node_modules/diacritics-map": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/diacritics-map/-/diacritics-map-0.1.0.tgz", - "integrity": "sha1-bfwP+dAQAKLt8oZTccrDFulJd68=", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/diff-match-patch": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz", - "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==" - }, - "node_modules/diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "node_modules/diffie-hellman/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "dependencies": { - "utila": "~0.4" - } - }, - "node_modules/dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", - "dependencies": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - } - }, - "node_modules/dom-serializer/node_modules/domelementtype": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", - "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/dom-serializer/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "engines": { - "node": ">=0.4", - "npm": ">=1.2" - } - }, - "node_modules/domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "node_modules/domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "dependencies": { - "domelementtype": "1" - } - }, - "node_modules/domready": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/domready/-/domready-1.0.8.tgz", - "integrity": "sha1-kfJS5Ze2Wvd+dFriTdAYXV4m1Yw=" - }, - "node_modules/domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "dependencies": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "node_modules/dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dotenv": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", - "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", - "engines": { - "node": ">=10" - } - }, - "node_modules/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" - }, - "node_modules/duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true - }, - "node_modules/duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dependencies": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "node_modules/duplexify/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/duplexify/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/duplexify/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "node_modules/electron-to-chromium": { - "version": "1.4.71", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.71.tgz", - "integrity": "sha512-Hk61vXXKRb2cd3znPE9F+2pLWdIOmP7GjiTj45y6L3W/lO+hSnUSUhq+6lEaERWBdZOHbk2s3YV5c9xVl3boVw==" - }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/enhanced-resolve": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", - "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", - "dependencies": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "node_modules/errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "dependencies": { - "prr": "~1.0.1" - }, - "bin": { - "errno": "cli.js" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/error-stack-parser": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.7.tgz", - "integrity": "sha512-chLOW0ZGRf4s8raLrDxa5sdkvPec5YdvwbFnqJme4rk0rFajP8mPtrDL1+I+CwrQDCjswDA5sREX7jYQDQs9vA==", - "dependencies": { - "stackframe": "^1.1.1" - } - }, - "node_modules/es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", - "dependencies": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-goat": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", - "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/eslint": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.9.0.tgz", - "integrity": "sha512-PB09IGwv4F4b0/atrbcMFboF/giawbBLVC7fyDamk5Wtey4Jh2K+rYaBhCAbUyEI4QzB1ly09Uglc9iCtFaG2Q==", - "dev": true, - "dependencies": { - "@eslint/eslintrc": "^1.1.0", - "@humanwhocodes/config-array": "^0.9.2", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.6.0", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-prettier": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.4.0.tgz", - "integrity": "sha512-CFotdUcMY18nGRo5KGsnNxpznzhkopOcOo0InID+sgQssPrzjvsyKZPvOgymTFeHrFuC3Tzdf2YndhXtULK9Iw==", - "dev": true, - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-loader": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-4.0.2.tgz", - "integrity": "sha512-EDpXor6lsjtTzZpLUn7KmXs02+nIjGcgees9BYjNkWra3jVq5vVa8IoCKgzT2M7dNNeoMBtaSG83Bd40N3poLw==", - "deprecated": "This loader has been deprecated. Please use eslint-webpack-plugin", - "dev": true, - "dependencies": { - "find-cache-dir": "^3.3.1", - "fs-extra": "^8.1.0", - "loader-utils": "^2.0.0", - "object-hash": "^2.0.3", - "schema-utils": "^2.6.5" - }, - "engines": { - "node": ">= 10.13.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0", - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/eslint-loader/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/eslint-loader/node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint-loader/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/eslint-loader/node_modules/loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "dev": true, - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/eslint-loader/node_modules/schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/eslint-loader/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz", - "integrity": "sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==", - "dev": true, - "dependencies": { - "prettier-linter-helpers": "^1.0.0" - }, - "engines": { - "node": ">=6.0.0" - }, - "peerDependencies": { - "eslint": ">=7.28.0", - "prettier": ">=2.0.0" - }, - "peerDependenciesMeta": { - "eslint-config-prettier": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-vue": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-8.4.1.tgz", - "integrity": "sha512-nmWOhNmDx9TZ+yP9ZhezTkZUupSHsYA2TocRm+efPSXMOyFrVczVlaIuQcLBjCtI8CbkBiUQ3VcyQsjlIhDrhA==", - "dev": true, - "dependencies": { - "eslint-utils": "^3.0.0", - "natural-compare": "^1.4.0", - "semver": "^7.3.5", - "vue-eslint-parser": "^8.0.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dependencies": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/eslint/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/eslint/node_modules/globals": { - "version": "13.12.1", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", - "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/eslint/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/espree": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", - "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", - "dev": true, - "dependencies": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/eventsource-polyfill": { - "version": "0.9.6", - "resolved": "https://registry.npmjs.org/eventsource-polyfill/-/eventsource-polyfill-0.9.6.tgz", - "integrity": "sha1-EODRh/ERsWfyj9q5GIQ859gY8Tw=" - }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dependencies": { - "fill-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-range/node_modules/fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dependencies": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-range/node_modules/is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-range/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-range/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extract-css-chunks-webpack-plugin": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/extract-css-chunks-webpack-plugin/-/extract-css-chunks-webpack-plugin-4.9.0.tgz", - "integrity": "sha512-HNuNPCXRMqJDQ1OHAUehoY+0JVCnw9Y/H22FQzYVwo8Ulgew98AGDu0grnY5c7xwiXHjQa6yJ/1dxLCI/xqTyQ==", - "dependencies": { - "loader-utils": "^2.0.0", - "normalize-url": "1.9.1", - "schema-utils": "^1.0.0", - "webpack-sources": "^1.1.0" - }, - "engines": { - "node": ">= 6.9.0" - }, - "peerDependencies": { - "webpack": "^4.4.0 || ^5.0.0" - } - }, - "node_modules/extract-css-chunks-webpack-plugin/node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/extract-css-chunks-webpack-plugin/node_modules/loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/extract-css-chunks-webpack-plugin/node_modules/normalize-url": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", - "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", - "dependencies": { - "object-assign": "^4.0.1", - "prepend-http": "^1.0.0", - "query-string": "^4.1.0", - "sort-keys": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/extract-css-chunks-webpack-plugin/node_modules/schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==" - }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/file-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", - "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", - "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/file-loader/node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/file-loader/node_modules/loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/filter-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", - "integrity": "sha1-mzERErxsYSehbgFsbF1/GeCAXFs=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "bin": { - "flat": "cli.js" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", - "dev": true - }, - "node_modules/flatten": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz", - "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==", - "deprecated": "flatten is deprecated in favor of utility frameworks such as lodash." - }, - "node_modules/flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dependencies": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - } - }, - "node_modules/flush-write-stream/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/flush-write-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/flush-write-stream/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dependencies": { - "map-cache": "^0.2.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dependencies": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, - "node_modules/from2/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/from2/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/from2/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/fs": { - "version": "0.0.1-security", - "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", - "integrity": "sha1-invTcYa23d84E/I4WLV+yq9eQdQ=" - }, - "node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/fs-memo": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fs-memo/-/fs-memo-1.2.0.tgz", - "integrity": "sha512-YEexkCpL4j03jn5SxaMHqcO6IuWuqm8JFUYhyCep7Ao89JIYmB8xoKhK7zXXJ9cCaNXpyNH5L3QtAmoxjoHW2w==" - }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs-monkey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", - "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==" - }, - "node_modules/fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dependencies": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - } - }, - "node_modules/fs-write-stream-atomic/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/fs-write-stream-atomic/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/fs-write-stream-atomic/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-port-please": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/get-port-please/-/get-port-please-2.3.0.tgz", - "integrity": "sha512-zO6ST8v7jBO+uSnm0vaQuZEpdr7DgY9iMgoMLUC+Zfz31HYoDiiQrL78oZspaAryT6NH903Bwk+mYxiCy3X/RQ==", - "dependencies": { - "fs-memo": "^1.2.0" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/git-config-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/git-config-path/-/git-config-path-2.0.0.tgz", - "integrity": "sha512-qc8h1KIQbJpp+241id3GuAtkdyJ+IK+LIVtkiFTRKRrmddDzs3SI9CvP1QYmWBFvm1I/PWRwj//of8bgAc0ltA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/git-up": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/git-up/-/git-up-4.0.5.tgz", - "integrity": "sha512-YUvVDg/vX3d0syBsk/CKUTib0srcQME0JyHkL5BaYdwLsiCslPWmDSi8PUMo9pXYjrryMcmsCoCgsTpSCJEQaA==", - "dependencies": { - "is-ssh": "^1.3.0", - "parse-url": "^6.0.0" - } - }, - "node_modules/git-url-parse": { - "version": "11.6.0", - "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-11.6.0.tgz", - "integrity": "sha512-WWUxvJs5HsyHL6L08wOusa/IXYtMuCAhrMmnTjQPpBU0TTHyDhnOATNH3xNQz7YOQUsqIIPTGr4xiVti1Hsk5g==", - "dependencies": { - "git-up": "^4.0.0" - } - }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/global-dirs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", - "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", - "dev": true, - "dependencies": { - "ini": "2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/global-dirs/node_modules/ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, - "dependencies": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/got/node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==" - }, - "node_modules/gray-matter": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-2.1.1.tgz", - "integrity": "sha1-MELZrewqHe1qdwep7SOA+KF6Qw4=", - "dependencies": { - "ansi-red": "^0.1.1", - "coffee-script": "^1.12.4", - "extend-shallow": "^2.0.1", - "js-yaml": "^3.8.1", - "toml": "^2.3.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gray-matter/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/gulp-header": { - "version": "1.8.12", - "resolved": "https://registry.npmjs.org/gulp-header/-/gulp-header-1.8.12.tgz", - "integrity": "sha512-lh9HLdb53sC7XIZOYzTXM4lFuXElv3EVkSDhsd7DoJBj7hm+Ni7D3qYbb+Rr8DuM8nRanBvkVO9d7askreXGnQ==", - "deprecated": "Removed event-stream from gulp-header", - "dependencies": { - "concat-with-sourcemaps": "*", - "lodash.template": "^4.4.0", - "through2": "^2.0.0" - } - }, - "node_modules/gzip-size": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", - "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", - "dependencies": { - "duplexer": "^0.1.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/hable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hable/-/hable-3.0.0.tgz", - "integrity": "sha512-7+G0/2/COR8pwteYFqHIVYfQpuEiO2HXwJrhCBJVgrNrl9O5eaUoJVDGXUJX+0RpGncNVTuestexjk1afj01wQ==" - }, - "node_modules/hard-source-webpack-plugin": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/hard-source-webpack-plugin/-/hard-source-webpack-plugin-0.13.1.tgz", - "integrity": "sha512-r9zf5Wq7IqJHdVAQsZ4OP+dcUSvoHqDMxJlIzaE2J0TZWn3UjMMrHqwDHR8Jr/pzPfG7XxSe36E7Y8QGNdtuAw==", - "dependencies": { - "chalk": "^2.4.1", - "find-cache-dir": "^2.0.0", - "graceful-fs": "^4.1.11", - "lodash": "^4.15.0", - "mkdirp": "^0.5.1", - "node-object-hash": "^1.2.0", - "parse-json": "^4.0.0", - "pkg-dir": "^3.0.0", - "rimraf": "^2.6.2", - "semver": "^5.6.0", - "tapable": "^1.0.0-beta.5", - "webpack-sources": "^1.0.1", - "write-json-file": "^2.3.0" - }, - "engines": { - "node": ">=8.0.0" - }, - "peerDependencies": { - "webpack": "*" - } - }, - "node_modules/hard-source-webpack-plugin/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hard-source-webpack-plugin/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hard-source-webpack-plugin/node_modules/find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/hard-source-webpack-plugin/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/hard-source-webpack-plugin/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/hard-source-webpack-plugin/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/hard-source-webpack-plugin/node_modules/make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/hard-source-webpack-plugin/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/hard-source-webpack-plugin/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "engines": { - "node": ">=4" - } - }, - "node_modules/hard-source-webpack-plugin/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "engines": { - "node": ">=6" - } - }, - "node_modules/hard-source-webpack-plugin/node_modules/pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/hard-source-webpack-plugin/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/hard-source-webpack-plugin/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-yarn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", - "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hash-sum": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz", - "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==" - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", - "dependencies": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "bin": { - "he": "bin/he" - } - }, - "node_modules/hex-color-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", - "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" - }, - "node_modules/highlight.js": { - "version": "11.4.0", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.4.0.tgz", - "integrity": "sha512-nawlpCBCSASs7EdvZOYOYVkJpGmAOKMYZgZtUqSRqodZE0GRVcFKwo1RcpeOemqh9hyttTdd5wDBwHkuSyUfnA==", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/hsl-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", - "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=" - }, - "node_modules/hsla-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", - "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=" - }, - "node_modules/html-entities": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.2.tgz", - "integrity": "sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ==" - }, - "node_modules/html-minifier": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-4.0.0.tgz", - "integrity": "sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==", - "dependencies": { - "camel-case": "^3.0.0", - "clean-css": "^4.2.1", - "commander": "^2.19.0", - "he": "^1.2.0", - "param-case": "^2.1.1", - "relateurl": "^0.2.7", - "uglify-js": "^3.5.1" - }, - "bin": { - "html-minifier": "cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/html-minifier-terser": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", - "integrity": "sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg==", - "dependencies": { - "camel-case": "^4.1.1", - "clean-css": "^4.2.3", - "commander": "^4.1.1", - "he": "^1.2.0", - "param-case": "^3.0.3", - "relateurl": "^0.2.7", - "terser": "^4.6.3" - }, - "bin": { - "html-minifier-terser": "cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/html-minifier/node_modules/camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", - "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", - "dependencies": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" - } - }, - "node_modules/html-minifier/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "node_modules/html-minifier/node_modules/lower-case": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=" - }, - "node_modules/html-minifier/node_modules/no-case": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", - "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", - "dependencies": { - "lower-case": "^1.1.1" - } - }, - "node_modules/html-minifier/node_modules/param-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", - "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", - "dependencies": { - "no-case": "^2.2.0" - } - }, - "node_modules/html-tags": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz", - "integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=", - "engines": { - "node": ">=4" - } - }, - "node_modules/html-webpack-plugin": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.5.2.tgz", - "integrity": "sha512-q5oYdzjKUIPQVjOosjgvCHQOv9Ett9CYYHlgvJeXG0qQvdSojnBq4vAdQBwn1+yGveAwHCoe/rMR86ozX3+c2A==", - "dependencies": { - "@types/html-minifier-terser": "^5.0.0", - "@types/tapable": "^1.0.5", - "@types/webpack": "^4.41.8", - "html-minifier-terser": "^5.0.1", - "loader-utils": "^1.2.3", - "lodash": "^4.17.20", - "pretty-error": "^2.1.1", - "tapable": "^1.1.3", - "util.promisify": "1.0.0" - }, - "engines": { - "node": ">=6.9" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/html-webpack-plugin/node_modules/util.promisify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", - "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", - "dependencies": { - "define-properties": "^1.1.2", - "object.getownpropertydescriptors": "^2.0.3" - } - }, - "node_modules/htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "dependencies": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "node_modules/http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, - "node_modules/http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/http-proxy-middleware": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-1.3.1.tgz", - "integrity": "sha512-13eVVDYS4z79w7f1+NPllJtOQFx/FdUW4btIvVRMaRlUY9VGstAbo5MOhLEuUgZFRHn3x50ufn25zkj/boZnEg==", - "dependencies": { - "@types/http-proxy": "^1.17.5", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/icss-utils": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", - "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", - "dependencies": { - "postcss": "^7.0.14" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/icss-utils/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/icss-utils/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/icss-utils/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" - }, - "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", - "dev": true - }, - "node_modules/image-size": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", - "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=", - "bin": { - "image-size": "bin/image-size.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/immutable": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz", - "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==", - "dev": true - }, - "node_modules/import-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", - "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", - "dependencies": { - "import-from": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", - "dependencies": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/import-from": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", - "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", - "dependencies": { - "resolve-from": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/indexes-of": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=" - }, - "node_modules/infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "node_modules/inquirer": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", - "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", - "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.19", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.6.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/inquirer/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/inquirer/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/inquirer/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/inquirer/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/inquirer/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/inquirer/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/inquirer/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/inquirer/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dependencies": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" - }, - "node_modules/is-absolute-url": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", - "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "node_modules/is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "dependencies": { - "ci-info": "^2.0.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, - "node_modules/is-ci/node_modules/ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "node_modules/is-color-stop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", - "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", - "dependencies": { - "css-color-names": "^0.0.4", - "hex-color-regex": "^1.1.0", - "hsl-regex": "^1.0.0", - "hsla-regex": "^1.0.0", - "rgb-regex": "^1.0.1", - "rgba-regex": "^1.0.0" - } - }, - "node_modules/is-core-module": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", - "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-descriptor/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "dev": true, - "dependencies": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-npm": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", - "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==" - }, - "node_modules/is-retry-allowed": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz", - "integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-ssh": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.3.3.tgz", - "integrity": "sha512-NKzJmQzJfEEma3w5cJNcUMxoXfDjz0Zj0eyCalHn2E6VOwlzjZo0yuO2fcBSf8zhFuVCL/82/r5gRcoi6aEPVQ==", - "dependencies": { - "protocols": "^1.1.0" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/is-yarn-global": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", - "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", - "dev": true - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/jest-worker/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jimp-compact": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/jimp-compact/-/jimp-compact-0.16.1.tgz", - "integrity": "sha512-dZ6Ra7u1G8c4Letq/B5EzAxj4tLFHL+cGtdpR+PVm4yzPDj+lCk+AbivWt1eOM+ikzkowtyV7qSqX6qr3t71Ww==" - }, - "node_modules/jiti": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.13.0.tgz", - "integrity": "sha512-/n9mNxZj/HDSrincJ6RP+L+yXbpnB8FybySBa+IjIaoH9FIxBbrbRT5XUbe8R7zuVM2AQqNMNDDqz0bzx3znOQ==", - "bin": { - "jiti": "bin/jiti.js" - } - }, - "node_modules/js-base64": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", - "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==" - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/js-yaml/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", - "dev": true - }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.0" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/klona": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz", - "integrity": "sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/last-call-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w==", - "dependencies": { - "lodash": "^4.17.5", - "webpack-sources": "^1.1.0" - } - }, - "node_modules/latest-version": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", - "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", - "dev": true, - "dependencies": { - "package-json": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/launch-editor": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.3.0.tgz", - "integrity": "sha512-3QrsCXejlWYHjBPFXTyGNhPj4rrQdB+5+r5r3wArpLH201aR+nWUgw/zKKkTmilCfY/sv6u8qo98pNvtg8LUTA==", - "dependencies": { - "picocolors": "^1.0.0", - "shell-quote": "^1.6.1" - } - }, - "node_modules/launch-editor-middleware": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/launch-editor-middleware/-/launch-editor-middleware-2.3.0.tgz", - "integrity": "sha512-GJR64trLdFFwCoL9DMn/d1SZX0OzTDPixu4mcfWTShQ4tIqCHCGvlg9fOEYQXyBlrSMQwylsJfUWncheShfV2w==", - "dependencies": { - "launch-editor": "^2.3.0" - } - }, - "node_modules/lazy-cache": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz", - "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=", - "dependencies": { - "set-getter": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/linkify-it": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", - "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", - "dependencies": { - "uc.micro": "^1.0.1" - } - }, - "node_modules/list-item": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/list-item/-/list-item-1.1.1.tgz", - "integrity": "sha1-DGXQDih8tmPMs8s4Sad+iewmilY=", - "dependencies": { - "expand-range": "^1.8.1", - "extend-shallow": "^2.0.1", - "is-number": "^2.1.0", - "repeat-string": "^1.5.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/list-item/node_modules/is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/list-item/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/loader-runner": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", - "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", - "engines": { - "node": ">=6.11.5" - } - }, - "node_modules/loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" - }, - "node_modules/lodash.kebabcase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", - "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=" - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "dependencies": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "node_modules/lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "dependencies": { - "lodash._reinterpolate": "^3.0.0" - } - }, - "node_modules/lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" - }, - "node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dependencies": { - "tslib": "^2.0.3" - } - }, - "node_modules/lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "dependencies": { - "p-defer": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/markdown-it": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz", - "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==", - "dependencies": { - "argparse": "^1.0.7", - "entities": "~1.1.1", - "linkify-it": "^2.0.0", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - }, - "bin": { - "markdown-it": "bin/markdown-it.js" - } - }, - "node_modules/markdown-link": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/markdown-link/-/markdown-link-0.1.1.tgz", - "integrity": "sha1-MsXGUZmmRXMWMi0eQinRNAfIx88=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/markdown-toc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/markdown-toc/-/markdown-toc-1.2.0.tgz", - "integrity": "sha512-eOsq7EGd3asV0oBfmyqngeEIhrbkc7XVP63OwcJBIhH2EpG2PzFcbZdhy1jutXSlRBBVMNXHvMtSr5LAxSUvUg==", - "dependencies": { - "concat-stream": "^1.5.2", - "diacritics-map": "^0.1.0", - "gray-matter": "^2.1.0", - "lazy-cache": "^2.0.2", - "list-item": "^1.1.1", - "markdown-link": "^0.1.1", - "minimist": "^1.2.0", - "mixin-deep": "^1.1.3", - "object.pick": "^1.2.0", - "remarkable": "^1.7.1", - "repeat-string": "^1.6.1", - "strip-color": "^0.1.0" - }, - "bin": { - "markdown-toc": "cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==" - }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/mdn-data": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", - "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" - }, - "node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" - }, - "node_modules/mem": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/mem/-/mem-8.1.1.tgz", - "integrity": "sha512-qFCFUDs7U3b8mBDPyz5EToEKoAkgCzqquIgi9nkkR9bixxOVOre+09lbuH7+9Kn2NFpm56M3GUWVbU2hQgdACA==", - "dependencies": { - "map-age-cleaner": "^0.1.3", - "mimic-fn": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/mem?sponsor=1" - } - }, - "node_modules/mem/node_modules/mimic-fn": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", - "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/memfs": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.1.tgz", - "integrity": "sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw==", - "dependencies": { - "fs-monkey": "1.0.3" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dependencies": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "engines": { - "node": ">=4.3.0 <5.0.0 || >=5.10" - } - }, - "node_modules/memory-fs/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/memory-fs/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/memory-fs/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/merge-options": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-1.0.1.tgz", - "integrity": "sha512-iuPV41VWKWBIOpBsjoxjDZw8/GbSfZ2mk7N1453bwMrfzdrIk7EzBd+8UVR6rkw67th7xnk9Dytl3J+lHPdxvg==", - "dependencies": { - "is-plain-obj": "^1.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/merge-options/node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/merge-source-map": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", - "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", - "dependencies": { - "source-map": "^0.6.1" - } - }, - "node_modules/merge-source-map/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "bin": { - "miller-rabin": "bin/miller-rabin" - } - }, - "node_modules/miller-rabin/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", - "dependencies": { - "mime-db": "1.51.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types/node_modules/mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "node_modules/minipass": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", - "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dependencies": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/mitt": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.1.2.tgz", - "integrity": "sha1-OA5hSA1qYVtmDwertg1R4KTkvtY=" - }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mixin-deep/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dependencies": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "node_modules/mrmime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.0.tgz", - "integrity": "sha512-a70zx7zFfVO7XpnQ2IX1Myh9yY4UYvfld/dikWRnsXxbyvMcfz+u6UfgNAtH+k2QqtJuzVpv6eLTx1G2+WKZbQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/mustache": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-2.3.2.tgz", - "integrity": "sha512-KpMNwdQsYz3O/SBS1qJ/o3sqUJ5wSb8gb0pul8CO0S56b9Y2ALm8zCfsjPXsqGFfoNBkDwZuZIAjhsZI03gYVQ==", - "bin": { - "mustache": "bin/mustache" - }, - "engines": { - "npm": ">=1.4.0" - } - }, - "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" - }, - "node_modules/nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-html-parser": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-3.3.6.tgz", - "integrity": "sha512-VkWDHvNgFGB3mbQGMyzqRE1i/BG7TKX9wRXC8e/v8kL0kZR/Oy6RjYxXH91K6/+m3g8iQ8dTqRy75lTYoA2Cjg==", - "dependencies": { - "css-select": "^4.1.3", - "he": "1.2.0" - } - }, - "node_modules/node-html-parser/node_modules/css-select": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.2.1.tgz", - "integrity": "sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^5.1.0", - "domhandler": "^4.3.0", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/node-html-parser/node_modules/css-what": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", - "integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/node-html-parser/node_modules/dom-serializer": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", - "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/node-html-parser/node_modules/domelementtype": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", - "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/node-html-parser/node_modules/domhandler": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz", - "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==", - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/node-html-parser/node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/node-html-parser/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/node-html-parser/node_modules/nth-check": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", - "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dependencies": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - } - }, - "node_modules/node-libs-browser/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - }, - "node_modules/node-libs-browser/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/node-libs-browser/node_modules/readable-stream/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/node-libs-browser/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/node-object-hash": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/node-object-hash/-/node-object-hash-1.4.2.tgz", - "integrity": "sha512-UdS4swXs85fCGWWf6t6DMGgpN/vnlKeSGEQ7hJcrs7PBFoxoKLmibc3QRb7fwiYsjdL7PX8iI/TMSlZ90dgHhQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/node-releases": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", - "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==" - }, - "node_modules/node-res": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/node-res/-/node-res-5.0.1.tgz", - "integrity": "sha512-YOleO9c7MAqoHC+Ccu2vzvV1fL6Ku49gShq3PIMKWHRgrMSih3XcwL05NbLBi6oU2J471gTBfdpVVxwT6Pfhxg==", - "dependencies": { - "destroy": "^1.0.4", - "etag": "^1.8.1", - "mime-types": "^2.1.19", - "on-finished": "^2.3.0", - "vary": "^1.1.2" - } - }, - "node_modules/nodemon": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.15.tgz", - "integrity": "sha512-gdHMNx47Gw7b3kWxJV64NI+Q5nfl0y5DgDbiVtShiwa7Z0IZ07Ll4RLFo6AjrhzMtoEZn5PDE3/c2AbVsiCkpA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "chokidar": "^3.5.2", - "debug": "^3.2.7", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.0.4", - "pstree.remy": "^1.1.8", - "semver": "^5.7.1", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.5", - "update-notifier": "^5.1.0" - }, - "bin": { - "nodemon": "bin/nodemon.js" - }, - "engines": { - "node": ">=8.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nodemon" - } - }, - "node_modules/nodemon/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/nodemon/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/nodemon/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/nodemon/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", - "dev": true, - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "*" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-url": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", - "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", - "dependencies": { - "boolbase": "~1.0.0" - } - }, - "node_modules/num2fraction": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=" - }, - "node_modules/nuxt": { - "version": "2.15.8", - "resolved": "https://registry.npmjs.org/nuxt/-/nuxt-2.15.8.tgz", - "integrity": "sha512-ceK3qLg/Baj7J8mK9bIxqw9AavrF+LXqwYEreBdY/a4Sj8YV4mIvhqea/6E7VTCNNGvKT2sJ/TTJjtfQ597lTA==", - "hasInstallScript": true, - "dependencies": { - "@nuxt/babel-preset-app": "2.15.8", - "@nuxt/builder": "2.15.8", - "@nuxt/cli": "2.15.8", - "@nuxt/components": "^2.1.8", - "@nuxt/config": "2.15.8", - "@nuxt/core": "2.15.8", - "@nuxt/generator": "2.15.8", - "@nuxt/loading-screen": "^2.0.3", - "@nuxt/opencollective": "^0.3.2", - "@nuxt/server": "2.15.8", - "@nuxt/telemetry": "^1.3.3", - "@nuxt/utils": "2.15.8", - "@nuxt/vue-app": "2.15.8", - "@nuxt/vue-renderer": "2.15.8", - "@nuxt/webpack": "2.15.8" - }, - "bin": { - "nuxt": "bin/nuxt.js" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-hash": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", - "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.getownpropertydescriptors": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz", - "integrity": "sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - }, - "engines": { - "node": ">= 0.8" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/opener": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", - "bin": { - "opener": "bin/opener-bin.js" - } - }, - "node_modules/optimize-css-assets-webpack-plugin": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.8.tgz", - "integrity": "sha512-mgFS1JdOtEGzD8l+EuISqL57cKO+We9GcoiQEmdCWRqqck+FGNmYJtx9qfAPzEz+lRrlThWMuGDaRkI/yWNx/Q==", - "dependencies": { - "cssnano": "^4.1.10", - "last-call-webpack-plugin": "^3.0.0" - }, - "peerDependencies": { - "webpack": "^4.0.0" - } - }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=" - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", - "engines": { - "node": ">=4" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/package-json": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", - "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", - "dev": true, - "dependencies": { - "got": "^9.6.0", - "registry-auth-token": "^4.0.0", - "registry-url": "^5.0.0", - "semver": "^6.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/package-json/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" - }, - "node_modules/parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dependencies": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - } - }, - "node_modules/parallel-transform/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/parallel-transform/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/parallel-transform/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parent-module/node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "dependencies": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/parse-git-config": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/parse-git-config/-/parse-git-config-3.0.0.tgz", - "integrity": "sha512-wXoQGL1D+2COYWCD35/xbiKma1Z15xvZL8cI25wvxzled58V51SJM04Urt/uznS900iQor7QO04SgdfT/XlbuA==", - "dependencies": { - "git-config-path": "^2.0.0", - "ini": "^1.3.5" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/parse-path": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-4.0.3.tgz", - "integrity": "sha512-9Cepbp2asKnWTJ9x2kpw6Fe8y9JDbqwahGCTvklzd/cEq5C5JC59x2Xb0Kx+x0QZ8bvNquGO8/BWP0cwBHzSAA==", - "dependencies": { - "is-ssh": "^1.3.0", - "protocols": "^1.4.0", - "qs": "^6.9.4", - "query-string": "^6.13.8" - } - }, - "node_modules/parse-path/node_modules/query-string": { - "version": "6.14.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.14.1.tgz", - "integrity": "sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==", - "dependencies": { - "decode-uri-component": "^0.2.0", - "filter-obj": "^1.1.0", - "split-on-first": "^1.0.0", - "strict-uri-encode": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse-path/node_modules/strict-uri-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", - "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=", - "engines": { - "node": ">=4" - } - }, - "node_modules/parse-url": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-6.0.0.tgz", - "integrity": "sha512-cYyojeX7yIIwuJzledIHeLUBVJ6COVLeT4eF+2P6aKVzwvgKQPndCBv3+yQ7pcWjqToYwaligxzSYNNmGoMAvw==", - "dependencies": { - "is-ssh": "^1.3.0", - "normalize-url": "^6.1.0", - "parse-path": "^4.0.0", - "protocols": "^1.4.0" - } - }, - "node_modules/parse-url/node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==" - }, - "node_modules/path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "optional": true - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", - "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pnp-webpack-plugin": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.7.0.tgz", - "integrity": "sha512-2Rb3vm+EXble/sMXNSu6eoBx8e79gKqhNq9F5ZWW6ERNCTE/Q0wQNne5541tE5vKjfM8hpNCYL+LGc1YTfI0dg==", - "dependencies": { - "ts-pnp": "^1.1.6" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dependencies": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/postcss-attribute-case-insensitive": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz", - "integrity": "sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA==", - "dependencies": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^6.0.2" - } - }, - "node_modules/postcss-attribute-case-insensitive/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-attribute-case-insensitive/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-attribute-case-insensitive/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-calc": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.5.tgz", - "integrity": "sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==", - "dependencies": { - "postcss": "^7.0.27", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.0.2" - } - }, - "node_modules/postcss-calc/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-calc/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-calc/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-color-functional-notation": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz", - "integrity": "sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g==", - "dependencies": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-color-functional-notation/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-color-functional-notation/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-color-functional-notation/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-color-gray": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz", - "integrity": "sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw==", - "dependencies": { - "@csstools/convert-colors": "^1.4.0", - "postcss": "^7.0.5", - "postcss-values-parser": "^2.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-color-gray/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-color-gray/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-color-gray/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-color-hex-alpha": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz", - "integrity": "sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw==", - "dependencies": { - "postcss": "^7.0.14", - "postcss-values-parser": "^2.0.1" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-color-hex-alpha/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-color-hex-alpha/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-color-hex-alpha/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-color-mod-function": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz", - "integrity": "sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ==", - "dependencies": { - "@csstools/convert-colors": "^1.4.0", - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-color-mod-function/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-color-mod-function/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-color-mod-function/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-color-rebeccapurple": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz", - "integrity": "sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g==", - "dependencies": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-color-rebeccapurple/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-color-rebeccapurple/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-color-rebeccapurple/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-colormin": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", - "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", - "dependencies": { - "browserslist": "^4.0.0", - "color": "^3.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-colormin/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-colormin/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-colormin/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-colormin/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-convert-values": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", - "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", - "dependencies": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-convert-values/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-convert-values/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-convert-values/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-convert-values/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-custom-media": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz", - "integrity": "sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg==", - "dependencies": { - "postcss": "^7.0.14" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-custom-media/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-custom-media/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-custom-media/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-custom-properties": { - "version": "8.0.11", - "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz", - "integrity": "sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA==", - "dependencies": { - "postcss": "^7.0.17", - "postcss-values-parser": "^2.0.1" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-custom-properties/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-custom-properties/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-custom-properties/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-custom-selectors": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz", - "integrity": "sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w==", - "dependencies": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^5.0.0-rc.3" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-custom-selectors/node_modules/cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-custom-selectors/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-custom-selectors/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-custom-selectors/node_modules/postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "dependencies": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-custom-selectors/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-dir-pseudo-class": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz", - "integrity": "sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw==", - "dependencies": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^5.0.0-rc.3" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/postcss-dir-pseudo-class/node_modules/cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-dir-pseudo-class/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-dir-pseudo-class/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-dir-pseudo-class/node_modules/postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "dependencies": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-dir-pseudo-class/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-discard-comments": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", - "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", - "dependencies": { - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-discard-comments/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-discard-comments/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-discard-comments/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-discard-duplicates": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", - "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", - "dependencies": { - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-discard-duplicates/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-discard-duplicates/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-discard-duplicates/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-discard-empty": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", - "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", - "dependencies": { - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-discard-empty/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-discard-empty/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-discard-empty/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-discard-overridden": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", - "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", - "dependencies": { - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-discard-overridden/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-discard-overridden/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-discard-overridden/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-double-position-gradients": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz", - "integrity": "sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA==", - "dependencies": { - "postcss": "^7.0.5", - "postcss-values-parser": "^2.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-double-position-gradients/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-double-position-gradients/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-double-position-gradients/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-env-function": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-2.0.2.tgz", - "integrity": "sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw==", - "dependencies": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-env-function/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-env-function/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-env-function/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-focus-visible": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz", - "integrity": "sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g==", - "dependencies": { - "postcss": "^7.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-focus-visible/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-focus-visible/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-focus-visible/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-focus-within": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz", - "integrity": "sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w==", - "dependencies": { - "postcss": "^7.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-focus-within/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-focus-within/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-focus-within/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-font-variant": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-4.0.1.tgz", - "integrity": "sha512-I3ADQSTNtLTTd8uxZhtSOrTCQ9G4qUVKPjHiDk0bV75QSxXjVWiJVJ2VLdspGUi9fbW9BcjKJoRvxAH1pckqmA==", - "dependencies": { - "postcss": "^7.0.2" - } - }, - "node_modules/postcss-font-variant/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-font-variant/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-font-variant/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-gap-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz", - "integrity": "sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg==", - "dependencies": { - "postcss": "^7.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-gap-properties/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-gap-properties/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-gap-properties/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-image-set-function": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz", - "integrity": "sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw==", - "dependencies": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-image-set-function/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-image-set-function/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-image-set-function/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-import": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-12.0.1.tgz", - "integrity": "sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw==", - "dependencies": { - "postcss": "^7.0.1", - "postcss-value-parser": "^3.2.3", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-import-resolver": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-import-resolver/-/postcss-import-resolver-2.0.0.tgz", - "integrity": "sha512-y001XYgGvVwgxyxw9J1a5kqM/vtmIQGzx34g0A0Oy44MFcy/ZboZw1hu/iN3VYFjSTRzbvd7zZJJz0Kh0AGkTw==", - "dependencies": { - "enhanced-resolve": "^4.1.1" - } - }, - "node_modules/postcss-import/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-import/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-import/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-import/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-initial": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-3.0.4.tgz", - "integrity": "sha512-3RLn6DIpMsK1l5UUy9jxQvoDeUN4gP939tDcKUHD/kM8SGSKbFAnvkpFpj3Bhtz3HGk1jWY5ZNWX6mPta5M9fg==", - "dependencies": { - "postcss": "^7.0.2" - } - }, - "node_modules/postcss-initial/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-initial/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-initial/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-lab-function": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz", - "integrity": "sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg==", - "dependencies": { - "@csstools/convert-colors": "^1.4.0", - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-lab-function/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-lab-function/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-lab-function/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-load-config": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.2.tgz", - "integrity": "sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw==", - "dependencies": { - "cosmiconfig": "^5.0.0", - "import-cwd": "^2.0.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-loader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", - "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", - "dependencies": { - "loader-utils": "^1.1.0", - "postcss": "^7.0.0", - "postcss-load-config": "^2.0.0", - "schema-utils": "^1.0.0" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/postcss-loader/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-loader/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-loader/node_modules/schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/postcss-loader/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-logical": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-3.0.0.tgz", - "integrity": "sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA==", - "dependencies": { - "postcss": "^7.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-logical/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-logical/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-logical/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-media-minmax": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz", - "integrity": "sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw==", - "dependencies": { - "postcss": "^7.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-media-minmax/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-media-minmax/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-media-minmax/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-merge-longhand": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", - "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", - "dependencies": { - "css-color-names": "0.0.4", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "stylehacks": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-merge-longhand/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-merge-longhand/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-merge-longhand/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-merge-longhand/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-merge-rules": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", - "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", - "dependencies": { - "browserslist": "^4.0.0", - "caniuse-api": "^3.0.0", - "cssnano-util-same-parent": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0", - "vendors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-merge-rules/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-merge-rules/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-merge-rules/node_modules/postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dependencies": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/postcss-merge-rules/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-minify-font-values": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", - "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", - "dependencies": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-minify-font-values/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-minify-font-values/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-minify-font-values/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-minify-font-values/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-minify-gradients": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", - "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", - "dependencies": { - "cssnano-util-get-arguments": "^4.0.0", - "is-color-stop": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-minify-gradients/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-minify-gradients/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-minify-gradients/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-minify-gradients/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-minify-params": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", - "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", - "dependencies": { - "alphanum-sort": "^1.0.0", - "browserslist": "^4.0.0", - "cssnano-util-get-arguments": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "uniqs": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-minify-params/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-minify-params/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-minify-params/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-minify-params/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-minify-selectors": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", - "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", - "dependencies": { - "alphanum-sort": "^1.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-minify-selectors/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-minify-selectors/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-minify-selectors/node_modules/postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dependencies": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/postcss-minify-selectors/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-modules-extract-imports": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", - "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", - "dependencies": { - "postcss": "^7.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/postcss-modules-extract-imports/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-modules-extract-imports/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-modules-extract-imports/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-modules-local-by-default": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz", - "integrity": "sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==", - "dependencies": { - "icss-utils": "^4.1.1", - "postcss": "^7.0.32", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/postcss-modules-local-by-default/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-modules-local-by-default/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-modules-local-by-default/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-modules-scope": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", - "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", - "dependencies": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^6.0.0" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/postcss-modules-scope/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-modules-scope/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-modules-scope/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-modules-values": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", - "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", - "dependencies": { - "icss-utils": "^4.0.0", - "postcss": "^7.0.6" - } - }, - "node_modules/postcss-modules-values/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-modules-values/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-modules-values/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-nesting": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-7.0.1.tgz", - "integrity": "sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg==", - "dependencies": { - "postcss": "^7.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-nesting/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-nesting/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-nesting/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-normalize-charset": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", - "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", - "dependencies": { - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-charset/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-normalize-charset/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-normalize-charset/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-normalize-display-values": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", - "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", - "dependencies": { - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-display-values/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-normalize-display-values/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-normalize-display-values/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-normalize-display-values/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-normalize-positions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", - "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", - "dependencies": { - "cssnano-util-get-arguments": "^4.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-positions/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-normalize-positions/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-normalize-positions/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-normalize-positions/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-normalize-repeat-style": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", - "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", - "dependencies": { - "cssnano-util-get-arguments": "^4.0.0", - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-repeat-style/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-normalize-repeat-style/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-normalize-repeat-style/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-normalize-repeat-style/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-normalize-string": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", - "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", - "dependencies": { - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-string/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-normalize-string/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-normalize-string/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-normalize-string/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-normalize-timing-functions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", - "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", - "dependencies": { - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-timing-functions/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-normalize-timing-functions/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-normalize-timing-functions/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-normalize-timing-functions/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-normalize-unicode": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", - "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", - "dependencies": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-unicode/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-normalize-unicode/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-normalize-unicode/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-normalize-unicode/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-normalize-url": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", - "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", - "dependencies": { - "is-absolute-url": "^2.0.0", - "normalize-url": "^3.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-url/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-normalize-url/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-normalize-url/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-normalize-url/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-normalize-whitespace": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", - "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", - "dependencies": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-whitespace/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-normalize-whitespace/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-normalize-whitespace/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-normalize-whitespace/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-ordered-values": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", - "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", - "dependencies": { - "cssnano-util-get-arguments": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-ordered-values/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-ordered-values/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-ordered-values/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-ordered-values/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-overflow-shorthand": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz", - "integrity": "sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g==", - "dependencies": { - "postcss": "^7.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-overflow-shorthand/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-overflow-shorthand/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-overflow-shorthand/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-page-break": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-2.0.0.tgz", - "integrity": "sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ==", - "dependencies": { - "postcss": "^7.0.2" - } - }, - "node_modules/postcss-page-break/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-page-break/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-page-break/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-place": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-4.0.1.tgz", - "integrity": "sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg==", - "dependencies": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-place/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-place/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-place/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-prefix-selector": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/postcss-prefix-selector/-/postcss-prefix-selector-1.14.0.tgz", - "integrity": "sha512-8d5fiBQZWMtGWH/7ewEeo6RnBNyT2kLD5wTIfV2oHYqH4hjiofg/rP5X3SUwnqOINzE4mM/K/UOAiNrIaKzd4w==", - "peerDependencies": { - "postcss": "7.x || 8.x" - } - }, - "node_modules/postcss-preset-env": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-6.7.1.tgz", - "integrity": "sha512-rlRkgX9t0v2On33n7TK8pnkcYOATGQSv48J2RS8GsXhqtg+xk6AummHP88Y5mJo0TLJelBjePvSjScTNkj3+qw==", - "dependencies": { - "autoprefixer": "^9.6.1", - "browserslist": "^4.6.4", - "caniuse-lite": "^1.0.30000981", - "css-blank-pseudo": "^0.1.4", - "css-has-pseudo": "^0.10.0", - "css-prefers-color-scheme": "^3.1.1", - "cssdb": "^4.4.0", - "postcss": "^7.0.17", - "postcss-attribute-case-insensitive": "^4.0.1", - "postcss-color-functional-notation": "^2.0.1", - "postcss-color-gray": "^5.0.0", - "postcss-color-hex-alpha": "^5.0.3", - "postcss-color-mod-function": "^3.0.3", - "postcss-color-rebeccapurple": "^4.0.1", - "postcss-custom-media": "^7.0.8", - "postcss-custom-properties": "^8.0.11", - "postcss-custom-selectors": "^5.1.2", - "postcss-dir-pseudo-class": "^5.0.0", - "postcss-double-position-gradients": "^1.0.0", - "postcss-env-function": "^2.0.2", - "postcss-focus-visible": "^4.0.0", - "postcss-focus-within": "^3.0.0", - "postcss-font-variant": "^4.0.0", - "postcss-gap-properties": "^2.0.0", - "postcss-image-set-function": "^3.0.1", - "postcss-initial": "^3.0.0", - "postcss-lab-function": "^2.0.1", - "postcss-logical": "^3.0.0", - "postcss-media-minmax": "^4.0.0", - "postcss-nesting": "^7.0.0", - "postcss-overflow-shorthand": "^2.0.0", - "postcss-page-break": "^2.0.0", - "postcss-place": "^4.0.1", - "postcss-pseudo-class-any-link": "^6.0.0", - "postcss-replace-overflow-wrap": "^3.0.0", - "postcss-selector-matches": "^4.0.0", - "postcss-selector-not": "^4.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-preset-env/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-preset-env/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-preset-env/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-pseudo-class-any-link": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz", - "integrity": "sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew==", - "dependencies": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^5.0.0-rc.3" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-pseudo-class-any-link/node_modules/cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-pseudo-class-any-link/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-pseudo-class-any-link/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-pseudo-class-any-link/node_modules/postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "dependencies": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-pseudo-class-any-link/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-reduce-initial": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", - "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", - "dependencies": { - "browserslist": "^4.0.0", - "caniuse-api": "^3.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-reduce-initial/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-reduce-initial/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-reduce-initial/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-reduce-transforms": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", - "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", - "dependencies": { - "cssnano-util-get-match": "^4.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-reduce-transforms/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-reduce-transforms/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-reduce-transforms/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-reduce-transforms/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-replace-overflow-wrap": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz", - "integrity": "sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw==", - "dependencies": { - "postcss": "^7.0.2" - } - }, - "node_modules/postcss-replace-overflow-wrap/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-replace-overflow-wrap/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-replace-overflow-wrap/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-selector-matches": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz", - "integrity": "sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww==", - "dependencies": { - "balanced-match": "^1.0.0", - "postcss": "^7.0.2" - } - }, - "node_modules/postcss-selector-matches/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-selector-matches/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-selector-matches/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-selector-not": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-4.0.1.tgz", - "integrity": "sha512-YolvBgInEK5/79C+bdFMyzqTg6pkYqDbzZIST/PDMqa/o3qtXenD05apBG2jLgT0/BQ77d4U2UK12jWpilqMAQ==", - "dependencies": { - "balanced-match": "^1.0.0", - "postcss": "^7.0.2" - } - }, - "node_modules/postcss-selector-not/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-selector-not/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-selector-not/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.0.9", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz", - "integrity": "sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ==", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-svgo": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.3.tgz", - "integrity": "sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==", - "dependencies": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "svgo": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-svgo/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-svgo/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-svgo/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-svgo/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-unique-selectors": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", - "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", - "dependencies": { - "alphanum-sort": "^1.0.0", - "postcss": "^7.0.0", - "uniqs": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-unique-selectors/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-unique-selectors/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-unique-selectors/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-url": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/postcss-url/-/postcss-url-8.0.0.tgz", - "integrity": "sha512-E2cbOQ5aii2zNHh8F6fk1cxls7QVFZjLPSrqvmiza8OuXLzIpErij8BDS5Y3STPfJgpIMNCPEr8JlKQWEoozUw==", - "dependencies": { - "mime": "^2.3.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.0", - "postcss": "^7.0.2", - "xxhashjs": "^0.2.1" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-url/node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/postcss-url/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss-url/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-url/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" - }, - "node_modules/postcss-values-parser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz", - "integrity": "sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg==", - "dependencies": { - "flatten": "^1.0.2", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - }, - "engines": { - "node": ">=6.14.4" - } - }, - "node_modules/posthtml": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.9.2.tgz", - "integrity": "sha1-9MBtufZ7Yf0XxOJW5+PZUVv3Jv0=", - "dependencies": { - "posthtml-parser": "^0.2.0", - "posthtml-render": "^1.0.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/posthtml-parser": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.2.1.tgz", - "integrity": "sha1-NdUw3jhnQMK6JP8usvrznM3ycd0=", - "dependencies": { - "htmlparser2": "^3.8.3", - "isobject": "^2.1.0" - } - }, - "node_modules/posthtml-parser/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/posthtml-rename-id": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/posthtml-rename-id/-/posthtml-rename-id-1.0.12.tgz", - "integrity": "sha512-UKXf9OF/no8WZo9edRzvuMenb6AD5hDLzIepJW+a4oJT+T/Lx7vfMYWT4aWlGNQh0WMhnUx1ipN9OkZ9q+ddEw==", - "dependencies": { - "escape-string-regexp": "1.0.5" - } - }, - "node_modules/posthtml-render": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-1.4.0.tgz", - "integrity": "sha512-W1779iVHGfq0Fvh2PROhCe2QhB8mEErgqzo1wpIt36tCgChafP+hbXIhLDOM8ePJrZcFs0vkNEtdibEWVqChqw==", - "engines": { - "node": ">=10" - } - }, - "node_modules/posthtml-svg-mode": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/posthtml-svg-mode/-/posthtml-svg-mode-1.0.3.tgz", - "integrity": "sha512-hEqw9NHZ9YgJ2/0G7CECOeuLQKZi8HjWLkBaSVtOWjygQ9ZD8P7tqeowYs7WrFdKsWEKG7o+IlsPY8jrr0CJpQ==", - "dependencies": { - "merge-options": "1.0.1", - "posthtml": "^0.9.2", - "posthtml-parser": "^0.2.1", - "posthtml-render": "^1.0.6" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/prettier": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", - "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pretty-error": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", - "integrity": "sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==", - "dependencies": { - "lodash": "^4.17.20", - "renderkid": "^2.0.4" - } - }, - "node_modules/pretty-time": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", - "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "node_modules/promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" - }, - "node_modules/proper-lockfile": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", - "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", - "dependencies": { - "graceful-fs": "^4.2.4", - "retry": "^0.12.0", - "signal-exit": "^3.0.2" - } - }, - "node_modules/protocols": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.8.tgz", - "integrity": "sha512-IgjKyaUSjsROSO8/D49Ab7hP8mJgTYcqApOqdPhLoPxAplXmkp+zRvsrSQjFn5by0rhm4VH0GAUELIPpx7B1yg==" - }, - "node_modules/prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" - }, - "node_modules/pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, - "node_modules/pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "dev": true - }, - "node_modules/public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/public-encrypt/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dependencies": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - } - }, - "node_modules/pumpify/node_modules/pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/pupa": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", - "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", - "dev": true, - "dependencies": { - "escape-goat": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", - "engines": { - "node": ">=0.6.0", - "teleport": ">=0.2.0" - } - }, - "node_modules/qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/query-string": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", - "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", - "dependencies": { - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dependencies": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/randomatic/node_modules/is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-loader": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.2.tgz", - "integrity": "sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==", - "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/raw-loader/node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/raw-loader/node_modules/loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/rc9": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/rc9/-/rc9-1.2.0.tgz", - "integrity": "sha512-/jknmhG0USFAx5uoKkAKhtG40sONds9RWhFHrP1UzJ3OvVfqFWOypSUpmsQD0fFwAV7YtzHhsn3QNasfAoxgcQ==", - "dependencies": { - "defu": "^2.0.4", - "destr": "^1.0.0", - "flat": "^5.0.0" - } - }, - "node_modules/rc9/node_modules/defu": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/defu/-/defu-2.0.4.tgz", - "integrity": "sha512-G9pEH1UUMxShy6syWk01VQSRVs3CDWtlxtZu7A+NyqjxaCA4gSlWAKDBx6QiUEKezqS8+DUlXLI14Fp05Hmpwg==" - }, - "node_modules/read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=", - "dependencies": { - "pify": "^2.3.0" - } - }, - "node_modules/read-cache/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz", - "integrity": "sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw==", - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" - }, - "node_modules/regenerator-transform": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", - "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", - "dependencies": { - "@babel/runtime": "^7.8.4" - } - }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-not/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-not/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/regexpu-core": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.0.1.tgz", - "integrity": "sha512-CriEZlrKK9VJw/xQGJpQM5rY88BtuL8DM+AEwvcThHilbxiTAy8vq4iJnd2tqq8wLmjbGZzP7ZcKFjbGkmEFrw==", - "dependencies": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.0.1", - "regjsgen": "^0.6.0", - "regjsparser": "^0.8.2", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/registry-auth-token": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", - "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", - "dev": true, - "dependencies": { - "rc": "^1.2.8" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/registry-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", - "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", - "dev": true, - "dependencies": { - "rc": "^1.2.8" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/regjsgen": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.6.0.tgz", - "integrity": "sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA==" - }, - "node_modules/regjsparser": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.8.4.tgz", - "integrity": "sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA==", - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "bin": { - "jsesc": "bin/jsesc" - } - }, - "node_modules/relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/remarkable": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/remarkable/-/remarkable-1.7.4.tgz", - "integrity": "sha512-e6NKUXgX95whv7IgddywbeN/ItCkWbISmc2DiqHJb0wTrqZIexqdco5b8Z3XZoo/48IdNVKM9ZCvTPJ4F5uvhg==", - "dependencies": { - "argparse": "^1.0.10", - "autolinker": "~0.28.0" - }, - "bin": { - "remarkable": "bin/remarkable.js" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "optional": true - }, - "node_modules/renderkid": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.7.tgz", - "integrity": "sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ==", - "dependencies": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^3.0.1" - } - }, - "node_modules/renderkid/node_modules/css-select": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.2.1.tgz", - "integrity": "sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^5.1.0", - "domhandler": "^4.3.0", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/renderkid/node_modules/css-what": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", - "integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/renderkid/node_modules/dom-serializer": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", - "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/domelementtype": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", - "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/renderkid/node_modules/domhandler": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz", - "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==", - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - }, - "node_modules/renderkid/node_modules/nth-check": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", - "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" - }, - "node_modules/resize-observer-polyfill": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", - "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" - }, - "node_modules/resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", - "dependencies": { - "is-core-module": "^2.8.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "deprecated": "https://github.com/lydell/resolve-url#deprecated" - }, - "node_modules/responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "dev": true, - "dependencies": { - "lowercase-keys": "^1.0.0" - } - }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "engines": { - "node": ">=0.12" - } - }, - "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", - "engines": { - "node": ">= 4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rgb-regex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", - "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=" - }, - "node_modules/rgba-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", - "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=" - }, - "node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dependencies": { - "aproba": "^1.1.1" - } - }, - "node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/rxjs/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dependencies": { - "ret": "~0.1.10" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/sass": { - "version": "1.49.8", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.49.8.tgz", - "integrity": "sha512-NoGOjvDDOU9og9oAxhRnap71QaTjjlzrvLnKecUJ3GxhaQBrV6e7gPuSPF28u1OcVAArVojPAe4ZhOXwwC4tGw==", - "dev": true, - "dependencies": { - "chokidar": ">=3.0.0 <4.0.0", - "immutable": "^4.0.0", - "source-map-js": ">=0.6.2 <2.0.0" - }, - "bin": { - "sass": "sass.js" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/sass-loader": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-10.2.1.tgz", - "integrity": "sha512-RRvWl+3K2LSMezIsd008ErK4rk6CulIMSwrcc2aZvjymUgKo/vjXGp1rSWmfTUX7bblEOz8tst4wBwWtCGBqKA==", - "dev": true, - "dependencies": { - "klona": "^2.0.4", - "loader-utils": "^2.0.0", - "neo-async": "^2.6.2", - "schema-utils": "^3.0.0", - "semver": "^7.3.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "fibers": ">= 3.1.0", - "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0", - "sass": "^1.3.0", - "webpack": "^4.36.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "fibers": { - "optional": true - }, - "node-sass": { - "optional": true - }, - "sass": { - "optional": true - } - } - }, - "node_modules/sass-loader/node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/sass-loader/node_modules/loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "dev": true, - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/scule": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/scule/-/scule-0.2.1.tgz", - "integrity": "sha512-M9gnWtn3J0W+UhJOHmBxBTwv8mZCan5i1Himp60t6vvZcor0wr+IM0URKmIglsWJ7bRujNAVVN77fp+uZaWoKg==" - }, - "node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver-diff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", - "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", - "dev": true, - "dependencies": { - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/semver-diff/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", - "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", - "dependencies": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "1.8.1", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/serve-placeholder": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/serve-placeholder/-/serve-placeholder-1.2.4.tgz", - "integrity": "sha512-jWD9cZXLcr4vHTTL5KEPIUBUYyOWN/z6v/tn0l6XxFhi9iqV3Fc5Y1aFeduUyz+cx8sALzGCUczkPfeOlrq9jg==", - "dependencies": { - "defu": "^5.0.0" - } - }, - "node_modules/serve-static": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", - "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/server-destroy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", - "integrity": "sha1-8Tv5KOQrnD55OD5hzDmYtdFObN0=" - }, - "node_modules/set-getter": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.1.tgz", - "integrity": "sha512-9sVWOy+gthr+0G9DzqqLaYNA7+5OKkSmcqjL9cBpDEaZrr3ShQlyX2cZ/O/ozE41oxn/Tt0LGEM/w4Rub3A3gw==", - "dependencies": { - "to-object-path": "^0.3.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "engines": { - "node": ">=8" - } - }, - "node_modules/shell-quote": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz", - "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==" - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/simple-swizzle/node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, - "node_modules/sirv": { - "version": "1.0.19", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.19.tgz", - "integrity": "sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==", - "dependencies": { - "@polka/url": "^1.0.0-next.20", - "mrmime": "^1.0.0", - "totalist": "^1.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", - "dependencies": { - "is-plain-obj": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sort-keys/node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" - }, - "node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "deprecated": "See https://github.com/lydell/source-map-url#deprecated" - }, - "node_modules/split-on-first": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", - "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split-string/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split-string/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "node_modules/ssri": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", - "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", - "dependencies": { - "minipass": "^3.1.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==" - }, - "node_modules/stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", - "engines": { - "node": "*" - } - }, - "node_modules/stackframe": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.1.tgz", - "integrity": "sha512-h88QkzREN/hy8eRdyNhhsO7RSJ5oyTqxxmmn0dzBIMUclZsjpfmrsg81vp8mjjAs2vAZ72nyWxRUwSwmh0e4xg==" - }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/std-env": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-2.3.1.tgz", - "integrity": "sha512-eOsoKTWnr6C8aWrqJJ2KAReXoa7Vn5Ywyw6uCXgA/xDhxPoaIsBa5aNJmISY04dLwXPBnDHW4diGM7Sn5K4R/g==", - "dependencies": { - "ci-info": "^3.1.1" - } - }, - "node_modules/stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dependencies": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "node_modules/stream-browserify/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/stream-browserify/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/stream-browserify/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dependencies": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "node_modules/stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dependencies": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - } - }, - "node_modules/stream-http/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/stream-http/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/stream-http/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" - }, - "node_modules/strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-color": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/strip-color/-/strip-color-0.1.0.tgz", - "integrity": "sha1-EG9l09PmotlAHKwOsM6LinArT3s=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/style-resources-loader": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/style-resources-loader/-/style-resources-loader-1.5.0.tgz", - "integrity": "sha512-fIfyvQ+uvXaCBGGAgfh+9v46ARQB1AWdaop2RpQw0PBVuROsTBqGvx8dj0kxwjGOAyq3vepe4AOK3M6+Q/q2jw==", - "dependencies": { - "glob": "^7.2.0", - "loader-utils": "^2.0.0", - "schema-utils": "^2.7.0", - "tslib": "^2.3.1" - }, - "engines": { - "node": ">=8.9" - }, - "peerDependencies": { - "webpack": "^3.0.0 || ^4.0.0 || ^5.0.0" - } - }, - "node_modules/style-resources-loader/node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/style-resources-loader/node_modules/loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/style-resources-loader/node_modules/schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "dependencies": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/stylehacks": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", - "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", - "dependencies": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/stylehacks/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/stylehacks/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/stylehacks/node_modules/postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dependencies": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/stylehacks/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dependencies": { - "has-flag": "^1.0.0" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/svg-baker": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/svg-baker/-/svg-baker-1.7.0.tgz", - "integrity": "sha512-nibslMbkXOIkqKVrfcncwha45f97fGuAOn1G99YwnwTj8kF9YiM6XexPcUso97NxOm6GsP0SIvYVIosBis1xLg==", - "dependencies": { - "bluebird": "^3.5.0", - "clone": "^2.1.1", - "he": "^1.1.1", - "image-size": "^0.5.1", - "loader-utils": "^1.1.0", - "merge-options": "1.0.1", - "micromatch": "3.1.0", - "postcss": "^5.2.17", - "postcss-prefix-selector": "^1.6.0", - "posthtml-rename-id": "^1.0", - "posthtml-svg-mode": "^1.0.3", - "query-string": "^4.3.2", - "traverse": "^0.6.6" - } - }, - "node_modules/svg-baker-runtime": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/svg-baker-runtime/-/svg-baker-runtime-1.4.7.tgz", - "integrity": "sha512-Zorfwwj5+lWjk/oxwSMsRdS2sPQQdTmmsvaSpzU+i9ZWi3zugHLt6VckWfnswphQP0LmOel3nggpF5nETbt6xw==", - "dependencies": { - "deepmerge": "1.3.2", - "mitt": "1.1.2", - "svg-baker": "^1.7.0" - } - }, - "node_modules/svg-baker/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/svg-baker/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/svg-baker/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/svg-baker/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/svg-baker/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/svg-baker/node_modules/micromatch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.0.tgz", - "integrity": "sha512-3StSelAE+hnRvMs8IdVW7Uhk8CVed5tp+kLLGlBP6WiRAXS21GPGu/Nat4WNPXj2Eoc24B02SaeoyozPMfj0/g==", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.2.2", - "define-property": "^1.0.0", - "extend-shallow": "^2.0.1", - "extglob": "^2.0.2", - "fragment-cache": "^0.2.1", - "kind-of": "^5.0.2", - "nanomatch": "^1.2.1", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/svg-baker/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/svg-sprite-loader": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/svg-sprite-loader/-/svg-sprite-loader-5.2.1.tgz", - "integrity": "sha512-n2IZc87rpOeXh+PQFksFMGCfMV/BT01YG+Dlbyjoh2Cz8BSTL5Vi/7KDr86Pt/u1NRDCVb3vY74BF5rKCmqbNA==", - "dependencies": { - "bluebird": "^3.5.0", - "deepmerge": "1.3.2", - "domready": "1.0.8", - "escape-string-regexp": "1.0.5", - "loader-utils": "^1.1.0", - "svg-baker": "^1.5.0", - "svg-baker-runtime": "^1.4.7", - "url-slug": "2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/svg-tags": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", - "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=" - }, - "node_modules/svg-to-vue": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/svg-to-vue/-/svg-to-vue-0.7.0.tgz", - "integrity": "sha512-Tg2nMmf3BQorYCAjxbtTkYyWPVSeox5AZUFvfy4MoWK/5tuQlnA/h3LAlTjV3sEvOC5FtUNovRSj3p784l4KOA==", - "dependencies": { - "svgo": "^1.3.2" - }, - "peerDependencies": { - "vue-template-compiler": "^2.0.0" - } - }, - "node_modules/svgo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", - "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", - "deprecated": "This SVGO version is no longer supported. Upgrade to v2.x.x.", - "dependencies": { - "chalk": "^2.4.1", - "coa": "^2.0.2", - "css-select": "^2.0.0", - "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.37", - "csso": "^4.0.2", - "js-yaml": "^3.13.1", - "mkdirp": "~0.5.1", - "object.values": "^1.1.0", - "sax": "~1.2.4", - "stable": "^0.1.8", - "unquote": "~1.1.1", - "util.promisify": "~1.0.0" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/svgo/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/svgo/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/svgo/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/svgo/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/svgo/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/tar/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", - "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", - "dependencies": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-4.2.3.tgz", - "integrity": "sha512-jTgXh40RnvOrLQNgIkwEKnQ8rmHjHK4u+6UBEi+W+FPmvb+uo+chJXntKe7/3lW5mNysgSWD60KyesnhW8D6MQ==", - "dependencies": { - "cacache": "^15.0.5", - "find-cache-dir": "^3.3.1", - "jest-worker": "^26.5.0", - "p-limit": "^3.0.2", - "schema-utils": "^3.0.0", - "serialize-javascript": "^5.0.1", - "source-map": "^0.6.1", - "terser": "^5.3.4", - "webpack-sources": "^1.4.3" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "node_modules/terser-webpack-plugin/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/terser-webpack-plugin/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/terser": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.11.0.tgz", - "integrity": "sha512-uCA9DLanzzWSsN1UirKwylhhRz3aKPInlfmpGfw8VN6jHsAtu8HJtIpeeHHK23rxnE/cDc+yvmq5wqkIC6Kn0A==", - "dependencies": { - "acorn": "^8.5.0", - "commander": "^2.20.0", - "source-map": "~0.7.2", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin/node_modules/terser/node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "node_modules/terser/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" - }, - "node_modules/thread-loader": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/thread-loader/-/thread-loader-3.0.4.tgz", - "integrity": "sha512-ByaL2TPb+m6yArpqQUZvP+5S1mZtXsEP7nWKKlAUTm7fCml8kB5s1uI3+eHRP2bk5mVYfRSBI7FFf+tWEyLZwA==", - "dependencies": { - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.1.0", - "loader-utils": "^2.0.0", - "neo-async": "^2.6.2", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.27.0 || ^5.0.0" - } - }, - "node_modules/thread-loader/node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/thread-loader/node_modules/loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/through2/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/through2/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/through2/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/time-fix-plugin": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/time-fix-plugin/-/time-fix-plugin-2.0.7.tgz", - "integrity": "sha512-uVFet1LQToeUX0rTcSiYVYVoGuBpc8gP/2jnlUzuHMHe+gux6XLsNzxLUweabMwiUj5ejhoIMsUI55nVSEa/Vw==", - "peerDependencies": { - "webpack": ">=4.0.0" - } - }, - "node_modules/timers-browserify": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", - "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", - "dependencies": { - "setimmediate": "^1.0.4" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/timsort": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" - }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=" - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "engines": { - "node": ">=4" - } - }, - "node_modules/to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/to-regex/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/toml": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/toml/-/toml-2.3.6.tgz", - "integrity": "sha512-gVweAectJU3ebq//Ferr2JUY4WKSDe5N+z0FvjDncLGyHmIDoxgY/2Ie4qfEIDm4IS7OA6Rmdm7pdEEdMcV/xQ==" - }, - "node_modules/totalist": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", - "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==", - "engines": { - "node": ">=6" - } - }, - "node_modules/touch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", - "dev": true, - "dependencies": { - "nopt": "~1.0.10" - }, - "bin": { - "nodetouch": "bin/nodetouch.js" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" - }, - "node_modules/traverse": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", - "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=" - }, - "node_modules/ts-pnp": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz", - "integrity": "sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==", - "engines": { - "node": ">=6" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" - }, - "node_modules/tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/ua-parser-js": { - "version": "0.7.31", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.31.tgz", - "integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/ua-parser-js" - }, - { - "type": "paypal", - "url": "https://paypal.me/faisalman" - } - ], - "engines": { - "node": "*" - } - }, - "node_modules/uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" - }, - "node_modules/ufo": { - "version": "0.7.10", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-0.7.10.tgz", - "integrity": "sha512-YTnDRlE1cIofRqOFN8ioAbz9qenDvkgVMSn0cnxvIDjM9sfEOMKB0ybMr+otSlCXMfQ/X35haYRoI7Nua82RrA==" - }, - "node_modules/uglify-js": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.1.tgz", - "integrity": "sha512-FAGKF12fWdkpvNJZENacOH0e/83eG6JyVQyanIJaBXCN1J11TUQv1T1/z8S+Z0CG0ZPk1nPcreF/c7lrTd0TEQ==", - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dependencies": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/undefsafe": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", - "dev": true - }, - "node_modules/unfetch": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz", - "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==" - }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", - "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", - "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unidecode": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/unidecode/-/unidecode-0.1.8.tgz", - "integrity": "sha1-77swFTi8RSRqmsjFWdcvAVMFBT4=", - "engines": { - "node": ">= 0.4.12" - } - }, - "node_modules/union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" - }, - "node_modules/uniqs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", - "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=" - }, - "node_modules/unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dependencies": { - "unique-slug": "^2.0.0" - } - }, - "node_modules/unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dependencies": { - "imurmurhash": "^0.1.4" - } - }, - "node_modules/unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dev": true, - "dependencies": { - "crypto-random-string": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/unquote": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", - "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=" - }, - "node_modules/unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/upath": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz", - "integrity": "sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==", - "engines": { - "node": ">=4", - "yarn": "*" - } - }, - "node_modules/update-notifier": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", - "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", - "dev": true, - "dependencies": { - "boxen": "^5.0.0", - "chalk": "^4.1.0", - "configstore": "^5.0.1", - "has-yarn": "^2.1.0", - "import-lazy": "^2.1.0", - "is-ci": "^2.0.0", - "is-installed-globally": "^0.4.0", - "is-npm": "^5.0.0", - "is-yarn-global": "^0.3.0", - "latest-version": "^5.1.0", - "pupa": "^2.1.1", - "semver": "^7.3.4", - "semver-diff": "^3.1.1", - "xdg-basedir": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/yeoman/update-notifier?sponsor=1" - } - }, - "node_modules/update-notifier/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/update-notifier/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/update-notifier/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/update-notifier/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/update-notifier/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/update-notifier/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/upper-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", - "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=" - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "deprecated": "Please see https://github.com/lydell/urix#deprecated" - }, - "node_modules/url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dependencies": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - }, - "node_modules/url-loader": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", - "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", - "dependencies": { - "loader-utils": "^2.0.0", - "mime-types": "^2.1.27", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "file-loader": "*", - "webpack": "^4.0.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "file-loader": { - "optional": true - } - } - }, - "node_modules/url-loader/node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/url-loader/node_modules/loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "dev": true, - "dependencies": { - "prepend-http": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/url-parse-lax/node_modules/prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/url-slug": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/url-slug/-/url-slug-2.0.0.tgz", - "integrity": "sha1-p4nVrtSZXA2VrzM3etHVxo1NcCc=", - "dependencies": { - "unidecode": "0.1.8" - } - }, - "node_modules/url/node_modules/punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" - }, - "node_modules/use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dependencies": { - "inherits": "2.0.3" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "node_modules/util.promisify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", - "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.2", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/util/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "node_modules/utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=" - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/vendors": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", - "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==" - }, - "node_modules/vue": { - "version": "2.6.14", - "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.14.tgz", - "integrity": "sha512-x2284lgYvjOMj3Za7kqzRcUSxBboHqtgRE2zlos1qWaOye5yUmHn42LB1250NJBLRwEcdrB0JRwyPTEPhfQjiQ==" - }, - "node_modules/vue-analytics": { - "version": "5.22.1", - "resolved": "https://registry.npmjs.org/vue-analytics/-/vue-analytics-5.22.1.tgz", - "integrity": "sha512-HPKQMN7gfcUqS5SxoO0VxqLRRSPkG1H1FqglsHccz6BatBatNtm/Vyy8brApktZxNCfnAkrSVDpxg3/FNDeOgQ==", - "deprecated": "Sorry but vue-analytics is no longer maintained. I would suggest you switch to vue-gtag, with love, the guy who made the package." - }, - "node_modules/vue-client-only": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/vue-client-only/-/vue-client-only-2.1.0.tgz", - "integrity": "sha512-vKl1skEKn8EK9f8P2ZzhRnuaRHLHrlt1sbRmazlvsx6EiC3A8oWF8YCBrMJzoN+W3OnElwIGbVjsx6/xelY1AA==" - }, - "node_modules/vue-codemirror": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/vue-codemirror/-/vue-codemirror-4.0.6.tgz", - "integrity": "sha512-ilU7Uf0mqBNSSV3KT7FNEeRIxH4s1fmpG4TfHlzvXn0QiQAbkXS9lLfwuZpaBVEnpP5CSE62iGJjoliTuA8poQ==", - "dependencies": { - "codemirror": "^5.41.0", - "diff-match-patch": "^1.0.0" - }, - "engines": { - "node": ">= 4.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/vue-eslint-parser": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.2.0.tgz", - "integrity": "sha512-hvl8OVT8imlKk/lQyhkshqwQQChzHETcBd5abiO4ePw7ib7QUZLfW+2TUrJHKUvFOCFRJrDin5KJO9OHzB5bRQ==", - "dev": true, - "dependencies": { - "debug": "^4.3.2", - "eslint-scope": "^7.0.0", - "eslint-visitor-keys": "^3.1.0", - "espree": "^9.0.0", - "esquery": "^1.4.0", - "lodash": "^4.17.21", - "semver": "^7.3.5" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=6.0.0" - } - }, - "node_modules/vue-eslint-parser/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/vue-eslint-parser/node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/vue-eslint-parser/node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/vue-eslint-parser/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/vue-eslint-parser/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/vue-highlightjs": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/vue-highlightjs/-/vue-highlightjs-1.3.3.tgz", - "integrity": "sha1-KaDVcTL8HOFc+mHolpGPW3GMXVI=", - "dependencies": { - "highlight.js": "*" - } - }, - "node_modules/vue-hot-reload-api": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz", - "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==" - }, - "node_modules/vue-js-modal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/vue-js-modal/-/vue-js-modal-2.0.1.tgz", - "integrity": "sha512-5FUwsH2zoxRKX4a7wkFAqX0eITCcIMunJDEfIxzHs2bHw9o20+Iqm+uQvBcg1jkzyo1+tVgThR/7NGU8djbD8Q==", - "dependencies": { - "resize-observer-polyfill": "^1.5.1" - }, - "peerDependencies": { - "vue": "^2.6.11" - } - }, - "node_modules/vue-loader": { - "version": "15.9.8", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.8.tgz", - "integrity": "sha512-GwSkxPrihfLR69/dSV3+5CdMQ0D+jXg8Ma1S4nQXKJAznYFX14vHdc/NetQc34Dw+rBbIJyP7JOuVb9Fhprvog==", - "dependencies": { - "@vue/component-compiler-utils": "^3.1.0", - "hash-sum": "^1.0.2", - "loader-utils": "^1.1.0", - "vue-hot-reload-api": "^2.3.0", - "vue-style-loader": "^4.1.0" - }, - "peerDependencies": { - "css-loader": "*", - "webpack": "^3.0.0 || ^4.1.0 || ^5.0.0-0" - }, - "peerDependenciesMeta": { - "cache-loader": { - "optional": true - }, - "vue-template-compiler": { - "optional": true - } - } - }, - "node_modules/vue-loader/node_modules/hash-sum": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", - "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=" - }, - "node_modules/vue-meta": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/vue-meta/-/vue-meta-2.4.0.tgz", - "integrity": "sha512-XEeZUmlVeODclAjCNpWDnjgw+t3WA6gdzs6ENoIAgwO1J1d5p1tezDhtteLUFwcaQaTtayRrsx7GL6oXp/m2Jw==", - "dependencies": { - "deepmerge": "^4.2.2" - } - }, - "node_modules/vue-meta/node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/vue-no-ssr": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/vue-no-ssr/-/vue-no-ssr-1.1.1.tgz", - "integrity": "sha512-ZMjqRpWabMPqPc7gIrG0Nw6vRf1+itwf0Itft7LbMXs2g3Zs/NFmevjZGN1x7K3Q95GmIjWbQZTVerxiBxI+0g==" - }, - "node_modules/vue-router": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.3.tgz", - "integrity": "sha512-FUlILrW3DGitS2h+Xaw8aRNvGTwtuaxrRkNSHWTizOfLUie7wuYwezeZ50iflRn8YPV5kxmU2LQuu3nM/b3Zsg==" - }, - "node_modules/vue-server-renderer": { - "version": "2.6.14", - "resolved": "https://registry.npmjs.org/vue-server-renderer/-/vue-server-renderer-2.6.14.tgz", - "integrity": "sha512-HifYRa/LW7cKywg9gd4ZtvtRuBlstQBao5ZCWlg40fyB4OPoGfEXAzxb0emSLv4pBDOHYx0UjpqvxpiQFEuoLA==", - "dependencies": { - "chalk": "^1.1.3", - "hash-sum": "^1.0.2", - "he": "^1.1.0", - "lodash.template": "^4.5.0", - "lodash.uniq": "^4.5.0", - "resolve": "^1.2.0", - "serialize-javascript": "^3.1.0", - "source-map": "0.5.6" - } - }, - "node_modules/vue-server-renderer/node_modules/hash-sum": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", - "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=" - }, - "node_modules/vue-server-renderer/node_modules/serialize-javascript": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", - "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/vue-server-renderer/node_modules/source-map": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", - "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/vue-style-loader": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz", - "integrity": "sha512-sFuh0xfbtpRlKfm39ss/ikqs9AbKCoXZBpHeVZ8Tx650o0k0q/YCM7FRvigtxpACezfq6af+a7JeqVTWvncqDg==", - "dependencies": { - "hash-sum": "^1.0.2", - "loader-utils": "^1.0.2" - } - }, - "node_modules/vue-style-loader/node_modules/hash-sum": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", - "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=" - }, - "node_modules/vue-svg-loader": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/vue-svg-loader/-/vue-svg-loader-0.16.0.tgz", - "integrity": "sha512-2RtFXlTCYWm8YAEO2qAOZ2SuIF2NvLutB5muc3KDYoZq5ZeCHf8ggzSan3ksbbca7CJ/Aw57ZnDF4B7W/AkGtw==", - "dependencies": { - "loader-utils": "^1.2.3", - "svg-to-vue": "^0.7.0" - }, - "peerDependencies": { - "vue-template-compiler": "^2.0.0" - } - }, - "node_modules/vue-template-compiler": { - "version": "2.6.14", - "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.14.tgz", - "integrity": "sha512-ODQS1SyMbjKoO1JBJZojSw6FE4qnh9rIpUZn2EUT86FKizx9uH5z6uXiIrm4/Nb/gwxTi/o17ZDEGWAXHvtC7g==", - "dependencies": { - "de-indent": "^1.0.2", - "he": "^1.1.0" - } - }, - "node_modules/vue-template-es2015-compiler": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz", - "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==" - }, - "node_modules/vuex": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.2.tgz", - "integrity": "sha512-ETW44IqCgBpVomy520DT5jf8n0zoCac+sxWnn+hMe/CzaSejb/eVw2YToiXYX+Ex/AuHHia28vWTq4goAexFbw==", - "peerDependencies": { - "vue": "^2.0.0" - } - }, - "node_modules/watchpack": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", - "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", - "dependencies": { - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "optionalDependencies": { - "chokidar": "^3.4.1", - "watchpack-chokidar2": "^2.0.1" - } - }, - "node_modules/watchpack-chokidar2": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", - "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==", - "optional": true, - "dependencies": { - "chokidar": "^2.1.8" - } - }, - "node_modules/watchpack-chokidar2/node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "optional": true, - "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "node_modules/watchpack-chokidar2/node_modules/anymatch/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "optional": true, - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "optional": true, - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "optional": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies", - "optional": true, - "dependencies": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - }, - "optionalDependencies": { - "fsevents": "^1.2.7" - } - }, - "node_modules/watchpack-chokidar2/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "optional": true, - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "optional": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/extend-shallow/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "optional": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "optional": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "optional": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "optional": true, - "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/glob-parent/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "optional": true, - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "optional": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "optional": true, - "dependencies": { - "binary-extensions": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "optional": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "optional": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "optional": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "optional": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "optional": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "optional": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/watchpack-chokidar2/node_modules/readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "optional": true, - "dependencies": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/watchpack-chokidar2/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "optional": true - }, - "node_modules/watchpack-chokidar2/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "optional": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "optional": true, - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "optional": true, - "engines": { - "node": ">=4", - "yarn": "*" - } - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" - }, - "node_modules/webpack": { - "version": "4.46.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz", - "integrity": "sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q==", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/wasm-edit": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "acorn": "^6.4.1", - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.5.0", - "eslint-scope": "^4.0.3", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.4.0", - "loader-utils": "^1.2.3", - "memory-fs": "^0.4.1", - "micromatch": "^3.1.10", - "mkdirp": "^0.5.3", - "neo-async": "^2.6.1", - "node-libs-browser": "^2.2.1", - "schema-utils": "^1.0.0", - "tapable": "^1.1.3", - "terser-webpack-plugin": "^1.4.3", - "watchpack": "^1.7.4", - "webpack-sources": "^1.4.1" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=6.11.5" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - }, - "webpack-command": { - "optional": true - } - } - }, - "node_modules/webpack-bundle-analyzer": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.5.0.tgz", - "integrity": "sha512-GUMZlM3SKwS8Z+CKeIFx7CVoHn3dXFcUAjT/dcZQQmfSZGvitPfMob2ipjai7ovFFqPvTqkEZ/leL4O0YOdAYQ==", - "dependencies": { - "acorn": "^8.0.4", - "acorn-walk": "^8.0.0", - "chalk": "^4.1.0", - "commander": "^7.2.0", - "gzip-size": "^6.0.0", - "lodash": "^4.17.20", - "opener": "^1.5.2", - "sirv": "^1.0.7", - "ws": "^7.3.1" - }, - "bin": { - "webpack-bundle-analyzer": "lib/bin/analyzer.js" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/webpack-bundle-analyzer/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/webpack-dev-middleware": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-4.3.0.tgz", - "integrity": "sha512-PjwyVY95/bhBh6VUqt6z4THplYcsvQ8YNNBTBM873xLVmw8FLeALn0qurHbs9EmcfhzQis/eoqypSnZeuUz26w==", - "dependencies": { - "colorette": "^1.2.2", - "mem": "^8.1.1", - "memfs": "^3.2.2", - "mime-types": "^2.1.30", - "range-parser": "^1.2.1", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= v10.23.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/webpack-hot-middleware": { - "version": "2.25.1", - "resolved": "https://registry.npmjs.org/webpack-hot-middleware/-/webpack-hot-middleware-2.25.1.tgz", - "integrity": "sha512-Koh0KyU/RPYwel/khxbsDz9ibDivmUbrRuKSSQvW42KSDdO4w23WI3SkHpSUKHE76LrFnnM/L7JCrpBwu8AXYw==", - "dependencies": { - "ansi-html-community": "0.0.8", - "html-entities": "^2.1.0", - "querystring": "^0.2.0", - "strip-ansi": "^6.0.0" - } - }, - "node_modules/webpack-hot-middleware/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/webpack-hot-middleware/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/webpack-node-externals": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-3.0.0.tgz", - "integrity": "sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dependencies": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "node_modules/webpack-sources/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/webpack/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dependencies": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - } - }, - "node_modules/webpack/node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, - "node_modules/webpack/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/extend-shallow/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "engines": { - "node": ">=4.3.0 <5.0.0 || >=5.10" - } - }, - "node_modules/webpack/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack/node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/webpack/node_modules/make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack/node_modules/memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dependencies": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "node_modules/webpack/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "engines": { - "node": ">=4" - } - }, - "node_modules/webpack/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack/node_modules/pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/webpack/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/webpack/node_modules/schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/webpack/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/webpack/node_modules/serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/webpack/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/ssri": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", - "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", - "dependencies": { - "figgy-pudding": "^3.5.1" - } - }, - "node_modules/webpack/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/webpack/node_modules/terser-webpack-plugin": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", - "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", - "dependencies": { - "cacache": "^12.0.2", - "find-cache-dir": "^2.1.0", - "is-wsl": "^1.1.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^4.0.0", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - }, - "engines": { - "node": ">= 6.9.0" - }, - "peerDependencies": { - "webpack": "^4.0.0" - } - }, - "node_modules/webpack/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, - "node_modules/webpackbar": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-4.0.0.tgz", - "integrity": "sha512-k1qRoSL/3BVuINzngj09nIwreD8wxV4grcuhHTD8VJgUbGcy8lQSPqv+bM00B7F+PffwIsQ8ISd4mIwRbr23eQ==", - "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^2.4.2", - "consola": "^2.10.0", - "figures": "^3.0.0", - "pretty-time": "^1.1.0", - "std-env": "^2.2.1", - "text-table": "^0.2.0", - "wrap-ansi": "^6.0.0" - }, - "engines": { - "node": ">= 8.0.0" - }, - "peerDependencies": { - "webpack": "^3.0.0 || ^4.0.0" - } - }, - "node_modules/webpackbar/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/webpackbar/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/webpackbar/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/webpackbar/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dependencies": { - "string-width": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/workbox-cdn": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-cdn/-/workbox-cdn-5.1.4.tgz", - "integrity": "sha512-04gM3mi8QGutokkSaA9xunVfjURnLbo9TTWyi8+pSDCEW5cD8u5GbJiliLK1vB9CShk/9OY1UDfW+XcmD+d6KQ==" - }, - "node_modules/worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dependencies": { - "errno": "~0.1.7" - } - }, - "node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "node_modules/write-file-atomic": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", - "dependencies": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } - }, - "node_modules/write-json-file": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-2.3.0.tgz", - "integrity": "sha1-K2TIozAE1UuGmMdtWFp3zrYdoy8=", - "dependencies": { - "detect-indent": "^5.0.0", - "graceful-fs": "^4.1.2", - "make-dir": "^1.0.0", - "pify": "^3.0.0", - "sort-keys": "^2.0.0", - "write-file-atomic": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/write-json-file/node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/write-json-file/node_modules/make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/write-json-file/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "engines": { - "node": ">=4" - } - }, - "node_modules/write-json-file/node_modules/sort-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", - "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", - "dependencies": { - "is-plain-obj": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ws": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", - "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "engines": { - "node": ">=0.4" - } - }, - "node_modules/xxhashjs": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz", - "integrity": "sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw==", - "dependencies": { - "cuint": "^0.2.2" - } - }, - "node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - }, - "dependencies": { - "@aitodotai/json-stringify-pretty-compact": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@aitodotai/json-stringify-pretty-compact/-/json-stringify-pretty-compact-1.3.0.tgz", - "integrity": "sha512-K+whdCBlVjzx8zCK2ZUohGJb5bUOxRpiEAfD1NCUgH0mApdDZD9c7VHXJVzWlt3wfV1X4OFyCRmTqbPd6U87lQ==" - }, - "@ampproject/remapping": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz", - "integrity": "sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==", - "requires": { - "@jridgewell/trace-mapping": "^0.3.0" - } - }, - "@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", - "requires": { - "@babel/highlight": "^7.16.7" - } - }, - "@babel/compat-data": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.0.tgz", - "integrity": "sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==" - }, - "@babel/core": { - "version": "7.17.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.5.tgz", - "integrity": "sha512-/BBMw4EvjmyquN5O+t5eh0+YqB3XXJkYD2cjKpYtWOfFy4lQ4UozNSmxAcWT8r2XtZs0ewG+zrfsqeR15i1ajA==", - "requires": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.3", - "@babel/helper-compilation-targets": "^7.16.7", - "@babel/helper-module-transforms": "^7.16.7", - "@babel/helpers": "^7.17.2", - "@babel/parser": "^7.17.3", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.3", - "@babel/types": "^7.17.0", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0" - }, - "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "requires": { - "ms": "2.1.2" - } - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "@babel/generator": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.3.tgz", - "integrity": "sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg==", - "requires": { - "@babel/types": "^7.17.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz", - "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==", - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz", - "integrity": "sha512-C6FdbRaxYjwVu/geKW4ZeQ0Q31AftgRcdSnZ5/jsH6BzCJbtvXvhpfkbkThYSuutZA7nCXpPR6AD9zd1dprMkA==", - "requires": { - "@babel/helper-explode-assignable-expression": "^7.16.7", - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", - "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", - "requires": { - "@babel/compat-data": "^7.16.4", - "@babel/helper-validator-option": "^7.16.7", - "browserslist": "^4.17.5", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.17.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.1.tgz", - "integrity": "sha512-JBdSr/LtyYIno/pNnJ75lBcqc3Z1XXujzPanHqjvvrhOA+DTceTFuJi8XjmWTZh4r3fsdfqaCMN0iZemdkxZHQ==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-member-expression-to-functions": "^7.16.7", - "@babel/helper-optimise-call-expression": "^7.16.7", - "@babel/helper-replace-supers": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7" - } - }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.0.tgz", - "integrity": "sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "regexpu-core": "^5.0.1" - } - }, - "@babel/helper-define-polyfill-provider": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz", - "integrity": "sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA==", - "requires": { - "@babel/helper-compilation-targets": "^7.13.0", - "@babel/helper-module-imports": "^7.12.13", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/traverse": "^7.13.0", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" - }, - "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "@babel/helper-environment-visitor": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", - "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-explode-assignable-expression": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz", - "integrity": "sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ==", - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-function-name": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", - "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", - "requires": { - "@babel/helper-get-function-arity": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", - "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", - "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz", - "integrity": "sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q==", - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-module-imports": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", - "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-module-transforms": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", - "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", - "requires": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-simple-access": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/helper-validator-identifier": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.16.7", - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz", - "integrity": "sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w==", - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==" - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz", - "integrity": "sha512-fm0gH7Flb8H51LqJHy3HJ3wnE1+qtYR2A99K06ahwrawLdOFsCEWjZOrYricXJHoPSudNKxrMBUPEIPxiIIvBw==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-wrap-function": "^7.16.8", - "@babel/types": "^7.16.8" - } - }, - "@babel/helper-replace-supers": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz", - "integrity": "sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw==", - "requires": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-member-expression-to-functions": "^7.16.7", - "@babel/helper-optimise-call-expression": "^7.16.7", - "@babel/traverse": "^7.16.7", - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-simple-access": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", - "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz", - "integrity": "sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==", - "requires": { - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", - "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==" - }, - "@babel/helper-validator-option": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", - "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==" - }, - "@babel/helper-wrap-function": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz", - "integrity": "sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw==", - "requires": { - "@babel/helper-function-name": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.16.8", - "@babel/types": "^7.16.8" - } - }, - "@babel/helpers": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz", - "integrity": "sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==", - "requires": { - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.0", - "@babel/types": "^7.17.0" - } - }, - "@babel/highlight": { - "version": "7.16.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", - "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", - "requires": { - "@babel/helper-validator-identifier": "^7.16.7", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.3.tgz", - "integrity": "sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==" - }, - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.7.tgz", - "integrity": "sha512-anv/DObl7waiGEnC24O9zqL0pSuI9hljihqiDuFHC8d7/bjr/4RLGPWuc8rYOff/QPzbEPSkzG8wGG9aDuhHRg==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.7.tgz", - "integrity": "sha512-di8vUHRdf+4aJ7ltXhaDbPoszdkh59AQtJM5soLsuHpQJdFQZOA4uGj0V2u/CZ8bJ/u8ULDL5yq6FO/bCXnKHw==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", - "@babel/plugin-proposal-optional-chaining": "^7.16.7" - } - }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz", - "integrity": "sha512-71YHIvMuiuqWJQkebWJtdhQTfd4Q4mF76q2IX37uZPkG9+olBxsX+rH1vkhFto4UeJZ9dPY2s+mDvhDm1u2BGQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-remap-async-to-generator": "^7.16.8", - "@babel/plugin-syntax-async-generators": "^7.8.4" - } - }, - "@babel/plugin-proposal-class-properties": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz", - "integrity": "sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-proposal-class-static-block": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.7.tgz", - "integrity": "sha512-dgqJJrcZoG/4CkMopzhPJjGxsIe9A8RlkQLnL/Vhhx8AA9ZuaRwGSlscSh42hazc7WSrya/IK7mTeoF0DP9tEw==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - } - }, - "@babel/plugin-proposal-decorators": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.17.2.tgz", - "integrity": "sha512-WH8Z95CwTq/W8rFbMqb9p3hicpt4RX4f0K659ax2VHxgOyT6qQmUaEVEjIh4WR9Eh9NymkVn5vwsrE68fAQNUw==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.17.1", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-replace-supers": "^7.16.7", - "@babel/plugin-syntax-decorators": "^7.17.0", - "charcodes": "^0.2.0" - } - }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz", - "integrity": "sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - } - }, - "@babel/plugin-proposal-export-namespace-from": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz", - "integrity": "sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - } - }, - "@babel/plugin-proposal-json-strings": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz", - "integrity": "sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-json-strings": "^7.8.3" - } - }, - "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz", - "integrity": "sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - } - }, - "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz", - "integrity": "sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - } - }, - "@babel/plugin-proposal-numeric-separator": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz", - "integrity": "sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - } - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.17.3.tgz", - "integrity": "sha512-yuL5iQA/TbZn+RGAfxQXfi7CNLmKi1f8zInn4IgobuCWcAb7i+zj4TYzQ9l8cEzVyJ89PDGuqxK1xZpUDISesw==", - "requires": { - "@babel/compat-data": "^7.17.0", - "@babel/helper-compilation-targets": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.16.7" - } - }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz", - "integrity": "sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - } - }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz", - "integrity": "sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - } - }, - "@babel/plugin-proposal-private-methods": { - "version": "7.16.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz", - "integrity": "sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.10", - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-proposal-private-property-in-object": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.7.tgz", - "integrity": "sha512-rMQkjcOFbm+ufe3bTZLyOfsOUOxyvLXZJCTARhJr+8UMSoZmqTe1K1BgkFcrW37rAchWg57yI69ORxiWvUINuQ==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-create-class-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - } - }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz", - "integrity": "sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-decorators": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.17.0.tgz", - "integrity": "sha512-qWe85yCXsvDEluNP0OyeQjH63DlhAR3W7K9BxxU1MvbDb48tgBG+Ao6IJJ6smPDrrVzSQZrbF6donpkFBMcs3A==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.3" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.7.tgz", - "integrity": "sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz", - "integrity": "sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz", - "integrity": "sha512-MtmUmTJQHCnyJVrScNzNlofQJ3dLFuobYn3mwOTKHnSCMtbNsqvF71GQmJfFjdrXSsAA7iysFmYWw4bXZ20hOg==", - "requires": { - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-remap-async-to-generator": "^7.16.8" - } - }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz", - "integrity": "sha512-JUuzlzmF40Z9cXyytcbZEZKckgrQzChbQJw/5PuEHYeqzCsvebDx0K0jWnIIVcmmDOAVctCgnYs0pMcrYj2zJg==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz", - "integrity": "sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz", - "integrity": "sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-optimise-call-expression": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-replace-supers": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "globals": "^11.1.0" - } - }, - "@babel/plugin-transform-computed-properties": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz", - "integrity": "sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.17.3.tgz", - "integrity": "sha512-dDFzegDYKlPqa72xIlbmSkly5MluLoaC1JswABGktyt6NTXSBcUuse/kWE/wvKFWJHPETpi158qJZFS3JmykJg==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz", - "integrity": "sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz", - "integrity": "sha512-03DvpbRfvWIXyK0/6QiR1KMTWeT6OcQ7tbhjrXyFS02kjuX/mu5Bvnh5SDSWHxyawit2g5aWhKwI86EE7GUnTw==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz", - "integrity": "sha512-8UYLSlyLgRixQvlYH3J2ekXFHDFLQutdy7FfFAMm3CPZ6q9wHCwnUyiXpQCe3gVVnQlHc5nsuiEVziteRNTXEA==", - "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-for-of": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz", - "integrity": "sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-function-name": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz", - "integrity": "sha512-SU/C68YVwTRxqWj5kgsbKINakGag0KTgq9f2iZEXdStoAbOzLHEBRYzImmA6yFo8YZhJVflvXmIHUO7GWHmxxA==", - "requires": { - "@babel/helper-compilation-targets": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-literals": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz", - "integrity": "sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz", - "integrity": "sha512-mBruRMbktKQwbxaJof32LT9KLy2f3gH+27a5XSuXo6h7R3vqltl0PgZ80C8ZMKw98Bf8bqt6BEVi3svOh2PzMw==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-modules-amd": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz", - "integrity": "sha512-KaaEtgBL7FKYwjJ/teH63oAmE3lP34N3kshz8mm4VMAw7U3PxjVwwUmxEFksbgsNUaO3wId9R2AVQYSEGRa2+g==", - "requires": { - "@babel/helper-module-transforms": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz", - "integrity": "sha512-oflKPvsLT2+uKQopesJt3ApiaIS2HW+hzHFcwRNtyDGieAeC/dIHZX8buJQ2J2X1rxGPy4eRcUijm3qcSPjYcA==", - "requires": { - "@babel/helper-module-transforms": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-simple-access": "^7.16.7", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.7.tgz", - "integrity": "sha512-DuK5E3k+QQmnOqBR9UkusByy5WZWGRxfzV529s9nPra1GE7olmxfqO2FHobEOYSPIjPBTr4p66YDcjQnt8cBmw==", - "requires": { - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-module-transforms": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-validator-identifier": "^7.16.7", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-umd": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz", - "integrity": "sha512-EMh7uolsC8O4xhudF2F6wedbSHm1HHZ0C6aJ7K67zcDNidMzVcxWdGr+htW9n21klm+bOn+Rx4CBsAntZd3rEQ==", - "requires": { - "@babel/helper-module-transforms": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz", - "integrity": "sha512-j3Jw+n5PvpmhRR+mrgIh04puSANCk/T/UA3m3P1MjJkhlK906+ApHhDIqBQDdOgL/r1UYpz4GNclTXxyZrYGSw==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.16.7" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz", - "integrity": "sha512-xiLDzWNMfKoGOpc6t3U+etCE2yRnn3SM09BXqWPIZOBpL2gvVrBWUKnsJx0K/ADi5F5YC5f8APFfWrz25TdlGg==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-object-super": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz", - "integrity": "sha512-14J1feiQVWaGvRxj2WjyMuXS2jsBkgB3MdSN5HuC2G5nRspa5RK9COcs82Pwy5BuGcjb+fYaUj94mYcOj7rCvw==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-replace-supers": "^7.16.7" - } - }, - "@babel/plugin-transform-parameters": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz", - "integrity": "sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-property-literals": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz", - "integrity": "sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.7.tgz", - "integrity": "sha512-mF7jOgGYCkSJagJ6XCujSQg+6xC1M77/03K2oBmVJWoFGNUtnVJO4WHKJk3dnPC8HCcj4xBQP1Egm8DWh3Pb3Q==", - "requires": { - "regenerator-transform": "^0.14.2" - } - }, - "@babel/plugin-transform-reserved-words": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz", - "integrity": "sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-runtime": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.17.0.tgz", - "integrity": "sha512-fr7zPWnKXNc1xoHfrIU9mN/4XKX4VLZ45Q+oMhfsYIaHvg7mHgmhfOy/ckRWqDK7XF3QDigRpkh5DKq6+clE8A==", - "requires": { - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "babel-plugin-polyfill-corejs2": "^0.3.0", - "babel-plugin-polyfill-corejs3": "^0.5.0", - "babel-plugin-polyfill-regenerator": "^0.3.0", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz", - "integrity": "sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-spread": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz", - "integrity": "sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0" - } - }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz", - "integrity": "sha512-NJa0Bd/87QV5NZZzTuZG5BPJjLYadeSZ9fO6oOUoL4iQx+9EEuw/eEM92SrsT19Yc2jgB1u1hsjqDtH02c3Drw==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-template-literals": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz", - "integrity": "sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz", - "integrity": "sha512-p2rOixCKRJzpg9JB4gjnG4gjWkWa89ZoYUnl9snJ1cWIcTH/hvxZqfO+WjG6T8DRBpctEol5jw1O5rA8gkCokQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-unicode-escapes": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz", - "integrity": "sha512-TAV5IGahIz3yZ9/Hfv35TV2xEm+kaBDaZQCn2S/hG9/CZ0DktxJv9eKfPc7yYCvOYR4JGx1h8C+jcSOvgaaI/Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz", - "integrity": "sha512-oC5tYYKw56HO75KZVLQ+R/Nl3Hro9kf8iG0hXoaHP7tjAyCpvqBiSNe6vGrZni1Z6MggmUOC6A7VP7AVmw225Q==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/preset-env": { - "version": "7.16.11", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.11.tgz", - "integrity": "sha512-qcmWG8R7ZW6WBRPZK//y+E3Cli151B20W1Rv7ln27vuPaXU/8TKms6jFdiJtF7UDTxcrb7mZd88tAeK9LjdT8g==", - "requires": { - "@babel/compat-data": "^7.16.8", - "@babel/helper-compilation-targets": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-validator-option": "^7.16.7", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.16.7", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.16.7", - "@babel/plugin-proposal-async-generator-functions": "^7.16.8", - "@babel/plugin-proposal-class-properties": "^7.16.7", - "@babel/plugin-proposal-class-static-block": "^7.16.7", - "@babel/plugin-proposal-dynamic-import": "^7.16.7", - "@babel/plugin-proposal-export-namespace-from": "^7.16.7", - "@babel/plugin-proposal-json-strings": "^7.16.7", - "@babel/plugin-proposal-logical-assignment-operators": "^7.16.7", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.7", - "@babel/plugin-proposal-numeric-separator": "^7.16.7", - "@babel/plugin-proposal-object-rest-spread": "^7.16.7", - "@babel/plugin-proposal-optional-catch-binding": "^7.16.7", - "@babel/plugin-proposal-optional-chaining": "^7.16.7", - "@babel/plugin-proposal-private-methods": "^7.16.11", - "@babel/plugin-proposal-private-property-in-object": "^7.16.7", - "@babel/plugin-proposal-unicode-property-regex": "^7.16.7", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.16.7", - "@babel/plugin-transform-async-to-generator": "^7.16.8", - "@babel/plugin-transform-block-scoped-functions": "^7.16.7", - "@babel/plugin-transform-block-scoping": "^7.16.7", - "@babel/plugin-transform-classes": "^7.16.7", - "@babel/plugin-transform-computed-properties": "^7.16.7", - "@babel/plugin-transform-destructuring": "^7.16.7", - "@babel/plugin-transform-dotall-regex": "^7.16.7", - "@babel/plugin-transform-duplicate-keys": "^7.16.7", - "@babel/plugin-transform-exponentiation-operator": "^7.16.7", - "@babel/plugin-transform-for-of": "^7.16.7", - "@babel/plugin-transform-function-name": "^7.16.7", - "@babel/plugin-transform-literals": "^7.16.7", - "@babel/plugin-transform-member-expression-literals": "^7.16.7", - "@babel/plugin-transform-modules-amd": "^7.16.7", - "@babel/plugin-transform-modules-commonjs": "^7.16.8", - "@babel/plugin-transform-modules-systemjs": "^7.16.7", - "@babel/plugin-transform-modules-umd": "^7.16.7", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.16.8", - "@babel/plugin-transform-new-target": "^7.16.7", - "@babel/plugin-transform-object-super": "^7.16.7", - "@babel/plugin-transform-parameters": "^7.16.7", - "@babel/plugin-transform-property-literals": "^7.16.7", - "@babel/plugin-transform-regenerator": "^7.16.7", - "@babel/plugin-transform-reserved-words": "^7.16.7", - "@babel/plugin-transform-shorthand-properties": "^7.16.7", - "@babel/plugin-transform-spread": "^7.16.7", - "@babel/plugin-transform-sticky-regex": "^7.16.7", - "@babel/plugin-transform-template-literals": "^7.16.7", - "@babel/plugin-transform-typeof-symbol": "^7.16.7", - "@babel/plugin-transform-unicode-escapes": "^7.16.7", - "@babel/plugin-transform-unicode-regex": "^7.16.7", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.16.8", - "babel-plugin-polyfill-corejs2": "^0.3.0", - "babel-plugin-polyfill-corejs3": "^0.5.0", - "babel-plugin-polyfill-regenerator": "^0.3.0", - "core-js-compat": "^3.20.2", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "@babel/preset-modules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", - "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - } - }, - "@babel/runtime": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz", - "integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==", - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, - "@babel/template": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", - "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", - "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/parser": "^7.16.7", - "@babel/types": "^7.16.7" - } - }, - "@babel/traverse": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", - "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", - "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.3", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.17.3", - "@babel/types": "^7.17.0", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "@babel/types": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", - "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", - "requires": { - "@babel/helper-validator-identifier": "^7.16.7", - "to-fast-properties": "^2.0.0" - } - }, - "@csstools/convert-colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz", - "integrity": "sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==" - }, - "@eslint/eslintrc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.1.0.tgz", - "integrity": "sha512-C1DfL7XX4nPqGd6jcP01W9pVM1HYCuUkFk1432D7F0v3JSlUIeOYn9oCoi3eoLZ+iwBSb29BMFxxny0YrrEZqg==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.3.1", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "globals": { - "version": "13.12.1", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", - "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - } - } - }, - "@gar/promisify": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", - "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==" - }, - "@hapi/accept": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@hapi/accept/-/accept-5.0.2.tgz", - "integrity": "sha512-CmzBx/bXUR8451fnZRuZAJRlzgm0Jgu5dltTX/bszmR2lheb9BpyN47Q1RbaGTsvFzn0PXAEs+lXDKfshccYZw==", - "requires": { - "@hapi/boom": "9.x.x", - "@hapi/hoek": "9.x.x" - } - }, - "@hapi/ammo": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@hapi/ammo/-/ammo-5.0.1.tgz", - "integrity": "sha512-FbCNwcTbnQP4VYYhLNGZmA76xb2aHg9AMPiy18NZyWMG310P5KdFGyA9v2rm5ujrIny77dEEIkMOwl0Xv+fSSA==", - "requires": { - "@hapi/hoek": "9.x.x" - } - }, - "@hapi/b64": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@hapi/b64/-/b64-5.0.0.tgz", - "integrity": "sha512-ngu0tSEmrezoiIaNGG6rRvKOUkUuDdf4XTPnONHGYfSGRmDqPZX5oJL6HAdKTo1UQHECbdB4OzhWrfgVppjHUw==", - "requires": { - "@hapi/hoek": "9.x.x" - } - }, - "@hapi/boom": { - "version": "9.1.4", - "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-9.1.4.tgz", - "integrity": "sha512-Ls1oH8jaN1vNsqcaHVYJrKmgMcKsC1wcp8bujvXrHaAqD2iDYq3HoOwsxwo09Cuda5R5nC0o0IxlrlTuvPuzSw==", - "requires": { - "@hapi/hoek": "9.x.x" - } - }, - "@hapi/bounce": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/bounce/-/bounce-2.0.0.tgz", - "integrity": "sha512-JesW92uyzOOyuzJKjoLHM1ThiOvHPOLDHw01YV8yh5nCso7sDwJho1h0Ad2N+E62bZyz46TG3xhAi/78Gsct6A==", - "requires": { - "@hapi/boom": "9.x.x", - "@hapi/hoek": "9.x.x" - } - }, - "@hapi/bourne": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-2.0.0.tgz", - "integrity": "sha512-WEezM1FWztfbzqIUbsDzFRVMxSoLy3HugVcux6KDDtTqzPsLE8NDRHfXvev66aH1i2oOKKar3/XDjbvh/OUBdg==" - }, - "@hapi/call": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@hapi/call/-/call-8.0.1.tgz", - "integrity": "sha512-bOff6GTdOnoe5b8oXRV3lwkQSb/LAWylvDMae6RgEWWntd0SHtkYbQukDHKlfaYtVnSAgIavJ0kqszF/AIBb6g==", - "requires": { - "@hapi/boom": "9.x.x", - "@hapi/hoek": "9.x.x" - } - }, - "@hapi/catbox": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/@hapi/catbox/-/catbox-11.1.1.tgz", - "integrity": "sha512-u/8HvB7dD/6X8hsZIpskSDo4yMKpHxFd7NluoylhGrL6cUfYxdQPnvUp9YU2C6F9hsyBVLGulBd9vBN1ebfXOQ==", - "requires": { - "@hapi/boom": "9.x.x", - "@hapi/hoek": "9.x.x", - "@hapi/podium": "4.x.x", - "@hapi/validate": "1.x.x" - } - }, - "@hapi/catbox-memory": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@hapi/catbox-memory/-/catbox-memory-5.0.1.tgz", - "integrity": "sha512-QWw9nOYJq5PlvChLWV8i6hQHJYfvdqiXdvTupJFh0eqLZ64Xir7mKNi96d5/ZMUAqXPursfNDIDxjFgoEDUqeQ==", - "requires": { - "@hapi/boom": "9.x.x", - "@hapi/hoek": "9.x.x" - } - }, - "@hapi/content": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@hapi/content/-/content-5.0.2.tgz", - "integrity": "sha512-mre4dl1ygd4ZyOH3tiYBrOUBzV7Pu/EOs8VLGf58vtOEECWed8Uuw6B4iR9AN/8uQt42tB04qpVaMyoMQh0oMw==", - "requires": { - "@hapi/boom": "9.x.x" - } - }, - "@hapi/cryptiles": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/cryptiles/-/cryptiles-5.1.0.tgz", - "integrity": "sha512-fo9+d1Ba5/FIoMySfMqPBR/7Pa29J2RsiPrl7bkwo5W5o+AN1dAYQRi4SPrPwwVxVGKjgLOEWrsvt1BonJSfLA==", - "requires": { - "@hapi/boom": "9.x.x" - } - }, - "@hapi/file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/file/-/file-2.0.0.tgz", - "integrity": "sha512-WSrlgpvEqgPWkI18kkGELEZfXr0bYLtr16iIN4Krh9sRnzBZN6nnWxHFxtsnP684wueEySBbXPDg/WfA9xJdBQ==" - }, - "@hapi/hapi": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@hapi/hapi/-/hapi-20.2.1.tgz", - "integrity": "sha512-OXAU+yWLwkMfPFic+KITo+XPp6Oxpgc9WUH+pxXWcTIuvWbgco5TC/jS8UDvz+NFF5IzRgF2CL6UV/KLdQYUSQ==", - "requires": { - "@hapi/accept": "^5.0.1", - "@hapi/ammo": "^5.0.1", - "@hapi/boom": "^9.1.0", - "@hapi/bounce": "^2.0.0", - "@hapi/call": "^8.0.0", - "@hapi/catbox": "^11.1.1", - "@hapi/catbox-memory": "^5.0.0", - "@hapi/heavy": "^7.0.1", - "@hapi/hoek": "^9.0.4", - "@hapi/mimos": "^6.0.0", - "@hapi/podium": "^4.1.1", - "@hapi/shot": "^5.0.5", - "@hapi/somever": "^3.0.0", - "@hapi/statehood": "^7.0.3", - "@hapi/subtext": "^7.0.3", - "@hapi/teamwork": "^5.1.0", - "@hapi/topo": "^5.0.0", - "@hapi/validate": "^1.1.1" - } - }, - "@hapi/heavy": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@hapi/heavy/-/heavy-7.0.1.tgz", - "integrity": "sha512-vJ/vzRQ13MtRzz6Qd4zRHWS3FaUc/5uivV2TIuExGTM9Qk+7Zzqj0e2G7EpE6KztO9SalTbiIkTh7qFKj/33cA==", - "requires": { - "@hapi/boom": "9.x.x", - "@hapi/hoek": "9.x.x", - "@hapi/validate": "1.x.x" - } - }, - "@hapi/hoek": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.1.tgz", - "integrity": "sha512-gfta+H8aziZsm8pZa0vj04KO6biEiisppNgA1kbJvFrrWu9Vm7eaUEy76DIxsuTaWvti5fkJVhllWc6ZTE+Mdw==" - }, - "@hapi/inert": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/@hapi/inert/-/inert-6.0.5.tgz", - "integrity": "sha512-eVAdUVhJLmmXLM/Zt7u5H5Vzazs9GKe4zfPK2b97ePHEfs3g/AQkxHfYQjJqMy11hvyB7a21Z6rBEA0R//dtXw==", - "requires": { - "@hapi/ammo": "5.x.x", - "@hapi/boom": "9.x.x", - "@hapi/bounce": "2.x.x", - "@hapi/hoek": "9.x.x", - "@hapi/validate": "1.x.x", - "lru-cache": "^6.0.0" - } - }, - "@hapi/iron": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@hapi/iron/-/iron-6.0.0.tgz", - "integrity": "sha512-zvGvWDufiTGpTJPG1Y/McN8UqWBu0k/xs/7l++HVU535NLHXsHhy54cfEMdW7EjwKfbBfM9Xy25FmTiobb7Hvw==", - "requires": { - "@hapi/b64": "5.x.x", - "@hapi/boom": "9.x.x", - "@hapi/bourne": "2.x.x", - "@hapi/cryptiles": "5.x.x", - "@hapi/hoek": "9.x.x" - } - }, - "@hapi/mimos": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@hapi/mimos/-/mimos-6.0.0.tgz", - "integrity": "sha512-Op/67tr1I+JafN3R3XN5DucVSxKRT/Tc+tUszDwENoNpolxeXkhrJ2Czt6B6AAqrespHoivhgZBWYSuANN9QXg==", - "requires": { - "@hapi/hoek": "9.x.x", - "mime-db": "1.x.x" - } - }, - "@hapi/nigel": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@hapi/nigel/-/nigel-4.0.2.tgz", - "integrity": "sha512-ht2KoEsDW22BxQOEkLEJaqfpoKPXxi7tvabXy7B/77eFtOyG5ZEstfZwxHQcqAiZhp58Ae5vkhEqI03kawkYNw==", - "requires": { - "@hapi/hoek": "^9.0.4", - "@hapi/vise": "^4.0.0" - } - }, - "@hapi/pez": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@hapi/pez/-/pez-5.0.3.tgz", - "integrity": "sha512-mpikYRJjtrbJgdDHG/H9ySqYqwJ+QU/D7FXsYciS9P7NYBXE2ayKDAy3H0ou6CohOCaxPuTV4SZ0D936+VomHA==", - "requires": { - "@hapi/b64": "5.x.x", - "@hapi/boom": "9.x.x", - "@hapi/content": "^5.0.2", - "@hapi/hoek": "9.x.x", - "@hapi/nigel": "4.x.x" - } - }, - "@hapi/podium": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@hapi/podium/-/podium-4.1.3.tgz", - "integrity": "sha512-ljsKGQzLkFqnQxE7qeanvgGj4dejnciErYd30dbrYzUOF/FyS/DOF97qcrT3bhoVwCYmxa6PEMhxfCPlnUcD2g==", - "requires": { - "@hapi/hoek": "9.x.x", - "@hapi/teamwork": "5.x.x", - "@hapi/validate": "1.x.x" - } - }, - "@hapi/shot": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@hapi/shot/-/shot-5.0.5.tgz", - "integrity": "sha512-x5AMSZ5+j+Paa8KdfCoKh+klB78otxF+vcJR/IoN91Vo2e5ulXIW6HUsFTCU+4W6P/Etaip9nmdAx2zWDimB2A==", - "requires": { - "@hapi/hoek": "9.x.x", - "@hapi/validate": "1.x.x" - } - }, - "@hapi/somever": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@hapi/somever/-/somever-3.0.1.tgz", - "integrity": "sha512-4ZTSN3YAHtgpY/M4GOtHUXgi6uZtG9nEZfNI6QrArhK0XN/RDVgijlb9kOmXwCR5VclDSkBul9FBvhSuKXx9+w==", - "requires": { - "@hapi/bounce": "2.x.x", - "@hapi/hoek": "9.x.x" - } - }, - "@hapi/statehood": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/@hapi/statehood/-/statehood-7.0.3.tgz", - "integrity": "sha512-pYB+pyCHkf2Amh67QAXz7e/DN9jcMplIL7Z6N8h0K+ZTy0b404JKPEYkbWHSnDtxLjJB/OtgElxocr2fMH4G7w==", - "requires": { - "@hapi/boom": "9.x.x", - "@hapi/bounce": "2.x.x", - "@hapi/bourne": "2.x.x", - "@hapi/cryptiles": "5.x.x", - "@hapi/hoek": "9.x.x", - "@hapi/iron": "6.x.x", - "@hapi/validate": "1.x.x" - } - }, - "@hapi/subtext": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/@hapi/subtext/-/subtext-7.0.3.tgz", - "integrity": "sha512-CekDizZkDGERJ01C0+TzHlKtqdXZxzSWTOaH6THBrbOHnsr3GY+yiMZC+AfNCypfE17RaIakGIAbpL2Tk1z2+A==", - "requires": { - "@hapi/boom": "9.x.x", - "@hapi/bourne": "2.x.x", - "@hapi/content": "^5.0.2", - "@hapi/file": "2.x.x", - "@hapi/hoek": "9.x.x", - "@hapi/pez": "^5.0.1", - "@hapi/wreck": "17.x.x" - } - }, - "@hapi/teamwork": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/teamwork/-/teamwork-5.1.0.tgz", - "integrity": "sha512-llqoQTrAJDTXxG3c4Kz/uzhBS1TsmSBa/XG5SPcVXgmffHE1nFtyLIK0hNJHCB3EuBKT84adzd1hZNY9GJLWtg==" - }, - "@hapi/topo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", - "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", - "requires": { - "@hapi/hoek": "^9.0.0" - } - }, - "@hapi/validate": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@hapi/validate/-/validate-1.1.3.tgz", - "integrity": "sha512-/XMR0N0wjw0Twzq2pQOzPBZlDzkekGcoCtzO314BpIEsbXdYGthQUbxgkGDf4nhk1+IPDAsXqWjMohRQYO06UA==", - "requires": { - "@hapi/hoek": "^9.0.0", - "@hapi/topo": "^5.0.0" - } - }, - "@hapi/vise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@hapi/vise/-/vise-4.0.0.tgz", - "integrity": "sha512-eYyLkuUiFZTer59h+SGy7hUm+qE9p+UemePTHLlIWppEd+wExn3Df5jO04bFQTm7nleF5V8CtuYQYb+VFpZ6Sg==", - "requires": { - "@hapi/hoek": "9.x.x" - } - }, - "@hapi/wreck": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/@hapi/wreck/-/wreck-17.1.0.tgz", - "integrity": "sha512-nx6sFyfqOpJ+EFrHX+XWwJAxs3ju4iHdbB/bwR8yTNZOiYmuhA8eCe7lYPtYmb4j7vyK/SlbaQsmTtUrMvPEBw==", - "requires": { - "@hapi/boom": "9.x.x", - "@hapi/bourne": "2.x.x", - "@hapi/hoek": "9.x.x" - } - }, - "@humanwhocodes/config-array": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.3.tgz", - "integrity": "sha512-3xSMlXHh03hCcCmFc0rbKp3Ivt2PFEJnQUJDDMTJQ2wkECZWdq4GePs2ctc5H8zV+cHPaq8k2vU8mrQjA6iHdQ==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - }, - "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "@jridgewell/resolve-uri": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", - "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==" - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.11", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", - "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==" - }, - "@jridgewell/trace-mapping": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", - "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@npmcli/fs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", - "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", - "requires": { - "@gar/promisify": "^1.0.1", - "semver": "^7.3.5" - } - }, - "@npmcli/move-file": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", - "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", - "requires": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "@nuxt/babel-preset-app": { - "version": "2.15.8", - "resolved": "https://registry.npmjs.org/@nuxt/babel-preset-app/-/babel-preset-app-2.15.8.tgz", - "integrity": "sha512-z23bY5P7dLTmIbk0ZZ95mcEXIEER/mQCOqEp2vxnzG2nurks+vq6tNcUAXqME1Wl6aXWTXlqky5plBe7RQHzhQ==", - "requires": { - "@babel/compat-data": "^7.14.0", - "@babel/core": "^7.14.0", - "@babel/helper-compilation-targets": "^7.13.16", - "@babel/helper-module-imports": "^7.13.12", - "@babel/plugin-proposal-class-properties": "^7.13.0", - "@babel/plugin-proposal-decorators": "^7.13.15", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8", - "@babel/plugin-proposal-optional-chaining": "^7.13.12", - "@babel/plugin-proposal-private-methods": "^7.13.0", - "@babel/plugin-transform-runtime": "^7.13.15", - "@babel/preset-env": "^7.14.1", - "@babel/runtime": "^7.14.0", - "@vue/babel-preset-jsx": "^1.2.4", - "core-js": "^2.6.5", - "core-js-compat": "^3.12.1", - "regenerator-runtime": "^0.13.7" - } - }, - "@nuxt/builder": { - "version": "2.15.8", - "resolved": "https://registry.npmjs.org/@nuxt/builder/-/builder-2.15.8.tgz", - "integrity": "sha512-WVhN874LFMdgRiJqpxmeKI+vh5lhCUBVOyR9PhL1m1V/GV3fb+Dqc1BKS6XgayrWAWavPLveCJmQ/FID0puOfQ==", - "requires": { - "@nuxt/devalue": "^1.2.5", - "@nuxt/utils": "2.15.8", - "@nuxt/vue-app": "2.15.8", - "@nuxt/webpack": "2.15.8", - "chalk": "^4.1.1", - "chokidar": "^3.5.1", - "consola": "^2.15.3", - "fs-extra": "^9.1.0", - "glob": "^7.1.7", - "hash-sum": "^2.0.0", - "ignore": "^5.1.8", - "lodash": "^4.17.21", - "pify": "^5.0.0", - "serialize-javascript": "^5.0.1", - "upath": "^2.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@nuxt/cli": { - "version": "2.15.8", - "resolved": "https://registry.npmjs.org/@nuxt/cli/-/cli-2.15.8.tgz", - "integrity": "sha512-KcGIILW/dAjBKea1DHsuLCG1sNzhzETShwT23DhXWO304qL8ljf4ndYKzn2RenzauGRGz7MREta80CbJCkLSHw==", - "requires": { - "@nuxt/config": "2.15.8", - "@nuxt/utils": "2.15.8", - "boxen": "^5.0.1", - "chalk": "^4.1.1", - "compression": "^1.7.4", - "connect": "^3.7.0", - "consola": "^2.15.3", - "crc": "^3.8.0", - "defu": "^4.0.1", - "destr": "^1.1.0", - "execa": "^5.0.0", - "exit": "^0.1.2", - "fs-extra": "^9.1.0", - "globby": "^11.0.3", - "hable": "^3.0.0", - "lodash": "^4.17.21", - "minimist": "^1.2.5", - "opener": "1.5.2", - "pretty-bytes": "^5.6.0", - "semver": "^7.3.5", - "serve-static": "^1.14.1", - "std-env": "^2.3.0", - "upath": "^2.0.1", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "defu": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/defu/-/defu-4.0.1.tgz", - "integrity": "sha512-lC+G0KvvWRbisQa50+iFelm3/eMmwo4IlBmfASOVlw9MZpHHyQeVsZxc5j23+TQy5ydgEoTVSrWl7ptou1kzJQ==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - } - } - }, - "@nuxt/components": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@nuxt/components/-/components-2.2.1.tgz", - "integrity": "sha512-r1LHUzifvheTnJtYrMuA+apgsrEJbxcgFKIimeXKb+jl8TnPWdV3egmrxBCaDJchrtY/wmHyP47tunsft7AWwg==", - "requires": { - "chalk": "^4.1.2", - "chokidar": "^3.5.2", - "glob": "^7.1.7", - "globby": "^11.0.4", - "scule": "^0.2.1", - "semver": "^7.3.5", - "upath": "^2.0.1", - "vue-template-compiler": "^2.6.14" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@nuxt/config": { - "version": "2.15.8", - "resolved": "https://registry.npmjs.org/@nuxt/config/-/config-2.15.8.tgz", - "integrity": "sha512-KMQbjmUf9RVHeTZEf7zcuFnh03XKZioYhok6GOCY+leu3g5n/UhyPvLnTsgTfsLWohqoRoOm94u4A+tNYwn9VQ==", - "requires": { - "@nuxt/utils": "2.15.8", - "consola": "^2.15.3", - "defu": "^4.0.1", - "destr": "^1.1.0", - "dotenv": "^9.0.2", - "lodash": "^4.17.21", - "rc9": "^1.2.0", - "std-env": "^2.3.0", - "ufo": "^0.7.4" - }, - "dependencies": { - "defu": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/defu/-/defu-4.0.1.tgz", - "integrity": "sha512-lC+G0KvvWRbisQa50+iFelm3/eMmwo4IlBmfASOVlw9MZpHHyQeVsZxc5j23+TQy5ydgEoTVSrWl7ptou1kzJQ==" - }, - "dotenv": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-9.0.2.tgz", - "integrity": "sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==" - } - } - }, - "@nuxt/core": { - "version": "2.15.8", - "resolved": "https://registry.npmjs.org/@nuxt/core/-/core-2.15.8.tgz", - "integrity": "sha512-31pipWRvwHiyB5VDqffgSO7JtmHxyzgshIzuZzSinxMbVmK3BKsOwacD/51oEyELgrPlUgLqcY9dg+RURgmHGQ==", - "requires": { - "@nuxt/config": "2.15.8", - "@nuxt/server": "2.15.8", - "@nuxt/utils": "2.15.8", - "consola": "^2.15.3", - "fs-extra": "^9.1.0", - "hable": "^3.0.0", - "hash-sum": "^2.0.0", - "lodash": "^4.17.21" - } - }, - "@nuxt/devalue": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@nuxt/devalue/-/devalue-1.2.5.tgz", - "integrity": "sha512-Tg86C7tqzvZtZli2BQVqgzZN136mZDTgauvJXagglKkP2xt5Kw3NUIiJyjX0Ww/IZy2xVmD0LN+CEPpij4dB2g==", - "requires": { - "consola": "^2.9.0" - } - }, - "@nuxt/friendly-errors-webpack-plugin": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@nuxt/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-2.5.2.tgz", - "integrity": "sha512-LLc+90lnxVbpKkMqk5z1EWpXoODhc6gRkqqXJCInJwF5xabHAE7biFvbULfvTRmtaTzAaP8IV4HQDLUgeAUTTw==", - "requires": { - "chalk": "^2.3.2", - "consola": "^2.6.0", - "error-stack-parser": "^2.0.0", - "string-width": "^4.2.3" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@nuxt/generator": { - "version": "2.15.8", - "resolved": "https://registry.npmjs.org/@nuxt/generator/-/generator-2.15.8.tgz", - "integrity": "sha512-hreLdYbBIe3SWcP8LsMG7OlDTx2ZVucX8+f8Vrjft3Q4r8iCwLMYC1s1N5etxeHAZfS2kZiLmF92iscOdfbgMQ==", - "requires": { - "@nuxt/utils": "2.15.8", - "chalk": "^4.1.1", - "consola": "^2.15.3", - "defu": "^4.0.1", - "devalue": "^2.0.1", - "fs-extra": "^9.1.0", - "html-minifier": "^4.0.0", - "node-html-parser": "^3.2.0", - "ufo": "^0.7.4" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "defu": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/defu/-/defu-4.0.1.tgz", - "integrity": "sha512-lC+G0KvvWRbisQa50+iFelm3/eMmwo4IlBmfASOVlw9MZpHHyQeVsZxc5j23+TQy5ydgEoTVSrWl7ptou1kzJQ==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@nuxt/loading-screen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nuxt/loading-screen/-/loading-screen-2.0.4.tgz", - "integrity": "sha512-xpEDAoRu75tLUYCkUJCIvJkWJSuwr8pqomvQ+fkXpSrkxZ/9OzlBFjAbVdOAWTMj4aV/LVQso4vcEdircKeFIQ==", - "requires": { - "connect": "^3.7.0", - "defu": "^5.0.0", - "get-port-please": "^2.2.0", - "node-res": "^5.0.1", - "serve-static": "^1.14.1" - } - }, - "@nuxt/opencollective": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@nuxt/opencollective/-/opencollective-0.3.2.tgz", - "integrity": "sha512-XG7rUdXG9fcafu9KTDIYjJSkRO38EwjlKYIb5TQ/0WDbiTUTtUtgncMscKOYzfsY86kGs05pAuMOR+3Fi0aN3A==", - "requires": { - "chalk": "^4.1.0", - "consola": "^2.15.0", - "node-fetch": "^2.6.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@nuxt/server": { - "version": "2.15.8", - "resolved": "https://registry.npmjs.org/@nuxt/server/-/server-2.15.8.tgz", - "integrity": "sha512-E4EtXudxtWQBUHMHOxFwm5DlPOkJbW+iF1+zc0dGmXLscep1KWPrlP+4nrpZj8/UKzpupamE8ZTS9I4IbnExVA==", - "requires": { - "@nuxt/utils": "2.15.8", - "@nuxt/vue-renderer": "2.15.8", - "@nuxtjs/youch": "^4.2.3", - "compression": "^1.7.4", - "connect": "^3.7.0", - "consola": "^2.15.3", - "etag": "^1.8.1", - "fresh": "^0.5.2", - "fs-extra": "^9.1.0", - "ip": "^1.1.5", - "launch-editor-middleware": "^2.2.1", - "on-headers": "^1.0.2", - "pify": "^5.0.0", - "serve-placeholder": "^1.2.3", - "serve-static": "^1.14.1", - "server-destroy": "^1.0.1", - "ufo": "^0.7.4" - } - }, - "@nuxt/telemetry": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/@nuxt/telemetry/-/telemetry-1.3.6.tgz", - "integrity": "sha512-sZpLf/rU3cvN8/alR1HpJIl3mHPA1GOg41GKdOOrtw7Gi/lCEVk4hK+lpXgYInZ2n6i1JyknpKhM9YzX2RU33w==", - "requires": { - "arg": "^5.0.0", - "chalk": "^4.1.1", - "ci-info": "^3.1.1", - "consola": "^2.15.3", - "create-require": "^1.1.1", - "defu": "^5.0.0", - "destr": "^1.1.0", - "dotenv": "^9.0.2", - "fs-extra": "^8.1.0", - "git-url-parse": "^11.4.4", - "inquirer": "^7.3.3", - "is-docker": "^2.2.1", - "jiti": "^1.9.2", - "nanoid": "^3.1.23", - "node-fetch": "^2.6.1", - "parse-git-config": "^3.0.0", - "rc9": "^1.2.0", - "std-env": "^2.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "dotenv": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-9.0.2.tgz", - "integrity": "sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==" - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - } - } - }, - "@nuxt/utils": { - "version": "2.15.8", - "resolved": "https://registry.npmjs.org/@nuxt/utils/-/utils-2.15.8.tgz", - "integrity": "sha512-e0VBarUbPiQ4ZO1T58puoFIuXme7L5gk1QfwyxOONlp2ryE7aRyZ8X/mryuOiIeyP64c4nwSUtN7q9EUWRb7Lg==", - "requires": { - "consola": "^2.15.3", - "create-require": "^1.1.1", - "fs-extra": "^9.1.0", - "hash-sum": "^2.0.0", - "jiti": "^1.9.2", - "lodash": "^4.17.21", - "proper-lockfile": "^4.1.2", - "semver": "^7.3.5", - "serialize-javascript": "^5.0.1", - "signal-exit": "^3.0.3", - "ua-parser-js": "^0.7.28", - "ufo": "^0.7.4" - } - }, - "@nuxt/vue-app": { - "version": "2.15.8", - "resolved": "https://registry.npmjs.org/@nuxt/vue-app/-/vue-app-2.15.8.tgz", - "integrity": "sha512-FJf9FSMPsWT3BqkS37zEuPTxLKzSg2EIwp1sP8Eou25eE08qxRfe2PwTVA8HnXUPNdpz2uk/T9DlNw+JraiFRQ==", - "requires": { - "node-fetch": "^2.6.1", - "ufo": "^0.7.4", - "unfetch": "^4.2.0", - "vue": "^2.6.12", - "vue-client-only": "^2.0.0", - "vue-meta": "^2.4.0", - "vue-no-ssr": "^1.1.1", - "vue-router": "^3.5.1", - "vue-template-compiler": "^2.6.12", - "vuex": "^3.6.2" - } - }, - "@nuxt/vue-renderer": { - "version": "2.15.8", - "resolved": "https://registry.npmjs.org/@nuxt/vue-renderer/-/vue-renderer-2.15.8.tgz", - "integrity": "sha512-54I/k+4G6axP9XVYYdtH6M1S6T49OIkarpF6/yIJj0yi3S/2tdJ9eUyfoLZ9EbquZFDDRHBxSswTtr2l/eakPw==", - "requires": { - "@nuxt/devalue": "^1.2.5", - "@nuxt/utils": "2.15.8", - "consola": "^2.15.3", - "defu": "^4.0.1", - "fs-extra": "^9.1.0", - "lodash": "^4.17.21", - "lru-cache": "^5.1.1", - "ufo": "^0.7.4", - "vue": "^2.6.12", - "vue-meta": "^2.4.0", - "vue-server-renderer": "^2.6.12" - }, - "dependencies": { - "defu": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/defu/-/defu-4.0.1.tgz", - "integrity": "sha512-lC+G0KvvWRbisQa50+iFelm3/eMmwo4IlBmfASOVlw9MZpHHyQeVsZxc5j23+TQy5ydgEoTVSrWl7ptou1kzJQ==" - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "requires": { - "yallist": "^3.0.2" - } - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - } - } - }, - "@nuxt/webpack": { - "version": "2.15.8", - "resolved": "https://registry.npmjs.org/@nuxt/webpack/-/webpack-2.15.8.tgz", - "integrity": "sha512-CzJYFed23Ow/UK0+cI1FVthDre1p2qc8Q97oizG39d3/SIh3aUHjgj8c60wcR+RSxVO0FzZMXkmq02NmA7vWJg==", - "requires": { - "@babel/core": "^7.14.0", - "@nuxt/babel-preset-app": "2.15.8", - "@nuxt/friendly-errors-webpack-plugin": "^2.5.1", - "@nuxt/utils": "2.15.8", - "babel-loader": "^8.2.2", - "cache-loader": "^4.1.0", - "caniuse-lite": "^1.0.30001228", - "consola": "^2.15.3", - "css-loader": "^4.3.0", - "cssnano": "^4.1.11", - "eventsource-polyfill": "^0.9.6", - "extract-css-chunks-webpack-plugin": "^4.9.0", - "file-loader": "^6.2.0", - "glob": "^7.1.7", - "hard-source-webpack-plugin": "^0.13.1", - "hash-sum": "^2.0.0", - "html-webpack-plugin": "^4.5.1", - "lodash": "^4.17.21", - "memory-fs": "^0.5.0", - "optimize-css-assets-webpack-plugin": "^5.0.4", - "pify": "^5.0.0", - "pnp-webpack-plugin": "^1.6.4", - "postcss": "^7.0.32", - "postcss-import": "^12.0.1", - "postcss-import-resolver": "^2.0.0", - "postcss-loader": "^3.0.0", - "postcss-preset-env": "^6.7.0", - "postcss-url": "^8.0.0", - "semver": "^7.3.5", - "std-env": "^2.3.0", - "style-resources-loader": "^1.4.1", - "terser-webpack-plugin": "^4.2.3", - "thread-loader": "^3.0.4", - "time-fix-plugin": "^2.0.7", - "ufo": "^0.7.4", - "url-loader": "^4.1.1", - "vue-loader": "^15.9.7", - "vue-style-loader": "^4.1.3", - "vue-template-compiler": "^2.6.12", - "webpack": "^4.46.0", - "webpack-bundle-analyzer": "^4.4.1", - "webpack-dev-middleware": "^4.2.0", - "webpack-hot-middleware": "^2.25.0", - "webpack-node-externals": "^3.0.0", - "webpackbar": "^4.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "@nuxtjs/axios": { - "version": "5.13.6", - "resolved": "https://registry.npmjs.org/@nuxtjs/axios/-/axios-5.13.6.tgz", - "integrity": "sha512-XS+pOE0xsDODs1zAIbo95A0LKlilvJi8YW0NoXYuq3/jjxGgWDxizZ6Yx0AIIjZOoGsXJOPc0/BcnSEUQ2mFBA==", - "requires": { - "@nuxtjs/proxy": "^2.1.0", - "axios": "^0.21.1", - "axios-retry": "^3.1.9", - "consola": "^2.15.3", - "defu": "^5.0.0" - }, - "dependencies": { - "axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "requires": { - "follow-redirects": "^1.14.0" - } - } - } - }, - "@nuxtjs/dotenv": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@nuxtjs/dotenv/-/dotenv-1.4.1.tgz", - "integrity": "sha512-DpdObsvRwC8d89I9mzz6pBg6e/PEXHazDM57DOI1mmML2ZjHfQ/DvkjlSzUL7T+TnW3b/a4Ks5wQx08DqFBmeQ==", - "requires": { - "consola": "^2.10.1", - "dotenv": "^8.1.0" - } - }, - "@nuxtjs/google-analytics": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@nuxtjs/google-analytics/-/google-analytics-2.4.0.tgz", - "integrity": "sha512-rDQTwHIjyjVrx8GywHPuWykJ3jRFGaHl5Iqji/y8tQWUc0yGEeHxOoR0yimzxnTS1Ph2/PubQYpgnVeEPEdL/A==", - "requires": { - "vue-analytics": "^5.22.1" - } - }, - "@nuxtjs/hapi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@nuxtjs/hapi/-/hapi-3.0.0.tgz", - "integrity": "sha512-Grhc/JCCNr/z+NI+MZOQIk2UIEgQzK/e3PhkI6wU0fbaTAgqNUi0PGY2Meor/iJSiKDdOiR+PkXE+B1ClucZ1Q==" - }, - "@nuxtjs/markdownit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@nuxtjs/markdownit/-/markdownit-2.0.0.tgz", - "integrity": "sha512-YAEK/s0IzdWK1L74WKTQSMcvNhGgOW0xIWdu5VMxDo1NkNpm/0CbJZgSPt1JYAnT8r8r6wVQ5SY1v/1MZanPlQ==", - "requires": { - "@nuxtjs/markdownit-loader": "^1.1.1", - "defu": "^3.2.2", - "raw-loader": "^4.0.2" - }, - "dependencies": { - "defu": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/defu/-/defu-3.2.2.tgz", - "integrity": "sha512-8UWj5lNv7HD+kB0e9w77Z7TdQlbUYDVWqITLHNqFIn6khrNHv5WQo38Dcm1f6HeNyZf0U7UbPf6WeZDSdCzGDQ==" - } - } - }, - "@nuxtjs/markdownit-loader": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@nuxtjs/markdownit-loader/-/markdownit-loader-1.2.0.tgz", - "integrity": "sha512-D6m4578NavamwD03nOU3H3NkS2zYfFJSMChUczlCGDx05DgAoenY4GdCmML1CnAEH/Cv6Bf230RIwDnD926oyQ==", - "requires": { - "highlight.js": "^10.5.0", - "loader-utils": "^1.1.0", - "markdown-it": "^8.3.1" - }, - "dependencies": { - "highlight.js": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==" - } - } - }, - "@nuxtjs/proxy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@nuxtjs/proxy/-/proxy-2.1.0.tgz", - "integrity": "sha512-/qtoeqXgZ4Mg6LRg/gDUZQrFpOlOdHrol/vQYMnKu3aN3bP90UfOUB3QSDghUUK7OISAJ0xp8Ld78aHyCTcKCQ==", - "requires": { - "http-proxy-middleware": "^1.0.6" - } - }, - "@nuxtjs/pwa": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/@nuxtjs/pwa/-/pwa-3.3.5.tgz", - "integrity": "sha512-8tTmW8DBspWxlJwTimOHTkwfkwPpL9wIcGmy75Gcmin+c9YtX2Ehxmhgt/TLFOC9XsLAqojqynw3/Agr/9OE1w==", - "requires": { - "clone-deep": "^4.0.1", - "defu": "^3.2.2", - "execa": "^5.0.0", - "fs-extra": "^9.1.0", - "hasha": "^5.2.2", - "jimp-compact": "^0.16.1", - "lodash.template": "^4.5.0", - "serve-static": "^1.14.1", - "workbox-cdn": "^5.1.4" - }, - "dependencies": { - "defu": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/defu/-/defu-3.2.2.tgz", - "integrity": "sha512-8UWj5lNv7HD+kB0e9w77Z7TdQlbUYDVWqITLHNqFIn6khrNHv5WQo38Dcm1f6HeNyZf0U7UbPf6WeZDSdCzGDQ==" - } - } - }, - "@nuxtjs/svg": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@nuxtjs/svg/-/svg-0.4.0.tgz", - "integrity": "sha512-XF8uvV5YKBPAJr52SFRVkhltAsjCBTwwTc4GTysSm8WPYB2utJLY48qXdVC/J9dNQiMd7NHo1xmEYEqQfzqpqg==", - "requires": { - "file-loader": "^6.0.0", - "raw-loader": "^4.0.0", - "svg-sprite-loader": "^5.2.1", - "url-loader": "^4.1.0", - "vue-svg-loader": "^0.16.0" - } - }, - "@nuxtjs/youch": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/@nuxtjs/youch/-/youch-4.2.3.tgz", - "integrity": "sha512-XiTWdadTwtmL/IGkNqbVe+dOlT+IMvcBu7TvKI7plWhVQeBCQ9iKhk3jgvVWFyiwL2yHJDlEwOM5v9oVES5Xmw==", - "requires": { - "cookie": "^0.3.1", - "mustache": "^2.3.0", - "stack-trace": "0.0.10" - }, - "dependencies": { - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" - } - } - }, - "@polka/url": { - "version": "1.0.0-next.21", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", - "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==" - }, - "@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true - }, - "@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, - "requires": { - "defer-to-connect": "^1.0.1" - } - }, - "@types/cookie": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.3.3.tgz", - "integrity": "sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow==" - }, - "@types/html-minifier-terser": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.2.tgz", - "integrity": "sha512-h4lTMgMJctJybDp8CQrxTUiiYmedihHWkjnF/8Pxseu2S6Nlfcy8kwboQ8yejh456rP2yWoEVm1sS/FVsfM48w==" - }, - "@types/http-proxy": { - "version": "1.17.8", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.8.tgz", - "integrity": "sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA==", - "requires": { - "@types/node": "*" - } - }, - "@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==" - }, - "@types/node": { - "version": "17.0.19", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.19.tgz", - "integrity": "sha512-PfeQhvcMR4cPFVuYfBN4ifG7p9c+Dlh3yUZR6k+5yQK7wX3gDgVxBly4/WkBRs9x4dmcy1TVl08SY67wwtEvmA==" - }, - "@types/q": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz", - "integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==" - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==" - }, - "@types/tapable": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.8.tgz", - "integrity": "sha512-ipixuVrh2OdNmauvtT51o3d8z12p6LtFW9in7U79der/kwejjdNchQC5UMn5u/KxNoM7VHHOs/l8KS8uHxhODQ==" - }, - "@types/uglify-js": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.13.1.tgz", - "integrity": "sha512-O3MmRAk6ZuAKa9CHgg0Pr0+lUOqoMLpc9AS4R8ano2auvsg7IE8syF3Xh/NPr26TWklxYcqoEEFdzLLs1fV9PQ==", - "requires": { - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "@types/webpack": { - "version": "4.41.32", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.32.tgz", - "integrity": "sha512-cb+0ioil/7oz5//7tZUSwbrSAN/NWHrQylz5cW8G0dWTcF/g+/dSdMlKVZspBYuMAN1+WnwHrkxiRrLcwd0Heg==", - "requires": { - "@types/node": "*", - "@types/tapable": "^1", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "anymatch": "^3.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "@types/webpack-sources": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-3.2.0.tgz", - "integrity": "sha512-Ft7YH3lEVRQ6ls8k4Ff1oB4jN6oy/XmU6tQISKdhfh+1mR+viZFphS6WL0IrtDOzvefmJg5a0s7ZQoRXwqTEFg==", - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.7.3" - }, - "dependencies": { - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" - } - } - }, - "@vue/babel-helper-vue-jsx-merge-props": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.2.1.tgz", - "integrity": "sha512-QOi5OW45e2R20VygMSNhyQHvpdUwQZqGPc748JLGCYEy+yp8fNFNdbNIGAgZmi9e+2JHPd6i6idRuqivyicIkA==" - }, - "@vue/babel-plugin-transform-vue-jsx": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.2.1.tgz", - "integrity": "sha512-HJuqwACYehQwh1fNT8f4kyzqlNMpBuUK4rSiSES5D4QsYncv5fxFsLyrxFPG2ksO7t5WP+Vgix6tt6yKClwPzA==", - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/plugin-syntax-jsx": "^7.2.0", - "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1", - "html-tags": "^2.0.0", - "lodash.kebabcase": "^4.1.1", - "svg-tags": "^1.0.0" - } - }, - "@vue/babel-preset-jsx": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@vue/babel-preset-jsx/-/babel-preset-jsx-1.2.4.tgz", - "integrity": "sha512-oRVnmN2a77bYDJzeGSt92AuHXbkIxbf/XXSE3klINnh9AXBmVS1DGa1f0d+dDYpLfsAKElMnqKTQfKn7obcL4w==", - "requires": { - "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1", - "@vue/babel-plugin-transform-vue-jsx": "^1.2.1", - "@vue/babel-sugar-composition-api-inject-h": "^1.2.1", - "@vue/babel-sugar-composition-api-render-instance": "^1.2.4", - "@vue/babel-sugar-functional-vue": "^1.2.2", - "@vue/babel-sugar-inject-h": "^1.2.2", - "@vue/babel-sugar-v-model": "^1.2.3", - "@vue/babel-sugar-v-on": "^1.2.3" - } - }, - "@vue/babel-sugar-composition-api-inject-h": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-composition-api-inject-h/-/babel-sugar-composition-api-inject-h-1.2.1.tgz", - "integrity": "sha512-4B3L5Z2G+7s+9Bwbf+zPIifkFNcKth7fQwekVbnOA3cr3Pq71q71goWr97sk4/yyzH8phfe5ODVzEjX7HU7ItQ==", - "requires": { - "@babel/plugin-syntax-jsx": "^7.2.0" - } - }, - "@vue/babel-sugar-composition-api-render-instance": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-composition-api-render-instance/-/babel-sugar-composition-api-render-instance-1.2.4.tgz", - "integrity": "sha512-joha4PZznQMsxQYXtR3MnTgCASC9u3zt9KfBxIeuI5g2gscpTsSKRDzWQt4aqNIpx6cv8On7/m6zmmovlNsG7Q==", - "requires": { - "@babel/plugin-syntax-jsx": "^7.2.0" - } - }, - "@vue/babel-sugar-functional-vue": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-functional-vue/-/babel-sugar-functional-vue-1.2.2.tgz", - "integrity": "sha512-JvbgGn1bjCLByIAU1VOoepHQ1vFsroSA/QkzdiSs657V79q6OwEWLCQtQnEXD/rLTA8rRit4rMOhFpbjRFm82w==", - "requires": { - "@babel/plugin-syntax-jsx": "^7.2.0" - } - }, - "@vue/babel-sugar-inject-h": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-inject-h/-/babel-sugar-inject-h-1.2.2.tgz", - "integrity": "sha512-y8vTo00oRkzQTgufeotjCLPAvlhnpSkcHFEp60+LJUwygGcd5Chrpn5480AQp/thrxVm8m2ifAk0LyFel9oCnw==", - "requires": { - "@babel/plugin-syntax-jsx": "^7.2.0" - } - }, - "@vue/babel-sugar-v-model": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.2.3.tgz", - "integrity": "sha512-A2jxx87mySr/ulAsSSyYE8un6SIH0NWHiLaCWpodPCVOlQVODCaSpiR4+IMsmBr73haG+oeCuSvMOM+ttWUqRQ==", - "requires": { - "@babel/plugin-syntax-jsx": "^7.2.0", - "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1", - "@vue/babel-plugin-transform-vue-jsx": "^1.2.1", - "camelcase": "^5.0.0", - "html-tags": "^2.0.0", - "svg-tags": "^1.0.0" - } - }, - "@vue/babel-sugar-v-on": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.2.3.tgz", - "integrity": "sha512-kt12VJdz/37D3N3eglBywV8GStKNUhNrsxChXIV+o0MwVXORYuhDTHJRKPgLJRb/EY3vM2aRFQdxJBp9CLikjw==", - "requires": { - "@babel/plugin-syntax-jsx": "^7.2.0", - "@vue/babel-plugin-transform-vue-jsx": "^1.2.1", - "camelcase": "^5.0.0" - } - }, - "@vue/component-compiler-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.3.0.tgz", - "integrity": "sha512-97sfH2mYNU+2PzGrmK2haqffDpVASuib9/w2/noxiFi31Z54hW+q3izKQXXQZSNhtiUpAI36uSuYepeBe4wpHQ==", - "requires": { - "consolidate": "^0.15.1", - "hash-sum": "^1.0.2", - "lru-cache": "^4.1.2", - "merge-source-map": "^1.1.0", - "postcss": "^7.0.36", - "postcss-selector-parser": "^6.0.2", - "prettier": "^1.18.2 || ^2.0.0", - "source-map": "~0.6.1", - "vue-template-es2015-compiler": "^1.9.0" - }, - "dependencies": { - "hash-sum": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", - "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=" - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - } - } - }, - "@webassemblyjs/ast": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", - "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", - "requires": { - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", - "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==" - }, - "@webassemblyjs/helper-api-error": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", - "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==" - }, - "@webassemblyjs/helper-buffer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", - "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==" - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", - "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", - "requires": { - "@webassemblyjs/wast-printer": "1.9.0" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", - "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==" - }, - "@webassemblyjs/helper-module-context": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", - "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", - "requires": { - "@webassemblyjs/ast": "1.9.0" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", - "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==" - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", - "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", - "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", - "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", - "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==" - }, - "@webassemblyjs/wasm-edit": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", - "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/helper-wasm-section": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-opt": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "@webassemblyjs/wast-printer": "1.9.0" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", - "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", - "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", - "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", - "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/floating-point-hex-parser": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-code-frame": "1.9.0", - "@webassemblyjs/helper-fsm": "1.9.0", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", - "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0", - "@xtuc/long": "4.2.2" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, - "acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==" - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" - }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "requires": {} - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "requires": {} - }, - "alphanum-sort": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", - "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=" - }, - "ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "requires": { - "string-width": "^4.1.0" - } - }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "requires": { - "type-fest": "^0.21.3" - }, - "dependencies": { - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" - } - } - }, - "ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==" - }, - "ansi-red": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", - "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=", - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, - "ansi-wrap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=" - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" - }, - "arg": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.1.tgz", - "integrity": "sha512-e0hDa9H2Z9AwFkk2qDlwhoMYE4eToKarchkQHovNdLTCYMHZHeRjI71crOh+dio4K6u1IcwubQqo79Ga4CyAQA==" - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" - }, - "asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } - } - }, - "assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", - "requires": { - "object-assign": "^4.1.1", - "util": "0.10.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "requires": { - "inherits": "2.0.1" - } - } - } - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "optional": true - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" - }, - "autolinker": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-0.28.1.tgz", - "integrity": "sha1-BlK0kYgYefB3XazgzcoyM5QqTkc=", - "requires": { - "gulp-header": "^1.7.1" - } - }, - "autoprefixer": { - "version": "9.8.8", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.8.tgz", - "integrity": "sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==", - "requires": { - "browserslist": "^4.12.0", - "caniuse-lite": "^1.0.30001109", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "picocolors": "^0.2.1", - "postcss": "^7.0.32", - "postcss-value-parser": "^4.1.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "axios": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.0.tgz", - "integrity": "sha512-lKoGLMYtHvFrPVt3r+RBMp9nh34N0M8zEfCWqdWZx6phynIEhQqAdydpyBAAG211zlhX9Rgu08cOamy6XjE5Og==", - "requires": { - "follow-redirects": "^1.14.8" - } - }, - "axios-retry": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.2.4.tgz", - "integrity": "sha512-Co3UXiv4npi6lM963mfnuH90/YFLKWWDmoBYfxkHT5xtkSSWNqK9zdG3fw5/CP/dsoKB5aMMJCsgab+tp1OxLQ==", - "requires": { - "@babel/runtime": "^7.15.4", - "is-retry-allowed": "^2.2.0" - } - }, - "babel-eslint": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", - "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0", - "eslint-visitor-keys": "^1.0.0", - "resolve": "^1.12.0" - } - }, - "babel-loader": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.3.tgz", - "integrity": "sha512-n4Zeta8NC3QAsuyiizu0GkmRcQ6clkV9WFUnUf1iXP//IeSKbWjofW3UHyZVwlOB4y039YQKefawyTn64Zwbuw==", - "requires": { - "find-cache-dir": "^3.3.1", - "loader-utils": "^1.4.0", - "make-dir": "^3.1.0", - "schema-utils": "^2.6.5" - }, - "dependencies": { - "schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "requires": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - } - } - } - }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "requires": { - "object.assign": "^4.1.0" - } - }, - "babel-plugin-polyfill-corejs2": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz", - "integrity": "sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w==", - "requires": { - "@babel/compat-data": "^7.13.11", - "@babel/helper-define-polyfill-provider": "^0.3.1", - "semver": "^6.1.1" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "babel-plugin-polyfill-corejs3": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz", - "integrity": "sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ==", - "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.1", - "core-js-compat": "^3.21.0" - } - }, - "babel-plugin-polyfill-regenerator": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz", - "integrity": "sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A==", - "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.1" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - } - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" - }, - "boxen": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", - "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", - "requires": { - "ansi-align": "^3.0.0", - "camelcase": "^6.2.0", - "chalk": "^4.1.0", - "cli-boxes": "^2.2.1", - "string-width": "^4.2.2", - "type-fest": "^0.20.2", - "widest-line": "^3.1.0", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==" - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "requires": { - "fill-range": "^7.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "requires": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "requires": { - "pako": "~1.0.5" - } - }, - "browserslist": { - "version": "4.19.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.3.tgz", - "integrity": "sha512-XK3X4xtKJ+Txj8G5c30B4gsm71s69lqXlkYui4s6EkKxuv49qjYlY6oVd+IFJ73d4YymtM3+djvvt/R/iJwwDg==", - "requires": { - "caniuse-lite": "^1.0.30001312", - "electron-to-chromium": "^1.4.71", - "escalade": "^3.1.1", - "node-releases": "^2.0.2", - "picocolors": "^1.0.0" - } - }, - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "buffer-json": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/buffer-json/-/buffer-json-2.0.0.tgz", - "integrity": "sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw==" - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" - }, - "bulma": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/bulma/-/bulma-0.9.3.tgz", - "integrity": "sha512-0d7GNW1PY4ud8TWxdNcP6Cc8Bu7MxcntD/RRLGWuiw/s0a9P+XlH/6QoOIrmbj6o8WWJzJYhytiu9nFjTszk1g==" - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" - }, - "cacache": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", - "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", - "requires": { - "@npmcli/fs": "^1.0.0", - "@npmcli/move-file": "^1.0.1", - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^8.0.1", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" - }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "cache-loader": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cache-loader/-/cache-loader-4.1.0.tgz", - "integrity": "sha512-ftOayxve0PwKzBF/GLsZNC9fJBXl8lkZE3TOsjkboHfVHVkL39iUEs1FO07A33mizmci5Dudt38UZrrYXDtbhw==", - "requires": { - "buffer-json": "^2.0.0", - "find-cache-dir": "^3.0.0", - "loader-utils": "^1.2.3", - "mkdirp": "^0.5.1", - "neo-async": "^2.6.1", - "schema-utils": "^2.0.0" - }, - "dependencies": { - "schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "requires": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - } - } - } - }, - "cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - }, - "normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", - "dev": true - } - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", - "requires": { - "callsites": "^2.0.0" - } - }, - "caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", - "requires": { - "caller-callsite": "^2.0.0" - } - }, - "callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=" - }, - "camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "requires": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, - "caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "requires": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "caniuse-lite": { - "version": "1.0.30001312", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz", - "integrity": "sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==" - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "dependencies": { - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - } - } - }, - "charcodes": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/charcodes/-/charcodes-0.2.0.tgz", - "integrity": "sha512-Y4kiDb+AM4Ecy58YkuZrrSRJBDQdQ2L+NyS1vHHFtNtUjgutcZfx3yp1dAONI/oPaPmyGfCLx5CxL+zauIMyKQ==" - }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" - }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" - }, - "chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" - }, - "ci-info": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", - "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==" - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "clean-css": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", - "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", - "requires": { - "source-map": "~0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" - }, - "cli-boxes": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==" - }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==" - }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=" - }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } - }, - "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "coa": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", - "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", - "requires": { - "@types/q": "^1.5.1", - "chalk": "^2.4.1", - "q": "^1.1.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "codemirror": { - "version": "5.65.2", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.2.tgz", - "integrity": "sha512-SZM4Zq7XEC8Fhroqe3LxbEEX1zUPWH1wMr5zxiBuiUF64iYOUH/JI88v4tBag8MiBS8B8gRv8O1pPXGYXQ4ErA==" - }, - "coffee-script": { - "version": "1.12.7", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz", - "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==" - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", - "requires": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "color-string": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.0.tgz", - "integrity": "sha512-9Mrz2AQLefkH1UvASKj6v6hj/7eWgjnT/cVsR8CumieLoT+g900exWeNogqtweI8dxloXN9BDQTYro1oWu/5CQ==", - "requires": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "colorette": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", - "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==" - }, - "commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==" - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" - }, - "compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "requires": { - "mime-db": ">= 1.43.0 < 2" - } - }, - "compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-with-sourcemaps": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz", - "integrity": "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==", - "requires": { - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "configstore": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "dev": true, - "requires": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" - }, - "dependencies": { - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - } - } - }, - "connect": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", - "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", - "requires": { - "debug": "2.6.9", - "finalhandler": "1.1.2", - "parseurl": "~1.3.3", - "utils-merge": "1.0.1" - } - }, - "consola": { - "version": "2.15.3", - "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", - "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==" - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==" - }, - "consolidate": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.15.1.tgz", - "integrity": "sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==", - "requires": { - "bluebird": "^3.1.1" - } - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=" - }, - "convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "requires": { - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } - }, - "cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" - }, - "cookie-universal": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/cookie-universal/-/cookie-universal-2.1.5.tgz", - "integrity": "sha512-nqOOmEkovCQxNYGIyzhcwsmh4c7xnxe7RWdiYFOoml9MP4L32IlU3LdPC7r7nQEnnM+9Uxlk/UhtvBl5is6M/w==", - "requires": { - "@types/cookie": "^0.3.3", - "cookie": "^0.4.0" - } - }, - "cookie-universal-nuxt": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/cookie-universal-nuxt/-/cookie-universal-nuxt-2.1.5.tgz", - "integrity": "sha512-P0WCTKIyemWNtHi9lxrS5cxZmieOIEjt28B7Alu6cdSB9RqtUtpkqYyV9PRK6oJrT5eIPDYjHsJQlh6SUrFJOg==", - "requires": { - "@types/cookie": "^0.3.3", - "cookie-universal": "^2.1.5" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" - }, - "core-js": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", - "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==" - }, - "core-js-compat": { - "version": "3.21.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.21.1.tgz", - "integrity": "sha512-gbgX5AUvMb8gwxC7FLVWYT7Kkgu/y7+h/h1X43yJkNqhlK2fuYyQimqvKGNZFAY6CKii/GFKJ2cp/1/42TN36g==", - "requires": { - "browserslist": "^4.19.1", - "semver": "7.0.0" - }, - "dependencies": { - "semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==" - } - } - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - }, - "dependencies": { - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - } - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "requires": { - "buffer": "^5.1.0" - }, - "dependencies": { - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - } - } - }, - "create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" - }, - "cross-env": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", - "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", - "requires": { - "cross-spawn": "^7.0.1" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "dev": true - }, - "css-blank-pseudo": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz", - "integrity": "sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w==", - "requires": { - "postcss": "^7.0.5" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "css-color-names": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", - "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=" - }, - "css-declaration-sorter": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", - "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", - "requires": { - "postcss": "^7.0.1", - "timsort": "^0.3.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "css-has-pseudo": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz", - "integrity": "sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ==", - "requires": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^5.0.0-rc.4" - }, - "dependencies": { - "cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==" - }, - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "requires": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "css-loader": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-4.3.0.tgz", - "integrity": "sha512-rdezjCjScIrsL8BSYszgT4s476IcNKt6yX69t0pHjJVnPUTDpn4WfIpDQTN3wCJvUvfsz/mFjuGOekf3PY3NUg==", - "requires": { - "camelcase": "^6.0.0", - "cssesc": "^3.0.0", - "icss-utils": "^4.1.1", - "loader-utils": "^2.0.0", - "postcss": "^7.0.32", - "postcss-modules-extract-imports": "^2.0.0", - "postcss-modules-local-by-default": "^3.0.3", - "postcss-modules-scope": "^2.2.0", - "postcss-modules-values": "^3.0.0", - "postcss-value-parser": "^4.1.0", - "schema-utils": "^2.7.1", - "semver": "^7.3.2" - }, - "dependencies": { - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==" - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "requires": { - "minimist": "^1.2.5" - } - }, - "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "requires": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "css-prefers-color-scheme": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz", - "integrity": "sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg==", - "requires": { - "postcss": "^7.0.5" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "css-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", - "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", - "requires": { - "boolbase": "^1.0.0", - "css-what": "^3.2.1", - "domutils": "^1.7.0", - "nth-check": "^1.0.2" - } - }, - "css-select-base-adapter": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", - "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" - }, - "css-tree": { - "version": "1.0.0-alpha.37", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", - "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", - "requires": { - "mdn-data": "2.0.4", - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "css-what": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", - "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==" - }, - "cssdb": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-4.4.0.tgz", - "integrity": "sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ==" - }, - "cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" - }, - "cssnano": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.11.tgz", - "integrity": "sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==", - "requires": { - "cosmiconfig": "^5.0.0", - "cssnano-preset-default": "^4.0.8", - "is-resolvable": "^1.0.0", - "postcss": "^7.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "cssnano-preset-default": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz", - "integrity": "sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==", - "requires": { - "css-declaration-sorter": "^4.0.1", - "cssnano-util-raw-cache": "^4.0.1", - "postcss": "^7.0.0", - "postcss-calc": "^7.0.1", - "postcss-colormin": "^4.0.3", - "postcss-convert-values": "^4.0.1", - "postcss-discard-comments": "^4.0.2", - "postcss-discard-duplicates": "^4.0.2", - "postcss-discard-empty": "^4.0.1", - "postcss-discard-overridden": "^4.0.1", - "postcss-merge-longhand": "^4.0.11", - "postcss-merge-rules": "^4.0.3", - "postcss-minify-font-values": "^4.0.2", - "postcss-minify-gradients": "^4.0.2", - "postcss-minify-params": "^4.0.2", - "postcss-minify-selectors": "^4.0.2", - "postcss-normalize-charset": "^4.0.1", - "postcss-normalize-display-values": "^4.0.2", - "postcss-normalize-positions": "^4.0.2", - "postcss-normalize-repeat-style": "^4.0.2", - "postcss-normalize-string": "^4.0.2", - "postcss-normalize-timing-functions": "^4.0.2", - "postcss-normalize-unicode": "^4.0.1", - "postcss-normalize-url": "^4.0.1", - "postcss-normalize-whitespace": "^4.0.2", - "postcss-ordered-values": "^4.1.2", - "postcss-reduce-initial": "^4.0.3", - "postcss-reduce-transforms": "^4.0.2", - "postcss-svgo": "^4.0.3", - "postcss-unique-selectors": "^4.0.1" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "cssnano-util-get-arguments": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", - "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=" - }, - "cssnano-util-get-match": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", - "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=" - }, - "cssnano-util-raw-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", - "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", - "requires": { - "postcss": "^7.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "cssnano-util-same-parent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", - "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==" - }, - "csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "requires": { - "css-tree": "^1.1.2" - }, - "dependencies": { - "css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "requires": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - } - }, - "mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "cuint": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", - "integrity": "sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs=" - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=" - }, - "de-indent": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", - "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=" - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "deepmerge": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.3.2.tgz", - "integrity": "sha1-FmNpFinU2/42T6EqKk8KqGqjoFA=" - }, - "defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "defu": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/defu/-/defu-5.0.1.tgz", - "integrity": "sha512-EPS1carKg+dkEVy3qNTqIdp2qV7mUP08nIsupfwQpz++slCVRw7qbQyWvSTig+kFPwz2XXp5/kIIkH+CwrJKkQ==" - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "destr": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/destr/-/destr-1.1.0.tgz", - "integrity": "sha512-Ev/sqS5AzzDwlpor/5wFCDu0dYMQu/0x2D6XfAsQ0E7uQmamIgYJ6Dppo2T2EOFVkeVYWjc+PCLKaqZZ57qmLg==" - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "detect-indent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", - "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=" - }, - "devalue": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/devalue/-/devalue-2.0.1.tgz", - "integrity": "sha512-I2TiqT5iWBEyB8GRfTDP0hiLZ0YeDJZ+upDxjBfOC2lebO5LezQMv7QvIUTzdb64jQyAKLf1AHADtGN+jw6v8Q==" - }, - "diacritics-map": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/diacritics-map/-/diacritics-map-0.1.0.tgz", - "integrity": "sha1-bfwP+dAQAKLt8oZTccrDFulJd68=" - }, - "diff-match-patch": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz", - "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==" - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } - } - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "requires": { - "path-type": "^4.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "requires": { - "utila": "~0.4" - } - }, - "dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", - "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==" - }, - "entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==" - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domready": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/domready/-/domready-1.0.8.tgz", - "integrity": "sha1-kfJS5Ze2Wvd+dFriTdAYXV4m1Yw=" - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "requires": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "requires": { - "is-obj": "^2.0.0" - } - }, - "dotenv": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", - "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==" - }, - "duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "electron-to-chromium": { - "version": "1.4.71", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.71.tgz", - "integrity": "sha512-Hk61vXXKRb2cd3znPE9F+2pLWdIOmP7GjiTj45y6L3W/lO+hSnUSUhq+6lEaERWBdZOHbk2s3YV5c9xVl3boVw==" - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", - "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "requires": { - "prr": "~1.0.1" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "error-stack-parser": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.7.tgz", - "integrity": "sha512-chLOW0ZGRf4s8raLrDxa5sdkvPec5YdvwbFnqJme4rk0rFajP8mPtrDL1+I+CwrQDCjswDA5sREX7jYQDQs9vA==", - "requires": { - "stackframe": "^1.1.1" - } - }, - "es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" - }, - "escape-goat": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", - "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", - "dev": true - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "eslint": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.9.0.tgz", - "integrity": "sha512-PB09IGwv4F4b0/atrbcMFboF/giawbBLVC7fyDamk5Wtey4Jh2K+rYaBhCAbUyEI4QzB1ly09Uglc9iCtFaG2Q==", - "dev": true, - "requires": { - "@eslint/eslintrc": "^1.1.0", - "@humanwhocodes/config-array": "^0.9.2", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.6.0", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "globals": { - "version": "13.12.1", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", - "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - } - } - }, - "eslint-config-prettier": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.4.0.tgz", - "integrity": "sha512-CFotdUcMY18nGRo5KGsnNxpznzhkopOcOo0InID+sgQssPrzjvsyKZPvOgymTFeHrFuC3Tzdf2YndhXtULK9Iw==", - "dev": true, - "requires": {} - }, - "eslint-loader": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-4.0.2.tgz", - "integrity": "sha512-EDpXor6lsjtTzZpLUn7KmXs02+nIjGcgees9BYjNkWra3jVq5vVa8IoCKgzT2M7dNNeoMBtaSG83Bd40N3poLw==", - "dev": true, - "requires": { - "find-cache-dir": "^3.3.1", - "fs-extra": "^8.1.0", - "loader-utils": "^2.0.0", - "object-hash": "^2.0.3", - "schema-utils": "^2.6.5" - }, - "dependencies": { - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - } - } - }, - "eslint-plugin-prettier": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz", - "integrity": "sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==", - "dev": true, - "requires": { - "prettier-linter-helpers": "^1.0.0" - } - }, - "eslint-plugin-vue": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-8.4.1.tgz", - "integrity": "sha512-nmWOhNmDx9TZ+yP9ZhezTkZUupSHsYA2TocRm+efPSXMOyFrVczVlaIuQcLBjCtI8CbkBiUQ3VcyQsjlIhDrhA==", - "dev": true, - "requires": { - "eslint-utils": "^3.0.0", - "natural-compare": "^1.4.0", - "semver": "^7.3.5", - "vue-eslint-parser": "^8.0.1" - } - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - }, - "espree": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", - "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", - "dev": true, - "requires": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true - } - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" - }, - "eventsource-polyfill": { - "version": "0.9.6", - "resolved": "https://registry.npmjs.org/eventsource-polyfill/-/eventsource-polyfill-0.9.6.tgz", - "integrity": "sha1-EODRh/ERsWfyj9q5GIQ859gY8Tw=" - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=" - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "requires": { - "fill-range": "^2.1.0" - }, - "dependencies": { - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "requires": { - "kind-of": "^3.0.2" - } - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "requires": { - "isarray": "1.0.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, - "extract-css-chunks-webpack-plugin": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/extract-css-chunks-webpack-plugin/-/extract-css-chunks-webpack-plugin-4.9.0.tgz", - "integrity": "sha512-HNuNPCXRMqJDQ1OHAUehoY+0JVCnw9Y/H22FQzYVwo8Ulgew98AGDu0grnY5c7xwiXHjQa6yJ/1dxLCI/xqTyQ==", - "requires": { - "loader-utils": "^2.0.0", - "normalize-url": "1.9.1", - "schema-utils": "^1.0.0", - "webpack-sources": "^1.1.0" - }, - "dependencies": { - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "requires": { - "minimist": "^1.2.5" - } - }, - "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "normalize-url": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", - "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", - "requires": { - "object-assign": "^4.0.1", - "prepend-http": "^1.0.0", - "query-string": "^4.1.0", - "sort-keys": "^1.0.0" - } - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - } - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true - }, - "fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "requires": { - "reusify": "^1.0.4" - } - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==" - }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "file-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", - "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", - "requires": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "dependencies": { - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "requires": { - "minimist": "^1.2.5" - } - }, - "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - } - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "filter-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", - "integrity": "sha1-mzERErxsYSehbgFsbF1/GeCAXFs=" - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - } - }, - "find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==" - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", - "dev": true - }, - "flatten": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz", - "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==" - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "requires": { - "map-cache": "^0.2.2" - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs": { - "version": "0.0.1-security", - "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", - "integrity": "sha1-invTcYa23d84E/I4WLV+yq9eQdQ=" - }, - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "fs-memo": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fs-memo/-/fs-memo-1.2.0.tgz", - "integrity": "sha512-YEexkCpL4j03jn5SxaMHqcO6IuWuqm8JFUYhyCep7Ao89JIYmB8xoKhK7zXXJ9cCaNXpyNH5L3QtAmoxjoHW2w==" - }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "requires": { - "minipass": "^3.0.0" - } - }, - "fs-monkey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", - "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==" - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-port-please": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/get-port-please/-/get-port-please-2.3.0.tgz", - "integrity": "sha512-zO6ST8v7jBO+uSnm0vaQuZEpdr7DgY9iMgoMLUC+Zfz31HYoDiiQrL78oZspaAryT6NH903Bwk+mYxiCy3X/RQ==", - "requires": { - "fs-memo": "^1.2.0" - } - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" - }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" - }, - "git-config-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/git-config-path/-/git-config-path-2.0.0.tgz", - "integrity": "sha512-qc8h1KIQbJpp+241id3GuAtkdyJ+IK+LIVtkiFTRKRrmddDzs3SI9CvP1QYmWBFvm1I/PWRwj//of8bgAc0ltA==" - }, - "git-up": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/git-up/-/git-up-4.0.5.tgz", - "integrity": "sha512-YUvVDg/vX3d0syBsk/CKUTib0srcQME0JyHkL5BaYdwLsiCslPWmDSi8PUMo9pXYjrryMcmsCoCgsTpSCJEQaA==", - "requires": { - "is-ssh": "^1.3.0", - "parse-url": "^6.0.0" - } - }, - "git-url-parse": { - "version": "11.6.0", - "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-11.6.0.tgz", - "integrity": "sha512-WWUxvJs5HsyHL6L08wOusa/IXYtMuCAhrMmnTjQPpBU0TTHyDhnOATNH3xNQz7YOQUsqIIPTGr4xiVti1Hsk5g==", - "requires": { - "git-up": "^4.0.0" - } - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "requires": { - "is-glob": "^4.0.1" - } - }, - "global-dirs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", - "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", - "dev": true, - "requires": { - "ini": "2.0.0" - }, - "dependencies": { - "ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "dev": true - } - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, - "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - }, - "dependencies": { - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - } - } - }, - "graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==" - }, - "gray-matter": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-2.1.1.tgz", - "integrity": "sha1-MELZrewqHe1qdwep7SOA+KF6Qw4=", - "requires": { - "ansi-red": "^0.1.1", - "coffee-script": "^1.12.4", - "extend-shallow": "^2.0.1", - "js-yaml": "^3.8.1", - "toml": "^2.3.2" - }, - "dependencies": { - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - } - } - }, - "gulp-header": { - "version": "1.8.12", - "resolved": "https://registry.npmjs.org/gulp-header/-/gulp-header-1.8.12.tgz", - "integrity": "sha512-lh9HLdb53sC7XIZOYzTXM4lFuXElv3EVkSDhsd7DoJBj7hm+Ni7D3qYbb+Rr8DuM8nRanBvkVO9d7askreXGnQ==", - "requires": { - "concat-with-sourcemaps": "*", - "lodash.template": "^4.4.0", - "through2": "^2.0.0" - } - }, - "gzip-size": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", - "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", - "requires": { - "duplexer": "^0.1.2" - } - }, - "hable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hable/-/hable-3.0.0.tgz", - "integrity": "sha512-7+G0/2/COR8pwteYFqHIVYfQpuEiO2HXwJrhCBJVgrNrl9O5eaUoJVDGXUJX+0RpGncNVTuestexjk1afj01wQ==" - }, - "hard-source-webpack-plugin": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/hard-source-webpack-plugin/-/hard-source-webpack-plugin-0.13.1.tgz", - "integrity": "sha512-r9zf5Wq7IqJHdVAQsZ4OP+dcUSvoHqDMxJlIzaE2J0TZWn3UjMMrHqwDHR8Jr/pzPfG7XxSe36E7Y8QGNdtuAw==", - "requires": { - "chalk": "^2.4.1", - "find-cache-dir": "^2.0.0", - "graceful-fs": "^4.1.11", - "lodash": "^4.15.0", - "mkdirp": "^0.5.1", - "node-object-hash": "^1.2.0", - "parse-json": "^4.0.0", - "pkg-dir": "^3.0.0", - "rimraf": "^2.6.2", - "semver": "^5.6.0", - "tapable": "^1.0.0-beta.5", - "webpack-sources": "^1.0.1", - "write-json-file": "^2.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "requires": { - "find-up": "^3.0.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" - }, - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "requires": { - "has-symbols": "^1.0.2" - } - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "has-yarn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", - "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", - "dev": true - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "hash-sum": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz", - "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==" - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", - "requires": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hex-color-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", - "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" - }, - "highlight.js": { - "version": "11.4.0", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.4.0.tgz", - "integrity": "sha512-nawlpCBCSASs7EdvZOYOYVkJpGmAOKMYZgZtUqSRqodZE0GRVcFKwo1RcpeOemqh9hyttTdd5wDBwHkuSyUfnA==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "hsl-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", - "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=" - }, - "hsla-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", - "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=" - }, - "html-entities": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.2.tgz", - "integrity": "sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ==" - }, - "html-minifier": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-4.0.0.tgz", - "integrity": "sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==", - "requires": { - "camel-case": "^3.0.0", - "clean-css": "^4.2.1", - "commander": "^2.19.0", - "he": "^1.2.0", - "param-case": "^2.1.1", - "relateurl": "^0.2.7", - "uglify-js": "^3.5.1" - }, - "dependencies": { - "camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", - "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", - "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" - } - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "lower-case": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=" - }, - "no-case": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", - "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", - "requires": { - "lower-case": "^1.1.1" - } - }, - "param-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", - "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", - "requires": { - "no-case": "^2.2.0" - } - } - } - }, - "html-minifier-terser": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", - "integrity": "sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg==", - "requires": { - "camel-case": "^4.1.1", - "clean-css": "^4.2.3", - "commander": "^4.1.1", - "he": "^1.2.0", - "param-case": "^3.0.3", - "relateurl": "^0.2.7", - "terser": "^4.6.3" - } - }, - "html-tags": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz", - "integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=" - }, - "html-webpack-plugin": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.5.2.tgz", - "integrity": "sha512-q5oYdzjKUIPQVjOosjgvCHQOv9Ett9CYYHlgvJeXG0qQvdSojnBq4vAdQBwn1+yGveAwHCoe/rMR86ozX3+c2A==", - "requires": { - "@types/html-minifier-terser": "^5.0.0", - "@types/tapable": "^1.0.5", - "@types/webpack": "^4.41.8", - "html-minifier-terser": "^5.0.1", - "loader-utils": "^1.2.3", - "lodash": "^4.17.20", - "pretty-error": "^2.1.1", - "tapable": "^1.1.3", - "util.promisify": "1.0.0" - }, - "dependencies": { - "util.promisify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", - "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", - "requires": { - "define-properties": "^1.1.2", - "object.getownpropertydescriptors": "^2.0.3" - } - } - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, - "http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" - } - }, - "http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "http-proxy-middleware": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-1.3.1.tgz", - "integrity": "sha512-13eVVDYS4z79w7f1+NPllJtOQFx/FdUW4btIvVRMaRlUY9VGstAbo5MOhLEuUgZFRHn3x50ufn25zkj/boZnEg==", - "requires": { - "@types/http-proxy": "^1.17.5", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==" - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "icss-utils": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", - "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", - "requires": { - "postcss": "^7.0.14" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" - }, - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==" - }, - "ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", - "dev": true - }, - "image-size": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", - "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=" - }, - "immutable": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz", - "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==", - "dev": true - }, - "import-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", - "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", - "requires": { - "import-from": "^2.1.0" - } - }, - "import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", - "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - } - }, - "import-from": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", - "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", - "requires": { - "resolve-from": "^3.0.0" - } - }, - "import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" - }, - "indexes-of": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=" - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "inquirer": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", - "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", - "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.19", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.6.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" - }, - "is-absolute-url": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", - "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==" - }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "requires": { - "ci-info": "^2.0.0" - }, - "dependencies": { - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - } - } - }, - "is-color-stop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", - "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", - "requires": { - "css-color-names": "^0.0.4", - "hex-color-regex": "^1.1.0", - "hsl-regex": "^1.0.0", - "hsla-regex": "^1.0.0", - "rgb-regex": "^1.0.1", - "rgba-regex": "^1.0.0" - } - }, - "is-core-module": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", - "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", - "requires": { - "has": "^1.0.3" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" - } - } - }, - "is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=" - }, - "is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==" - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "dev": true, - "requires": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - } - }, - "is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==" - }, - "is-npm": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", - "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" - }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true - }, - "is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==" - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { - "isobject": "^3.0.1" - } - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==" - }, - "is-retry-allowed": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz", - "integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==" - }, - "is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==" - }, - "is-ssh": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.3.3.tgz", - "integrity": "sha512-NKzJmQzJfEEma3w5cJNcUMxoXfDjz0Zj0eyCalHn2E6VOwlzjZo0yuO2fcBSf8zhFuVCL/82/r5gRcoi6aEPVQ==", - "requires": { - "protocols": "^1.1.0" - } - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "is-yarn-global": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", - "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jimp-compact": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/jimp-compact/-/jimp-compact-0.16.1.tgz", - "integrity": "sha512-dZ6Ra7u1G8c4Letq/B5EzAxj4tLFHL+cGtdpR+PVm4yzPDj+lCk+AbivWt1eOM+ikzkowtyV7qSqX6qr3t71Ww==" - }, - "jiti": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.13.0.tgz", - "integrity": "sha512-/n9mNxZj/HDSrincJ6RP+L+yXbpnB8FybySBa+IjIaoH9FIxBbrbRT5XUbe8R7zuVM2AQqNMNDDqz0bzx3znOQ==" - }, - "js-base64": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", - "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==" - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "requires": { - "argparse": "^2.0.1" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - } - } - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" - }, - "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "requires": { - "minimist": "^1.2.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, - "requires": { - "json-buffer": "3.0.0" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" - }, - "klona": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz", - "integrity": "sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==", - "dev": true - }, - "last-call-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w==", - "requires": { - "lodash": "^4.17.5", - "webpack-sources": "^1.1.0" - } - }, - "latest-version": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", - "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", - "dev": true, - "requires": { - "package-json": "^6.3.0" - } - }, - "launch-editor": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.3.0.tgz", - "integrity": "sha512-3QrsCXejlWYHjBPFXTyGNhPj4rrQdB+5+r5r3wArpLH201aR+nWUgw/zKKkTmilCfY/sv6u8qo98pNvtg8LUTA==", - "requires": { - "picocolors": "^1.0.0", - "shell-quote": "^1.6.1" - } - }, - "launch-editor-middleware": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/launch-editor-middleware/-/launch-editor-middleware-2.3.0.tgz", - "integrity": "sha512-GJR64trLdFFwCoL9DMn/d1SZX0OzTDPixu4mcfWTShQ4tIqCHCGvlg9fOEYQXyBlrSMQwylsJfUWncheShfV2w==", - "requires": { - "launch-editor": "^2.3.0" - } - }, - "lazy-cache": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz", - "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=", - "requires": { - "set-getter": "^0.1.0" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "linkify-it": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", - "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", - "requires": { - "uc.micro": "^1.0.1" - } - }, - "list-item": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/list-item/-/list-item-1.1.1.tgz", - "integrity": "sha1-DGXQDih8tmPMs8s4Sad+iewmilY=", - "requires": { - "expand-range": "^1.8.1", - "extend-shallow": "^2.0.1", - "is-number": "^2.1.0", - "repeat-string": "^1.5.2" - }, - "dependencies": { - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "requires": { - "kind-of": "^3.0.2" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "loader-runner": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", - "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==" - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "requires": { - "p-locate": "^4.1.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" - }, - "lodash.kebabcase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", - "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=" - }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=" - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "requires": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "requires": { - "lodash._reinterpolate": "^3.0.0" - } - }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" - }, - "lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "requires": { - "tslib": "^2.0.3" - } - }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "requires": { - "p-defer": "^1.0.0" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "requires": { - "object-visit": "^1.0.0" - } - }, - "markdown-it": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz", - "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==", - "requires": { - "argparse": "^1.0.7", - "entities": "~1.1.1", - "linkify-it": "^2.0.0", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - } - }, - "markdown-link": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/markdown-link/-/markdown-link-0.1.1.tgz", - "integrity": "sha1-MsXGUZmmRXMWMi0eQinRNAfIx88=" - }, - "markdown-toc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/markdown-toc/-/markdown-toc-1.2.0.tgz", - "integrity": "sha512-eOsq7EGd3asV0oBfmyqngeEIhrbkc7XVP63OwcJBIhH2EpG2PzFcbZdhy1jutXSlRBBVMNXHvMtSr5LAxSUvUg==", - "requires": { - "concat-stream": "^1.5.2", - "diacritics-map": "^0.1.0", - "gray-matter": "^2.1.0", - "lazy-cache": "^2.0.2", - "list-item": "^1.1.1", - "markdown-link": "^0.1.1", - "minimist": "^1.2.0", - "mixin-deep": "^1.1.3", - "object.pick": "^1.2.0", - "remarkable": "^1.7.1", - "repeat-string": "^1.6.1", - "strip-color": "^0.1.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==" - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "mdn-data": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", - "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" - }, - "mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" - }, - "mem": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/mem/-/mem-8.1.1.tgz", - "integrity": "sha512-qFCFUDs7U3b8mBDPyz5EToEKoAkgCzqquIgi9nkkR9bixxOVOre+09lbuH7+9Kn2NFpm56M3GUWVbU2hQgdACA==", - "requires": { - "map-age-cleaner": "^0.1.3", - "mimic-fn": "^3.1.0" - }, - "dependencies": { - "mimic-fn": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", - "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==" - } - } - }, - "memfs": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.1.tgz", - "integrity": "sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw==", - "requires": { - "fs-monkey": "1.0.3" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "merge-options": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-1.0.1.tgz", - "integrity": "sha512-iuPV41VWKWBIOpBsjoxjDZw8/GbSfZ2mk7N1453bwMrfzdrIk7EzBd+8UVR6rkw67th7xnk9Dytl3J+lHPdxvg==", - "requires": { - "is-plain-obj": "^1.1" - }, - "dependencies": { - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" - } - } - }, - "merge-source-map": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", - "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", - "requires": { - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", - "requires": { - "mime-db": "1.51.0" - }, - "dependencies": { - "mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" - } - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "minipass": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", - "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", - "requires": { - "yallist": "^4.0.0" - } - }, - "minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "requires": { - "minipass": "^3.0.0" - } - }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - } - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mitt": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.1.2.tgz", - "integrity": "sha1-OA5hSA1qYVtmDwertg1R4KTkvtY=" - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "mrmime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.0.tgz", - "integrity": "sha512-a70zx7zFfVO7XpnQ2IX1Myh9yY4UYvfld/dikWRnsXxbyvMcfz+u6UfgNAtH+k2QqtJuzVpv6eLTx1G2+WKZbQ==" - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "mustache": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-2.3.2.tgz", - "integrity": "sha512-KpMNwdQsYz3O/SBS1qJ/o3sqUJ5wSb8gb0pul8CO0S56b9Y2ALm8zCfsjPXsqGFfoNBkDwZuZIAjhsZI03gYVQ==" - }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" - }, - "nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==" - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - } - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "requires": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "node-html-parser": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-3.3.6.tgz", - "integrity": "sha512-VkWDHvNgFGB3mbQGMyzqRE1i/BG7TKX9wRXC8e/v8kL0kZR/Oy6RjYxXH91K6/+m3g8iQ8dTqRy75lTYoA2Cjg==", - "requires": { - "css-select": "^4.1.3", - "he": "1.2.0" - }, - "dependencies": { - "css-select": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.2.1.tgz", - "integrity": "sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==", - "requires": { - "boolbase": "^1.0.0", - "css-what": "^5.1.0", - "domhandler": "^4.3.0", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - } - }, - "css-what": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", - "integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==" - }, - "dom-serializer": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", - "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - } - }, - "domelementtype": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", - "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==" - }, - "domhandler": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz", - "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==", - "requires": { - "domelementtype": "^2.2.0" - } - }, - "domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "requires": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - } - }, - "entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" - }, - "nth-check": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", - "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", - "requires": { - "boolbase": "^1.0.0" - } - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } - }, - "node-object-hash": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/node-object-hash/-/node-object-hash-1.4.2.tgz", - "integrity": "sha512-UdS4swXs85fCGWWf6t6DMGgpN/vnlKeSGEQ7hJcrs7PBFoxoKLmibc3QRb7fwiYsjdL7PX8iI/TMSlZ90dgHhQ==" - }, - "node-releases": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", - "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==" - }, - "node-res": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/node-res/-/node-res-5.0.1.tgz", - "integrity": "sha512-YOleO9c7MAqoHC+Ccu2vzvV1fL6Ku49gShq3PIMKWHRgrMSih3XcwL05NbLBi6oU2J471gTBfdpVVxwT6Pfhxg==", - "requires": { - "destroy": "^1.0.4", - "etag": "^1.8.1", - "mime-types": "^2.1.19", - "on-finished": "^2.3.0", - "vary": "^1.1.2" - } - }, - "nodemon": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.15.tgz", - "integrity": "sha512-gdHMNx47Gw7b3kWxJV64NI+Q5nfl0y5DgDbiVtShiwa7Z0IZ07Ll4RLFo6AjrhzMtoEZn5PDE3/c2AbVsiCkpA==", - "dev": true, - "requires": { - "chokidar": "^3.5.2", - "debug": "^3.2.7", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.0.4", - "pstree.remy": "^1.1.8", - "semver": "^5.7.1", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.5", - "update-notifier": "^5.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, - "normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=" - }, - "normalize-url": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", - "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==" - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "requires": { - "path-key": "^3.0.0" - } - }, - "nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", - "requires": { - "boolbase": "~1.0.0" - } - }, - "num2fraction": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=" - }, - "nuxt": { - "version": "2.15.8", - "resolved": "https://registry.npmjs.org/nuxt/-/nuxt-2.15.8.tgz", - "integrity": "sha512-ceK3qLg/Baj7J8mK9bIxqw9AavrF+LXqwYEreBdY/a4Sj8YV4mIvhqea/6E7VTCNNGvKT2sJ/TTJjtfQ597lTA==", - "requires": { - "@nuxt/babel-preset-app": "2.15.8", - "@nuxt/builder": "2.15.8", - "@nuxt/cli": "2.15.8", - "@nuxt/components": "^2.1.8", - "@nuxt/config": "2.15.8", - "@nuxt/core": "2.15.8", - "@nuxt/generator": "2.15.8", - "@nuxt/loading-screen": "^2.0.3", - "@nuxt/opencollective": "^0.3.2", - "@nuxt/server": "2.15.8", - "@nuxt/telemetry": "^1.3.3", - "@nuxt/utils": "2.15.8", - "@nuxt/vue-app": "2.15.8", - "@nuxt/vue-renderer": "2.15.8", - "@nuxt/webpack": "2.15.8" - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-hash": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", - "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", - "dev": true - }, - "object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==" - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "requires": { - "isobject": "^3.0.0" - } - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz", - "integrity": "sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "requires": { - "isobject": "^3.0.1" - } - }, - "object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "opener": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==" - }, - "optimize-css-assets-webpack-plugin": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.8.tgz", - "integrity": "sha512-mgFS1JdOtEGzD8l+EuISqL57cKO+We9GcoiQEmdCWRqqck+FGNmYJtx9qfAPzEz+lRrlThWMuGDaRkI/yWNx/Q==", - "requires": { - "cssnano": "^4.1.10", - "last-call-webpack-plugin": "^3.0.0" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=" - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true - }, - "p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=" - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "package-json": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", - "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", - "dev": true, - "requires": { - "got": "^9.6.0", - "registry-auth-token": "^4.0.0", - "registry-url": "^5.0.0", - "semver": "^6.2.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "requires": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - }, - "dependencies": { - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - } - } - }, - "parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "requires": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "parse-git-config": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/parse-git-config/-/parse-git-config-3.0.0.tgz", - "integrity": "sha512-wXoQGL1D+2COYWCD35/xbiKma1Z15xvZL8cI25wvxzled58V51SJM04Urt/uznS900iQor7QO04SgdfT/XlbuA==", - "requires": { - "git-config-path": "^2.0.0", - "ini": "^1.3.5" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "parse-path": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-4.0.3.tgz", - "integrity": "sha512-9Cepbp2asKnWTJ9x2kpw6Fe8y9JDbqwahGCTvklzd/cEq5C5JC59x2Xb0Kx+x0QZ8bvNquGO8/BWP0cwBHzSAA==", - "requires": { - "is-ssh": "^1.3.0", - "protocols": "^1.4.0", - "qs": "^6.9.4", - "query-string": "^6.13.8" - }, - "dependencies": { - "query-string": { - "version": "6.14.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.14.1.tgz", - "integrity": "sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==", - "requires": { - "decode-uri-component": "^0.2.0", - "filter-obj": "^1.1.0", - "split-on-first": "^1.0.0", - "strict-uri-encode": "^2.0.0" - } - }, - "strict-uri-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", - "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=" - } - } - }, - "parse-url": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-6.0.0.tgz", - "integrity": "sha512-cYyojeX7yIIwuJzledIHeLUBVJ6COVLeT4eF+2P6aKVzwvgKQPndCBv3+yQ7pcWjqToYwaligxzSYNNmGoMAvw==", - "requires": { - "is-ssh": "^1.3.0", - "normalize-url": "^6.1.0", - "parse-path": "^4.0.0", - "protocols": "^1.4.0" - }, - "dependencies": { - "normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" - } - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "requires": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==" - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "optional": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" - }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" - }, - "pify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", - "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==" - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "requires": { - "find-up": "^4.0.0" - } - }, - "pnp-webpack-plugin": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.7.0.tgz", - "integrity": "sha512-2Rb3vm+EXble/sMXNSu6eoBx8e79gKqhNq9F5ZWW6ERNCTE/Q0wQNne5541tE5vKjfM8hpNCYL+LGc1YTfI0dg==", - "requires": { - "ts-pnp": "^1.1.6" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "postcss-attribute-case-insensitive": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz", - "integrity": "sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA==", - "requires": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^6.0.2" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-calc": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.5.tgz", - "integrity": "sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==", - "requires": { - "postcss": "^7.0.27", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.0.2" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-color-functional-notation": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz", - "integrity": "sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g==", - "requires": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-color-gray": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz", - "integrity": "sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw==", - "requires": { - "@csstools/convert-colors": "^1.4.0", - "postcss": "^7.0.5", - "postcss-values-parser": "^2.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-color-hex-alpha": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz", - "integrity": "sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw==", - "requires": { - "postcss": "^7.0.14", - "postcss-values-parser": "^2.0.1" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-color-mod-function": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz", - "integrity": "sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ==", - "requires": { - "@csstools/convert-colors": "^1.4.0", - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-color-rebeccapurple": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz", - "integrity": "sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g==", - "requires": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-colormin": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", - "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", - "requires": { - "browserslist": "^4.0.0", - "color": "^3.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-convert-values": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", - "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", - "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-custom-media": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz", - "integrity": "sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg==", - "requires": { - "postcss": "^7.0.14" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-custom-properties": { - "version": "8.0.11", - "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz", - "integrity": "sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA==", - "requires": { - "postcss": "^7.0.17", - "postcss-values-parser": "^2.0.1" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-custom-selectors": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz", - "integrity": "sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w==", - "requires": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^5.0.0-rc.3" - }, - "dependencies": { - "cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==" - }, - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "requires": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-dir-pseudo-class": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz", - "integrity": "sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw==", - "requires": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^5.0.0-rc.3" - }, - "dependencies": { - "cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==" - }, - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "requires": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-discard-comments": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", - "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", - "requires": { - "postcss": "^7.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-discard-duplicates": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", - "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", - "requires": { - "postcss": "^7.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-discard-empty": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", - "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", - "requires": { - "postcss": "^7.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-discard-overridden": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", - "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", - "requires": { - "postcss": "^7.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-double-position-gradients": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz", - "integrity": "sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA==", - "requires": { - "postcss": "^7.0.5", - "postcss-values-parser": "^2.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-env-function": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-2.0.2.tgz", - "integrity": "sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw==", - "requires": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-focus-visible": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz", - "integrity": "sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g==", - "requires": { - "postcss": "^7.0.2" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-focus-within": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz", - "integrity": "sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w==", - "requires": { - "postcss": "^7.0.2" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-font-variant": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-4.0.1.tgz", - "integrity": "sha512-I3ADQSTNtLTTd8uxZhtSOrTCQ9G4qUVKPjHiDk0bV75QSxXjVWiJVJ2VLdspGUi9fbW9BcjKJoRvxAH1pckqmA==", - "requires": { - "postcss": "^7.0.2" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-gap-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz", - "integrity": "sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg==", - "requires": { - "postcss": "^7.0.2" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-image-set-function": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz", - "integrity": "sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw==", - "requires": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-import": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-12.0.1.tgz", - "integrity": "sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw==", - "requires": { - "postcss": "^7.0.1", - "postcss-value-parser": "^3.2.3", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-import-resolver": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-import-resolver/-/postcss-import-resolver-2.0.0.tgz", - "integrity": "sha512-y001XYgGvVwgxyxw9J1a5kqM/vtmIQGzx34g0A0Oy44MFcy/ZboZw1hu/iN3VYFjSTRzbvd7zZJJz0Kh0AGkTw==", - "requires": { - "enhanced-resolve": "^4.1.1" - } - }, - "postcss-initial": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-3.0.4.tgz", - "integrity": "sha512-3RLn6DIpMsK1l5UUy9jxQvoDeUN4gP939tDcKUHD/kM8SGSKbFAnvkpFpj3Bhtz3HGk1jWY5ZNWX6mPta5M9fg==", - "requires": { - "postcss": "^7.0.2" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-lab-function": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz", - "integrity": "sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg==", - "requires": { - "@csstools/convert-colors": "^1.4.0", - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-load-config": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.2.tgz", - "integrity": "sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw==", - "requires": { - "cosmiconfig": "^5.0.0", - "import-cwd": "^2.0.0" - } - }, - "postcss-loader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", - "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", - "requires": { - "loader-utils": "^1.1.0", - "postcss": "^7.0.0", - "postcss-load-config": "^2.0.0", - "schema-utils": "^1.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-logical": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-3.0.0.tgz", - "integrity": "sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA==", - "requires": { - "postcss": "^7.0.2" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-media-minmax": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz", - "integrity": "sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw==", - "requires": { - "postcss": "^7.0.2" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-merge-longhand": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", - "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", - "requires": { - "css-color-names": "0.0.4", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "stylehacks": "^4.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-merge-rules": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", - "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", - "requires": { - "browserslist": "^4.0.0", - "caniuse-api": "^3.0.0", - "cssnano-util-same-parent": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0", - "vendors": "^1.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "requires": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-minify-font-values": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", - "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", - "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-minify-gradients": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", - "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", - "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "is-color-stop": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-minify-params": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", - "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", - "requires": { - "alphanum-sort": "^1.0.0", - "browserslist": "^4.0.0", - "cssnano-util-get-arguments": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "uniqs": "^2.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-minify-selectors": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", - "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", - "requires": { - "alphanum-sort": "^1.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "requires": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-modules-extract-imports": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", - "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", - "requires": { - "postcss": "^7.0.5" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-modules-local-by-default": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz", - "integrity": "sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==", - "requires": { - "icss-utils": "^4.1.1", - "postcss": "^7.0.32", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-modules-scope": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", - "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", - "requires": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^6.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-modules-values": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", - "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", - "requires": { - "icss-utils": "^4.0.0", - "postcss": "^7.0.6" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-nesting": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-7.0.1.tgz", - "integrity": "sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg==", - "requires": { - "postcss": "^7.0.2" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-normalize-charset": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", - "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", - "requires": { - "postcss": "^7.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-normalize-display-values": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", - "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", - "requires": { - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-normalize-positions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", - "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", - "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-normalize-repeat-style": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", - "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", - "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-normalize-string": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", - "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", - "requires": { - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-normalize-timing-functions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", - "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", - "requires": { - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-normalize-unicode": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", - "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", - "requires": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-normalize-url": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", - "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", - "requires": { - "is-absolute-url": "^2.0.0", - "normalize-url": "^3.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-normalize-whitespace": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", - "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", - "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-ordered-values": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", - "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", - "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-overflow-shorthand": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz", - "integrity": "sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g==", - "requires": { - "postcss": "^7.0.2" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-page-break": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-2.0.0.tgz", - "integrity": "sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ==", - "requires": { - "postcss": "^7.0.2" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-place": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-4.0.1.tgz", - "integrity": "sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg==", - "requires": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-prefix-selector": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/postcss-prefix-selector/-/postcss-prefix-selector-1.14.0.tgz", - "integrity": "sha512-8d5fiBQZWMtGWH/7ewEeo6RnBNyT2kLD5wTIfV2oHYqH4hjiofg/rP5X3SUwnqOINzE4mM/K/UOAiNrIaKzd4w==", - "requires": {} - }, - "postcss-preset-env": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-6.7.1.tgz", - "integrity": "sha512-rlRkgX9t0v2On33n7TK8pnkcYOATGQSv48J2RS8GsXhqtg+xk6AummHP88Y5mJo0TLJelBjePvSjScTNkj3+qw==", - "requires": { - "autoprefixer": "^9.6.1", - "browserslist": "^4.6.4", - "caniuse-lite": "^1.0.30000981", - "css-blank-pseudo": "^0.1.4", - "css-has-pseudo": "^0.10.0", - "css-prefers-color-scheme": "^3.1.1", - "cssdb": "^4.4.0", - "postcss": "^7.0.17", - "postcss-attribute-case-insensitive": "^4.0.1", - "postcss-color-functional-notation": "^2.0.1", - "postcss-color-gray": "^5.0.0", - "postcss-color-hex-alpha": "^5.0.3", - "postcss-color-mod-function": "^3.0.3", - "postcss-color-rebeccapurple": "^4.0.1", - "postcss-custom-media": "^7.0.8", - "postcss-custom-properties": "^8.0.11", - "postcss-custom-selectors": "^5.1.2", - "postcss-dir-pseudo-class": "^5.0.0", - "postcss-double-position-gradients": "^1.0.0", - "postcss-env-function": "^2.0.2", - "postcss-focus-visible": "^4.0.0", - "postcss-focus-within": "^3.0.0", - "postcss-font-variant": "^4.0.0", - "postcss-gap-properties": "^2.0.0", - "postcss-image-set-function": "^3.0.1", - "postcss-initial": "^3.0.0", - "postcss-lab-function": "^2.0.1", - "postcss-logical": "^3.0.0", - "postcss-media-minmax": "^4.0.0", - "postcss-nesting": "^7.0.0", - "postcss-overflow-shorthand": "^2.0.0", - "postcss-page-break": "^2.0.0", - "postcss-place": "^4.0.1", - "postcss-pseudo-class-any-link": "^6.0.0", - "postcss-replace-overflow-wrap": "^3.0.0", - "postcss-selector-matches": "^4.0.0", - "postcss-selector-not": "^4.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-pseudo-class-any-link": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz", - "integrity": "sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew==", - "requires": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^5.0.0-rc.3" - }, - "dependencies": { - "cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==" - }, - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "requires": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-reduce-initial": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", - "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", - "requires": { - "browserslist": "^4.0.0", - "caniuse-api": "^3.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-reduce-transforms": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", - "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", - "requires": { - "cssnano-util-get-match": "^4.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-replace-overflow-wrap": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz", - "integrity": "sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw==", - "requires": { - "postcss": "^7.0.2" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-selector-matches": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz", - "integrity": "sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww==", - "requires": { - "balanced-match": "^1.0.0", - "postcss": "^7.0.2" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-selector-not": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-4.0.1.tgz", - "integrity": "sha512-YolvBgInEK5/79C+bdFMyzqTg6pkYqDbzZIST/PDMqa/o3qtXenD05apBG2jLgT0/BQ77d4U2UK12jWpilqMAQ==", - "requires": { - "balanced-match": "^1.0.0", - "postcss": "^7.0.2" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-selector-parser": { - "version": "6.0.9", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz", - "integrity": "sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ==", - "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - } - }, - "postcss-svgo": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.3.tgz", - "integrity": "sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==", - "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "svgo": "^1.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-unique-selectors": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", - "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", - "requires": { - "alphanum-sort": "^1.0.0", - "postcss": "^7.0.0", - "uniqs": "^2.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-url": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/postcss-url/-/postcss-url-8.0.0.tgz", - "integrity": "sha512-E2cbOQ5aii2zNHh8F6fk1cxls7QVFZjLPSrqvmiza8OuXLzIpErij8BDS5Y3STPfJgpIMNCPEr8JlKQWEoozUw==", - "requires": { - "mime": "^2.3.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.0", - "postcss": "^7.0.2", - "xxhashjs": "^0.2.1" - }, - "dependencies": { - "mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==" - }, - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" - }, - "postcss-values-parser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz", - "integrity": "sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg==", - "requires": { - "flatten": "^1.0.2", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, - "posthtml": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.9.2.tgz", - "integrity": "sha1-9MBtufZ7Yf0XxOJW5+PZUVv3Jv0=", - "requires": { - "posthtml-parser": "^0.2.0", - "posthtml-render": "^1.0.5" - } - }, - "posthtml-parser": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.2.1.tgz", - "integrity": "sha1-NdUw3jhnQMK6JP8usvrznM3ycd0=", - "requires": { - "htmlparser2": "^3.8.3", - "isobject": "^2.1.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "posthtml-rename-id": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/posthtml-rename-id/-/posthtml-rename-id-1.0.12.tgz", - "integrity": "sha512-UKXf9OF/no8WZo9edRzvuMenb6AD5hDLzIepJW+a4oJT+T/Lx7vfMYWT4aWlGNQh0WMhnUx1ipN9OkZ9q+ddEw==", - "requires": { - "escape-string-regexp": "1.0.5" - } - }, - "posthtml-render": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-1.4.0.tgz", - "integrity": "sha512-W1779iVHGfq0Fvh2PROhCe2QhB8mEErgqzo1wpIt36tCgChafP+hbXIhLDOM8ePJrZcFs0vkNEtdibEWVqChqw==" - }, - "posthtml-svg-mode": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/posthtml-svg-mode/-/posthtml-svg-mode-1.0.3.tgz", - "integrity": "sha512-hEqw9NHZ9YgJ2/0G7CECOeuLQKZi8HjWLkBaSVtOWjygQ9ZD8P7tqeowYs7WrFdKsWEKG7o+IlsPY8jrr0CJpQ==", - "requires": { - "merge-options": "1.0.1", - "posthtml": "^0.9.2", - "posthtml-parser": "^0.2.1", - "posthtml-render": "^1.0.6" - } - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" - }, - "prettier": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", - "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==" - }, - "prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "requires": { - "fast-diff": "^1.1.2" - } - }, - "pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==" - }, - "pretty-error": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", - "integrity": "sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==", - "requires": { - "lodash": "^4.17.20", - "renderkid": "^2.0.4" - } - }, - "pretty-time": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", - "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==" - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" - }, - "proper-lockfile": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", - "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", - "requires": { - "graceful-fs": "^4.2.4", - "retry": "^0.12.0", - "signal-exit": "^3.0.2" - } - }, - "protocols": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.8.tgz", - "integrity": "sha512-IgjKyaUSjsROSO8/D49Ab7hP8mJgTYcqApOqdPhLoPxAplXmkp+zRvsrSQjFn5by0rhm4VH0GAUELIPpx7B1yg==" - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, - "pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "dev": true - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "pupa": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", - "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", - "dev": true, - "requires": { - "escape-goat": "^2.0.0" - } - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "requires": { - "side-channel": "^1.0.4" - } - }, - "query-string": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", - "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", - "requires": { - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=" - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "raw-loader": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.2.tgz", - "integrity": "sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==", - "requires": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "dependencies": { - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "requires": { - "minimist": "^1.2.5" - } - }, - "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - } - } - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - } - } - }, - "rc9": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/rc9/-/rc9-1.2.0.tgz", - "integrity": "sha512-/jknmhG0USFAx5uoKkAKhtG40sONds9RWhFHrP1UzJ3OvVfqFWOypSUpmsQD0fFwAV7YtzHhsn3QNasfAoxgcQ==", - "requires": { - "defu": "^2.0.4", - "destr": "^1.0.0", - "flat": "^5.0.0" - }, - "dependencies": { - "defu": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/defu/-/defu-2.0.4.tgz", - "integrity": "sha512-G9pEH1UUMxShy6syWk01VQSRVs3CDWtlxtZu7A+NyqjxaCA4gSlWAKDBx6QiUEKezqS8+DUlXLI14Fp05Hmpwg==" - } - } - }, - "read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=", - "requires": { - "pify": "^2.3.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - } - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "requires": { - "picomatch": "^2.2.1" - } - }, - "regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" - }, - "regenerate-unicode-properties": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz", - "integrity": "sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw==", - "requires": { - "regenerate": "^1.4.2" - } - }, - "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" - }, - "regenerator-transform": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", - "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", - "requires": { - "@babel/runtime": "^7.8.4" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, - "regexpu-core": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.0.1.tgz", - "integrity": "sha512-CriEZlrKK9VJw/xQGJpQM5rY88BtuL8DM+AEwvcThHilbxiTAy8vq4iJnd2tqq8wLmjbGZzP7ZcKFjbGkmEFrw==", - "requires": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.0.1", - "regjsgen": "^0.6.0", - "regjsparser": "^0.8.2", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.0.0" - } - }, - "registry-auth-token": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", - "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", - "dev": true, - "requires": { - "rc": "^1.2.8" - } - }, - "registry-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", - "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", - "dev": true, - "requires": { - "rc": "^1.2.8" - } - }, - "regjsgen": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.6.0.tgz", - "integrity": "sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA==" - }, - "regjsparser": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.8.4.tgz", - "integrity": "sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA==", - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" - } - } - }, - "relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=" - }, - "remarkable": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/remarkable/-/remarkable-1.7.4.tgz", - "integrity": "sha512-e6NKUXgX95whv7IgddywbeN/ItCkWbISmc2DiqHJb0wTrqZIexqdco5b8Z3XZoo/48IdNVKM9ZCvTPJ4F5uvhg==", - "requires": { - "argparse": "^1.0.10", - "autolinker": "~0.28.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "optional": true - }, - "renderkid": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.7.tgz", - "integrity": "sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ==", - "requires": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "css-select": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.2.1.tgz", - "integrity": "sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==", - "requires": { - "boolbase": "^1.0.0", - "css-what": "^5.1.0", - "domhandler": "^4.3.0", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - } - }, - "css-what": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", - "integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==" - }, - "dom-serializer": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", - "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - } - }, - "domelementtype": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", - "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==" - }, - "domhandler": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz", - "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==", - "requires": { - "domelementtype": "^2.2.0" - } - }, - "domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "requires": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - } - }, - "entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" - }, - "htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - }, - "nth-check": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", - "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", - "requires": { - "boolbase": "^1.0.0" - } - } - } - }, - "repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==" - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" - }, - "resize-observer-polyfill": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", - "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" - }, - "resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", - "requires": { - "is-core-module": "^2.8.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=" - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" - }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "dev": true, - "requires": { - "lowercase-keys": "^1.0.0" - } - }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" - }, - "retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=" - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" - }, - "rgb-regex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", - "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=" - }, - "rgba-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", - "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=" - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==" - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "requires": { - "aproba": "^1.1.1" - } - }, - "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "requires": { - "tslib": "^1.9.0" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "sass": { - "version": "1.49.8", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.49.8.tgz", - "integrity": "sha512-NoGOjvDDOU9og9oAxhRnap71QaTjjlzrvLnKecUJ3GxhaQBrV6e7gPuSPF28u1OcVAArVojPAe4ZhOXwwC4tGw==", - "dev": true, - "requires": { - "chokidar": ">=3.0.0 <4.0.0", - "immutable": "^4.0.0", - "source-map-js": ">=0.6.2 <2.0.0" - } - }, - "sass-loader": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-10.2.1.tgz", - "integrity": "sha512-RRvWl+3K2LSMezIsd008ErK4rk6CulIMSwrcc2aZvjymUgKo/vjXGp1rSWmfTUX7bblEOz8tst4wBwWtCGBqKA==", - "dev": true, - "requires": { - "klona": "^2.0.4", - "loader-utils": "^2.0.0", - "neo-async": "^2.6.2", - "schema-utils": "^3.0.0", - "semver": "^7.3.2" - }, - "dependencies": { - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - } - } - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, - "scule": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/scule/-/scule-0.2.1.tgz", - "integrity": "sha512-M9gnWtn3J0W+UhJOHmBxBTwv8mZCan5i1Himp60t6vvZcor0wr+IM0URKmIglsWJ7bRujNAVVN77fp+uZaWoKg==" - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "semver-diff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", - "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", - "dev": true, - "requires": { - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", - "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "1.8.1", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - } - }, - "serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", - "requires": { - "randombytes": "^2.1.0" - } - }, - "serve-placeholder": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/serve-placeholder/-/serve-placeholder-1.2.4.tgz", - "integrity": "sha512-jWD9cZXLcr4vHTTL5KEPIUBUYyOWN/z6v/tn0l6XxFhi9iqV3Fc5Y1aFeduUyz+cx8sALzGCUczkPfeOlrq9jg==", - "requires": { - "defu": "^5.0.0" - } - }, - "serve-static": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", - "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.2" - } - }, - "server-destroy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", - "integrity": "sha1-8Tv5KOQrnD55OD5hzDmYtdFObN0=" - }, - "set-getter": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.1.tgz", - "integrity": "sha512-9sVWOy+gthr+0G9DzqqLaYNA7+5OKkSmcqjL9cBpDEaZrr3ShQlyX2cZ/O/ozE41oxn/Tt0LGEM/w4Rub3A3gw==", - "requires": { - "to-object-path": "^0.3.0" - } - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "requires": { - "kind-of": "^6.0.2" - } - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "shell-quote": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz", - "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==" - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, - "simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", - "requires": { - "is-arrayish": "^0.3.1" - }, - "dependencies": { - "is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - } - } - }, - "sirv": { - "version": "1.0.19", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.19.tgz", - "integrity": "sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==", - "requires": { - "@polka/url": "^1.0.0-next.20", - "mrmime": "^1.0.0", - "totalist": "^1.0.0" - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", - "requires": { - "is-plain-obj": "^1.0.0" - }, - "dependencies": { - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" - } - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - }, - "source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==" - }, - "split-on-first": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", - "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==" - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "requires": { - "extend-shallow": "^3.0.0" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "ssri": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", - "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", - "requires": { - "minipass": "^3.1.1" - } - }, - "stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==" - }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" - }, - "stackframe": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.1.tgz", - "integrity": "sha512-h88QkzREN/hy8eRdyNhhsO7RSJ5oyTqxxmmn0dzBIMUclZsjpfmrsg81vp8mjjAs2vAZ72nyWxRUwSwmh0e4xg==" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" - }, - "std-env": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-2.3.1.tgz", - "integrity": "sha512-eOsoKTWnr6C8aWrqJJ2KAReXoa7Vn5Ywyw6uCXgA/xDhxPoaIsBa5aNJmISY04dLwXPBnDHW4diGM7Sn5K4R/g==", - "requires": { - "ci-info": "^3.1.1" - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-color": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/strip-color/-/strip-color-0.1.0.tgz", - "integrity": "sha1-EG9l09PmotlAHKwOsM6LinArT3s=" - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "style-resources-loader": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/style-resources-loader/-/style-resources-loader-1.5.0.tgz", - "integrity": "sha512-fIfyvQ+uvXaCBGGAgfh+9v46ARQB1AWdaop2RpQw0PBVuROsTBqGvx8dj0kxwjGOAyq3vepe4AOK3M6+Q/q2jw==", - "requires": { - "glob": "^7.2.0", - "loader-utils": "^2.0.0", - "schema-utils": "^2.7.0", - "tslib": "^2.3.1" - }, - "dependencies": { - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "requires": { - "minimist": "^1.2.5" - } - }, - "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "requires": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - } - } - } - }, - "stylehacks": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", - "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", - "requires": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "requires": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "requires": { - "has-flag": "^1.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" - }, - "svg-baker": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/svg-baker/-/svg-baker-1.7.0.tgz", - "integrity": "sha512-nibslMbkXOIkqKVrfcncwha45f97fGuAOn1G99YwnwTj8kF9YiM6XexPcUso97NxOm6GsP0SIvYVIosBis1xLg==", - "requires": { - "bluebird": "^3.5.0", - "clone": "^2.1.1", - "he": "^1.1.1", - "image-size": "^0.5.1", - "loader-utils": "^1.1.0", - "merge-options": "1.0.1", - "micromatch": "3.1.0", - "postcss": "^5.2.17", - "postcss-prefix-selector": "^1.6.0", - "posthtml-rename-id": "^1.0", - "posthtml-svg-mode": "^1.0.3", - "query-string": "^4.3.2", - "traverse": "^0.6.6" - }, - "dependencies": { - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" - }, - "micromatch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.0.tgz", - "integrity": "sha512-3StSelAE+hnRvMs8IdVW7Uhk8CVed5tp+kLLGlBP6WiRAXS21GPGu/Nat4WNPXj2Eoc24B02SaeoyozPMfj0/g==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.2.2", - "define-property": "^1.0.0", - "extend-shallow": "^2.0.1", - "extglob": "^2.0.2", - "fragment-cache": "^0.2.1", - "kind-of": "^5.0.2", - "nanomatch": "^1.2.1", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - } - } - }, - "svg-baker-runtime": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/svg-baker-runtime/-/svg-baker-runtime-1.4.7.tgz", - "integrity": "sha512-Zorfwwj5+lWjk/oxwSMsRdS2sPQQdTmmsvaSpzU+i9ZWi3zugHLt6VckWfnswphQP0LmOel3nggpF5nETbt6xw==", - "requires": { - "deepmerge": "1.3.2", - "mitt": "1.1.2", - "svg-baker": "^1.7.0" - } - }, - "svg-sprite-loader": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/svg-sprite-loader/-/svg-sprite-loader-5.2.1.tgz", - "integrity": "sha512-n2IZc87rpOeXh+PQFksFMGCfMV/BT01YG+Dlbyjoh2Cz8BSTL5Vi/7KDr86Pt/u1NRDCVb3vY74BF5rKCmqbNA==", - "requires": { - "bluebird": "^3.5.0", - "deepmerge": "1.3.2", - "domready": "1.0.8", - "escape-string-regexp": "1.0.5", - "loader-utils": "^1.1.0", - "svg-baker": "^1.5.0", - "svg-baker-runtime": "^1.4.7", - "url-slug": "2.0.0" - } - }, - "svg-tags": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", - "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=" - }, - "svg-to-vue": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/svg-to-vue/-/svg-to-vue-0.7.0.tgz", - "integrity": "sha512-Tg2nMmf3BQorYCAjxbtTkYyWPVSeox5AZUFvfy4MoWK/5tuQlnA/h3LAlTjV3sEvOC5FtUNovRSj3p784l4KOA==", - "requires": { - "svgo": "^1.3.2" - } - }, - "svgo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", - "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", - "requires": { - "chalk": "^2.4.1", - "coa": "^2.0.2", - "css-select": "^2.0.0", - "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.37", - "csso": "^4.0.2", - "js-yaml": "^3.13.1", - "mkdirp": "~0.5.1", - "object.values": "^1.1.0", - "sax": "~1.2.4", - "stable": "^0.1.8", - "unquote": "~1.1.1", - "util.promisify": "~1.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" - }, - "tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" - } - } - }, - "terser": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", - "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "terser-webpack-plugin": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-4.2.3.tgz", - "integrity": "sha512-jTgXh40RnvOrLQNgIkwEKnQ8rmHjHK4u+6UBEi+W+FPmvb+uo+chJXntKe7/3lW5mNysgSWD60KyesnhW8D6MQ==", - "requires": { - "cacache": "^15.0.5", - "find-cache-dir": "^3.3.1", - "jest-worker": "^26.5.0", - "p-limit": "^3.0.2", - "schema-utils": "^3.0.0", - "serialize-javascript": "^5.0.1", - "source-map": "^0.6.1", - "terser": "^5.3.4", - "webpack-sources": "^1.4.3" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "terser": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.11.0.tgz", - "integrity": "sha512-uCA9DLanzzWSsN1UirKwylhhRz3aKPInlfmpGfw8VN6jHsAtu8HJtIpeeHHK23rxnE/cDc+yvmq5wqkIC6Kn0A==", - "requires": { - "acorn": "^8.5.0", - "commander": "^2.20.0", - "source-map": "~0.7.2", - "source-map-support": "~0.5.20" - }, - "dependencies": { - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" - } - } - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" - }, - "thread-loader": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/thread-loader/-/thread-loader-3.0.4.tgz", - "integrity": "sha512-ByaL2TPb+m6yArpqQUZvP+5S1mZtXsEP7nWKKlAUTm7fCml8kB5s1uI3+eHRP2bk5mVYfRSBI7FFf+tWEyLZwA==", - "requires": { - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.1.0", - "loader-utils": "^2.0.0", - "neo-async": "^2.6.2", - "schema-utils": "^3.0.0" - }, - "dependencies": { - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "requires": { - "minimist": "^1.2.5" - } - }, - "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - } - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "time-fix-plugin": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/time-fix-plugin/-/time-fix-plugin-2.0.7.tgz", - "integrity": "sha512-uVFet1LQToeUX0rTcSiYVYVoGuBpc8gP/2jnlUzuHMHe+gux6XLsNzxLUweabMwiUj5ejhoIMsUI55nVSEa/Vw==", - "requires": {} - }, - "timers-browserify": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", - "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", - "requires": { - "setimmediate": "^1.0.4" - } - }, - "timsort": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=" - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "dev": true - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "dependencies": { - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - } - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "requires": { - "is-number": "^7.0.0" - } - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" - }, - "toml": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/toml/-/toml-2.3.6.tgz", - "integrity": "sha512-gVweAectJU3ebq//Ferr2JUY4WKSDe5N+z0FvjDncLGyHmIDoxgY/2Ie4qfEIDm4IS7OA6Rmdm7pdEEdMcV/xQ==" - }, - "totalist": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", - "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==" - }, - "touch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", - "dev": true, - "requires": { - "nopt": "~1.0.10" - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" - }, - "traverse": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", - "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=" - }, - "ts-pnp": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz", - "integrity": "sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==" - }, - "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=" - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "ua-parser-js": { - "version": "0.7.31", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.31.tgz", - "integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==" - }, - "uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" - }, - "ufo": { - "version": "0.7.10", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-0.7.10.tgz", - "integrity": "sha512-YTnDRlE1cIofRqOFN8ioAbz9qenDvkgVMSn0cnxvIDjM9sfEOMKB0ybMr+otSlCXMfQ/X35haYRoI7Nua82RrA==" - }, - "uglify-js": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.1.tgz", - "integrity": "sha512-FAGKF12fWdkpvNJZENacOH0e/83eG6JyVQyanIJaBXCN1J11TUQv1T1/z8S+Z0CG0ZPk1nPcreF/c7lrTd0TEQ==" - }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, - "undefsafe": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", - "dev": true - }, - "unfetch": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz", - "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==" - }, - "unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==" - }, - "unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "requires": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - } - }, - "unicode-match-property-value-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", - "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==" - }, - "unicode-property-aliases-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", - "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==" - }, - "unidecode": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/unidecode/-/unidecode-0.1.8.tgz", - "integrity": "sha1-77swFTi8RSRqmsjFWdcvAVMFBT4=" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" - }, - "uniqs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", - "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=" - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dev": true, - "requires": { - "crypto-random-string": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "unquote": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", - "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" - } - } - }, - "upath": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz", - "integrity": "sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==" - }, - "update-notifier": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", - "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", - "dev": true, - "requires": { - "boxen": "^5.0.0", - "chalk": "^4.1.0", - "configstore": "^5.0.1", - "has-yarn": "^2.1.0", - "import-lazy": "^2.1.0", - "is-ci": "^2.0.0", - "is-installed-globally": "^0.4.0", - "is-npm": "^5.0.0", - "is-yarn-global": "^0.3.0", - "latest-version": "^5.1.0", - "pupa": "^2.1.1", - "semver": "^7.3.4", - "semver-diff": "^3.1.1", - "xdg-basedir": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "upper-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", - "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=" - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" - } - } - }, - "url-loader": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", - "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", - "requires": { - "loader-utils": "^2.0.0", - "mime-types": "^2.1.27", - "schema-utils": "^3.0.0" - }, - "dependencies": { - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "requires": { - "minimist": "^1.2.5" - } - }, - "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - } - } - }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "dev": true, - "requires": { - "prepend-http": "^2.0.0" - }, - "dependencies": { - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", - "dev": true - } - } - }, - "url-slug": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/url-slug/-/url-slug-2.0.0.tgz", - "integrity": "sha1-p4nVrtSZXA2VrzM3etHVxo1NcCc=", - "requires": { - "unidecode": "0.1.8" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "util.promisify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", - "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.2", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.0" - } - }, - "utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "vendors": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", - "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==" - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==" - }, - "vue": { - "version": "2.6.14", - "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.14.tgz", - "integrity": "sha512-x2284lgYvjOMj3Za7kqzRcUSxBboHqtgRE2zlos1qWaOye5yUmHn42LB1250NJBLRwEcdrB0JRwyPTEPhfQjiQ==" - }, - "vue-analytics": { - "version": "5.22.1", - "resolved": "https://registry.npmjs.org/vue-analytics/-/vue-analytics-5.22.1.tgz", - "integrity": "sha512-HPKQMN7gfcUqS5SxoO0VxqLRRSPkG1H1FqglsHccz6BatBatNtm/Vyy8brApktZxNCfnAkrSVDpxg3/FNDeOgQ==" - }, - "vue-client-only": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/vue-client-only/-/vue-client-only-2.1.0.tgz", - "integrity": "sha512-vKl1skEKn8EK9f8P2ZzhRnuaRHLHrlt1sbRmazlvsx6EiC3A8oWF8YCBrMJzoN+W3OnElwIGbVjsx6/xelY1AA==" - }, - "vue-codemirror": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/vue-codemirror/-/vue-codemirror-4.0.6.tgz", - "integrity": "sha512-ilU7Uf0mqBNSSV3KT7FNEeRIxH4s1fmpG4TfHlzvXn0QiQAbkXS9lLfwuZpaBVEnpP5CSE62iGJjoliTuA8poQ==", - "requires": { - "codemirror": "^5.41.0", - "diff-match-patch": "^1.0.0" - } - }, - "vue-eslint-parser": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.2.0.tgz", - "integrity": "sha512-hvl8OVT8imlKk/lQyhkshqwQQChzHETcBd5abiO4ePw7ib7QUZLfW+2TUrJHKUvFOCFRJrDin5KJO9OHzB5bRQ==", - "dev": true, - "requires": { - "debug": "^4.3.2", - "eslint-scope": "^7.0.0", - "eslint-visitor-keys": "^3.1.0", - "espree": "^9.0.0", - "esquery": "^1.4.0", - "lodash": "^4.17.21", - "semver": "^7.3.5" - }, - "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "vue-highlightjs": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/vue-highlightjs/-/vue-highlightjs-1.3.3.tgz", - "integrity": "sha1-KaDVcTL8HOFc+mHolpGPW3GMXVI=", - "requires": { - "highlight.js": "*" - } - }, - "vue-hot-reload-api": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz", - "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==" - }, - "vue-js-modal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/vue-js-modal/-/vue-js-modal-2.0.1.tgz", - "integrity": "sha512-5FUwsH2zoxRKX4a7wkFAqX0eITCcIMunJDEfIxzHs2bHw9o20+Iqm+uQvBcg1jkzyo1+tVgThR/7NGU8djbD8Q==", - "requires": { - "resize-observer-polyfill": "^1.5.1" - } - }, - "vue-loader": { - "version": "15.9.8", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.8.tgz", - "integrity": "sha512-GwSkxPrihfLR69/dSV3+5CdMQ0D+jXg8Ma1S4nQXKJAznYFX14vHdc/NetQc34Dw+rBbIJyP7JOuVb9Fhprvog==", - "requires": { - "@vue/component-compiler-utils": "^3.1.0", - "hash-sum": "^1.0.2", - "loader-utils": "^1.1.0", - "vue-hot-reload-api": "^2.3.0", - "vue-style-loader": "^4.1.0" - }, - "dependencies": { - "hash-sum": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", - "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=" - } - } - }, - "vue-meta": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/vue-meta/-/vue-meta-2.4.0.tgz", - "integrity": "sha512-XEeZUmlVeODclAjCNpWDnjgw+t3WA6gdzs6ENoIAgwO1J1d5p1tezDhtteLUFwcaQaTtayRrsx7GL6oXp/m2Jw==", - "requires": { - "deepmerge": "^4.2.2" - }, - "dependencies": { - "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" - } - } - }, - "vue-no-ssr": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/vue-no-ssr/-/vue-no-ssr-1.1.1.tgz", - "integrity": "sha512-ZMjqRpWabMPqPc7gIrG0Nw6vRf1+itwf0Itft7LbMXs2g3Zs/NFmevjZGN1x7K3Q95GmIjWbQZTVerxiBxI+0g==" - }, - "vue-router": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.3.tgz", - "integrity": "sha512-FUlILrW3DGitS2h+Xaw8aRNvGTwtuaxrRkNSHWTizOfLUie7wuYwezeZ50iflRn8YPV5kxmU2LQuu3nM/b3Zsg==" - }, - "vue-server-renderer": { - "version": "2.6.14", - "resolved": "https://registry.npmjs.org/vue-server-renderer/-/vue-server-renderer-2.6.14.tgz", - "integrity": "sha512-HifYRa/LW7cKywg9gd4ZtvtRuBlstQBao5ZCWlg40fyB4OPoGfEXAzxb0emSLv4pBDOHYx0UjpqvxpiQFEuoLA==", - "requires": { - "chalk": "^1.1.3", - "hash-sum": "^1.0.2", - "he": "^1.1.0", - "lodash.template": "^4.5.0", - "lodash.uniq": "^4.5.0", - "resolve": "^1.2.0", - "serialize-javascript": "^3.1.0", - "source-map": "0.5.6" - }, - "dependencies": { - "hash-sum": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", - "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=" - }, - "serialize-javascript": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", - "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==", - "requires": { - "randombytes": "^2.1.0" - } - }, - "source-map": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", - "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=" - } - } - }, - "vue-style-loader": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz", - "integrity": "sha512-sFuh0xfbtpRlKfm39ss/ikqs9AbKCoXZBpHeVZ8Tx650o0k0q/YCM7FRvigtxpACezfq6af+a7JeqVTWvncqDg==", - "requires": { - "hash-sum": "^1.0.2", - "loader-utils": "^1.0.2" - }, - "dependencies": { - "hash-sum": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", - "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=" - } - } - }, - "vue-svg-loader": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/vue-svg-loader/-/vue-svg-loader-0.16.0.tgz", - "integrity": "sha512-2RtFXlTCYWm8YAEO2qAOZ2SuIF2NvLutB5muc3KDYoZq5ZeCHf8ggzSan3ksbbca7CJ/Aw57ZnDF4B7W/AkGtw==", - "requires": { - "loader-utils": "^1.2.3", - "svg-to-vue": "^0.7.0" - } - }, - "vue-template-compiler": { - "version": "2.6.14", - "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.14.tgz", - "integrity": "sha512-ODQS1SyMbjKoO1JBJZojSw6FE4qnh9rIpUZn2EUT86FKizx9uH5z6uXiIrm4/Nb/gwxTi/o17ZDEGWAXHvtC7g==", - "requires": { - "de-indent": "^1.0.2", - "he": "^1.1.0" - } - }, - "vue-template-es2015-compiler": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz", - "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==" - }, - "vuex": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.2.tgz", - "integrity": "sha512-ETW44IqCgBpVomy520DT5jf8n0zoCac+sxWnn+hMe/CzaSejb/eVw2YToiXYX+Ex/AuHHia28vWTq4goAexFbw==", - "requires": {} - }, - "watchpack": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", - "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", - "requires": { - "chokidar": "^3.4.1", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0", - "watchpack-chokidar2": "^2.0.1" - } - }, - "watchpack-chokidar2": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", - "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==", - "optional": true, - "requires": { - "chokidar": "^2.1.8" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "optional": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "optional": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "optional": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "optional": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "optional": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "optional": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - } - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "optional": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "optional": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "optional": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "optional": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "optional": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "optional": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "optional": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "optional": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "optional": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "optional": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "optional": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "optional": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "optional": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "optional": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "optional": true - } - } - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" - }, - "webpack": { - "version": "4.46.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz", - "integrity": "sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q==", - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/wasm-edit": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "acorn": "^6.4.1", - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.5.0", - "eslint-scope": "^4.0.3", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.4.0", - "loader-utils": "^1.2.3", - "memory-fs": "^0.4.1", - "micromatch": "^3.1.10", - "mkdirp": "^0.5.3", - "neo-async": "^2.6.1", - "node-libs-browser": "^2.2.1", - "schema-utils": "^1.0.0", - "tapable": "^1.1.3", - "terser-webpack-plugin": "^1.4.3", - "watchpack": "^1.7.4", - "webpack-sources": "^1.4.1" - }, - "dependencies": { - "acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==" - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - } - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==" - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - } - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "requires": { - "find-up": "^3.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", - "requires": { - "randombytes": "^2.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "ssri": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", - "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "terser-webpack-plugin": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", - "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", - "requires": { - "cacache": "^12.0.2", - "find-cache-dir": "^2.1.0", - "is-wsl": "^1.1.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^4.0.0", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - } - } - }, - "webpack-bundle-analyzer": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.5.0.tgz", - "integrity": "sha512-GUMZlM3SKwS8Z+CKeIFx7CVoHn3dXFcUAjT/dcZQQmfSZGvitPfMob2ipjai7ovFFqPvTqkEZ/leL4O0YOdAYQ==", - "requires": { - "acorn": "^8.0.4", - "acorn-walk": "^8.0.0", - "chalk": "^4.1.0", - "commander": "^7.2.0", - "gzip-size": "^6.0.0", - "lodash": "^4.17.20", - "opener": "^1.5.2", - "sirv": "^1.0.7", - "ws": "^7.3.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "webpack-dev-middleware": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-4.3.0.tgz", - "integrity": "sha512-PjwyVY95/bhBh6VUqt6z4THplYcsvQ8YNNBTBM873xLVmw8FLeALn0qurHbs9EmcfhzQis/eoqypSnZeuUz26w==", - "requires": { - "colorette": "^1.2.2", - "mem": "^8.1.1", - "memfs": "^3.2.2", - "mime-types": "^2.1.30", - "range-parser": "^1.2.1", - "schema-utils": "^3.0.0" - } - }, - "webpack-hot-middleware": { - "version": "2.25.1", - "resolved": "https://registry.npmjs.org/webpack-hot-middleware/-/webpack-hot-middleware-2.25.1.tgz", - "integrity": "sha512-Koh0KyU/RPYwel/khxbsDz9ibDivmUbrRuKSSQvW42KSDdO4w23WI3SkHpSUKHE76LrFnnM/L7JCrpBwu8AXYw==", - "requires": { - "ansi-html-community": "0.0.8", - "html-entities": "^2.1.0", - "querystring": "^0.2.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "webpack-node-externals": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-3.0.0.tgz", - "integrity": "sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==" - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "webpackbar": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-4.0.0.tgz", - "integrity": "sha512-k1qRoSL/3BVuINzngj09nIwreD8wxV4grcuhHTD8VJgUbGcy8lQSPqv+bM00B7F+PffwIsQ8ISd4mIwRbr23eQ==", - "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^2.4.2", - "consola": "^2.10.0", - "figures": "^3.0.0", - "pretty-time": "^1.1.0", - "std-env": "^2.2.1", - "text-table": "^0.2.0", - "wrap-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "requires": { - "string-width": "^4.0.0" - } - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "workbox-cdn": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-cdn/-/workbox-cdn-5.1.4.tgz", - "integrity": "sha512-04gM3mi8QGutokkSaA9xunVfjURnLbo9TTWyi8+pSDCEW5cD8u5GbJiliLK1vB9CShk/9OY1UDfW+XcmD+d6KQ==" - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "write-file-atomic": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", - "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } - }, - "write-json-file": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-2.3.0.tgz", - "integrity": "sha1-K2TIozAE1UuGmMdtWFp3zrYdoy8=", - "requires": { - "detect-indent": "^5.0.0", - "graceful-fs": "^4.1.2", - "make-dir": "^1.0.0", - "pify": "^3.0.0", - "sort-keys": "^2.0.0", - "write-file-atomic": "^2.0.0" - }, - "dependencies": { - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" - }, - "sort-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", - "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", - "requires": { - "is-plain-obj": "^1.0.0" - } - } - } - }, - "ws": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", - "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", - "requires": {} - }, - "xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "dev": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, - "xxhashjs": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz", - "integrity": "sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw==", - "requires": { - "cuint": "^0.2.2" - } - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" - } - } -} diff --git a/package.json b/package.json index a7cb72ff..5add3f37 100644 --- a/package.json +++ b/package.json @@ -1,60 +1,41 @@ { "name": "hapi.dev", "version": "1.0.0", + "private": true, "description": "The hapi.dev developer portal", + "type": "module", + "packageManager": "pnpm@10.33.0", "repository": "git://github.com/hapijs/hapi.dev", "scripts": { - "dev": "cross-env NODE_ENV=development nodemon server/index.js --watch server", - "static": "NODE_ENV=production node server/static.js", - "build": "nuxt build", - "docker-build": "docker build -t hapi.dev .", - "docker-up": "docker-compose up -d", - "docker-down": "docker-compose down", - "gen": "nuxt generate", - "start": "cross-env NODE_ENV=production node server/index.js", - "generate": "node assets/js/getModuleInfo && nuxt generate", - "lint": "eslint --ext .js,.vue --ignore-path .gitignore .", - "devTest": "node assets/js/getModuleInfo", - "lintfix": "eslint --fix --ext .js,.vue --ignore-path .gitignore ." + "dev": "vitepress dev", + "fetch-data": "tsx cli/getModuleInfo.ts", + "build": "vitepress build", + "preview": "vitepress preview", + "generate": "tsx cli/getModuleInfo.ts && vitepress build", + "lint": "oxlint", + "lint:fix": "oxlint --fix", + "fmt": "oxfmt --check", + "fmt:fix": "oxfmt", + "test": "pnpm run lint && pnpm run fmt && tsc --noEmit" }, "license": "BSD-3-Clause", "dependencies": { - "@aitodotai/json-stringify-pretty-compact": "^1.3.0", - "@hapi/hapi": "^20.2.1", - "@hapi/inert": "^6.0.5", - "@nuxtjs/axios": "^5.12.2", - "@nuxtjs/dotenv": "^1.3.0", - "@nuxtjs/google-analytics": "^2.2.0", - "@nuxtjs/hapi": "^3.0.0", - "@nuxtjs/markdownit": "^2.0.0", - "@nuxtjs/pwa": "^3.2.2", - "@nuxtjs/svg": "^0.4.0", - "axios": "^0.26.0", - "bulma": "^0.9.1", - "cookie-universal-nuxt": "^2.0.17", - "cross-env": "^7.0.2", - "fs": "0.0.1-security", - "highlight.js": "^11.4.0", - "js-yaml": "^4.0.0", - "lodash": "^4.17.20", - "markdown-toc": "^1.2.0", - "nuxt": "^2.15.8", - "semver": "^7.3.2", - "vue-codemirror": "^4.0.6", - "vue-highlightjs": "^1.3.3", - "vue-js-modal": "^2.0.1" + "@vueuse/core": "^14.2.1", + "es-toolkit": "^1.45.1", + "feed": "^5.2.0", + "semver": "^7.7.4", + "vitepress-plugin-group-icons": "^1.7.3", + "vue": "^3.5.31" }, "devDependencies": { - "babel-eslint": "^10.0.3", - "dotenv": "^16.4.5", - "eslint": "^8.9.0", - "eslint-config-prettier": "^8.4.0", - "eslint-loader": "^4.0.2", - "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-vue": "^8.4.1", - "nodemon": "^2.0.15", - "prettier": "^2.5.1", - "sass": "^1.49.8", - "sass-loader": "^10.1.1" + "@octokit/plugin-throttling": "^11.0.3", + "@octokit/rest": "^22.0.1", + "@types/node": "^24.12.0", + "@types/semver": "^7.7.1", + "oxfmt": "^0.43.0", + "oxlint": "^1.59.0", + "tsx": "^4.21.0", + "typescript": "^6.0.2", + "vitepress": "2.0.0-alpha.17" } } diff --git a/pages/api.vue b/pages/api.vue deleted file mode 100644 index 26c3ccd2..00000000 --- a/pages/api.vue +++ /dev/null @@ -1,280 +0,0 @@ - - - - - diff --git a/pages/index.vue b/pages/index.vue deleted file mode 100644 index 7c88a27a..00000000 --- a/pages/index.vue +++ /dev/null @@ -1,405 +0,0 @@ - - - - - diff --git a/pages/module/_family/api/index.vue b/pages/module/_family/api/index.vue deleted file mode 100644 index d9ebd62d..00000000 --- a/pages/module/_family/api/index.vue +++ /dev/null @@ -1,601 +0,0 @@ - - - - - diff --git a/pages/module/_family/changelog.vue b/pages/module/_family/changelog.vue deleted file mode 100644 index 59f41289..00000000 --- a/pages/module/_family/changelog.vue +++ /dev/null @@ -1,167 +0,0 @@ - - - - - diff --git a/pages/module/_family/index.vue b/pages/module/_family/index.vue deleted file mode 100644 index 31e55335..00000000 --- a/pages/module/_family/index.vue +++ /dev/null @@ -1,473 +0,0 @@ - - - - - diff --git a/pages/module/bell/api/index.vue b/pages/module/bell/api/index.vue deleted file mode 100644 index 4bf8db18..00000000 --- a/pages/module/bell/api/index.vue +++ /dev/null @@ -1,615 +0,0 @@ - - - - - diff --git a/pages/module/bell/changelog.vue b/pages/module/bell/changelog.vue deleted file mode 100644 index 67ba2cf8..00000000 --- a/pages/module/bell/changelog.vue +++ /dev/null @@ -1,163 +0,0 @@ - - - - - diff --git a/pages/module/bell/examples.vue b/pages/module/bell/examples.vue deleted file mode 100644 index 1cdcbf25..00000000 --- a/pages/module/bell/examples.vue +++ /dev/null @@ -1,572 +0,0 @@ - - - - - diff --git a/pages/module/bell/index.vue b/pages/module/bell/index.vue deleted file mode 100644 index 2185baf3..00000000 --- a/pages/module/bell/index.vue +++ /dev/null @@ -1,496 +0,0 @@ - - - - - diff --git a/pages/module/bell/providers.vue b/pages/module/bell/providers.vue deleted file mode 100644 index afc1964d..00000000 --- a/pages/module/bell/providers.vue +++ /dev/null @@ -1,539 +0,0 @@ - - - - - diff --git a/pages/module/index.vue b/pages/module/index.vue deleted file mode 100644 index 90dfc8b0..00000000 --- a/pages/module/index.vue +++ /dev/null @@ -1,267 +0,0 @@ - - - - - diff --git a/pages/plugins.vue b/pages/plugins.vue deleted file mode 100644 index 9b237f9c..00000000 --- a/pages/plugins.vue +++ /dev/null @@ -1,235 +0,0 @@ - - - - - diff --git a/pages/policies/coc.vue b/pages/policies/coc.vue deleted file mode 100644 index 791dc7e6..00000000 --- a/pages/policies/coc.vue +++ /dev/null @@ -1,86 +0,0 @@ - - - - - diff --git a/pages/policies/contributing.vue b/pages/policies/contributing.vue deleted file mode 100644 index e1e627c6..00000000 --- a/pages/policies/contributing.vue +++ /dev/null @@ -1,86 +0,0 @@ - - - - - diff --git a/pages/policies/index.vue b/pages/policies/index.vue deleted file mode 100644 index 8d7dc6b0..00000000 --- a/pages/policies/index.vue +++ /dev/null @@ -1,17 +0,0 @@ - - - - - \ No newline at end of file diff --git a/pages/policies/license.vue b/pages/policies/license.vue deleted file mode 100644 index f339d043..00000000 --- a/pages/policies/license.vue +++ /dev/null @@ -1,86 +0,0 @@ - - - - - diff --git a/pages/policies/security.vue b/pages/policies/security.vue deleted file mode 100644 index 97316652..00000000 --- a/pages/policies/security.vue +++ /dev/null @@ -1,86 +0,0 @@ - - - - - diff --git a/pages/policies/sponsors.vue b/pages/policies/sponsors.vue deleted file mode 100644 index 08fe276c..00000000 --- a/pages/policies/sponsors.vue +++ /dev/null @@ -1,98 +0,0 @@ - - - - - diff --git a/pages/policies/styleguide.vue b/pages/policies/styleguide.vue deleted file mode 100644 index 62965adc..00000000 --- a/pages/policies/styleguide.vue +++ /dev/null @@ -1,86 +0,0 @@ - - - - - diff --git a/pages/policies/support.vue b/pages/policies/support.vue deleted file mode 100644 index 25fd7a85..00000000 --- a/pages/policies/support.vue +++ /dev/null @@ -1,61 +0,0 @@ - - - - - \ No newline at end of file diff --git a/pages/resources/changelog.vue b/pages/resources/changelog.vue deleted file mode 100644 index bd2b4699..00000000 --- a/pages/resources/changelog.vue +++ /dev/null @@ -1,126 +0,0 @@ - - - - - diff --git a/pages/resources/index.vue b/pages/resources/index.vue deleted file mode 100644 index f27f2ba8..00000000 --- a/pages/resources/index.vue +++ /dev/null @@ -1,13 +0,0 @@ - - - \ No newline at end of file diff --git a/pages/resources/list.vue b/pages/resources/list.vue deleted file mode 100644 index 93442f74..00000000 --- a/pages/resources/list.vue +++ /dev/null @@ -1,76 +0,0 @@ - - - - - diff --git a/pages/resources/status.vue b/pages/resources/status.vue deleted file mode 100644 index a3ef3a53..00000000 --- a/pages/resources/status.vue +++ /dev/null @@ -1,452 +0,0 @@ - - - - - diff --git a/pages/support.vue b/pages/support.vue deleted file mode 100644 index f5da3bd6..00000000 --- a/pages/support.vue +++ /dev/null @@ -1,171 +0,0 @@ - - - - - diff --git a/pages/tutorials/_tutorial.vue b/pages/tutorials/_tutorial.vue deleted file mode 100644 index ef7f3e58..00000000 --- a/pages/tutorials/_tutorial.vue +++ /dev/null @@ -1,271 +0,0 @@ - - - - - diff --git a/pages/tutorials/index.vue b/pages/tutorials/index.vue deleted file mode 100644 index e3172f14..00000000 --- a/pages/tutorials/index.vue +++ /dev/null @@ -1,264 +0,0 @@ - - - - - diff --git a/plugins/README.md b/plugins/README.md deleted file mode 100644 index ca1f9d8a..00000000 --- a/plugins/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# PLUGINS - -**This directory is not required, you can delete it if you don't want to use it.** - -This directory contains Javascript plugins that you want to run before mounting the root Vue.js application. - -More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/plugins). diff --git a/plugins/vue-codemirror.js b/plugins/vue-codemirror.js deleted file mode 100644 index 4710a8b7..00000000 --- a/plugins/vue-codemirror.js +++ /dev/null @@ -1,6 +0,0 @@ -import Vue from 'vue' - -if (process.browser) { - const VueCodeMirror = require('vue-codemirror') - Vue.use(VueCodeMirror) -} \ No newline at end of file diff --git a/plugins/vue-highlightjs.js b/plugins/vue-highlightjs.js deleted file mode 100644 index 04c74b16..00000000 --- a/plugins/vue-highlightjs.js +++ /dev/null @@ -1,4 +0,0 @@ -import Vue from 'vue' -import VueHighlightJS from 'vue-highlightjs' - -Vue.use(VueHighlightJS) \ No newline at end of file diff --git a/plugins/vue-js-modal.js b/plugins/vue-js-modal.js deleted file mode 100644 index 0467235e..00000000 --- a/plugins/vue-js-modal.js +++ /dev/null @@ -1,4 +0,0 @@ -import Vue from 'vue' -import VModal from 'vue-js-modal/dist/ssr.index' - -Vue.use(VModal) \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 00000000..0ceb0b92 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,2206 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@vueuse/core': + specifier: ^14.2.1 + version: 14.2.1(vue@3.5.32(typescript@6.0.2)) + es-toolkit: + specifier: ^1.45.1 + version: 1.45.1 + feed: + specifier: ^5.2.0 + version: 5.2.0 + semver: + specifier: ^7.7.4 + version: 7.7.4 + vitepress-plugin-group-icons: + specifier: ^1.7.3 + version: 1.7.3(vite@7.3.2(@types/node@24.12.2)(tsx@4.21.0)) + vue: + specifier: ^3.5.31 + version: 3.5.32(typescript@6.0.2) + devDependencies: + '@octokit/plugin-throttling': + specifier: ^11.0.3 + version: 11.0.3(@octokit/core@7.0.6) + '@octokit/rest': + specifier: ^22.0.1 + version: 22.0.1 + '@types/node': + specifier: ^24.12.0 + version: 24.12.2 + '@types/semver': + specifier: ^7.7.1 + version: 7.7.1 + oxfmt: + specifier: ^0.43.0 + version: 0.43.0 + oxlint: + specifier: ^1.59.0 + version: 1.59.0 + tsx: + specifier: ^4.21.0 + version: 4.21.0 + typescript: + specifier: ^6.0.2 + version: 6.0.2 + vitepress: + specifier: 2.0.0-alpha.17 + version: 2.0.0-alpha.17(@types/node@24.12.2)(postcss@8.5.8)(tsx@4.21.0)(typescript@6.0.2) + +packages: + + '@antfu/install-pkg@1.1.0': + resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.2': + resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} + + '@docsearch/css@4.6.2': + resolution: {integrity: sha512-fH/cn8BjEEdM2nJdjNMHIvOVYupG6AIDtFVDgIZrNzdCSj4KXr9kd+hsehqsNGYjpUjObeKYKvgy/IwCb1jZYQ==} + + '@docsearch/js@4.6.2': + resolution: {integrity: sha512-qj1yoxl3y4GKoK7+VM6fq/rQqPnvUmg3IKzJ9x0VzN14QVzdB/SG/J6VfV1BWT5RcPUFxIcVwoY1fwHM2fSRRw==} + + '@docsearch/sidepanel-js@4.6.2': + resolution: {integrity: sha512-Pni85AP/GwRj7fFg8cBJp0U04tzbueBvWSd3gysgnOsVnQVSZwSYncfErUScLE1CAtR+qocPDFjmYR9AMRNJtQ==} + + '@esbuild/aix-ppc64@0.27.7': + resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.27.7': + resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.27.7': + resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.27.7': + resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.27.7': + resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.7': + resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.27.7': + resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.7': + resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.27.7': + resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.27.7': + resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.27.7': + resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.27.7': + resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.27.7': + resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.27.7': + resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.7': + resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.27.7': + resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.27.7': + resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.27.7': + resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.7': + resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.27.7': + resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.7': + resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.7': + resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.27.7': + resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.27.7': + resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.27.7': + resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.27.7': + resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@iconify-json/logos@1.2.11': + resolution: {integrity: sha512-fOo4pGEatuyuCFNL+cwquYMa2Im0oJHRHV7lt/Qqs5Ode/lPImHCQcfTtPzZj7qYMPb/h8YHN3TG54uEowrjNQ==} + + '@iconify-json/simple-icons@1.2.76': + resolution: {integrity: sha512-lLRlA8yaf+1L5VCPRvR9lynoSklsddKHEylchmZJKdj/q2xVQ1ZAEJ8SCQlv9cbgtMefnlyM98U+8Si2aoFZPA==} + + '@iconify-json/vscode-icons@1.2.45': + resolution: {integrity: sha512-ow+ueibMIq79ueM1kv6cOWgHx8jfh1XJQi2RrqMHb4HLbvIBlxpy5PCMvOJXlA68R6fBAHpWQeh6uWx7VKEVsA==} + + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + + '@iconify/utils@3.1.0': + resolution: {integrity: sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw==} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@octokit/auth-token@6.0.0': + resolution: {integrity: sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==} + engines: {node: '>= 20'} + + '@octokit/core@7.0.6': + resolution: {integrity: sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==} + engines: {node: '>= 20'} + + '@octokit/endpoint@11.0.3': + resolution: {integrity: sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag==} + engines: {node: '>= 20'} + + '@octokit/graphql@9.0.3': + resolution: {integrity: sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==} + engines: {node: '>= 20'} + + '@octokit/openapi-types@27.0.0': + resolution: {integrity: sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==} + + '@octokit/plugin-paginate-rest@14.0.0': + resolution: {integrity: sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==} + engines: {node: '>= 20'} + peerDependencies: + '@octokit/core': '>=6' + + '@octokit/plugin-request-log@6.0.0': + resolution: {integrity: sha512-UkOzeEN3W91/eBq9sPZNQ7sUBvYCqYbrrD8gTbBuGtHEuycE4/awMXcYvx6sVYo7LypPhmQwwpUe4Yyu4QZN5Q==} + engines: {node: '>= 20'} + peerDependencies: + '@octokit/core': '>=6' + + '@octokit/plugin-rest-endpoint-methods@17.0.0': + resolution: {integrity: sha512-B5yCyIlOJFPqUUeiD0cnBJwWJO8lkJs5d8+ze9QDP6SvfiXSz1BF+91+0MeI1d2yxgOhU/O+CvtiZ9jSkHhFAw==} + engines: {node: '>= 20'} + peerDependencies: + '@octokit/core': '>=6' + + '@octokit/plugin-throttling@11.0.3': + resolution: {integrity: sha512-34eE0RkFCKycLl2D2kq7W+LovheM/ex3AwZCYN8udpi6bxsyjZidb2McXs69hZhLmJlDqTSP8cH+jSRpiaijBg==} + engines: {node: '>= 20'} + peerDependencies: + '@octokit/core': ^7.0.0 + + '@octokit/request-error@7.1.0': + resolution: {integrity: sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==} + engines: {node: '>= 20'} + + '@octokit/request@10.0.8': + resolution: {integrity: sha512-SJZNwY9pur9Agf7l87ywFi14W+Hd9Jg6Ifivsd33+/bGUQIjNujdFiXII2/qSlN2ybqUHfp5xpekMEjIBTjlSw==} + engines: {node: '>= 20'} + + '@octokit/rest@22.0.1': + resolution: {integrity: sha512-Jzbhzl3CEexhnivb1iQ0KJ7s5vvjMWcmRtq5aUsKmKDrRW6z3r84ngmiFKFvpZjpiU/9/S6ITPFRpn5s/3uQJw==} + engines: {node: '>= 20'} + + '@octokit/types@16.0.0': + resolution: {integrity: sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==} + + '@oxfmt/binding-android-arm-eabi@0.43.0': + resolution: {integrity: sha512-CgU2s+/9hHZgo0IxVxrbMPrMj+tJ6VM3mD7Mr/4oiz4FNTISLoCvRmB5nk4wAAle045RtRjd86m673jwPyb1OQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxfmt/binding-android-arm64@0.43.0': + resolution: {integrity: sha512-T9OfRwjA/EdYxAqbvR7TtqLv5nIrwPXuCtTwOHtS7aR9uXyn74ZYgzgTo6/ZwvTq9DY4W+DsV09hB2EXgn9EbA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxfmt/binding-darwin-arm64@0.43.0': + resolution: {integrity: sha512-o3i49ZUSJWANzXMAAVY1wnqb65hn4JVzwlRQ5qfcwhRzIA8lGVaud31Q3by5ALHPrksp5QEaKCQF9aAS3TXpZA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@oxfmt/binding-darwin-x64@0.43.0': + resolution: {integrity: sha512-vWECzzCFkb0kK6jaHjbtC5sC3adiNWtqawFCxhpvsWlzVeKmv5bNvkB4nux+o4JKWTpHCM57NDK/MeXt44txmA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@oxfmt/binding-freebsd-x64@0.43.0': + resolution: {integrity: sha512-rgz8JpkKiI/umOf7fl9gwKyQasC8bs5SYHy6g7e4SunfLBY3+8ATcD5caIg8KLGEtKFm5ujKaH8EfjcmnhzTLg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@oxfmt/binding-linux-arm-gnueabihf@0.43.0': + resolution: {integrity: sha512-nWYnF3vIFzT4OM1qL/HSf1Yuj96aBuKWSaObXHSWliwAk2rcj7AWd6Lf7jowEBQMo4wCZVnueIGw/7C4u0KTBQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxfmt/binding-linux-arm-musleabihf@0.43.0': + resolution: {integrity: sha512-sFg+NWJbLfupYTF4WELHAPSnLPOn1jiDZ33Z1jfDnTaA+cC3iB35x0FMMZTFdFOz3icRIArncwCcemJFGXu6TQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxfmt/binding-linux-arm64-gnu@0.43.0': + resolution: {integrity: sha512-MelWqv68tX6wZEILDrTc9yewiGXe7im62+5x0bNXlCYFOZdA+VnYiJfAihbROsZ5fm90p9C3haFrqjj43XnlAA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxfmt/binding-linux-arm64-musl@0.43.0': + resolution: {integrity: sha512-ROaWfYh+6BSJ1Arwy5ujijTlwnZetxDxzBpDc1oBR4d7rfrPBqzeyjd5WOudowzQUgyavl2wEpzn1hw3jWcqLA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxfmt/binding-linux-ppc64-gnu@0.43.0': + resolution: {integrity: sha512-PJRs/uNxmFipJJ8+SyKHh7Y7VZIKQicqrrBzvfyM5CtKi8D7yZKTwUOZV3ffxmiC2e7l1SDJpkBEOyue5NAFsg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxfmt/binding-linux-riscv64-gnu@0.43.0': + resolution: {integrity: sha512-j6biGAgzIhj+EtHXlbNumvwG7XqOIdiU4KgIWRXAEj/iUbHKukKW8eXa4MIwpQwW1YkxovduKtzEAPnjlnAhVQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxfmt/binding-linux-riscv64-musl@0.43.0': + resolution: {integrity: sha512-RYWxAcslKxvy7yri24Xm9cmD0RiANaiEPs007EFG6l9h1ChM69Q5SOzACaCoz4Z9dEplnhhneeBaTWMEdpgIbA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxfmt/binding-linux-s390x-gnu@0.43.0': + resolution: {integrity: sha512-DT6Q8zfQQy3jxpezAsBACEHNUUixKSYTwdXeXojNHe4DQOoxjPdjr3Szu6BRNjxLykZM/xMNmp9ElOIyDppwtw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxfmt/binding-linux-x64-gnu@0.43.0': + resolution: {integrity: sha512-R8Yk7iYcuZORXmCfFZClqbDxRZgZ9/HEidUuBNdoX8Ptx07cMePnMVJ/woB84lFIDjh2ROHVaOP40Ds3rBXFqg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxfmt/binding-linux-x64-musl@0.43.0': + resolution: {integrity: sha512-F2YYqyvnQNvi320RWZNAvsaWEHwmW3k4OwNJ1hZxRKXupY63expbBaNp6jAgvYs7y/g546vuQnGHQuCBhslhLQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxfmt/binding-openharmony-arm64@0.43.0': + resolution: {integrity: sha512-OE6TdietLXV3F6c7pNIhx/9YC1/2YFwjU9DPc/fbjxIX19hNIaP1rS0cFjCGJlGX+cVJwIKWe8Mos+LdQ1yAJw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxfmt/binding-win32-arm64-msvc@0.43.0': + resolution: {integrity: sha512-0nWK6a7pGkbdoypfVicmV9k/N1FwjPZENoqhlTU+5HhZnAhpIO3za30nEE33u6l6tuy9OVfpdXUqxUgZ+4lbZw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@oxfmt/binding-win32-ia32-msvc@0.43.0': + resolution: {integrity: sha512-9aokTR4Ft+tRdvgN/pKzSkVy2ksc4/dCpDm9L/xFrbIw0yhLtASLbvoG/5WOTUh/BRPPnfGTsWznEqv0dlOmhA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxfmt/binding-win32-x64-msvc@0.43.0': + resolution: {integrity: sha512-4bPgdQux2ZLWn3bf2TTXXMHcJB4lenmuxrLqygPmvCJ104Yqzj1UctxSRzR31TiJ4MLaG22RK8dUsVpJtrCz5g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@oxlint/binding-android-arm-eabi@1.59.0': + resolution: {integrity: sha512-etYDw/UaEv936AQUd/CRMBVd+e+XuuU6wC+VzOv1STvsTyZenLChepLWqLtnyTTp4YMlM22ypzogDDwqYxv5cg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxlint/binding-android-arm64@1.59.0': + resolution: {integrity: sha512-TgLc7XVLKH2a4h8j3vn1MDjfK33i9MY60f/bKhRGWyVzbk5LCZ4X01VZG7iHrMmi5vYbAp8//Ponigx03CLsdw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxlint/binding-darwin-arm64@1.59.0': + resolution: {integrity: sha512-DXyFPf5ZKldMLloRHx/B9fsxsiTQomaw7cmEW3YIJko2HgCh+GUhp9gGYwHrqlLJPsEe3dYj9JebjX92D3j3AA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@oxlint/binding-darwin-x64@1.59.0': + resolution: {integrity: sha512-LgvrsdgVLX1qWqIEmNsSmMXJhpAWdtUQ0M+oR0CySwi+9IHWyOGuIL8w8+u/kbZNMyZr4WUyYB5i0+D+AKgkLg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@oxlint/binding-freebsd-x64@1.59.0': + resolution: {integrity: sha512-bOJhqX/ny4hrFuTPlyk8foSRx/vLRpxJh0jOOKN2NWW6FScXHPAA5rQbrwdQPcgGB5V8Ua51RS03fke8ssBcug==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@oxlint/binding-linux-arm-gnueabihf@1.59.0': + resolution: {integrity: sha512-vVUXxYMF9trXCsz4m9H6U0IjehosVHxBzVgJUxly1uz4W1PdDyicaBnpC0KRXsHYretLVe+uS9pJy8iM57Kujw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxlint/binding-linux-arm-musleabihf@1.59.0': + resolution: {integrity: sha512-TULQW8YBPGRWg5yZpFPL54HLOnJ3/HiX6VenDPi6YfxB/jlItwSMFh3/hCeSNbh+DAMaE1Py0j5MOaivHkI/9Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxlint/binding-linux-arm64-gnu@1.59.0': + resolution: {integrity: sha512-Gt54Y4eqSgYJ90xipm24xeyaPV854706o/kiT8oZvUt3VDY7qqxdqyGqchMaujd87ib+/MXvnl9WkK8Cc1BExg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxlint/binding-linux-arm64-musl@1.59.0': + resolution: {integrity: sha512-3CtsKp7NFB3OfqQzbuAecrY7GIZeiv7AD+xutU4tefVQzlfmTI7/ygWLrvkzsDEjTlMq41rYHxgsn6Yh8tybmA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxlint/binding-linux-ppc64-gnu@1.59.0': + resolution: {integrity: sha512-K0diOpT3ncDmOfl9I1HuvpEsAuTxkts0VYwIv/w6Xiy9CdwyPBVX88Ga9l8VlGgMrwBMnSY4xIvVlVY/fkQk7Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxlint/binding-linux-riscv64-gnu@1.59.0': + resolution: {integrity: sha512-xAU7+QDU6kTJJ7mJLOGgo7oOjtAtkKyFZ0Yjdb5cEo3DiCCPFLvyr08rWiQh6evZ7RiUTf+o65NY/bqttzJiQQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxlint/binding-linux-riscv64-musl@1.59.0': + resolution: {integrity: sha512-KUmZmKlTTyauOnvUNVxK7G40sSSx0+w5l1UhaGsC6KPpOYHenx2oqJTnabmpLJicok7IC+3Y6fXAUOMyexaeJQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxlint/binding-linux-s390x-gnu@1.59.0': + resolution: {integrity: sha512-4usRxC8gS0PGdkHnRmwJt/4zrQNZyk6vL0trCxwZSsAKM+OxhB8nKiR+mhjdBbl8lbMh2gc3bZpNN/ik8c4c2A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxlint/binding-linux-x64-gnu@1.59.0': + resolution: {integrity: sha512-s/rNE2gDmbwAOOP493xk2X7M8LZfI1LJFSSW1+yanz3vuQCFPiHkx4GY+O1HuLUDtkzGlhtMrIcxxzyYLv308w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxlint/binding-linux-x64-musl@1.59.0': + resolution: {integrity: sha512-+yYj1udJa2UvvIUmEm0IcKgc0UlPMgz0nsSTvkPL2y6n0uU5LgIHSwVu4AHhrve6j9BpVSoRksnz8c9QcvITJA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxlint/binding-openharmony-arm64@1.59.0': + resolution: {integrity: sha512-bUplUb48LYsB3hHlQXP2ZMOenpieWoOyppLAnnAhuPag3MGPnt+7caxE3w/Vl9wpQsTA3gzLntQi9rxWrs7Xqg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxlint/binding-win32-arm64-msvc@1.59.0': + resolution: {integrity: sha512-/HLsLuz42rWl7h7ePdmMTpHm2HIDmPtcEMYgm5BBEHiEiuNOrzMaUpd2z7UnNni5LGN9obJy2YoAYBLXQwazrA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@oxlint/binding-win32-ia32-msvc@1.59.0': + resolution: {integrity: sha512-rUPy+JnanpPwV/aJCPnxAD1fW50+XPI0VkWr7f0vEbqcdsS8NpB24Rw6RsS7SdpFv8Dw+8ugCwao5nCFbqOUSg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxlint/binding-win32-x64-msvc@1.59.0': + resolution: {integrity: sha512-xkE7puteDS/vUyRngLXW0t8WgdWoS/tfxXjhP/P7SMqPDx+hs44SpssO3h3qmTqECYEuXBUPzcAw5257Ka+ofA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.0-rc.2': + resolution: {integrity: sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==} + + '@rollup/rollup-android-arm-eabi@4.60.1': + resolution: {integrity: sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.60.1': + resolution: {integrity: sha512-YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.60.1': + resolution: {integrity: sha512-mjCpF7GmkRtSJwon+Rq1N8+pI+8l7w5g9Z3vWj4T7abguC4Czwi3Yu/pFaLvA3TTeMVjnu3ctigusqWUfjZzvw==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.60.1': + resolution: {integrity: sha512-haZ7hJ1JT4e9hqkoT9R/19XW2QKqjfJVv+i5AGg57S+nLk9lQnJ1F/eZloRO3o9Scy9CM3wQ9l+dkXtcBgN5Ew==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.60.1': + resolution: {integrity: sha512-czw90wpQq3ZsAVBlinZjAYTKduOjTywlG7fEeWKUA7oCmpA8xdTkxZZlwNJKWqILlq0wehoZcJYfBvOyhPTQ6w==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.60.1': + resolution: {integrity: sha512-KVB2rqsxTHuBtfOeySEyzEOB7ltlB/ux38iu2rBQzkjbwRVlkhAGIEDiiYnO2kFOkJp+Z7pUXKyrRRFuFUKt+g==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.60.1': + resolution: {integrity: sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm-musleabihf@4.60.1': + resolution: {integrity: sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg==} + cpu: [arm] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-arm64-gnu@4.60.1': + resolution: {integrity: sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm64-musl@4.60.1': + resolution: {integrity: sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-loong64-gnu@4.60.1': + resolution: {integrity: sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ==} + cpu: [loong64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-loong64-musl@4.60.1': + resolution: {integrity: sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw==} + cpu: [loong64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-ppc64-gnu@4.60.1': + resolution: {integrity: sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-ppc64-musl@4.60.1': + resolution: {integrity: sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg==} + cpu: [ppc64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-riscv64-gnu@4.60.1': + resolution: {integrity: sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-riscv64-musl@4.60.1': + resolution: {integrity: sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-s390x-gnu@4.60.1': + resolution: {integrity: sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-gnu@4.60.1': + resolution: {integrity: sha512-77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-musl@4.60.1': + resolution: {integrity: sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rollup/rollup-openbsd-x64@4.60.1': + resolution: {integrity: sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.60.1': + resolution: {integrity: sha512-4Cv23ZrONRbNtbZa37mLSueXUCtN7MXccChtKpUnQNgF010rjrjfHx3QxkS2PI7LqGT5xXyYs1a7LbzAwT0iCA==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.60.1': + resolution: {integrity: sha512-i1okWYkA4FJICtr7KpYzFpRTHgy5jdDbZiWfvny21iIKky5YExiDXP+zbXzm3dUcFpkEeYNHgQ5fuG236JPq0g==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.60.1': + resolution: {integrity: sha512-u09m3CuwLzShA0EYKMNiFgcjjzwqtUMLmuCJLeZWjjOYA3IT2Di09KaxGBTP9xVztWyIWjVdsB2E9goMjZvTQg==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.60.1': + resolution: {integrity: sha512-k+600V9Zl1CM7eZxJgMyTUzmrmhB/0XZnF4pRypKAlAgxmedUA+1v9R+XOFv56W4SlHEzfeMtzujLJD22Uz5zg==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.60.1': + resolution: {integrity: sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ==} + cpu: [x64] + os: [win32] + + '@shikijs/core@3.23.0': + resolution: {integrity: sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA==} + + '@shikijs/engine-javascript@3.23.0': + resolution: {integrity: sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA==} + + '@shikijs/engine-oniguruma@3.23.0': + resolution: {integrity: sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==} + + '@shikijs/langs@3.23.0': + resolution: {integrity: sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==} + + '@shikijs/themes@3.23.0': + resolution: {integrity: sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==} + + '@shikijs/transformers@3.23.0': + resolution: {integrity: sha512-F9msZVxdF+krQNSdQ4V+Ja5QemeAoTQ2jxt7nJCwhDsdF1JWS3KxIQXA3lQbyKwS3J61oHRUSv4jYWv3CkaKTQ==} + + '@shikijs/types@3.23.0': + resolution: {integrity: sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==} + + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/linkify-it@5.0.0': + resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} + + '@types/markdown-it@14.1.2': + resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/mdurl@2.0.0': + resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + + '@types/node@24.12.2': + resolution: {integrity: sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==} + + '@types/semver@7.7.1': + resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@types/web-bluetooth@0.0.21': + resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==} + + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + + '@vitejs/plugin-vue@6.0.5': + resolution: {integrity: sha512-bL3AxKuQySfk1iGcBsQnoRVexTPJq0Z/ixFVM8OhVJAP6ZXXXLtM7NFKWhLl30Kg7uTBqIaPXbh+nuQCuBDedg==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + vue: ^3.2.25 + + '@vue/compiler-core@3.5.32': + resolution: {integrity: sha512-4x74Tbtqnda8s/NSD6e1Dr5p1c8HdMU5RWSjMSUzb8RTcUQqevDCxVAitcLBKT+ie3o0Dl9crc/S/opJM7qBGQ==} + + '@vue/compiler-dom@3.5.32': + resolution: {integrity: sha512-ybHAu70NtiEI1fvAUz3oXZqkUYEe5J98GjMDpTGl5iHb0T15wQYLR4wE3h9xfuTNA+Cm2f4czfe8B4s+CCH57Q==} + + '@vue/compiler-sfc@3.5.32': + resolution: {integrity: sha512-8UYUYo71cP/0YHMO814TRZlPuUUw3oifHuMR7Wp9SNoRSrxRQnhMLNlCeaODNn6kNTJsjFoQ/kqIj4qGvya4Xg==} + + '@vue/compiler-ssr@3.5.32': + resolution: {integrity: sha512-Gp4gTs22T3DgRotZ8aA/6m2jMR+GMztvBXUBEUOYOcST+giyGWJ4WvFd7QLHBkzTxkfOt8IELKNdpzITLbA2rw==} + + '@vue/devtools-api@8.1.1': + resolution: {integrity: sha512-bsDMJ07b3GN1puVwJb/fyFnj/U2imyswK5UQVLZwVl7O05jDrt6BHxeG5XffmOOdasOj/bOmIjxJvGPxU7pcqw==} + + '@vue/devtools-kit@8.1.1': + resolution: {integrity: sha512-gVBaBv++i+adg4JpH71k9ppl4soyR7Y2McEqO5YNgv0BI1kMZ7BDX5gnwkZ5COYgiCyhejZG+yGNrBAjj6Coqg==} + + '@vue/devtools-shared@8.1.1': + resolution: {integrity: sha512-+h4ttmJYl/txpxHKaoZcaKpC+pvckgLzIDiSQlaQ7kKthKh8KuwoLW2D8hPJEnqKzXOvu15UHEoGyngAXCz0EQ==} + + '@vue/reactivity@3.5.32': + resolution: {integrity: sha512-/ORasxSGvZ6MN5gc+uE364SxFdJ0+WqVG0CENXaGW58TOCdrAW76WWaplDtECeS1qphvtBZtR+3/o1g1zL4xPQ==} + + '@vue/runtime-core@3.5.32': + resolution: {integrity: sha512-pDrXCejn4UpFDFmMd27AcJEbHaLemaE5o4pbb7sLk79SRIhc6/t34BQA7SGNgYtbMnvbF/HHOftYBgFJtUoJUQ==} + + '@vue/runtime-dom@3.5.32': + resolution: {integrity: sha512-1CDVv7tv/IV13V8Nip1k/aaObVbWqRlVCVezTwx3K07p7Vxossp5JU1dcPNhJk3w347gonIUT9jQOGutyJrSVQ==} + + '@vue/server-renderer@3.5.32': + resolution: {integrity: sha512-IOjm2+JQwRFS7W28HNuJeXQle9KdZbODFY7hFGVtnnghF51ta20EWAZJHX+zLGtsHhaU6uC9BGPV52KVpYryMQ==} + peerDependencies: + vue: 3.5.32 + + '@vue/shared@3.5.32': + resolution: {integrity: sha512-ksNyrmRQzWJJ8n3cRDuSF7zNNontuJg1YHnmWRJd2AMu8Ij2bqwiiri2lH5rHtYPZjj4STkNcgcmiQqlOjiYGg==} + + '@vueuse/core@14.2.1': + resolution: {integrity: sha512-3vwDzV+GDUNpdegRY6kzpLm4Igptq+GA0QkJ3W61Iv27YWwW/ufSlOfgQIpN6FZRMG0mkaz4gglJRtq5SeJyIQ==} + peerDependencies: + vue: ^3.5.0 + + '@vueuse/integrations@14.2.1': + resolution: {integrity: sha512-2LIUpBi/67PoXJGqSDQUF0pgQWpNHh7beiA+KG2AbybcNm+pTGWT6oPGlBgUoDWmYwfeQqM/uzOHqcILpKL7nA==} + peerDependencies: + async-validator: ^4 + axios: ^1 + change-case: ^5 + drauu: ^0.4 + focus-trap: ^7 || ^8 + fuse.js: ^7 + idb-keyval: ^6 + jwt-decode: ^4 + nprogress: ^0.2 + qrcode: ^1.5 + sortablejs: ^1 + universal-cookie: ^7 || ^8 + vue: ^3.5.0 + peerDependenciesMeta: + async-validator: + optional: true + axios: + optional: true + change-case: + optional: true + drauu: + optional: true + focus-trap: + optional: true + fuse.js: + optional: true + idb-keyval: + optional: true + jwt-decode: + optional: true + nprogress: + optional: true + qrcode: + optional: true + sortablejs: + optional: true + universal-cookie: + optional: true + + '@vueuse/metadata@14.2.1': + resolution: {integrity: sha512-1ButlVtj5Sb/HDtIy1HFr1VqCP4G6Ypqt5MAo0lCgjokrk2mvQKsK2uuy0vqu/Ks+sHfuHo0B9Y9jn9xKdjZsw==} + + '@vueuse/shared@14.2.1': + resolution: {integrity: sha512-shTJncjV9JTI4oVNyF1FQonetYAiTBd+Qj7cY89SWbXSkx7gyhrgtEdF2ZAVWS1S3SHlaROO6F2IesJxQEkZBw==} + peerDependencies: + vue: ^3.5.0 + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + + before-after-hook@4.0.0: + resolution: {integrity: sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==} + + birpc@2.9.0: + resolution: {integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==} + + bottleneck@2.19.5: + resolution: {integrity: sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} + engines: {node: '>=0.12'} + + es-toolkit@1.45.1: + resolution: {integrity: sha512-/jhoOj/Fx+A+IIyDNOvO3TItGmlMKhtX8ISAHKE90c4b/k1tqaqEZ+uUqfpU8DMnW5cgNJv606zS55jGvza0Xw==} + + esbuild@0.27.7: + resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} + engines: {node: '>=18'} + hasBin: true + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + fast-content-type-parse@3.0.0: + resolution: {integrity: sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + feed@5.2.0: + resolution: {integrity: sha512-hgH6CCb+7+0c8PBlakI2KubG6R+Rb1MhpNcdvqUXZTBwBHf32piwY255diAkAmkGZ6AWlywOU88AkOgP9q8Rdw==} + engines: {node: '>=20', pnpm: '>=10'} + + focus-trap@8.0.1: + resolution: {integrity: sha512-9ptSG6z51YQOstI/oN4XuVGP/03u2nh0g//qz7L6zX0i6PZiPnkcf3GenXq7N2hZnASXaMxTPpbKwdI+PFvxlw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + get-tsconfig@4.13.7: + resolution: {integrity: sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q==} + + hast-util-to-html@9.0.5: + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + json-with-bigint@3.5.8: + resolution: {integrity: sha512-eq/4KP6K34kwa7TcFdtvnftvHCD9KvHOGGICWwMFc4dOOKF5t4iYqnfLK8otCRCRv06FXOzGGyqE8h8ElMvvdw==} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + mark.js@8.11.1: + resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==} + + mdast-util-to-hast@13.2.1: + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + minisearch@7.2.0: + resolution: {integrity: sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==} + + mlly@1.8.2: + resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + oniguruma-parser@0.12.1: + resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==} + + oniguruma-to-es@4.3.5: + resolution: {integrity: sha512-Zjygswjpsewa0NLTsiizVuMQZbp0MDyM6lIt66OxsF21npUDlzpHi1Mgb/qhQdkb+dWFTzJmFbEWdvZgRho8eQ==} + + oxfmt@0.43.0: + resolution: {integrity: sha512-KTYNG5ISfHSdmeZ25Xzb3qgz9EmQvkaGAxgBY/p38+ZiAet3uZeu7FnMwcSQJg152Qwl0wnYAxDc+Z/H6cvrwA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + oxlint@1.59.0: + resolution: {integrity: sha512-0xBLeGGjP4vD9pygRo8iuOkOzEU1MqOnfiOl7KYezL/QvWL8NUg6n03zXc7ZVqltiOpUxBk2zgHI3PnRIEdAvw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + oxlint-tsgolint: '>=0.18.0' + peerDependenciesMeta: + oxlint-tsgolint: + optional: true + + package-manager-detector@1.6.0: + resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + perfect-debounce@2.1.0: + resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} + + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + postcss@8.5.8: + resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} + engines: {node: ^10 || ^12 || >=14} + + property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + + regex-recursion@6.0.2: + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} + + regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + + regex@6.1.0: + resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + rollup@4.60.1: + resolution: {integrity: sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + sax@1.6.0: + resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} + engines: {node: '>=11.0.0'} + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + shiki@3.23.0: + resolution: {integrity: sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + tabbable@6.4.0: + resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==} + + tinyexec@1.1.1: + resolution: {integrity: sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg==} + engines: {node: '>=18'} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + tinypool@2.1.0: + resolution: {integrity: sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw==} + engines: {node: ^20.0.0 || >=22.0.0} + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + tsx@4.21.0: + resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} + engines: {node: '>=18.0.0'} + hasBin: true + + typescript@6.0.2: + resolution: {integrity: sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.6.3: + resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} + + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.1.0: + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + + universal-user-agent@7.0.3: + resolution: {integrity: sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==} + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + vite@7.3.2: + resolution: {integrity: sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitepress-plugin-group-icons@1.7.3: + resolution: {integrity: sha512-Nj2znOveQC7KH1CQ1k2WlVvEDAuymhumcUvD51ognVUv2yjrfAhOzL1VEESPzoJN0kWoRxXK+iu+OKNLe7unGQ==} + peerDependencies: + vite: '>=3' + peerDependenciesMeta: + vite: + optional: true + + vitepress@2.0.0-alpha.17: + resolution: {integrity: sha512-Z3VPUpwk/bHYqt1uMVOOK1/4xFiWQov1GNc2FvMdz6kvje4JRXEOngVI9C+bi5jeedMSHiA4dwKkff1NCvbZ9Q==} + hasBin: true + peerDependencies: + markdown-it-mathjax3: ^4 + oxc-minify: '*' + postcss: ^8 + peerDependenciesMeta: + markdown-it-mathjax3: + optional: true + oxc-minify: + optional: true + postcss: + optional: true + + vue@3.5.32: + resolution: {integrity: sha512-vM4z4Q9tTafVfMAK7IVzmxg34rSzTFMyIe0UUEijUCkn9+23lj0WRfA83dg7eQZIUlgOSGrkViIaCfqSAUXsMw==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + xml-js@1.6.11: + resolution: {integrity: sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==} + hasBin: true + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@antfu/install-pkg@1.1.0': + dependencies: + package-manager-detector: 1.6.0 + tinyexec: 1.1.1 + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/parser@7.29.2': + dependencies: + '@babel/types': 7.29.0 + + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@docsearch/css@4.6.2': {} + + '@docsearch/js@4.6.2': {} + + '@docsearch/sidepanel-js@4.6.2': {} + + '@esbuild/aix-ppc64@0.27.7': + optional: true + + '@esbuild/android-arm64@0.27.7': + optional: true + + '@esbuild/android-arm@0.27.7': + optional: true + + '@esbuild/android-x64@0.27.7': + optional: true + + '@esbuild/darwin-arm64@0.27.7': + optional: true + + '@esbuild/darwin-x64@0.27.7': + optional: true + + '@esbuild/freebsd-arm64@0.27.7': + optional: true + + '@esbuild/freebsd-x64@0.27.7': + optional: true + + '@esbuild/linux-arm64@0.27.7': + optional: true + + '@esbuild/linux-arm@0.27.7': + optional: true + + '@esbuild/linux-ia32@0.27.7': + optional: true + + '@esbuild/linux-loong64@0.27.7': + optional: true + + '@esbuild/linux-mips64el@0.27.7': + optional: true + + '@esbuild/linux-ppc64@0.27.7': + optional: true + + '@esbuild/linux-riscv64@0.27.7': + optional: true + + '@esbuild/linux-s390x@0.27.7': + optional: true + + '@esbuild/linux-x64@0.27.7': + optional: true + + '@esbuild/netbsd-arm64@0.27.7': + optional: true + + '@esbuild/netbsd-x64@0.27.7': + optional: true + + '@esbuild/openbsd-arm64@0.27.7': + optional: true + + '@esbuild/openbsd-x64@0.27.7': + optional: true + + '@esbuild/openharmony-arm64@0.27.7': + optional: true + + '@esbuild/sunos-x64@0.27.7': + optional: true + + '@esbuild/win32-arm64@0.27.7': + optional: true + + '@esbuild/win32-ia32@0.27.7': + optional: true + + '@esbuild/win32-x64@0.27.7': + optional: true + + '@iconify-json/logos@1.2.11': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify-json/simple-icons@1.2.76': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify-json/vscode-icons@1.2.45': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify/types@2.0.0': {} + + '@iconify/utils@3.1.0': + dependencies: + '@antfu/install-pkg': 1.1.0 + '@iconify/types': 2.0.0 + mlly: 1.8.2 + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@octokit/auth-token@6.0.0': {} + + '@octokit/core@7.0.6': + dependencies: + '@octokit/auth-token': 6.0.0 + '@octokit/graphql': 9.0.3 + '@octokit/request': 10.0.8 + '@octokit/request-error': 7.1.0 + '@octokit/types': 16.0.0 + before-after-hook: 4.0.0 + universal-user-agent: 7.0.3 + + '@octokit/endpoint@11.0.3': + dependencies: + '@octokit/types': 16.0.0 + universal-user-agent: 7.0.3 + + '@octokit/graphql@9.0.3': + dependencies: + '@octokit/request': 10.0.8 + '@octokit/types': 16.0.0 + universal-user-agent: 7.0.3 + + '@octokit/openapi-types@27.0.0': {} + + '@octokit/plugin-paginate-rest@14.0.0(@octokit/core@7.0.6)': + dependencies: + '@octokit/core': 7.0.6 + '@octokit/types': 16.0.0 + + '@octokit/plugin-request-log@6.0.0(@octokit/core@7.0.6)': + dependencies: + '@octokit/core': 7.0.6 + + '@octokit/plugin-rest-endpoint-methods@17.0.0(@octokit/core@7.0.6)': + dependencies: + '@octokit/core': 7.0.6 + '@octokit/types': 16.0.0 + + '@octokit/plugin-throttling@11.0.3(@octokit/core@7.0.6)': + dependencies: + '@octokit/core': 7.0.6 + '@octokit/types': 16.0.0 + bottleneck: 2.19.5 + + '@octokit/request-error@7.1.0': + dependencies: + '@octokit/types': 16.0.0 + + '@octokit/request@10.0.8': + dependencies: + '@octokit/endpoint': 11.0.3 + '@octokit/request-error': 7.1.0 + '@octokit/types': 16.0.0 + fast-content-type-parse: 3.0.0 + json-with-bigint: 3.5.8 + universal-user-agent: 7.0.3 + + '@octokit/rest@22.0.1': + dependencies: + '@octokit/core': 7.0.6 + '@octokit/plugin-paginate-rest': 14.0.0(@octokit/core@7.0.6) + '@octokit/plugin-request-log': 6.0.0(@octokit/core@7.0.6) + '@octokit/plugin-rest-endpoint-methods': 17.0.0(@octokit/core@7.0.6) + + '@octokit/types@16.0.0': + dependencies: + '@octokit/openapi-types': 27.0.0 + + '@oxfmt/binding-android-arm-eabi@0.43.0': + optional: true + + '@oxfmt/binding-android-arm64@0.43.0': + optional: true + + '@oxfmt/binding-darwin-arm64@0.43.0': + optional: true + + '@oxfmt/binding-darwin-x64@0.43.0': + optional: true + + '@oxfmt/binding-freebsd-x64@0.43.0': + optional: true + + '@oxfmt/binding-linux-arm-gnueabihf@0.43.0': + optional: true + + '@oxfmt/binding-linux-arm-musleabihf@0.43.0': + optional: true + + '@oxfmt/binding-linux-arm64-gnu@0.43.0': + optional: true + + '@oxfmt/binding-linux-arm64-musl@0.43.0': + optional: true + + '@oxfmt/binding-linux-ppc64-gnu@0.43.0': + optional: true + + '@oxfmt/binding-linux-riscv64-gnu@0.43.0': + optional: true + + '@oxfmt/binding-linux-riscv64-musl@0.43.0': + optional: true + + '@oxfmt/binding-linux-s390x-gnu@0.43.0': + optional: true + + '@oxfmt/binding-linux-x64-gnu@0.43.0': + optional: true + + '@oxfmt/binding-linux-x64-musl@0.43.0': + optional: true + + '@oxfmt/binding-openharmony-arm64@0.43.0': + optional: true + + '@oxfmt/binding-win32-arm64-msvc@0.43.0': + optional: true + + '@oxfmt/binding-win32-ia32-msvc@0.43.0': + optional: true + + '@oxfmt/binding-win32-x64-msvc@0.43.0': + optional: true + + '@oxlint/binding-android-arm-eabi@1.59.0': + optional: true + + '@oxlint/binding-android-arm64@1.59.0': + optional: true + + '@oxlint/binding-darwin-arm64@1.59.0': + optional: true + + '@oxlint/binding-darwin-x64@1.59.0': + optional: true + + '@oxlint/binding-freebsd-x64@1.59.0': + optional: true + + '@oxlint/binding-linux-arm-gnueabihf@1.59.0': + optional: true + + '@oxlint/binding-linux-arm-musleabihf@1.59.0': + optional: true + + '@oxlint/binding-linux-arm64-gnu@1.59.0': + optional: true + + '@oxlint/binding-linux-arm64-musl@1.59.0': + optional: true + + '@oxlint/binding-linux-ppc64-gnu@1.59.0': + optional: true + + '@oxlint/binding-linux-riscv64-gnu@1.59.0': + optional: true + + '@oxlint/binding-linux-riscv64-musl@1.59.0': + optional: true + + '@oxlint/binding-linux-s390x-gnu@1.59.0': + optional: true + + '@oxlint/binding-linux-x64-gnu@1.59.0': + optional: true + + '@oxlint/binding-linux-x64-musl@1.59.0': + optional: true + + '@oxlint/binding-openharmony-arm64@1.59.0': + optional: true + + '@oxlint/binding-win32-arm64-msvc@1.59.0': + optional: true + + '@oxlint/binding-win32-ia32-msvc@1.59.0': + optional: true + + '@oxlint/binding-win32-x64-msvc@1.59.0': + optional: true + + '@rolldown/pluginutils@1.0.0-rc.2': {} + + '@rollup/rollup-android-arm-eabi@4.60.1': + optional: true + + '@rollup/rollup-android-arm64@4.60.1': + optional: true + + '@rollup/rollup-darwin-arm64@4.60.1': + optional: true + + '@rollup/rollup-darwin-x64@4.60.1': + optional: true + + '@rollup/rollup-freebsd-arm64@4.60.1': + optional: true + + '@rollup/rollup-freebsd-x64@4.60.1': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.60.1': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.60.1': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.60.1': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.60.1': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.60.1': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.60.1': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.60.1': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.60.1': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.60.1': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.60.1': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.60.1': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.60.1': + optional: true + + '@rollup/rollup-linux-x64-musl@4.60.1': + optional: true + + '@rollup/rollup-openbsd-x64@4.60.1': + optional: true + + '@rollup/rollup-openharmony-arm64@4.60.1': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.60.1': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.60.1': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.60.1': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.60.1': + optional: true + + '@shikijs/core@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 + + '@shikijs/engine-javascript@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 + oniguruma-to-es: 4.3.5 + + '@shikijs/engine-oniguruma@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/langs@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + + '@shikijs/themes@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + + '@shikijs/transformers@3.23.0': + dependencies: + '@shikijs/core': 3.23.0 + '@shikijs/types': 3.23.0 + + '@shikijs/types@3.23.0': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@10.0.2': {} + + '@types/estree@1.0.8': {} + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/linkify-it@5.0.0': {} + + '@types/markdown-it@14.1.2': + dependencies: + '@types/linkify-it': 5.0.0 + '@types/mdurl': 2.0.0 + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mdurl@2.0.0': {} + + '@types/node@24.12.2': + dependencies: + undici-types: 7.16.0 + + '@types/semver@7.7.1': {} + + '@types/unist@3.0.3': {} + + '@types/web-bluetooth@0.0.21': {} + + '@ungap/structured-clone@1.3.0': {} + + '@vitejs/plugin-vue@6.0.5(vite@7.3.2(@types/node@24.12.2)(tsx@4.21.0))(vue@3.5.32(typescript@6.0.2))': + dependencies: + '@rolldown/pluginutils': 1.0.0-rc.2 + vite: 7.3.2(@types/node@24.12.2)(tsx@4.21.0) + vue: 3.5.32(typescript@6.0.2) + + '@vue/compiler-core@3.5.32': + dependencies: + '@babel/parser': 7.29.2 + '@vue/shared': 3.5.32 + entities: 7.0.1 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.5.32': + dependencies: + '@vue/compiler-core': 3.5.32 + '@vue/shared': 3.5.32 + + '@vue/compiler-sfc@3.5.32': + dependencies: + '@babel/parser': 7.29.2 + '@vue/compiler-core': 3.5.32 + '@vue/compiler-dom': 3.5.32 + '@vue/compiler-ssr': 3.5.32 + '@vue/shared': 3.5.32 + estree-walker: 2.0.2 + magic-string: 0.30.21 + postcss: 8.5.8 + source-map-js: 1.2.1 + + '@vue/compiler-ssr@3.5.32': + dependencies: + '@vue/compiler-dom': 3.5.32 + '@vue/shared': 3.5.32 + + '@vue/devtools-api@8.1.1': + dependencies: + '@vue/devtools-kit': 8.1.1 + + '@vue/devtools-kit@8.1.1': + dependencies: + '@vue/devtools-shared': 8.1.1 + birpc: 2.9.0 + hookable: 5.5.3 + perfect-debounce: 2.1.0 + + '@vue/devtools-shared@8.1.1': {} + + '@vue/reactivity@3.5.32': + dependencies: + '@vue/shared': 3.5.32 + + '@vue/runtime-core@3.5.32': + dependencies: + '@vue/reactivity': 3.5.32 + '@vue/shared': 3.5.32 + + '@vue/runtime-dom@3.5.32': + dependencies: + '@vue/reactivity': 3.5.32 + '@vue/runtime-core': 3.5.32 + '@vue/shared': 3.5.32 + csstype: 3.2.3 + + '@vue/server-renderer@3.5.32(vue@3.5.32(typescript@6.0.2))': + dependencies: + '@vue/compiler-ssr': 3.5.32 + '@vue/shared': 3.5.32 + vue: 3.5.32(typescript@6.0.2) + + '@vue/shared@3.5.32': {} + + '@vueuse/core@14.2.1(vue@3.5.32(typescript@6.0.2))': + dependencies: + '@types/web-bluetooth': 0.0.21 + '@vueuse/metadata': 14.2.1 + '@vueuse/shared': 14.2.1(vue@3.5.32(typescript@6.0.2)) + vue: 3.5.32(typescript@6.0.2) + + '@vueuse/integrations@14.2.1(focus-trap@8.0.1)(vue@3.5.32(typescript@6.0.2))': + dependencies: + '@vueuse/core': 14.2.1(vue@3.5.32(typescript@6.0.2)) + '@vueuse/shared': 14.2.1(vue@3.5.32(typescript@6.0.2)) + vue: 3.5.32(typescript@6.0.2) + optionalDependencies: + focus-trap: 8.0.1 + + '@vueuse/metadata@14.2.1': {} + + '@vueuse/shared@14.2.1(vue@3.5.32(typescript@6.0.2))': + dependencies: + vue: 3.5.32(typescript@6.0.2) + + acorn@8.16.0: {} + + before-after-hook@4.0.0: {} + + birpc@2.9.0: {} + + bottleneck@2.19.5: {} + + ccount@2.0.1: {} + + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + comma-separated-tokens@2.0.3: {} + + confbox@0.1.8: {} + + csstype@3.2.3: {} + + dequal@2.0.3: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + entities@7.0.1: {} + + es-toolkit@1.45.1: {} + + esbuild@0.27.7: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.7 + '@esbuild/android-arm': 0.27.7 + '@esbuild/android-arm64': 0.27.7 + '@esbuild/android-x64': 0.27.7 + '@esbuild/darwin-arm64': 0.27.7 + '@esbuild/darwin-x64': 0.27.7 + '@esbuild/freebsd-arm64': 0.27.7 + '@esbuild/freebsd-x64': 0.27.7 + '@esbuild/linux-arm': 0.27.7 + '@esbuild/linux-arm64': 0.27.7 + '@esbuild/linux-ia32': 0.27.7 + '@esbuild/linux-loong64': 0.27.7 + '@esbuild/linux-mips64el': 0.27.7 + '@esbuild/linux-ppc64': 0.27.7 + '@esbuild/linux-riscv64': 0.27.7 + '@esbuild/linux-s390x': 0.27.7 + '@esbuild/linux-x64': 0.27.7 + '@esbuild/netbsd-arm64': 0.27.7 + '@esbuild/netbsd-x64': 0.27.7 + '@esbuild/openbsd-arm64': 0.27.7 + '@esbuild/openbsd-x64': 0.27.7 + '@esbuild/openharmony-arm64': 0.27.7 + '@esbuild/sunos-x64': 0.27.7 + '@esbuild/win32-arm64': 0.27.7 + '@esbuild/win32-ia32': 0.27.7 + '@esbuild/win32-x64': 0.27.7 + + estree-walker@2.0.2: {} + + fast-content-type-parse@3.0.0: {} + + fdir@6.5.0(picomatch@4.0.4): + optionalDependencies: + picomatch: 4.0.4 + + feed@5.2.0: + dependencies: + xml-js: 1.6.11 + + focus-trap@8.0.1: + dependencies: + tabbable: 6.4.0 + + fsevents@2.3.3: + optional: true + + get-tsconfig@4.13.7: + dependencies: + resolve-pkg-maps: 1.0.0 + + hast-util-to-html@9.0.5: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hookable@5.5.3: {} + + html-void-elements@3.0.0: {} + + json-with-bigint@3.5.8: {} + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + mark.js@8.11.1: {} + + mdast-util-to-hast@13.2.1: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-encode@2.0.1: {} + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + + minisearch@7.2.0: {} + + mlly@1.8.2: + dependencies: + acorn: 8.16.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.3 + + nanoid@3.3.11: {} + + oniguruma-parser@0.12.1: {} + + oniguruma-to-es@4.3.5: + dependencies: + oniguruma-parser: 0.12.1 + regex: 6.1.0 + regex-recursion: 6.0.2 + + oxfmt@0.43.0: + dependencies: + tinypool: 2.1.0 + optionalDependencies: + '@oxfmt/binding-android-arm-eabi': 0.43.0 + '@oxfmt/binding-android-arm64': 0.43.0 + '@oxfmt/binding-darwin-arm64': 0.43.0 + '@oxfmt/binding-darwin-x64': 0.43.0 + '@oxfmt/binding-freebsd-x64': 0.43.0 + '@oxfmt/binding-linux-arm-gnueabihf': 0.43.0 + '@oxfmt/binding-linux-arm-musleabihf': 0.43.0 + '@oxfmt/binding-linux-arm64-gnu': 0.43.0 + '@oxfmt/binding-linux-arm64-musl': 0.43.0 + '@oxfmt/binding-linux-ppc64-gnu': 0.43.0 + '@oxfmt/binding-linux-riscv64-gnu': 0.43.0 + '@oxfmt/binding-linux-riscv64-musl': 0.43.0 + '@oxfmt/binding-linux-s390x-gnu': 0.43.0 + '@oxfmt/binding-linux-x64-gnu': 0.43.0 + '@oxfmt/binding-linux-x64-musl': 0.43.0 + '@oxfmt/binding-openharmony-arm64': 0.43.0 + '@oxfmt/binding-win32-arm64-msvc': 0.43.0 + '@oxfmt/binding-win32-ia32-msvc': 0.43.0 + '@oxfmt/binding-win32-x64-msvc': 0.43.0 + + oxlint@1.59.0: + optionalDependencies: + '@oxlint/binding-android-arm-eabi': 1.59.0 + '@oxlint/binding-android-arm64': 1.59.0 + '@oxlint/binding-darwin-arm64': 1.59.0 + '@oxlint/binding-darwin-x64': 1.59.0 + '@oxlint/binding-freebsd-x64': 1.59.0 + '@oxlint/binding-linux-arm-gnueabihf': 1.59.0 + '@oxlint/binding-linux-arm-musleabihf': 1.59.0 + '@oxlint/binding-linux-arm64-gnu': 1.59.0 + '@oxlint/binding-linux-arm64-musl': 1.59.0 + '@oxlint/binding-linux-ppc64-gnu': 1.59.0 + '@oxlint/binding-linux-riscv64-gnu': 1.59.0 + '@oxlint/binding-linux-riscv64-musl': 1.59.0 + '@oxlint/binding-linux-s390x-gnu': 1.59.0 + '@oxlint/binding-linux-x64-gnu': 1.59.0 + '@oxlint/binding-linux-x64-musl': 1.59.0 + '@oxlint/binding-openharmony-arm64': 1.59.0 + '@oxlint/binding-win32-arm64-msvc': 1.59.0 + '@oxlint/binding-win32-ia32-msvc': 1.59.0 + '@oxlint/binding-win32-x64-msvc': 1.59.0 + + package-manager-detector@1.6.0: {} + + pathe@2.0.3: {} + + perfect-debounce@2.1.0: {} + + picocolors@1.1.1: {} + + picomatch@4.0.4: {} + + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.2 + pathe: 2.0.3 + + postcss@8.5.8: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + property-information@7.1.0: {} + + regex-recursion@6.0.2: + dependencies: + regex-utilities: 2.3.0 + + regex-utilities@2.3.0: {} + + regex@6.1.0: + dependencies: + regex-utilities: 2.3.0 + + resolve-pkg-maps@1.0.0: {} + + rollup@4.60.1: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.60.1 + '@rollup/rollup-android-arm64': 4.60.1 + '@rollup/rollup-darwin-arm64': 4.60.1 + '@rollup/rollup-darwin-x64': 4.60.1 + '@rollup/rollup-freebsd-arm64': 4.60.1 + '@rollup/rollup-freebsd-x64': 4.60.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.60.1 + '@rollup/rollup-linux-arm-musleabihf': 4.60.1 + '@rollup/rollup-linux-arm64-gnu': 4.60.1 + '@rollup/rollup-linux-arm64-musl': 4.60.1 + '@rollup/rollup-linux-loong64-gnu': 4.60.1 + '@rollup/rollup-linux-loong64-musl': 4.60.1 + '@rollup/rollup-linux-ppc64-gnu': 4.60.1 + '@rollup/rollup-linux-ppc64-musl': 4.60.1 + '@rollup/rollup-linux-riscv64-gnu': 4.60.1 + '@rollup/rollup-linux-riscv64-musl': 4.60.1 + '@rollup/rollup-linux-s390x-gnu': 4.60.1 + '@rollup/rollup-linux-x64-gnu': 4.60.1 + '@rollup/rollup-linux-x64-musl': 4.60.1 + '@rollup/rollup-openbsd-x64': 4.60.1 + '@rollup/rollup-openharmony-arm64': 4.60.1 + '@rollup/rollup-win32-arm64-msvc': 4.60.1 + '@rollup/rollup-win32-ia32-msvc': 4.60.1 + '@rollup/rollup-win32-x64-gnu': 4.60.1 + '@rollup/rollup-win32-x64-msvc': 4.60.1 + fsevents: 2.3.3 + + sax@1.6.0: {} + + semver@7.7.4: {} + + shiki@3.23.0: + dependencies: + '@shikijs/core': 3.23.0 + '@shikijs/engine-javascript': 3.23.0 + '@shikijs/engine-oniguruma': 3.23.0 + '@shikijs/langs': 3.23.0 + '@shikijs/themes': 3.23.0 + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + source-map-js@1.2.1: {} + + space-separated-tokens@2.0.2: {} + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + + tabbable@6.4.0: {} + + tinyexec@1.1.1: {} + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + + tinypool@2.1.0: {} + + trim-lines@3.0.1: {} + + tsx@4.21.0: + dependencies: + esbuild: 0.27.7 + get-tsconfig: 4.13.7 + optionalDependencies: + fsevents: 2.3.3 + + typescript@6.0.2: {} + + ufo@1.6.3: {} + + undici-types@7.16.0: {} + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.1.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + universal-user-agent@7.0.3: {} + + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + + vite@7.3.2(@types/node@24.12.2)(tsx@4.21.0): + dependencies: + esbuild: 0.27.7 + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + postcss: 8.5.8 + rollup: 4.60.1 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 24.12.2 + fsevents: 2.3.3 + tsx: 4.21.0 + + vitepress-plugin-group-icons@1.7.3(vite@7.3.2(@types/node@24.12.2)(tsx@4.21.0)): + dependencies: + '@iconify-json/logos': 1.2.11 + '@iconify-json/vscode-icons': 1.2.45 + '@iconify/utils': 3.1.0 + optionalDependencies: + vite: 7.3.2(@types/node@24.12.2)(tsx@4.21.0) + + vitepress@2.0.0-alpha.17(@types/node@24.12.2)(postcss@8.5.8)(tsx@4.21.0)(typescript@6.0.2): + dependencies: + '@docsearch/css': 4.6.2 + '@docsearch/js': 4.6.2 + '@docsearch/sidepanel-js': 4.6.2 + '@iconify-json/simple-icons': 1.2.76 + '@shikijs/core': 3.23.0 + '@shikijs/transformers': 3.23.0 + '@shikijs/types': 3.23.0 + '@types/markdown-it': 14.1.2 + '@vitejs/plugin-vue': 6.0.5(vite@7.3.2(@types/node@24.12.2)(tsx@4.21.0))(vue@3.5.32(typescript@6.0.2)) + '@vue/devtools-api': 8.1.1 + '@vue/shared': 3.5.32 + '@vueuse/core': 14.2.1(vue@3.5.32(typescript@6.0.2)) + '@vueuse/integrations': 14.2.1(focus-trap@8.0.1)(vue@3.5.32(typescript@6.0.2)) + focus-trap: 8.0.1 + mark.js: 8.11.1 + minisearch: 7.2.0 + shiki: 3.23.0 + vite: 7.3.2(@types/node@24.12.2)(tsx@4.21.0) + vue: 3.5.32(typescript@6.0.2) + optionalDependencies: + postcss: 8.5.8 + transitivePeerDependencies: + - '@types/node' + - async-validator + - axios + - change-case + - drauu + - fuse.js + - idb-keyval + - jiti + - jwt-decode + - less + - lightningcss + - nprogress + - qrcode + - sass + - sass-embedded + - sortablejs + - stylus + - sugarss + - terser + - tsx + - typescript + - universal-cookie + - yaml + + vue@3.5.32(typescript@6.0.2): + dependencies: + '@vue/compiler-dom': 3.5.32 + '@vue/compiler-sfc': 3.5.32 + '@vue/runtime-dom': 3.5.32 + '@vue/server-renderer': 3.5.32(vue@3.5.32(typescript@6.0.2)) + '@vue/shared': 3.5.32 + optionalDependencies: + typescript: 6.0.2 + + xml-js@1.6.11: + dependencies: + sax: 1.6.0 + + zwitch@2.0.4: {} diff --git a/server/index.js b/server/index.js deleted file mode 100644 index 4acde48c..00000000 --- a/server/index.js +++ /dev/null @@ -1,24 +0,0 @@ -const Hapi = require("@hapi/hapi") -const consola = require("consola") -const HapiNuxt = require("@nuxtjs/hapi") - -const server = new Hapi.Server({ - host: process.env.HOST || "0.0.0.0", - port: process.env.PORT || 3000 -}) - -server - .register({ - plugin: HapiNuxt - }) - .then(() => server.start()) - .then(() => - consola.ready({ - message: `Server running at: ${server.info.uri}`, - badge: true - }) - ) - .catch(err => { - consola.error(err) - throw err - }) diff --git a/server/static.js b/server/static.js deleted file mode 100644 index c2abd53e..00000000 --- a/server/static.js +++ /dev/null @@ -1,37 +0,0 @@ -'use strict'; - -const Hapi = require('@hapi/hapi'); -const Path = require('path'); - -const start = async () => { - - const server = Hapi.server({ - host: process.env.HOST || "0.0.0.0", - port: process.env.PORT || 3000, - routes: { - files: { - relativeTo: Path.join(__dirname, '../dist') - } - } - - }); - - await server.register(require('@hapi/inert')); - - server.route({ - method: 'GET', - path: '/{param*}', - handler: { - directory: { - path: '../dist', - index: ['index.html'] - } - } - }); - - await server.start(); - - console.log('Server running at:', server.info.uri); -}; - -start(); diff --git a/static/lib/plugins.json b/src/plugins.json similarity index 100% rename from static/lib/plugins.json rename to src/plugins.json diff --git a/static/_redirects b/static/_redirects deleted file mode 100644 index 409fd8e4..00000000 --- a/static/_redirects +++ /dev/null @@ -1,8 +0,0 @@ -# Redirects from what the browser requests to what we serve -/family/hapi /api -/family/hapi/api /api -/family/hapi/changelog /resources/changelog -/family/:module /module/:module -/family/:module/:api /module/:module/:api -/family/:module/:changelog /module/:module/:changelog -/family/* /module/:splat diff --git a/static/icon.png b/static/icon.png deleted file mode 100644 index f05ae633..00000000 Binary files a/static/icon.png and /dev/null differ diff --git a/static/img/arrow.png b/static/img/arrow.png deleted file mode 100644 index c286e4f7..00000000 Binary files a/static/img/arrow.png and /dev/null differ diff --git a/static/img/auth0-logo.svg b/static/img/auth0-logo.svg deleted file mode 100644 index 8af360c5..00000000 --- a/static/img/auth0-logo.svg +++ /dev/null @@ -1 +0,0 @@ -auth0-logo-whitebg \ No newline at end of file diff --git a/static/img/clipboard.png b/static/img/clipboard.png deleted file mode 100644 index df02651a..00000000 Binary files a/static/img/clipboard.png and /dev/null differ diff --git a/static/img/clipboardCheck.png b/static/img/clipboardCheck.png deleted file mode 100644 index 1fe0e383..00000000 Binary files a/static/img/clipboardCheck.png and /dev/null differ diff --git a/static/img/close.png b/static/img/close.png deleted file mode 100644 index f9700dff..00000000 Binary files a/static/img/close.png and /dev/null differ diff --git a/static/img/conde-nast-logo.png b/static/img/conde-nast-logo.png deleted file mode 100644 index 350b8c98..00000000 Binary files a/static/img/conde-nast-logo.png and /dev/null differ diff --git a/static/img/down.png b/static/img/down.png deleted file mode 100644 index 6cfe5ace..00000000 Binary files a/static/img/down.png and /dev/null differ diff --git a/static/img/family.svg b/static/img/family.svg deleted file mode 100644 index f6cf1677..00000000 --- a/static/img/family.svg +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/static/img/joiTestIcon.png b/static/img/joiTestIcon.png deleted file mode 100644 index 673e2d77..00000000 Binary files a/static/img/joiTestIcon.png and /dev/null differ diff --git a/static/img/search.png b/static/img/search.png deleted file mode 100644 index 8db1cf74..00000000 Binary files a/static/img/search.png and /dev/null differ diff --git a/static/img/vrbo-logo.png b/static/img/vrbo-logo.png deleted file mode 100644 index e10a9173..00000000 Binary files a/static/img/vrbo-logo.png and /dev/null differ diff --git a/static/lib/index.js b/static/lib/index.js deleted file mode 100644 index b7a01946..00000000 --- a/static/lib/index.js +++ /dev/null @@ -1,6 +0,0 @@ -"use strict"; - -export const tutorials = require("./tutorials"); -export const plugins = require("./plugins.json"); -export const resources = require("./resources.md"); -export const moduleInfo = require("./moduleInfo.json"); diff --git a/static/lib/moduleInfo.json b/static/lib/moduleInfo.json deleted file mode 100644 index ca3fe876..00000000 --- a/static/lib/moduleInfo.json +++ /dev/null @@ -1,2286 +0,0 @@ -{ - "accept": { - "name": "accept", - "versions": [ - { - "name": "6.0.3", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "5.0.2", - "branch": "v5", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "6.0.3", - "5.0.2" - ], - "api": true, - "isPlugin": false, - "6.0.3": { - "menu": "- [Methods](#methods)\n - [`charset()`](#charsetcharsetheader-preferences)\n - [`charsets()`](#charsetscharsetheader)\n - [`encoding()`](#encodingencodingheader-preferences)\n - [`encodings()`](#encodingsencodingheader)\n - [`language()`](#languagelanguageheader-preferences)\n - [`languages()`](#languageslanguageheader)\n - [`mediaType()`](#mediatypemediatypeheader-preferences)\n - [`mediaTypes()`](#mediatypesmediatypeheader)\n - [`parseAll()`](#parseallheaders)\n- [Q Weightings](#q-weightings)\n- [Encodings](#encodings)\n - [Preferences](#preferences)\n - [Identity](#identity)", - "api": "

    Methods

    \n

    charset(charsetHeader, [preferences])

    \n

    Given a string of acceptable charsets from a HTTP request Accept-Charset header, and an optional array of charset preferences, it will return a string indicating the best charset option that can be used in the HTTP response. This takes into account any weighting parameters given in the header for ordering and exclusion.

    \n
    const charset = Accept.charsets(\"iso-8859-5, unicode-1-1;q=0.8\"); // charset === \"iso-8859-5\"\nconst charset = Accept.charsets(\"iso-8859-5, unicode-1-1;q=0.8\", [\"unicode-1-1\"]); // charset === \"unicode-1-1\"\n
    \n

    charsets(charsetHeader)

    \n

    Given a string of acceptable charsets from a HTTP request Accept-Charset header it will return an array of strings indicating the possible charset options that can be used in the HTTP response, in order from most preferred to least as determined by the q weightings

    \n
    const charsets = Accept.charsets(\"iso-8859-5, unicode-1-1;q=0.8\"); // charsets === [\"iso-8859-5\", \"unicode-1-1\"]\nconst charsets = Accept.charsets(\"iso-8859-5;q=0.5, unicode-1-1;q=0.8\"); // charsets === [\"unicode-1-1\", \"iso-8859-5\"]\n
    \n

    encoding(encodingHeader, [preferences])

    \n

    Given a string of acceptable encodings from a HTTP request Accept-Encoding header, and optionally an array of preferences, it will return a string with the best fit encoding that should be used in the HTTP response. If no preferences array parameter is given the highest weighted or first ordered encoding is returned. If weightings are given in the header (using the q parameter) they are taken into account and the highest weighted match is returned. If a preferences array is given the best match from the array is returned. For more information about how the preferences array works see the section below on Preferences.

    \n
    const encoding = Accept.encoding(\"gzip, deflate, sdch\"); // encoding === \"gzip\"\nconst encoding = Accept.encoding(\"gzip, deflate, sdch\", [\"deflate\", \"identity\"]); // encoding === \"delate\"\n
    \n

    encodings(encodingHeader)

    \n

    Given a string of acceptable encodings from a HTTP request Accept-Encoding header it will return an array of strings indicating the possible encoding options that can be used in the HTTP response, in order from most preferred to least as determined by the q weightings

    \n
    const encodings = Accept.encodings(\"compress;q=0.5, gzip;q=1.0\"); // encodings === [\"gzip\", \"compress\", \"identity\"]\n
    \n

    language(languageHeader, [preferences])

    \n

    Given a string of acceptable language ranges from a HTTP request Accept-Language header, and an optional array of language-tag preferences, it will return a string indicating the best language that can be used in the HTTP response. It respects the q weightings of the languages in the header, returning the matched preference with the highest weighting. The case of the preference does not have to match the case of the option in the header.

    \n

    If preferences is missing or an empty array, the highest weighted language is returned. If no preference matches, an empty string is returned.

    \n
    const language = Accept.language(\"en;q=0.7, en-GB;q=0.8\"); // language === \"en-gb\"\n\n// the case of the preference \"en-gb\" does not match the case of the header option \"en-GB\"\nconst language = Accept.language(\"en;q=0.7, en-GB;q=0.8\", [\"en-gb\"]); // language === \"en-gb\"\n
    \n

    languages(languageHeader)

    \n

    Given a string of acceptable languages from a HTTP request Accept-Language header it will return an array of strings indicating the possible languages that can be used in the HTTP response, in order from most preferred to least as determined by the q weightings.

    \n
    const languages = Accept.languages(\"da, en;q=0.7, en-GB;q=0.8\"); // languages === [\"da\", \"en-gb\", \"en\"]\n
    \n

    mediaType(mediaTypeHeader, [preferences])

    \n

    Given a string of acceptable media types from a HTTP request Accept header, and optionally an array of preferences, it will return a string with the best fit media type that should be used in the HTTP response. If no preferences array parameter is given the highest weighted or first ordered media type is returned. If weightings are given in the header (using the q parameter) they are taken into account and the highest weighted match is returned. If a preferences array is given the best match from the array is returned. For more information about how the preferences array works see the section below on Preferences.

    \n
    const mediaType = Accept.mediaType(\"text/plain, application/json;q=0.5, text/html, */*;q=0.1\");\n// mediaType === \"text/plain\"\n\nconst mediaType = Accept.mediaType(\"text/plain, application/json;q=0.5, text/html, */*;q=0.1\", [\"text/html\", \"application/json\"]);\n// mediaType === \"text/html\"\n
    \n

    mediaTypes(mediaTypeHeader)

    \n

    Given a string of acceptable media types from a HTTP request Accept header it will return an array of strings indicating the possible media types that can be used in the HTTP response, in order from most preferred to least as determined by the q weightings.

    \n
    const mediaTypes = Accept.mediaTypes(\"text/plain, application/json;q=0.5, text/html, */*;q=0.1\");\n// mediaTypes === [\"text/plain\", \"text/html\", \"application/json\", \"*/*\"]\n
    \n

    parseAll(headers)

    \n

    Given the headers from a Hapi request object, parseAll() will parse all of the Accepts-* headers it currently understands into an object.

    \n
    const all = Accept.parseAll(request.headers);\n// all === {\n//    \"charsets\": [\"iso-8859-5\", \"unicode-1-1\"],\n//    \"encodings\": [\"gzip\", \"compress\", \"identity\"],\n//    \"languages\": [\"da\", \"en-gb\", \"en\"],\n//    \"mediaTypes\": [\"text/plain\", \"text/html\", \"application/json\", \"*/*\"]\n// }\n
    \n

    Q Weightings

    \n

    The Accept-* headers may optionally include preferential weighting to indicate which options are best for the requester. It does this with q parameters in the headers (which stands for quality). These q weightings must be in the range of 0 to 1, with a max of three decimal places. The weightings are used to order the data given in the header, with the highest number being most preferential. Anything with a q rating of 0 is not allowed at all.

    \n

    If a particular Accept method allows a preferences array parameter, such as encoding(), the weightings in the header affect which preference will be returned. Your preferences are matched with the weighting in mind, and the highest weighted option will be returned, no matter what order you list your preferences. The header weighting is most important.

    \n
    const encoding = Accept.encoding(\"gzip;q=1.0, identity;q=0.5\", [\"identity\", \"gzip\"]);\n// encoding === \"gzip\"\n// despite identity getting listed first in the preferences array, gzip has a higher q weighting, so it is returned.\n
    \n

    Encodings

    \n

    Preferences

    \n

    If you are looking for a set of specific encodings you can pass that in as an array to the preferences parameter. Your preferences must be an array. In the preferences array you specify a list of possible encodings you want to look for, in order of preference. Accept will return back the most preferential option it can find, if any match. The preferences array does not support parameters, only base types.

    \n
    const encoding = Accept.encoding(\"gzip, deflate, sdch\", [\"deflate\", \"identity\"]); // encoding === \"delate\"\n
    \n

    Your preferences are evaluated without any case sensitivity, to better match what the browser sends. This means that \"gZip\" will match a preference of [\"gzip\"].

    \n
    const encoding = Accept.encoding(\"gZip, deflate, sdch\", [\"gzip\"]); // encoding === \"gzip\"\n
    \n

    If you supply a preferences array, and no match is found, encoding() will return an empty string, rather than an encoding from the header.

    \n
    const encoding = Accept.encoding(\"gZip\", [\"deflate\"]); // encoding === \"\"\n
    \n

    If the encoding header is the special \"*\" that indicates the browser will accept any encoding. In that case the top preference from your supplied options will be returned.

    \n
    const encoding = Accept.encoding(\"*\", [\"gzip\"]); // encoding === \"gzip\"\n
    \n

    Identity

    \n

    When you ask Accept for a list of all the supported encodings from the request, using the encodings() function (plural, not singular), you will be returned an array of strings in order from most preferred to least as determined by the encoding weight.

    \n
    const encodings = Accept.encodings(\"compress;q=0.5, gzip;q=1.0\"); // encodings === [\"gzip\", \"compress\", \"identity\"]\n
    \n

    You'll notice that identity was returned in the array, even though it's not in the encoding header. Identity is always an option for encoding, unless specifically excluded in the header using a weighting of zero. Identity just means respond with no special encoding.

    \n", - "intro": "## Introduction\n\nAccept helps to answer the question of how best to respond to a HTTP request, based on the requesting browser's capabilities. Accept will parse the headers of a HTTP request and tell you what the preferred encoding is, what language should be used, and what charsets and media types are accepted.\n\nAdditional details about Accept headers and content negotiation can be found in [IETF RFC 7231, Section 5.3](https://tools.ietf.org/html/rfc7231#section-5.3).\n", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "5.0.2": { - "menu": "- [Methods](#methods)\n - [`charset()`](#charsetcharsetheader-preferences)\n - [`charsets()`](#charsetscharsetheader)\n - [`encoding()`](#encodingencodingheader-preferences)\n - [`encodings()`](#encodingsencodingheader)\n - [`language()`](#languagelanguageheader-preferences)\n - [`languages()`](#languageslanguageheader)\n - [`mediaType()`](#mediatypemediatypeheader-preferences)\n - [`mediaTypes()`](#mediatypesmediatypeheader)\n - [`parseAll()`](#parseallheaders)\n- [Q Weightings](#q-weightings)\n- [Encodings](#encodings)\n - [Preferences](#preferences)\n - [Identity](#identity)", - "api": "

    Introduction

    \n

    Accept helps to answer the question of how best to respond to a HTTP request, based on the requesting browser's capabilities. Accept will parse the headers of a HTTP request and tell you what the preferred encoding is, what language should be used, and what charsets and media types are accepted.

    \n

    Additional details about Accept headers and content negotiation can be found in IETF RFC 7231, Section 5.3.

    \n

    Methods

    \n

    charset(charsetHeader, [preferences])

    \n

    Given a string of acceptable charsets from a HTTP request Accept-Charset header, and an optional array of charset preferences, it will return a string indicating the best charset option that can be used in the HTTP response. This takes into account any weighting parameters given in the header for ordering and exclusion.

    \n
    const charset = Accept.charsets(\"iso-8859-5, unicode-1-1;q=0.8\"); // charset === \"iso-8859-5\"\nconst charset = Accept.charsets(\"iso-8859-5, unicode-1-1;q=0.8\", [\"unicode-1-1\"]); // charset === \"unicode-1-1\"\n
    \n

    charsets(charsetHeader)

    \n

    Given a string of acceptable charsets from a HTTP request Accept-Charset header it will return an array of strings indicating the possible charset options that can be used in the HTTP response, in order from most preferred to least as determined by the q weightings

    \n
    const charsets = Accept.charsets(\"iso-8859-5, unicode-1-1;q=0.8\"); // charsets === [\"iso-8859-5\", \"unicode-1-1\"]\nconst charsets = Accept.charsets(\"iso-8859-5;q=0.5, unicode-1-1;q=0.8\"); // charsets === [\"unicode-1-1\", \"iso-8859-5\"]\n
    \n

    encoding(encodingHeader, [preferences])

    \n

    Given a string of acceptable encodings from a HTTP request Accept-Encoding header, and optionally an array of preferences, it will return a string with the best fit encoding that should be used in the HTTP response. If no preferences array parameter is given the highest weighted or first ordered encoding is returned. If weightings are given in the header (using the q parameter) they are taken into account and the highest weighted match is returned. If a preferences array is given the best match from the array is returned. For more information about how the preferences array works see the section below on Preferences.

    \n
    const encoding = Accept.encoding(\"gzip, deflate, sdch\"); // encoding === \"gzip\"\nconst encoding = Accept.encoding(\"gzip, deflate, sdch\", [\"deflate\", \"identity\"]); // encoding === \"delate\"\n
    \n

    encodings(encodingHeader)

    \n

    Given a string of acceptable encodings from a HTTP request Accept-Encoding header it will return an array of strings indicating the possible encoding options that can be used in the HTTP response, in order from most preferred to least as determined by the q weightings

    \n
    const encodings = Accept.encodings(\"compress;q=0.5, gzip;q=1.0\"); // encodings === [\"gzip\", \"compress\", \"identity\"]\n
    \n

    language(languageHeader, [preferences])

    \n

    Given a string of acceptable language ranges from a HTTP request Accept-Language header, and an optional array of language-tag preferences, it will return a string indicating the best language that can be used in the HTTP response. It respects the q weightings of the languages in the header, returning the matched preference with the highest weighting. The case of the preference does not have to match the case of the option in the header.

    \n

    If preferences is missing or an empty array, the highest weighted language is returned. If no preference matches, an empty string is returned.

    \n
    const language = Accept.language(\"en;q=0.7, en-GB;q=0.8\"); // language === \"en-gb\"\n\n// the case of the preference \"en-gb\" does not match the case of the header option \"en-GB\"\nconst language = Accept.language(\"en;q=0.7, en-GB;q=0.8\", [\"en-gb\"]); // language === \"en-gb\"\n
    \n

    languages(languageHeader)

    \n

    Given a string of acceptable languages from a HTTP request Accept-Language header it will return an array of strings indicating the possible languages that can be used in the HTTP response, in order from most preferred to least as determined by the q weightings.

    \n
    const languages = Accept.languages(\"da, en;q=0.7, en-GB;q=0.8\"); // languages === [\"da\", \"en-gb\", \"en\"]\n
    \n

    mediaType(mediaTypeHeader, [preferences])

    \n

    Given a string of acceptable media types from a HTTP request Accept header, and optionally an array of preferences, it will return a string with the best fit media type that should be used in the HTTP response. If no preferences array parameter is given the highest weighted or first ordered media type is returned. If weightings are given in the header (using the q parameter) they are taken into account and the highest weighted match is returned. If a preferences array is given the best match from the array is returned. For more information about how the preferences array works see the section below on Preferences.

    \n
    const mediaType = Accept.mediaType(\"text/plain, application/json;q=0.5, text/html, */*;q=0.1\");\n// mediaType === \"text/plain\"\n\nconst mediaType = Accept.mediaType(\"text/plain, application/json;q=0.5, text/html, */*;q=0.1\", [\"text/html\", \"application/json\"]);\n// mediaType === \"text/html\"\n
    \n

    mediaTypes(mediaTypeHeader)

    \n

    Given a string of acceptable media types from a HTTP request Accept header it will return an array of strings indicating the possible media types that can be used in the HTTP response, in order from most preferred to least as determined by the q weightings.

    \n
    const mediaTypes = Accept.mediaTypes(\"text/plain, application/json;q=0.5, text/html, */*;q=0.1\");\n// mediaTypes === [\"text/plain\", \"text/html\", \"application/json\", \"*/*\"]\n
    \n

    parseAll(headers)

    \n

    Given the headers from a Hapi request object, parseAll() will parse all of the Accepts-* headers it currently understands into an object.

    \n
    const all = Accept.parseAll(request.headers);\n// all === {\n//    \"charsets\": [\"iso-8859-5\", \"unicode-1-1\"],\n//    \"encodings\": [\"gzip\", \"compress\", \"identity\"],\n//    \"languages\": [\"da\", \"en-gb\", \"en\"],\n//    \"mediaTypes\": [\"text/plain\", \"text/html\", \"application/json\", \"*/*\"]\n// }\n
    \n

    Q Weightings

    \n

    The Accept-* headers may optionally include preferential weighting to indicate which options are best for the requester. It does this with q parameters in the headers (which stands for quality). These q weightings must be in the range of 0 to 1, with a max of three decimal places. The weightings are used to order the data given in the header, with the highest number being most preferential. Anything with a q rating of 0 is not allowed at all.

    \n

    If a particular Accept method allows a preferences array parameter, such as encoding(), the weightings in the header affect which preference will be returned. Your preferences are matched with the weighting in mind, and the highest weighted option will be returned, no matter what order you list your preferences. The header weighting is most important.

    \n
    const encoding = Accept.encoding(\"gzip;q=1.0, identity;q=0.5\", [\"identity\", \"gzip\"]);\n// encoding === \"gzip\"\n// despite identity getting listed first in the preferences array, gzip has a higher q weighting, so it is returned.\n
    \n

    Encodings

    \n

    Preferences

    \n

    If you are looking for a set of specific encodings you can pass that in as an array to the preferences parameter. Your preferences must be an array. In the preferences array you specify a list of possible encodings you want to look for, in order of preference. Accept will return back the most preferential option it can find, if any match. The preferences array does not support parameters, only base types.

    \n
    const encoding = Accept.encoding(\"gzip, deflate, sdch\", [\"deflate\", \"identity\"]); // encoding === \"delate\"\n
    \n

    Your preferences are evaluated without any case sensitivity, to better match what the browser sends. This means that \"gZip\" will match a preference of [\"gzip\"].

    \n
    const encoding = Accept.encoding(\"gZip, deflate, sdch\", [\"gzip\"]); // encoding === \"gzip\"\n
    \n

    If you supply a preferences array, and no match is found, encoding() will return an empty string, rather than an encoding from the header.

    \n
    const encoding = Accept.encoding(\"gZip\", [\"deflate\"]); // encoding === \"\"\n
    \n

    If the encoding header is the special \"*\" that indicates the browser will accept any encoding. In that case the top preference from your supplied options will be returned.

    \n
    const encoding = Accept.encoding(\"*\", [\"gzip\"]); // encoding === \"gzip\"\n
    \n

    Identity

    \n

    When you ask Accept for a list of all the supported encodings from the request, using the encodings() function (plural, not singular), you will be returned an array of strings in order from most preferred to least as determined by the encoding weight.

    \n
    const encodings = Accept.encodings(\"compress;q=0.5, gzip;q=1.0\"); // encodings === [\"gzip\", \"compress\", \"identity\"]\n
    \n

    You'll notice that identity was returned in the array, even though it's not in the encoding header. Identity is always an option for encoding, unless specifically excluded in the header using a weighting of zero. Identity just means respond with no special encoding.

    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "HTTP Accept-* headers parsing.", - "forks": 30, - "stars": 53, - "date": "2024-10-23T14:51:04Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/accept" - }, - "ammo": { - "name": "ammo", - "versions": [ - { - "name": "6.0.1", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "5.0.1", - "branch": "v5", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "6.0.1", - "5.0.1" - ], - "api": true, - "isPlugin": false, - "6.0.1": { - "menu": "- [Methods](#methods)\n - [`header()`](#headerheader-length)\n - [`new Ammo.Stream()`](#new-ammostreamrange)", - "api": "

    Methods

    \n

    header(header, length)

    \n

    Parses the range from a HTTP header, where:

    \n
      \n
    • \nheader - A string in the form of bytes=from-to, where from and to are integers specifying the range. Both are optional. Multiple ranges can be passed as a comma delimited list.
    • \n
    • \nlength - A positive integer specifying the maximum length the range can cover. If a to value passed in the header string is greater than length, the to value is set as length - 1.
    • \n
    \n

    Returns an array of objects with the properties from and to, which specify the beginning and ending of the range. Overlapping ranges are combined into one object. Returns null for invalid input.

    \n

    new Ammo.Stream(range)

    \n

    Creates a Transform Stream that extracts the portion of a piped in stream within range, where:

    \n
      \n
    • \nrange - an object with the properties from and to that specify the range of the piped in stream to read. Objects returned by Ammo.header can be passed into range.
    • \n
    \n", - "intro": "", - "example": "", - "usage": "## Usage\n\n```js\n// basic usage\nconst range = Ammo.header('bytes=1-5', 10);\n// range --> [{ from: 1, to: 5 }]\n\n// multiple ranges\nconst range = Ammo.header('bytes=1-5,7-10', 10);\n// range --> [{ from: 1, to: 5 }, { from: 7, to: 9 }]\n\n// streams (get range within a `source`)\nconst range = Ammo.header('bytes=1000-4000', 5000);\nconst stream = new Ammo.Stream(range[0]);\nconst buffer = await Wreck.read(source.pipe(stream));\n\n// buffer is the portion of source within range\n```\n", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "5.0.1": { - "menu": "- [Methods](#methods)\n - [`header()`](#headerheader-length)\n - [`new Ammo.Stream()`](#new-ammostreamrange)", - "api": "

    Usage

    \n
    // basic usage\nconst range = Ammo.header('bytes=1-5', 10);\n// range --> [{ from: 1, to: 5 }]\n\n// multiple ranges\nconst range = Ammo.header('bytes=1-5,7-10', 10);\n// range --> [{ from: 1, to: 5 }, { from: 7, to: 9 }]\n\n// streams (get range within a `source`)\nconst range = Ammo.header('bytes=1000-4000', 5000);\nconst stream = new Ammo.Stream(range[0]);\nconst buffer = await Wreck.read(source.pipe(stream));\n\n// buffer is the portion of source within range
    \n

    Methods

    \n

    header(header, length)

    \n

    Parses the range from a HTTP header, where:

    \n
      \n
    • \nheader - A string in the form of bytes=from-to, where from and to are integers specifying the range. Both are optional. Multiple ranges can be passed as a comma delimited list.
    • \n
    • \nlength - A positive integer specifying the maximum length the range can cover. If a to value passed in the header string is greater than length, the to value is set as length - 1.
    • \n
    \n

    Returns an array of objects with the properties from and to, which specify the beginning and ending of the range. Overlapping ranges are combined into one object. Returns null for invalid input.

    \n

    new Ammo.Stream(range)

    \n

    Creates a Transform Stream that extracts the portion of a piped in stream within range, where:

    \n
      \n
    • \nrange - an object with the properties from and to that specify the range of the piped in stream to read. Objects returned by Ammo.header can be passed into range.
    • \n
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "HTTP Range processing utilities.", - "forks": 8, - "stars": 1, - "date": "2024-10-23T15:38:18Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/ammo" - }, - "b64": { - "name": "b64", - "versions": [ - { - "name": "6.0.1", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "5.0.0", - "branch": "v5", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "6.0.1", - "5.0.0" - ], - "api": true, - "isPlugin": false, - "6.0.1": { - "menu": "- [encode()](#encodebuffer)\n- [decode()](#decodebuffer)\n- [Encoder](#encoder)\n- [Decoder](#decoder)\n- [base64urlEncode()](#base64urlencodevalue)\n- [base64urlDecode()](#base64urldecodevalue)", - "api": "

    encode(buffer)

    \n

    Base64 encode the buffer and return it as a new Buffer.

    \n

    decode(buffer)

    \n

    Base64 decode the buffer and return the result as a new buffer.

    \n

    Encoder

    \n

    Transform stream that base64 encodes each chunk of the stream.

    \n

    Example:

    \n
    'use strict';\n\nconst Fs = require('fs');\nconst B64 = require('@hapi/b64');\n\nconst stream = Fs.createReadStream(`${__dirname}/package.json`);\nconst encoder = new B64.Encoder();\n\nstream.pipe(encoder).pipe(process.stdout);
    \n

    Decoder

    \n

    Transform stream that base64 decodes each chunk of the stream.

    \n

    Example:

    \n
    'use strict';\n\nconst Fs = require('fs');\nconst B64 = require('@hapi/b64');\n\nconst stream = Fs.createReadStream(`${__dirname}/encodedfile.b64`);\nconst decoder = new B64.Decoder();\n\nstream.pipe(decoder).pipe(process.stdout);
    \n

    base64urlEncode(value)

    \n

    Encodes value of string or buffer type in Base64 or URL encoding, function will assert input value is correct.

    \n

    base64urlDecode(value)

    \n

    Decodes string into Base64 or URL encoding, function throws an error on invalid input and returns a string or buffer depending on encoding provided. Default encoding is binary.

    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "5.0.0": { - "menu": "- [encode()](#encodebuffer)\n- [decode()](#decodebuffer)\n- [Encoder](#encoder)\n- [Decoder](#decoder)\n- [base64urlEncode()](#base64urlencodevalue)\n- [base64urlDecode()](#base64urldecodevalue)", - "api": "

    encode(buffer)

    \n

    Base64 encode the buffer and return it as a new Buffer.

    \n

    decode(buffer)

    \n

    Base64 decode the buffer and return the result as a new buffer.

    \n

    Encoder

    \n

    Transform stream that base64 encodes each chunk of the stream.

    \n

    Example:

    \n
    'use strict';\n\nconst Fs = require('fs');\nconst B64 = require('@hapi/b64');\n\nconst stream = Fs.createReadStream(`${__dirname}/package.json`);\nconst encoder = new B64.Encoder();\n\nstream.pipe(encoder).pipe(process.stdout);
    \n

    Decoder

    \n

    Transform stream that base64 decodes each chunk of the stream.

    \n

    Example:

    \n
    'use strict';\n\nconst Fs = require('fs');\nconst B64 = require('@hapi/b64');\n\nconst stream = Fs.createReadStream(`${__dirname}/encodedfile.b64`);\nconst decoder = new B64.Decoder();\n\nstream.pipe(decoder).pipe(process.stdout);
    \n

    base64urlEncode(value)

    \n

    Encodes value of string or buffer type in Base64 or URL encoding, function will assert input value is correct.

    \n

    base64urlDecode(value)

    \n

    Decodes string into Base64 or URL encoding, function throws an error on invalid input and returns a string or buffer depending on encoding provided. Default encoding is binary.

    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Base64 streaming encoder and decoder.", - "forks": 13, - "stars": 41, - "date": "2024-10-23T15:42:49Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/b64" - }, - "basic": { - "name": "basic", - "versions": [ - { - "name": "7.0.2", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "7.0.2" - ], - "api": true, - "isPlugin": true, - "7.0.2": { - "menu": "- [Usage](#usage)", - "api": "

    Usage

    \n

    Basic authentication requires validating a username and password combination. The 'basic' scheme takes the following options:

    \n
      \n
    • \nvalidate - (required) a user lookup and password validation function with the signature [async] function(request, username, password, h) where:\n
        \n
      • \nrequest - is the hapi request object of the request which is being authenticated.
      • \n
      • \nusername - the username received from the client.
      • \n
      • \npassword - the password received from the client.
      • \n
      • \nh - the response toolkit.
      • \n
      • Returns an object { isValid, credentials, response } where:\n
          \n
        • \nisValid - true if both the username was found and the password matched, otherwise false.
        • \n
        • \ncredentials - a credentials object passed back to the application in request.auth.credentials.
        • \n
        • \nresponse - Optional. If provided will be used immediately as a takeover response. Can be used to redirect the client, for example. Don't need to provide isValid or credentials if response is provided
        • \n
        \n
      • \n
      • Throwing an error from this function will replace default Boom.unauthorized error
      • \n
      • Typically, credentials are only included when isValid is true, but there are cases when the application needs to know who tried to authenticate even when it fails (e.g. with authentication mode 'try').
      • \n
      \n
    • \n
    • \nallowEmptyUsername - (optional) if true, allows making requests with an empty username. Defaults to false.
    • \n
    • \nunauthorizedAttributes - (optional) if set, passed directly to Boom.unauthorized if no custom err is thrown. Useful for setting realm attribute in WWW-Authenticate header. Defaults to undefined.
    • \n
    \n
    const Bcrypt = require('bcrypt');\nconst Hapi = require('@hapi/hapi');\n\nconst users = {\n    john: {\n        username: 'john',\n        password: '$2a$10$iqJSHD.BGr0E2IxQwYgJmeP3NvhPrXAeLSaGCj6IR/XU5QtjVu5Tm',   // 'secret'\n        name: 'John Doe',\n        id: '2133d32a'\n    }\n};\n\nconst validate = async (request, username, password, h) => {\n\n    if (username === 'help') {\n        return { response: h.redirect('https://hapijs.com/help') };     // custom response\n    }\n\n    const user = users[username];\n    if (!user) {\n        return { credentials: null, isValid: false };\n    }\n\n    const isValid = await Bcrypt.compare(password, user.password);\n    const credentials = { id: user.id, name: user.name };\n\n    return { isValid, credentials };\n};\n\nconst main = async () => {\n\n    const server = Hapi.server({ port: 4000 });\n\n    await server.register(require('@hapi/basic'));\n\n    server.auth.strategy('simple', 'basic', { validate });\n    server.auth.default('simple');\n\n    server.route({\n        method: 'GET',\n        path: '/',\n        handler: function (request, h) {\n\n            return 'welcome';\n        }\n    });\n\n    await server.start();\n\n    return server;\n};\n\nmain()\n.then((server) => console.log(`Server listening on ${server.info.uri}`))\n.catch((err) => {\n\n    console.error(err);\n    process.exit(1);\n});
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Basic authentication plugin.", - "forks": 65, - "stars": 148, - "date": "2024-10-23T14:42:22Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/basic" - }, - "bell": { - "name": "bell", - "versions": [ - { - "name": "13.0.2", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "12.3.0", - "branch": "v12", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "13.0.2", - "12.3.0" - ], - "api": true, - "isPlugin": true, - "13.0.2": { - "menu": "- [Tutorials](#tutorials)\n- [Examples](#examples)\n- [Notes](#notes)\n- [Options](#options)\n- [Authentication information](#authentication-information)\n - [Always present](#always-present)\n - [Present on successful authentication](#present-on-successful-authentication)\n - [OAuth protocol](#oauth-protocol)\n - [OAuth2 protocol](#oauth2-protocol)\n - [Present on failed authentication ()](#present-on-failed-authentication-routeauthmodetry)\n- [Advanced Usage](#advanced-usage)\n - [Configuration via Environment Variables](#configuration-via-environment-variables)\n - [Handling Errors](#handling-errors)\n - [Token Refresh](#token-refresh)\n - [Simulated authentication](#simulated-authentication)\n- [Usage without a strategy](#usage-without-a-strategy)\n- [Customized Scope and Params](#customized-scope-and-params)", - "api": "

    Tutorials

    \n

    Social Login with Twitter using hapi.js

    \n

    Examples

    \n

    All Examples

    \n

    Twitter:

    \n
    // Load modules\n\nconst Bell = require('@hapi/bell');\nconst Hapi = require('@hapi/hapi');\n\n\n// Declare internals\n\nconst internals = {};\n\n\ninternals.start = async function () {\n\n    const server = Hapi.server({ port: 8000 });\n\n    // Register bell with the server\n\n    await server.register(Bell);\n\n    // Declare an authentication strategy using the bell scheme\n    // with the name of the provider, cookie encryption password,\n    // and the OAuth client credentials.\n\n    server.auth.strategy('twitter', 'bell', {\n        provider: 'twitter',\n        password: 'cookie_encryption_password_secure',\n        clientId: 'my_twitter_client_id',\n        clientSecret: 'my_twitter_client_secret',\n        isSecure: false     // Terrible idea but required if not using HTTPS especially if developing locally\n    });\n\n    // Use the 'twitter' authentication strategy to protect the\n    // endpoint handling the incoming authentication credentials.\n    // This endpoint usually looks up the third party account in\n    // the database and sets some application state (cookie) with\n    // the local application account information.\n\n    server.route({\n        method: ['GET', 'POST'],    // Must handle both GET and POST\n        path: '/login',             // The callback endpoint registered with the provider\n        options: {\n            auth: {\n              mode: 'try',\n              strategy: 'twitter'\n            },\n            handler: function (request, h) {\n\n                if (!request.auth.isAuthenticated) {\n                    return `Authentication failed due to: ${request.auth.error.message}`;\n                }\n\n                // Perform any account lookup or registration, setup local session,\n                // and redirect to the application. The third-party credentials are\n                // stored in request.auth.credentials. Any query parameters from\n                // the initial request are passed back via request.auth.credentials.query.\n\n                return h.redirect('/home');\n            }\n        }\n    });\n\n    await server.start();\n};\n\ninternals.start();
    \n

    Notes

    \n

    Testing third-party authorization is often a painful process. They are hard to test, tidious to configure, and tend to break when running on local servers. If you are having issues running bell locally, you might want to look at the isSecure and isSameSite options. Since most people don't run TLS on their local test server, isSecure must be set to false to remove the TLS requirement. isSameSite might need to be set to 'Lax' in some cases.

    \n

    You should also review the default scope set for each provider early in your implementation. The default scope is meant to get the minimal permissions needed to perform simple user login. In most cases, you would want to ask for more permissions as the default often does not provide access to most API calls provided by the third-party services.

    \n

    Options

    \n

    The server.auth.strategy() method requires the following strategy options:

    \n
      \n
    • \n

      provider - the name of the third-party provider ('auth0', 'azure', 'bitbucket',\n'dropbox', 'facebook', 'fitbit', 'foursquare', 'github', 'google', 'googleplus',\n'instagram', 'linkedin', 'live', 'twitter', 'vk', 'arcgisonline', 'yahoo',\n'nest', 'phabricator', 'pinterest') or an object containing a custom\nprovider with the following:

      \n
        \n
      • \nname - the custom provider name. Defaults to custom.
      • \n
      • \nprotocol - the authorization protocol used. Must be one of:\n
          \n
        • \n'oauth' - OAuth 1.0a
        • \n
        • \n'oauth2' - OAuth 2.0
        • \n
        \n
      • \n
      • \nsignatureMethod - the OAuth signature method (OAuth 1.0a only). Must be one of:\n
          \n
        • \n'HMAC-SHA1' - default
        • \n
        • \n'RSA-SHA1' - in that case, the clientSecret is your RSA private key
        • \n
        \n
      • \n
      • \ntemporary - the temporary credentials (request token) endpoint (OAuth 1.0a only).
      • \n
      • \nuseParamsAuth - boolean that determines if OAuth client id and client secret will be sent\nas parameters as opposed to an Authorization header (OAuth 2.0 only). Defaults to false.
      • \n
      • \nauth - the authorization endpoint URI.
      • \n
      • \ntoken - the access token endpoint URI.
      • \n
      • \nscope - an array of scope strings (OAuth 2.0 only).
      • \n
      • \nscopeSeparator - the scope separator character (OAuth 2.0 only). Only required when a\nprovider has a broken OAuth 2.0 implementation. Defaults to space (Facebook and GitHub\ndefault to comma).
      • \n
      • \nheaders - a headers object with additional headers required by the provider (e.g. GitHub\nrequired the 'User-Agent' header which is set by default).
      • \n
      • \nprofileMethod - get or post for obtaining user profile by profile function. Default\nis get.
      • \n
      • \nprofile - a function used to obtain user profile information and normalize it. The function\nsignature is async function(credentials, params, get) where:\n
          \n
        • \ncredentials - the credentials object. Change the object directly within the function\n(profile information is typically stored under credentials.profile).
        • \n
        • \nparams - the parsed information received from the provider (e.g. token, secret, and\nother custom fields).
        • \n
        • \nget - an OAuth helper function to make authenticated requests using the credentials\nreceived. The get function signature is async function(uri, params) where:\n
            \n
          • \nuri - the requested resource URI (bell will add the token or authentication\nheader as needed).
          • \n
          • \nparams - any URI query parameters (cannot include them in the URI due to signature\nrequirements).
          • \n
          • returns the parsed profile response object.
          • \n
          \n
        • \n
        \n
      • \n
      \n
    • \n
    • \n

      password - the cookie encryption password. Used to encrypt the temporary state cookie used by\nthe module in between the authorization protocol steps.

      \n
    • \n
    • \n

      clientId - the OAuth client identifier (consumer key).

      \n
    • \n
    • \n

      clientSecret - the OAuth client secret (consumer secret). This is usually a client password\nformatted as a string, but to allow OAuth2 custom client authentication\n(e.g. client certificate-based authentication), this option can be passed as an object. This\nobject will be merged with the Wreck request object used to call the token endpoint. Such an\nobject can contain custom HTTP headers or TLS options (e.g.\n{ agent: new Https.Agent({ cert: myClientCert, key: myClientKey}) }).\nTo allow dynamically updating secret, this option can be passed as a function returning string\nto be used as clientSecret.

      \n
    • \n
    • \n

      forceHttps - A boolean indicating whether or not you want the redirect_uri to be forced to\nhttps. Useful if your hapi application runs as http, but is accessed through https.

      \n
    • \n
    • \n

      location - Set the base redirect_uri manually if it cannot be inferred properly from server\nsettings. Useful to override port, protocol, and host if proxied or forwarded. It may be passed\neither as a string (in which case request.path is appended for you), or a function which takes\nthe client's request and returns a non-empty string, which is used as provided. In both cases,\nan empty string will result in default processing just as if the location option had not been\nspecified.

      \n
    • \n
    \n

    Each strategy accepts the following optional settings:

    \n
      \n
    • \ncookie - the name of the cookie used to manage the temporary state. Defaults to\n'bell-provider' where 'provider' is the provider name. For\nexample, the Twitter cookie name defaults to 'bell-twitter'.
    • \n
    • \nisSameSite - sets the cookie same site option. Defaults to Strict.
    • \n
    • \nisSecure - sets the cookie secure flag. Defaults to true.
    • \n
    • \nisHttpOnly - sets the cookie HTTP only flag. Defaults to true.
    • \n
    • \nttl - cookie time-to-live in milliseconds. Defaults to null (session time-life - cookies are\ndeleted when the browser is closed).
    • \n
    • \ndomain - the domain scope. Defaults to null (no domain).
    • \n
    • \nproviderParams - provider-specific query parameters for the authentication endpoint. It may be\npassed either as an object to merge into the query string, or a function which takes the client's\nrequest and returns an object. Each provider supports its own set of parameters which customize\nthe user's login experience. For example:\n
        \n
      • Facebook supports display ('page', 'popup', or 'touch'), auth_type, auth_nonce.
      • \n
      • Google supports access_type, approval_prompt, prompt, login_hint, user_id, hd.
      • \n
      • Twitter supports force_login, screen_name.
      • \n
      • Linkedin supports fields.
      • \n
      \n
    • \n
    • \nallowRuntimeProviderParams - allows passing query parameters from a bell protected endpoint\nto the auth request. It will merge the query params you pass along with the providerParams and\nany other predefined ones. Be aware that this will override predefined query parameters! Default\nto false.
    • \n
    • \nscope - Each built-in vendor comes with the required scope for basic profile information. Use\nscope to specify a different scope as required by your application. It may be passed either as\nan object to merge into the query string, or a function which takes the client's request and\nreturns an object. Consult the provider for their specific supported scopes.
    • \n
    • \nskipProfile - skips obtaining a user profile from the provider. Useful if you need specific\nscopes, but not the user profile. Defaults to false.
    • \n
    • \nconfig - a configuration object used to customize the provider settings:\n
        \n
      • Twitter:\n
          \n
        • extendedProfile
        • \n
        • getMethod
        • \n
        \n
      • \n
      • GitHub and Phabricator:\n
          \n
        • \nuri - allows pointing to a private enterprise installation (e.g.\n'https://vpn.example.com'). See Providers documentation for more\ninformation.
        • \n
        \n
      • \n
      \n
    • \n
    • \nprofileParams - an object of key-value pairs that specify additional URL query parameters to\nsend with the profile request to the provider. The built-in facebook provider, for example,\ncould have fields specified to determine the fields returned from the user's graph, which would\nthen be available to you in the auth.credentials.profile.raw object.
    • \n
    • \nruntimeStateCallback - allows passing additional OAuth state from initial request. This must be\na function returning a string, which will be appended to the bell internal state parameter\nfor OAuth code flow.
    • \n
    \n

    Authentication information

    \n

    On route handlers, the authentication object may contain one or more of the following properties depending on your route configuration and whether the authentication process was completed successfully or not:

    \n

    Always present

    \n
    auth.credentials = {\n  provider: String, // provider name\n};
    \n

    Present on successful authentication

    \n
    OAuth protocol
    \n
    auth.credentials = {\n  token: String,\n  secret: String,\n  query: Object // sign-in request query params\n};
    \n
    OAuth2 protocol
    \n
    auth.credentials = {\n  token: String,\n  refreshToken: String,\n  expiresIn: Number,\n  query: Object // sign-in request query params\n};\n\nauth.artifacts = Object; // OAuth token payload response
    \n
    Present on failed authentication (route.auth.mode=try)
    \n
    auth.credentials = {\n  query: Object // sign-in request query params\n};
    \n

    Advanced Usage

    \n

    Configuration via Environment Variables

    \n

    The server.auth.strategy() method supports string representations of its boolean and number typed\noptions. For example, forceHttps can be set to 'true', 'false', 'yes', or 'no'. In effect, this\nallows you to configure any strategy option using environment variables.

    \n

    Handling Errors

    \n

    By default, bell will reply back with an internal error (500) on most authentication errors due\nto the nature of the OAuth protocol. There is little that can be done to recover from errors as\nalmost all of them are caused by implementation or deployment issues.

    \n

    If you would like to display a useful error page instead of the default JSON response, use the\nhapi onPreResponse extension point to transform\nthe error into a useful page or to redirect the user to another destination.

    \n

    Another way to handle authentication errors is within the route handler. By default, an\nauthentication error will cause the handler to be skipped. However, if the authentication mode is\nset to 'try' instead of 'required', the handler will still be called. In this case, the\nrequest.auth.isAuthenticated must be checked to test if authentication failed. In that case,\nrequest.auth.error will contain the error.

    \n

    Token Refresh

    \n

    To keep track of the token expiry time, request.auth.credentials.expiresIn provides you the\nduration (in seconds) after which you could send a refresh token request using the\nrequest.auth.credentials.refreshToken to get a new token.

    \n

    Simulated authentication

    \n

    Testing applications using third-party login can be challenging given the lack of user interaction\nto perform the third-party login flow as well as the multiple steps required. To assist in testing\nsuch application without having to modify the application with custom code, Bell provides an\noverride method Bell.simulate() which puts the module into simulation mode and any strategies\ncreated while it is in this mode will return the simulated credentials.

    \n

    The Bell.simulate(credentialsFunc) takes a single argument:

    \n
      \n
    • \n

      credentialsFunc - a function called for each incoming request to the protected resource that\nshould return the credentials object to be set in request.auth.credentials. Note that bell\nwill set the default keys automatically if not present except for the provider-specific values.

      \n

      has the signature function(request) where:

      \n
        \n
      • \nrequest - the hapi request object.
      • \n
      \n
    • \n
    \n

    Note that you must call Bell.simulate() before the module is registered by your application and\nneed to call Bell.simulate(false) to stop it from simulating authentication.

    \n

    Usage without a strategy

    \n

    Sometimes, you want to use bell without using specifying a Hapi strategy. This can be the case when\ncombining the auth logic together with another module.

    \n

    bell exposes an oauth object in its plugin. Therefore, server.plugins.bell.oauth now has all\nthat's needed. For example, calling the v2 method with all the settings documented above, will\nhandle the oauth2 flow.

    \n

    Customized Scope and Params

    \n

    You can pass a function, rather than an object, into the providerParams and scope config\noptions to allow you to customize the scope or parameters based on the user's request. For example,\nthis may be used you want people to be able to log in with a provider (and only need some basic\nuser information) but also want to let users authorize your application to post messages or status\nupdates on their behalf.

    \n
    server.auth.strategy('twitter', 'bell', {\n    provider: 'twitter',\n    password: 'some cookie password',\n    location: 'http://example.com/oauth',\n    scope(request) {\n\n        const scopes = ['public_profile', 'email'];\n        if (request.query.wantsSharePermission) {\n          scopes.push('publish_actions');\n        }\n        return scopes;\n    }\n});
    \n", - "intro": "### Introduction\n\n**bell** ships with built-in support for authentication using `ArcGIS Online`, `Auth0`, `AzureAD`,\n`BitBucket`, `Cognito`, `DigitalOcean`, `Discord`, `Dropbox`, `Facebook`, `Fitbit`, `Foursquare`,\n`GitHub`, `GitLab`, `Google Plus`, `Google`, `Instagram`, `LinkedIn`, `Medium`, `Meetup`, `Mixer`,\n`Nest`, `Office365`, `Okta`, `Phabricator`, `Pingfed`, `Pinterest`, `Reddit`, `Salesforce`, `Slack`,\n`Spotify`, `Stripe`, `trakt.tv`, `Tumblr`, `Twitch`, `Twitter`, `VK`, `Wordpress`, `Windows Live`,\nand `Yahoo`.\n\nIt also supports any compliant `OAuth 1.0a` and `OAuth 2.0` based login services with a simple\nconfiguration object.\n\n[**Providers Documentation**](https://hapi.dev/family/bell/providers)\n", - "example": "", - "usage": "### Usage\n\n**bell** works by adding a login endpoint and setting it to use a **bell**-based authentication strategy. **bell** will manage the third-party authentication flow and will only call the handler if the user successfully authenticated. The handler function is then used to examine the third-party credentials (e.g. lookup an existing account or offer a registration page), setup an active session, and redirect to the actual application.\n\n**bell** does not maintain a session beyond a temporary state between the authorization flow. If a user authenticated once when accessing the endpoint, they will have to authenticate again. This means **bell** cannot be used alone as a login system except for single-page applications that require loading a single resource. Once the handler is called, the application must set its own\nsession management. A common solution is to combine **bell** with the [**@hapi/cookie**](https://hapi.dev/family/cookie) authentication scheme plugin.\n\n```js\n// Load modules\n\nconst Bell = require('@hapi/bell');\nconst Hapi = require('@hapi/hapi');\n\n\n// Declare internals\n\nconst internals = {};\n\n\ninternals.start = async function () {\n\n const server = Hapi.server({ port: 8000 });\n\n // Register bell with the server\n\n await server.register(Bell);\n\n // Declare an authentication strategy using the bell scheme\n // with the name of the provider, cookie encryption password,\n // and the OAuth client credentials.\n\n server.auth.strategy('twitter', 'bell', {\n provider: 'twitter',\n password: 'cookie_encryption_password_secure',\n clientId: 'my_twitter_client_id',\n clientSecret: 'my_twitter_client_secret',\n isSecure: false // Terrible idea but required if not using HTTPS especially if developing locally\n });\n\n // Use the 'twitter' authentication strategy to protect the\n // endpoint handling the incoming authentication credentials.\n // This endpoints usually looks up the third party account in\n // the database and sets some application state (cookie) with\n // the local application account information.\n\n server.route({\n method: ['GET', 'POST'], // Must handle both GET and POST\n path: '/login', // The callback endpoint registered with the provider\n options: {\n auth: {\n mode: 'try',\n strategy: 'twitter'\n },\n handler: function (request, h) {\n\n if (!request.auth.isAuthenticated) {\n return `Authentication failed due to: ${request.auth.error.message}`;\n }\n\n // Perform any account lookup or registration, setup local session,\n // and redirect to the application. The third-party credentials are\n // stored in request.auth.credentials. Any query parameters from\n // the initial request are passed back via request.auth.credentials.query.\n\n return h.redirect('/home');\n }\n }\n });\n\n await server.start();\n};\n\ninternals.start();\n```\n\n", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "12.3.0": { - "menu": "- [Introduction](#introduction)\n- [Tutorials](#tutorials)\n- [Examples](#examples)\n- [Notes](#notes)\n- [Usage](#usage)\n- [Options](#options)\n- [Authentication information](#authentication-information)\n - [Always present](#always-present)\n - [Present on successful authentication](#present-on-successful-authentication)\n - [OAuth protocol](#oauth-protocol)\n - [OAuth2 protocol](#oauth2-protocol)\n - [Present on failed authentication ()](#present-on-failed-authentication-routeauthmodetry)\n- [Advanced Usage](#advanced-usage)\n - [Configuration via Environment Variables](#configuration-via-environment-variables)\n - [Handling Errors](#handling-errors)\n - [Token Refresh](#token-refresh)\n - [Simulated authentication](#simulated-authentication)\n- [Usage without a strategy](#usage-without-a-strategy)\n- [Customized Scope and Params](#customized-scope-and-params)", - "api": "

    Introduction

    \n

    bell ships with built-in support for authentication using ArcGIS Online, Auth0, AzureAD,\nBitBucket, Cognito, DigitalOcean, Discord, Dropbox, Facebook, Fitbit, Foursquare,\nGitHub, GitLab, Google Plus, Google, Instagram, LinkedIn, Medium, Meetup, Mixer,\nNest, Office365, Okta, Phabricator, Pingfed, Pinterest, Reddit, Salesforce, Slack,\nSpotify, Stripe, trakt.tv, Tumblr, Twitch, Twitter, VK, Wordpress, Windows Live,\nand Yahoo.

    \n

    It also supports any compliant OAuth 1.0a and OAuth 2.0 based login services with a simple\nconfiguration object.

    \n

    Providers Documentation

    \n

    Tutorials

    \n

    Social Login with Twitter using hapi.js

    \n

    Examples

    \n

    All Examples

    \n

    Twitter:

    \n
    // Load modules\n\nconst Bell = require('@hapi/bell');\nconst Hapi = require('@hapi/hapi');\n\n\n// Declare internals\n\nconst internals = {};\n\n\ninternals.start = async function () {\n\n    const server = Hapi.server({ port: 8000 });\n\n    // Register bell with the server\n\n    await server.register(Bell);\n\n    // Declare an authentication strategy using the bell scheme\n    // with the name of the provider, cookie encryption password,\n    // and the OAuth client credentials.\n\n    server.auth.strategy('twitter', 'bell', {\n        provider: 'twitter',\n        password: 'cookie_encryption_password_secure',\n        clientId: 'my_twitter_client_id',\n        clientSecret: 'my_twitter_client_secret',\n        isSecure: false     // Terrible idea but required if not using HTTPS especially if developing locally\n    });\n\n    // Use the 'twitter' authentication strategy to protect the\n    // endpoint handling the incoming authentication credentials.\n    // This endpoint usually looks up the third party account in\n    // the database and sets some application state (cookie) with\n    // the local application account information.\n\n    server.route({\n        method: ['GET', 'POST'],    // Must handle both GET and POST\n        path: '/login',             // The callback endpoint registered with the provider\n        options: {\n            auth: {\n              mode: 'try',\n              strategy: 'twitter'\n            },\n            handler: function (request, h) {\n\n                if (!request.auth.isAuthenticated) {\n                    return `Authentication failed due to: ${request.auth.error.message}`;\n                }\n\n                // Perform any account lookup or registration, setup local session,\n                // and redirect to the application. The third-party credentials are\n                // stored in request.auth.credentials. Any query parameters from\n                // the initial request are passed back via request.auth.credentials.query.\n\n                return h.redirect('/home');\n            }\n        }\n    });\n\n    await server.start();\n};\n\ninternals.start();
    \n

    Notes

    \n

    Testing third-party authorization is often a painful process. They are hard to test, tidious to configure, and tend to break when running on local servers. If you are having issues running bell locally, you might want to look at the isSecure and isSameSite options. Since most people don't run TLS on their local test server, isSecure must be set to false to remove the TLS requirement. isSameSite might need to be set to 'Lax' in some cases.

    \n

    You should also review the default scope set for each provider early in your implementation. The default scope is meant to get the minimal permissions needed to perform simple user login. In most cases, you would want to ask for more permissions as the default often does not provide access to most API calls provided by the third-party services.

    \n

    Usage

    \n

    bell works by adding a login endpoint and setting it to use a bell-based authentication strategy. bell will manage the third-party authentication flow and will only call the handler if the user successfully authenticated. The handler function is then used to examine the third-party credentials (e.g. lookup an existing account or offer a registration page), setup an active session, and redirect to the actual application.

    \n

    bell does not maintain a session beyond a temporary state between the authorization flow. If a user authenticated once when accessing the endpoint, they will have to authenticate again. This means bell cannot be used alone as a login system except for single-page applications that require loading a single resource. Once the handler is called, the application must set its own\nsession management. A common solution is to combine bell with the @hapi/cookie authentication scheme plugin.

    \n
    // Load modules\n\nconst Bell = require('@hapi/bell');\nconst Hapi = require('@hapi/hapi');\n\n\n// Declare internals\n\nconst internals = {};\n\n\ninternals.start = async function () {\n\n    const server = Hapi.server({ port: 8000 });\n\n    // Register bell with the server\n\n    await server.register(Bell);\n\n    // Declare an authentication strategy using the bell scheme\n    // with the name of the provider, cookie encryption password,\n    // and the OAuth client credentials.\n\n    server.auth.strategy('twitter', 'bell', {\n        provider: 'twitter',\n        password: 'cookie_encryption_password_secure',\n        clientId: 'my_twitter_client_id',\n        clientSecret: 'my_twitter_client_secret',\n        isSecure: false     // Terrible idea but required if not using HTTPS especially if developing locally\n    });\n\n    // Use the 'twitter' authentication strategy to protect the\n    // endpoint handling the incoming authentication credentials.\n    // This endpoints usually looks up the third party account in\n    // the database and sets some application state (cookie) with\n    // the local application account information.\n\n    server.route({\n        method: ['GET', 'POST'],    // Must handle both GET and POST\n        path: '/login',             // The callback endpoint registered with the provider\n        options: {\n            auth: {\n              mode: 'try',\n              strategy: 'twitter'\n            },\n            handler: function (request, h) {\n\n                if (!request.auth.isAuthenticated) {\n                    return `Authentication failed due to: ${request.auth.error.message}`;\n                }\n\n                // Perform any account lookup or registration, setup local session,\n                // and redirect to the application. The third-party credentials are\n                // stored in request.auth.credentials. Any query parameters from\n                // the initial request are passed back via request.auth.credentials.query.\n\n                return h.redirect('/home');\n            }\n        }\n    });\n\n    await server.start();\n};\n\ninternals.start();
    \n

    Options

    \n

    The server.auth.strategy() method requires the following strategy options:

    \n
      \n
    • \n

      provider - the name of the third-party provider ('auth0', 'azure', 'bitbucket',\n'dropbox', 'facebook', 'fitbit', 'foursquare', 'github', 'google', 'googleplus',\n'instagram', 'linkedin', 'live', 'twitter', 'vk', 'arcgisonline', 'yahoo',\n'nest', 'phabricator', 'pinterest') or an object containing a custom\nprovider with the following:

      \n
        \n
      • \nname - the custom provider name. Defaults to custom.
      • \n
      • \nprotocol - the authorization protocol used. Must be one of:\n
          \n
        • \n'oauth' - OAuth 1.0a
        • \n
        • \n'oauth2' - OAuth 2.0
        • \n
        \n
      • \n
      • \nsignatureMethod - the OAuth signature method (OAuth 1.0a only). Must be one of:\n
          \n
        • \n'HMAC-SHA1' - default
        • \n
        • \n'RSA-SHA1' - in that case, the clientSecret is your RSA private key
        • \n
        \n
      • \n
      • \ntemporary - the temporary credentials (request token) endpoint (OAuth 1.0a only).
      • \n
      • \nuseParamsAuth - boolean that determines if OAuth client id and client secret will be sent\nas parameters as opposed to an Authorization header (OAuth 2.0 only). Defaults to false.
      • \n
      • \nauth - the authorization endpoint URI.
      • \n
      • \ntoken - the access token endpoint URI.
      • \n
      • \nscope - an array of scope strings (OAuth 2.0 only).
      • \n
      • \nscopeSeparator - the scope separator character (OAuth 2.0 only). Only required when a\nprovider has a broken OAuth 2.0 implementation. Defaults to space (Facebook and GitHub\ndefault to comma).
      • \n
      • \nheaders - a headers object with additional headers required by the provider (e.g. GitHub\nrequired the 'User-Agent' header which is set by default).
      • \n
      • \nprofileMethod - get or post for obtaining user profile by profile function. Default\nis get.
      • \n
      • \nprofile - a function used to obtain user profile information and normalize it. The function\nsignature is async function(credentials, params, get) where:\n
          \n
        • \ncredentials - the credentials object. Change the object directly within the function\n(profile information is typically stored under credentials.profile).
        • \n
        • \nparams - the parsed information received from the provider (e.g. token, secret, and\nother custom fields).
        • \n
        • \nget - an OAuth helper function to make authenticated requests using the credentials\nreceived. The get function signature is async function(uri, params) where:\n
            \n
          • \nuri - the requested resource URI (bell will add the token or authentication\nheader as needed).
          • \n
          • \nparams - any URI query parameters (cannot include them in the URI due to signature\nrequirements).
          • \n
          • returns the parsed profile response object.
          • \n
          \n
        • \n
        \n
      • \n
      \n
    • \n
    • \n

      password - the cookie encryption password. Used to encrypt the temporary state cookie used by\nthe module in between the authorization protocol steps.

      \n
    • \n
    • \n

      clientId - the OAuth client identifier (consumer key).

      \n
    • \n
    • \n

      clientSecret - the OAuth client secret (consumer secret). This is usually a client password\nformatted as a string, but to allow OAuth2 custom client authentication\n(e.g. client certificate-based authentication), this option can be passed as an object. This\nobject will be merged with the Wreck request object used to call the token endpoint. Such an\nobject can contain custom HTTP headers or TLS options (e.g.\n{ agent: new Https.Agent({ cert: myClientCert, key: myClientKey}) }).\nTo allow dynamically updating secret, this option can be passed as a function returning string\nto be used as clientSecret.

      \n
    • \n
    • \n

      forceHttps - A boolean indicating whether or not you want the redirect_uri to be forced to\nhttps. Useful if your hapi application runs as http, but is accessed through https.

      \n
    • \n
    • \n

      location - Set the base redirect_uri manually if it cannot be inferred properly from server\nsettings. Useful to override port, protocol, and host if proxied or forwarded. It may be passed\neither as a string (in which case request.path is appended for you), or a function which takes\nthe client's request and returns a non-empty string, which is used as provided. In both cases,\nan empty string will result in default processing just as if the location option had not been\nspecified.

      \n
    • \n
    \n

    Each strategy accepts the following optional settings:

    \n
      \n
    • \ncookie - the name of the cookie used to manage the temporary state. Defaults to\n'bell-provider' where 'provider' is the provider name. For\nexample, the Twitter cookie name defaults to 'bell-twitter'.
    • \n
    • \nisSameSite - sets the cookie same site option. Defaults to Strict.
    • \n
    • \nisSecure - sets the cookie secure flag. Defaults to true.
    • \n
    • \nisHttpOnly - sets the cookie HTTP only flag. Defaults to true.
    • \n
    • \nttl - cookie time-to-live in milliseconds. Defaults to null (session time-life - cookies are\ndeleted when the browser is closed).
    • \n
    • \ndomain - the domain scope. Defaults to null (no domain).
    • \n
    • \nproviderParams - provider-specific query parameters for the authentication endpoint. It may be\npassed either as an object to merge into the query string, or a function which takes the client's\nrequest and returns an object. Each provider supports its own set of parameters which customize\nthe user's login experience. For example:\n
        \n
      • Facebook supports display ('page', 'popup', or 'touch'), auth_type, auth_nonce.
      • \n
      • Google supports access_type, approval_prompt, prompt, login_hint, user_id, hd.
      • \n
      • Twitter supports force_login, screen_name.
      • \n
      • Linkedin supports fields.
      • \n
      \n
    • \n
    • \nallowRuntimeProviderParams - allows passing query parameters from a bell protected endpoint\nto the auth request. It will merge the query params you pass along with the providerParams and\nany other predefined ones. Be aware that this will override predefined query parameters! Default\nto false.
    • \n
    • \nscope - Each built-in vendor comes with the required scope for basic profile information. Use\nscope to specify a different scope as required by your application. It may be passed either as\nan object to merge into the query string, or a function which takes the client's request and\nreturns an object. Consult the provider for their specific supported scopes.
    • \n
    • \nskipProfile - skips obtaining a user profile from the provider. Useful if you need specific\nscopes, but not the user profile. Defaults to false.
    • \n
    • \nconfig - a configuration object used to customize the provider settings:\n
        \n
      • Twitter:\n
          \n
        • extendedProfile
        • \n
        • getMethod
        • \n
        \n
      • \n
      • GitHub and Phabricator:\n
          \n
        • \nuri - allows pointing to a private enterprise installation (e.g.\n'https://vpn.example.com'). See Providers documentation for more\ninformation.
        • \n
        \n
      • \n
      \n
    • \n
    • \nprofileParams - an object of key-value pairs that specify additional URL query parameters to\nsend with the profile request to the provider. The built-in facebook provider, for example,\ncould have fields specified to determine the fields returned from the user's graph, which would\nthen be available to you in the auth.credentials.profile.raw object.
    • \n
    • \nruntimeStateCallback - allows passing additional OAuth state from initial request. This must be\na function returning a string, which will be appended to the bell internal state parameter\nfor OAuth code flow.
    • \n
    \n

    Authentication information

    \n

    On route handlers, the authentication object may contain one or more of the following properties depending on your route configuration and whether the authentication process was completed successfully or not:

    \n

    Always present

    \n
    auth.credentials = {\n  provider: String, // provider name\n};
    \n

    Present on successful authentication

    \n
    OAuth protocol
    \n
    auth.credentials = {\n  token: String,\n  secret: String,\n  query: Object // sign-in request query params\n};
    \n
    OAuth2 protocol
    \n
    auth.credentials = {\n  token: String,\n  refreshToken: String,\n  expiresIn: Number,\n  query: Object // sign-in request query params\n};\n\nauth.artifacts = Object; // OAuth token payload response
    \n
    Present on failed authentication (route.auth.mode=try)
    \n
    auth.credentials = {\n  query: Object // sign-in request query params\n};
    \n

    Advanced Usage

    \n

    Configuration via Environment Variables

    \n

    The server.auth.strategy() method supports string representations of its boolean and number typed\noptions. For example, forceHttps can be set to 'true', 'false', 'yes', or 'no'. In effect, this\nallows you to configure any strategy option using environment variables.

    \n

    Handling Errors

    \n

    By default, bell will reply back with an internal error (500) on most authentication errors due\nto the nature of the OAuth protocol. There is little that can be done to recover from errors as\nalmost all of them are caused by implementation or deployment issues.

    \n

    If you would like to display a useful error page instead of the default JSON response, use the\nhapi onPreResponse extension point to transform\nthe error into a useful page or to redirect the user to another destination.

    \n

    Another way to handle authentication errors is within the route handler. By default, an\nauthentication error will cause the handler to be skipped. However, if the authentication mode is\nset to 'try' instead of 'required', the handler will still be called. In this case, the\nrequest.auth.isAuthenticated must be checked to test if authentication failed. In that case,\nrequest.auth.error will contain the error.

    \n

    Token Refresh

    \n

    To keep track of the token expiry time, request.auth.credentials.expiresIn provides you the\nduration (in seconds) after which you could send a refresh token request using the\nrequest.auth.credentials.refreshToken to get a new token.

    \n

    Simulated authentication

    \n

    Testing applications using third-party login can be challenging given the lack of user interaction\nto perform the third-party login flow as well as the multiple steps required. To assist in testing\nsuch application without having to modify the application with custom code, Bell provides an\noverride method Bell.simulate() which puts the module into simulation mode and any strategies\ncreated while it is in this mode will return the simulated credentials.

    \n

    The Bell.simulate(credentialsFunc) takes a single argument:

    \n
      \n
    • \n

      credentialsFunc - a function called for each incoming request to the protected resource that\nshould return the credentials object to be set in request.auth.credentials. Note that bell\nwill set the default keys automatically if not present except for the provider-specific values.

      \n

      has the signature function(request) where:

      \n
        \n
      • \nrequest - the hapi request object.
      • \n
      \n
    • \n
    \n

    Note that you must call Bell.simulate() before the module is registered by your application and\nneed to call Bell.simulate(false) to stop it from simulating authentication.

    \n

    Usage without a strategy

    \n

    Sometimes, you want to use bell without using specifying a Hapi strategy. This can be the case when\ncombining the auth logic together with another module.

    \n

    bell exposes an oauth object in its plugin. Therefore, server.plugins.bell.oauth now has all\nthat's needed. For example, calling the v2 method with all the settings documented above, will\nhandle the oauth2 flow.

    \n

    Customized Scope and Params

    \n

    You can pass a function, rather than an object, into the providerParams and scope config\noptions to allow you to customize the scope or parameters based on the user's request. For example,\nthis may be used you want people to be able to log in with a provider (and only need some basic\nuser information) but also want to let users authorize your application to post messages or status\nupdates on their behalf.

    \n
    server.auth.strategy('twitter', 'bell', {\n    provider: 'twitter',\n    password: 'some cookie password',\n    location: 'http://example.com/oauth',\n    scope(request) {\n\n        const scopes = ['public_profile', 'email'];\n        if (request.query.wantsSharePermission) {\n          scopes.push('publish_actions');\n        }\n        return scopes;\n    }\n});
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Third-party login plugin for hapi.js.", - "forks": 210, - "stars": 623, - "date": "2024-10-23T15:36:25Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/bell" - }, - "boom": { - "name": "boom", - "versions": [ - { - "name": "10.0.1", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "9.1.4", - "branch": "v9", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "10.0.1", - "9.1.4" - ], - "api": true, - "isPlugin": false, - "10.0.1": { - "menu": "- [`reformat()`](#reformatdebug)\n- [Helper Methods](#helper-methods)\n - [`new Boom()`](#new-boomboommessage-options)\n - [`boomify()`](#boomifyerr-options)\n - [`isBoom()`](#isboomerr-statuscode)\n- [HTTP 4xx Errors](#http-4xx-errors)\n - [`badRequest()`](#boombadrequestmessage-data)\n - [`unauthorized()`](#boomunauthorizedmessage-scheme-attributes)\n - [`paymentRequired()`](#boompaymentrequiredmessage-data)\n - [`forbidden()`](#boomforbiddenmessage-data)\n - [`notFound()`](#boomnotfoundmessage-data)\n - [`methodNotAllowed()`](#boommethodnotallowedmessage-data-allow)\n - [`notAcceptable()`](#boomnotacceptablemessage-data)\n - [`proxyAuthRequired()`](#boomproxyauthrequiredmessage-data)\n - [`clientTimeout()`](#boomclienttimeoutmessage-data)\n - [`conflict()`](#boomconflictmessage-data)\n - [`resourceGone()`](#boomresourcegonemessage-data)\n - [`lengthRequired()`](#boomlengthrequiredmessage-data)\n - [`preconditionFailed()`](#boompreconditionfailedmessage-data)\n - [`entityTooLarge()`](#boomentitytoolargemessage-data)\n - [`uriTooLong()`](#boomuritoolongmessage-data)\n - [`unsupportedMediaType()`](#boomunsupportedmediatypemessage-data)\n - [`rangeNotSatisfiable()`](#boomrangenotsatisfiablemessage-data)\n - [`expectationFailed()`](#boomexpectationfailedmessage-data)\n - [`teapot()`](#boomteapotmessage-data)\n - [`badData()`](#boombaddatamessage-data)\n - [`locked()`](#boomlockedmessage-data)\n - [`failedDependency()`](#boomfaileddependencymessage-data)\n - [`tooEarly()`](#boomtooearlymessage-data)\n - [`preconditionRequired()`](#boompreconditionrequiredmessage-data)\n - [`tooManyRequests()`](#boomtoomanyrequestsmessage-data)\n - [`illegal()`](#boomillegalmessage-data)\n- [HTTP 5xx Errors](#http-5xx-errors)\n - [`badImplementation()` - (*alias: `internal`*)](#boombadimplementationmessage-data---alias-internal)\n - [`notImplemented()`](#boomnotimplementedmessage-data)\n - [`badGateway()`](#boombadgatewaymessage-data)\n - [`serverUnavailable()`](#boomserverunavailablemessage-data)\n - [`gatewayTimeout()`](#boomgatewaytimeoutmessage-data)", - "api": "

    boom provides a set of utilities for returning HTTP errors. Each utility returns a Boom\nerror response object which includes the following properties:

    \n
      \n
    • \nisBoom - if true, indicates this is a Boom object instance. Note that this boolean should\nonly be used if the error is an instance of Error. If it is not certain, use Boom.isBoom()\ninstead.
    • \n
    • \nisServer - convenience bool indicating status code >= 500.
    • \n
    • \nmessage - the error message.
    • \n
    • \ntypeof - the constructor used to create the error (e.g. Boom.badRequest).
    • \n
    • \noutput - the formatted response. Can be directly manipulated after object construction to return a custom\nerror response. Allowed root keys:\n
        \n
      • \nstatusCode - the HTTP status code (typically 4xx or 5xx).
      • \n
      • \nheaders - an object containing any HTTP headers where each key is a header name and value is the header content.
      • \n
      • \npayload - the formatted object used as the response payload (stringified). Can be directly manipulated but any\nchanges will be lost\nif reformat() is called. Any content allowed and by default includes the following content:\n
          \n
        • \nstatusCode - the HTTP status code, derived from error.output.statusCode.
        • \n
        • \nerror - the HTTP status message (e.g. 'Bad Request', 'Internal Server Error') derived from statusCode.
        • \n
        • \nmessage - the error message derived from error.message.
        • \n
        \n
      • \n
      \n
    • \n
    • inherited Error properties.
    • \n
    \n

    The Boom object also supports the following method:

    \n

    reformat(debug)

    \n

    Rebuilds error.output using the other object properties where:

    \n
      \n
    • \ndebug - a Boolean that, when true, causes Internal Server Error messages to be left in tact. Defaults to false, meaning that Internal Server Error messages are redacted.
    • \n
    \n

    Note that Boom object will return true when used with instanceof Boom, but do not use the\nBoom prototype (they are either plain Error or the error prototype passed in). This means\nBoom objects should only be tested using instanceof Boom or Boom.isBoom() but not by looking\nat the prototype or contructor information. This limitation is to avoid manipulating the prototype\nchain which is very slow.

    \n

    Helper Methods

    \n
    new Boom.Boom(message, [options])
    \n

    Creates a new Boom object using the provided message and then calling\nboomify() to decorate the error with the Boom properties, where:

    \n
      \n
    • \nmessage - the error message. If message is an error, it is the same as calling\nboomify() directly.
    • \n
    • \noptions - and optional object where:\n
        \n
      • \nstatusCode - the HTTP status code. Defaults to 500 if no status code is already set.
      • \n
      • \ndata - additional error information (assigned to error.data).
      • \n
      • \ndecorate - an option with extra properties to set on the error object.
      • \n
      • \nctor - constructor reference used to crop the exception call stack output.
      • \n
      • if message is an error object, also supports the other boomify()\noptions.
      • \n
      \n
    • \n
    \n
    boomify(err, [options])
    \n

    Decorates an error with the Boom properties where:

    \n
      \n
    • \nerr - the Error object to decorate.
    • \n
    • \noptions - optional object with the following optional settings:\n
        \n
      • \nstatusCode - the HTTP status code. Defaults to 500 if no status code is already set and err is not a Boom object.
      • \n
      • \nmessage - error message string. If the error already has a message, the provided message is added as a prefix.\nDefaults to no message.
      • \n
      • \ndecorate - an option with extra properties to set on the error object.
      • \n
      • \noverride - if false, the err provided is a Boom object, and a statusCode or message are provided,\nthe values are ignored. Defaults to true (apply the provided statusCode and message options to the error\nregardless of its type, Error or Boom object).
      • \n
      \n
    • \n
    \n
    var error = new Error('Unexpected input');\nBoom.boomify(error, { statusCode: 400 });
    \n
    isBoom(err, [statusCode])
    \n

    Identifies whether an error is a Boom object. Same as calling instanceof Boom.Boom.

    \n
      \n
    • \nerr - Error object.
    • \n
    • \nstatusCode - optional status code.
    • \n
    \n
    Boom.isBoom(Boom.badRequest()); // true\nBoom.isBoom(Boom.badRequest(), 400); // true
    \n

    HTTP 4xx Errors

    \n
    Boom.badRequest([message], [data])
    \n

    Returns a 400 Bad Request error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.badRequest('invalid query');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 400,\n    \"error\": \"Bad Request\",\n    \"message\": \"invalid query\"\n}
    \n
    Boom.unauthorized([message], [scheme], [attributes])
    \n

    Returns a 401 Unauthorized error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \nscheme can be one of the following:\n
        \n
      • an authentication scheme name
      • \n
      • an array of string values. These values will be separated by ', ' and set to the 'WWW-Authenticate' header.
      • \n
      \n
    • \n
    • \nattributes - an object of values to use while setting the 'WWW-Authenticate' header. This value is only used\nwhen scheme is a string, otherwise it is ignored. Every key/value pair will be included in the\n'WWW-Authenticate' in the format of 'key=\"value\"' as well as in the response payload under the attributes key. Alternatively value can be a string which is use to set the value of the scheme, for example setting the token value for negotiate header. If string is used message parameter must be null.\nnull and undefined will be replaced with an empty string. If attributes is set, message will be used as\nthe 'error' segment of the 'WWW-Authenticate' header. If message is unset, the 'error' segment of the header\nwill not be present and isMissing will be true on the error object.
    • \n
    \n

    If either scheme or attributes are set, the resultant Boom object will have the\n'WWW-Authenticate' header set for the response.

    \n
    Boom.unauthorized('invalid password');
    \n

    Generates the following response:

    \n
    \"payload\": {\n    \"statusCode\": 401,\n    \"error\": \"Unauthorized\",\n    \"message\": \"invalid password\"\n},\n\"headers\": {}
    \n
    Boom.unauthorized('invalid password', 'sample');
    \n

    Generates the following response:

    \n
    \"payload\": {\n    \"statusCode\": 401,\n    \"error\": \"Unauthorized\",\n    \"message\": \"invalid password\",\n    \"attributes\": {\n        \"error\": \"invalid password\"\n    }\n},\n\"headers\": {\n  \"WWW-Authenticate\": \"sample error=\\\"invalid password\\\"\"\n}
    \n
    Boom.unauthorized(null, 'Negotiate', 'VGhpcyBpcyBhIHRlc3QgdG9rZW4=');
    \n

    Generates the following response:

    \n
    \"payload\": {\n    \"statusCode\": 401,\n    \"error\": \"Unauthorized\",\n    \"attributes\": \"VGhpcyBpcyBhIHRlc3QgdG9rZW4=\"\n},\n\"headers\": {\n  \"WWW-Authenticate\": \"Negotiate VGhpcyBpcyBhIHRlc3QgdG9rZW4=\"\n}
    \n
    Boom.unauthorized('invalid password', 'sample', { ttl: 0, cache: null, foo: 'bar' });
    \n

    Generates the following response:

    \n
    \"payload\": {\n    \"statusCode\": 401,\n    \"error\": \"Unauthorized\",\n    \"message\": \"invalid password\",\n    \"attributes\": {\n        \"error\": \"invalid password\",\n        \"ttl\": 0,\n        \"cache\": \"\",\n        \"foo\": \"bar\"\n    }\n},\n\"headers\": {\n  \"WWW-Authenticate\": \"sample ttl=\\\"0\\\", cache=\\\"\\\", foo=\\\"bar\\\", error=\\\"invalid password\\\"\"\n}
    \n
    Boom.paymentRequired([message], [data])
    \n

    Returns a 402 Payment Required error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.paymentRequired('bandwidth used');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 402,\n    \"error\": \"Payment Required\",\n    \"message\": \"bandwidth used\"\n}
    \n
    Boom.forbidden([message], [data])
    \n

    Returns a 403 Forbidden error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.forbidden('try again some time');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 403,\n    \"error\": \"Forbidden\",\n    \"message\": \"try again some time\"\n}
    \n
    Boom.notFound([message], [data])
    \n

    Returns a 404 Not Found error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.notFound('missing');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 404,\n    \"error\": \"Not Found\",\n    \"message\": \"missing\"\n}
    \n
    Boom.methodNotAllowed([message], [data], [allow])
    \n

    Returns a 405 Method Not Allowed error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    • \nallow - optional string or array of strings (to be combined and separated by ', ') which is set to the 'Allow' header.
    • \n
    \n
    Boom.methodNotAllowed('that method is not allowed');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 405,\n    \"error\": \"Method Not Allowed\",\n    \"message\": \"that method is not allowed\"\n}
    \n
    Boom.notAcceptable([message], [data])
    \n

    Returns a 406 Not Acceptable error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.notAcceptable('unacceptable');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 406,\n    \"error\": \"Not Acceptable\",\n    \"message\": \"unacceptable\"\n}
    \n
    Boom.proxyAuthRequired([message], [data])
    \n

    Returns a 407 Proxy Authentication Required error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.proxyAuthRequired('auth missing');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 407,\n    \"error\": \"Proxy Authentication Required\",\n    \"message\": \"auth missing\"\n}
    \n
    Boom.clientTimeout([message], [data])
    \n

    Returns a 408 Request Time-out error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.clientTimeout('timed out');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 408,\n    \"error\": \"Request Time-out\",\n    \"message\": \"timed out\"\n}
    \n
    Boom.conflict([message], [data])
    \n

    Returns a 409 Conflict error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.conflict('there was a conflict');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 409,\n    \"error\": \"Conflict\",\n    \"message\": \"there was a conflict\"\n}
    \n
    Boom.resourceGone([message], [data])
    \n

    Returns a 410 Gone error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.resourceGone('it is gone');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 410,\n    \"error\": \"Gone\",\n    \"message\": \"it is gone\"\n}
    \n
    Boom.lengthRequired([message], [data])
    \n

    Returns a 411 Length Required error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.lengthRequired('length needed');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 411,\n    \"error\": \"Length Required\",\n    \"message\": \"length needed\"\n}
    \n
    Boom.preconditionFailed([message], [data])
    \n

    Returns a 412 Precondition Failed error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.preconditionFailed();
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 412,\n    \"error\": \"Precondition Failed\"\n}
    \n
    Boom.entityTooLarge([message], [data])
    \n

    Returns a 413 Request Entity Too Large error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.entityTooLarge('too big');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 413,\n    \"error\": \"Request Entity Too Large\",\n    \"message\": \"too big\"\n}
    \n
    Boom.uriTooLong([message], [data])
    \n

    Returns a 414 Request-URI Too Large error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.uriTooLong('uri is too long');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 414,\n    \"error\": \"Request-URI Too Large\",\n    \"message\": \"uri is too long\"\n}
    \n
    Boom.unsupportedMediaType([message], [data])
    \n

    Returns a 415 Unsupported Media Type error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.unsupportedMediaType('that media is not supported');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 415,\n    \"error\": \"Unsupported Media Type\",\n    \"message\": \"that media is not supported\"\n}
    \n
    Boom.rangeNotSatisfiable([message], [data])
    \n

    Returns a 416 Requested Range Not Satisfiable error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.rangeNotSatisfiable();
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 416,\n    \"error\": \"Requested Range Not Satisfiable\"\n}
    \n
    Boom.expectationFailed([message], [data])
    \n

    Returns a 417 Expectation Failed error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.expectationFailed('expected this to work');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 417,\n    \"error\": \"Expectation Failed\",\n    \"message\": \"expected this to work\"\n}
    \n
    Boom.teapot([message], [data])
    \n

    Returns a 418 I'm a Teapot error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.teapot('sorry, no coffee...');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 418,\n    \"error\": \"I'm a Teapot\",\n    \"message\": \"Sorry, no coffee...\"\n}
    \n
    Boom.badData([message], [data])
    \n

    Returns a 422 Unprocessable Entity error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.badData('your data is bad and you should feel bad');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 422,\n    \"error\": \"Unprocessable Entity\",\n    \"message\": \"your data is bad and you should feel bad\"\n}
    \n
    Boom.locked([message], [data])
    \n

    Returns a 423 Locked error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.locked('this resource has been locked');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 423,\n    \"error\": \"Locked\",\n    \"message\": \"this resource has been locked\"\n}
    \n
    Boom.failedDependency([message], [data])
    \n

    Returns a 424 Failed Dependency error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.failedDependency('an external resource failed');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 424,\n    \"error\": \"Failed Dependency\",\n    \"message\": \"an external resource failed\"\n}
    \n
    Boom.tooEarly([message], [data])
    \n

    Returns a 425 Too Early error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.tooEarly('the server is unwilling to risk processing the request');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 425,\n    \"error\": \"Too Early\",\n    \"message\": \"the server is unwilling to risk processing the request\"\n}
    \n
    Boom.preconditionRequired([message], [data])
    \n

    Returns a 428 Precondition Required error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.preconditionRequired('you must supply an If-Match header');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 428,\n    \"error\": \"Precondition Required\",\n    \"message\": \"you must supply an If-Match header\"\n}
    \n
    Boom.tooManyRequests([message], [data])
    \n

    Returns a 429 Too Many Requests error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.tooManyRequests('you have exceeded your request limit');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 429,\n    \"error\": \"Too Many Requests\",\n    \"message\": \"you have exceeded your request limit\"\n}
    \n
    Boom.illegal([message], [data])
    \n

    Returns a 451 Unavailable For Legal Reasons error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.illegal('you are not permitted to view this resource for legal reasons');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 451,\n    \"error\": \"Unavailable For Legal Reasons\",\n    \"message\": \"you are not permitted to view this resource for legal reasons\"\n}
    \n

    HTTP 5xx Errors

    \n

    All 500 errors hide your message from the end user.

    \n
    \nBoom.badImplementation([message], [data]) - (alias: internal)
    \n

    Returns a 500 Internal Server Error error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.badImplementation('terrible implementation');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 500,\n    \"error\": \"Internal Server Error\",\n    \"message\": \"An internal server error occurred\"\n}
    \n
    Boom.notImplemented([message], [data])
    \n

    Returns a 501 Not Implemented error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.notImplemented('method not implemented');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 501,\n    \"error\": \"Not Implemented\",\n    \"message\": \"method not implemented\"\n}
    \n
    Boom.badGateway([message], [data])
    \n

    Returns a 502 Bad Gateway error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.badGateway('that is a bad gateway');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 502,\n    \"error\": \"Bad Gateway\",\n    \"message\": \"that is a bad gateway\"\n}
    \n
    Boom.serverUnavailable([message], [data])
    \n

    Returns a 503 Service Unavailable error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.serverUnavailable('unavailable');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 503,\n    \"error\": \"Service Unavailable\",\n    \"message\": \"unavailable\"\n}
    \n
    Boom.gatewayTimeout([message], [data])
    \n

    Returns a 504 Gateway Time-out error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.gatewayTimeout();
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 504,\n    \"error\": \"Gateway Time-out\"\n}
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "#### F.A.Q.\n\n**Q** How do I include extra information in my responses? `output.payload` is missing `data`, what gives?\n\n**A** There is a reason the values passed back in the response payloads are pretty locked down. It's mostly for security and to not leak any important information back to the client. This means you will need to put in a little more effort to include extra information about your custom error. Check out the [\"Error transformation\"](https://github.com/hapijs/hapi/blob/master/API.md#error-transformation) section in the hapi documentation.", - "advanced": "", - "license": "BSD" - }, - "9.1.4": { - "menu": "- [`reformat()`](#reformatdebug)\n- [Helper Methods](#helper-methods)\n - [`new Boom()`](#new-boomboommessage-options)\n - [`boomify()`](#boomifyerr-options)\n - [`isBoom()`](#isboomerr-statuscode)\n- [HTTP 4xx Errors](#http-4xx-errors)\n - [`badRequest()`](#boombadrequestmessage-data)\n - [`unauthorized()`](#boomunauthorizedmessage-scheme-attributes)\n - [`paymentRequired()`](#boompaymentrequiredmessage-data)\n - [`forbidden()`](#boomforbiddenmessage-data)\n - [`notFound()`](#boomnotfoundmessage-data)\n - [`methodNotAllowed()`](#boommethodnotallowedmessage-data-allow)\n - [`notAcceptable()`](#boomnotacceptablemessage-data)\n - [`proxyAuthRequired()`](#boomproxyauthrequiredmessage-data)\n - [`clientTimeout()`](#boomclienttimeoutmessage-data)\n - [`conflict()`](#boomconflictmessage-data)\n - [`resourceGone()`](#boomresourcegonemessage-data)\n - [`lengthRequired()`](#boomlengthrequiredmessage-data)\n - [`preconditionFailed()`](#boompreconditionfailedmessage-data)\n - [`entityTooLarge()`](#boomentitytoolargemessage-data)\n - [`uriTooLong()`](#boomuritoolongmessage-data)\n - [`unsupportedMediaType()`](#boomunsupportedmediatypemessage-data)\n - [`rangeNotSatisfiable()`](#boomrangenotsatisfiablemessage-data)\n - [`expectationFailed()`](#boomexpectationfailedmessage-data)\n - [`teapot()`](#boomteapotmessage-data)\n - [`badData()`](#boombaddatamessage-data)\n - [`locked()`](#boomlockedmessage-data)\n - [`failedDependency()`](#boomfaileddependencymessage-data)\n - [`tooEarly()`](#boomtooearlymessage-data)\n - [`preconditionRequired()`](#boompreconditionrequiredmessage-data)\n - [`tooManyRequests()`](#boomtoomanyrequestsmessage-data)\n - [`illegal()`](#boomillegalmessage-data)\n- [HTTP 5xx Errors](#http-5xx-errors)\n - [`badImplementation()` - (*alias: `internal`*)](#boombadimplementationmessage-data---alias-internal)\n - [`notImplemented()`](#boomnotimplementedmessage-data)\n - [`badGateway()`](#boombadgatewaymessage-data)\n - [`serverUnavailable()`](#boomserverunavailablemessage-data)\n - [`gatewayTimeout()`](#boomgatewaytimeoutmessage-data)\n- [F.A.Q.](#faq)", - "api": "

    boom provides a set of utilities for returning HTTP errors. Each utility returns a Boom\nerror response object which includes the following properties:

    \n
      \n
    • \nisBoom - if true, indicates this is a Boom object instance. Note that this boolean should\nonly be used if the error is an instance of Error. If it is not certain, use Boom.isBoom()\ninstead.
    • \n
    • \nisServer - convenience bool indicating status code >= 500.
    • \n
    • \nmessage - the error message.
    • \n
    • \ntypeof - the constructor used to create the error (e.g. Boom.badRequest).
    • \n
    • \noutput - the formatted response. Can be directly manipulated after object construction to return a custom\nerror response. Allowed root keys:\n
        \n
      • \nstatusCode - the HTTP status code (typically 4xx or 5xx).
      • \n
      • \nheaders - an object containing any HTTP headers where each key is a header name and value is the header content.
      • \n
      • \npayload - the formatted object used as the response payload (stringified). Can be directly manipulated but any\nchanges will be lost\nif reformat() is called. Any content allowed and by default includes the following content:\n
          \n
        • \nstatusCode - the HTTP status code, derived from error.output.statusCode.
        • \n
        • \nerror - the HTTP status message (e.g. 'Bad Request', 'Internal Server Error') derived from statusCode.
        • \n
        • \nmessage - the error message derived from error.message.
        • \n
        \n
      • \n
      \n
    • \n
    • inherited Error properties.
    • \n
    \n

    The Boom object also supports the following method:

    \n

    reformat(debug)

    \n

    Rebuilds error.output using the other object properties where:

    \n
      \n
    • \ndebug - a Boolean that, when true, causes Internal Server Error messages to be left in tact. Defaults to false, meaning that Internal Server Error messages are redacted.
    • \n
    \n

    Note that Boom object will return true when used with instanceof Boom, but do not use the\nBoom prototype (they are either plain Error or the error prototype passed in). This means\nBoom objects should only be tested using instanceof Boom or Boom.isBoom() but not by looking\nat the prototype or contructor information. This limitation is to avoid manipulating the prototype\nchain which is very slow.

    \n

    Helper Methods

    \n
    new Boom.Boom(message, [options])
    \n

    Creates a new Boom object using the provided message and then calling\nboomify() to decorate the error with the Boom properties, where:

    \n
      \n
    • \nmessage - the error message. If message is an error, it is the same as calling\nboomify() directly.
    • \n
    • \noptions - and optional object where:\n
        \n
      • \nstatusCode - the HTTP status code. Defaults to 500 if no status code is already set.
      • \n
      • \ndata - additional error information (assigned to error.data).
      • \n
      • \ndecorate - an option with extra properties to set on the error object.
      • \n
      • \nctor - constructor reference used to crop the exception call stack output.
      • \n
      • if message is an error object, also supports the other boomify()\noptions.
      • \n
      \n
    • \n
    \n
    boomify(err, [options])
    \n

    Decorates an error with the Boom properties where:

    \n
      \n
    • \nerr - the Error object to decorate.
    • \n
    • \noptions - optional object with the following optional settings:\n
        \n
      • \nstatusCode - the HTTP status code. Defaults to 500 if no status code is already set and err is not a Boom object.
      • \n
      • \nmessage - error message string. If the error already has a message, the provided message is added as a prefix.\nDefaults to no message.
      • \n
      • \ndecorate - an option with extra properties to set on the error object.
      • \n
      • \noverride - if false, the err provided is a Boom object, and a statusCode or message are provided,\nthe values are ignored. Defaults to true (apply the provided statusCode and message options to the error\nregardless of its type, Error or Boom object).
      • \n
      \n
    • \n
    \n
    var error = new Error('Unexpected input');\nBoom.boomify(error, { statusCode: 400 });
    \n
    isBoom(err, [statusCode])
    \n

    Identifies whether an error is a Boom object. Same as calling instanceof Boom.Boom.

    \n
      \n
    • \nerr - Error object.
    • \n
    • \nstatusCode - optional status code.
    • \n
    \n
    Boom.isBoom(Boom.badRequest()); // true\nBoom.isBoom(Boom.badRequest(), 400); // true
    \n

    HTTP 4xx Errors

    \n
    Boom.badRequest([message], [data])
    \n

    Returns a 400 Bad Request error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.badRequest('invalid query');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 400,\n    \"error\": \"Bad Request\",\n    \"message\": \"invalid query\"\n}
    \n
    Boom.unauthorized([message], [scheme], [attributes])
    \n

    Returns a 401 Unauthorized error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \nscheme can be one of the following:\n
        \n
      • an authentication scheme name
      • \n
      • an array of string values. These values will be separated by ', ' and set to the 'WWW-Authenticate' header.
      • \n
      \n
    • \n
    • \nattributes - an object of values to use while setting the 'WWW-Authenticate' header. This value is only used\nwhen scheme is a string, otherwise it is ignored. Every key/value pair will be included in the\n'WWW-Authenticate' in the format of 'key=\"value\"' as well as in the response payload under the attributes key. Alternatively value can be a string which is use to set the value of the scheme, for example setting the token value for negotiate header. If string is used message parameter must be null.\nnull and undefined will be replaced with an empty string. If attributes is set, message will be used as\nthe 'error' segment of the 'WWW-Authenticate' header. If message is unset, the 'error' segment of the header\nwill not be present and isMissing will be true on the error object.
    • \n
    \n

    If either scheme or attributes are set, the resultant Boom object will have the\n'WWW-Authenticate' header set for the response.

    \n
    Boom.unauthorized('invalid password');
    \n

    Generates the following response:

    \n
    \"payload\": {\n    \"statusCode\": 401,\n    \"error\": \"Unauthorized\",\n    \"message\": \"invalid password\"\n},\n\"headers\": {}
    \n
    Boom.unauthorized('invalid password', 'sample');
    \n

    Generates the following response:

    \n
    \"payload\": {\n    \"statusCode\": 401,\n    \"error\": \"Unauthorized\",\n    \"message\": \"invalid password\",\n    \"attributes\": {\n        \"error\": \"invalid password\"\n    }\n},\n\"headers\": {\n  \"WWW-Authenticate\": \"sample error=\\\"invalid password\\\"\"\n}
    \n
    Boom.unauthorized(null, 'Negotiate', 'VGhpcyBpcyBhIHRlc3QgdG9rZW4=');
    \n

    Generates the following response:

    \n
    \"payload\": {\n    \"statusCode\": 401,\n    \"error\": \"Unauthorized\",\n    \"attributes\": \"VGhpcyBpcyBhIHRlc3QgdG9rZW4=\"\n},\n\"headers\": {\n  \"WWW-Authenticate\": \"Negotiate VGhpcyBpcyBhIHRlc3QgdG9rZW4=\"\n}
    \n
    Boom.unauthorized('invalid password', 'sample', { ttl: 0, cache: null, foo: 'bar' });
    \n

    Generates the following response:

    \n
    \"payload\": {\n    \"statusCode\": 401,\n    \"error\": \"Unauthorized\",\n    \"message\": \"invalid password\",\n    \"attributes\": {\n        \"error\": \"invalid password\",\n        \"ttl\": 0,\n        \"cache\": \"\",\n        \"foo\": \"bar\"\n    }\n},\n\"headers\": {\n  \"WWW-Authenticate\": \"sample ttl=\\\"0\\\", cache=\\\"\\\", foo=\\\"bar\\\", error=\\\"invalid password\\\"\"\n}
    \n
    Boom.paymentRequired([message], [data])
    \n

    Returns a 402 Payment Required error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.paymentRequired('bandwidth used');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 402,\n    \"error\": \"Payment Required\",\n    \"message\": \"bandwidth used\"\n}
    \n
    Boom.forbidden([message], [data])
    \n

    Returns a 403 Forbidden error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.forbidden('try again some time');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 403,\n    \"error\": \"Forbidden\",\n    \"message\": \"try again some time\"\n}
    \n
    Boom.notFound([message], [data])
    \n

    Returns a 404 Not Found error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.notFound('missing');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 404,\n    \"error\": \"Not Found\",\n    \"message\": \"missing\"\n}
    \n
    Boom.methodNotAllowed([message], [data], [allow])
    \n

    Returns a 405 Method Not Allowed error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    • \nallow - optional string or array of strings (to be combined and separated by ', ') which is set to the 'Allow' header.
    • \n
    \n
    Boom.methodNotAllowed('that method is not allowed');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 405,\n    \"error\": \"Method Not Allowed\",\n    \"message\": \"that method is not allowed\"\n}
    \n
    Boom.notAcceptable([message], [data])
    \n

    Returns a 406 Not Acceptable error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.notAcceptable('unacceptable');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 406,\n    \"error\": \"Not Acceptable\",\n    \"message\": \"unacceptable\"\n}
    \n
    Boom.proxyAuthRequired([message], [data])
    \n

    Returns a 407 Proxy Authentication Required error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.proxyAuthRequired('auth missing');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 407,\n    \"error\": \"Proxy Authentication Required\",\n    \"message\": \"auth missing\"\n}
    \n
    Boom.clientTimeout([message], [data])
    \n

    Returns a 408 Request Time-out error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.clientTimeout('timed out');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 408,\n    \"error\": \"Request Time-out\",\n    \"message\": \"timed out\"\n}
    \n
    Boom.conflict([message], [data])
    \n

    Returns a 409 Conflict error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.conflict('there was a conflict');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 409,\n    \"error\": \"Conflict\",\n    \"message\": \"there was a conflict\"\n}
    \n
    Boom.resourceGone([message], [data])
    \n

    Returns a 410 Gone error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.resourceGone('it is gone');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 410,\n    \"error\": \"Gone\",\n    \"message\": \"it is gone\"\n}
    \n
    Boom.lengthRequired([message], [data])
    \n

    Returns a 411 Length Required error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.lengthRequired('length needed');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 411,\n    \"error\": \"Length Required\",\n    \"message\": \"length needed\"\n}
    \n
    Boom.preconditionFailed([message], [data])
    \n

    Returns a 412 Precondition Failed error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.preconditionFailed();
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 412,\n    \"error\": \"Precondition Failed\"\n}
    \n
    Boom.entityTooLarge([message], [data])
    \n

    Returns a 413 Request Entity Too Large error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.entityTooLarge('too big');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 413,\n    \"error\": \"Request Entity Too Large\",\n    \"message\": \"too big\"\n}
    \n
    Boom.uriTooLong([message], [data])
    \n

    Returns a 414 Request-URI Too Large error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.uriTooLong('uri is too long');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 414,\n    \"error\": \"Request-URI Too Large\",\n    \"message\": \"uri is too long\"\n}
    \n
    Boom.unsupportedMediaType([message], [data])
    \n

    Returns a 415 Unsupported Media Type error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.unsupportedMediaType('that media is not supported');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 415,\n    \"error\": \"Unsupported Media Type\",\n    \"message\": \"that media is not supported\"\n}
    \n
    Boom.rangeNotSatisfiable([message], [data])
    \n

    Returns a 416 Requested Range Not Satisfiable error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.rangeNotSatisfiable();
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 416,\n    \"error\": \"Requested Range Not Satisfiable\"\n}
    \n
    Boom.expectationFailed([message], [data])
    \n

    Returns a 417 Expectation Failed error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.expectationFailed('expected this to work');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 417,\n    \"error\": \"Expectation Failed\",\n    \"message\": \"expected this to work\"\n}
    \n
    Boom.teapot([message], [data])
    \n

    Returns a 418 I'm a Teapot error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.teapot('sorry, no coffee...');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 418,\n    \"error\": \"I'm a Teapot\",\n    \"message\": \"Sorry, no coffee...\"\n}
    \n
    Boom.badData([message], [data])
    \n

    Returns a 422 Unprocessable Entity error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.badData('your data is bad and you should feel bad');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 422,\n    \"error\": \"Unprocessable Entity\",\n    \"message\": \"your data is bad and you should feel bad\"\n}
    \n
    Boom.locked([message], [data])
    \n

    Returns a 423 Locked error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.locked('this resource has been locked');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 423,\n    \"error\": \"Locked\",\n    \"message\": \"this resource has been locked\"\n}
    \n
    Boom.failedDependency([message], [data])
    \n

    Returns a 424 Failed Dependency error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.failedDependency('an external resource failed');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 424,\n    \"error\": \"Failed Dependency\",\n    \"message\": \"an external resource failed\"\n}
    \n
    Boom.tooEarly([message], [data])
    \n

    Returns a 425 Too Early error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.tooEarly('the server is unwilling to risk processing the request');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 425,\n    \"error\": \"Too Early\",\n    \"message\": \"the server is unwilling to risk processing the request\"\n}
    \n
    Boom.preconditionRequired([message], [data])
    \n

    Returns a 428 Precondition Required error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.preconditionRequired('you must supply an If-Match header');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 428,\n    \"error\": \"Precondition Required\",\n    \"message\": \"you must supply an If-Match header\"\n}
    \n
    Boom.tooManyRequests([message], [data])
    \n

    Returns a 429 Too Many Requests error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.tooManyRequests('you have exceeded your request limit');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 429,\n    \"error\": \"Too Many Requests\",\n    \"message\": \"you have exceeded your request limit\"\n}
    \n
    Boom.illegal([message], [data])
    \n

    Returns a 451 Unavailable For Legal Reasons error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.illegal('you are not permitted to view this resource for legal reasons');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 451,\n    \"error\": \"Unavailable For Legal Reasons\",\n    \"message\": \"you are not permitted to view this resource for legal reasons\"\n}
    \n

    HTTP 5xx Errors

    \n

    All 500 errors hide your message from the end user.

    \n
    \nBoom.badImplementation([message], [data]) - (alias: internal)
    \n

    Returns a 500 Internal Server Error error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.badImplementation('terrible implementation');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 500,\n    \"error\": \"Internal Server Error\",\n    \"message\": \"An internal server error occurred\"\n}
    \n
    Boom.notImplemented([message], [data])
    \n

    Returns a 501 Not Implemented error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.notImplemented('method not implemented');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 501,\n    \"error\": \"Not Implemented\",\n    \"message\": \"method not implemented\"\n}
    \n
    Boom.badGateway([message], [data])
    \n

    Returns a 502 Bad Gateway error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.badGateway('that is a bad gateway');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 502,\n    \"error\": \"Bad Gateway\",\n    \"message\": \"that is a bad gateway\"\n}
    \n
    Boom.serverUnavailable([message], [data])
    \n

    Returns a 503 Service Unavailable error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.serverUnavailable('unavailable');
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 503,\n    \"error\": \"Service Unavailable\",\n    \"message\": \"unavailable\"\n}
    \n
    Boom.gatewayTimeout([message], [data])
    \n

    Returns a 504 Gateway Time-out error where:

    \n
      \n
    • \nmessage - optional message.
    • \n
    • \ndata - optional additional error data.
    • \n
    \n
    Boom.gatewayTimeout();
    \n

    Generates the following response payload:

    \n
    {\n    \"statusCode\": 504,\n    \"error\": \"Gateway Time-out\"\n}
    \n

    F.A.Q.

    \n

    Q How do I include extra information in my responses? output.payload is missing data, what gives?

    \n

    A There is a reason the values passed back in the response payloads are pretty locked down. It's mostly for security and to not leak any important information back to the client. This means you will need to put in a little more effort to include extra information about your custom error. Check out the \"Error transformation\" section in the hapi documentation.

    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "HTTP-friendly error objects.", - "forks": 192, - "stars": 2936, - "date": "2024-10-23T14:38:54Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/boom" - }, - "bossy": { - "name": "bossy", - "versions": [ - { - "name": "6.0.1", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "5.1.0", - "branch": "v5", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "6.0.1", - "5.1.0" - ], - "api": true, - "isPlugin": false, - "6.0.1": { - "menu": "- [Methods](#methods)\n - [`parse()`](#parsedefinition-options)\n - [`usage()`](#usagedefinition-usage-options)\n - [`object()`](#objectname-parsed)\n- [Definition Object](#definition-object)", - "api": "

    Methods

    \n

    parse(definition, [options])

    \n

    Expects a bossy definition object and will return the parsed process.argv arguments provided. If there is an error\nthen the return value will be an instanceof Error.

    \n

    Options accepts the following keys:

    \n
      \n
    • \nargv - custom argv array value. Defaults to process.argv.
    • \n
    \n

    usage(definition, [usage], [options])

    \n

    Format a bossy definition object for display in the console. If usage is provided the returned value will\ninclude the usage value formatted at the top of the message.

    \n

    Options accepts the following keys:

    \n
      \n
    • \ncolors - Determines if colors are enabled when formatting usage. Defaults to whatever TTY supports.
    • \n
    \n

    object(name, parsed)

    \n

    Un-flattens dot-separated arguments based at name from Bossy.parse()'s output into an object.

    \n
    const Bossy = require('@hapi/bossy');\n\nconst definition = {\n    'pet.name': {\n        type: 'string'\n    },\n    'pet.age': {\n        type: 'number'\n    }\n};\n\n// Example CLI args: --pet.name Maddie --pet.age 5\n\nconst parsed = Bossy.parse(definition);     // { 'pet.name': 'Maddie', 'pet.age': 5 }\n\nif (parsed instanceof Error) {\n    console.error(parsed.message);\n    return;\n}\n\nconst pet = Bossy.object('pet', parsed);    // { name: 'Maddie', age: 5 }
    \n

    Definition Object

    \n

    The definition object should be structured with each object key representing the short form of an available command\nline argument. Each argument key supports the following properties:

    \n
      \n
    • \n

      alias: A string or array of strings that can also be used as the argument name. For example:

      \n
      h: {\n    alias: 'help'\n}
      \n
    • \n
    • \n

      type: Available types are: boolean, range, number, string, json, and help. Defaults to string.

      \n

      The boolean type may be negated by passing its argument prefixed with no-.\nFor example, if the command line argument is named color then --color would\nensure the boolean is true and --no-color would ensure it is false.

      \n

      help is a special type that allows the switch to be executed even though\nother paramters are required. Use case is to display a help message and\nquit. This will bypass all other errors, so be sure to capture it. It\nbehaves like a boolean.

      \n

      The json type allows building an object using command line arguments that utilize\ndot-separated (.) paths and JSON values. For example, an object argument named\npet might be built from --pet '{ \"type\": \"dog\" }' --pet.name Maddie, resulting in\nthe parsing output { pet: { type: 'dog', name: 'Maddie' } }. The contents of the\nflags are deeply merged together in the order they were specified. Additionally,\nJSON primitives (i.e. null, booleans, and numbers) and non-JSON are treated as strings\nby default, though this behavior may be controlled with the parsePrimitives option\ndocumented below. The following example demonstrates the default behavior:

      \n
      # CLI input\ncreate-pet --pet.type kangaroo --pet.legs 2 --pet.mammal true \\\n           --pet '{ \"name\": \"Maddie\", \"type\": \"dog\" }' --pet.legs 4
      \n
      // Parsing output\n{ pet: { name: 'Maddie', type: 'dog', legs: '4', mammal: 'true' } }
      \n
    • \n
    • \n

      multiple : Boolean to indicate if the same argument can be provided multiple times. If true, the parsed value\nwill always be an array of type's. Defaults to false. Does not apply to json type arguments.

      \n
    • \n
    • \n

      description: Description message that will be returned with usage information.

      \n
    • \n
    • \n

      require: Boolean to indicate if the argument is required. Defaults to false

      \n
    • \n
    • \n

      default: A default value to assign to the argument if its not provided as an argument.

      \n
    • \n
    • \n

      valid: A value or array of values that the argument is allowed to equal. Does not apply to json type arguments.

      \n
    • \n
    • \n

      parsePrimitives: A value of false, true, or 'strict' used to control the treatment of input to json type arguments. Defaults to false. Each of the settings are described below:

      \n
        \n
      • \n

        false - JSON primitives (i.e. null, booleans, and numbers) are treated as strings, non-JSON input is interpreted as a string, and the input may be a JSON array or object. This is the default behavior.

        \n
        # CLI input\ncreate-pet --pet.type kangaroo --pet.legs 2 --pet.mammal true \\\n            --pet '{ \"name\": \"Maddie\", \"type\": \"dog\" }' --pet.legs 4
        \n
        // Parsing output\n{ pet: { name: 'Maddie', type: 'dog', legs: '4', mammal: 'true' } }
        \n
      • \n
      • \n

        true - JSON primitives are parsed, non-JSON input is interpreted as a string, and the input may be a JSON array or object.

        \n

        For example, when parsePrimitives is false, --pet.name null will result in the output { pet: { name: 'null' } }. However, when parsePrimitives is true, the same input would result in the output { pet: { name: null } }. The same applies for other JSON primitives too, i.e. booleans and numbers. When this option is true, users may represent string values as JSON in order to avoid ambiguity, e.g. --pet.name '\"null\"'. It's recommended that applications using this option document the behavior for their users.

        \n
        # CLI input\ncreate-pet --pet.type kangaroo --pet.legs 2 --pet.mammal true \\\n           --pet '{ \"name\": \"Maddie\", \"type\": \"dog\" }' --pet.legs 4
        \n
        // Parsing output\n{ pet: { name: 'Maddie', type: 'dog', legs: 4, mammal: true } }
        \n
      • \n
      • \n

        'strict' - JSON primitives are parsed, non-JSON input is not allowed, and the input may not be a JSON array or object. In other words, the user may only set primitive values, and they are required to be valid JSON.

        \n

        When this option is used, users must represent string values as JSON, e.g. --pet.name '\"Maddie\"'. It's recommended that applications using this option document the behavior for their users.

        \n
        # CLI input\ncreate-pet --pet.type '\"kangaroo\"' --pet.legs 2 --pet.mammal true
        \n
        // Parsing output\n{ pet: { type: 'kangaroo', legs: 2, mammal: true } }
        \n

        The following input would result in an error because the input to --pet.type is invalid JSON:

        \n
        # CLI input\ncreate-pet --pet.type kangaroo --pet.legs 2 --pet.mammal true
        \n

        The following input would result in an error because the input to --pet does not represent a JSON primitive:

        \n
        # CLI input\ncreate-pet --pet '{ \"name\": \"Maddie\", \"type\": \"dog\" }' --pet.type '\"kangaroo\"'
        \n
      • \n
      \n
    • \n
    \n", - "intro": "", - "example": "", - "usage": "## Usage\n\n```js\nconst Bossy = require('@hapi/bossy');\n\nconst definition = {\n h: {\n description: 'Show help',\n alias: 'help',\n type: 'boolean'\n },\n n: {\n description: 'Show your name',\n alias: 'name'\n }\n};\n\nconst args = Bossy.parse(definition);\n\nif (args instanceof Error) {\n console.error(args.message);\n return;\n}\n\nif (args.h || !args.n) {\n console.log(Bossy.usage(definition, 'hello -n '));\n return;\n}\n\nconsole.log('Hello ' + args.n);\nconsole.log('Hello ' + args.name);\n```\n", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "5.1.0": { - "menu": "- [Usage](#usage)\n- [Methods](#methods)\n - [`parse()`](#parsedefinition-options)\n - [`usage()`](#usagedefinition-usage-options)\n - [`object()`](#objectname-parsed)\n- [Definition Object](#definition-object)", - "api": "

    Usage

    \n
    const Bossy = require('@hapi/bossy');\n\nconst definition = {\n    h: {\n        description: 'Show help',\n        alias: 'help',\n        type: 'boolean'\n    },\n    n: {\n        description: 'Show your name',\n        alias: 'name'\n    }\n};\n\nconst args = Bossy.parse(definition);\n\nif (args instanceof Error) {\n    console.error(args.message);\n    return;\n}\n\nif (args.h || !args.n) {\n    console.log(Bossy.usage(definition, 'hello -n <name>'));\n    return;\n}\n\nconsole.log('Hello ' + args.n);\nconsole.log('Hello ' + args.name);
    \n

    Methods

    \n

    parse(definition, [options])

    \n

    Expects a bossy definition object and will return the parsed process.argv arguments provided. If there is an error\nthen the return value will be an instanceof Error.

    \n

    Options accepts the following keys:

    \n
      \n
    • \nargv - custom argv array value. Defaults to process.argv.
    • \n
    \n

    usage(definition, [usage], [options])

    \n

    Format a bossy definition object for display in the console. If usage is provided the returned value will\ninclude the usage value formatted at the top of the message.

    \n

    Options accepts the following keys:

    \n
      \n
    • \ncolors - Determines if colors are enabled when formatting usage. Defaults to whatever TTY supports.
    • \n
    \n

    object(name, parsed)

    \n

    Un-flattens dot-separated arguments based at name from Bossy.parse()'s output into an object.

    \n
    const Bossy = require('@hapi/bossy');\n\nconst definition = {\n    'pet.name': {\n        type: 'string'\n    },\n    'pet.age': {\n        type: 'number'\n    }\n};\n\n// Example CLI args: --pet.name Maddie --pet.age 5\n\nconst parsed = Bossy.parse(definition);     // { 'pet.name': 'Maddie', 'pet.age': 5 }\n\nif (parsed instanceof Error) {\n    console.error(parsed.message);\n    return;\n}\n\nconst pet = Bossy.object('pet', parsed);    // { name: 'Maddie', age: 5 }
    \n

    Definition Object

    \n

    The definition object should be structured with each object key representing the short form of an available command\nline argument. Each argument key supports the following properties:

    \n
      \n
    • \n

      alias: A string or array of strings that can also be used as the argument name. For example:

      \n
      h: {\n    alias: 'help'\n}
      \n
    • \n
    • \n

      type: Available types are: boolean, range, number, string, json, and help. Defaults to string.

      \n

      The boolean type may be negated by passing its argument prefixed with no-.\nFor example, if the command line argument is named color then --color would\nensure the boolean is true and --no-color would ensure it is false.

      \n

      help is a special type that allows the switch to be executed even though\nother paramters are required. Use case is to display a help message and\nquit. This will bypass all other errors, so be sure to capture it. It\nbehaves like a boolean.

      \n

      The json type allows building an object using command line arguments that utilize\ndot-separated (.) paths and JSON values. For example, an object argument named\npet might be built from --pet '{ \"type\": \"dog\" }' --pet.name Maddie, resulting in\nthe parsing output { pet: { type: 'dog', name: 'Maddie' } }. The contents of the\nflags are deeply merged together in the order they were specified. Additionally,\nJSON primitives (i.e. null, booleans, and numbers) and non-JSON are treated as strings\nby default, though this behavior may be controlled with the parsePrimitives option\ndocumented below. The following example demonstrates the default behavior:

      \n
      # CLI input\ncreate-pet --pet.type kangaroo --pet.legs 2 --pet.mammal true \\\n           --pet '{ \"name\": \"Maddie\", \"type\": \"dog\" }' --pet.legs 4
      \n
      // Parsing output\n{ pet: { name: 'Maddie', type: 'dog', legs: '4', mammal: 'true' } }
      \n
    • \n
    • \n

      multiple : Boolean to indicate if the same argument can be provided multiple times. If true, the parsed value\nwill always be an array of type's. Defaults to false. Does not apply to json type arguments.

      \n
    • \n
    • \n

      description: Description message that will be returned with usage information.

      \n
    • \n
    • \n

      require: Boolean to indicate if the argument is required. Defaults to false

      \n
    • \n
    • \n

      default: A default value to assign to the argument if its not provided as an argument.

      \n
    • \n
    • \n

      valid: A value or array of values that the argument is allowed to equal. Does not apply to json type arguments.

      \n
    • \n
    • \n

      parsePrimitives: A value of false, true, or 'strict' used to control the treatment of input to json type arguments. Defaults to false. Each of the settings are described below:

      \n
        \n
      • \n

        false - JSON primitives (i.e. null, booleans, and numbers) are treated as strings, non-JSON input is interpreted as a string, and the input may be a JSON array or object. This is the default behavior.

        \n
        # CLI input\ncreate-pet --pet.type kangaroo --pet.legs 2 --pet.mammal true \\\n            --pet '{ \"name\": \"Maddie\", \"type\": \"dog\" }' --pet.legs 4
        \n
        // Parsing output\n{ pet: { name: 'Maddie', type: 'dog', legs: '4', mammal: 'true' } }
        \n
      • \n
      • \n

        true - JSON primitives are parsed, non-JSON input is interpreted as a string, and the input may be a JSON array or object.

        \n

        For example, when parsePrimitives is false, --pet.name null will result in the output { pet: { name: 'null' } }. However, when parsePrimitives is true, the same input would result in the output { pet: { name: null } }. The same applies for other JSON primitives too, i.e. booleans and numbers. When this option is true, users may represent string values as JSON in order to avoid ambiguity, e.g. --pet.name '\"null\"'. It's recommended that applications using this option document the behavior for their users.

        \n
        # CLI input\ncreate-pet --pet.type kangaroo --pet.legs 2 --pet.mammal true \\\n           --pet '{ \"name\": \"Maddie\", \"type\": \"dog\" }' --pet.legs 4
        \n
        // Parsing output\n{ pet: { name: 'Maddie', type: 'dog', legs: 4, mammal: true } }
        \n
      • \n
      • \n

        'strict' - JSON primitives are parsed, non-JSON input is not allowed, and the input may not be a JSON array or object. In other words, the user may only set primitive values, and they are required to be valid JSON.

        \n

        When this option is used, users must represent string values as JSON, e.g. --pet.name '\"Maddie\"'. It's recommended that applications using this option document the behavior for their users.

        \n
        # CLI input\ncreate-pet --pet.type '\"kangaroo\"' --pet.legs 2 --pet.mammal true
        \n
        // Parsing output\n{ pet: { type: 'kangaroo', legs: 2, mammal: true } }
        \n

        The following input would result in an error because the input to --pet.type is invalid JSON:

        \n
        # CLI input\ncreate-pet --pet.type kangaroo --pet.legs 2 --pet.mammal true
        \n

        The following input would result in an error because the input to --pet does not represent a JSON primitive:

        \n
        # CLI input\ncreate-pet --pet '{ \"name\": \"Maddie\", \"type\": \"dog\" }' --pet.type '\"kangaroo\"'
        \n
      • \n
      \n
    • \n
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Command line options parser.", - "forks": 30, - "stars": 45, - "date": "2024-10-23T15:40:09Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/bossy" - }, - "bounce": { - "name": "bounce", - "versions": [ - { - "name": "3.0.2", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "2.0.0", - "branch": "v2", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "3.0.2", - "2.0.0" - ], - "api": true, - "isPlugin": false, - "3.0.2": { - "menu": "- [`rethrow()`](#rethrowerr-types-options)\n- [`ignore()`](#ignoreerr-types-options)\n- [`background()`](#backgroundoperation-action-types-options)\n- [`isBoom()`](#isboomerr)\n- [`isError()`](#iserrorerr)\n- [`isSystem()`](#issystemerr)", - "api": "

    rethrow(err, types, [options])

    \n

    Throws the error passed if it matches any of the specified rules where:

    \n
      \n
    • \nerr - the error.
    • \n
    • \ntype - a single item or an array of items of:\n
        \n
      • An error constructor (e.g. SyntaxError).
      • \n
      • \n'system' - matches any languange native error or node assertions.
      • \n
      • \n'boom' - matches boom errors.
      • \n
      • an object where each property is compared with the error and must match the error property\nvalue. All the properties in the object must match the error but do not need to include all\nthe error properties.
      • \n
      \n
    • \n
    • \noptions - optional object where:\n
        \n
      • \ndecorate - an object which is assigned to the err, copying the properties onto the error.
      • \n
      • \noverride - an error used to override err when err matches. If used with decorate,\nthe override object is modified.
      • \n
      • \nreturn - if true, the error is returned instead of thrown. Defaults to false.
      • \n
      \n
    • \n
    \n

    ignore(err, types, [options])

    \n

    The opposite action of rethrow(). Ignores any errors matching the specified types. Any error\nnot matching is thrown after applying the options.

    \n

    background(operation, [action], [types], [options])

    \n

    Awaits for the value to resolve in the background and then apply either the rethrow() or ignore()\nactions where:

    \n
      \n
    • \noperation - a function, promise, or value that is awaited on inside a try...catch and any\nerror thrown processed by the action rule.
    • \n
    • \naction - one of 'rethrow' or 'ignore'. Defaults to 'rethrow'.
    • \n
    • \ntypes - same as the types argument passed to rethrow() or ignore(). Defaults to 'system'.
    • \n
    • \noptions - same as the options argument passed to rethrow() or ignore().
    • \n
    \n

    isBoom(err)

    \n

    Returns true when err is a boom error.

    \n

    isError(err)

    \n

    Returns true when err is an error.

    \n

    isSystem(err)

    \n

    Return true when err is one of:

    \n
      \n
    • EvalError
    • \n
    • RangeError
    • \n
    • ReferenceError
    • \n
    • SyntaxError
    • \n
    • TypeError
    • \n
    • URIError
    • \n
    • Node's AssertionError\n
    • \n
    \n", - "intro": "## Introduction\n\nWorking with `async`/`await` introduces a new challenge in handling errors. Unlike callbacks, which\nprovide a dual mechanism for passing application errors via the callback `err` argument and\ndeveloper errors via exceptions, `await` combines these two channels into one.\n\nIt is common practice to ignore application errors in background processing or when there is no\nuseful fallback. In those cases, it is still imperative to allow developer errors to surface and\nnot get swallowed.\n\nFor more information read:\n- [Learning to Throw Again](https://medium.com/@eranhammer/learning-to-throw-again-79b498504d28)\n- [Catching without Awaiting](https://medium.com/@eranhammer/catching-without-awaiting-b2cb7df45790)\n\nFor example:\n\n```js\nasync function email(user) {\n\n if (!user.address) {\n throw new Error('User has no email address');\n }\n\n const message = 'Welcome!';\n if (user.name) {\n message = `Welcome ${user.name}!`;\n }\n\n await mailer.send(user.address, message);\n}\n\nasync function register(address, name) {\n\n const user = { address, name };\n const id = await db.user.insert(user);\n user.id = id;\n\n try {\n await email(user);\n }\n catch (err) { } // Ignore errors\n\n return user;\n}\n```\n\nThis will fail silently every time the user has a `name` because it is reassigning a value to a\n`const` variable. However, because `email()` errors are ignored, system errors are ignored as well.\nThe idea is that `email()` can be used in both critical and non-critical paths. In the critical\npaths, errors are checked and addressed, but in the non-critical paths, errors are simply ignored.\n\nThis can be solved by adding a `rethrow()` statement:\n\n```js\nconst Bounce = require('@hapi/bounce');\n\nasync function register(address, name) {\n\n const user = { address, name };\n const id = await db.user.insert(user);\n user.id = id;\n\n try {\n await email(user);\n }\n catch (err) {\n Bounce.rethrow(err, 'system'); // Rethrows system errors and ignores application errors\n }\n\n return user;\n}\n```\n", - "example": "", - "usage": "## Usage\n", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "2.0.0": { - "menu": "- [Introduction](#introduction)\n- [Usage](#usage)\n - [`rethrow()`](#rethrowerr-types-options)\n - [`ignore()`](#ignoreerr-types-options)\n - [`background()`](#backgroundoperation-action-types-options)\n - [`isBoom()`](#isboomerr)\n - [`isError()`](#iserrorerr)\n - [`isSystem()`](#issystemerr)", - "api": "

    Introduction

    \n

    Working with async/await introduces a new challenge in handling errors. Unlike callbacks, which\nprovide a dual mechanism for passing application errors via the callback err argument and\ndeveloper errors via exceptions, await combines these two channels into one.

    \n

    It is common practice to ignore application errors in background processing or when there is no\nuseful fallback. In those cases, it is still imperative to allow developer errors to surface and\nnot get swallowed.

    \n

    For more information read:

    \n\n

    For example:

    \n
    async function email(user) {\n\n    if (!user.address) {\n        throw new Error('User has no email address');\n    }\n\n    const message = 'Welcome!';\n    if (user.name) {\n        message = `Welcome ${user.name}!`;\n    }\n\n    await mailer.send(user.address, message);\n}\n\nasync function register(address, name) {\n\n    const user = { address, name };\n    const id = await db.user.insert(user);\n    user.id = id;\n\n    try {\n        await email(user);\n    }\n    catch (err) { }             // Ignore errors\n\n    return user;\n}
    \n

    This will fail silently every time the user has a name because it is reassigning a value to a\nconst variable. However, because email() errors are ignored, system errors are ignored as well.\nThe idea is that email() can be used in both critical and non-critical paths. In the critical\npaths, errors are checked and addressed, but in the non-critical paths, errors are simply ignored.

    \n

    This can be solved by adding a rethrow() statement:

    \n
    const Bounce = require('@hapi/bounce');\n\nasync function register(address, name) {\n\n    const user = { address, name };\n    const id = await db.user.insert(user);\n    user.id = id;\n\n    try {\n        await email(user);\n    }\n    catch (err) {\n        Bounce.rethrow(err, 'system');  // Rethrows system errors and ignores application errors\n    }\n\n    return user;\n}
    \n

    Usage

    \n

    rethrow(err, types, [options])

    \n

    Throws the error passed if it matches any of the specified rules where:

    \n
      \n
    • \nerr - the error.
    • \n
    • \ntype - a single item or an array of items of:\n
        \n
      • An error constructor (e.g. SyntaxError).
      • \n
      • \n'system' - matches any languange native error or node assertions.
      • \n
      • \n'boom' - matches boom errors.
      • \n
      • an object where each property is compared with the error and must match the error property\nvalue. All the properties in the object must match the error but do not need to include all\nthe error properties.
      • \n
      \n
    • \n
    • \noptions - optional object where:\n
        \n
      • \ndecorate - an object which is assigned to the err, copying the properties onto the error.
      • \n
      • \noverride - an error used to override err when err matches. If used with decorate,\nthe override object is modified.
      • \n
      • \nreturn - if true, the error is returned instead of thrown. Defaults to false.
      • \n
      \n
    • \n
    \n

    ignore(err, types, [options])

    \n

    The opposite action of rethrow(). Ignores any errors matching the specified types. Any error\nnot matching is thrown after applying the options.

    \n

    background(operation, [action], [types], [options])

    \n

    Awaits for the value to resolve in the background and then apply either the rethrow() or ignore()\nactions where:

    \n
      \n
    • \noperation - a function, promise, or value that is awaited on inside a try...catch and any\nerror thrown processed by the action rule.
    • \n
    • \naction - one of 'rethrow' or 'ignore'. Defaults to 'rethrow'.
    • \n
    • \ntypes - same as the types argument passed to rethrow() or ignore(). Defaults to 'system'.
    • \n
    • \noptions - same as the options argument passed to rethrow() or ignore().
    • \n
    \n

    isBoom(err)

    \n

    Returns true when err is a boom error.

    \n

    isError(err)

    \n

    Returns true when err is an error.

    \n

    isSystem(err)

    \n

    Return true when err is one of:

    \n
      \n
    • EvalError
    • \n
    • RangeError
    • \n
    • ReferenceError
    • \n
    • SyntaxError
    • \n
    • TypeError
    • \n
    • URIError
    • \n
    • Node's AssertionError\n
    • \n
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Selective error catching and rewrite rules.", - "forks": 13, - "stars": 176, - "date": "2024-10-23T15:47:48Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/bounce" - }, - "bourne": { - "name": "bourne", - "versions": [ - { - "name": "3.0.0", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "2.1.0", - "branch": "v2", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "3.0.0", - "2.1.0" - ], - "api": true, - "isPlugin": false, - "3.0.0": { - "menu": "- [`Bourne.parse()`](#bourneparsetext-reviver-options)\n- [`Bourne.scan()`](#bournescanobj-options)\n- [`Bourne.safeParse()`](#bournesafeparsetext-reviver)", - "api": "

    Bourne.parse(text, [reviver], [options])

    \n

    Parses a given JSON-formatted text into an object where:

    \n
      \n
    • \ntext - the JSON text string.
    • \n
    • \nreviver - the JSON.parse() optional reviver argument.
    • \n
    • \noptions - optional configuration object where:\n
        \n
      • \nprotoAction - optional string with one of:\n
          \n
        • \n'error' - throw a SyntaxError when a __proto__ key is found. This is the default value.
        • \n
        • \n'remove' - deletes any __proto__ keys from the result object.
        • \n
        • \n'ignore' - skips all validation (same as calling JSON.parse() directly).
        • \n
        \n
      • \n
      \n
    • \n
    \n

    Bourne.scan(obj, [options])

    \n

    Scans a given object for prototype properties where:

    \n
      \n
    • \nobj - the object being scanned.
    • \n
    • \noptions - optional configuration object where:\n
        \n
      • \nprotoAction - optional string with one of:\n
          \n
        • \n'error' - throw a SyntaxError when a __proto__ key is found. This is the default value.
        • \n
        • \n'remove' - deletes any __proto__ keys from the input obj.
        • \n
        \n
      • \n
      \n
    • \n
    \n

    Bourne.safeParse(text, [reviver])

    \n

    Same as Bourne.parse() except that it returns null instead of throwing a SyntaxError when a __proto__ key is found.

    \n", - "intro": "### Introduction\n\nConsider this:\n\n```\n> const a = '{\"__proto__\":{ \"b\":5}}';\n'{\"__proto__\":{ \"b\":5}}'\n\n> const b = JSON.parse(a);\n{ __proto__: { b: 5 } }\n\n> b.b;\nundefined\n\n> const c = Object.assign({}, b);\n{}\n\n> c.b\n5\n```\n\nThe problem is that `JSON.parse()` retains the `__proto__` property as a plain object key. By\nitself, this is not a security issue. However, as soon as that object is assigned to another or\niterated on and values copied, the `__proto__` property leaks and becomes the object's prototype.\n", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "2.1.0": { - "menu": "- [`Bourne.parse()`](#bourneparsetext-reviver-options)\n- [`Bourne.scan()`](#bournescanobj-options)\n- [`Bourne.safeParse()`](#bournesafeparsetext-reviver)", - "api": "

    Introduction

    \n

    Consider this:

    \n
    > const a = '{\"__proto__\":{ \"b\":5}}';\n'{\"__proto__\":{ \"b\":5}}'\n\n> const b = JSON.parse(a);\n{ __proto__: { b: 5 } }\n\n> b.b;\nundefined\n\n> const c = Object.assign({}, b);\n{}\n\n> c.b\n5\n
    \n

    The problem is that JSON.parse() retains the __proto__ property as a plain object key. By\nitself, this is not a security issue. However, as soon as that object is assigned to another or\niterated on and values copied, the __proto__ property leaks and becomes the object's prototype.

    \n

    Bourne.parse(text, [reviver], [options])

    \n

    Parses a given JSON-formatted text into an object where:

    \n
      \n
    • \ntext - the JSON text string.
    • \n
    • \nreviver - the JSON.parse() optional reviver argument.
    • \n
    • \noptions - optional configuration object where:\n
        \n
      • \nprotoAction - optional string with one of:\n
          \n
        • \n'error' - throw a SyntaxError when a __proto__ key is found. This is the default value.
        • \n
        • \n'remove' - deletes any __proto__ keys from the result object.
        • \n
        • \n'ignore' - skips all validation (same as calling JSON.parse() directly).
        • \n
        \n
      • \n
      \n
    • \n
    \n

    Bourne.scan(obj, [options])

    \n

    Scans a given object for prototype properties where:

    \n
      \n
    • \nobj - the object being scanned.
    • \n
    • \noptions - optional configuration object where:\n
        \n
      • \nprotoAction - optional string with one of:\n
          \n
        • \n'error' - throw a SyntaxError when a __proto__ key is found. This is the default value.
        • \n
        • \n'remove' - deletes any __proto__ keys from the input obj.
        • \n
        \n
      • \n
      \n
    • \n
    \n

    Bourne.safeParse(text, [reviver])

    \n

    Same as Bourne.parse() except that it returns null instead of throwing a SyntaxError when a __proto__ key is found.

    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "JSON.parse() drop-in replacement with prototype poisoning protection.", - "forks": 13, - "stars": 169, - "date": "2024-10-23T15:09:24Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/bourne" - }, - "call": { - "name": "call", - "versions": [ - { - "name": "9.0.1", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "8.0.1", - "branch": "v8", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "9.0.1", - "8.0.1" - ], - "api": true, - "isPlugin": false, - "9.0.1": { - "menu": "- [Paths matching](#paths-matching)\n - [Exact match](#exact-match)\n - [Optional parameters](#optional-parameters)\n - [Multi-segment parameters](#multi-segment-parameters)\n - [Catch all](#catch-all)\n- [Routing order](#routing-order)\n- [Method](#method)\n - [`new Router()`](#new-routeroptions)\n - [`add()`](#addoptions-data)\n - [`route()`](#routemethod-path)", - "api": "

    Paths matching

    \n

    Exact match

    \n

    {param}: If path contains /users/{user} then it matches /users/john or /users/1234 but not /users.

    \n

    Optional parameters

    \n

    {param?}: ? means parameter is optional . If path contains /users/{user?} It matches /users/john as well as /users.

    \n

    It is important to be aware that only the last named parameter in a path can be optional. That means that /{one?}/{two}/ is an invalid path, since in this case there is another parameter after the optional one. You may also have a named parameter covering only part of a segment of the path, but you may only have one named parameter per segment. That means that /{filename}.jpg is valid while /{filename}.{ext} is not.

    \n

    Multi-segment parameters

    \n

    {params*n}: With path configuration /users/{user*2}, it matches /users/john/doe or /users/harshal/patil but not /users/john. Number n after asterisk sign specifies the multiplier.

    \n

    Like the optional parameters, a wildcard parameter (for example /{users*}) may only appear as the last parameter in your path.

    \n

    Catch all

    \n

    {params*}: Using this option, it matches anything. So /users/{user*} with match /users/, /users/john, /users/john/doe, /users/john/doe/smith

    \n

    For more details about path parameters, read hapi.js docs.

    \n

    Routing order

    \n

    When determining what handler to use for a particular request, router searches paths in order from most specific to least specific. That means if you have two routes, one with the path /filename.jpg and a second route /filename.{ext} a request to /filename.jpg will match the first route, and not the second. This also means that a route with the path /{files*} will be the last route tested, and will only match if all other routes fail.

    \n

    Call router has deterministic order than other routers and because of this deterministic order, call is able to detect conflicting routes and throw exception accordingly. In comparison, Express.js has different routing mechanism based on simple RegEx pattern matching making it faster (probably it only matters in theory) but unable to catch route conflicts.

    \n

    Method

    \n

    new Router([options])

    \n

    Constructor to create a new router instance where:

    \n
      \n
    • \noptions - an optional configuration object with the following fields:\n
        \n
      • \nisCaseSensitive - specifies if the paths should case sensitive. If set to true,\n/users and /USERS are considered as two different paths. Defaults to true.
      • \n
      \n
    • \n
    \n
    const router = new Call.Router();
    \n

    add(options, [data])

    \n

    Adds a new route to the router where:

    \n
      \n
    • \noptions - a configuration object with the following fields:\n
        \n
      • \nmethod - the HTTP method ('get', 'put', 'post', 'delete', etc.) or the wildcard\ncharacter ('*') to match any methods. The method must be lowercase.
      • \n
      • \npath - the URL path to be used for route matching. The path segment can be static like\n'/users/1234' or it can be a dynamic path.
      • \n
      \n
    • \n
    • \ndata - the application data to retrieve when a route match is found during lookup. This is\ntypically the route handler or other metadata about what to do when a route is matched.
    • \n
    \n

    Throws on invalid route configuration or on a conflict with existing routes.

    \n

    route(method, path)

    \n

    Finds a matching route where:

    \n
      \n
    • \nmethod - the requested route method.
    • \n
    • \npath - the requested route path.
    • \n
    \n

    Returns an object with the following when a match is found:

    \n
      \n
    • \nparams - an object containing all path parameters where each key is path name and\nvalue is the corresponding parameter value in the requested path.
    • \n
    • \nparamsArray - an array of the parameter values in order.
    • \n
    • \nroute - the data value provided when the route was added.
    • \n
    \n

    If no match is found, returns (not throws) an error.

    \n", - "intro": "## Introduction\n\n`call` is a simple node.js HTTP Router. It is used by popular [hapi.js](https://github.com/hapijs/hapi) web framework. It implements predictable and easy to use routing. Even if it is designed to work with Hapi.js, you can still use it as an independent router in your app.\n", - "example": "## Example\n\n```js\nconst Call = require('@hapi/call');\n\n// Create new router\nconst router = new Call.Router();\n\n// Add route\nrouter.add({ method: 'get', path: '/' }, { label: 'root-path' });\n\n// Add another route\nrouter.add({ method: 'post', path: '/users' }, 'route specific data');\n\n// Add another route with dynamic path\nrouter.add({ method: 'put', path: '/users/{userId}' }, () => { /* ...handler... */ });\n\n// Match route\nrouter.route('post', '/users');\n/* If matching route is found, it returns an object containing\n {\n params: {}, // All dynamic path parameters as key/value\n paramsArray: [], // All dynamic path parameter values in order\n route: 'route specific data'; // routeData\n }\n*/\n\n\n// Match route\nrouter.route('put', '/users/1234');\n/* returns\n {\n params: { userId: '1234' },\n paramsArray: [ '1234' ],\n route: [Function]\n }\n*/\n```\n", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "8.0.1": { - "menu": "- [Example](#example)\n- [Paths matching](#paths-matching)\n - [Exact match](#exact-match)\n - [Optional parameters](#optional-parameters)\n - [Multi-segment parameters](#multi-segment-parameters)\n - [Catch all](#catch-all)\n- [Routing order](#routing-order)\n- [Method](#method)\n - [`new Router()`](#new-routeroptions)\n - [`add()`](#addoptions-data)\n - [`route()`](#routemethod-path)", - "api": "

    Introduction

    \n

    call is a simple node.js HTTP Router. It is used by popular hapi.js web framework. It implements predictable and easy to use routing. Even if it is designed to work with Hapi.js, you can still use it as an independent router in your app.

    \n

    Example

    \n
    const Call = require('@hapi/call');\n\n// Create new router\nconst router = new Call.Router();\n\n// Add route\nrouter.add({ method: 'get', path: '/' }, { label: 'root-path' });\n\n// Add another route\nrouter.add({ method: 'post', path: '/users' }, 'route specific data');\n\n// Add another route with dynamic path\nrouter.add({ method: 'put', path: '/users/{userId}' }, () => { /* ...handler... */ });\n\n// Match route\nrouter.route('post', '/users');\n/* If matching route is found, it returns an object containing\n    {\n        params: {},                     // All dynamic path parameters as key/value\n        paramsArray: [],                // All dynamic path parameter values in order\n        route: 'route specific data';   // routeData\n    }\n*/\n\n\n// Match route\nrouter.route('put', '/users/1234');\n/* returns\n    {\n        params: { userId: '1234' },\n        paramsArray: [ '1234' ],\n        route: [Function]\n    }\n*/
    \n

    Paths matching

    \n

    Exact match

    \n

    {param}: If path contains /users/{user} then it matches /users/john or /users/1234 but not /users.

    \n

    Optional parameters

    \n

    {param?}: ? means parameter is optional . If path contains /users/{user?} It matches /users/john as well as /users.

    \n

    It is important to be aware that only the last named parameter in a path can be optional. That means that /{one?}/{two}/ is an invalid path, since in this case there is another parameter after the optional one. You may also have a named parameter covering only part of a segment of the path, but you may only have one named parameter per segment. That means that /{filename}.jpg is valid while /{filename}.{ext} is not.

    \n

    Multi-segment parameters

    \n

    {params*n}: With path configuration /users/{user*2}, it matches /users/john/doe or /users/harshal/patil but not /users/john. Number n after asterisk sign specifies the multiplier.

    \n

    Like the optional parameters, a wildcard parameter (for example /{users*}) may only appear as the last parameter in your path.

    \n

    Catch all

    \n

    {params*}: Using this option, it matches anything. So /users/{user*} with match /users/, /users/john, /users/john/doe, /users/john/doe/smith

    \n

    For more details about path parameters, read hapi.js docs.

    \n

    Routing order

    \n

    When determining what handler to use for a particular request, router searches paths in order from most specific to least specific. That means if you have two routes, one with the path /filename.jpg and a second route /filename.{ext} a request to /filename.jpg will match the first route, and not the second. This also means that a route with the path /{files*} will be the last route tested, and will only match if all other routes fail.

    \n

    Call router has deterministic order than other routers and because of this deterministic order, call is able to detect conflicting routes and throw exception accordingly. In comparison, Express.js has different routing mechanism based on simple RegEx pattern matching making it faster (probably it only matters in theory) but unable to catch route conflicts.

    \n

    Method

    \n

    new Router([options])

    \n

    Constructor to create a new router instance where:

    \n
      \n
    • \noptions - an optional configuration object with the following fields:\n
        \n
      • \nisCaseSensitive - specifies if the paths should case sensitive. If set to true,\n/users and /USERS are considered as two different paths. Defaults to true.
      • \n
      \n
    • \n
    \n
    const router = new Call.Router();
    \n

    add(options, [data])

    \n

    Adds a new route to the router where:

    \n
      \n
    • \noptions - a configuration object with the following fields:\n
        \n
      • \nmethod - the HTTP method ('get', 'put', 'post', 'delete', etc.) or the wildcard\ncharacter ('*') to match any methods. The method must be lowercase.
      • \n
      • \npath - the URL path to be used for route matching. The path segment can be static like\n'/users/1234' or it can be a dynamic path.
      • \n
      \n
    • \n
    • \ndata - the application data to retrieve when a route match is found during lookup. This is\ntypically the route handler or other metadata about what to do when a route is matched.
    • \n
    \n

    Throws on invalid route configuration or on a conflict with existing routes.

    \n

    route(method, path)

    \n

    Finds a matching route where:

    \n
      \n
    • \nmethod - the requested route method.
    • \n
    • \npath - the requested route path.
    • \n
    \n

    Returns an object with the following when a match is found:

    \n
      \n
    • \nparams - an object containing all path parameters where each key is path name and\nvalue is the corresponding parameter value in the requested path.
    • \n
    • \nparamsArray - an array of the parameter values in order.
    • \n
    • \nroute - the data value provided when the route was added.
    • \n
    \n

    If no match is found, returns (not throws) an error.

    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Simple HTTP Router.", - "forks": 27, - "stars": 37, - "date": "2024-10-23T15:38:49Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/call" - }, - "catbox": { - "name": "catbox", - "versions": [ - { - "name": "12.1.1", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "11.1.1", - "branch": "v11", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "12.1.1", - "11.1.1" - ], - "api": true, - "isPlugin": false, - "12.1.1": { - "menu": "- [Installation](#installation)\n- [`Client`](#client)\n - [API](#api)\n- [`Policy`](#policy)\n - [API](#api-1)", - "api": "

    catbox is a multi-strategy key-value object store. It comes with extensions supporting a memory\ncache, Redis, and Memcached. Additional providers from the\ncommunity can be found on the npm Registry.

    \n

    catbox provides two interfaces: a low-level Client and a high-level Policy.

    \n

    Installation

    \n

    In order to reduce module dependencies, catbox does not include the external caching\nstrategies. To use other strategies, each service must be manually installed via npm or package\ndependencies manually. The available strategies are:

    \n\n

    Client

    \n

    The Client object provides a low-level cache abstraction. The object is constructed using\nnew Client(engine, options) where:

    \n
      \n
    • \nengine - is an object or a prototype function implementing the cache strategy:\n
        \n
      • function - a prototype function with the signature function(options). catbox will call\nnew func(options).
      • \n
      • object - a pre instantiated client implementation object. Does not support passing options.
      • \n
      \n
    • \n
    • \noptions - the strategy configuration object. Each strategy defines its own configuration\noptions with the following common options:\n
        \n
      • \npartition - the partition name used to isolate the cached results across multiple clients.\nThe partition name is used as the MongoDB database name, the Riak bucket, or as a key prefix\nin Redis and Memcached. To share the cache across multiple clients, use the same partition\nname.
      • \n
      \n
    • \n
    \n

    Note that any implementation of client strategies must return deep copies of the stored data as the\nAPI assumes that the object returned from a get() is owned by the called and can be safely\nmodified without affecting the cache copy.

    \n

    API

    \n

    The Client object provides the following methods:

    \n
      \n
    • \nawait start() - creates a connection to the cache server. Must be called before any other\nmethod is available. Any errors are thrown.
    • \n
    • \nawait stop() - terminates the connection to the cache server.
    • \n
    • \nawait get(key) - retrieve an item from the cache engine if found where:\n
        \n
      • \nkey - a cache key object (see below).
      • \n
      • return value:\n
          \n
        • \nnull is the item is not found.
        • \n
        • throws an error if the request failed.
        • \n
        • otherwise, an object with the following properties:\n
            \n
          • \nitem - the value stored in the cache using set().
          • \n
          • \nstored - the timestamp when the item was stored in the cache (in milliseconds).
          • \n
          • \nttl - the remaining time-to-live (not the original value used when storing the\nobject).
          • \n
          \n
        • \n
        \n
      • \n
      \n
    • \n
    • \nawait set(key, value, ttl) - store an item in the cache for a specified length of time, where:\n
        \n
      • \nkey - a cache key object (see below).
      • \n
      • \nvalue - the string or object value to be stored.
      • \n
      • \nttl - a time-to-live value in milliseconds after which the item is automatically removed\nfrom the cache (or is marked invalid).
      • \n
      • any errors are thrown.
      • \n
      \n
    • \n
    • \nawait drop(key) - remove an item from cache where:\n
        \n
      • \nkey - a cache key object (see below).
      • \n
      • any errors are thrown.
      • \n
      \n
    • \n
    • \nisReady() - returns true if cache engine determines itself as ready, false if it is not\nready.
    • \n
    • \nvalidateSegmentName(segment) - returns null if the segment name is valid (see below),\notherwise should return an instance of Error with an appropriate message.
    • \n
    \n

    Any method with a key argument takes an object with the following required properties:

    \n
      \n
    • \nsegment - a caching segment name string. Enables using a single cache server for storing\ndifferent sets of items with overlapping ids.
    • \n
    • \nid - a unique item identifier string (per segment). Can be an empty string.
    • \n
    \n

    Policy

    \n

    The Policy object provides a convenient cache interface by setting a global policy which is\nautomatically applied to every storage action. The object is constructed using\nnew Policy(options, [cache, segment]) where:

    \n
      \n
    • \noptions - is an object with the following optional keys (unless noted otherwise):\n
        \n
      • \nexpiresIn - relative expiration expressed in the number of milliseconds since the item was\nsaved in the cache. Cannot be used together with expiresAt.
      • \n
      • \nexpiresAt - time of day expressed in 24h notation using the 'HH:MM' format, at which point\nall cache records for the route expire. Uses local time. Cannot be used together with\nexpiresIn.
      • \n
      • \ngenerateFunc - a function used to generate a new cache item if one is not found in the\ncache when calling get(). The method's signature is async function(id, flags) where:\n
          \n
        • \nid - the id string or object provided to the get() method as-is (not normalized).
        • \n
        • \nflags - an object used to pass back additional flags:\n
            \n
          • \nttl - the cache ttl value in milliseconds. Set to 0 to skip storing in the cache.\nDefaults to the cache global policy.
          • \n
          \n
        • \n
        \n
      • \n
      • \nstaleIn - number of milliseconds to mark an item stored in cache as stale and attempt to\nregenerate it when generateFunc is provided. Must be less than expiresIn. Alternatively\nfunction that returns staleIn value in milliseconds. The function signature is\nfunction(stored, ttl) where:\n
          \n
        • \nstored - the timestamp when the item was stored in the cache (in milliseconds).
        • \n
        • \nttl - the remaining time-to-live (not the original value used when storing the object).
        • \n
        \n
      • \n
      • \nstaleTimeout - number of milliseconds to wait before returning a stale value while\ngenerateFunc is generating a fresh value.
      • \n
      • \ngenerateTimeout - number of milliseconds to wait before returning a timeout error when the\ngenerateFunc function takes too long to return a value. When the value is eventually\nreturned, it is stored in the cache for future requests. Required if generateFunc is\npresent. Set to false to disable timeouts which may cause all get() requests to get stuck\nforever.
      • \n
      • \ndropOnError - if true, an error or timeout in the generateFunc causes the stale value\nto be evicted from the cache. Defaults to true.
      • \n
      • \ngenerateOnReadError - if false, an upstream cache read error will stop the get() method\nfrom calling the generate function and will instead pass back the cache error. Defaults to\ntrue.
      • \n
      • \ngenerateIgnoreWriteError - if false, an upstream cache write error will be passed back\nwith the generated value when calling the get() method. Defaults to true.
      • \n
      • \npendingGenerateTimeout - number of milliseconds while generateFunc call is in progress for\na given id, before a subsequent generateFunc call is allowed. Defaults to 0, no blocking of\nconcurrent generateFunc calls beyond staleTimeout.
      • \n
      • \ngetDecoratedValue - if true, the return value of policy.get() calls is an object with\n{ value, cached, report }. Defaults to false which returns a plain value.
      • \n
      \n
    • \n
    • \ncache - a Client instance (which has already been started).
    • \n
    • \nsegment - required when cache is provided. The segment name used to isolate cached items\nwithin the cache partition.
    • \n
    \n

    API

    \n

    The Policy object provides the following methods:

    \n
      \n
    • \nawait get(id) - retrieve an item from the cache. If the item is not found and the\ngenerateFunc method was provided, a new value is generated, stored in the cache, and returned.\nMultiple concurrent requests are queued and processed once. The method arguments are:\n
        \n
      • \nid - the unique item identifier (within the policy segment). Can be a string or an object\nwith the required 'id' key.
      • \n
      • return value:\n
          \n
        • the requested item if found, otherwise null.
        • \n
        • any errors are thrown.
        • \n
        • if getDecoratedValue is true, returns an object with the following properties:\n
            \n
          • \nvalue - the fetched or generated value.
          • \n
          • \ncached - null if a valid item was not found in the cache, or an object with the\nfollowing keys:\n
              \n
            • \nitem - the cached value.
            • \n
            • \nstored - the timestamp when the item was stored in the cache.
            • \n
            • \nttl - the cache ttl value for the record.
            • \n
            • \nisStale - true if the item is stale.
            • \n
            \n
          • \n
          • \nreport - an object with logging information about the generation operation\ncontaining the following keys (as relevant):\n
              \n
            • \nmsec - the cache lookup time in milliseconds.
            • \n
            • \nstored - the timestamp when the item was stored in the cache.
            • \n
            • \nisStale - true if the item is stale.
            • \n
            • \nttl - the cache ttl value for the record.
            • \n
            • \nerror - lookup error.
            • \n
            \n
          • \n
          \n
        • \n
        \n
      • \n
      \n
    • \n
    • \nawait set(id, value, ttl) - store an item in the cache where:\n
        \n
      • \nid - the unique item identifier (within the policy segment).
      • \n
      • \nvalue - the string or object value to be stored.
      • \n
      • \nttl - a time-to-live override value in milliseconds after which the item is\nautomatically removed from the cache (or is marked invalid). This should be set to 0 in\norder to use the caching rules configured when creating the Policy object.
      • \n
      • any errors are thrown.
      • \n
      \n
    • \n
    • \nawait drop(id) - remove the item from cache where:\n
        \n
      • \nid - the unique item identifier (within the policy segment).
      • \n
      • any errors are thrown.
      • \n
      \n
    • \n
    • \nttl(created) - given a created timestamp in milliseconds, returns the time-to-live left based\non the configured rules.
    • \n
    • \nrules(options) - changes the policy rules after construction (note that items already stored\nwill not be affected) where:\n
        \n
      • \noptions - the same options as the Policy constructor.
      • \n
      \n
    • \n
    • \nisReady() - returns true if cache engine determines itself as ready, false if it is not\nready or if there is no cache engine set.
    • \n
    • \nstats - an object with cache statistics where:\n
        \n
      • \nsets - number of cache writes.
      • \n
      • \ngets - number of cache get() requests.
      • \n
      • \nhits - number of cache get() requests in which the requested id was found in the cache\n(can be stale).
      • \n
      • \nstales - number of cache reads with stale requests (only counts the first request in a\nqueued get() operation).
      • \n
      • \ngenerates - number of calls to the generate function.
      • \n
      • \nerrors - cache operations errors.
      • \n
      \n
    • \n
    • \nevents - a podium event emitter, emitting 'error'\nevents under the following channels:\n
        \n
      • \n'persist' - emits any cache errors thrown during the generation of new values as a result\nof a get() request.
      • \n
      • \n'generate' - emits any new value generation errors thrown as a result of a get() request.
      • \n
      \n
    • \n
    • \nclient - a reference to the cache client if set.
    • \n
    \n

    Note that errors generated by set() and drop() are reported directly by the functions calls and\nare not included in the reported events.

    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "11.1.1": { - "menu": "- [Installation](#installation)\n- [`Client`](#client)\n - [API](#api)\n- [`Policy`](#policy)\n - [API](#api-1)", - "api": "

    catbox is a multi-strategy key-value object store. It comes with extensions supporting a memory\ncache, Redis, and Memcached. Additional providers from the\ncommunity can be found on the npm Registry.

    \n

    catbox provides two interfaces: a low-level Client and a high-level Policy.

    \n

    Installation

    \n

    In order to reduce module dependencies, catbox does not include the external caching\nstrategies. To use other strategies, each service must be manually installed via npm or package\ndependencies manually. The available strategies are:

    \n\n

    Client

    \n

    The Client object provides a low-level cache abstraction. The object is constructed using\nnew Client(engine, options) where:

    \n
      \n
    • \nengine - is an object or a prototype function implementing the cache strategy:\n
        \n
      • function - a prototype function with the signature function(options). catbox will call\nnew func(options).
      • \n
      • object - a pre instantiated client implementation object. Does not support passing options.
      • \n
      \n
    • \n
    • \noptions - the strategy configuration object. Each strategy defines its own configuration\noptions with the following common options:\n
        \n
      • \npartition - the partition name used to isolate the cached results across multiple clients.\nThe partition name is used as the MongoDB database name, the Riak bucket, or as a key prefix\nin Redis and Memcached. To share the cache across multiple clients, use the same partition\nname.
      • \n
      \n
    • \n
    \n

    Note that any implementation of client strategies must return deep copies of the stored data as the\nAPI assumes that the object returned from a get() is owned by the called and can be safely\nmodified without affecting the cache copy.

    \n

    API

    \n

    The Client object provides the following methods:

    \n
      \n
    • \nawait start() - creates a connection to the cache server. Must be called before any other\nmethod is available. Any errors are thrown.
    • \n
    • \nawait stop() - terminates the connection to the cache server.
    • \n
    • \nawait get(key) - retrieve an item from the cache engine if found where:\n
        \n
      • \nkey - a cache key object (see below).
      • \n
      • return value:\n
          \n
        • \nnull is the item is not found.
        • \n
        • throws an error if the request failed.
        • \n
        • otherwise, an object with the following properties:\n
            \n
          • \nitem - the value stored in the cache using set().
          • \n
          • \nstored - the timestamp when the item was stored in the cache (in milliseconds).
          • \n
          • \nttl - the remaining time-to-live (not the original value used when storing the\nobject).
          • \n
          \n
        • \n
        \n
      • \n
      \n
    • \n
    • \nawait set(key, value, ttl) - store an item in the cache for a specified length of time, where:\n
        \n
      • \nkey - a cache key object (see below).
      • \n
      • \nvalue - the string or object value to be stored.
      • \n
      • \nttl - a time-to-live value in milliseconds after which the item is automatically removed\nfrom the cache (or is marked invalid).
      • \n
      • any errors are thrown.
      • \n
      \n
    • \n
    • \nawait drop(key) - remove an item from cache where:\n
        \n
      • \nkey - a cache key object (see below).
      • \n
      • any errors are thrown.
      • \n
      \n
    • \n
    • \nisReady() - returns true if cache engine determines itself as ready, false if it is not\nready.
    • \n
    • \nvalidateSegmentName(segment) - returns null if the segment name is valid (see below),\notherwise should return an instance of Error with an appropriate message.
    • \n
    \n

    Any method with a key argument takes an object with the following required properties:

    \n
      \n
    • \nsegment - a caching segment name string. Enables using a single cache server for storing\ndifferent sets of items with overlapping ids.
    • \n
    • \nid - a unique item identifier string (per segment). Can be an empty string.
    • \n
    \n

    Policy

    \n

    The Policy object provides a convenient cache interface by setting a global policy which is\nautomatically applied to every storage action. The object is constructed using\nnew Policy(options, [cache, segment]) where:

    \n
      \n
    • \noptions - is an object with the following optional keys (unless noted otherwise):\n
        \n
      • \nexpiresIn - relative expiration expressed in the number of milliseconds since the item was\nsaved in the cache. Cannot be used together with expiresAt.
      • \n
      • \nexpiresAt - time of day expressed in 24h notation using the 'HH:MM' format, at which point\nall cache records for the route expire. Uses local time. Cannot be used together with\nexpiresIn.
      • \n
      • \ngenerateFunc - a function used to generate a new cache item if one is not found in the\ncache when calling get(). The method's signature is async function(id, flags) where:\n
          \n
        • \nid - the id string or object provided to the get() method as-is (not normalized).
        • \n
        • \nflags - an object used to pass back additional flags:\n
            \n
          • \nttl - the cache ttl value in milliseconds. Set to 0 to skip storing in the cache.\nDefaults to the cache global policy.
          • \n
          \n
        • \n
        \n
      • \n
      • \nstaleIn - number of milliseconds to mark an item stored in cache as stale and attempt to\nregenerate it when generateFunc is provided. Must be less than expiresIn. Alternatively\nfunction that returns staleIn value in milliseconds. The function signature is\nfunction(stored, ttl) where:\n
          \n
        • \nstored - the timestamp when the item was stored in the cache (in milliseconds).
        • \n
        • \nttl - the remaining time-to-live (not the original value used when storing the object).
        • \n
        \n
      • \n
      • \nstaleTimeout - number of milliseconds to wait before returning a stale value while\ngenerateFunc is generating a fresh value.
      • \n
      • \ngenerateTimeout - number of milliseconds to wait before returning a timeout error when the\ngenerateFunc function takes too long to return a value. When the value is eventually\nreturned, it is stored in the cache for future requests. Required if generateFunc is\npresent. Set to false to disable timeouts which may cause all get() requests to get stuck\nforever.
      • \n
      • \ndropOnError - if true, an error or timeout in the generateFunc causes the stale value\nto be evicted from the cache. Defaults to true.
      • \n
      • \ngenerateOnReadError - if false, an upstream cache read error will stop the get() method\nfrom calling the generate function and will instead pass back the cache error. Defaults to\ntrue.
      • \n
      • \ngenerateIgnoreWriteError - if false, an upstream cache write error will be passed back\nwith the generated value when calling the get() method. Defaults to true.
      • \n
      • \npendingGenerateTimeout - number of milliseconds while generateFunc call is in progress for\na given id, before a subsequent generateFunc call is allowed. Defaults to 0, no blocking of\nconcurrent generateFunc calls beyond staleTimeout.
      • \n
      • \ngetDecoratedValue - if true, the return value of policy.get() calls is an object with\n{ value, cached, report }. Defaults to false which returns a plain value.
      • \n
      \n
    • \n
    • \ncache - a Client instance (which has already been started).
    • \n
    • \nsegment - required when cache is provided. The segment name used to isolate cached items\nwithin the cache partition.
    • \n
    \n

    API

    \n

    The Policy object provides the following methods:

    \n
      \n
    • \nawait get(id) - retrieve an item from the cache. If the item is not found and the\ngenerateFunc method was provided, a new value is generated, stored in the cache, and returned.\nMultiple concurrent requests are queued and processed once. The method arguments are:\n
        \n
      • \nid - the unique item identifier (within the policy segment). Can be a string or an object\nwith the required 'id' key.
      • \n
      • return value:\n
          \n
        • the requested item if found, otherwise null.
        • \n
        • any errors are thrown.
        • \n
        • if getDecoratedValue is true, returns an object with the following properties:\n
            \n
          • \nvalue - the fetched or generated value.
          • \n
          • \ncached - null if a valid item was not found in the cache, or an object with the\nfollowing keys:\n
              \n
            • \nitem - the cached value.
            • \n
            • \nstored - the timestamp when the item was stored in the cache.
            • \n
            • \nttl - the cache ttl value for the record.
            • \n
            • \nisStale - true if the item is stale.
            • \n
            \n
          • \n
          • \nreport - an object with logging information about the generation operation\ncontaining the following keys (as relevant):\n
              \n
            • \nmsec - the cache lookup time in milliseconds.
            • \n
            • \nstored - the timestamp when the item was stored in the cache.
            • \n
            • \nisStale - true if the item is stale.
            • \n
            • \nttl - the cache ttl value for the record.
            • \n
            • \nerror - lookup error.
            • \n
            \n
          • \n
          \n
        • \n
        \n
      • \n
      \n
    • \n
    • \nawait set(id, value, ttl) - store an item in the cache where:\n
        \n
      • \nid - the unique item identifier (within the policy segment).
      • \n
      • \nvalue - the string or object value to be stored.
      • \n
      • \nttl - a time-to-live override value in milliseconds after which the item is\nautomatically removed from the cache (or is marked invalid). This should be set to 0 in\norder to use the caching rules configured when creating the Policy object.
      • \n
      • any errors are thrown.
      • \n
      \n
    • \n
    • \nawait drop(id) - remove the item from cache where:\n
        \n
      • \nid - the unique item identifier (within the policy segment).
      • \n
      • any errors are thrown.
      • \n
      \n
    • \n
    • \nttl(created) - given a created timestamp in milliseconds, returns the time-to-live left based\non the configured rules.
    • \n
    • \nrules(options) - changes the policy rules after construction (note that items already stored\nwill not be affected) where:\n
        \n
      • \noptions - the same options as the Policy constructor.
      • \n
      \n
    • \n
    • \nisReady() - returns true if cache engine determines itself as ready, false if it is not\nready or if there is no cache engine set.
    • \n
    • \nstats - an object with cache statistics where:\n
        \n
      • \nsets - number of cache writes.
      • \n
      • \ngets - number of cache get() requests.
      • \n
      • \nhits - number of cache get() requests in which the requested id was found in the cache\n(can be stale).
      • \n
      • \nstales - number of cache reads with stale requests (only counts the first request in a\nqueued get() operation).
      • \n
      • \ngenerates - number of calls to the generate function.
      • \n
      • \nerrors - cache operations errors.
      • \n
      \n
    • \n
    • \nevents - a podium event emitter, emitting 'error'\nevents under the following channels:\n
        \n
      • \n'persist' - emits any cache errors thrown during the generation of new values as a result\nof a get() request.
      • \n
      • \n'generate' - emits any new value generation errors thrown as a result of a get() request.
      • \n
      \n
    • \n
    • \nclient - a reference to the cache client if set.
    • \n
    \n

    Note that errors generated by set() and drop() are reported directly by the functions calls and\nare not included in the reported events.

    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Multi-strategy object caching service.", - "forks": 72, - "stars": 494, - "date": "2024-10-23T15:27:54Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/catbox" - }, - "catbox-memcached": { - "name": "catbox-memcached", - "versions": [ - { - "name": "4.0.0", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "3.0.0", - "branch": "v3", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "4.0.0", - "3.0.0" - ], - "api": true, - "isPlugin": false, - "4.0.0": { - "menu": "- [`new CatboxMemcached.Engine()`](#new-catboxmemcachedengineoptions)", - "api": "

    new CatboxMemcached.Engine(options)

    \n
      \n
    • \nhost - the Memcache server hostname. Defaults to 127.0.0.1. Cannot be used with server.\n
    • \n
    • \nport - the Memcache server port. Defaults to 11211. Cannot be used with server.\n
    • \n
    • \nserver - the Memcache server hostname and port. Defaults to 127.0.0.1:11211. Can be a string or an object as per memcache-client server specification.
    • \n
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "3.0.0": { - "menu": "- [Options](#options)", - "api": "

    Options

    \n
      \n
    • \nhost - the Memcache server hostname. Defaults to 127.0.0.1. Cannot be used with location.\n
    • \n
    • \nport - the Memcache server port. Defaults to 11211. Cannot be used with location.\n
    • \n
    • \nlocation - the Memcache server hostname and port. Defaults to 127.0.0.1:11211. Can be a String,\nArray, or an Object as per node-memcached location specification\n
    • \n
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Memcached adaptor for [catbox](https://github.com/hapijs/catbox).", - "forks": 18, - "stars": 11, - "date": "2022-11-06T04:05:12Z", - "updated": "Sun Nov 06 2022", - "link": "https://github.com/hapijs/catbox-memcached" - }, - "catbox-memory": { - "name": "catbox-memory", - "versions": [ - { - "name": "6.0.2", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "5.0.1", - "branch": "v5", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "6.0.2", - "5.0.1" - ], - "api": true, - "isPlugin": false, - "6.0.2": { - "menu": "- [`new CatboxMemory.Engine()`](#new-catboxmemoryengineoptions)", - "api": "

    new CatboxMemory.Engine(options)

    \n
      \n
    • \nmaxByteSize - sets an upper limit on the number of bytes that can be stored in the\ncache. Once this limit is reached no additional items will be added to the cache\nuntil some expire. The utilized memory calculation is a rough approximation and must\nnot be relied on. Defaults to 104857600 (100MB).
    • \n
    • \nminCleanupIntervalMsec - the minimum number of milliseconds in between each cache cleanup.\nDefaults to 1 second (1000).
    • \n
    • \ncloneBuffersOnGet - by default, buffers stored in the cache are copied when they are set but\nnot when they are retrieved. This means a change to the buffer returned by a get() will change\nthe value in the cache. To prevent this, set cloneBuffersOnGet to true to always return a\ncopy of the cached buffer. Defaults to false.
    • \n
    \n", - "intro": "### Introduction\n\nMemory adapter for [catbox](https://github.com/hapijs/catbox).\nThis adapter is not designed to share a common cache between multiple processes (e.g. in a cluster\nmode). It uses a single interval timeout to look for expired records and clean them from memory.\n", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "5.0.1": { - "menu": "- [Introduction](#introduction)\n- [Options](#options)", - "api": "

    Introduction

    \n

    Memory adapter for catbox.\nThis adapter is not designed to share a common cache between multiple processes (e.g. in a cluster\nmode). It uses a single interval timeout to look for expired records and clean them from memory.

    \n

    Options

    \n
      \n
    • \nmaxByteSize - sets an upper limit on the number of bytes that can be stored in the\ncache. Once this limit is reached no additional items will be added to the cache\nuntil some expire. The utilized memory calculation is a rough approximation and must\nnot be relied on. Defaults to 104857600 (100MB).
    • \n
    • \nminCleanupIntervalMsec - the minimum number of milliseconds in between each cache cleanup.\nDefaults to 1 second (1000).
    • \n
    • \ncloneBuffersOnGet - by default, buffers stored in the cache are copied when they are set but\nnot when they are retrieved. This means a change to the buffer returned by a get() will change\nthe value in the cache. To prevent this, set cloneBuffersOnGet to true to always return a\ncopy of the cached buffer. Defaults to false.
    • \n
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Memory adaptor for [catbox](https://github.com/hapijs/catbox).", - "forks": 30, - "stars": 33, - "date": "2024-10-23T15:27:21Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/catbox-memory" - }, - "catbox-object": { - "name": "catbox-object", - "versions": [ - { - "name": "3.0.1", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "2.0.0", - "branch": "v2", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "3.0.1", - "2.0.0" - ], - "api": true, - "isPlugin": false, - "3.0.1": { - "menu": "- [`new CatboxObject.Engine()`](#new-catboxobjectengineoptions)", - "api": "

    new CatboxObject.Engine(options)

    \n
      \n
    • \nmaxSize - sets an upper limit on the number of items that can be stored in the\ncache. Once this limit is reached no additional items will be added to the cache\nuntil some expire. Defaults to 1000.
    • \n
    • \nminCleanupIntervalMsec - the minimum number of milliseconds in between each cache cleanup.\nDefaults to 1 second (1000).
    • \n
    \n", - "intro": "### Introduction\n\nMemory object adapter for [catbox](https://github.com/hapijs/catbox).\nThis adapter is not designed to share a common cache between multiple processes (e.g. in a cluster\nmode). It uses a single interval timeout to look for expired records and clean them from memory.\nUnlike the **catbox-memory** cache, it does not clone objects stored (in either direction) or keep\ntrack of memory usage.\n", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "2.0.0": { - "menu": "- [Introduction](#introduction)\n- [Options](#options)", - "api": "

    Introduction

    \n

    Memory object adapter for catbox.\nThis adapter is not designed to share a common cache between multiple processes (e.g. in a cluster\nmode). It uses a single interval timeout to look for expired records and clean them from memory.\nUnlike the catbox-memory cache, it does not clone objects stored (in either direction) or keep\ntrack of memory usage.

    \n

    Options

    \n
      \n
    • \nmaxSize - sets an upper limit on the number of items that can be stored in the\ncache. Once this limit is reached no additional items will be added to the cache\nuntil some expire. Defaults to 1000.
    • \n
    • \nminCleanupIntervalMsec - the minimum number of milliseconds in between each cache cleanup.\nDefaults to 1 second (1000).
    • \n
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Object cache adaptor for [catbox](https://github.com/hapijs/catbox).", - "forks": 7, - "stars": 2, - "date": "2024-10-23T15:26:43Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/catbox-object" - }, - "catbox-redis": { - "name": "catbox-redis", - "versions": [ - { - "name": "7.0.2", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "6.0.2", - "branch": "v6", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "7.0.2", - "6.0.2" - ], - "api": true, - "isPlugin": true, - "7.0.2": { - "menu": "- [`new CatboxRedis.Engine()`](#new-catboxredisengineoptions)\n- [Tests](#tests)", - "api": "

    new CatboxRedis.Engine(options)

    \n

    The connection can be specified with one (and only one) of:

    \n
      \n
    • \n

      client - a custom Redis client instance where client must:

      \n
        \n
      • be manually started and stopped,
      • \n
      • be compatible with the ioredis module API, and
      • \n
      • expose the status property that must be set to 'ready' when connected.
      • \n
      \n
    • \n
    • \n

      url - a Redis server URL.

      \n
    • \n
    • \n

      socket - a unix socket string.

      \n
    • \n
    • \n

      cluster - an array of { host, port } pairs.

      \n
    • \n
    \n

    Or:

    \n
      \n
    • \nhost - a Redis server hostname. Defaults to '127.0.0.1' if no other connection method specified from the above.
    • \n
    • \nport - a Redis server port or unix domain socket path. Defaults to 6379 if no other connection method specified from the above.
    • \n
    \n

    catbox options:

    \n
      \n
    • \npartition - a string used to prefix all item keys with. Defaults to ''.
    • \n
    \n

    Other supported Redis options:

    \n
      \n
    • \npassword - the Redis authentication password when required.
    • \n
    • \ndb - a Redis database name or number.
    • \n
    • \nsentinels - an array of { host, port } sentinel address pairs.
    • \n
    • \nsentinelName - the name of the sentinel master (when sentinels is specified).
    • \n
    • \ntls - an object representing TLS config options for ioredis.
    • \n
    \n

    The plugin also accepts other redis options not mentioned above.

    \n

    Tests

    \n

    The test suite expects:

    \n
      \n
    • a redis server to be running on port 6379
    • \n
    • a redis server listenning to port 6378 and requiring a password: 'secret'
    • \n
    • a redis cluster contains nodes running on ports 7000 to 7005
    • \n
    \n

    See docker-compose.yml

    \n", - "intro": "", - "example": "", - "usage": "### Usage\n\nSample catbox cache initialization:\n\n```js\nconst Catbox = require('@hapi/catbox');\nconst { Engine: CatboxRedis } = require('@hapi/catbox-redis');\n\n\nconst cache = new Catbox.Client(CatboxRedis, {\n partition : 'my_cached_data',\n host: 'redis-cluster.domain.com',\n port: 6379,\n db: 0,\n tls: {},\n});\n```\n\nWhen used in a hapi server (hapi version 18 or newer):\n\n```js\nconst Hapi = require('hapi')\nconst { Engine: CatboxRedis } = require('@hapi/catbox-redis');\n\nconst server = new Hapi.Server({\n cache : [\n {\n name: 'my_cache',\n provider: {\n constructor: CatboxRedis,\n options: {\n partition : 'my_cached_data',\n host: 'redis-cluster.domain.com',\n port: 6379,\n db: 0,\n tls: {},\n }\n }\n }\n ]\n});\n```\n\n", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "6.0.2": { - "menu": "- [Options](#options)\n- [Usage](#usage)\n- [Tests](#tests)", - "api": "

    Options

    \n

    The connection can be specified with one (and only one) of:

    \n
      \n
    • \n

      client - a custom Redis client instance where client must:

      \n
        \n
      • be manually started and stopped,
      • \n
      • be compatible with the ioredis module API, and
      • \n
      • expose the status property that must be set to 'ready' when connected.
      • \n
      \n
    • \n
    • \n

      url - a Redis server URL.

      \n
    • \n
    • \n

      socket - a unix socket string.

      \n
    • \n
    • \n

      cluster - an array of { host, port } pairs.

      \n
    • \n
    \n

    Or:

    \n
      \n
    • \nhost - a Redis server hostname. Defaults to '127.0.0.1' if no other connection method specified from the above.
    • \n
    • \nport - a Redis server port or unix domain socket path. Defaults to 6379 if no other connection method specified from the above.
    • \n
    \n

    catbox options:

    \n
      \n
    • \npartition - a string used to prefix all item keys with. Defaults to ''.
    • \n
    \n

    Other supported Redis options:

    \n
      \n
    • \npassword - the Redis authentication password when required.
    • \n
    • \ndb - a Redis database name or number.
    • \n
    • \nsentinels - an array of { host, port } sentinel address pairs.
    • \n
    • \nsentinelName - the name of the sentinel master (when sentinels is specified).
    • \n
    • \ntls - an object representing TLS config options for ioredis.
    • \n
    \n

    The plugin also accepts other redis options not mentioned above.

    \n

    Usage

    \n

    Sample catbox cache initialization:

    \n
    const Catbox = require('@hapi/catbox');\nconst CatboxRedis = require('@hapi/catbox-redis');\n\n\nconst cache = new Catbox.Client(CatboxRedis, {\n    partition : 'my_cached_data',\n    host: 'redis-cluster.domain.com',\n    port: 6379,\n    db: 0,\n    tls: {},\n});
    \n

    When used in a hapi server (hapi version 18 or newer):

    \n
    const Hapi = require('hapi')\nconst CatboxRedis = require('@hapi/catbox-redis');\n\nconst server = new Hapi.Server({\n    cache : [\n        {\n            name: 'my_cache',\n            provider: {\n                constructor: CatboxRedis,\n                options: {\n                    partition : 'my_cached_data',\n                    host: 'redis-cluster.domain.com',\n                    port: 6379,\n                    db: 0,\n                    tls: {},\n                }\n            }\n        }\n    ]\n});
    \n

    Tests

    \n

    The test suite expects:

    \n
      \n
    • a redis server to be running on port 6379
    • \n
    • a redis server listenning to port 6378 and requiring a password: 'secret'
    • \n
    • a redis cluster contains nodes running on ports 7000 to 7005
    • \n
    \n

    See docker-compose.yml

    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Redis adapter for [catbox](https://github.com/hapijs/catbox).", - "forks": 63, - "stars": 69, - "date": "2024-10-23T15:26:12Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/catbox-redis" - }, - "code": { - "name": "code", - "versions": [ - { - "name": "9.0.3", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "8.0.7", - "branch": "v8", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "9.0.3", - "8.0.7" - ], - "api": true, - "isPlugin": false, - "9.0.3": { - "menu": "- [Grammar](#grammar)\n- [Flags](#flags)\n- [`expect()`](#expectvalue-prefix)\n - [Types](#types)\n - [`arguments()`](#arguments)\n - [`array()`](#array)\n - [`boolean()`](#boolean)\n - [`buffer()`](#buffer)\n - [`date()`](#date)\n - [`error()`](#errortype-message)\n - [`function()`](#function)\n - [`number()`](#number)\n - [`regexp()`](#regexp)\n - [`string()`](#string)\n - [`object()`](#object)\n - [Values](#values)\n - [`true()`](#true)\n - [`false()`](#false)\n - [`null()`](#null)\n - [`undefined()`](#undefined)\n - [`NaN()`](#nan)\n - [`include()`](#includevalues)\n - [`startWith()`](#startwithvalue)\n - [`endWith()`](#endwithvalue)\n - [`exist()`](#exist)\n - [`empty()`](#empty)\n - [`length()`](#lengthsize)\n - [`equal()`](#equalvalue-options)\n - [`above()`](#abovevalue)\n - [`least()`](#leastvalue)\n - [`below()`](#belowvalue)\n - [`most()`](#mostvalue)\n - [`within()`](#withinfrom-to)\n - [`between()`](#betweenfrom-to)\n - [`about()`](#aboutvalue-delta)\n - [`instanceof()`](#instanceoftype)\n - [`match()`](#matchregex)\n - [`satisfy()`](#satisfyvalidator)\n - [`throw()`](#throwtype-message)\n - [`await reject()`](#await-rejecttype-message)\n- [`fail()`](#failmessage)\n- [`count()`](#count)\n- [`incomplete()`](#incomplete)\n- [`thrownAt()`](#thrownaterror)\n- [Settings](#settings)\n - [`truncateMessages`](#truncatemessages)\n - [`comparePrototypes`](#compareprototypes)", - "api": "

    Grammar

    \n

    code supports usage of connecting words to make assertions more readable. The inclusion of these\ngrammar elements has no impact over the assertion outcome and are used for human readability only.\nEvery method or property of the assertion object returned by expect() returns this which allows\nchaining addition assertions or grammar words.

    \n

    The supported words are:

    \n
      \n
    • a
    • \n
    • an
    • \n
    • and
    • \n
    • at
    • \n
    • be
    • \n
    • have
    • \n
    • in
    • \n
    • to
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(10).to.be.above(5);\nexpect('abc').to.be.a.string();\nexpect([1, 2]).to.be.an.array();\nexpect(20).to.be.at.least(20);\nexpect('abc').to.have.length(3);\nexpect('abc').to.be.a.string().and.contain(['a', 'b']);\nexpect(6).to.be.in.range(5, 6);
    \n

    Flags

    \n

    The following words toggle a status flag for the current assertion:

    \n
      \n
    • \nnot - inverses the expected result of any assertion.
    • \n
    • \nonce - requires that inclusion matches appear only once in the provided value. Used by include().
    • \n
    • \nonly - requires that only the provided elements appear in the provided value. Used by include().
    • \n
    • \npart - allows a partial match when asserting inclusion. Used by include(). Defaults to false.
    • \n
    • \nshallow - performs a comparison using strict equality (===). Code defaults to deep comparison. Used by equal() and include().
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(10).to.not.be.above(20);\nexpect([1, 2, 3]).to.shallow.include(3);\nexpect([1, 1, 2]).to.only.include([1, 2]);\nexpect([1, 2]).to.once.include([1, 2]);\nexpect([1, 2, 3]).to.part.include([1, 4]);
    \n

    Note that including the same flag twice toggles the last value set. This is especially important when\nchaining multiple assertions in a single statement (e.g. when using the and grammar word).

    \n

    expect(value, [prefix])

    \n

    Generates an assertion object where:

    \n
      \n
    • \nvalue - the reference value on which to apply the assertion rules.
    • \n
    • \nprefix - an optional string used as an error message prefix.
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(10, 'Age').to.be.above(5);
    \n

    Types

    \n

    Asserts that the reference value is of a certain type.

    \n
    arguments()
    \n

    Asserts that the reference value is an arguments object.

    \n
    const Code = require('code');\nconst expect = Code.expect;\nconst func = function () { return arguments; };\nexpect(func()).to.be.arguments();
    \n
    array()
    \n

    Asserts that the reference value is an Array.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect([1, 2]).to.be.an.array();
    \n
    boolean()
    \n

    Asserts that the reference value is a boolean.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(true).to.be.a.boolean();
    \n
    buffer()
    \n

    Asserts that the reference value is a Buffer.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(new Buffer('')).to.be.a.buffer();
    \n
    date()
    \n

    Asserts that the reference value is a Date.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(new Date()).to.be.a.date();
    \n
    error([type], [message])
    \n

    Asserts that the reference value is an error. You can provide optional requirements where:

    \n
      \n
    • \ntype - the instanceof value of the error.
    • \n
    • \nmessage a string or regular expression matching the error message property. Note that a string\nmust provide a full match.
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nconst err = new Error('Oops an error occured.');\nexpect(err).to.be.an.error();\nexpect(err).to.be.an.error(Error);\nexpect(err).to.be.an.error('Oops an error occured.');\nexpect(err).to.be.an.error(Error, /occured/);
    \n
    function()
    \n

    Asserts that the reference value is a function.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(function () {}).to.be.a.function();
    \n
    number()
    \n

    Asserts that the reference value is a number.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(123).to.be.a.number();
    \n
    regexp()
    \n

    Asserts that the reference value is an RegExp.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(/abc/).to.be.a.regexp();
    \n
    string()
    \n

    Asserts that the reference value is a string.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect('abc').to.be.a.string();
    \n
    object()
    \n

    Asserts that the reference value is an object (excluding array, buffer, or other native objects).

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect({ a: '1' }).to.be.an.object();
    \n

    Values

    \n

    Asserts that the reference value is equal to a predefined value.

    \n
    true()
    \n

    Asserts that the reference value is true.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(true).to.be.true();
    \n
    false()
    \n

    Asserts that the reference value is false.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(false).to.be.false();
    \n
    null()
    \n

    Asserts that the reference value is null.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(null).to.be.null();
    \n
    undefined()
    \n

    Asserts that the reference value is undefined.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(undefined).to.be.undefined();
    \n
    NaN()
    \n

    Asserts that the reference value is NaN.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(NaN).to.be.NaN();
    \n

    include(values)

    \n

    Aliases: includes(), contain(), contains()

    \n

    See also: Hoek.contain()

    \n

    Asserts that the reference value (a string, array, or object) includes the provided values where:

    \n
      \n
    • \nvalues - a single or array of values. If the reference value is a string, the values must be strings.\nIf the reference value is an array, the values can be any array member. If the reference value is an object, the values can be key names, or a single object\nwith key-value pairs to match.
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect('abc').to.include('ab');\nexpect('abc').to.only.include('abc');\nexpect('aaa').to.only.include('a');\nexpect('abc').to.once.include('b');\nexpect('abc').to.include(['a', 'c']);\nexpect('abc').to.part.include(['a', 'd']);\n\nexpect([1, 2, 3]).to.include(1);\nexpect([{ a: 1 }]).to.include({ a: 1 });\nexpect([1, 2, 3]).to.include([1, 2]);\nexpect([{ a: 1 }]).to.include([{ a: 1 }]);\nexpect([1, 1, 2]).to.only.include([1, 2]);\nexpect([1, 2]).to.once.include([1, 2]);\nexpect([1, 2, 3]).to.part.include([1, 4]);\nexpect([[1], [2]]).to.include([[1]]);\n\nexpect({ a: 1, b: 2, c: 3 }).to.include('a');\nexpect({ a: 1, b: 2, c: 3 }).to.include(['a', 'c']);\nexpect({ a: 1, b: 2, c: 3 }).to.only.include(['a', 'b', 'c']);\nexpect({ a: 1, b: 2, c: 3 }).to.include({ a: 1 });\nexpect({ a: 1, b: 2, c: 3 }).to.include({ a: 1, c: 3 });\nexpect({ a: 1, b: 2, c: 3 }).to.part.include({ a: 1, d: 4 });\nexpect({ a: 1, b: 2, c: 3 }).to.only.include({ a: 1, b: 2, c: 3 });\nexpect({ a: [1], b: [2], c: [3] }).to.include({ a: [1], c: [3] });
    \n

    startWith(value)

    \n

    Aliases: startsWith(),

    \n

    Asserts that the reference value (a string) starts with the provided value where:

    \n
      \n
    • \nvalue - a string.
    • \n
    \n

    Note that this assertion is case sensitive.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect('https://example.org/secure').to.startWith('https://');
    \n

    endWith(value)

    \n

    Aliases: endsWith(),

    \n

    Asserts that the reference value (a string) ends with the provided value where:

    \n
      \n
    • \nvalue - a string.
    • \n
    \n

    Note that this assertion is case sensitive.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect('http://example.org/relative').to.endWith('/relative');
    \n

    exist()

    \n

    Aliases: exists

    \n

    Asserts that the reference value exists (not null or undefined).

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(4).to.exist();\nexpect(null).to.not.exist();
    \n

    empty()

    \n

    Asserts that the reference value has a length property equal to zero or an object with no keys.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect('abc').to.be.empty();
    \n

    length(size)

    \n

    Asserts that the reference value has a length property matching the provided size or an object with the\nspecified number of keys where:

    \n
      \n
    • \nsize - the required size.
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect('abcd').to.have.length(4);
    \n

    equal(value[, options])

    \n

    Aliases: equals()

    \n

    Asserts that the reference value equals the provided value where:

    \n
      \n
    • \nvalue - the value to compare to.
    • \n
    • \noptions - optional object specifying comparison options. This is ignored on shallow comparisons.
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(5).to.equal(5);\nexpect({ a: 1 }).to.equal({ a: 1 });
    \n

    Deep comparisons (the default) are performed using\nHoek.deepEqual(). The\noptional options argument is passed directly to Hoek.deepEqual(). An example\ndeep comparison which ignores object prototypes is shown below.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(Object.create(null)).to.equal({}, { prototype: false });
    \n

    Strict equality can be checked using the shallow modifier. This yields the same output as a === check.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(5).to.shallow.equal(5);\nexpect({ a: 1 }).to.shallow.equal({ a: 1 }); // fails as they are not the same reference
    \n

    above(value)

    \n

    Aliases: greaterThan()

    \n

    Asserts that the reference value is greater than (>) the provided value where:

    \n
      \n
    • \nvalue - the value to compare to.
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(10).to.be.above(5);
    \n

    least(value)

    \n

    Aliases: min()

    \n

    Asserts that the reference value is at least (>=) the provided value where:

    \n
      \n
    • \nvalue - the value to compare to.
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(10).to.be.at.least(10);
    \n

    below(value)

    \n

    Aliases: lessThan()

    \n

    Asserts that the reference value is less than (<) the provided value where:

    \n
      \n
    • \nvalue - the value to compare to.
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(10).to.be.below(20);
    \n

    most(value)

    \n

    Aliases: max()

    \n

    Asserts that the reference value is at most (<=) the provided value where:

    \n
      \n
    • \nvalue - the value to compare to.
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(10).to.be.at.most(10);
    \n

    within(from, to)

    \n

    Aliases: range()

    \n

    Asserts that the reference value is within (from <= value <= to) the provided values where:

    \n
      \n
    • \nfrom - the start of the range (inclusive).
    • \n
    • \nto - the end of the range (inclusive).
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(10).to.be.within(10, 20);\nexpect(20).to.be.within(10, 20);
    \n

    between(from, to)

    \n

    Asserts that the reference value is between but not equal (from < value < to) the provided values where:

    \n
      \n
    • \nfrom - the start of the range (exclusive).
    • \n
    • \nto - the end of the range (exclusive).
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(15).to.be.between(10, 20);
    \n

    about(value, delta)

    \n

    Asserts that the reference value is about the provided value within a delta margin of difference where:

    \n
      \n
    • \nvalue - the value to compare to.
    • \n
    • \ndelta - the allowed margin of difference.
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(10).to.be.about(9, 1);
    \n

    instanceof(type)

    \n

    Aliases: instanceOf()

    \n

    Asserts that the reference value has the provided instanceof value where:

    \n
      \n
    • \ntype - the type value to match.
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(new Date()).to.be.an.instanceof(Date);
    \n

    match(regex)

    \n

    Aliases: matches()

    \n

    Asserts that the reference value's toString() representation matches the provided regular\nexpression where:

    \n
      \n
    • \nregex - the regular expression to match.
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect('a5').to.match(/\\w\\d/);\nexpect([\"abc\", \"def\"]).to.match(/^[\\w\\d,]*$/);\nexpect(1).to.match(/^\\d$/);
    \n

    satisfy(validator)

    \n

    Aliases: satisfies()

    \n

    Asserts that the reference value satisfies the provided validator function where:

    \n
      \n
    • \nvalidator - a function with the signature function(value) with return value true or false. The\nreference value is passed as the only argument to the validator function and the assertion passes if\nthe return value is true.
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect('x').to.satisfy(function (value) { return value === 'x'; });
    \n

    throw([type], [message])

    \n

    Aliases: throws

    \n

    Asserts that the function reference value throws an exception when called. The provided reference function\nis invoked within a try-catch block and any error throws is caught and compared to the provided optional\nrequirements where:

    \n
      \n
    • \ntype - the instanceof value of the thrown object.
    • \n
    • \nmessage a string or regular expression matching the thrown error message property. Note that a string\nmust provide a full match.
    • \n
    \n
    const NodeUtil = require('util');\nconst Code = require('code');\nconst expect = Code.expect;\n\nconst CustomError = function (message) {\n\n    Error.call(this, message);\n};\n\nNodeUtil.inherit(CustomError, Error)\n\nconst throws = function () {\n\n    throw new CustomError('Oh no!');\n};\n\nexpect(throws).to.throw(CustomError, 'Oh no!');
    \n

    await reject([type], [message])

    \n

    Aliases: rejects

    \n

    Asserts that the Promise reference value rejects with an exception when called. The provided reference\npromise is resolved using an await statement within a try-catch block and any error throws is caught\nand compared to the provided optional requirements where:

    \n
      \n
    • \ntype - the instanceof value of the rejected object.
    • \n
    • \nmessage a string or regular expression matching the rejected error message property. Note that a string\nmust provide a full match.
    • \n
    \n

    Returns a promise resolving to the rejected error object.

    \n
    const NodeUtil = require('util');\nconst Code = require('code');\nconst expect = Code.expect;\n\nconst CustomError = function (message, code) {\n\n    this.message = message;\n    this.code = code;\n};\n\nNodeUtil.inherits(CustomError, Error);\n\nconst rejects = function () {\n\n    return new Promise((resolve, reject) => reject(new CustomError('Oh no!', 123)));\n};\n\nconst err = await expect(rejects()).to.reject(CustomError, 'Oh no!');\nexpect(err.code).to.equal(123);
    \n

    fail(message)

    \n

    Makes the test fail with message.

    \n
    const Code = require('code');\n\nCode.fail('This should not occur');
    \n

    count()

    \n

    Returns the total number of assertions created using the expect() method.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(5).to.not.be.a.string();\nconsole.log(Code.count());\t\t// -> 1
    \n

    incomplete()

    \n

    Returns an array of the locations where incomplete assertions were declared or null if no incomplete assertions found.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(5).to.not.be.a.string;\nconsole.log(Code.incomplete());\t\t// -> [ 'readme.js:667:1' ]
    \n

    thrownAt([error])

    \n

    Returns the filename, line number, and column number of where the error was created. If no error is provided, the current location returned.

    \n
    const Code = require('code');\n\nconst error = new Error('oops');\nCode.thrownAt(error);
    \n

    Settings

    \n

    code can be configured using the module's settings object. The following\nsettings are supported:

    \n

    truncateMessages

    \n

    A Boolean value that, when true, causes long assertion error messages to be\ntruncated for readability. Setting this to false causes the entire message\nto be displayed. Defaults to true.

    \n
    const Code = require('code');\nconst expect = Code.expect;\nconst foo = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];\n\nCode.settings.truncateMessages = false;\nexpect(foo).to.equal([]);
    \n

    comparePrototypes

    \n

    A Boolean value that, when false, ignores object prototypes when doing a deep comparison. Defaults to false.

    \n
    const Code = require('code');\nconst expect = Code.expect;\nconst foo = Object.create(null);\n\nCode.settings.comparePrototypes = false;\nexpect(foo).to.equal({});\n\nCode.settings.comparePrototypes = true;\nexpect(foo).to.equal({}); // fails
    \n", - "intro": "### Introduction\n\n**code** was created as a direct rewrite of the powerful [**chai**](http://chaijs.com) assertions\nlibrary. This virtual fork was created for a few reasons. First, **chai** mixed usage of methods and\nproperties creates a problematic environment in which it is too easy to forget a method `()` and result\nin an assertion that is never executed (and therefore passes incorrectly). This observation was noted by\nthe [**must**](https://github.com/moll/js-must) author.\n\nThe second reason is that similar to [**lab**](https://github.com/hapijs/lab), our test runner, we wanted\nan assertion library that is small, simple, and intuitive - without plugins, extensions, or the overhead\nof having to support testing in the browser. **code** provides much of the same functionality in about\n300 lines of code that are trivial to read in a few minutes.\n\nAnd last, we wanted to experiment with some new features that allow deeper integration between the test\nrunner and assertions library. The first of which are two methods exported (and used by **lab**) for getting\nthe total assertions count (which is a measure of the tests comprehensiveness), and by verifying that every\nassertion created (e.g. every `expect()` call) is also executed. This will alert when a statement like\n`expect(5).to.be.a.string` is not allowed to remain unnoticed (and fail to throw due to the missing `()`).\n\nLike **lab**, the goal is to keep this module small and simple. If you need extensibility or other\nfunctionality, we recommend looking at the many other excellent assertions libraries available.\n", - "example": "### Example\n\n```js\nconst Code = require('@hapi/code');\nconst expect = Code.expect;\n\nexpect(true).to.be.a.boolean().and.to.not.equal(false);\nexpect('this string').to.only.include(['this', 'string']);\n```\n", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "8.0.7": { - "menu": "- [Introduction](#introduction)\n- [Example](#example)\n- [Grammar](#grammar)\n- [Flags](#flags)\n- [`expect()`](#expectvalue-prefix)\n - [Types](#types)\n - [`arguments()`](#arguments)\n - [`array()`](#array)\n - [`boolean()`](#boolean)\n - [`buffer()`](#buffer)\n - [`date()`](#date)\n - [`error()`](#errortype-message)\n - [`function()`](#function)\n - [`number()`](#number)\n - [`regexp()`](#regexp)\n - [`string()`](#string)\n - [`object()`](#object)\n - [Values](#values)\n - [`true()`](#true)\n - [`false()`](#false)\n - [`null()`](#null)\n - [`undefined()`](#undefined)\n - [`NaN()`](#nan)\n - [`include()`](#includevalues)\n - [`startWith()`](#startwithvalue)\n - [`endWith()`](#endwithvalue)\n - [`exist()`](#exist)\n - [`empty()`](#empty)\n - [`length()`](#lengthsize)\n - [`equal()`](#equalvalue-options)\n - [`above()`](#abovevalue)\n - [`least()`](#leastvalue)\n - [`below()`](#belowvalue)\n - [`most()`](#mostvalue)\n - [`within()`](#withinfrom-to)\n - [`between()`](#betweenfrom-to)\n - [`about()`](#aboutvalue-delta)\n - [`instanceof()`](#instanceoftype)\n - [`match()`](#matchregex)\n - [`satisfy()`](#satisfyvalidator)\n - [`throw()`](#throwtype-message)\n - [`await reject()`](#await-rejecttype-message)\n- [`fail()`](#failmessage)\n- [`count()`](#count)\n- [`incomplete()`](#incomplete)\n- [`thrownAt()`](#thrownaterror)\n- [Settings](#settings)\n - [`truncateMessages`](#truncatemessages)\n - [`comparePrototypes`](#compareprototypes)", - "api": "

    Introduction

    \n

    code was created as a direct rewrite of the powerful chai assertions\nlibrary. This virtual fork was created for a few reasons. First, chai mixed usage of methods and\nproperties creates a problematic environment in which it is too easy to forget a method () and result\nin an assertion that is never executed (and therefore passes incorrectly). This observation was noted by\nthe must author.

    \n

    The second reason is that similar to lab, our test runner, we wanted\nan assertion library that is small, simple, and intuitive - without plugins, extensions, or the overhead\nof having to support testing in the browser. code provides much of the same functionality in about\n300 lines of code that are trivial to read in a few minutes.

    \n

    And last, we wanted to experiment with some new features that allow deeper integration between the test\nrunner and assertions library. The first of which are two methods exported (and used by lab) for getting\nthe total assertions count (which is a measure of the tests comprehensiveness), and by verifying that every\nassertion created (e.g. every expect() call) is also executed. This will alert when a statement like\nexpect(5).to.be.a.string is not allowed to remain unnoticed (and fail to throw due to the missing ()).

    \n

    Like lab, the goal is to keep this module small and simple. If you need extensibility or other\nfunctionality, we recommend looking at the many other excellent assertions libraries available.

    \n

    Example

    \n
    const Code = require('@hapi/code');\nconst expect = Code.expect;\n\nexpect(true).to.be.a.boolean().and.to.not.equal(false);\nexpect('this string').to.only.include(['this', 'string']);
    \n

    Grammar

    \n

    code supports usage of connecting words to make assertions more readable. The inclusion of these\ngrammar elements has no impact over the assertion outcome and are used for human readability only.\nEvery method or property of the assertion object returned by expect() returns this which allows\nchaining addition assertions or grammar words.

    \n

    The supported words are:

    \n
      \n
    • a
    • \n
    • an
    • \n
    • and
    • \n
    • at
    • \n
    • be
    • \n
    • have
    • \n
    • in
    • \n
    • to
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(10).to.be.above(5);\nexpect('abc').to.be.a.string();\nexpect([1, 2]).to.be.an.array();\nexpect(20).to.be.at.least(20);\nexpect('abc').to.have.length(3);\nexpect('abc').to.be.a.string().and.contain(['a', 'b']);\nexpect(6).to.be.in.range(5, 6);
    \n

    Flags

    \n

    The following words toggle a status flag for the current assertion:

    \n
      \n
    • \nnot - inverses the expected result of any assertion.
    • \n
    • \nonce - requires that inclusion matches appear only once in the provided value. Used by include().
    • \n
    • \nonly - requires that only the provided elements appear in the provided value. Used by include().
    • \n
    • \npart - allows a partial match when asserting inclusion. Used by include(). Defaults to false.
    • \n
    • \nshallow - performs a comparison using strict equality (===). Code defaults to deep comparison. Used by equal() and include().
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(10).to.not.be.above(20);\nexpect([1, 2, 3]).to.shallow.include(3);\nexpect([1, 1, 2]).to.only.include([1, 2]);\nexpect([1, 2]).to.once.include([1, 2]);\nexpect([1, 2, 3]).to.part.include([1, 4]);
    \n

    Note that including the same flag twice toggles the last value set. This is especially important when\nchaining multiple assertions in a single statement (e.g. when using the and grammar word).

    \n

    expect(value, [prefix])

    \n

    Generates an assertion object where:

    \n
      \n
    • \nvalue - the reference value on which to apply the assertion rules.
    • \n
    • \nprefix - an optional string used as an error message prefix.
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(10, 'Age').to.be.above(5);
    \n

    Types

    \n

    Asserts that the reference value is of a certain type.

    \n
    arguments()
    \n

    Asserts that the reference value is an arguments object.

    \n
    const Code = require('code');\nconst expect = Code.expect;\nconst func = function () { return arguments; };\nexpect(func()).to.be.arguments();
    \n
    array()
    \n

    Asserts that the reference value is an Array.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect([1, 2]).to.be.an.array();
    \n
    boolean()
    \n

    Asserts that the reference value is a boolean.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(true).to.be.a.boolean();
    \n
    buffer()
    \n

    Asserts that the reference value is a Buffer.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(new Buffer('')).to.be.a.buffer();
    \n
    date()
    \n

    Asserts that the reference value is a Date.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(new Date()).to.be.a.date();
    \n
    error([type], [message])
    \n

    Asserts that the reference value is an error. You can provide optional requirements where:

    \n
      \n
    • \ntype - the instanceof value of the error.
    • \n
    • \nmessage a string or regular expression matching the error message property. Note that a string\nmust provide a full match.
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nconst err = new Error('Oops an error occured.');\nexpect(err).to.be.an.error();\nexpect(err).to.be.an.error(Error);\nexpect(err).to.be.an.error('Oops an error occured.');\nexpect(err).to.be.an.error(Error, /occured/);
    \n
    function()
    \n

    Asserts that the reference value is a function.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(function () {}).to.be.a.function();
    \n
    number()
    \n

    Asserts that the reference value is a number.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(123).to.be.a.number();
    \n
    regexp()
    \n

    Asserts that the reference value is an RegExp.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(/abc/).to.be.a.regexp();
    \n
    string()
    \n

    Asserts that the reference value is a string.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect('abc').to.be.a.string();
    \n
    object()
    \n

    Asserts that the reference value is an object (excluding array, buffer, or other native objects).

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect({ a: '1' }).to.be.an.object();
    \n

    Values

    \n

    Asserts that the reference value is equal to a predefined value.

    \n
    true()
    \n

    Asserts that the reference value is true.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(true).to.be.true();
    \n
    false()
    \n

    Asserts that the reference value is false.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(false).to.be.false();
    \n
    null()
    \n

    Asserts that the reference value is null.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(null).to.be.null();
    \n
    undefined()
    \n

    Asserts that the reference value is undefined.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(undefined).to.be.undefined();
    \n
    NaN()
    \n

    Asserts that the reference value is NaN.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(NaN).to.be.NaN();
    \n

    include(values)

    \n

    Aliases: includes(), contain(), contains()

    \n

    See also: Hoek.contain()

    \n

    Asserts that the reference value (a string, array, or object) includes the provided values where:

    \n
      \n
    • \nvalues - a single or array of values. If the reference value is a string, the values must be strings.\nIf the reference value is an array, the values can be any array member. If the reference value is an object, the values can be key names, or a single object\nwith key-value pairs to match.
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect('abc').to.include('ab');\nexpect('abc').to.only.include('abc');\nexpect('aaa').to.only.include('a');\nexpect('abc').to.once.include('b');\nexpect('abc').to.include(['a', 'c']);\nexpect('abc').to.part.include(['a', 'd']);\n\nexpect([1, 2, 3]).to.include(1);\nexpect([{ a: 1 }]).to.include({ a: 1 });\nexpect([1, 2, 3]).to.include([1, 2]);\nexpect([{ a: 1 }]).to.include([{ a: 1 }]);\nexpect([1, 1, 2]).to.only.include([1, 2]);\nexpect([1, 2]).to.once.include([1, 2]);\nexpect([1, 2, 3]).to.part.include([1, 4]);\nexpect([[1], [2]]).to.include([[1]]);\n\nexpect({ a: 1, b: 2, c: 3 }).to.include('a');\nexpect({ a: 1, b: 2, c: 3 }).to.include(['a', 'c']);\nexpect({ a: 1, b: 2, c: 3 }).to.only.include(['a', 'b', 'c']);\nexpect({ a: 1, b: 2, c: 3 }).to.include({ a: 1 });\nexpect({ a: 1, b: 2, c: 3 }).to.include({ a: 1, c: 3 });\nexpect({ a: 1, b: 2, c: 3 }).to.part.include({ a: 1, d: 4 });\nexpect({ a: 1, b: 2, c: 3 }).to.only.include({ a: 1, b: 2, c: 3 });\nexpect({ a: [1], b: [2], c: [3] }).to.include({ a: [1], c: [3] });
    \n

    startWith(value)

    \n

    Aliases: startsWith(),

    \n

    Asserts that the reference value (a string) starts with the provided value where:

    \n
      \n
    • \nvalue - a string.
    • \n
    \n

    Note that this assertion is case sensitive.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect('https://example.org/secure').to.startWith('https://');
    \n

    endWith(value)

    \n

    Aliases: endsWith(),

    \n

    Asserts that the reference value (a string) ends with the provided value where:

    \n
      \n
    • \nvalue - a string.
    • \n
    \n

    Note that this assertion is case sensitive.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect('http://example.org/relative').to.endWith('/relative');
    \n

    exist()

    \n

    Aliases: exists

    \n

    Asserts that the reference value exists (not null or undefined).

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(4).to.exist();\nexpect(null).to.not.exist();
    \n

    empty()

    \n

    Asserts that the reference value has a length property equal to zero or an object with no keys.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect('abc').to.be.empty();
    \n

    length(size)

    \n

    Asserts that the reference value has a length property matching the provided size or an object with the\nspecified number of keys where:

    \n
      \n
    • \nsize - the required size.
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect('abcd').to.have.length(4);
    \n

    equal(value[, options])

    \n

    Aliases: equals()

    \n

    Asserts that the reference value equals the provided value where:

    \n
      \n
    • \nvalue - the value to compare to.
    • \n
    • \noptions - optional object specifying comparison options. This is ignored on shallow comparisons.
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(5).to.equal(5);\nexpect({ a: 1 }).to.equal({ a: 1 });
    \n

    Deep comparisons (the default) are performed using\nHoek.deepEqual(). The\noptional options argument is passed directly to Hoek.deepEqual(). An example\ndeep comparison which ignores object prototypes is shown below.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(Object.create(null)).to.equal({}, { prototype: false });
    \n

    Strict equality can be checked using the shallow modifier. This yields the same output as a === check.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(5).to.shallow.equal(5);\nexpect({ a: 1 }).to.shallow.equal({ a: 1 }); // fails as they are not the same reference
    \n

    above(value)

    \n

    Aliases: greaterThan()

    \n

    Asserts that the reference value is greater than (>) the provided value where:

    \n
      \n
    • \nvalue - the value to compare to.
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(10).to.be.above(5);
    \n

    least(value)

    \n

    Aliases: min()

    \n

    Asserts that the reference value is at least (>=) the provided value where:

    \n
      \n
    • \nvalue - the value to compare to.
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(10).to.be.at.least(10);
    \n

    below(value)

    \n

    Aliases: lessThan()

    \n

    Asserts that the reference value is less than (<) the provided value where:

    \n
      \n
    • \nvalue - the value to compare to.
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(10).to.be.below(20);
    \n

    most(value)

    \n

    Aliases: max()

    \n

    Asserts that the reference value is at most (<=) the provided value where:

    \n
      \n
    • \nvalue - the value to compare to.
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(10).to.be.at.most(10);
    \n

    within(from, to)

    \n

    Aliases: range()

    \n

    Asserts that the reference value is within (from <= value <= to) the provided values where:

    \n
      \n
    • \nfrom - the start of the range (inclusive).
    • \n
    • \nto - the end of the range (inclusive).
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(10).to.be.within(10, 20);\nexpect(20).to.be.within(10, 20);
    \n

    between(from, to)

    \n

    Asserts that the reference value is between but not equal (from < value < to) the provided values where:

    \n
      \n
    • \nfrom - the start of the range (exclusive).
    • \n
    • \nto - the end of the range (exclusive).
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(15).to.be.between(10, 20);
    \n

    about(value, delta)

    \n

    Asserts that the reference value is about the provided value within a delta margin of difference where:

    \n
      \n
    • \nvalue - the value to compare to.
    • \n
    • \ndelta - the allowed margin of difference.
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(10).to.be.about(9, 1);
    \n

    instanceof(type)

    \n

    Aliases: instanceOf()

    \n

    Asserts that the reference value has the provided instanceof value where:

    \n
      \n
    • \ntype - the type value to match.
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(new Date()).to.be.an.instanceof(Date);
    \n

    match(regex)

    \n

    Aliases: matches()

    \n

    Asserts that the reference value's toString() representation matches the provided regular\nexpression where:

    \n
      \n
    • \nregex - the regular expression to match.
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect('a5').to.match(/\\w\\d/);\nexpect([\"abc\", \"def\"]).to.match(/^[\\w\\d,]*$/);\nexpect(1).to.match(/^\\d$/);
    \n

    satisfy(validator)

    \n

    Aliases: satisfies()

    \n

    Asserts that the reference value satisfies the provided validator function where:

    \n
      \n
    • \nvalidator - a function with the signature function(value) with return value true or false. The\nreference value is passed as the only argument to the validator function and the assertion passes if\nthe return value is true.
    • \n
    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect('x').to.satisfy(function (value) { return value === 'x'; });
    \n

    throw([type], [message])

    \n

    Aliases: throws

    \n

    Asserts that the function reference value throws an exception when called. The provided reference function\nis invoked within a try-catch block and any error throws is caught and compared to the provided optional\nrequirements where:

    \n
      \n
    • \ntype - the instanceof value of the thrown object.
    • \n
    • \nmessage a string or regular expression matching the thrown error message property. Note that a string\nmust provide a full match.
    • \n
    \n
    const NodeUtil = require('util');\nconst Code = require('code');\nconst expect = Code.expect;\n\nconst CustomError = function (message) {\n\n    Error.call(this, message);\n};\n\nNodeUtil.inherit(CustomError, Error)\n\nconst throws = function () {\n\n    throw new CustomError('Oh no!');\n};\n\nexpect(throws).to.throw(CustomError, 'Oh no!');
    \n

    await reject([type], [message])

    \n

    Aliases: rejects

    \n

    Asserts that the Promise reference value rejects with an exception when called. The provided reference\npromise is resolved using an await statement within a try-catch block and any error throws is caught\nand compared to the provided optional requirements where:

    \n
      \n
    • \ntype - the instanceof value of the rejected object.
    • \n
    • \nmessage a string or regular expression matching the rejected error message property. Note that a string\nmust provide a full match.
    • \n
    \n

    Returns the rejected error object.

    \n
    const NodeUtil = require('util');\nconst Code = require('code');\nconst expect = Code.expect;\n\nconst CustomError = function (message, code) {\n\n    this.message = message;\n    this.code = code;\n};\n\nNodeUtil.inherits(CustomError, Error);\n\nconst rejects = function () {\n\n    return new Promise((resolve, reject) => reject(new CustomError('Oh no!', 123)));\n};\n\nconst err = await expect(rejects()).to.reject(CustomError, 'Oh no!');\nexpect(err.code).to.equal(123);
    \n

    fail(message)

    \n

    Makes the test fail with message.

    \n
    const Code = require('code');\n\nCode.fail('This should not occur');
    \n

    count()

    \n

    Returns the total number of assertions created using the expect() method.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(5).to.not.be.a.string();\nconsole.log(Code.count());\t\t// -> 1
    \n

    incomplete()

    \n

    Returns an array of the locations where incomplete assertions were declared or null if no incomplete assertions found.

    \n
    const Code = require('code');\nconst expect = Code.expect;\n\nexpect(5).to.not.be.a.string;\nconsole.log(Code.incomplete());\t\t// -> [ 'readme.js:667:1' ]
    \n

    thrownAt([error])

    \n

    Returns the filename, line number, and column number of where the error was created. If no error is provided, the current location returned.

    \n
    const Code = require('code');\n\nconst error = new Error('oops');\nCode.thrownAt(error);
    \n

    Settings

    \n

    code can be configured using the module's settings object. The following\nsettings are supported:

    \n

    truncateMessages

    \n

    A Boolean value that, when true, causes long assertion error messages to be\ntruncated for readability. Setting this to false causes the entire message\nto be displayed. Defaults to true.

    \n
    const Code = require('code');\nconst expect = Code.expect;\nconst foo = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];\n\nCode.settings.truncateMessages = false;\nexpect(foo).to.equal([]);
    \n

    comparePrototypes

    \n

    A Boolean value that, when false, ignores object prototypes when doing a deep comparison. Defaults to false.

    \n
    const Code = require('code');\nconst expect = Code.expect;\nconst foo = Object.create(null);\n\nCode.settings.comparePrototypes = false;\nexpect(foo).to.equal({});\n\nCode.settings.comparePrototypes = true;\nexpect(foo).to.equal({}); // fails
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "BDD assertion library.", - "forks": 74, - "stars": 232, - "date": "2024-10-23T15:37:52Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/code" - }, - "content": { - "name": "content", - "versions": [ - { - "name": "6.0.0", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "5.0.2", - "branch": "v5", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "6.0.0", - "5.0.2" - ], - "api": true, - "isPlugin": false, - "6.0.0": { - "menu": "- [`type()`](#typeheader)\n- [`disposition()`](#dispositionheader)", - "api": "

    type(header)

    \n

    Generates an object containing the associated mime-type, charset and the boundary (if specified).

    \n
    Content.type('application/json; some=property; and=\"another\"');\n// { mime: 'application/json' }\n\nContent.type('text/html; charset=utf-8')\n// { mime: 'text/html', charset: 'utf-8' }\n\nContent.type('multipart/form-data; boundary=asdf');\n// { mime: 'multipart/form-data', boundary: 'asdf' }
    \n

    If the header is invalid (malformed) or missing required data, such as a multipart/form-data header missing its boundary, it returns an HTTP Bad Request error.

    \n

    disposition(header)

    \n

    Generates an object containing the details related to the Content-Disposition header for the form-data content type with support for utf8 encoding.

    \n
    Content.disposition('form-data; name=\"file\"; filename=file.jpg');\n// { name: 'file', filename: 'file.jpg' }\n\nContent.disposition('form-data; name=\"file\"; filename*=utf-8\\'en\\'with%20space');\n// { name: 'file', filename: 'with space' }
    \n

    If the header is invalid (malformed, invalid or missing properties) or is empty/missing, it returns an explanatory error.

    \n", - "intro": "", - "example": "", - "usage": "## Usage\n\n**content** allows to parse HTTP `Content-*` headers, currently based on the rules established in both [RFC 7231 Section 3.1.1.1](https://tools.ietf.org/html/rfc7231#section-3.1.1.1) and [RFC 6266 Section 4.1](http://tools.ietf.org/html/rfc6266#section-4.1).\n", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "5.0.2": { - "menu": "- [Usage](#usage)\n - [`type()`](#typeheader)\n - [`disposition()`](#dispositionheader)", - "api": "

    Usage

    \n

    content allows to parse HTTP Content-* headers, currently based on the rules established in both RFC 7231 Section 3.1.1.1 and RFC 6266 Section 4.1.

    \n

    type(header)

    \n

    Generates an object containing the associated mime-type and the boundary (if specified).

    \n
    Content.type('application/json; some=property; and=\"another\"');\n// { mime: 'application/json' }\n\nContent.type('application/json; boundary=asdf');\n// { mime: 'application/json', boundary: 'asdf' }
    \n

    If the header is invalid (malformed) or missing required data, such as a multipart/form-data header missing its boundary, it returns an HTTP Bad Request error.

    \n

    disposition(header)

    \n

    Generates an object containing the details related to the Content-Disposition header for the form-data content type with support for utf8 encoding.

    \n
    Content.disposition('form-data; name=\"file\"; filename=file.jpg');\n// { name: 'file', filename: 'file.jpg' }\n\nContent.disposition('form-data; name=\"file\"; filename*=utf-8\\'en\\'with%20space');\n// { name: 'file', filename: 'with space' }
    \n

    If the header is invalid (malformed, invalid or missing properties) or is empty/missing, it returns an explanatory error

    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "HTTP Content-* headers parsing.", - "forks": 13, - "stars": 8, - "date": "2024-10-23T15:39:18Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/content" - }, - "cookie": { - "name": "cookie", - "versions": [ - { - "name": "12.0.1", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "11.0.2", - "branch": "v12", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "12.0.1", - "11.0.2" - ], - "api": true, - "isPlugin": true, - "12.0.1": { - "menu": "- [Usage](#usage)", - "api": "

    Usage

    \n

    Cookie authentication provides simple cookie-based session management. The user has to be\nauthenticated via other means, typically a web form, and upon successful authentication\nthe browser receives a reply with a session cookie. The cookie uses Iron to encrypt and sign the session content.

    \n

    Subsequent requests containing the session cookie are authenticated and validated via the provided validate in case the cookie's encrypted content requires validation on each request.

    \n

    It is important to remember a couple of things:

    \n
      \n
    1. Each cookie operates as a bearer token and anyone in possession of the cookie content can use it to impersonate its true owner.
    2. \n
    3. Cookies have a practical maximum length. All of the data you store in a cookie is sent to the browser. If your cookie is too long, browsers may not set it. Read more here and here. If you need to store more data, store a small amount of identifying data in the cookie and use that as a key to a server-side cache system.
    4. \n
    \n

    The 'cookie' scheme takes the following options:

    \n
      \n
    • \n

      cookie - an object with the following:

      \n
        \n
      • \nname - the cookie name. Defaults to 'sid'.
      • \n
      • \npassword - used for Iron cookie encoding. Should be at least 32 characters long.
      • \n
      • \nttl - sets the cookie expires time in milliseconds. Defaults to single browser session (ends\nwhen browser closes). Required when keepAlive is true.
      • \n
      • \ndomain - sets the cookie Domain value. Defaults to none.
      • \n
      • \npath - sets the cookie path value. Defaults to none.
      • \n
      • \nclearInvalid - if true, any authentication cookie that fails validation will be marked as\nexpired in the response and cleared. Defaults to false.
      • \n
      • \nisSameSite - if false omitted. Other options Strict or Lax. Defaults to Strict.
      • \n
      • \nisSecure - if false, the cookie is allowed to be transmitted over insecure connections which\nexposes it to attacks. Defaults to true.
      • \n
      • \nisHttpOnly - if false, the cookie will not include the 'HttpOnly' flag. Defaults to true.
      • \n
      \n
    • \n
    • \n

      keepAlive - if true, automatically sets the session cookie after validation to extend the\ncurrent session for a new ttl duration. Defaults to false.

      \n
    • \n
    • \n

      redirectTo - optional login URI or function function(request) that returns a URI to redirect unauthenticated requests to. Note that it will only\ntrigger when the authentication mode is 'required'. To enable or disable redirections for a specific route,\nset the route plugins config ({ options: { plugins: { cookie: { redirectTo: false } } } }).\nDefaults to no redirection.

      \n
    • \n
    • \n

      appendNext - if redirectTo is true, can be a boolean, string, or object. Defaults to false.

      \n
        \n
      • if set to true, a string, or an object, appends the current request path to the query component\nof the redirectTo URI
      • \n
      • set to a string value or set the name property in an object to define the parameter name.\ndefaults to 'next'\n
      • \n
      • set the raw property of the object to true to determine the current request path based on\nthe raw node.js request object received from the HTTP server callback instead of the processed\nhapi request object
      • \n
      \n
    • \n
    • \n

      async validate - an optional session validation function used to validate the content of the\nsession cookie on each request. Used to verify that the internal session state is still valid\n(e.g. user account still exists). The function has the signature function(request, session)\nwhere:

      \n
        \n
      • \nrequest - is the Hapi request object of the request which is being authenticated.
      • \n
      • \nsession - is the session object set via request.cookieAuth.set().
      • \n
      \n

      Must return an object that contains:

      \n
        \n
      • \nisValid - true if the content of the session is valid, otherwise false.
      • \n
      • \ncredentials - a credentials object passed back to the application in\nrequest.auth.credentials. If value is null or undefined, defaults to session. If\nset, will override the current cookie as if request.cookieAuth.set() was called.
      • \n
      \n
    • \n
    • \n

      requestDecoratorName - USE WITH CAUTION an optional name to use with decorating the request object. Defaults to 'cookieAuth'. Using multiple decorator names for separate authentication strategies could allow a developer to call the methods for the wrong strategy. Potentially resulting in unintended authorized access.

      \n
    • \n
    \n

    When the cookie scheme is enabled on a route, the request.cookieAuth objects is decorated with\nthe following methods:

    \n
      \n
    • \nset(session) - sets the current session. Must be called after a successful login to begin the\nsession. session must be a non-null object, which is set on successful subsequent\nauthentications in request.auth.credentials where:\n
        \n
      • \nsession - the session object.
      • \n
      \n
    • \n
    • \nset(key, value) - sets a specific object key on the current session (which must already exist)\nwhere:\n
        \n
      • \nkey - session key string.
      • \n
      • \nvalue - value to assign key.
      • \n
      \n
    • \n
    • \nclear([key]) - clears the current session or session key where:\n
        \n
      • \nkey - optional key string to remove a specific property of the session. If none provided,\ndefaults to removing the entire session which is used to log the user out.
      • \n
      \n
    • \n
    • \nttl(msecs) - sets the ttl of the current active session where:\n
        \n
      • \nmsecs - the new ttl in milliseconds.
      • \n
      \n
    • \n
    \n

    Because this scheme decorates the request object with session-specific methods, it cannot be\nregistered more than once.

    \n
    'use strict';\n\nconst Hapi = require('@hapi/hapi');\n\n\nconst internals = {};\n\n\n// Simulate database for demo\n\ninternals.users = [\n    {\n        id: 1,\n        name: 'john',\n        password: 'password',\n    },\n];\n\n\ninternals.renderHtml = {\n    login: (message) => {\n\n        return `\n    <html><head><title>Login page</title></head><body>\n    ${message ? '<h3>' + message + '</h3><br></a>' : ''}\n    <form method=\"post\" action=\"/login\">\n      Username: <input type=\"text\" name=\"username\"><br>\n      Password: <input type=\"password\" name=\"password\"><br></a>\n    <input type=\"submit\" value=\"Login\"></form>\n    </body></html>\n      `;\n    },\n    home: (name) => {\n\n        return `\n    <html><head><title>Login page</title></head><body>\n    <h3>Welcome ${name}! You are logged in!</h3>\n    <form method=\"get\" action=\"/logout\">\n      <input type=\"submit\" value=\"Logout\">\n    </form>\n    </body></html>\n      `;\n    }\n};\n\n\ninternals.server = async function () {\n\n    const server = Hapi.server({ port: 8000 });\n\n    await server.register(require('@hapi/cookie'));\n\n    server.auth.strategy('session', 'cookie', {\n\n        cookie: {\n            name: 'sid-example',\n\n            // Don't forget to change it to your own secret password!\n            password: 'password-should-be-32-characters',\n\n            // For working via HTTP in localhost\n            isSecure: false\n        },\n\n        redirectTo: '/login',\n\n        validate: async (request, session) => {\n\n            const account = internals.users.find((user) => (user.id === session.id));\n\n            if (!account) {\n                // Must return { isValid: false } for invalid cookies\n                return { isValid: false };\n            }\n\n            return { isValid: true, credentials: account };\n        }\n    });\n\n    server.auth.default('session');\n\n    server.route([\n        {\n            method: 'GET',\n            path: '/',\n            options: {\n                handler: (request, h) => {\n\n                    return internals.renderHtml.home(request.auth.credentials.name);\n                }\n            }\n        },\n        {\n            method: 'GET',\n            path: '/login',\n            options: {\n                auth: {\n                    mode: 'try'\n                },\n                plugins: {\n                    cookie: {\n                        redirectTo: false\n                    }\n                },\n                handler: async (request, h) => {\n\n                    if (request.auth.isAuthenticated) {\n                        return h.redirect('/');\n                    }\n\n                    return internals.renderHtml.login();\n                }\n            }\n        },\n        {\n            method: 'POST',\n            path: '/login',\n            options: {\n                auth: {\n                    mode: 'try'\n                },\n                handler: async (request, h) => {\n\n                    const { username, password } = request.payload;\n                    if (!username || !password) {\n                        return internals.renderHtml.login('Missing username or password');\n                    }\n\n                    // Try to find user with given credentials\n\n                    const account = internals.users.find(\n                        (user) => user.name === username && user.password === password\n                    );\n\n                    if (!account) {\n                        return internals.renderHtml.login('Invalid username or password');\n                    }\n\n                    request.cookieAuth.set({ id: account.id });\n                    return h.redirect('/');\n                }\n            }\n        },\n        {\n            method: 'GET',\n            path: '/logout',\n            options: {\n                handler: (request, h) => {\n\n                    request.cookieAuth.clear();\n                    return h.redirect('/');\n                }\n            }\n        }\n    ]);\n\n    await server.start();\n    console.log(`Server started at: ${server.info.uri}`);\n};\n\n\ninternals.start = async function() {\n\n    try {\n        await internals.server();\n    }\n    catch (err) {\n        console.error(err.stack);\n        process.exit(1);\n    }\n};\n\ninternals.start();
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "11.0.2": { - "menu": "- [Usage](#usage)", - "api": "

    Usage

    \n

    Cookie authentication provides simple cookie-based session management. The user has to be\nauthenticated via other means, typically a web form, and upon successful authentication\nthe browser receives a reply with a session cookie. The cookie uses Iron to encrypt and sign the session content.

    \n

    Subsequent requests containing the session cookie are authenticated and validated via the provided validate in case the cookie's encrypted content requires validation on each request.

    \n

    It is important to remember a couple of things:

    \n
      \n
    1. Each cookie operates as a bearer token and anyone in possession of the cookie content can use it to impersonate its true owner.
    2. \n
    3. Cookies have a practical maximum length. All of the data you store in a cookie is sent to the browser. If your cookie is too long, browsers may not set it. Read more here and here. If you need to store more data, store a small amount of identifying data in the cookie and use that as a key to a server-side cache system.
    4. \n
    \n

    The 'cookie' scheme takes the following options:

    \n
      \n
    • \n

      cookie - an object with the following:

      \n
        \n
      • \nname - the cookie name. Defaults to 'sid'.
      • \n
      • \npassword - used for Iron cookie encoding. Should be at least 32 characters long.
      • \n
      • \nttl - sets the cookie expires time in milliseconds. Defaults to single browser session (ends\nwhen browser closes). Required when keepAlive is true.
      • \n
      • \ndomain - sets the cookie Domain value. Defaults to none.
      • \n
      • \npath - sets the cookie path value. Defaults to none.
      • \n
      • \nclearInvalid - if true, any authentication cookie that fails validation will be marked as\nexpired in the response and cleared. Defaults to false.
      • \n
      • \nisSameSite - if false omitted. Other options Strict or Lax. Defaults to Strict.
      • \n
      • \nisSecure - if false, the cookie is allowed to be transmitted over insecure connections which\nexposes it to attacks. Defaults to true.
      • \n
      • \nisHttpOnly - if false, the cookie will not include the 'HttpOnly' flag. Defaults to true.
      • \n
      \n
    • \n
    • \n

      keepAlive - if true, automatically sets the session cookie after validation to extend the\ncurrent session for a new ttl duration. Defaults to false.

      \n
    • \n
    • \n

      redirectTo - optional login URI or function function(request) that returns a URI to redirect unauthenticated requests to. Note that it will only\ntrigger when the authentication mode is 'required'. To enable or disable redirections for a specific route,\nset the route plugins config ({ options: { plugins: { cookie: { redirectTo: false } } } }).\nDefaults to no redirection.

      \n
    • \n
    • \n

      appendNext - if redirectTo is true, can be a boolean, string, or object. Defaults to false.

      \n
        \n
      • if set to true, a string, or an object, appends the current request path to the query component\nof the redirectTo URI
      • \n
      • set to a string value or set the name property in an object to define the parameter name.\ndefaults to 'next'\n
      • \n
      • set the raw property of the object to true to determine the current request path based on\nthe raw node.js request object received from the HTTP server callback instead of the processed\nhapi request object
      • \n
      \n
    • \n
    • \n

      async validate - an optional session validation function used to validate the content of the\nsession cookie on each request. Used to verify that the internal session state is still valid\n(e.g. user account still exists). The function has the signature function(request, session)\nwhere:

      \n
        \n
      • \nrequest - is the Hapi request object of the request which is being authenticated.
      • \n
      • \nsession - is the session object set via request.cookieAuth.set().
      • \n
      \n

      Must return an object that contains:

      \n
        \n
      • \nisValid - true if the content of the session is valid, otherwise false.
      • \n
      • \ncredentials - a credentials object passed back to the application in\nrequest.auth.credentials. If value is null or undefined, defaults to session. If\nset, will override the current cookie as if request.cookieAuth.set() was called.
      • \n
      \n
    • \n
    • \n

      requestDecoratorName - USE WITH CAUTION an optional name to use with decorating the request object. Defaults to 'cookieAuth'. Using multiple decorator names for separate authentication strategies could allow a developer to call the methods for the wrong strategy. Potentially resulting in unintended authorized access.

      \n
    • \n
    \n

    When the cookie scheme is enabled on a route, the request.cookieAuth objects is decorated with\nthe following methods:

    \n
      \n
    • \nset(session) - sets the current session. Must be called after a successful login to begin the\nsession. session must be a non-null object, which is set on successful subsequent\nauthentications in request.auth.credentials where:\n
        \n
      • \nsession - the session object.
      • \n
      \n
    • \n
    • \nset(key, value) - sets a specific object key on the current session (which must already exist)\nwhere:\n
        \n
      • \nkey - session key string.
      • \n
      • \nvalue - value to assign key.
      • \n
      \n
    • \n
    • \nclear([key]) - clears the current session or session key where:\n
        \n
      • \nkey - optional key string to remove a specific property of the session. If none provided,\ndefaults to removing the entire session which is used to log the user out.
      • \n
      \n
    • \n
    • \nttl(msecs) - sets the ttl of the current active session where:\n
        \n
      • \nmsecs - the new ttl in milliseconds.
      • \n
      \n
    • \n
    \n

    Because this scheme decorates the request object with session-specific methods, it cannot be\nregistered more than once.

    \n
    'use strict';\n\nconst Hapi = require('@hapi/hapi');\n\n\nconst internals = {};\n\n\n// Simulate database for demo\n\ninternals.users = [\n    {\n        id: 1,\n        name: 'john',\n        password: 'password',\n    },\n];\n\n\ninternals.renderHtml = {\n    login: (message) => {\n\n        return `\n    <html><head><title>Login page</title></head><body>\n    ${message ? '<h3>' + message + '</h3><br></a>' : ''}\n    <form method=\"post\" action=\"/login\">\n      Username: <input type=\"text\" name=\"username\"><br>\n      Password: <input type=\"password\" name=\"password\"><br></a>\n    <input type=\"submit\" value=\"Login\"></form>\n    </body></html>\n      `;\n    },\n    home: (name) => {\n\n        return `\n    <html><head><title>Login page</title></head><body>\n    <h3>Welcome ${name}! You are logged in!</h3>\n    <form method=\"get\" action=\"/logout\">\n      <input type=\"submit\" value=\"Logout\">\n    </form>\n    </body></html>\n      `;\n    }\n};\n\n\ninternals.server = async function () {\n\n    const server = Hapi.server({ port: 8000 });\n\n    await server.register(require('@hapi/cookie'));\n\n    server.auth.strategy('session', 'cookie', {\n\n        cookie: {\n            name: 'sid-example',\n\n            // Don't forget to change it to your own secret password!\n            password: 'password-should-be-32-characters',\n\n            // For working via HTTP in localhost\n            isSecure: false\n        },\n\n        redirectTo: '/login',\n\n        validate: async (request, session) => {\n\n            const account = internals.users.find((user) => (user.id === session.id));\n\n            if (!account) {\n                // Must return { isValid: false } for invalid cookies\n                return { isValid: false };\n            }\n\n            return { isValid: true, credentials: account };\n        }\n    });\n\n    server.auth.default('session');\n\n    server.route([\n        {\n            method: 'GET',\n            path: '/',\n            options: {\n                handler: (request, h) => {\n\n                    return internals.renderHtml.home(request.auth.credentials.name);\n                }\n            }\n        },\n        {\n            method: 'GET',\n            path: '/login',\n            options: {\n                auth: {\n                    mode: 'try'\n                },\n                plugins: {\n                    cookie: {\n                        redirectTo: false\n                    }\n                },\n                handler: async (request, h) => {\n\n                    if (request.auth.isAuthenticated) {\n                        return h.redirect('/');\n                    }\n\n                    return internals.renderHtml.login();\n                }\n            }\n        },\n        {\n            method: 'POST',\n            path: '/login',\n            options: {\n                auth: {\n                    mode: 'try'\n                },\n                handler: async (request, h) => {\n\n                    const { username, password } = request.payload;\n                    if (!username || !password) {\n                        return internals.renderHtml.login('Missing username or password');\n                    }\n\n                    // Try to find user with given credentials\n\n                    const account = internals.users.find(\n                        (user) => user.name === username && user.password === password\n                    );\n\n                    if (!account) {\n                        return internals.renderHtml.login('Invalid username or password');\n                    }\n\n                    request.cookieAuth.set({ id: account.id });\n                    return h.redirect('/');\n                }\n            }\n        },\n        {\n            method: 'GET',\n            path: '/logout',\n            options: {\n                handler: (request, h) => {\n\n                    request.cookieAuth.clear();\n                    return h.redirect('/');\n                }\n            }\n        }\n    ]);\n\n    await server.start();\n    console.log(`Server started at: ${server.info.uri}`);\n};\n\n\ninternals.start = async function() {\n\n    try {\n        await internals.server();\n    }\n    catch (err) {\n        console.error(err.stack);\n        process.exit(1);\n    }\n};\n\ninternals.start();
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Cookie authentication plugin.", - "forks": 100, - "stars": 228, - "date": "2024-10-23T15:43:20Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/cookie" - }, - "crumb": { - "name": "crumb", - "versions": [ - { - "name": "9.0.1", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "8.0.1", - "branch": "v8", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "9.0.1", - "8.0.1" - ], - "api": true, - "isPlugin": true, - "9.0.1": { - "menu": " - [About](#about)\n - [CORS](#cors)\n- [Options](#options)\n - [Registration options](#registration-options)\n - [Routes configuration](#routes-configuration)", - "api": "

    About

    \n

    Crumb is used to diminish CSRF attacks using a random unique token that is validated on the server side.

    \n

    Crumb may be used whenever you want to prevent malicious code to execute system commands, that are performed by HTTP requests. For example, if users are able to publish code on your website, malicious code added by a user could force every other user who opens the page, to load and execute code from a third party website e.g. via an HTML image tag. With Crumb implemented into your hapi.js application, you are able to verify requests with unique tokens and prevent the execution of malicious requests.

    \n

    CORS

    \n

    Crumb has been refactored to securely work with CORS, as OWASP recommends using CSRF protection with CORS.

    \n

    It is highly discouraged to have a production servers cors.origin setting set to \"[*]\" or \"true\" with Crumb as it will leak the crumb token to potentially malicious sites

    \n

    Options

    \n

    The following options are available when registering the plugin.

    \n

    Registration options

    \n
      \n
    • \nkey - the name of the cookie to store the csrf crumb into. Defaults to crumb.
    • \n
    • \nsize - the length of the crumb to generate. Defaults to 43, which is 256 bits, see cryptile for more information.
    • \n
    • \nautoGenerate - whether to automatically generate a new crumb for requests. Defaults to true.
    • \n
    • \naddToViewContext - whether to automatically add the crumb to view contexts as the given key. Defaults to true.
    • \n
    • \ncookieOptions - storage options for the cookie containing the crumb, see the server.state() documentation of hapi for more information. Default to cookieOptions.path=/ . Note that the cookie is not set as secure by default. It should be set as 'secure:true' for production use.\n
    • \n
    • \nheaderName - specify the name of the custom CSRF header. Defaults to X-CSRF-Token.
    • \n
    • \nrestful - RESTful mode that validates crumb tokens from \"X-CSRF-Token\" request header for POST, PUT, PATCH and DELETE server routes. Disables payload/query crumb validation. Defaults to false.
    • \n
    • \nskip - a function with the signature of function (request, h) {}, which when provided, is called for every request. If the provided function returns true, validation and generation of crumb is skipped. Defaults to false.
    • \n
    • \nenforce - defaults to true, using enforce with false will set the CSRF header cookie but won't execute the validation
    • \n
    • \nlogUnauthorized - whether to add to the request log with tag 'crumb' and data 'validation failed' (defaults to false)
    • \n
    \n

    Routes configuration

    \n

    Additionally, some configuration can be passed on a per-route basis. Disable Crumb for a particular route by passing false instead of a configuration object.

    \n
      \n
    • \nkey - the key used in the view contexts and payloads for the crumb. Defaults to plugin.key.
    • \n
    • \nsource - can be either payload or query specifying how the crumb will be sent in requests. Defaults to payload.
    • \n
    • \nrestful - an override for the server's 'restful' setting. Defaults to plugin.restful.
    • \n
    \n", - "intro": "", - "example": "", - "usage": "## Usage\n\n```js\n const Hapi = require('@hapi/hapi');\n const Crumb = require('@hapi/crumb');\n\n const server = new Hapi.Server({ port: 8000 });\n\n (async () => {\n await server.register({\n plugin: Crumb,\n\n // plugin options\n options: {}\n });\n\n server.route({\n path: '/login',\n method: 'GET',\n options: {\n plugins: {\n // route specific options\n crumb: {}\n },\n handler(request, h) {\n // this requires to have a view engine configured\n return h.view('some-view');\n }\n }\n });\n })();\n```\n\nFor a complete example see [the examples folder](https://github.com/hapijs/crumb/tree/master/example).\n", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "8.0.1": { - "menu": " - [About](#about)\n - [CORS](#cors)\n- [Usage](#usage)\n- [Options](#options)\n - [Registration options](#registration-options)\n - [Routes configuration](#routes-configuration)", - "api": "

    About

    \n

    Crumb is used to diminish CSRF attacks using a random unique token that is validated on the server side.

    \n

    Crumb may be used whenever you want to prevent malicious code to execute system commands, that are performed by HTTP requests. For example, if users are able to publish code on your website, malicious code added by a user could force every other user who opens the page, to load and execute code from a third party website e.g. via an HTML image tag. With Crumb implemented into your hapi.js application, you are able to verify requests with unique tokens and prevent the execution of malicious requests.

    \n

    CORS

    \n

    Crumb has been refactored to securely work with CORS, as OWASP recommends using CSRF protection with CORS.

    \n

    It is highly discouraged to have a production servers cors.origin setting set to \"[*]\" or \"true\" with Crumb as it will leak the crumb token to potentially malicious sites

    \n

    Usage

    \n
      const Hapi = require('@hapi/hapi');\n  const Crumb = require('@hapi/crumb');\n\n  const server = new Hapi.Server({ port: 8000 });\n\n  (async () => {\n    await server.register({\n      plugin: Crumb,\n\n      // plugin options\n      options: {}\n    });\n\n    server.route({\n      path: '/login',\n      method: 'GET',\n      options: {\n        plugins: {\n          // route specific options\n          crumb: {}\n        },\n        handler(request, h) {\n          // this requires to have a view engine configured\n          return h.view('some-view');\n        }\n      }\n    });\n  })();
    \n

    For a complete example see the examples folder.

    \n

    Options

    \n

    The following options are available when registering the plugin.

    \n

    Registration options

    \n
      \n
    • \nkey - the name of the cookie to store the csrf crumb into. Defaults to crumb.
    • \n
    • \nsize - the length of the crumb to generate. Defaults to 43, which is 256 bits, see cryptile for more information.
    • \n
    • \nautoGenerate - whether to automatically generate a new crumb for requests. Defaults to true.
    • \n
    • \naddToViewContext - whether to automatically add the crumb to view contexts as the given key. Defaults to true.
    • \n
    • \ncookieOptions - storage options for the cookie containing the crumb, see the server.state() documentation of hapi for more information. Default to cookieOptions.path=/ . Note that the cookie is not set as secure by default. It should be set as 'secure:true' for production use.\n
    • \n
    • \nheaderName - specify the name of the custom CSRF header. Defaults to X-CSRF-Token.
    • \n
    • \nrestful - RESTful mode that validates crumb tokens from \"X-CSRF-Token\" request header for POST, PUT, PATCH and DELETE server routes. Disables payload/query crumb validation. Defaults to false.
    • \n
    • \nskip - a function with the signature of function (request, h) {}, which when provided, is called for every request. If the provided function returns true, validation and generation of crumb is skipped. Defaults to false.
    • \n
    • \nenforce - defaults to true, using enforce with false will set the CSRF header cookie but won't execute the validation
    • \n
    • \nlogUnauthorized - whether to add to the request log with tag 'crumb' and data 'validation failed' (defaults to false)
    • \n
    \n

    Routes configuration

    \n

    Additionally, some configuration can be passed on a per-route basis. Disable Crumb for a particular route by passing false instead of a configuration object.

    \n
      \n
    • \nkey - the key used in the view contexts and payloads for the crumb. Defaults to plugin.key.
    • \n
    • \nsource - can be either payload or query specifying how the crumb will be sent in requests. Defaults to payload.
    • \n
    • \nrestful - an override for the server's 'restful' setting. Defaults to plugin.restful.
    • \n
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "CSRF crumb generation and validation for hapi.", - "forks": 51, - "stars": 171, - "date": "2024-10-23T15:29:18Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/crumb" - }, - "cryptiles": { - "name": "cryptiles", - "versions": [ - { - "name": "6.0.1", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "5.1.0", - "branch": "v5", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "6.0.1", - "5.1.0" - ], - "api": true, - "isPlugin": false, - "6.0.1": { - "menu": "- [Methods](#methods)\n - [`randomString()`](#randomstring-size)\n - [`randomAlphanumString()`](#randomalphanumstring-size)\n - [`randomDigits()`](#randomdigits-size)", - "api": "

    Methods

    \n

    randomString(<Number> size)

    \n

    Returns a cryptographically strong pseudo-random data string. Takes a size argument for the length of the string.

    \n

    randomAlphanumString(<Number> size)

    \n

    Returns a cryptographically strong pseudo-random alphanumeric data string. Takes a size argument for the length of the string.

    \n

    randomDigits(<Number> size)

    \n

    Returns a cryptographically strong pseudo-random data string consisting of only numerical digits (0-9). Takes a size argument for the length of the string.

    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "5.1.0": { - "menu": "- [Methods](#methods)\n - [`randomString()`](#randomstring-size)\n - [`randomAlphanumString()`](#randomalphanumstring-size)\n - [`randomDigits()`](#randomdigits-size)", - "api": "

    Methods

    \n

    randomString(<Number> size)

    \n

    Returns a cryptographically strong pseudo-random data string. Takes a size argument for the length of the string.

    \n

    randomAlphanumString(<Number> size)

    \n

    Returns a cryptographically strong pseudo-random alphanumeric data string. Takes a size argument for the length of the string.

    \n

    randomDigits(<Number> size)

    \n

    Returns a cryptographically strong pseudo-random data string consisting of only numerical digits (0-9). Takes a size argument for the length of the string

    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "General purpose crypto utilities.", - "forks": 26, - "stars": 181, - "date": "2024-10-23T14:40:13Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/cryptiles" - }, - "eslint-plugin": { - "name": "eslint-plugin", - "versions": [ - { - "name": "7.0.0", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "5.1.0", - "branch": "v5", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "7.0.0", - "5.1.0" - ], - "api": true, - "isPlugin": false, - "7.0.0": { - "menu": " - [`@hapi/recommended`](#hapirecommended)\n - [`@hapi/module`](#hapimodule)\n- [Rules](#rules)\n - [capitalize-modules](#capitalize-modules)\n - [`global-scope-only`](#global-scope-only)\n - [for-loop](#for-loop)\n - [Rule options](#rule-options)\n - [`maxDepth`](#maxdepth)\n - [`startIterator`](#startiterator)\n - [no-var](#no-var)\n - [scope-start](#scope-start)\n - [`allow-one-liners`](#allow-one-liners)\n - [`max-in-one-liner`](#max-in-one-liner)\n - [no-arrowception](#no-arrowception)\n- [Config](#config)", - "api": "

    Configurations

    \n

    This ESLint plugin exposes two configurations:

    \n
      \n
    • @hapi/recommended
    • \n
    • @hapi/module
    • \n
    \n

    @hapi/recommended

    \n

    An ESLint configuration containing hapi style guide rules and config. To use in your project, add\n@hapi/eslint-plugin to your package.json, then in your ESLint configuration add:

    \n
    {\n  \"extends\": \"plugin:@hapi/recommended\"\n}
    \n

    @hapi/module

    \n

    The ESLint configuration used by @hapi/lab when you use the linting feature through either the -L command argument or the lint: true configuration.

    \n

    To use it in your project, there are multiple dependencies you need to add to your package.json:

    \n\n

    Then in your ESLint configuration add:

    \n
    {\n  \"extends\": \"plugin:@hapi/module\"\n}
    \n

    Rules

    \n

    This plugin includes the following ESLint rules:

    \n

    capitalize-modules

    \n

    Enforces capitalization of imported module variables.

    \n

    global-scope-only

    \n

    If the string 'global-scope-only' is passed as the first option to this rule,\nthen it will only be enforced on assignments in the module's top level scope.

    \n

    for-loop

    \n

    Enforces for loop iterator variable rules and restricts loop nesting depth.

    \n

    This rule enforces the following:

    \n
      \n
    • Restrict iterator variable names. for loop iterator variables should be named i. Nested loops should use the variables j, k, and so on.
    • \n
    • Restrict loop nesting. You can restrict the maximum nesting of for loops. By default, this limit is three.
    • \n
    • Prevent postfix increment and decrement operators. The hapi style guide does not allow postfix increment and decrement operators in for loop updates. The prefix version of these operators should be used instead.
    • \n
    • Single variable declaration in initialization section. A single var i = 0; is allowed in the initialization section. This only applies to variable declarations, not assignments to existing variables. This means that for (i = 0, j = 0) is allowed if i and j are existing variables. Variable declarations involving destructuring are not allowed.
    • \n
    \n

    Rule options

    \n

    This rule can be configured by providing a single options object. The object supports the following keys.

    \n
    maxDepth
    \n

    A number representing the maximum allowed nesting of for loops. Defaults to three.

    \n
    startIterator
    \n

    The first variable iterator name to use. This defaults to 'i'.

    \n

    no-var

    \n

    Enforces the usage of var declarations only in try-catch scope.

    \n

    scope-start

    \n

    Enforces a new line at the beginning of function scope.

    \n

    allow-one-liners

    \n

    If the string 'allow-one-liners' is passed as the first option to this rule,\nthen functions whose bodies contain zero or one statements are allowed to be\nwritten on a single line. This defaults to true for arrow functions, and\nfalse otherwise.

    \n

    max-in-one-liner

    \n

    The second option to this rule dictates the maximum number of statements allowed\nin the bodies of one line function. This must be used in conjunction with\nallow-one-liners. Defaults to one.

    \n

    no-arrowception

    \n

    Prevents arrow functions that implicitly create additional arrow functions.

    \n

    This rule prevents the pattern () => () => () => ...;.

    \n

    Functions can still be returned by arrow functions whose bodies use curly braces and an explicit return.

    \n

    This rule does not accept any configuration options.

    \n

    Config

    \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
    RuleOption
    '@hapi/capitalize-modules'['warn', 'global-scope-only']
    '@hapi/for-loop'['warn', { maxDepth: 3, startIterator: 'i' }]
    '@hapi/no-var''error'
    '@hapi/scope-start''warn'
    '@hapi/no-arrowception''error'
    'camelcase''off'
    'consistent-return''off'
    'vars-on-top''off'
    'new-cap''off
    'no-console''off'
    'no-constant-condition''error'
    'no-empty''off'
    'no-native-reassign''off'
    'no-underscore-dangle''off'
    'no-undef'['error', { typeof: false }]
    'no-process-exit''off'
    'no-unused-expressions''off'
    'no-regex-spaces''off'
    'no-catch-shadow''off'
    'no-lonely-if''off'
    'brace-style'['warn', 'stroustrup']
    'no-shadow'['warn', { allow: ['err', 'done'] }]
    'no-unused-vars'['warn', { vars: 'all', varsIgnorePattern: '^internals$', args: 'none' }]
    'one-var'['error', 'never']
    'handle-callback-err'['error', '^(e|err|error)$']
    'array-bracket-spacing''warn'
    'dot-notation''warn'
    'eol-last''warn'
    'no-trailing-spaces''warn'
    'no-eq-null''warn'
    'no-extend-native''warn'
    'no-redeclare''warn'
    'no-loop-func''warn'
    'yoda'['warn', 'never']
    'sort-vars''warn'
    'arrow-parens'['error', 'always']
    'arrow-spacing'['error', { before: true, after: true }]
    'quotes'['error', 'single', { allowTemplateLiterals: true }]
    'consistent-this'['error', 'self']
    'new-parens''error'
    'no-array-constructor''error'
    'no-confusing-arrow''error'
    'no-new-object''error'
    'no-spaced-func''error'
    'no-mixed-spaces-and-tabs''error'
    'key-spacing''error'
    'keyword-spacing'['error', { before: true, after: true }]
    'semi'['error', 'always']
    'semi-spacing'['error', { before: false, after: true }]
    'space-before-blocks''error'
    'space-infix-ops''error'
    'space-unary-ops'['warn', { words: true, nonwords: false }]
    'strict'['error', 'global']
    'eqeqeq''error'
    'curly'['error', 'all']
    'no-eval''error'
    'no-else-return''error'
    'no-return-assign''error'
    'no-new-wrappers''error'
    'comma-dangle'['error', 'never']
    'no-sparse-arrays''error'
    'no-ex-assign''error'
    'prefer-arrow-callback''error'
    'prefer-const'['error', { destructuring: 'all' }]
    'indent'['error', 4, { SwitchCase: 1 }]
    'space-before-function-paren'['error', { anonymous: 'always', named: 'never' }]
    'func-style'['error', 'expression']
    'object-curly-spacing'['error', 'always']
    'object-shorthand'['error', 'properties']
    'no-unsafe-finally''error'
    'no-useless-computed-key''error'
    'require-await''error'
    'constructor-super''error'
    'no-buffer-constructor''error'
    'no-mixed-requires''error'
    'no-new-require''error'
    'no-caller''error'
    'no-const-assign''error'
    'no-dupe-class-members''error'
    'no-class-assign''warn'
    'no-new-symbol''error
    'no-this-before-super''error'
    'prefer-rest-params''error'
    'prefer-spread''error'
    'no-useless-call''error'
    'rest-spread-spacing'['error', 'never']
    'no-extra-semi''error'
    'no-dupe-keys''error'
    'padding-line-between-statements'[
    'error',
    { blankLine: 'always', prev: 'directive', next: '*' },
    { blankLine: 'any', prev: 'directive', next: 'directive' },
    { blankLine: 'always', prev: 'cjs-import', next: '*' },
    { blankLine: 'any', prev: 'cjs-import', next: 'cjs-import' },
    { blankLine: 'always', prev: 'cjs-export', next: '*' },
    { blankLine: 'always', prev: 'multiline-block-like', next: '*' },
    { blankLine: 'always', prev: 'class', next: '*' }
    ]
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "5.1.0": { - "menu": " - [`@hapi/recommended`](#hapirecommended)\n - [`@hapi/module`](#hapimodule)\n- [Rules](#rules)\n - [capitalize-modules](#capitalize-modules)\n - [`global-scope-only`](#global-scope-only)\n - [for-loop](#for-loop)\n - [Rule options](#rule-options)\n - [`maxDepth`](#maxdepth)\n - [`startIterator`](#startiterator)\n - [no-var](#no-var)\n - [scope-start](#scope-start)\n - [`allow-one-liners`](#allow-one-liners)\n - [`max-in-one-liner`](#max-in-one-liner)\n - [no-arrowception](#no-arrowception)\n- [Config](#config)", - "api": "

    Configurations

    \n

    This ESLint plugin exposes two configurations:

    \n
      \n
    • @hapi/recommended
    • \n
    • @hapi/module
    • \n
    \n

    @hapi/recommended

    \n

    An ESLint configuration containing hapi style guide rules and config. To use in your project, add\n@hapi/eslint-plugin to your package.json, then in your ESLint configuration add:

    \n
    {\n  \"extends\": \"plugin:@hapi/recommended\"\n}
    \n

    @hapi/module

    \n

    The ESLint configuration used by @hapi/lab when you use the linting feature through either the -L command argument or the lint: true configuration.

    \n

    To use it in your project, there are multiple dependencies you need to add to your package.json:

    \n\n

    Then in your ESLint configuration add:

    \n
    {\n  \"extends\": \"plugin:@hapi/module\"\n}
    \n

    Rules

    \n

    This plugin includes the following ESLint rules:

    \n

    capitalize-modules

    \n

    Enforces capitalization of imported module variables.

    \n

    global-scope-only

    \n

    If the string 'global-scope-only' is passed as the first option to this rule,\nthen it will only be enforced on assignments in the module's top level scope.

    \n

    for-loop

    \n

    Enforces for loop iterator variable rules and restricts loop nesting depth.

    \n

    This rule enforces the following:

    \n
      \n
    • Restrict iterator variable names. for loop iterator variables should be named i. Nested loops should use the variables j, k, and so on.
    • \n
    • Restrict loop nesting. You can restrict the maximum nesting of for loops. By default, this limit is three.
    • \n
    • Prevent postfix increment and decrement operators. The hapi style guide does not allow postfix increment and decrement operators in for loop updates. The prefix version of these operators should be used instead.
    • \n
    • Single variable declaration in initialization section. A single var i = 0; is allowed in the initialization section. This only applies to variable declarations, not assignments to existing variables. This means that for (i = 0, j = 0) is allowed if i and j are existing variables. Variable declarations involving destructuring are not allowed.
    • \n
    \n

    Rule options

    \n

    This rule can be configured by providing a single options object. The object supports the following keys.

    \n
    maxDepth
    \n

    A number representing the maximum allowed nesting of for loops. Defaults to three.

    \n
    startIterator
    \n

    The first variable iterator name to use. This defaults to 'i'.

    \n

    no-var

    \n

    Enforces the usage of var declarations only in try-catch scope.

    \n

    scope-start

    \n

    Enforces a new line at the beginning of function scope.

    \n

    allow-one-liners

    \n

    If the string 'allow-one-liners' is passed as the first option to this rule,\nthen functions whose bodies contain zero or one statements are allowed to be\nwritten on a single line. This defaults to true for arrow functions, and\nfalse otherwise.

    \n

    max-in-one-liner

    \n

    The second option to this rule dictates the maximum number of statements allowed\nin the bodies of one line function. This must be used in conjunction with\nallow-one-liners. Defaults to one.

    \n

    no-arrowception

    \n

    Prevents arrow functions that implicitly create additional arrow functions.

    \n

    This rule prevents the pattern () => () => () => ...;.

    \n

    Functions can still be returned by arrow functions whose bodies use curly braces and an explicit return.

    \n

    This rule does not accept any configuration options.

    \n

    Config

    \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
    RuleOption
    '@hapi/capitalize-modules'['warn', 'global-scope-only']
    '@hapi/for-loop'['warn', { maxDepth: 3, startIterator: 'i' }]
    '@hapi/no-var''error'
    '@hapi/scope-start''warn'
    '@hapi/no-arrowception''error'
    'camelcase''off'
    'consistent-return''off'
    'vars-on-top''off'
    'new-cap''off
    'no-console''off'
    'no-constant-condition''error'
    'no-empty''off'
    'no-native-reassign''off'
    'no-underscore-dangle''off'
    'no-undef'['error', { typeof: false }]
    'no-process-exit''off'
    'no-unused-expressions''off'
    'no-regex-spaces''off'
    'no-catch-shadow''off'
    'no-lonely-if''off'
    'brace-style'['warn', 'stroustrup']
    'no-shadow'['warn', { allow: ['err', 'done'] }]
    'no-unused-vars'['warn', { vars: 'all', varsIgnorePattern: '^internals$', args: 'none' }]
    'one-var'['error', 'never']
    'handle-callback-err'['error', '^(e|err|error)$']
    'array-bracket-spacing''warn'
    'dot-notation''warn'
    'eol-last''warn'
    'no-trailing-spaces''warn'
    'no-eq-null''warn'
    'no-extend-native''warn'
    'no-redeclare''warn'
    'no-loop-func''warn'
    'yoda'['warn', 'never']
    'sort-vars''warn'
    'arrow-parens'['error', 'always']
    'arrow-spacing'['error', { before: true, after: true }]
    'quotes'['error', 'single', { allowTemplateLiterals: true }]
    'consistent-this'['error', 'self']
    'new-parens''error'
    'no-array-constructor''error'
    'no-confusing-arrow''error'
    'no-new-object''error'
    'no-spaced-func''error'
    'no-mixed-spaces-and-tabs''error'
    'key-spacing''error'
    'keyword-spacing'['error', { before: true, after: true }]
    'semi'['error', 'always']
    'semi-spacing'['error', { before: false, after: true }]
    'space-before-blocks''error'
    'space-infix-ops''error'
    'space-unary-ops'['warn', { words: true, nonwords: false }]
    'strict'['error', 'global']
    'eqeqeq''error'
    'curly'['error', 'all']
    'no-eval''error'
    'no-else-return''error'
    'no-return-assign''error'
    'no-new-wrappers''error'
    'comma-dangle'['error', 'never']
    'no-sparse-arrays''error'
    'no-ex-assign''error'
    'prefer-arrow-callback''error'
    'prefer-const'['error', { destructuring: 'all' }]
    'indent'['error', 4, { SwitchCase: 1 }]
    'space-before-function-paren'['error', { anonymous: 'always', named: 'never' }]
    'func-style'['error', 'expression']
    'object-curly-spacing'['error', 'always']
    'object-shorthand'['error', 'properties']
    'no-unsafe-finally''error'
    'no-useless-computed-key''error'
    'require-await''error'
    'constructor-super''error'
    'no-buffer-constructor''error'
    'no-mixed-requires''error'
    'no-new-require''error'
    'no-caller''error'
    'no-const-assign''error'
    'no-dupe-class-members''error'
    'no-class-assign''warn'
    'no-new-symbol''error
    'no-this-before-super''error'
    'prefer-rest-params''error'
    'prefer-spread''error'
    'no-useless-call''error'
    'rest-spread-spacing'['error', 'never']
    'no-extra-semi''error'
    'no-dupe-keys''error'
    'padding-line-between-statements'[
    'error',
    { blankLine: 'always', prev: 'directive', next: '*' },
    { blankLine: 'any', prev: 'directive', next: 'directive' },
    { blankLine: 'always', prev: 'cjs-import', next: '*' },
    { blankLine: 'any', prev: 'cjs-import', next: 'cjs-import' },
    { blankLine: 'always', prev: 'cjs-export', next: '*' },
    { blankLine: 'always', prev: 'multiline-block-like', next: '*' },
    { blankLine: 'always', prev: 'class', next: '*' }
    ]
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "ESLint plugin containing hapi style guide rules and config.", - "forks": 10, - "stars": 21, - "date": "2024-10-22T13:41:18Z", - "updated": "Tue Oct 22 2024", - "link": "https://github.com/hapijs/eslint-plugin" - }, - "file": { - "name": "file", - "versions": [ - { - "name": "3.0.0", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "2.0.0", - "branch": "v2", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "3.0.0", - "2.0.0" - ], - "api": true, - "isPlugin": false, - "3.0.0": { - "menu": "- [Methods](#methods)\n - [`uniqueFilename()`](#uniquefilenamepath-extension)", - "api": "

    Methods

    \n

    uniqueFilename(path, extension)

    \n

    Generate a random file name within a given path and optional extension.

    \n
      \n
    • \npath - The file path within to generate a temporary file.
    • \n
    • \nextension - File extension.
    • \n
    \n
    const File = require('@hapi/file');\n\nconst fileName = File.uniqueFilename('/root', '.txt');  //results in 'C:\\root\\1580115599192-8540-61d96458412e09d9.txt'
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "2.0.0": { - "menu": "- [Methods](#methods)\n - [`uniqueFilename()`](#uniquefilenamepath-extension)", - "api": "

    Methods

    \n

    uniqueFilename(path, extension)

    \n

    Generate a random file name within a given path and optional extension.

    \n
      \n
    • \npath - The file path within to generate a temporary file.
    • \n
    • \nextension - File extension.
    • \n
    \n
    const File = require('@hapi/file');\n\nconst fileName = File.uniqueFilename('/root', '.txt');  //results in 'C:\\root\\1580115599192-8540-61d96458412e09d9.txt'\n``
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "General purpose file utilities.", - "forks": 7, - "stars": 4, - "date": "2022-05-30T23:06:24Z", - "updated": "Tue May 31 2022", - "link": "https://github.com/hapijs/file" - }, - "glue": { - "name": "glue", - "versions": [ - { - "name": "9.0.1", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "8.0.0", - "branch": "v8", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "9.0.1", - "8.0.0" - ], - "api": true, - "isPlugin": false, - "9.0.1": { - "menu": " - [A server composer for hapi.js.](#a-server-composer-for-hapijs)\n - [hapi version dependency](#hapi-version-dependency)\n- [Interface](#interface)\n - [`await compose()`](#await-composemanifest-options)\n - [Notes](#notes)\n- [Usage](#usage)", - "api": "

    A server composer for hapi.js.

    \n

    Glue provides configuration based composition of hapi's Server object. Specifically it wraps

    \n
      \n
    • server = Hapi.server(Options)
    • \n
    • server.register(Plugins, Options)
    • \n
    \n

    calling each based on the configuration generated from the glue manifest.

    \n

    hapi version dependency

    \n

    Version 9 supports hapi v20 and v21 as a peer dependency.\nVersion 8 supports hapi v20\nVersion 7 supports hapi v19\nVersion 6 supports hapi v18\nVersion 5 supports hapi v17

    \n

    As of glue v9, hapi is treated as a peer dependency. It's recommended to include hapi in your package dependencies alongside of glue, however if you're using npm v7+ then peer dependencies are automatically installed.

    \n

    Interface

    \n

    Glue exports a single function compose accepting a JSON manifest specifying the hapi server options and plugin registrations and returns a hapi server object.\nTo start the server use the returned object to call await server.start().

    \n

    await compose(manifest, [options])

    \n

    Composes a hapi server object where:

    \n
      \n
    • \nmanifest - an object having:\n
        \n
      • \nserver - an object containing the options passed to hapi's new Hapi.Server([options])\n
          \n
        • If server.cache is specified, glue will parse the entry and replace any prototype function field (eg. provider) specified as string by calling require() with that string.
        • \n
        \n
      • \n
      • \nregister - an object containing two properties: the plugins to be registered and options to pass to server.register\n
          \n
        • \nplugins - an array of entries to register with hapi's await server.register(plugins, [options])\n
            \n
          • each entry may be one of three alternatives:\n
              \n
            1. A string to be require()d during composition.
            2. \n
            \n
            {\n  register: {\n    plugins: [ 'myplugin' ]\n  }\n}
            \n
              \n
            1. An object containing the plugin property which is a string to be required during composition
            2. \n
            \n
            {\n  register: {\n    plugins: [ { plugin: 'myplugin' } ]\n  }\n}
            \n
              \n
            1. An object containing the plugin property which is the plugin object to be passed directly to await server.register*[]:
            2. \n
            \n
            {\n  register: {\n    plugins: [ { plugin: require('myplugin') } ]\n  }\n}
            \n
          • \n
          • object entries may also contain the options property, which contains the plugin-level options passed to the plugin at registration time.
          • \n
          \n
          {\n  register: {\n    plugins: [ { plugin: 'myplugin', options: { host: 'my-host.com' } } ]\n  }\n}
          \n
            \n
          • object entries may also contain override registration-options such as routes.
          • \n
          \n
          {\n  register: {\n    plugins: [ { plugin: 'myplugin', routes: { prefix: '/test/' } } ]\n  }\n}
          \n
        • \n
        • \noptions - optional registration-options object passed to server.register().
        • \n
        \n
      • \n
      \n
    • \n
    • \noptions - an object containing the following compose options:\n
        \n
      • \nrelativeTo - a file-system path string that is used to resolve loading modules with require. Used in server.cache and register.plugins[]\n
      • \n
      • \npreRegister - an async function that is called prior to registering plugins with the server. The function signature is async function (server) where:\n
          \n
        • \nserver - is the hapi server object.
        • \n
        \n
      • \n
      \n
    • \n
    \n

    compose returns the hapi server object. Call await server.start() to actually start the server.

    \n

    Notes

    \n

    If you are developing a plugin, ensure your plugin dependencies are properly managed to guarantee that all dependencies are loaded before your plugin registration completes. See hapi's server.dependency(dependencies, [after]) for more information.

    \n

    Usage

    \n
    'use strict';\n\nconst Glue = require('@hapi/glue');\n\nconst manifest = {\n    server: {\n        cache: 'redis',\n        port: 8000\n    },\n    register: {\n        plugins: [\n            './awesome-plugin.js',\n            {\n                plugin: require('myplugin'),\n                options: {\n                    uglify: true\n                }\n            },\n            {\n                plugin: './ui-user'\n            },\n            {\n                plugin: './ui-admin',\n                options: {\n                    sessiontime: 500\n                },\n                routes: {\n                    prefix: '/admin'\n                }\n            }\n        ],\n        options: {\n            once: false\n        }\n    }\n};\n\nconst options = {\n    relativeTo: __dirname\n};\n\nconst startServer = async function () {\n    try {\n        const server = await Glue.compose(manifest, options);\n        await server.start();\n        console.log('hapi days!');\n    }\n    catch (err) {\n        console.error(err);\n        process.exit(1);\n    }\n};\n\nstartServer();
    \n

    The above is translated into the following equivalent hapi API calls.

    \n
    'use strict';\n\nconst Hapi = require('@hapi/hapi');\n\nconst startServer = async function () {\n    try {\n        const server = Hapi.server({ cache: [{ provider: require('redis') }], port: 8000 });\n        const plugins = [];\n        const registerOptions = { once: false };\n        let pluginPath;\n\n        pluginPath = Path.join(__dirname, './awesome-plugin.js');\n        plugins.push({ plugin: require(pluginPath) });\n\n        plugins.push({ plugin: require('myplugin'), options:{ uglify: true } });\n\n        pluginPath = Path.join(__dirname, './ui-user');\n        plugins.push({ plugin: require(pluginPath) });\n\n        pluginPath = Path.join(__dirname, './ui-admin');\n        plugins.push({ plugin: require(pluginPath), options: { sessiontime: 500 }, routes: { prefix: '/admin' } });\n\n        await server.register(plugins, registerOptions);\n\n        await server.start();\n        console.log('hapi days!');\n    }\n    catch (err)\n        console.error(err);\n        process.exit(1);\n    }\n};\n\nstartServer();
    \n", - "intro": "## Introduction\n", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "8.0.0": { - "menu": "- [Introduction](#introduction)\n - [A server composer for hapi.js.](#a-server-composer-for-hapijs)\n - [hapi version dependency](#hapi-version-dependency)\n- [Interface](#interface)\n - [`await compose()`](#await-composemanifest-options)\n - [Notes](#notes)\n- [Usage](#usage)", - "api": "

    Introduction

    \n

    A server composer for hapi.js.

    \n

    Glue provides configuration based composition of hapi's Server object. Specifically it wraps

    \n
      \n
    • server = Hapi.server(Options)
    • \n
    • server.register(Plugins, Options)
    • \n
    \n

    calling each based on the configuration generated from the glue manifest.

    \n

    hapi version dependency

    \n

    Version 8 supports hapi v20\nVersion 7 supports hapi v19\nVersion 6 supports hapi v18\nVersion 5 supports hapi v17

    \n

    By default npm will resolve glue's dependency on hapi using the most recent supported version of hapi. To force a specific supported hapi version for your project, include hapi in your package dependencies along side of glue.

    \n

    Interface

    \n

    Glue exports a single function compose accepting a JSON manifest specifying the hapi server options and plugin registrations and returns a hapi server object.\nTo start the server use the returned object to call await server.start().

    \n

    await compose(manifest, [options])

    \n

    Composes a hapi server object where:

    \n
      \n
    • \nmanifest - an object having:\n
        \n
      • \nserver - an object containing the options passed to hapi's new Hapi.Server([options])\n
          \n
        • If server.cache is specified, glue will parse the entry and replace any prototype function field (eg. provider) specified as string by calling require() with that string.
        • \n
        \n
      • \n
      • \nregister - an object containing two properties: the plugins to be registered and options to pass to server.register\n
          \n
        • \nplugins - an array of entries to register with hapi's await server.register(plugins, [options])\n
            \n
          • each entry may be one of three alternatives:\n
              \n
            1. A string to be require()d during composition.
            2. \n
            \n
            {\n  register: {\n    plugins: [ 'myplugin' ]\n  }\n}
            \n
              \n
            1. An object containing the plugin property which is a string to be required during composition
            2. \n
            \n
            {\n  register: {\n    plugins: [ { plugin: 'myplugin' } ]\n  }\n}
            \n
              \n
            1. An object containing the plugin property which is the plugin object to be passed directly to await server.register*[]:
            2. \n
            \n
            {\n  register: {\n    plugins: [ { plugin: require('myplugin') } ]\n  }\n}
            \n
          • \n
          • object entries may also contain the options property, which contains the plugin-level options passed to the plugin at registration time.
          • \n
          \n
          {\n  register: {\n    plugins: [ { plugin: 'myplugin', options: { host: 'my-host.com' } } ]\n  }\n}
          \n
            \n
          • object entries may also contain override registration-options such as routes.
          • \n
          \n
          {\n  register: {\n    plugins: [ { plugin: 'myplugin', routes: { prefix: '/test/' } } ]\n  }\n}
          \n
        • \n
        • \noptions - optional registration-options object passed to server.register().
        • \n
        \n
      • \n
      \n
    • \n
    • \noptions - an object containing the following compose options:\n
        \n
      • \nrelativeTo - a file-system path string that is used to resolve loading modules with require. Used in server.cache and register.plugins[]\n
      • \n
      • \npreRegister - an async function that is called prior to registering plugins with the server. The function signature is async function (server) where:\n
          \n
        • \nserver - is the hapi server object.
        • \n
        \n
      • \n
      \n
    • \n
    \n

    compose returns the hapi server object. Call await server.start() to actually start the server.

    \n

    Notes

    \n

    If you are developing a plugin, ensure your plugin dependencies are properly managed to guarantee that all dependencies are loaded before your plugin registration completes. See hapi's server.dependency(dependencies, [after]) for more information.

    \n

    Usage

    \n
    'use strict';\n\nconst Glue = require('@hapi/glue');\n\nconst manifest = {\n    server: {\n        cache: 'redis',\n        port: 8000\n    },\n    register: {\n        plugins: [\n            './awesome-plugin.js',\n            {\n                plugin: require('myplugin'),\n                options: {\n                    uglify: true\n                }\n            },\n            {\n                plugin: './ui-user'\n            },\n            {\n                plugin: './ui-admin',\n                options: {\n                    sessiontime: 500\n                },\n                routes: {\n                    prefix: '/admin'\n                }\n            }\n        ],\n        options: {\n            once: false\n        }\n    }\n};\n\nconst options = {\n    relativeTo: __dirname\n};\n\nconst startServer = async function () {\n    try {\n        const server = await Glue.compose(manifest, options);\n        await server.start();\n        console.log('hapi days!');\n    }\n    catch (err) {\n        console.error(err);\n        process.exit(1);\n    }\n};\n\nstartServer();
    \n

    The above is translated into the following equivalent hapi API calls.

    \n
    'use strict';\n\nconst Hapi = require('@hapi/hapi');\n\nconst startServer = async function () {\n    try {\n        const server = Hapi.server({ cache: [{ provider: require('redis') }], port: 8000 });\n        const plugins = [];\n        const registerOptions = { once: false };\n        let pluginPath;\n\n        pluginPath = Path.join(__dirname, './awesome-plugin.js');\n        plugins.push({ plugin: require(pluginPath) });\n\n        plugins.push({ plugin: require('myplugin'), options:{ uglify: true } });\n\n        pluginPath = Path.join(__dirname, './ui-user');\n        plugins.push({ plugin: require(pluginPath) });\n\n        pluginPath = Path.join(__dirname, './ui-admin');\n        plugins.push({ plugin: require(pluginPath), options: { sessiontime: 500 }, routes: { prefix: '/admin' } });\n\n        await server.register(plugins, registerOptions);\n\n        await server.start();\n        console.log('hapi days!');\n    }\n    catch (err)\n        console.error(err);\n        process.exit(1);\n    }\n};\n\nstartServer();
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Server composer for hapi.js.", - "forks": 62, - "stars": 245, - "date": "2024-10-23T15:39:45Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/glue" - }, - "h2o2": { - "name": "h2o2", - "versions": [ - { - "name": "10.0.4", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "9.1.0", - "branch": "v9", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "10.0.4", - "9.1.0" - ], - "api": true, - "isPlugin": true, - "10.0.4": { - "menu": "- [Manual loading](#manual-loading)\n- [Options](#options)\n - [`h.proxy()`](#hproxyoptions)\n - [Using the `host`, `port`, `protocol` options](#using-the-host-port-protocol-options)\n - [Using the `uri` option](#using-the-uri-option)\n - [Custom `uri` template values](#custom-uri-template-values)\n - [Using the `mapUri` and `onResponse` options](#using-the-mapuri-and-onresponse-options)\n - [Using a custom http client](#using-a-custom-http-client)", - "api": "

    Manual loading

    \n
    const Hapi = require('@hapi/hapi');\nconst H2o2 = require('@hapi/h2o2');\n\n\nconst start = async function() {\n\n  const server = Hapi.server();\n\n  await server.register(H2o2);\n  await server.start();\n\n  console.log(`Server started at:  ${server.info.uri}`);\n};\n\nstart();
    \n

    Options

    \n

    The plugin can be registered with an optional object specifying defaults to be applied to the proxy handler object.

    \n

    The proxy handler object has the following properties:

    \n
      \n
    • \nhost - upstream service host to proxy requests to. It will have the same path as the client request.
    • \n
    • \nport - upstream service port.
    • \n
    • \nprotocol - protocol to use when making the request to the proxied host:\n
        \n
      • 'http'
      • \n
      • 'https'
      • \n
      \n
    • \n
    • \nuri - absolute URI used instead of host, port, protocol, path, and query. Cannot be used with host, port, protocol, or mapUri.
    • \n
    • \nhttpClient - an http client that abides by the Wreck interface. Defaults to wreck.
    • \n
    • \npassThrough - if set to true, it forwards the headers from the client to the upstream service, headers sent from the upstream service will also be forwarded to the client. Defaults to false.
    • \n
    • \nlocalStatePassThrough - if set tofalse, any locally defined state is removed from incoming requests before being sent to the upstream service. This value can be overridden on a per state basis via the server.state() passThrough option. Defaults to false\n
    • \n
    • \nacceptEncoding - if set to false, does not pass-through the 'Accept-Encoding' HTTP header which is useful for the onResponse post-processing to avoid receiving an encoded response. Can only be used together with passThrough. Defaults to true (passing header).
    • \n
    • \nrejectUnauthorized - sets the rejectUnauthorized property on the https agent making the request. This value is only used when the proxied server uses TLS/SSL. If set it will override the node.js rejectUnauthorized property. If false then ssl errors will be ignored. When true the server certificate is verified and an 500 response will be sent when verification fails. This shouldn't be used alongside the agent setting as the agent will be used instead. Defaults to the https agent default value of true.
    • \n
    • \nxforward - if set to true, sets the 'X-Forwarded-For', 'X-Forwarded-Port', 'X-Forwarded-Proto', 'X-Forwarded-Host' headers when making a request to the proxied upstream endpoint. Defaults to false.
    • \n
    • \nredirects - the maximum number of HTTP redirections allowed to be followed automatically by the handler. Set to false or 0 to disable all redirections (the response will contain the redirection received from the upstream service). If redirections are enabled, no redirections (301, 302, 307, 308) will be passed along to the client, and reaching the maximum allowed redirections will return an error response. Defaults to false.
    • \n
    • \ntimeout - number of milliseconds before aborting the upstream request. Defaults to 180000 (3 minutes).
    • \n
    • \nmapUri - a function used to map the request URI to the proxied URI. Cannot be used together with host, port, protocol, or uri. The function signature is function (request) where:\n
        \n
      • \nrequest - is the incoming request object. The response from this function should be an object with the following properties:\n
          \n
        • \nuri - the absolute proxy URI.
        • \n
        • \nheaders - optional object where each key is an HTTP request header and the value is the header content.
        • \n
        \n
      • \n
      \n
    • \n
    • \nonRequest - a custom function which is passed the upstream request. Function signature is function (req) where:\n\n
    • \n
    • \nonResponse - a custom function for processing the response from the upstream service before sending to the client. Useful for custom error handling of responses from the proxied endpoint or other payload manipulation. Function signature is function (err, res, request, h, settings, ttl) where:\n
        \n
      • \nerr - internal or upstream error returned from attempting to contact the upstream proxy.
      • \n
      • \nres - the node response object received from the upstream service. res is a readable stream (use the wreck module read method to easily convert it to a Buffer or string). Note that it is your responsibility to close the res stream.
      • \n
      • \nrequest - is the incoming request object.
      • \n
      • \nh - the response toolkit.
      • \n
      • \nsettings - the proxy handler configuration.
      • \n
      • \nttl - the upstream TTL in milliseconds if proxy.ttl it set to 'upstream' and the upstream response included a valid 'Cache-Control' header with 'max-age'.
      • \n
      \n
    • \n
    • \nttl - if set to 'upstream', applies the upstream response caching policy to the response using the response.ttl() method (or passed as an argument to the onResponse method if provided).
    • \n
    • \nagent - a node http(s) agent to be used for connections to upstream server.
    • \n
    • \nmaxSockets - sets the maximum number of sockets available per outgoing proxy host connection. false means use the wreck module default value (Infinity). Does not affect non-proxy outgoing client connections. Defaults to Infinity.
    • \n
    • \nsecureProtocol - TLS flag indicating the SSL method to use, e.g. SSLv3_method\nto force SSL version 3. The possible values depend on your installation of OpenSSL. Read the official OpenSSL docs for possible SSL_METHODS.
    • \n
    • \nciphers - TLS list of TLS ciphers to override node's default.\nThe possible values depend on your installation of OpenSSL. Read the official OpenSSL docs for possible TLS_CIPHERS.
    • \n
    • \ndownstreamResponseTime - logs the time spent processing the downstream request using process.hrtime. Defaults to false.
    • \n
    \n

    h.proxy(options)

    \n

    Proxies the request to an upstream endpoint where:

    \n\n

    No return value.

    \n

    The response flow control rules do not apply.

    \n
    const handler = function (request, h) {\n\n    return h.proxy({ host: 'example.com', port: 80, protocol: 'http' });\n};
    \n

    Using the host, port, protocol options

    \n

    Setting these options will send the request to certain route to a specific upstream service with the same path as the original request. Cannot be used with uri, mapUri.

    \n
    server.route({\n    method: 'GET',\n    path: '/',\n    handler: {\n        proxy: {\n            host: '10.33.33.1',\n            port: '443',\n            protocol: 'https'\n        }\n    }\n});
    \n

    Using the uri option

    \n

    Setting this option will send the request to an absolute URI instead of the incoming host, port, protocol, path and query. Cannot be used with host, port, protocol, mapUri.

    \n
    server.route({\n    method: 'GET',\n    path: '/',\n    handler: {\n        proxy: {\n            uri: 'https://some.upstream.service.com/that/has?what=you&want=todo'\n        }\n    }\n});
    \n

    Custom uri template values

    \n

    When using the uri option, there are optional default template values that can be injected from the incoming request:

    \n
      \n
    • {protocol}
    • \n
    • {host}
    • \n
    • {port}
    • \n
    • {path}
    • \n
    • {query}
    • \n
    \n
    server.route({\n    method: 'GET',\n    path: '/foo',\n    handler: {\n        proxy: {\n            uri: '{protocol}://{host}:{port}/go/to/{path}'\n        }\n    }\n});
    \n

    Requests to http://127.0.0.1:8080/foo/ would be proxied to an upstream destination of http://127.0.0.1:8080/go/to/foo

    \n

    Additionally, you can capture request.params and query values and inject them into the upstream uri value using a similar replacement strategy:

    \n
    server.route({\n    method: 'GET',\n    path: '/foo/{bar}',\n    handler: {\n        proxy: {\n            uri: 'https://some.upstream.service.com/some/path/to/{bar}{query}'\n        }\n    }\n});
    \n

    Note The default variables of {protocol}, {host}, {port}, {path}, {query} take precedence - it's best to treat those as reserved when naming your own request.params.

    \n

    Using the mapUri and onResponse options

    \n

    Setting both options with custom functions will allow you to map the original request to an upstream service and to processing the response from the upstream service, before sending it to the client. Cannot be used together with host, port, protocol, or uri.

    \n
    server.route({\n    method: 'GET',\n    path: '/',\n    handler: {\n        proxy: {\n            mapUri: function (request) {\n\n                console.log('doing some additional stuff before redirecting');\n                return {\n                    uri: 'https://some.upstream.service.com/'\n                };\n            },\n            onResponse: async function (err, res, request, h, settings, ttl) {\n\n                console.log('receiving the response from the upstream.');\n                const payload = await Wreck.read(res, { json: true });\n\n                console.log('some payload manipulation if you want to.');\n                const response = h.response(payload);\n                response.headers = res.headers;\n                return response;\n            }\n        }\n    }\n});
    \n

    Using a custom http client

    \n

    By default, h2o2 uses Wreck to perform requests. A custom http client can be provided by passing a client to httpClient, as long as it abides by the wreck interface. The two functions that h2o2 utilizes are request() and parseCacheControl().

    \n
    server.route({\n    method: 'GET',\n    path: '/',\n    handler: {\n        proxy: {\n            httpClient: {\n                request(method, uri, options) {\n                    return axios({\n                        method,\n                        url: 'https://some.upstream.service.com/'\n                    })\n                }\n            }\n        }\n    }\n});
    \n", - "intro": "## Introduction\n\n**h2o2** adds proxying functionality to a hapi server.\n", - "example": "", - "usage": "## Usage\n\nAs one of the handlers for hapi, it is used through the route configuration object.\n", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "9.1.0": { - "menu": "- [Introduction](#introduction)\n- [Manual loading](#manual-loading)\n- [Options](#options)\n- [Usage](#usage)\n - [`h.proxy()`](#hproxyoptions)\n - [Using the `host`, `port`, `protocol` options](#using-the-host-port-protocol-options)\n - [Using the `uri` option](#using-the-uri-option)\n - [Custom `uri` template values](#custom-uri-template-values)\n - [Using the `mapUri` and `onResponse` options](#using-the-mapuri-and-onresponse-options)\n - [Using a custom http client](#using-a-custom-http-client)", - "api": "

    Introduction

    \n

    h2o2 adds proxying functionality to a hapi server.

    \n

    Manual loading

    \n
    const Hapi = require('@hapi/hapi');\nconst H2o2 = require('@hapi/h2o2');\n\n\nconst start = async function() {\n\n  const server = Hapi.server();\n  try {\n    await server.register(H2o2);\n    await server.start();\n\n    console.log(`Server started at:  ${server.info.uri}`);\n  }\n  catch(e) {\n    console.log('Failed to load h2o2');\n  }\n}\n\nstart();
    \n

    Options

    \n

    The plugin can be registered with an optional object specifying defaults to be applied to the proxy handler object.

    \n

    The proxy handler object has the following properties:

    \n
      \n
    • \nhost - upstream service host to proxy requests to. It will have the same path as the client request.
    • \n
    • \nport - upstream service port.
    • \n
    • \nprotocol - protocol to use when making the request to the proxied host:\n
        \n
      • 'http'
      • \n
      • 'https'
      • \n
      \n
    • \n
    • \nuri - absolute URI used instead of host, port, protocol, path, and query. Cannot be used with host, port, protocol, or mapUri.
    • \n
    • \nhttpClient - an http client that abides by the Wreck interface. Defaults to wreck.
    • \n
    • \npassThrough - if set to true, it forwards the headers from the client to the upstream service, headers sent from the upstream service will also be forwarded to the client. Defaults to false.
    • \n
    • \nlocalStatePassThrough - if set tofalse, any locally defined state is removed from incoming requests before being sent to the upstream service. This value can be overridden on a per state basis via the server.state() passThrough option. Defaults to false\n
    • \n
    • \nacceptEncoding - if set to false, does not pass-through the 'Accept-Encoding' HTTP header which is useful for the onResponse post-processing to avoid receiving an encoded response. Can only be used together with passThrough. Defaults to true (passing header).
    • \n
    • \nrejectUnauthorized - sets the rejectUnauthorized property on the https agent making the request. This value is only used when the proxied server uses TLS/SSL. If set it will override the node.js rejectUnauthorized property. If false then ssl errors will be ignored. When true the server certificate is verified and an 500 response will be sent when verification fails. This shouldn't be used alongside the agent setting as the agent will be used instead. Defaults to the https agent default value of true.
    • \n
    • \nxforward - if set to true, sets the 'X-Forwarded-For', 'X-Forwarded-Port', 'X-Forwarded-Proto', 'X-Forwarded-Host' headers when making a request to the proxied upstream endpoint. Defaults to false.
    • \n
    • \nredirects - the maximum number of HTTP redirections allowed to be followed automatically by the handler. Set to false or 0 to disable all redirections (the response will contain the redirection received from the upstream service). If redirections are enabled, no redirections (301, 302, 307, 308) will be passed along to the client, and reaching the maximum allowed redirections will return an error response. Defaults to false.
    • \n
    • \ntimeout - number of milliseconds before aborting the upstream request. Defaults to 180000 (3 minutes).
    • \n
    • \nmapUri - a function used to map the request URI to the proxied URI. Cannot be used together with host, port, protocol, or uri. The function signature is function (request) where:\n
        \n
      • \nrequest - is the incoming request object. The response from this function should be an object with the following properties:\n
          \n
        • \nuri - the absolute proxy URI.
        • \n
        • \nheaders - optional object where each key is an HTTP request header and the value is the header content.
        • \n
        \n
      • \n
      \n
    • \n
    • \nonRequest - a custom function which is passed the upstream request. Function signature is function (req) where:\n\n
    • \n
    • \nonResponse - a custom function for processing the response from the upstream service before sending to the client. Useful for custom error handling of responses from the proxied endpoint or other payload manipulation. Function signature is function (err, res, request, h, settings, ttl) where:\n
        \n
      • \nerr - internal or upstream error returned from attempting to contact the upstream proxy.
      • \n
      • \nres - the node response object received from the upstream service. res is a readable stream (use the wreck module read method to easily convert it to a Buffer or string). Note that it is your responsibility to close the res stream.
      • \n
      • \nrequest - is the incoming request object.
      • \n
      • \nh - the response toolkit.
      • \n
      • \nsettings - the proxy handler configuration.
      • \n
      • \nttl - the upstream TTL in milliseconds if proxy.ttl it set to 'upstream' and the upstream response included a valid 'Cache-Control' header with 'max-age'.
      • \n
      \n
    • \n
    • \nttl - if set to 'upstream', applies the upstream response caching policy to the response using the response.ttl() method (or passed as an argument to the onResponse method if provided).
    • \n
    • \nagent - a node http(s) agent to be used for connections to upstream server.
    • \n
    • \nmaxSockets - sets the maximum number of sockets available per outgoing proxy host connection. false means use the wreck module default value (Infinity). Does not affect non-proxy outgoing client connections. Defaults to Infinity.
    • \n
    • \nsecureProtocol - TLS flag indicating the SSL method to use, e.g. SSLv3_method\nto force SSL version 3. The possible values depend on your installation of OpenSSL. Read the official OpenSSL docs for possible SSL_METHODS.
    • \n
    • \nciphers - TLS list of TLS ciphers to override node's default.\nThe possible values depend on your installation of OpenSSL. Read the official OpenSSL docs for possible TLS_CIPHERS.
    • \n
    • \ndownstreamResponseTime - logs the time spent processing the downstream request using process.hrtime. Defaults to false.
    • \n
    \n

    Usage

    \n

    As one of the handlers for hapi, it is used through the route configuration object.

    \n

    h.proxy(options)

    \n

    Proxies the request to an upstream endpoint where:

    \n\n

    No return value.

    \n

    The response flow control rules do not apply.

    \n
    const handler = function (request, h) {\n\n    return h.proxy({ host: 'example.com', port: 80, protocol: 'http' });\n};
    \n

    Using the host, port, protocol options

    \n

    Setting these options will send the request to certain route to a specific upstream service with the same path as the original request. Cannot be used with uri, mapUri.

    \n
    server.route({\n    method: 'GET',\n    path: '/',\n    handler: {\n        proxy: {\n            host: '10.33.33.1',\n            port: '443',\n            protocol: 'https'\n        }\n    }\n});
    \n

    Using the uri option

    \n

    Setting this option will send the request to an absolute URI instead of the incoming host, port, protocol, path and query. Cannot be used with host, port, protocol, mapUri.

    \n
    server.route({\n    method: 'GET',\n    path: '/',\n    handler: {\n        proxy: {\n            uri: 'https://some.upstream.service.com/that/has?what=you&want=todo'\n        }\n    }\n});
    \n

    Custom uri template values

    \n

    When using the uri option, there are optional default template values that can be injected from the incoming request:

    \n
      \n
    • {protocol}
    • \n
    • {host}
    • \n
    • {port}
    • \n
    • {path}
    • \n
    \n
    server.route({\n    method: 'GET',\n    path: '/foo',\n    handler: {\n        proxy: {\n            uri: '{protocol}://{host}:{port}/go/to/{path}'\n        }\n    }\n});
    \n

    Requests to http://127.0.0.1:8080/foo/ would be proxied to an upstream destination of http://127.0.0.1:8080/go/to/foo

    \n

    Additionally, you can capture request.params values and inject them into the upstream uri value using a similar replacment strategy:

    \n
    server.route({\n    method: 'GET',\n    path: '/foo/{bar}',\n    handler: {\n        proxy: {\n            uri: 'https://some.upstream.service.com/some/path/to/{bar}'\n        }\n    }\n});
    \n

    Note The default variables of {protocol}, {host}, {port}, {path} take precedence - it's best to treat those as reserved when naming your own request.params.

    \n

    Using the mapUri and onResponse options

    \n

    Setting both options with custom functions will allow you to map the original request to an upstream service and to processing the response from the upstream service, before sending it to the client. Cannot be used together with host, port, protocol, or uri.

    \n
    server.route({\n    method: 'GET',\n    path: '/',\n    handler: {\n        proxy: {\n            mapUri: function (request) {\n\n                console.log('doing some additional stuff before redirecting');\n                return {\n                    uri: 'https://some.upstream.service.com/'\n                };\n            },\n            onResponse: async function (err, res, request, h, settings, ttl) {\n\n                console.log('receiving the response from the upstream.');\n                const payload = await Wreck.read(res, { json: true });\n\n                console.log('some payload manipulation if you want to.');\n                const response = h.response(payload);\n                response.headers = res.headers;\n                return response;\n            }\n        }\n    }\n});
    \n

    Using a custom http client

    \n

    By default, h2o2 uses Wreck to perform requests. A custom http client can be provided by passing a client to httpClient, as long as it abides by the wreck interface. The two functions that h2o2 utilizes are request() and parseCacheControl().

    \n
    server.route({\n    method: 'GET',\n    path: '/',\n    handler: {\n        proxy: {\n            httpClient: {\n                request(method, uri, options) {\n                    return axios({\n                        method,\n                        url: 'https://some.upstream.service.com/'\n                    })\n                }\n            }\n        }\n    }\n});
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Proxy handler for hapi.js.", - "forks": 66, - "stars": 165, - "date": "2024-10-23T15:12:00Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/h2o2" - }, - "heavy": { - "name": "heavy", - "versions": [ - { - "name": "8.0.1", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "7.0.1", - "branch": "v7", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "8.0.1", - "7.0.1" - ], - "api": false, - "isPlugin": false, - "8.0.1": { - "menu": "", - "api": "", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "7.0.1": { - "menu": "", - "api": "", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Measure process load.", - "forks": 15, - "stars": 74, - "date": "2024-10-23T14:51:56Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/heavy" - }, - "hoek": { - "name": "hoek", - "versions": [ - { - "name": "11.0.4", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "9.3.0", - "branch": "v9", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "11.0.4", - "9.3.0" - ], - "api": true, - "isPlugin": false, - "11.0.4": { - "menu": "- [Object](#object)\n - [clone()](#cloneobj-options)\n - [merge()](#mergetarget-source-options)\n - [applyToDefaults()](#applytodefaultsdefaults-source-options)\n - [deepEqual()](#deepequala-b-options)\n - [intersect()](#intersectarray1-array2-options)\n - [contain()](#containref-values-options)\n - [flatten()](#flattenarray-target)\n - [reach()](#reachobj-chain-options)\n - [reachTemplate()](#reachtemplateobj-template-options)\n - [stringify()](#stringifyargs)\n- [Bench](#bench)\n- [Escaping Characters](#escaping-characters)\n - [escapeHtml()](#escapehtmlstring)\n - [escapeHeaderAttribute()](#escapeheaderattributeattribute)\n - [escapeJson()](#escapejsonstring)\n - [escapeRegex()](#escaperegexstring)\n- [Errors](#errors)\n - [assert()](#assertcondition-message)\n- [Function](#function)\n - [once()](#oncefn)\n - [ignore](#ignore)\n- [Promises](#promises)\n - [wait()](#waittimeout-returnvalue)\n - [block()](#block)\n - [isPromise()](#ispromisepromise)", - "api": "

    Object

    \n

    hoek provides several helpful methods for objects and arrays.

    \n

    clone(obj, [options])

    \n

    Clones an object or an array. A deep copy is made (duplicates everything, including values that are\nobjects, as well as non-enumerable properties) where:

    \n
      \n
    • \nobj - the object to be cloned.
    • \n
    • \noptions - optional settings:\n
        \n
      • \nsymbols - clone symbol properties. Defaults to true.
      • \n
      • \nshallow - one of:\n
          \n
        • an array of object key strings (dot-separated or array-based key paths) to shallow copy from obj instead of deep.
        • \n
        • \ntrue to shallow copy all object properties. Used to shallow copy an object with non-enumerable properties and prototype;
        • \n
        \n
      • \n
      \n
    • \n
    \n
    const nestedObj = {\n        w: /^something$/ig,\n        x: {\n            a: [1, 2, 3],\n            b: 123456,\n            c: new Date()\n        },\n        y: 'y',\n        z: new Date()\n    };\n\nconst copy = Hoek.clone(nestedObj);\n\ncopy.x.b = 100;\n\nconsole.log(copy.y);        // results in 'y'\nconsole.log(nestedObj.x.b); // results in 123456\nconsole.log(copy.x.b);      // results in 100
    \n

    Clones an object or array excluding some keys which are shallow copied:

    \n
    const nestedObj = {\n        w: /^something$/ig,\n        x: {\n            a: [1, 2, 3],\n            b: 123456,\n            c: new Date()\n        },\n        y: 'y',\n        z: new Date()\n    };\n\nconst copy = Hoek.clone(nestedObj, { shallow: ['x'] });\n\ncopy.x.b = 100;\n\nconsole.log(copy.y);        // results in 'y'\nconsole.log(nestedObj.x.b); // results in 100\nconsole.log(copy.x.b);      // results in 100
    \n

    merge(target, source, [options])

    \n

    Merge all the properties of source into target where:

    \n
      \n
    • \ntarget - the object onto which the properties of source are copied to.
    • \n
    • \nsource - the object copied onto target.
    • \n
    • \noptions - optional settings:\n
        \n
      • \nnullOverride - if true, a null value in the source overrides any existing value in the defaults.\nIf false, null values in the source are ignored. Defaults to true.
      • \n
      • \nmergeArrays - if true, array values from source are appended to existing array values in target.\nDefaults to true.
      • \n
      • \nsymbols - clone symbol properties. Defaults to true.
      • \n
      \n
    • \n
    \n

    Note that source wins in conflict, and by default null and undefined from source are applied.\nMerge is destructive where the target is modified. For non destructive merge, use applyToDefaults.

    \n
    const target = {a: 1, b : 2};\nconst source = {a: 0, c: 5};\nconst source2 = {a: null, c: 5};\n\nHoek.merge(target, source);         // results in {a: 0, b: 2, c: 5}\nHoek.merge(target, source2);        // results in {a: null, b: 2, c: 5}\nHoek.merge(target, source2, { nullOverride: false} ); // results in {a: 1, b: 2, c: 5}\n\nconst targetArray = [1, 2, 3];\nconst sourceArray = [4, 5];\n\nHoek.merge(targetArray, sourceArray);              // results in [1, 2, 3, 4, 5]\nHoek.merge(targetArray, sourceArray, { mergeArrays: false }); // results in [4, 5]
    \n

    applyToDefaults(defaults, source, [options])

    \n

    Apply source to a copy of the defaults where:

    \n
      \n
    • \ndefaults - the default object to clone and then apply source onto.
    • \n
    • \nsource - the object applied to the defaults.
    • \n
    • \noptions - optional settings:\n
        \n
      • \nnullOverride - if true, a null value in the source overrides any existing value in the defaults.\nIf false, null values in the source are ignored. Defaults to false.
      • \n
      • \nshallow - an array of dot-separated or array-based key paths to shallow copy values in source.
      • \n
      \n
    • \n
    \n
    const defaults = { host: \"localhost\", port: 8000 };\nconst source = { port: 8080 };\n\nconst config = Hoek.applyToDefaults(defaults, source); // results in { host: \"localhost\", port: 8080 }
    \n

    Apply source with a null value to a copy of the defaults

    \n
    const defaults = { host: \"localhost\", port: 8000 };\nconst source = { host: null, port: 8080 };\n\nconst config = Hoek.applyToDefaults(defaults, source, { nullOverride: true }); // results in { host: null, port: 8080 }
    \n

    Apply source to a copy of the defaults where the shallow keys specified in the last parameter are shallow copied from source instead of merged

    \n
    const defaults = {\n    db: {\n        server: {\n            host: \"localhost\",\n            port: 8000\n        },\n        name: 'example'\n    }\n};\n\nconst source = { server: { port: 8080 } };\n\nconst config = Hoek.applyToDefaults(defaults, source, { shallow: ['db.server'] });        // results in { db: { server: { port: 8080 }, name: 'example' } }\nconst config = Hoek.applyToDefaults(defaults, source, { shallow: [['db', 'server']] });   // results in { db: { server: { port: 8080 }, name: 'example' } }
    \n

    deepEqual(a, b, [options])

    \n

    Performs a deep comparison of the two values including support for circular dependencies,\nprototype, and enumerable properties, where:

    \n
      \n
    • \na - the first value.
    • \n
    • \nb - the second value.
    • \n
    • \noptions - optional settings:\n
        \n
      • \ndeepFunction - when true, function values are deep compared using their source code and\nobject properties. Defaults to false.
      • \n
      • \npart - when true, allows a partial match where some of b is present in a. Defaults to\nfalse.
      • \n
      • \nprototype - when false, prototype comparisons are skipped. Defaults to true`.
      • \n
      • \nskip - an array of key name strings to skip comparing. The keys can be found in any level\nof the object. Note that both values must contain the key - only the value comparison is\nskipped. Only applies to plain objects and deep functions (not to map, sets, etc.). Defaults\nto no skipping.
      • \n
      • \nsymbols - when false, symbol properties are ignored. Defaults to true.
      • \n
      \n
    • \n
    \n
    Hoek.deepEqual({ a: [1, 2], b: 'string', c: { d: true } }, { a: [1, 2], b: 'string', c: { d: true } }); //results in true\nHoek.deepEqual(Object.create(null), {}, { prototype: false }); //results in true\nHoek.deepEqual(Object.create(null), {}); //results in false
    \n

    intersect(array1, array2, [options])

    \n

    Find the common unique items betwee two arrays where:

    \n
      \n
    • \narray1 - the first array.
    • \n
    • \narray2 - the second array.
    • \n
    • \noptions - optional settings:\n
        \n
      • \nfirst - if true, return only the first intersecting item. Defaults to false.
      • \n
      \n
    • \n
    \n
    const array1 = [1, 2, 3];\nconst array2 = [1, 4, 5];\n\nconst newArray = Hoek.intersect(array1, array2); // results in [1]
    \n

    contain(ref, values, [options])

    \n

    Tests if the reference value contains the provided values where:

    \n
      \n
    • \nref - the reference string, array, or object.
    • \n
    • \nvalues - a single or array of values to find within the ref value. If ref is an object, values can be a key name,\nan array of key names, or an object with key-value pairs to compare.
    • \n
    • \noptions - an optional object with the following optional settings:\n
        \n
      • \ndeep - if true, performed a deep comparison of the values.
      • \n
      • \nonce - if true, allows only one occurrence of each value.
      • \n
      • \nonly - if true, does not allow values not explicitly listed.
      • \n
      • \npart - if true, allows partial match of the values (at least one must always match).
      • \n
      • \nsymbols - clone symbol properties. Defaults to true.
      • \n
      \n
    • \n
    \n

    Note: comparing a string to overlapping values will result in failed comparison (e.g. contain('abc', ['ab', 'bc'])).\nAlso, if an object key's value does not match the provided value, false is returned even when part is specified.

    \n
    Hoek.contain('aaa', 'a', { only: true });\t\t\t\t\t\t\t// true\nHoek.contain([{ a: 1 }], [{ a: 1 }], { deep: true });\t\t\t\t// true\nHoek.contain([1, 2, 2], [1, 2], { once: true });\t\t\t\t\t// false\nHoek.contain({ a: 1, b: 2, c: 3 }, { a: 1, d: 4 }, { part: true }); // true
    \n

    flatten(array, [target])

    \n

    Flatten an array

    \n
    const array = [1, [2, 3]];\n\nconst flattenedArray = Hoek.flatten(array); // results in [1, 2, 3]\n\narray = [1, [2, 3]];\ntarget = [4, [5]];\n\nflattenedArray = Hoek.flatten(array, target); // results in [4, [5], 1, 2, 3]
    \n

    reach(obj, chain, [options])

    \n

    Converts an object key chain string or array to reference

    \n
      \n
    • \noptions - optional settings\n
        \n
      • \nseparator - string to split chain path on, defaults to '.'
      • \n
      • \ndefault - value to return if the path or value is not present, default is undefined\n
      • \n
      • \nstrict - if true, will throw an error on missing member, default is false\n
      • \n
      • \nfunctions - if true, allow traversing functions for properties. false will throw an\nerror if a function is part of the chain. Defaults to true.
      • \n
      • \niterables - if true, allows traversing Set and Map objects. false will result in\nundefined return value is the chain contains any Set or Map objects. Note that enabling\niterables can impact performance by up to 10% for all calls regardless of the presence of\nSet or Map objects. Defaults to false.
      • \n
      \n
    • \n
    \n

    A chain can be a string that will be split into key names using separator,\nor an array containing each individual key name.

    \n

    A chain including negative numbers will work like negative indices on an array.

    \n

    If chain is null, undefined or false, the object itself will be returned.

    \n
    const chain = 'a.b.c';\nconst obj = {a : {b : { c : 1}}};\n\nHoek.reach(obj, chain); // returns 1\n\nconst chain = ['a', 'b', -1];\nconst obj = {a : {b : [2,3,6]}};\n\nHoek.reach(obj, chain); // returns 6
    \n

    reachTemplate(obj, template, [options])

    \n

    Replaces string parameters ({name}) with their corresponding object key values by applying the\nreach() method where:

    \n
      \n
    • \nobj - the context object used for key lookup.
    • \n
    • \ntemplate - a string containing {} parameters.
    • \n
    • \noptions - optional reach() options.
    • \n
    \n
    const template = '1+{a.b.c}=2';\nconst obj = { a: { b: { c: 1 } } };\n\nHoek.reachTemplate(obj, template); // returns '1+1=2'
    \n

    stringify(...args)

    \n

    Converts an object to string using the built-in JSON.stringify() method with the difference that any errors are caught\nand reported back in the form of the returned string. Used as a shortcut for displaying information to the console (e.g. in\nerror message) without the need to worry about invalid conversion.

    \n
    const a = {};\na.b = a;\nHoek.stringify(a);\t\t// Returns '[Cannot display object: Converting circular structure to JSON]'
    \n

    Bench

    \n

    Same as Timer with the exception that ts stores the internal node clock which is not related to Date.now() and cannot be used to display\nhuman-readable timestamps. More accurate for benchmarking or internal timers.

    \n

    Escaping Characters

    \n

    hoek provides convenient methods for escaping html characters. The escaped characters are as followed:

    \n
    internals.htmlEscaped = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#x27;',\n    '`': '&#x60;'\n};
    \n

    escapeHtml(string)

    \n
    const string = '<html> hey </html>';\nconst escapedString = Hoek.escapeHtml(string); // returns &lt;html&gt; hey &lt;/html&gt;
    \n

    escapeHeaderAttribute(attribute)

    \n

    Escape attribute value for use in HTTP header

    \n
    const a = Hoek.escapeHeaderAttribute('I said \"go w\\\\o me\"');  //returns I said \\\"go w\\\\o me\\\"
    \n

    escapeJson(string)

    \n

    Unicode escapes the characters <, >, and & to prevent mime-sniffing older browsers mistaking JSON as HTML, and escapes line and paragraph separators for JSONP and script contexts.

    \n
    const lineSeparator = String.fromCharCode(0x2028);\nconst a = Hoek.escapeJson('I said <script>confirm(&).' + lineSeparator);  //returns I said \\\\u003cscript\\\\u003econfirm(\\\\u0026).\\\\u2028
    \n

    escapeRegex(string)

    \n

    Escape string for Regex construction

    \n
    const a = Hoek.escapeRegex('4^f$s.4*5+-_?%=#!:@|~\\\\/`\"(>)[<]d{}s,');  // returns 4\\^f\\$s\\.4\\*5\\+\\-_\\?%\\=#\\!\\:@\\|~\\\\\\/`\"\\(>\\)\\[<\\]d\\{\\}s\\,
    \n

    Errors

    \n

    assert(condition, message)

    \n
    const a = 1, b = 2;\n\nHoek.assert(a === b, 'a should equal b');  // Throws 'a should equal b'
    \n

    Note that you may also pass an already created Error object as the second parameter, and assert will throw that object.

    \n
    const a = 1, b = 2;\n\nHoek.assert(a === b, new Error('a should equal b')); // Throws the given error object
    \n

    Function

    \n

    once(fn)

    \n

    Returns a new function that can be run multiple times, but makes sure fn is only run once.

    \n
    const myFn = function () {\n    console.log('Ran myFn');\n};\n\nconst onceFn = Hoek.once(myFn);\nonceFn(); // results in \"Ran myFn\"\nonceFn(); // results in undefined
    \n

    ignore

    \n

    A simple no-op function. It does nothing at all.

    \n

    Promises

    \n

    wait(timeout, [returnValue])

    \n

    Resolve the promise after timeout milliseconds with the provided returnValue.

    \n
    await Hoek.wait(2000); // waits for 2 seconds\nconst timeout = Hoek.wait(1000, 'timeout'); // resolves after 1s with 'timeout'
    \n

    block()

    \n

    A no-op Promise. Does nothing.

    \n

    isPromise(promise)

    \n

    Determines if an item is a promise where:

    \n
      \n
    • \npromise - the item being tested.
    • \n
    \n

    Returns true is the item is a promise, otherwise false.

    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "9.3.0": { - "menu": "- [Object](#object)\n - [clone()](#cloneobj-options)\n - [merge()](#mergetarget-source-options)\n - [applyToDefaults()](#applytodefaultsdefaults-source-options)\n - [deepEqual()](#deepequala-b-options)\n - [intersect()](#intersectarray1-array2-options)\n - [contain()](#containref-values-options)\n - [flatten()](#flattenarray-target)\n - [reach()](#reachobj-chain-options)\n - [reachTemplate()](#reachtemplateobj-template-options)\n - [stringify()](#stringifyargs)\n- [Bench](#bench)\n- [Escaping Characters](#escaping-characters)\n - [escapeHtml()](#escapehtmlstring)\n - [escapeHeaderAttribute()](#escapeheaderattributeattribute)\n - [escapeJson()](#escapejsonstring)\n - [escapeRegex()](#escaperegexstring)\n- [Errors](#errors)\n - [assert()](#assertcondition-message)\n- [Function](#function)\n - [once()](#oncefn)\n - [ignore](#ignore)\n- [Promises](#promises)\n - [wait()](#waittimeout-returnvalue)\n - [block()](#block)\n - [isPromise()](#ispromisepromise)", - "api": "

    Object

    \n

    hoek provides several helpful methods for objects and arrays.

    \n

    clone(obj, [options])

    \n

    Clones an object or an array. A deep copy is made (duplicates everything, including values that are\nobjects, as well as non-enumerable properties) where:

    \n
      \n
    • \nobj - the object to be cloned.
    • \n
    • \noptions - optional settings:\n
        \n
      • \nsymbols - clone symbol properties. Defaults to true.
      • \n
      • \nshallow - one of:\n
          \n
        • an array of object key strings (dot-separated or array-based key paths) to shallow copy from obj instead of deep.
        • \n
        • \ntrue to shallow copy all object properties. Used to shallow copy an object with non-enumerable properties and prototype;
        • \n
        \n
      • \n
      \n
    • \n
    \n
    const nestedObj = {\n        w: /^something$/ig,\n        x: {\n            a: [1, 2, 3],\n            b: 123456,\n            c: new Date()\n        },\n        y: 'y',\n        z: new Date()\n    };\n\nconst copy = Hoek.clone(nestedObj);\n\ncopy.x.b = 100;\n\nconsole.log(copy.y);        // results in 'y'\nconsole.log(nestedObj.x.b); // results in 123456\nconsole.log(copy.x.b);      // results in 100
    \n

    Clones an object or array excluding some keys which are shallow copied:

    \n
    const nestedObj = {\n        w: /^something$/ig,\n        x: {\n            a: [1, 2, 3],\n            b: 123456,\n            c: new Date()\n        },\n        y: 'y',\n        z: new Date()\n    };\n\nconst copy = Hoek.clone(nestedObj, { shallow: ['x'] });\n\ncopy.x.b = 100;\n\nconsole.log(copy.y);        // results in 'y'\nconsole.log(nestedObj.x.b); // results in 100\nconsole.log(copy.x.b);      // results in 100
    \n

    merge(target, source, [options])

    \n

    Merge all the properties of source into target where:

    \n
      \n
    • \ntarget - the object onto which the properties of source are copied to.
    • \n
    • \nsource - the object copied onto target.
    • \n
    • \noptions - optional settings:\n
        \n
      • \nnullOverride - if true, a null value in the source overrides any existing value in the defaults.\nIf false, null values in the source are ignored. Defaults to true.
      • \n
      • \nmergeArrays - if true, array values from source are appended to existing array values in target.\nDefaults to true.
      • \n
      • \nsymbols - clone symbol properties. Defaults to true.
      • \n
      \n
    • \n
    \n

    Note that source wins in conflict, and by default null and undefined from source are applied.\nMerge is destructive where the target is modified. For non destructive merge, use applyToDefaults.

    \n
    const target = {a: 1, b : 2};\nconst source = {a: 0, c: 5};\nconst source2 = {a: null, c: 5};\n\nHoek.merge(target, source);         // results in {a: 0, b: 2, c: 5}\nHoek.merge(target, source2);        // results in {a: null, b: 2, c: 5}\nHoek.merge(target, source2, { nullOverride: false} ); // results in {a: 1, b: 2, c: 5}\n\nconst targetArray = [1, 2, 3];\nconst sourceArray = [4, 5];\n\nHoek.merge(targetArray, sourceArray);              // results in [1, 2, 3, 4, 5]\nHoek.merge(targetArray, sourceArray, { mergeArrays: false }); // results in [4, 5]
    \n

    applyToDefaults(defaults, source, [options])

    \n

    Apply source to a copy of the defaults where:

    \n
      \n
    • \ndefaults - the default object to clone and then apply source onto.
    • \n
    • \nsource - the object applied to the defaults.
    • \n
    • \noptions - optional settings:\n
        \n
      • \nnullOverride - if true, a null value in the source overrides any existing value in the defaults.\nIf false, null values in the source are ignored. Defaults to false.
      • \n
      • \nshallow - an array of dot-separated or array-based key paths to shallow copy values in source.
      • \n
      \n
    • \n
    \n
    const defaults = { host: \"localhost\", port: 8000 };\nconst source = { port: 8080 };\n\nconst config = Hoek.applyToDefaults(defaults, source); // results in { host: \"localhost\", port: 8080 }
    \n

    Apply source with a null value to a copy of the defaults

    \n
    const defaults = { host: \"localhost\", port: 8000 };\nconst source = { host: null, port: 8080 };\n\nconst config = Hoek.applyToDefaults(defaults, source, { nullOverride: true }); // results in { host: null, port: 8080 }
    \n

    Apply source to a copy of the defaults where the shallow keys specified in the last parameter are shallow copied from source instead of merged

    \n
    const defaults = {\n    db: {\n        server: {\n            host: \"localhost\",\n            port: 8000\n        },\n        name: 'example'\n    }\n};\n\nconst source = { server: { port: 8080 } };\n\nconst config = Hoek.applyToDefaults(defaults, source, { shallow: ['db.server'] });        // results in { db: { server: { port: 8080 }, name: 'example' } }\nconst config = Hoek.applyToDefaults(defaults, source, { shallow: [['db', 'server']] });   // results in { db: { server: { port: 8080 }, name: 'example' } }
    \n

    deepEqual(a, b, [options])

    \n

    Performs a deep comparison of the two values including support for circular dependencies,\nprototype, and enumerable properties, where:

    \n
      \n
    • \na - the first value.
    • \n
    • \nb - the second value.
    • \n
    • \noptions - optional settings:\n
        \n
      • \ndeepFunction - when true, function values are deep compared using their source code and\nobject properties. Defaults to false.
      • \n
      • \npart - when true, allows a partial match where some of b is present in a. Defaults to\nfalse.
      • \n
      • \nprototype - when false, prototype comparisons are skipped. Defaults to true`.
      • \n
      • \nskip - an array of key name strings to skip comparing. The keys can be found in any level\nof the object. Note that both values must contain the key - only the value comparison is\nskipped. Only applies to plain objects and deep functions (not to map, sets, etc.). Defaults\nto no skipping.
      • \n
      • \nsymbols - when false, symbol properties are ignored. Defaults to true.
      • \n
      \n
    • \n
    \n
    Hoek.deepEqual({ a: [1, 2], b: 'string', c: { d: true } }, { a: [1, 2], b: 'string', c: { d: true } }); //results in true\nHoek.deepEqual(Object.create(null), {}, { prototype: false }); //results in true\nHoek.deepEqual(Object.create(null), {}); //results in false
    \n

    intersect(array1, array2, [options])

    \n

    Find the common unique items betwee two arrays where:

    \n
      \n
    • \narray1 - the first array.
    • \n
    • \narray2 - the second array.
    • \n
    • \noptions - optional settings:\n
        \n
      • \nfirst - if true, return only the first intersecting item. Defaults to false.
      • \n
      \n
    • \n
    \n
    const array1 = [1, 2, 3];\nconst array2 = [1, 4, 5];\n\nconst newArray = Hoek.intersect(array1, array2); // results in [1]
    \n

    contain(ref, values, [options])

    \n

    Tests if the reference value contains the provided values where:

    \n
      \n
    • \nref - the reference string, array, or object.
    • \n
    • \nvalues - a single or array of values to find within the ref value. If ref is an object, values can be a key name,\nan array of key names, or an object with key-value pairs to compare.
    • \n
    • \noptions - an optional object with the following optional settings:\n
        \n
      • \ndeep - if true, performed a deep comparison of the values.
      • \n
      • \nonce - if true, allows only one occurrence of each value.
      • \n
      • \nonly - if true, does not allow values not explicitly listed.
      • \n
      • \npart - if true, allows partial match of the values (at least one must always match).
      • \n
      • \nsymbols - clone symbol properties. Defaults to true.
      • \n
      \n
    • \n
    \n

    Note: comparing a string to overlapping values will result in failed comparison (e.g. contain('abc', ['ab', 'bc'])).\nAlso, if an object key's value does not match the provided value, false is returned even when part is specified.

    \n
    Hoek.contain('aaa', 'a', { only: true });\t\t\t\t\t\t\t// true\nHoek.contain([{ a: 1 }], [{ a: 1 }], { deep: true });\t\t\t\t// true\nHoek.contain([1, 2, 2], [1, 2], { once: true });\t\t\t\t\t// false\nHoek.contain({ a: 1, b: 2, c: 3 }, { a: 1, d: 4 }, { part: true }); // true
    \n

    flatten(array, [target])

    \n

    Flatten an array

    \n
    const array = [1, [2, 3]];\n\nconst flattenedArray = Hoek.flatten(array); // results in [1, 2, 3]\n\narray = [1, [2, 3]];\ntarget = [4, [5]];\n\nflattenedArray = Hoek.flatten(array, target); // results in [4, [5], 1, 2, 3]
    \n

    reach(obj, chain, [options])

    \n

    Converts an object key chain string or array to reference

    \n
      \n
    • \noptions - optional settings\n
        \n
      • \nseparator - string to split chain path on, defaults to '.'
      • \n
      • \ndefault - value to return if the path or value is not present, default is undefined\n
      • \n
      • \nstrict - if true, will throw an error on missing member, default is false\n
      • \n
      • \nfunctions - if true, allow traversing functions for properties. false will throw an\nerror if a function is part of the chain. Defaults to true.
      • \n
      • \niterables - if true, allows traversing Set and Map objects. false will result in\nundefined return value is the chain contains any Set or Map objects. Note that enabling\niterables can impact performance by up to 10% for all calls regardless of the presence of\nSet or Map objects. Defaults to false.
      • \n
      \n
    • \n
    \n

    A chain can be a string that will be split into key names using separator,\nor an array containing each individual key name.

    \n

    A chain including negative numbers will work like negative indices on an array.

    \n

    If chain is null, undefined or false, the object itself will be returned.

    \n
    const chain = 'a.b.c';\nconst obj = {a : {b : { c : 1}}};\n\nHoek.reach(obj, chain); // returns 1\n\nconst chain = ['a', 'b', -1];\nconst obj = {a : {b : [2,3,6]}};\n\nHoek.reach(obj, chain); // returns 6
    \n

    reachTemplate(obj, template, [options])

    \n

    Replaces string parameters ({name}) with their corresponding object key values by applying the\nreach() method where:

    \n
      \n
    • \nobj - the context object used for key lookup.
    • \n
    • \ntemplate - a string containing {} parameters.
    • \n
    • \noptions - optional reach() options.
    • \n
    \n
    const template = '1+{a.b.c}=2';\nconst obj = { a: { b: { c: 1 } } };\n\nHoek.reachTemplate(obj, template); // returns '1+1=2'
    \n

    stringify(...args)

    \n

    Converts an object to string using the built-in JSON.stringify() method with the difference that any errors are caught\nand reported back in the form of the returned string. Used as a shortcut for displaying information to the console (e.g. in\nerror message) without the need to worry about invalid conversion.

    \n
    const a = {};\na.b = a;\nHoek.stringify(a);\t\t// Returns '[Cannot display object: Converting circular structure to JSON]'
    \n

    Bench

    \n

    Same as Timer with the exception that ts stores the internal node clock which is not related to Date.now() and cannot be used to display\nhuman-readable timestamps. More accurate for benchmarking or internal timers.

    \n

    Escaping Characters

    \n

    hoek provides convenient methods for escaping html characters. The escaped characters are as followed:

    \n
    internals.htmlEscaped = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#x27;',\n    '`': '&#x60;'\n};
    \n

    escapeHtml(string)

    \n
    const string = '<html> hey </html>';\nconst escapedString = Hoek.escapeHtml(string); // returns &lt;html&gt; hey &lt;/html&gt;
    \n

    escapeHeaderAttribute(attribute)

    \n

    Escape attribute value for use in HTTP header

    \n
    const a = Hoek.escapeHeaderAttribute('I said \"go w\\\\o me\"');  //returns I said \\\"go w\\\\o me\\\"
    \n

    escapeJson(string)

    \n

    Unicode escapes the characters <, >, and & to prevent mime-sniffing older browsers mistaking JSON as HTML, and escapes line and paragraph separators for JSONP and script contexts.

    \n
    const lineSeparator = String.fromCharCode(0x2028);\nconst a = Hoek.escapeJson('I said <script>confirm(&).' + lineSeparator);  //returns I said \\\\u003cscript\\\\u003econfirm(\\\\u0026).\\\\u2028
    \n

    escapeRegex(string)

    \n

    Escape string for Regex construction

    \n
    const a = Hoek.escapeRegex('4^f$s.4*5+-_?%=#!:@|~\\\\/`\"(>)[<]d{}s,');  // returns 4\\^f\\$s\\.4\\*5\\+\\-_\\?%\\=#\\!\\:@\\|~\\\\\\/`\"\\(>\\)\\[<\\]d\\{\\}s\\,
    \n

    Errors

    \n

    assert(condition, message)

    \n
    const a = 1, b = 2;\n\nHoek.assert(a === b, 'a should equal b');  // Throws 'a should equal b'
    \n

    Note that you may also pass an already created Error object as the second parameter, and assert will throw that object.

    \n
    const a = 1, b = 2;\n\nHoek.assert(a === b, new Error('a should equal b')); // Throws the given error object
    \n

    Function

    \n

    once(fn)

    \n

    Returns a new function that can be run multiple times, but makes sure fn is only run once.

    \n
    const myFn = function () {\n    console.log('Ran myFn');\n};\n\nconst onceFn = Hoek.once(myFn);\nonceFn(); // results in \"Ran myFn\"\nonceFn(); // results in undefined
    \n

    ignore

    \n

    A simple no-op function. It does nothing at all.

    \n

    Promises

    \n

    wait(timeout, [returnValue])

    \n

    Resolve the promise after timeout milliseconds with the provided returnValue.

    \n
    await Hoek.wait(2000); // waits for 2 seconds\nconst timeout = Hoek.wait(1000, 'timeout'); // resolves after 1s with 'timeout'
    \n

    block()

    \n

    A no-op Promise. Does nothing.

    \n

    isPromise(promise)

    \n

    Determines if an item is a promise where:

    \n
      \n
    • \npromise - the item being tested.
    • \n
    \n

    Returns true is the item is a promise, otherwise false.

    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Utility methods for the hapi ecosystem.", - "forks": 171, - "stars": 480, - "date": "2024-10-23T10:16:41Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/hoek" - }, - "inert": { - "name": "inert", - "versions": [ - { - "name": "7.1.0", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "6.0.5", - "branch": "v6", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "7.1.0", - "6.0.5" - ], - "api": true, - "isPlugin": true, - "7.1.0": { - "menu": "- [Features](#features)\n- [Examples](#examples)\n - [Static file server](#static-file-server)\n - [Serving a single file](#serving-a-single-file)\n - [Customized file response](#customized-file-response)\n - [Server options](#server-options)\n - [`h.file()`](#hfilepath-options)\n - [The `file` handler](#the-file-handler)\n - [The `directory` handler](#the-directory-handler)\n - [Errors](#errors)", - "api": "

    inert provides new handler\nmethods for serving static files and directories, as well as adding a h.file() method to the\ntoolkit, which can respond with\nfile based resources.

    \n

    Features

    \n
      \n
    • Files are served with cache friendly last-modified and etag headers.
    • \n
    • Generated file listings and custom indexes.
    • \n
    • Pre-compressed file support for content-encoding: gzip responses.
    • \n
    • File attachment support using content-disposition header.
    • \n
    \n

    Examples

    \n

    inert enables a number of common use cases for serving static assets.

    \n

    Static file server

    \n

    The following creates a basic static file server that can be used to serve html content from the\npublic directory on port 3000:

    \n
    const Path = require('path');\nconst Hapi = require('@hapi/hapi');\nconst Inert = require('@hapi/inert');\n\nconst server = new Hapi.Server({\n    port: 3000,\n    routes: {\n        files: {\n            relativeTo: Path.join(__dirname, 'public')\n        }\n    }\n});\n\nconst provision = async () => {\n\n    await server.register(Inert);\n\n    server.route({\n        method: 'GET',\n        path: '/{param*}',\n        handler: {\n            directory: {\n                path: '.',\n                redirectToSlash: true,\n                index: true,\n            }\n        }\n    });\n\n    await server.start();\n\n    console.log('Server running at:', server.info.uri);\n};\n\nprovision();
    \n

    Serving a single file

    \n

    You can serve specific files using the file handler:

    \n
    server.route({\n    method: 'GET',\n    path: '/{path*}',\n    handler: {\n        file: 'page.html'\n    }\n});
    \n

    Customized file response

    \n

    If you need more control, the h.file() method is available to use inside handlers:

    \n
    server.route({\n    method: 'GET',\n    path: '/file',\n    handler(request, h) {\n\n        let path = 'plain.txt';\n        if (request.headers['x-magic'] === 'sekret') {\n            path = 'awesome.png';\n        }\n\n        return h.file(path).vary('x-magic');\n    }\n});\n\nserver.ext('onPreResponse', (request, h) => {\n\n    const response = request.response;\n    if (response.isBoom &&\n        response.output.statusCode === 404) {\n\n        return h.file('404.html').code(404);\n    }\n\n    return h.continue;\n});
    \n

    Server options

    \n

    inert handles the following server plugin options on plugins.inert:

    \n
      \n
    • \netagsCacheMaxSize - sets the maximum number of file etag hash values stored in the\netags cache. Defaults to 1000.
    • \n
    \n

    h.file(path, [options])

    \n

    Transmits a file from the file system. The 'Content-Type' header defaults to the matching mime\ntype based on filename extension.:

    \n
      \n
    • \npath - the file path.
    • \n
    • \noptions - optional settings:\n
        \n
      • \nconfine - serve file relative to this directory and returns 403 Forbidden if the\npath resolves outside the confine directory.\nDefaults to true which uses the relativeTo route option as the confine.\nSet to false to disable this security feature.
      • \n
      • \nfilename - an optional filename to specify if sending a 'Content-Disposition' header,\ndefaults to the basename of path\n
      • \n
      • \nmode - specifies whether to include the 'Content-Disposition' header with the response.\nAvailable values:\n
          \n
        • \nfalse - header is not included. This is the default value.
        • \n
        • 'attachment'
        • \n
        • 'inline'
        • \n
        \n
      • \n
      • \nlookupCompressed - if true, looks for for a pre-compressed version of the file with\nthe same filename with an extension, depending on the accepted encoding.\nDefaults to false.
      • \n
      • \nlookupMap - an object which maps content encoding to expected file name extension.\nDefaults to { gzip: '.gz' }.
      • \n
      • \netagMethod - specifies the method used to calculate the ETag header response.\nAvailable values:\n
          \n
        • \n'hash' - SHA1 sum of the file contents, suitable for distributed deployments.\nDefault value.
        • \n
        • \n'simple' - Hex encoded size and modification date, suitable when files are stored\non a single server.
        • \n
        • \nfalse - Disable ETag computation.
        • \n
        \n
      • \n
      • \nstart - offset in file to reading from, defaults to 0.
      • \n
      • \nend - offset in file to stop reading from. If not set, will read to end of file.
      • \n
      \n
    • \n
    \n

    Returns a standard response object.

    \n

    The response flow control rules do not apply.

    \n

    The file handler

    \n

    Generates a static file endpoint for serving a single file. file can be set to:

    \n
      \n
    • a relative or absolute file path string (relative paths are resolved based on the\nroute files\nconfiguration).
    • \n
    • a function with the signature function(request) which returns the relative or absolute\nfile path.
    • \n
    • an object with one or more of the following options:\n
        \n
      • \npath - a path string or function as described above (required).
      • \n
      • \nconfine - serve file relative to this directory and returns 403 Forbidden if the\npath resolves outside the confine directory.\nDefaults to true which uses the relativeTo route option as the confine.\nSet to false to disable this security feature.
      • \n
      • \nfilename - an optional filename to specify if sending a 'Content-Disposition'\nheader, defaults to the basename of path\n
      • \n
      • \nmode - specifies whether to include the 'Content-Disposition' header with the\nresponse. Available values:\n
          \n
        • \nfalse - header is not included. This is the default value.
        • \n
        • 'attachment'
        • \n
        • 'inline'
        • \n
        \n
      • \n
      • \nlookupCompressed - if true, looks for for a pre-compressed version of the file with\nthe same filename with an extension, depending on the accepted encoding.\nDefaults to false.
      • \n
      • \nlookupMap - an object which maps content encoding to expected file name extension.\nDefaults to { gzip: '.gz' }.
      • \n
      • \netagMethod - specifies the method used to calculate the ETag header response.\nAvailable values:\n
          \n
        • \n'hash' - SHA1 sum of the file contents, suitable for distributed deployments.\nDefault value.
        • \n
        • \n'simple' - Hex encoded size and modification date, suitable when files are stored\non a single server.
        • \n
        • \nfalse - Disable ETag computation.
        • \n
        \n
      • \n
      • \nstart - offset in file to reading from, defaults to 0.
      • \n
      • \nend - offset in file to stop reading from. If not set, will read to end of file.
      • \n
      \n
    • \n
    \n

    The directory handler

    \n

    Generates a directory endpoint for serving static content from a directory.\nRoutes using the directory handler must include a path parameter at the end of the path\nstring (e.g. /path/to/somewhere/{param} where the parameter name does not matter). The\npath parameter can use any of the parameter options (e.g. {param} for one level files\nonly, {param?} for one level files or the directory root, {param*} for any level, or\n{param*3} for a specific level). If additional path parameters are present, they are\nignored for the purpose of selecting the file system resource. The directory handler is an\nobject with the following options:

    \n
      \n
    • \npath - (required) the directory root path (relative paths are resolved based on the\nroute files\nconfiguration). Value can be:\n
        \n
      • a single path string used as the prefix for any resources requested by appending the\nrequest path parameter to the provided string.
      • \n
      • an array of path strings. Each path will be attempted in order until a match is\nfound (by following the same process as the single path string).
      • \n
      • a function with the signature function(request) which returns the path string or\nan array of path strings. If the function returns an error, the error is passed back\nto the client in the response.
      • \n
      \n
    • \n
    • \nindex - optional boolean|string|string[], determines if an index file will be served\nif found in the folder when requesting a directory. The given string or strings specify\nthe name(s) of the index file to look for. If true, looks for 'index.html'. Any falsy\nvalue disables index file lookup. Defaults to true.
    • \n
    • \nlisting - optional boolean, determines if directory listing is generated when a\ndirectory is requested without an index document.\nDefaults to false.
    • \n
    • \nshowHidden - optional boolean, determines if hidden files will be shown and served.\nDefaults to false.
    • \n
    • \nredirectToSlash - optional boolean, determines if requests for a directory without a\ntrailing slash are redirected to the same path with the missing slash. Useful for\nensuring relative links inside the response are resolved correctly. Disabled when the\nserver config router.stripTrailingSlash is true. Defaults to false.
    • \n
    • \nlookupCompressed - optional boolean, instructs the file processor to look for the same\nfilename with an extension, depending on the accepted encoding, for a pre-compressed\nversion of the file to serve. Defaults to false.
    • \n
    • \nlookupMap - an object which maps content encoding to expected file name extension.\nDefaults to { gzip: '.gz' }.
    • \n
    • \netagMethod - specifies the method used to calculate the ETag header response.\nAvailable values:\n
        \n
      • \n'hash' - SHA1 sum of the file contents, suitable for distributed deployments.\nDefault value.
      • \n
      • \n'simple' - Hex encoded size and modification date, suitable when files are stored\non a single server.
      • \n
      • \nfalse - Disable ETag computation.
      • \n
      \n
    • \n
    • \ndefaultExtension - optional string, appended to file requests if the requested file is\nnot found. Defaults to no extension.
    • \n
    \n

    Errors

    \n

    Any file access errors are signalled using appropriate Boom\nerrors. These are Boom.notFound() for missing or hidden files, and Boom.forbidden() for\nfiles that exist, but can't otherwise be accessed.

    \n

    The error can contain an err.data.path property, which is the path that the error failed for.\nThis property does not always exist if the response was generated without a file system lookup,\nand for the directory handler it will be the last tested non-index path.

    \n

    If an unexpected configuration or processing errors occurs, Boom.internal() and 'system'\nerrors can also be thrown.

    \n", - "intro": "", - "example": "", - "usage": "## Usage\n\nAfter registration, this plugin adds a new method to the `toolkit` object and exposes the `'file'`\nand `'directory'` route handlers.\n\nNote that **inert** uses the custom `'file'` `variety` to signal that the response is a static\nfile generated by this plugin.\n", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "6.0.5": { - "menu": "- [Features](#features)\n- [Examples](#examples)\n - [Static file server](#static-file-server)\n - [Serving a single file](#serving-a-single-file)\n - [Customized file response](#customized-file-response)\n- [Usage](#usage)\n - [Server options](#server-options)\n - [`h.file()`](#hfilepath-options)\n - [The `file` handler](#the-file-handler)\n - [The `directory` handler](#the-directory-handler)\n - [Errors](#errors)", - "api": "

    inert provides new handler\nmethods for serving static files and directories, as well as adding a h.file() method to the\ntoolkit, which can respond with\nfile based resources.

    \n

    Features

    \n
      \n
    • Files are served with cache friendly last-modified and etag headers.
    • \n
    • Generated file listings and custom indexes.
    • \n
    • Pre-compressed file support for content-encoding: gzip responses.
    • \n
    • File attachment support using content-disposition header.
    • \n
    \n

    Examples

    \n

    inert enables a number of common use cases for serving static assets.

    \n

    Static file server

    \n

    The following creates a basic static file server that can be used to serve html content from the\npublic directory on port 3000:

    \n
    const Path = require('path');\nconst Hapi = require('@hapi/hapi');\nconst Inert = require('@hapi/inert');\n\nconst server = new Hapi.Server({\n    port: 3000,\n    routes: {\n        files: {\n            relativeTo: Path.join(__dirname, 'public')\n        }\n    }\n});\n\nconst provision = async () => {\n\n    await server.register(Inert);\n\n    server.route({\n        method: 'GET',\n        path: '/{param*}',\n        handler: {\n            directory: {\n                path: '.',\n                redirectToSlash: true,\n                index: true,\n            }\n        }\n    });\n\n    await server.start();\n\n    console.log('Server running at:', server.info.uri);\n};\n\nprovision();
    \n

    Serving a single file

    \n

    You can serve specific files using the file handler:

    \n
    server.route({\n    method: 'GET',\n    path: '/{path*}',\n    handler: {\n        file: 'page.html'\n    }\n});
    \n

    Customized file response

    \n

    If you need more control, the h.file() method is available to use inside handlers:

    \n
    server.route({\n    method: 'GET',\n    path: '/file',\n    handler(request, h) {\n\n        let path = 'plain.txt';\n        if (request.headers['x-magic'] === 'sekret') {\n            path = 'awesome.png';\n        }\n\n        return h.file(path).vary('x-magic');\n    }\n});\n\nserver.ext('onPreResponse', (request, h) => {\n\n    const response = request.response;\n    if (response.isBoom &&\n        response.output.statusCode === 404) {\n\n        return h.file('404.html').code(404);\n    }\n\n    return h.continue;\n});
    \n

    Usage

    \n

    After registration, this plugin adds a new method to the toolkit object and exposes the 'file'\nand 'directory' route handlers.

    \n

    Note that inert uses the custom 'file' variety to signal that the response is a static\nfile generated by this plugin.

    \n

    Server options

    \n

    inert handles the following server plugin options on plugins.inert:

    \n
      \n
    • \netagsCacheMaxSize - sets the maximum number of file etag hash values stored in the\netags cache. Defaults to 1000.
    • \n
    \n

    h.file(path, [options])

    \n

    Transmits a file from the file system. The 'Content-Type' header defaults to the matching mime\ntype based on filename extension.:

    \n
      \n
    • \npath - the file path.
    • \n
    • \noptions - optional settings:\n
        \n
      • \nconfine - serve file relative to this directory and returns 403 Forbidden if the\npath resolves outside the confine directory.\nDefaults to true which uses the relativeTo route option as the confine.\nSet to false to disable this security feature.
      • \n
      • \nfilename - an optional filename to specify if sending a 'Content-Disposition' header,\ndefaults to the basename of path\n
      • \n
      • \nmode - specifies whether to include the 'Content-Disposition' header with the response.\nAvailable values:\n
          \n
        • \nfalse - header is not included. This is the default value.
        • \n
        • 'attachment'
        • \n
        • 'inline'
        • \n
        \n
      • \n
      • \nlookupCompressed - if true, looks for for a pre-compressed version of the file with\nthe same filename with an extension, depending on the accepted encoding.\nDefaults to false.
      • \n
      • \nlookupMap - an object which maps content encoding to expected file name extension.\nDefaults to { gzip: '.gz' }.
      • \n
      • \netagMethod - specifies the method used to calculate the ETag header response.\nAvailable values:\n
          \n
        • \n'hash' - SHA1 sum of the file contents, suitable for distributed deployments.\nDefault value.
        • \n
        • \n'simple' - Hex encoded size and modification date, suitable when files are stored\non a single server.
        • \n
        • \nfalse - Disable ETag computation.
        • \n
        \n
      • \n
      • \nstart - offset in file to reading from, defaults to 0.
      • \n
      • \nend - offset in file to stop reading from. If not set, will read to end of file.
      • \n
      \n
    • \n
    \n

    Returns a standard response object.

    \n

    The response flow control rules do not apply.

    \n

    The file handler

    \n

    Generates a static file endpoint for serving a single file. file can be set to:

    \n
      \n
    • a relative or absolute file path string (relative paths are resolved based on the\nroute files\nconfiguration).
    • \n
    • a function with the signature function(request) which returns the relative or absolute\nfile path.
    • \n
    • an object with one or more of the following options:\n
        \n
      • \npath - a path string or function as described above (required).
      • \n
      • \nconfine - serve file relative to this directory and returns 403 Forbidden if the\npath resolves outside the confine directory.\nDefaults to true which uses the relativeTo route option as the confine.\nSet to false to disable this security feature.
      • \n
      • \nfilename - an optional filename to specify if sending a 'Content-Disposition'\nheader, defaults to the basename of path\n
      • \n
      • \nmode - specifies whether to include the 'Content-Disposition' header with the\nresponse. Available values:\n
          \n
        • \nfalse - header is not included. This is the default value.
        • \n
        • 'attachment'
        • \n
        • 'inline'
        • \n
        \n
      • \n
      • \nlookupCompressed - if true, looks for for a pre-compressed version of the file with\nthe same filename with an extension, depending on the accepted encoding.\nDefaults to false.
      • \n
      • \nlookupMap - an object which maps content encoding to expected file name extension.\nDefaults to { gzip: '.gz' }.
      • \n
      • \netagMethod - specifies the method used to calculate the ETag header response.\nAvailable values:\n
          \n
        • \n'hash' - SHA1 sum of the file contents, suitable for distributed deployments.\nDefault value.
        • \n
        • \n'simple' - Hex encoded size and modification date, suitable when files are stored\non a single server.
        • \n
        • \nfalse - Disable ETag computation.
        • \n
        \n
      • \n
      • \nstart - offset in file to reading from, defaults to 0.
      • \n
      • \nend - offset in file to stop reading from. If not set, will read to end of file.
      • \n
      \n
    • \n
    \n

    The directory handler

    \n

    Generates a directory endpoint for serving static content from a directory.\nRoutes using the directory handler must include a path parameter at the end of the path\nstring (e.g. /path/to/somewhere/{param} where the parameter name does not matter). The\npath parameter can use any of the parameter options (e.g. {param} for one level files\nonly, {param?} for one level files or the directory root, {param*} for any level, or\n{param*3} for a specific level). If additional path parameters are present, they are\nignored for the purpose of selecting the file system resource. The directory handler is an\nobject with the following options:

    \n
      \n
    • \npath - (required) the directory root path (relative paths are resolved based on the\nroute files\nconfiguration). Value can be:\n
        \n
      • a single path string used as the prefix for any resources requested by appending the\nrequest path parameter to the provided string.
      • \n
      • an array of path strings. Each path will be attempted in order until a match is\nfound (by following the same process as the single path string).
      • \n
      • a function with the signature function(request) which returns the path string or\nan array of path strings. If the function returns an error, the error is passed back\nto the client in the response.
      • \n
      \n
    • \n
    • \nindex - optional boolean|string|string[], determines if an index file will be served\nif found in the folder when requesting a directory. The given string or strings specify\nthe name(s) of the index file to look for. If true, looks for 'index.html'. Any falsy\nvalue disables index file lookup. Defaults to true.
    • \n
    • \nlisting - optional boolean, determines if directory listing is generated when a\ndirectory is requested without an index document.\nDefaults to false.
    • \n
    • \nshowHidden - optional boolean, determines if hidden files will be shown and served.\nDefaults to false.
    • \n
    • \nredirectToSlash - optional boolean, determines if requests for a directory without a\ntrailing slash are redirected to the same path with the missing slash. Useful for\nensuring relative links inside the response are resolved correctly. Disabled when the\nserver config router.stripTrailingSlash is true. Defaults to false.
    • \n
    • \nlookupCompressed - optional boolean, instructs the file processor to look for the same\nfilename with an extension, depending on the accepted encoding, for a pre-compressed\nversion of the file to serve. Defaults to false.
    • \n
    • \nlookupMap - an object which maps content encoding to expected file name extension.\nDefaults to { gzip: '.gz' }.
    • \n
    • \netagMethod - specifies the method used to calculate the ETag header response.\nAvailable values:\n
        \n
      • \n'hash' - SHA1 sum of the file contents, suitable for distributed deployments.\nDefault value.
      • \n
      • \n'simple' - Hex encoded size and modification date, suitable when files are stored\non a single server.
      • \n
      • \nfalse - Disable ETag computation.
      • \n
      \n
    • \n
    • \ndefaultExtension - optional string, appended to file requests if the requested file is\nnot found. Defaults to no extension.
    • \n
    \n

    Errors

    \n

    Any file access errors are signalled using appropriate Boom\nerrors. These are Boom.notFound() for missing or hidden files, and Boom.forbidden() for\nfiles that exist, but can't otherwise be accessed.

    \n

    The error can contain an err.data.path property, which is the path that the error failed for.\nThis property does not always exist if the response was generated without a file system lookup,\nand for the directory handler it will be the last tested non-index path.

    \n

    If an unexpected configuration or processing errors occurs, Boom.internal() and 'system'\nerrors can also be thrown.

    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Static file and directory handlers for hapi.js.", - "forks": 49, - "stars": 238, - "date": "2024-10-23T15:13:24Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/inert" - }, - "iron": { - "name": "iron", - "versions": [ - { - "name": "7.0.1", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "6.0.0", - "branch": "v6", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "7.0.1", - "6.0.0" - ], - "api": true, - "isPlugin": false, - "7.0.1": { - "menu": "- [Security Considerations](#security-considerations)\n - [Plaintext Storage of Credentials](#plaintext-storage-of-credentials)\n- [Frequently Asked Questions](#frequently-asked-questions)\n - [Where is the protocol specification?](#where-is-the-protocol-specification)\n - [Is it done?](#is-it-done)\n - [How come the defaults must be manually passed and not automatically applied?](#how-come-the-defaults-must-be-manually-passed-and-not-automatically-applied)\n- [Acknowledgements](#acknowledgements)\n- [Methods](#methods)\n - [`await seal()`](#await-sealobject-password-options)\n - [`await unseal()`](#await-unsealsealed-password-options)\n - [`await generateKey()`](#await-generatekeypassword-options)\n - [`await encrypt()`](#await-encryptpassword-options-data)\n - [`await decrypt()`](#await-decryptpassword-options-data)\n - [`await hmacWithPassword()`](#await-hmacwithpasswordpassword-options-data)\n- [Options](#options)\n - [Defaults](#defaults)", - "api": "

    Security Considerations

    \n

    The greatest sources of security risks are usually found not in iron but in the policies and\nprocedures surrounding its use. Implementers are strongly encouraged to assess how this module\naddresses their security requirements. This section includes an incomplete list of security\nconsiderations that must be reviewed and understood before using iron.

    \n

    Plaintext Storage of Credentials

    \n

    The iron password is only used to derive keys and is never sent or shared. However, in order to\ngenerate (and regenerate) the keys used to encrypt the object and compute the request MAC, the\nserver must have access to the password in plaintext form. This is in contrast, for example, to\nmodern operating systems, which store only a one-way hash of user credentials.

    \n

    If an attacker were to gain access to the password - or worse, to the server's database of all such\npassword - he or she would be able to encrypt and decrypt any sealed object. Accordingly, it is\ncritical that servers protect these passwords from unauthorized access.

    \n

    Frequently Asked Questions

    \n

    Where is the protocol specification?

    \n

    If you are looking for some prose explaining how all this works, there isn't any. iron is being\ndeveloped as an open source project instead of a standard. In other words, the code is the\nspecification. Not sure about something? Open an issue!

    \n

    Is it done?

    \n

    Yep.

    \n

    How come the defaults must be manually passed and not automatically applied?

    \n

    Because you should know what you are doing and explicitly set it. The options matter a lot to the\nsecurity properties of the implementation. While reasonable defaults are provided, you still need\nto explicitly state you want to use them.

    \n

    Acknowledgements

    \n

    Special thanks to Adam Barth for his infinite patience, and always insightful feedback and advice.

    \n

    Methods

    \n

    await seal(object, password, options)

    \n

    Seriealizes, encrypts, and signs objects into an iron protocol string where:

    \n
      \n
    • \n

      object - the data being sealed. Can be any JavaScript value that is serializable via\nJSON.stringify(). Note: JSON.stringify will not keep object properties which values are undefined. So if you pass an object like {id: undefined} then it will be serialized as {}.

      \n
    • \n
    • \n

      password - one of:

      \n
        \n
      • \n

        a password string used to generate a key using the pbkdf2 algorithm.

        \n
      • \n
      • \n

        a key buffer used as-is (after validating sufficient length based on the algorithm used).

        \n
      • \n
      • \n

        an object with:

        \n
          \n
        • \nid - a password identifier (must consist of only letters, numbers, and _).
        • \n
        • \nsecret - a password string or key buffer used for both encryption and integrity.
        • \n
        \n
      • \n
      • \n

        an object with:

        \n
          \n
        • \nid - a password identifier (must consist of only letters, numbers, and _).
        • \n
        • \nencryption - a password string or key buffer used for encryption.
        • \n
        • \nintegrity - a password string or key buffer used for integrity.
        • \n
        \n
      • \n
      \n
    • \n
    • \n

      options - see Options.

      \n
    • \n
    \n

    Return value: iron sealed string.

    \n

    Note: assigning the password used an id allows for password rotation to improve the security of\nyour deployment. Passwords should be rotated over time to reduce the risk of compromised security.\nWhen providing a password id, the id is included with the iron protocol string and it must\nmatch the id used to unseal.

    \n

    It is recommended to combine password id with the ttl option to generate iron protocol\nstrings of limited time validity which also allow for rotating passwords without the need to keep\nall previous passwords around (only the number of passwords used within the ttl window).

    \n

    await unseal(sealed, password, options)

    \n

    Verifies, decrypts, and reconstruct an iron protocol string into an object where:

    \n
      \n
    • \n

      sealed - the iron protocol string generated with seal().

      \n
    • \n
    • \n

      password - must match the password value passed to seal()\nand be one of:

      \n
        \n
      • \n

        a password string used to generate a key using the pbkdf2 algorithm.

        \n
      • \n
      • \n

        a key buffer used as-is (after validating sufficient length based on the algorithm used).

        \n
      • \n
      • \n

        an object with id as the key and value is one of:

        \n
          \n
        • a password string or key buffer used for both encryption and integrity.
        • \n
        • an object with:\n
            \n
          • \nencryption - a password string or key buffer used for encryption.
          • \n
          • \nintegrity - a password string or key buffer used for integrity.
          • \n
          \n
        • \n
        \n
      • \n
      \n
    • \n
    • \n

      options - see Options. Must match the options value passed to\nseal()

      \n
    • \n
    \n

    Return value: the verified, decripted object.

    \n

    Note: In order to enable password rotation, the password argument can accept an object with more\nthan one password, each keyed by its id. Together with the ttl option, the password object only\nneeds to include the passwords used within the ttl window.

    \n

    await generateKey(password, options)

    \n

    Generates an key from the password where:

    \n
      \n
    • \npassword - a password string or buffer key.
    • \n
    • \noptions - see Options.
    • \n
    \n

    Return value: an object with the following keys:

    \n
      \n
    • key
    • \n
    • salt
    • \n
    • iv
    • \n
    \n

    await encrypt(password, options, data)

    \n

    Encrypts data where:

    \n
      \n
    • \npassword - a password string or buffer key.
    • \n
    • \noptions - see Options.
    • \n
    • 'data' - the string to encrypt.
    • \n
    \n

    Return value: an object with the following keys:

    \n
      \n
    • encrypted
    • \n
    • \nkey:\n
        \n
      • key
      • \n
      • salt
      • \n
      • iv
      • \n
      \n
    • \n
    \n

    await decrypt(password, options, data)

    \n

    Decrypts data where:

    \n
      \n
    • \npassword - a password string or buffer key.
    • \n
    • \noptions - see Options.
    • \n
    • 'data' - the string to decrypt.
    • \n
    \n

    Return value: the decrypted string.

    \n

    await hmacWithPassword(password, options, data)

    \n

    Calculates an HMAC digest where:

    \n
      \n
    • \npassword - a password string or buffer key.
    • \n
    • \noptions - see Options.
    • \n
    • 'data' - the string to calculate the HMAC over.
    • \n
    \n

    Return value: an object with the following keys:

    \n
      \n
    • digest
    • \n
    • salt
    • \n
    \n

    Options

    \n

    iron provides options for customizing the key deriviation algorithm used to generate encryption\nand integrity verification keys, as well as the algorithms and salt sizes used.iron methods\ntake an options object with the following keys:

    \n
      \n
    • \nencryption - (required) defines the options used by the encryption process.
    • \n
    • \nintegrity - (required) defines the options used by the HMAC integrity verification process.
    • \n
    \n

    Each of these option objects support the following keys:

    \n
      \n
    • \nalgorithm - (required) the algorithm name ('aes-256-cbc' and 'aes-128-ctr' for encryption and\n'sha256' for integrity are the only two supported at this time).
    • \n
    • \niv - (optional) an initialization vector\nbuffer. If no iv is provided, one is generated based on the algorithm ivBits configuration.
    • \n
    \n

    When the password argument passed is a string (used for key generation), the following options\nare used:

    \n
      \n
    • \nsalt - (optional) a pre-generated salt string (a random buffer used to ensure that two\nidentical objects will generate a different encrypted result).
    • \n
    • \nsaltBits - (required if salt is not provided, otherwise ignored) the size of the salt.
    • \n
    • \niterations - (required) the number of iterations used to derive a key from the password.\nDefaults to 1 iteration. The number of ideal iterations to use is dependent on your\napplication's performance requirements. More iterations means it takes longer to generate the\nkey.
    • \n
    • \nminPasswordlength - (required) the minimum password string length required for key generation.\nDefaults to 32 characters.
    • \n
    \n

    The 'seal()' and 'unseal()' methods also support the following options:

    \n
      \n
    • \nttl - sealed object lifetime in milliseconds where 0 means forever. Defaults to 0.
    • \n
    • \ntimestampSkewSec - number of seconds of permitted clock skew for incoming expirations.\nDefaults to 60 seconds.
    • \n
    • \nlocaltimeOffsetMsec - local clock time offset, expressed in number of milliseconds (positive or\nnegative). Defaults to 0.
    • \n
    \n

    Defaults

    \n

    iron includes a default options object which can be passed to the methods as shown above in the\nexample. The default settings are:

    \n
    var options = {\n    encryption: {\n        saltBits: 256,\n        algorithm: 'aes-256-cbc',\n        iterations: 1\n    },\n    integrity: {\n        saltBits: 256,\n        algorithm: 'sha256',\n        iterations: 1\n    },\n    ttl: 0,\n    timestampSkewSec: 60,\n    localtimeOffsetMsec: 0\n};
    \n", - "intro": "## Introduction\n\n**iron** is a cryptographic utility for sealing a JSON object using symmetric key encryption with message\nintegrity verification. Or in other words, it lets you encrypt an object, send it around (in\ncookies, authentication credentials, etc.), then receive it back and decrypt it. The algorithm\nensures that the message was not tampered with, and also provides a simple mechanism for password\nrotation.\n\nNote: the wire protocol has not changed since 1.x (the version increments reflected a change in\nthe internal error format used by the module and by the node API as well as other node API changes).\n\n**iron** provides methods for encrypting an object, generating a message authentication code (MAC),\nand serializing both into a cookie / URI / HTTP header friendly format. Sealed objects are useful\nin cases where state has to reside on other applications not under your control, without exposing\nthe details of this state to those application.\n\nFor example, sealed objects allow you to encrypt the permissions granted to the authenticated user,\nstore those permissions using a cookie, without worrying about someone modifying (or even knowing)\nwhat those permissions are. Any modification to the encrypted data will invalidate its integrity.\n\nThe seal process follows these general steps:\n\n- generate encryption salt `saltE`\n- derive an encryption key `keyE` using `saltE` and a password\n- generate an integrity salt `saltI`\n- derive an integrity (HMAC) key `keyI` using `saltI` and the password\n- generate a random [initialization vector](http://en.wikipedia.org/wiki/Initialization_vector) `iv`\n- encrypt the serialized object string using `keyE` and `iv`\n- mac the encrypted object along with `saltE` and `iv`\n- concatenate `saltE`, `saltI`, `iv`, and the encrypted object into a URI-friendly string\n", - "example": "## Example\n\nTo seal an object:\n\n```javascript\nconst obj = {\n a: 1,\n b: 2,\n c: [3, 4, 5],\n d: {\n e: 'f'\n }\n};\n\nconst password = 'some_not_random_password_that_is_at_least_32_characters';\n\ntry {\n const sealed = await Iron.seal(obj, password, Iron.defaults);\n} catch (err) {\n console.log(err.message);\n}\n```\n\nThe result `sealed` object is a string which can be sent via cookies, URI query parameter, or an\nHTTP header attribute. To unseal the string:\n\n```javascript\ntry {\n const unsealed = await Iron.unseal(sealed, password, Iron.defaults);\n} catch (err) {\n console.log(err.message);\n}\n```\n", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "6.0.0": { - "menu": "- [Introduction](#introduction)\n- [Example](#example)\n- [Security Considerations](#security-considerations)\n - [Plaintext Storage of Credentials](#plaintext-storage-of-credentials)\n- [Frequently Asked Questions](#frequently-asked-questions)\n - [Where is the protocol specification?](#where-is-the-protocol-specification)\n - [Is it done?](#is-it-done)\n - [How come the defaults must be manually passed and not automatically applied?](#how-come-the-defaults-must-be-manually-passed-and-not-automatically-applied)\n- [Acknowledgements](#acknowledgements)\n- [Methods](#methods)\n - [`await seal()`](#await-sealobject-password-options)\n - [`await unseal()`](#await-unsealsealed-password-options)\n - [`await generateKey()`](#await-generatekeypassword-options)\n - [`await encrypt()`](#await-encryptpassword-options-data)\n - [`await decrypt()`](#await-decryptpassword-options-data)\n - [`await hmacWithPassword()`](#await-hmacwithpasswordpassword-options-data)\n- [Options](#options)\n - [Defaults](#defaults)", - "api": "

    Introduction

    \n

    iron is a cryptographic utility for sealing a JSON object using symmetric key encryption with message\nintegrity verification. Or in other words, it lets you encrypt an object, send it around (in\ncookies, authentication credentials, etc.), then receive it back and decrypt it. The algorithm\nensures that the message was not tampered with, and also provides a simple mechanism for password\nrotation.

    \n

    Note: the wire protocol has not changed since 1.x (the version increments reflected a change in\nthe internal error format used by the module and by the node API as well as other node API changes).

    \n

    iron provides methods for encrypting an object, generating a message authentication code (MAC),\nand serializing both into a cookie / URI / HTTP header friendly format. Sealed objects are useful\nin cases where state has to reside on other applications not under your control, without exposing\nthe details of this state to those application.

    \n

    For example, sealed objects allow you to encrypt the permissions granted to the authenticated user,\nstore those permissions using a cookie, without worrying about someone modifying (or even knowing)\nwhat those permissions are. Any modification to the encrypted data will invalidate its integrity.

    \n

    The seal process follows these general steps:

    \n
      \n
    • generate encryption salt saltE\n
    • \n
    • derive an encryption key keyE using saltE and a password
    • \n
    • generate an integrity salt saltI\n
    • \n
    • derive an integrity (HMAC) key keyI using saltI and the password
    • \n
    • generate a random initialization vector iv\n
    • \n
    • encrypt the serialized object string using keyE and iv\n
    • \n
    • mac the encrypted object along with saltE and iv\n
    • \n
    • concatenate saltE, saltI, iv, and the encrypted object into a URI-friendly string
    • \n
    \n

    Example

    \n

    To seal an object:

    \n
    const obj = {\n    a: 1,\n    b: 2,\n    c: [3, 4, 5],\n    d: {\n        e: 'f'\n    }\n};\n\nconst password = 'some_not_random_password_that_is_at_least_32_characters';\n\ntry {\n    const sealed = await Iron.seal(obj, password, Iron.defaults);\n} catch (err) {\n    console.log(err.message);\n}
    \n

    The result sealed object is a string which can be sent via cookies, URI query parameter, or an\nHTTP header attribute. To unseal the string:

    \n
    try {\n    const unsealed = await Iron.unseal(sealed, password, Iron.defaults);\n} catch (err) {\n    console.log(err.message);\n}
    \n

    Security Considerations

    \n

    The greatest sources of security risks are usually found not in iron but in the policies and\nprocedures surrounding its use. Implementers are strongly encouraged to assess how this module\naddresses their security requirements. This section includes an incomplete list of security\nconsiderations that must be reviewed and understood before using iron.

    \n

    Plaintext Storage of Credentials

    \n

    The iron password is only used to derive keys and is never sent or shared. However, in order to\ngenerate (and regenerate) the keys used to encrypt the object and compute the request MAC, the\nserver must have access to the password in plaintext form. This is in contrast, for example, to\nmodern operating systems, which store only a one-way hash of user credentials.

    \n

    If an attacker were to gain access to the password - or worse, to the server's database of all such\npassword - he or she would be able to encrypt and decrypt any sealed object. Accordingly, it is\ncritical that servers protect these passwords from unauthorized access.

    \n

    Frequently Asked Questions

    \n

    Where is the protocol specification?

    \n

    If you are looking for some prose explaining how all this works, there isn't any. iron is being\ndeveloped as an open source project instead of a standard. In other words, the code is the\nspecification. Not sure about something? Open an issue!

    \n

    Is it done?

    \n

    Yep.

    \n

    How come the defaults must be manually passed and not automatically applied?

    \n

    Because you should know what you are doing and explicitly set it. The options matter a lot to the\nsecurity properties of the implementation. While reasonable defaults are provided, you still need\nto explicitly state you want to use them.

    \n

    Acknowledgements

    \n

    Special thanks to Adam Barth for his infinite patience, and always insightful feedback and advice.

    \n

    Methods

    \n

    await seal(object, password, options)

    \n

    Seriealizes, encrypts, and signs objects into an iron protocol string where:

    \n
      \n
    • \n

      object - the data being sealed. Can be any JavaScript value that is serializable via\nJSON.stringify(). Note: JSON.stringify will not keep object properties which values are undefined. So if you pass an object like {id: undefined} then it will be serialized as {}.

      \n
    • \n
    • \n

      password - one of:

      \n
        \n
      • \n

        a password string used to generate a key using the pbkdf2 algorithm.

        \n
      • \n
      • \n

        a key buffer used as-is (after validating sufficient length based on the algorithm used).

        \n
      • \n
      • \n

        an object with:

        \n
          \n
        • \nid - a password identifier (must consist of only letters, numbers, and _).
        • \n
        • \nsecret - a password string or key buffer used for both encryption and integrity.
        • \n
        \n
      • \n
      • \n

        an object with:

        \n
          \n
        • \nid - a password identifier (must consist of only letters, numbers, and _).
        • \n
        • \nencryption - a password string or key buffer used for encryption.
        • \n
        • \nintegrity - a password string or key buffer used for integrity.
        • \n
        \n
      • \n
      \n
    • \n
    • \n

      options - see Options.

      \n
    • \n
    \n

    Return value: iron sealed string.

    \n

    Note: assigning the password used an id allows for password rotation to improve the security of\nyour deployment. Passwords should be rotated over time to reduce the risk of compromised security.\nWhen providing a password id, the id is included with the iron protocol string and it must\nmatch the id used to unseal.

    \n

    It is recommended to combine password id with the ttl option to generate iron protocol\nstrings of limited time validity which also allow for rotating passwords without the need to keep\nall previous passwords around (only the number of passwords used within the ttl window).

    \n

    await unseal(sealed, password, options)

    \n

    Verifies, decrypts, and reconstruct an iron protocol string into an object where:

    \n
      \n
    • \n

      sealed - the iron protocol string generated with seal().

      \n
    • \n
    • \n

      password - must match the password value passed to seal()\nand be one of:

      \n
        \n
      • \n

        a password string used to generate a key using the pbkdf2 algorithm.

        \n
      • \n
      • \n

        a key buffer used as-is (after validating sufficient length based on the algorithm used).

        \n
      • \n
      • \n

        an object with id as the key and value is one of:

        \n
          \n
        • a password string or key buffer used for both encryption and integrity.
        • \n
        • an object with:\n
            \n
          • \nencryption - a password string or key buffer used for encryption.
          • \n
          • \nintegrity - a password string or key buffer used for integrity.
          • \n
          \n
        • \n
        \n
      • \n
      \n
    • \n
    • \n

      options - see Options. Must match the options value passed to\nseal()

      \n
    • \n
    \n

    Return value: the verified, decripted object.

    \n

    Note: In order to enable password rotation, the password argument can accept an object with more\nthan one password, each keyed by its id. Together with the ttl option, the password object only\nneeds to include the passwords used within the ttl window.

    \n

    await generateKey(password, options)

    \n

    Generates an key from the password where:

    \n
      \n
    • \npassword - a password string or buffer key.
    • \n
    • \noptions - see Options.
    • \n
    \n

    Return value: an object with the following keys:

    \n
      \n
    • key
    • \n
    • salt
    • \n
    • iv
    • \n
    \n

    await encrypt(password, options, data)

    \n

    Encrypts data where:

    \n
      \n
    • \npassword - a password string or buffer key.
    • \n
    • \noptions - see Options.
    • \n
    • 'data' - the string to encrypt.
    • \n
    \n

    Return value: an object with the following keys:

    \n
      \n
    • encrypted
    • \n
    • \nkey:\n
        \n
      • key
      • \n
      • salt
      • \n
      • iv
      • \n
      \n
    • \n
    \n

    await decrypt(password, options, data)

    \n

    Decrypts data where:

    \n
      \n
    • \npassword - a password string or buffer key.
    • \n
    • \noptions - see Options.
    • \n
    • 'data' - the string to decrypt.
    • \n
    \n

    Return value: the decrypted string.

    \n

    await hmacWithPassword(password, options, data)

    \n

    Calculates an HMAC digest where:

    \n
      \n
    • \npassword - a password string or buffer key.
    • \n
    • \noptions - see Options.
    • \n
    • 'data' - the string to calculate the HMAC over.
    • \n
    \n

    Return value: an object with the following keys:

    \n
      \n
    • digest
    • \n
    • salt
    • \n
    \n

    Options

    \n

    iron provides options for customizing the key deriviation algorithm used to generate encryption\nand integrity verification keys, as well as the algorithms and salt sizes used.iron methods\ntake an options object with the following keys:

    \n
      \n
    • \nencryption - (required) defines the options used by the encryption process.
    • \n
    • \nintegrity - (required) defines the options used by the HMAC integrity verification process.
    • \n
    \n

    Each of these option objects support the following keys:

    \n
      \n
    • \nalgorithm - (required) the algorithm name ('aes-256-cbc' and 'aes-128-ctr' for encryption and\n'sha256' for integrity are the only two supported at this time).
    • \n
    • \niv - (optional) an initialization vector\nbuffer. If no iv is provided, one is generated based on the algorithm ivBits configuration.
    • \n
    \n

    When the password argument passed is a string (used for key generation), the following options\nare used:

    \n
      \n
    • \nsalt - (optional) a pre-generated salt string (a random buffer used to ensure that two\nidentical objects will generate a different encrypted result).
    • \n
    • \nsaltBits - (required if salt is not provided, otherwise ignored) the size of the salt.
    • \n
    • \niterations - (required) the number of iterations used to derive a key from the password.\nDefaults to 1 iteration. The number of ideal iterations to use is dependent on your\napplication's performance requirements. More iterations means it takes longer to generate the\nkey.
    • \n
    • \nminPasswordlength - (required) the minimum password string length required for key generation.\nDefaults to 32 characters.
    • \n
    \n

    The 'seal()' and 'unseal()' methods also support the following options:

    \n
      \n
    • \nttl - sealed object lifetime in milliseconds where 0 means forever. Defaults to 0.
    • \n
    • \ntimestampSkewSec - number of seconds of permitted clock skew for incoming expirations.\nDefaults to 60 seconds.
    • \n
    • \nlocaltimeOffsetMsec - local clock time offset, expressed in number of milliseconds (positive or\nnegative). Defaults to 0.
    • \n
    \n

    Defaults

    \n

    iron includes a default options object which can be passed to the methods as shown above in the\nexample. The default settings are:

    \n
    var options = {\n    encryption: {\n        saltBits: 256,\n        algorithm: 'aes-256-cbc',\n        iterations: 1\n    },\n    integrity: {\n        saltBits: 256,\n        algorithm: 'sha256',\n        iterations: 1\n    },\n    ttl: 0,\n    timestampSkewSec: 60,\n    localtimeOffsetMsec: 0\n};
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Encapsulated tokens (encrypted and mac'ed objects).", - "forks": 54, - "stars": 632, - "date": "2024-10-23T15:37:19Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/iron" - }, - "jwt": { - "name": "jwt", - "versions": [ - { - "name": "3.2.0", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "2.1.1", - "branch": "v2", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "3.2.0", - "2.1.1" - ], - "api": true, - "isPlugin": true, - "3.2.0": { - "menu": " - [server.auth.strategy](#serverauthstrategy)\n - [options](#options)\n - [keys](#keys)\n - [HMAC algorithms](#hmac-algorithms)\n - [Public algorithms](#public-algorithms)\n - [Public and RSA algorithms using JWKS](#public-and-rsa-algorithms-using-jwks)\n - [No algorithms](#no-algorithms)\n - [Custom Function](#custom-function)\n - [Keys Option Examples](#keys-option-examples)\n - [Important Security Note](#important-security-note)\n - [verify](#verify)\n - [headless](#headless)\n - [httpAuthScheme](#httpauthscheme)\n - [unauthorizedAttributes](#unauthorizedattributes)\n - [validate](#validate)\n - [validate example](#validate-example)\n - [headerName](#headername)\n - [cookieName](#cookiename)\n- [token](#token)\n - [generate](#generate)\n - [decode](#decode)\n - [verify](#verify-1)\n - [verifySignature](#verifysignature)\n - [verifyPayload](#verifypayload)\n - [verifyTime](#verifytime)\n- [Additional Information](#additional-information)\n - [Registered Claim Names](#registered-claim-names)\n - [Key algorithms supported by jwt](#key-algorithms-supported-by-jwt)", - "api": "

    server.auth.strategy

    \n

    Declares a named strategy using the jwt scheme.

    \n

    server.auth.strategy('my_jwt_strategy', 'jwt', options)

    \n

    options

    \n
      \n
    • \noptions - Config object containing keys to define your jwt authentication and response with the following:\n
        \n
      • \nkeys - Object or array of objects containing the key method to be used for jwt verification. The keys object can be expressed in many ways. See keys option examples for a handful of ways to express this option.
      • \n
      \n
    • \n
    \n
    keys
    \n

    There are many ways you can do keys and here is an extensive list of all the key options.

    \n
    HMAC algorithms
    \n

    You can do HMAC algorithms a couple of different ways. You can do it either like:

    \n
      \n
    • \nkeys - 'some_shared_secret' - a string that is used for shared secret.
    • \n
    \n

    OR with optional algorithm and key ID header (kid) like:

    \n
      \n
    • \nkeys\n
        \n
      • \nkey - String that is used for shared secret.
      • \n
      • \nalgorithms - Array of accepted algorithms (optional).
      • \n
      • \nkid - String representing the key ID header (optional).
      • \n
      \n
    • \n
    \n
    Public algorithms
    \n

    Similar to the HMAC algorithms you can do it like:

    \n
      \n
    • \nkey - Binary data of the public key. Often retrieve via Fs.readFileSync('public.pem').
    • \n
    \n

    OR with optional algorithm and key ID header (kid) like:

    \n
      \n
    • \nkeys\n
        \n
      • \nkey - Binary data of the public key. Often retrieve via Fs.readFileSync('public.pem').
      • \n
      • \nalgorithms - Array of accepted algorithms (optional).
      • \n
      • \nkid - String representing the key ID header (optional).
      • \n
      \n
    • \n
    \n
    Public and RSA algorithms using JWKS
    \n
      \n
    • \nkeys\n
        \n
      • \nuri - String that defines your json web key set uri.
      • \n
      • \nrejectUnauthorized - Boolean that determines if TLS flag indicating whether the client should reject a response from a server with invalid certificates. Default is true.
      • \n
      • \nheaders - Object containing the request headers to send to the uri (optional).
      • \n
      • \nalgorithms - Array of accepted algorithms (optional).
      • \n
      \n
    • \n
    \n
    No algorithms
    \n
      \n
    • \nkeys\n
        \n
      • \nalgorithms - ['none']\n
      • \n
      \n
    • \n
    \n
    Custom Function
    \n
      \n
    • \nkeys - (param) => { return key; } - Custom function that derives the key.
    • \n
    \n
    Keys Option Examples
    \n
        // Single shared secret\n    {\n        keys: 'some_shared_secret'\n    }\n    ...\n\n    // Single shared secret with algorithms and key ID header\n    {\n        keys: {\n            key: 'some_shared_secret',\n            algorithms: ['HS256', 'HS512'],\n            kid: 'someKid'\n        }\n    }\n    ...\n\n    // Multiple shared secret\n    {\n        keys: ['some_shared_secret_1', 'shared_secret_2', 'shared_secret_3']\n    }\n    ...\n\n    // Multiple shared secret with algorithm and key ID header\n    {\n        keys: [\n            {\n                key: 'some_shared_secret'\n                algorithms: ['HS256', 'HS512'],\n                kid: 'someKid'\n            },\n            {\n                key: 'shared_secret2'\n                algorithms: ['HS512'],\n                kid: 'someKid2'\n            }\n        ]\n    }\n    ...\n\n    // Single Public Key\n    {\n        keys: fs.readFileSync('public.pem')\n    }\n    ...\n\n    // Single EdDSA key with algorithms\n    {\n        keys: {\n            key: Mock.pair('EdDSA', 'ed25519').public,\n            algorithms: ['EdDSA']\n        }\n    }\n\n    ...\n    // Single JWKS with headers and algorithms\n    {\n        keys: {\n            uri: 'https://jwks-provider.com/.well-known/jwks.json',\n            headers: {'x-org-name': 'my_company'},\n            algorithms: ['RS256', 'RS512']\n        }\n    }\n    ...\n\n    // No algorithms\n    {\n        keys: ['none']\n    }\n    ...\n\n    // Single custom function\n    // This function accomplishes the same thing as Single shared secret\n    {\n        keys: () => { return 'some_shared_secret'; }\n    }
    \n
    Important Security Note
    \n

    It is not advisable to put shared secrets in your source code, use environment variables and/or other encryption methods to encrypt/decrypt your shared secret. It is also not advisable to use no algorithms. Both of these practices are ideal for local testing and should be used with caution.

    \n
    verify
    \n

    In addition to keys you can provide other options.

    \n
      \n
    • \nverify - Object to determine how key contents are verified beyond key signature. Set to false to do no verification. This includes the keys even if they are defined.\n
        \n
      • \naud - String or RegExp or array of strings or RegExp that matches the audience of the token. Set to boolean false to not verify aud. Required if verify is not false.
      • \n
      • \niss - String or array of strings that matches the issuer of the token. Set to boolean false to not verify iss. Required if verify is not false.
      • \n
      • \nsub - String or array of strings that matches the subject of the token. Set to boolean false to not verify sub. Required if verify is not false.
      • \n
      • \nnbf - Boolean to determine if the \"Not Before\" NumericDate of the token should be validated. Default is true.
      • \n
      • \nexp - Boolean to determine if the \"Expiration Time\" NumericDate of the token should be validated. Default is true.
      • \n
      • \nmaxAgeSec - Integer to determine the maximum age of the token in seconds. Default is 0. This is time validation using the \"Issued At\" NumericDate (iat). Please note that 0 effectively disables this validation, it does not make the maximum age of the token 0 seconds. Also if maxAgeSec is not 0 and exp is true, both will be validated and if either validation fails, the token validation will fail.
      • \n
      • \ntimeSkewSec - Integer to adust exp and maxAgeSec to account for server time drift in seconds. Default is 0.
      • \n
      \n
    • \n
    \n
    headless
    \n
      \n
    • \nheadless - String representing base64 header or an Object to use as a header on headless tokens. If this is set, tokens that contain a header section will return 401.
    • \n
    \n
    httpAuthScheme
    \n
      \n
    • \nhttpAuthScheme - String the represents the Authentication Scheme. Default is 'Bearer'.
    • \n
    \n
    unauthorizedAttributes
    \n
      \n
    • \nunauthorizedAttributes - String passed directly to Boom.unauthorized if no custom err is thrown. Useful for setting realm attribute in WWW-Authenticate header. Defaults to undefined.
    • \n
    \n
    validate
    \n
      \n
    • \nvalidate - Function that allows additional validation based on the decoded payload and to put specific credentials in the request object. Can be set to false if no additional validation is needed. Setting this to false will also set the credentials to be the exact payload of the token, including the Registered Claim Names.
    • \n
    \n

    The validate function has a signature of [async] function (artifacts, request, h) where:

    \n
      \n
    • \nartifacts - An object that contains information from the token.\n
        \n
      • \ntoken - The complete token that was sent.
      • \n
      • \ndecoded - An object that contains decoded token.\n
          \n
        • \nheader - An object that contain the header information.\n
            \n
          • \nalg - The algorithm used to sign the token.
          • \n
          • \ntyp - The token type (should be 'JWT' if present) (optional).
          • \n
          \n
        • \n
        • \npayload - An object containing the payload.
        • \n
        • \nsignature - The signature string of the token.
        • \n
        \n
      • \n
      • \nraw - An object that contains the token that was sent broken out by header, payload, and signature.
      • \n
      • \nkeys - An array of information about key(s) used for authentication\n
          \n
        • \nkey - The key.
        • \n
        • \nalgorithm - The algorithm used to sign the token.
        • \n
        • \nkid - The key ID header. undefined if none was set.
        • \n
        \n
      • \n
      \n
    • \n
    • \nrequest - Is the hapi request object of the request which is being authenticated.
    • \n
    • \nh - The response toolkit.
    • \n
    • Returns an object { isValid, credentials, response } where:\n
        \n
      • \nisValid - Boolean that should be set to true if additional validation passed, otherwise false.
      • \n
      • \ncredentials - Object passed back to the application in request.auth.credentials.
      • \n
      • \nresponse - Will be used immediately as a takeover response. isValid and credentials are ignored if provided.
      • \n
      \n
    • \n
    • Throwing an error from this function will replace default message in the Boom.unauthorized error.
    • \n
    • Typically, credentials are only included when isValid is true, but there are cases when the application needs to know who tried to authenticate even when it fails (e.g. with authentication mode 'try').
    • \n
    \n
    validate example
    \n

    Token payload:

    \n
    {\n    user: 'some_user_name',\n    group: 'hapi_community'\n}
    \n

    Function:

    \n
    validate: (artifacts, request, h) => {\n\n    if (artifacts.decoded.payload.user === 'help') {\n        return { response: h.redirect('https://hapi.dev/module/jwt/') }; // custom response\n    }\n\n    if (artifacts.decoded.payload.user === 'crash') {\n        throw new Error('We hit a tree!'); // custom message in Boom.unauthorized\n    }\n\n    let isValid;\n    if (artifacts.decoded.payload.group === 'hapi_community') {\n        isValid = true;\n    }\n    else {\n        isValid = false;\n    }\n\n    // Return isValid value based on group\n    // Set credentials object to have the key username with a value of the user value from the payload\n\n    return {\n        isValid,\n        credentials: { username: artifacts.decoded.payload.user }\n    };\n}
    \n
    headerName
    \n
      \n
    • \nheaderName - Tells the jwt plugin to read the token from the header specified. Default is 'authorization'.
    • \n
    \n
    cookieName
    \n
      \n
    • \ncookieName - Tells the jwt plugin to read the token from the cookie specified. Note that the plugin does not allow you to read from cookie and header at the same time, either read from a header or from a cookie. If you want to read from cookie and header you must use multiple strategies with in which one will have headerName config and other will have cookieName config. Defaults to undefined.
    • \n
    \n

    token

    \n

    In addition to creating an auth strategy, the jwt module can be used directly even if you aren't using hapi, to run token based functions.

    \n
    // Load modules\n\nconst Jwt = require('@hapi/jwt');\n\n// Generate a Token\n\nconst token = Jwt.token.generate(\n    {\n        aud: 'urn:audience:test',\n        iss: 'urn:issuer:test',\n        user: 'some_user_name',\n        group: 'hapi_community'\n    },\n    {\n        key: 'some_shared_secret',\n        algorithm: 'HS512'\n    },\n    {\n        ttlSec: 14400 // 4 hours\n    }\n);\n\n// Decode a token\n\nconst decodedToken = Jwt.token.decode(token);\n\n\n// Create function to verify a token\n\nconst verifyToken = (artifact, secret, options = {}) => {\n\n    try {\n        Jwt.token.verify(artifact, secret, options);\n        return { isValid: true };\n    }\n    catch (err) {\n        return {\n            isValid: false,\n            error: err.message\n        };\n    }\n\n};\n\n// Get response of a successful verification\n\nconst validResponse = verifyToken(decodedToken, 'some_shared_secret');\n\n// Get response of a unsuccessful verification due to wrong shared secret\n\nconst badSecretResponse = verifyToken(decodedToken, 'some_unshared_secret');\n\n// Get response of a unsuccessful verification due to wrong iss\n\nconst badIssResponse = verifyToken(decodedToken, 'some_shared_secret', { iss: 'urn:issuer:different_test' });\n\n// Display results to console\n\nconsole.dir(\n    {\n        token,\n        decodedToken,\n        validResponse,\n        badSecretResponse,\n        badIssResponse\n    },\n    { depth: null }\n);
    \n

    Displays the following to the console:

    \n
    {\n  token: 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ1cm46YXVka...', // Will vary based on time\n  decodedToken: {\n    token: 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ1cm46YXVka...', // Will vary based on time\n    decoded: {\n      header: { alg: 'HS512', typ: 'JWT' },\n      payload: {\n        aud: 'urn:audience:test',\n        iss: 'urn:issuer:test',\n        user: 'some_user_name',\n        group: 'hapi_community',\n        iat: 1600604562, // Will vary based on time\n        exp: 1600618962 // Will vary based on time\n      },\n      signature: 'yh3ASEIrgNJZn...' // Will vary based on time\n    },\n    raw: {\n      header: 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9',\n      payload: 'eyJhdWQiOiJ1cm46YXVka...', // Will vary based on time\n      signature: 'yh3ASEIrgNJZn...' // Will vary based on time\n    }\n  },\n  validResponse: { isValid: true },\n  badSecretResponse: { isValid: false, error: 'Invalid token signature' },\n  badIssResponse: { isValid: false, error: 'Token payload iss value not allowed' }\n}
    \n

    generate

    \n

    generate(payload, secret, [options])

    \n

    Generates a token as a string where:

    \n
      \n
    • \npayload - Object that contains Registered Claim Names (optional) and additional credentials (optional). While both Registered Claim Names and additional credentials are optional, an empty payload {}, would result in a key that only has an iat of now. This would make a token that is valid for one second and containing no other information.
    • \n
    • \nsecret - String or buffer that creates signature or object where:\n
        \n
      • \nkey - String or buffer that creates signature.
      • \n
      • \nalgorithm- String containing an accepted algorithm to be used. Default is 'HS256'.
      • \n
      \n
    • \n
    • \noptions - Optional configuration object with the following:\n
        \n
      • \nheader - Object to put additional key/value pairs in the header of the token in addition to alg and typ.
      • \n
      • \ntyp Boolean if set to false typ: 'JWT' is not included in the header.
      • \n
      • \nnow - Integer as an alternative way to set iat claim. Takes JavaScript style epoch time (with ms). iat claim must not be set and iat option must not be false. Milliseconds are truncated, not rounded.
      • \n
      • \nttlSec - Integer as an alternative way to set exp claim. exp is set to be iat + ttlSec. exp claim must not be set.
      • \n
      • \niat - Boolean if set to false to turn off default behavior of creating an iat claim.
      • \n
      • \nheadless - Boolean if set to true will create a headless token. Default is false.
      • \n
      \n
    • \n
    \n

    decode

    \n

    decode(token, [options])

    \n

    Returns an Object of a decoded token in the format of artifacts described in the validate section above. This does not verify the token, it only decodes it where:

    \n
      \n
    • \ntoken - String of encoded token.
    • \n
    • \noptions - Optional configuration object with the following:\n
        \n
      • \nheadless: String representing base64 header or an Object to use as a header on headless tokens. If this is set, tokens that contain a header section will create an error. Default is null.
      • \n
      \n
    • \n
    \n

    verify

    \n

    verify(artifacts, secret, [options])

    \n

    A function that will complete if verification passes or throw an error if verification fails where:

    \n
      \n
    • \nartifacts - Object of a decoded token in the format of artifacts described in the validate section above.
    • \n
    • \nsecret - String or buffer that creates signature or object where:\n
        \n
      • \nkey - String or buffer that creates signature.
      • \n
      • \nalgorithm- String containing an accepted algorithm to be used. Default is 'HS256'.
      • \n
      \n
    • \n
    • \noptions - Optional configuration object with the following:\n
        \n
      • \naud- String or RegExp or array of strings or RegExp that matches the audience of the token.
      • \n
      • \niss - String or array of strings that matches the issuer of the token.
      • \n
      • \nsub - String or array of strings that matches the subject of the token.
      • \n
      • \njti - String or array of strings that matches the JWT ID of the token.
      • \n
      • \nnonce - String or array of strings that matches the nonce of the token. nonce is used on Open ID for the ID Tokens.
      • \n
      • \nnbf - Integer that represents the \"Not Before\" NumericDate of the token.
      • \n
      • \nexp - Integer that represents the \"Expiration Time\" NumericDate of the token.
      • \n
      • \nnow - Integer that represents the current time in JavaScript epoch format (with msecs). When evaluated the msecs are truncated, not rounded.
      • \n
      • \nmaxAgeSec - Integer to determine the maximum age of the token in seconds. This is time validation using the \"Issued At\" NumericDate (iat).
      • \n
      • \ntimeSkewSec - Integer to adust exp and maxAgeSec to account for server time drift in seconds.
      • \n
      \n
    • \n
    \n

    verifySignature

    \n

    verifySignature({ decoded, raw }, secret)

    \n

    A function that will complete if the signature is valid or throw an error if invalid. This does not do verification on the payload. An expired token will not throw an error if the signature is valid, where:

    \n
      \n
    • \ndecoded - Object of decoded token in the format of artifacts.decoded described in the validate section above.
    • \n
    • \nraw - Object of decoded token in the format of artifacts.raw described in the validate section above.
    • \n
    • \nsecret - String or buffer that creates signature or object where:\n
        \n
      • \nkey - String or buffer that creates signature.
      • \n
      • \nalgorithm- String containing an accepted algorithm to be used. Default is 'HS256'.
      • \n
      \n
    • \n
    \n

    verifyPayload

    \n

    verifyPayload({ decoded }, [options])

    \n

    A function that will complete if payload verification passes or throw an error if payload verification fails. This does not do verification on the signature, where:

    \n
      \n
    • \ndecoded - Object of decoded token in the format of artifacts.decoded described in the validate section above.
    • \n
    • \noptions - Optional configuration object in format of options described in the verify section above.
    • \n
    \n

    verifyTime

    \n

    verifyTime({ decoded }, [options, nowSec])

    \n

    A function that will complete if iat and exp verification pass and throw an error if verification fails. This is a subset of verifyPayload for only iat and exp where:

    \n
      \n
    • \ndecoded - Object of decoded token in the format of artifacts.decoded described in the validate section above.
    • \n
    • \noptions - Optional configuration object with the following:\n
        \n
      • \nnow - Integer that represents the current time in JavaScript epoch format (with msecs). When evaluated the msecs are truncated, not rounded. Either this or nowSec need to be defined.
      • \n
      • \nexp - Integer that represents the \"Expiration Time\" NumericDate of the token.
      • \n
      • \nmaxAgeSec - Integer to determine the maximum age of the token in seconds. This is time validation using the \"Issued At\" NumericDate (iat).
      • \n
      • \ntimeSkewSec - Integer to adust exp and maxAgeSec to account for server time drift in seconds.
      • \n
      \n
    • \n
    \n

    Additional Information

    \n

    Registered Claim Names

    \n

    List and explanation of Registered Claim Names according to RFC 7519. Please note that NumericDate refers to a timestamp in UNIX epoch time, without milliseconds. Whereas Javascript integer timestamps include milliseconds.

    \n
      \n
    • \niss - The \"iss\" (issuer) claim identifies the principal that issued the\nJWT. Expressed in a string.
    • \n
    • \nsub- The \"sub\" (subject) claim identifies the principal that is the\nsubject of the JWT. Expressed in a string.
    • \n
    • \naud - The \"aud\" (audience) claim identifies the recipients that the JWT is\nintended for. Expressed in a string.
    • \n
    • \nexp - The \"exp\" (expiration time) claim identifies the expiration time on\nor after which the JWT MUST NOT be accepted for processing. Expressed in NumericDate.
    • \n
    • \nnbf - The \"nbf\" (not before) claim identifies the time before which the JWT\nMUST NOT be accepted for processing. Expressed in NumericDate.
    • \n
    • \niat - The \"iat\" (issued at) claim identifies the time at which the JWT was\nissued. Expressed in NumericDate.
    • \n
    • \njti - The \"jti\" (JWT ID) claim provides a unique identifier for the JWT. Expressed in a string.
    • \n
    • \nnonce - While nonce is not an RFC 7519 Registered Claim, it is used on Open ID for the ID Tokens.
    • \n
    \n

    Key algorithms supported by jwt

    \n
      \n
    • Public: ['RS256', 'RS384', 'RS512', 'PS256', 'PS384', 'PS512', 'ES256', 'ES384', 'ES512', 'EdDSA']\n
    • \n
    • RSA: ['RS256', 'RS384', 'RS512', 'PS256', 'PS384', 'PS512']\n
    • \n
    • HMAC: ['HS256', 'HS384', 'HS512']\n
    • \n
    • No Algorithm: ['none']\n
    • \n
    \n", - "intro": "## Introduction\n**jwt** is part of the **hapi** ecosystem and was designed to work seamlessly with the [hapi web framework](https://hapi.dev) and its other components (but works great on its own or with other frameworks). If you are using a different web framework and find this module useful, check out [hapi](https://hapi.dev) – they work even better together.\n", - "example": "", - "usage": "## Usage\n```js\n// Load modules\n\nconst Jwt = require('@hapi/jwt');\nconst Hapi = require('@hapi/hapi');\n\n// Declare internals\n\nconst internals = {};\n\ninternals.start = async function () {\n\n const server = Hapi.server({ port: 8000 });\n\n // Register jwt with the server\n\n await server.register(Jwt);\n\n // Declare an authentication strategy using the jwt scheme.\n // Use keys: with a shared secret key OR json web key set uri.\n // Use verify: To determine how key contents are verified beyond signature.\n // If verify is set to false, the keys option is not required and ignored.\n // The verify: { aud, iss, sub } options are required if verify is not set to false.\n // The verify: { exp, nbf, timeSkewSec, maxAgeSec } parameters have defaults.\n // Use validate: To create a function called after token validation.\n\n server.auth.strategy('my_jwt_strategy', 'jwt', {\n keys: 'some_shared_secret',\n verify: {\n aud: 'urn:audience:test',\n iss: 'urn:issuer:test',\n sub: false,\n nbf: true,\n exp: true,\n maxAgeSec: 14400, // 4 hours\n timeSkewSec: 15\n },\n validate: (artifacts, request, h) => {\n\n return {\n isValid: true,\n credentials: { user: artifacts.decoded.payload.user }\n };\n }\n });\n\n // Set the strategy\n\n server.auth.default('my_jwt_strategy');\n};\n\ninternals.start();\n```", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "2.1.1": { - "menu": "- [Usage](#usage)\n - [server.auth.strategy](#serverauthstrategy)\n - [options](#options)\n - [keys](#keys)\n - [HMAC algorithms](#hmac-algorithms)\n - [Public algorithms](#public-algorithms)\n - [Public and RSA algorithms using JWKS](#public-and-rsa-algorithms-using-jwks)\n - [No algorithms](#no-algorithms)\n - [Custom Function](#custom-function)\n - [Keys Option Examples](#keys-option-examples)\n - [Important Security Note](#important-security-note)\n - [verify](#verify)\n - [headless](#headless)\n - [httpAuthScheme](#httpauthscheme)\n - [unauthorizedAttributes](#unauthorizedattributes)\n - [validate](#validate)\n - [validate example](#validate-example)\n- [token](#token)\n - [generate](#generate)\n - [decode](#decode)\n - [verify](#verify-1)\n - [verifySignature](#verifysignature)\n - [verifyPayload](#verifypayload)\n - [verifyTime](#verifytime)\n- [Additional Information](#additional-information)\n - [Registered Claim Names](#registered-claim-names)\n - [Key algorithms supported by jwt](#key-algorithms-supported-by-jwt)", - "api": "

    Introduction

    \n

    jwt is part of the hapi ecosystem and was designed to work seamlessly with the hapi web framework and its other components (but works great on its own or with other frameworks). If you are using a different web framework and find this module useful, check out hapi – they work even better together.

    \n

    Usage

    \n
    // Load modules\n\nconst Jwt = require('@hapi/jwt');\nconst Hapi = require('@hapi/hapi');\n\n// Declare internals\n\nconst internals = {};\n\ninternals.start = async function () {\n\n    const server = Hapi.server({ port: 8000 });\n\n    // Register jwt with the server\n\n    await server.register(Jwt);\n\n    // Declare an authentication strategy using the jwt scheme.\n    // Use keys: with a shared secret key OR json web key set uri.\n    // Use verify: To determine how key contents are verified beyond signature.\n    // If verify is set to false, the keys option is not required and ignored.\n    // The verify: { aud, iss, sub } options are required if verify is not set to false.\n    // The verify: { exp, nbf, timeSkewSec, maxAgeSec } parameters have defaults.\n    // Use validate: To create a function called after token validation.\n\n    server.auth.strategy('my_jwt_strategy', 'jwt', {\n        keys: 'some_shared_secret',\n        verify: {\n            aud: 'urn:audience:test',\n            iss: 'urn:issuer:test',\n            sub: false,\n            nbf: true,\n            exp: true,\n            maxAgeSec: 14400, // 4 hours\n            timeSkewSec: 15\n        },\n        validate: (artifacts, request, h) => {\n\n            return {\n                isValid: true,\n                credentials: { user: artifacts.decoded.payload.user }\n            };\n        }\n    });\n\n    // Set the strategy\n\n    server.auth.default('my_jwt_strategy');\n};\n\ninternals.start();
    \n

    server.auth.strategy

    \n

    Declares a named strategy using the jwt scheme.

    \n

    server.auth.strategy('my_jwt_strategy', 'jwt', options)

    \n

    options

    \n
      \n
    • \noptions - Config object containing keys to define your jwt authentication and response with the following:\n
        \n
      • \nkeys - Object or array of objects containing the key method to be used for jwt verification. The keys object can be expressed in many ways. See keys option examples for a handful of ways to express this option.
      • \n
      \n
    • \n
    \n
    keys
    \n

    There are many ways you can do keys and here is an extensive list of all the key options.

    \n
    HMAC algorithms
    \n

    You can do HMAC algorithms a couple of different ways. You can do it either like:

    \n
      \n
    • \nkeys - 'some_shared_secret' - a string that is used for shared secret.
    • \n
    \n

    OR with optional algorithm and key ID header (kid) like:

    \n
      \n
    • \nkeys\n
        \n
      • \nkey - String that is used for shared secret.
      • \n
      • \nalgorithms - Array of accepted algorithms (optional).
      • \n
      • \nkid - String representing the key ID header (optional).
      • \n
      \n
    • \n
    \n
    Public algorithms
    \n

    Similar to the HMAC algorithms you can do it like:

    \n
      \n
    • \nkey - Binary data of the public key. Often retrieve via Fs.readFileSync('public.pem').
    • \n
    \n

    OR with optional algorithm and key ID header (kid) like:

    \n
      \n
    • \nkeys\n
        \n
      • \nkey - Binary data of the public key. Often retrieve via Fs.readFileSync('public.pem').
      • \n
      • \nalgorithms - Array of accepted algorithms (optional).
      • \n
      • \nkid - String representing the key ID header (optional).
      • \n
      \n
    • \n
    \n
    Public and RSA algorithms using JWKS
    \n
      \n
    • \nkeys\n
        \n
      • \nuri - String that defines your json web key set uri.
      • \n
      • \nrejectUnauthorized - Boolean that determines if TLS flag indicating whether the client should reject a response from a server with invalid certificates. Default is true.
      • \n
      • \nheaders - Object containing the request headers to send to the uri (optional).
      • \n
      • \nalgorithms - Array of accepted algorithms (optional).
      • \n
      \n
    • \n
    \n
    No algorithms
    \n
      \n
    • \nkeys\n
        \n
      • \nalgorithms - ['none']\n
      • \n
      \n
    • \n
    \n
    Custom Function
    \n
      \n
    • \nkeys - (param) => { return key; } - Custom function that derives the key.
    • \n
    \n
    Keys Option Examples
    \n
        // Single shared secret\n    {\n        keys: 'some_shared_secret'\n    }\n    ...\n\n    // Single shared secret with algorithms and key ID header\n    {\n        keys: {\n            key: 'some_shared_secret',\n            algorithms: ['HS256', 'HS512'],\n            kid: 'someKid'\n        }\n    }\n    ...\n\n    // Multiple shared secret\n    {\n        keys: ['some_shared_secret_1', 'shared_secret_2', 'shared_secret_3']\n    }\n    ...\n\n    // Multiple shared secret with algorithm and key ID header\n    {\n        keys: [\n            {\n                key: 'some_shared_secret'\n                algorithms: ['HS256', 'HS512'],\n                kid: 'someKid'\n            },\n            {\n                key: 'shared_secret2'\n                algorithms: ['HS512'],\n                kid: 'someKid2'\n            }\n        ]\n    }\n    ...\n\n    // Single Public Key\n    {\n        keys: fs.readFileSync('public.pem')\n    }\n    ...\n\n    // Single JWKS with headers and algorithms\n    {\n        keys: {\n            uri: 'https://jwks-provider.com/.well-known/jwks.json',\n            headers: {'x-org-name': 'my_company'},\n            algorithms: ['RS256', 'RS512']\n        }\n    }\n    ...\n\n    // No algorithms\n    {\n        keys: ['none']\n    }\n    ...\n\n    // Single custom function\n    // This function accomplishes the same thing as Single shared secret\n    {\n        keys: () => { return 'some_shared_secret'; }\n    }
    \n
    Important Security Note
    \n

    It is not advisable to put shared secrets in your source code, use environment variables and/or other encryption methods to encrypt/decrypt your shared secret. It is also not advisable to use no algorithms. Both of these practices are ideal for local testing and should be used with caution.

    \n
    verify
    \n

    In addition to keys you can provide other options.

    \n
      \n
    • \nverify - Object to determine how key contents are verified beyond key signature. Set to false to do no verification. This includes the keys even if they are defined.\n
        \n
      • \naud - String or RegExp or array of strings or RegExp that matches the audience of the token. Set to boolean false to not verify aud. Required if verify is not false.
      • \n
      • \niss - String or array of strings that matches the issuer of the token. Set to boolean false to not verify iss. Required if verify is not false.
      • \n
      • \nsub - String or array of strings that matches the subject of the token. Set to boolean false to not verify sub. Required if verify is not false.
      • \n
      • \nnbf - Boolean to determine if the \"Not Before\" NumericDate of the token should be validated. Default is true.
      • \n
      • \nexp - Boolean to determine if the \"Expiration Time\" NumericDate of the token should be validated. Default is true.
      • \n
      • \nmaxAgeSec - Integer to determine the maximum age of the token in seconds. Default is 0. This is time validation using the \"Issued At\" NumericDate (iat). Please note that 0 effectively disables this validation, it does not make the maximum age of the token 0 seconds. Also if maxAgeSec is not 0 and exp is true, both will be validated and if either validation fails, the token validation will fail.
      • \n
      • \ntimeSkewSec - Integer to adust exp and maxAgeSec to account for server time drift in seconds. Default is 0.
      • \n
      \n
    • \n
    \n
    headless
    \n
      \n
    • \nheadless - String representing base64 header or an Object to use as a header on headless tokens. If this is set, tokens that contain a header section will return 401.
    • \n
    \n
    httpAuthScheme
    \n
      \n
    • \nhttpAuthScheme - String the represents the Authentication Scheme. Default is 'Bearer'.
    • \n
    \n
    unauthorizedAttributes
    \n
      \n
    • \nunauthorizedAttributes - String passed directly to Boom.unauthorized if no custom err is thrown. Useful for setting realm attribute in WWW-Authenticate header. Defaults to undefined.
    • \n
    \n
    validate
    \n
      \n
    • \nvalidate - Function that allows additional validation based on the decoded payload and to put specific credentials in the request object. Can be set to false if no additional validation is needed. Setting this to false will also set the credentials to be the exact payload of the token, including the Registered Claim Names.
    • \n
    \n

    The validate function has a signature of [async] function (artifacts, request, h) where:

    \n
      \n
    • \nartifacts - An object that contains information from the token.\n
        \n
      • \ntoken - The complete token that was sent.
      • \n
      • \ndecoded - An object that contains decoded token.\n
          \n
        • \nheader - An object that contain the header information.\n
            \n
          • \nalg - The algorithm used to sign the token.
          • \n
          • \ntyp - The token type (should be 'JWT' if present) (optional).
          • \n
          \n
        • \n
        • \npayload - An object containing the payload.
        • \n
        • \nsignature - The signature string of the token.
        • \n
        \n
      • \n
      • \nraw - An object that contains the token that was sent broken out by header, payload, and signature.
      • \n
      • \nkeys - An array of information about key(s) used for authentication\n
          \n
        • \nkey - The key.
        • \n
        • \nalgorithm - The algorithm used to sign the token.
        • \n
        • \nkid - The key ID header. undefined if none was set.
        • \n
        \n
      • \n
      \n
    • \n
    • \nrequest - Is the hapi request object of the request which is being authenticated.
    • \n
    • \nh - The response toolkit.
    • \n
    • Returns an object { isValid, credentials, response } where:\n
        \n
      • \nisValid - Boolean that should be set to true if additional validation passed, otherwise false.
      • \n
      • \ncredentials - Object passed back to the application in request.auth.credentials.
      • \n
      • \nresponse - Will be used immediately as a takeover response. isValid and credentials are ignored if provided.
      • \n
      \n
    • \n
    • Throwing an error from this function will replace default message in the Boom.unauthorized error.
    • \n
    • Typically, credentials are only included when isValid is true, but there are cases when the application needs to know who tried to authenticate even when it fails (e.g. with authentication mode 'try').
    • \n
    \n
    validate example
    \n

    Token payload:

    \n
    {\n    user: 'some_user_name',\n    group: 'hapi_community'\n}
    \n

    Function:

    \n
    validate: (artifacts, request, h) => {\n\n    if (artifacts.decoded.payload.user === 'help') {\n        return { response: h.redirect('https://hapi.dev/module/jwt/') }; // custom response\n    }\n\n    if (artifacts.decoded.payload.user === 'crash') {\n        throw new Error('We hit a tree!'); // custom message in Boom.unauthorized\n    }\n\n    let isValid;\n    if (artifacts.decoded.payload.group === 'hapi_community') {\n        isValid = true;\n    }\n    else {\n        isValid = false;\n    }\n\n    // Return isValid value based on group\n    // Set credentials object to have the key username with a value of the user value from the payload\n\n    return {\n        isValid,\n        credentials: { username: artifacts.decoded.payload.user }\n    };\n}
    \n

    token

    \n

    In addition to creating an auth strategy, the jwt module can be used directly even if you aren't using hapi, to run token based functions.

    \n
    // Load modules\n\nconst Jwt = require('@hapi/jwt');\n\n// Generate a Token\n\nconst token = Jwt.token.generate(\n    {\n        aud: 'urn:audience:test',\n        iss: 'urn:issuer:test',\n        user: 'some_user_name',\n        group: 'hapi_community'\n    },\n    {\n        key: 'some_shared_secret',\n        algorithm: 'HS512'\n    },\n    {\n        ttlSec: 14400 // 4 hours\n    }\n);\n\n// Decode a token\n\nconst decodedToken = Jwt.token.decode(token);\n\n\n// Create function to verify a token\n\nconst verifyToken = (artifact, secret, options = {}) => {\n\n    try {\n        Jwt.token.verify(artifact, secret, options);\n        return { isValid: true };\n    }\n    catch (err) {\n        return {\n            isValid: false,\n            error: err.message\n        };\n    }\n\n};\n\n// Get response of a successful verification\n\nconst validResponse = verifyToken(decodedToken, 'some_shared_secret');\n\n// Get response of a unsuccessful verification due to wrong shared secret\n\nconst badSecretResponse = verifyToken(decodedToken, 'some_unshared_secret');\n\n// Get response of a unsuccessful verification due to wrong iss\n\nconst badIssResponse = verifyToken(decodedToken, 'some_shared_secret', { iss: 'urn:issuer:different_test' });\n\n// Display results to console\n\nconsole.dir(\n    {\n        token,\n        decodedToken,\n        validResponse,\n        badSecretResponse,\n        badIssResponse\n    },\n    { depth: null }\n);
    \n

    Displays the following to the console:

    \n
    {\n  token: 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ1cm46YXVka...', // Will vary based on time\n  decodedToken: {\n    token: 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ1cm46YXVka...', // Will vary based on time\n    decoded: {\n      header: { alg: 'HS512', typ: 'JWT' },\n      payload: {\n        aud: 'urn:audience:test',\n        iss: 'urn:issuer:test',\n        user: 'some_user_name',\n        group: 'hapi_community',\n        iat: 1600604562, // Will vary based on time\n        exp: 1600618962 // Will vary based on time\n      },\n      signature: 'yh3ASEIrgNJZn...' // Will vary based on time\n    },\n    raw: {\n      header: 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9',\n      payload: 'eyJhdWQiOiJ1cm46YXVka...', // Will vary based on time\n      signature: 'yh3ASEIrgNJZn...' // Will vary based on time\n    }\n  },\n  validResponse: { isValid: true },\n  badSecretResponse: { isValid: false, error: 'Invalid token signature' },\n  badIssResponse: { isValid: false, error: 'Token payload iss value not allowed' }\n}
    \n

    generate

    \n

    generate(payload, secret, [options])

    \n

    Generates a token as a string where:

    \n
      \n
    • \npayload - Object that contains Registered Claim Names (optional) and additional credentials (optional). While both Registered Claim Names and additional credentials are optional, an empty payload {}, would result in a key that only has an iat of now. This would make a token that is valid for one second and containing no other information.
    • \n
    • \nsecret - String or buffer that creates signature or object where:\n
        \n
      • \nkey - String or buffer that creates signature.
      • \n
      • \nalgorithm- String containing an accepted algorithm to be used. Default is 'HS256'.
      • \n
      \n
    • \n
    • \noptions - Optional configuration object with the following:\n
        \n
      • \nheader - Object to put additional key/value pairs in the header of the token in addition to alg and typ.
      • \n
      • \ntyp Boolean if set to false typ: 'JWT' is not included in the header.
      • \n
      • \nnow - Integer as an alternative way to set iat claim. Takes JavaScript style epoch time (with ms). iat claim must not be set and iat option must not be false. Milliseconds are truncated, not rounded.
      • \n
      • \nttlSec - Integer as an alternative way to set exp claim. exp is set to be iat + ttlSec. exp claim must not be set.
      • \n
      • \niat - Boolean if set to false to turn off default behavior of creating an iat claim.
      • \n
      • \nheadless - Boolean if set to true will create a headless token. Default is false.
      • \n
      \n
    • \n
    \n

    decode

    \n

    decode(token, [options])

    \n

    Returns an Object of a decoded token in the format of artifacts described in the validate section above. This does not verify the token, it only decodes it where:

    \n
      \n
    • \ntoken - String of encoded token.
    • \n
    • \noptions - Optional configuration object with the following:\n
        \n
      • \nheadless: String representing base64 header or an Object to use as a header on headless tokens. If this is set, tokens that contain a header section will create an error. Default is null.
      • \n
      \n
    • \n
    \n

    verify

    \n

    verify(artifacts, secret, [options])

    \n

    A function that will complete if verification passes or throw an error if verification fails where:

    \n
      \n
    • \nartifacts - Object of a decoded token in the format of artifacts described in the validate section above.
    • \n
    • \nsecret - String or buffer that creates signature or object where:\n
        \n
      • \nkey - String or buffer that creates signature.
      • \n
      • \nalgorithm- String containing an accepted algorithm to be used. Default is 'HS256'.
      • \n
      \n
    • \n
    • \noptions - Optional configuration object with the following:\n
        \n
      • \naud- String or RegExp or array of strings or RegExp that matches the audience of the token.
      • \n
      • \niss - String or array of strings that matches the issuer of the token.
      • \n
      • \nsub - String or array of strings that matches the subject of the token.
      • \n
      • \njti - String or array of strings that matches the JWT ID of the token.
      • \n
      • \nnonce - String or array of strings that matches the nonce of the token. nonce is used on Open ID for the ID Tokens.
      • \n
      • \nnbf - Integer that represents the \"Not Before\" NumericDate of the token.
      • \n
      • \nexp - Integer that represents the \"Expiration Time\" NumericDate of the token.
      • \n
      • \nnow - Integer that represents the current time in JavaScript epoch format (with msecs). When evaluated the msecs are truncated, not rounded.
      • \n
      • \nmaxAgeSec - Integer to determine the maximum age of the token in seconds. This is time validation using the \"Issued At\" NumericDate (iat).
      • \n
      • \ntimeSkewSec - Integer to adust exp and maxAgeSec to account for server time drift in seconds.
      • \n
      \n
    • \n
    \n

    verifySignature

    \n

    verifySignature({ decoded, raw }, secret)

    \n

    A function that will complete if the signature is valid or throw an error if invalid. This does not do verification on the payload. An expired token will not throw an error if the signature is valid, where:

    \n
      \n
    • \ndecoded - Object of decoded token in the format of artifacts.decoded described in the validate section above.
    • \n
    • \nraw - Object of decoded token in the format of artifacts.raw described in the validate section above.
    • \n
    • \nsecret - String or buffer that creates signature or object where:\n
        \n
      • \nkey - String or buffer that creates signature.
      • \n
      • \nalgorithm- String containing an accepted algorithm to be used. Default is 'HS256'.
      • \n
      \n
    • \n
    \n

    verifyPayload

    \n

    verifyPayload({ decoded }, [options])

    \n

    A function that will complete if payload verification passes or throw an error if payload verification fails. This does not do verification on the signature, where:

    \n
      \n
    • \ndecoded - Object of decoded token in the format of artifacts.decoded described in the validate section above.
    • \n
    • \noptions - Optional configuration object in format of options described in the verify section above.
    • \n
    \n

    verifyTime

    \n

    verifyTime({ decoded }, [options, nowSec])

    \n

    A function that will complete if iat and exp verification pass and throw an error if verification fails. This is a subset of verifyPayload for only iat and exp where:

    \n
      \n
    • \ndecoded - Object of decoded token in the format of artifacts.decoded described in the validate section above.
    • \n
    • \noptions - Optional configuration object with the following:\n
        \n
      • \nnow - Integer that represents the current time in JavaScript epoch format (with msecs). When evaluated the msecs are truncated, not rounded. Either this or nowSec need to be defined.
      • \n
      • \nexp - Integer that represents the \"Expiration Time\" NumericDate of the token.
      • \n
      • \nmaxAgeSec - Integer to determine the maximum age of the token in seconds. This is time validation using the \"Issued At\" NumericDate (iat).
      • \n
      • \ntimeSkewSec - Integer to adust exp and maxAgeSec to account for server time drift in seconds.
      • \n
      \n
    • \n
    \n

    Additional Information

    \n

    Registered Claim Names

    \n

    List and explanation of Registered Claim Names according to RFC 7519. Please note that NumericDate refers to a timestamp in UNIX epoch time, without milliseconds. Whereas Javascript integer timestamps include milliseconds.

    \n
      \n
    • \niss - The \"iss\" (issuer) claim identifies the principal that issued the\nJWT. Expressed in a string.
    • \n
    • \nsub- The \"sub\" (subject) claim identifies the principal that is the\nsubject of the JWT. Expressed in a string.
    • \n
    • \naud - The \"aud\" (audience) claim identifies the recipients that the JWT is\nintended for. Expressed in a string.
    • \n
    • \nexp - The \"exp\" (expiration time) claim identifies the expiration time on\nor after which the JWT MUST NOT be accepted for processing. Expressed in NumericDate.
    • \n
    • \nnbf - The \"nbf\" (not before) claim identifies the time before which the JWT\nMUST NOT be accepted for processing. Expressed in NumericDate.
    • \n
    • \niat - The \"iat\" (issued at) claim identifies the time at which the JWT was\nissued. Expressed in NumericDate.
    • \n
    • \njti - The \"jti\" (JWT ID) claim provides a unique identifier for the JWT. Expressed in a string.
    • \n
    • \nnonce - While nonce is not an RFC 7519 Registered Claim, it is used on Open ID for the ID Tokens.
    • \n
    \n

    Key algorithms supported by jwt

    \n
      \n
    • Public: ['RS256', 'RS384', 'RS512', 'PS256', 'PS384', 'PS512', 'ES256', 'ES384', 'ES512']\n
    • \n
    • RSA: ['RS256', 'RS384', 'RS512', 'PS256', 'PS384', 'PS512']\n
    • \n
    • HMAC: ['HS256', 'HS384', 'HS512']\n
    • \n
    • No Algorithm: ['none']\n
    • \n
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "JWT (JSON Web Token) Authentication.", - "forks": 25, - "stars": 36, - "date": "2024-03-16T11:06:55Z", - "updated": "Sat Mar 16 2024", - "link": "https://github.com/hapijs/jwt" - }, - "lab": { - "name": "lab", - "versions": [ - { - "name": "26.0.0", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "25.3.2", - "branch": "v25", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "24.7.1", - "branch": "v24", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "26.0.0", - "24.7.1", - "25.3.2" - ], - "api": true, - "isPlugin": false, - "26.0.0": { - "menu": " - [Behavior Driven Development](#behavior-driven-development)\n - [Test Driven Development](#test-driven-development)\n - [Best practices](#best-practices)\n - [Timeouts](#timeouts)\n - [Transforms](#transforms)\n - [TypeScript](#typescript)\n- [Command Line](#command-line)\n- [Methods](#methods)\n - [`Lab.script()`](#labscriptoptions)\n - [`script.after()`](#scriptafteroptions-action)\n - [`script.afterEach()`](#scriptaftereach)\n - [`script.before()`](#scriptbefore)\n - [`script.beforeEach()`](#scriptbeforeeach)\n - [`script.describe()`](#scriptdescribetitle-options-content)\n - [`script.experiment()`](#scriptexperimenttitle-options-content)\n - [`script.experiment.only()`](#scriptexperimentonlytitle-options-content)\n - [`script.experiment.skip()`](#scriptexperimentskiptitle-options-content)\n - [`script.it()`](#scriptittitle-options-test)\n - [`script.suite()`](#scriptsuitetitle-options-content)\n - [`script.test()`](#scripttesttitle-options-test)\n - [`script.test.only()`](#scripttestonlytitle-options-test)\n - [`script.test.skip()`](#scripttestskiptitle-options-test)\n - [`Flags`](#flags)\n - [`context`](#context)\n - [`mustCall()`](#mustcallfunc-count)\n - [`note()`](#notenote)\n - [`onCleanup`](#oncleanup)\n - [`onUncaughtException`](#onuncaughtexception)\n - [`onUnhandledRejection`](#onunhandledrejection)\n- [`.labrc.js` File](#labrcjs-file)\n - [Setting precedent](#setting-precedent)\n - [Available settings](#available-settings)\n- [Linting](#linting)\n - [Ignoring files in linting](#ignoring-files-in-linting)\n - [Only run linting](#only-run-linting)\n- [Integration with an assertion library](#integration-with-an-assertion-library)\n- [Debuggers](#debuggers)\n- [Multiple Reporters](#multiple-reporters)\n- [Custom Reporters](#custom-reporters)\n- [Coverage](#coverage)\n - [ESM support](#esm-support)\n - [Inline enabling/disabling](#inline-enablingdisabling)\n - [Coverage bypass stack](#coverage-bypass-stack)\n - [Excluding paths from coverage reporting](#excluding-paths-from-coverage-reporting)\n- [Acknowledgements](#acknowledgements)", - "api": "

    Behavior Driven Development

    \n

    To make lab look like BDD:

    \n
    const Code = require('@hapi/code');\nconst Lab = require('@hapi/lab');\n\nconst { expect } = Code;\nconst { after, before, describe, it } = exports.lab = Lab.script();\n\ndescribe('math', () => {\n\n    before(() => {});\n\n    after(() => {});\n\n    it('returns true when 1 + 1 equals 2', () => {\n\n        expect(1 + 1).to.equal(2);\n    });\n});
    \n

    Test Driven Development

    \n

    To make lab look like TDD:

    \n
    const Code = require('@hapi/code');\nconst Lab = require('@hapi/lab');\n\nconst { expect } = Code;\nconst { suite, test } = exports.lab = Lab.script();\n\nsuite('math', () => {\n\n    test('returns true when 1 + 1 equals 2', () => {\n\n        expect(1 + 1).to.equal(2);\n    });\n});
    \n

    Best practices

    \n
      \n
    • Add lab as a dev dependency to your project's package.json along with a test script:
    • \n
    \n
    {\n  \"devDependencies\": {\n    \"@hapi/lab\": \"21.x.x\"\n  },\n  \"scripts\": {\n    \"test\": \"lab -t 100\",\n    \"test-cov-html\": \"lab -r html -o coverage.html\"\n  }\n}
    \n

    Note that npm test will execute lab with the -t 100 option which will require 100% code coverage. Run npm run test-cov-html and check the coverage.html file to figure out where coverage is lacking. When coverage is below the threshold, the CLI will exit with code 1 and will result in an npm Error message.

    \n
      \n
    • Run your tests with
    • \n
    \n
    $ npm test
    \n

    Timeouts

    \n

    before(), after(), beforeEach(), afterEach() accept an optional options argument which must be an object with the following optional keys:

    \n
      \n
    • \ntimeout - set a specific timeout in milliseconds. Disabled by default or the value of -M.
    • \n
    \n
    lab.experiment('math', { timeout: 1000 }, () => {\n\n    lab.before({ timeout: 500 }, () =>  {\n\n        doSomething();\n    });\n\n    lab.test('returns true when 1 + 1 equals 2', () =>  {\n\n        expect(1 + 1).to.equal(2);\n    });\n});
    \n

    Transforms

    \n

    To use source transforms, you must specify a file with the -T command line option that tells Lab how to do the transformation. You can specify many extensions with different transform functions such as .ts or .jsx.

    \n

    TypeScript

    \n

    A TypeScript definition file is included with lab to make it easier to use inside of an existing TypeScript project. To enable running test files written in TypeScript use the --typescript CLI option.

    \n
    import * as Lab from '@hapi/lab';\nimport { expect } from '@hapi/code';\n\nconst lab = Lab.script();\nconst { describe, it, before } = lab;\nexport { lab };\n\n\ndescribe('experiment', () => {\n\n    before(() => {});\n\n    it('verifies 1 equals 1', () => {\n\n        expect(1).to.equal(1);\n    });\n});
    \n

    Then the test can be executed using the following command line:

    \n
    $ lab --typescript
    \n

    If your typescript project has custom paths, Lab can be passed tsconfig-paths/register as a requirement before running and it will resolve based on your path config.

    \n
    $ lab --typescript --require 'tsconfig-paths/register'
    \n

    Command Line

    \n

    lab supports the following command line options:

    \n
      \n
    • \n-a, --assert - name of assert library to use. To disable assertion library set to false.
    • \n
    • \n--bail - terminate the process with a non-zero exit code on the first test failure. Defaults to false.
    • \n
    • \n-c, --coverage - enables code coverage analysis.
    • \n
    • \n--coverage-path - sets code coverage path.
    • \n
    • \n--coverage-exclude - sets code coverage excludes.
    • \n
    • \n--coverage-all - report coverage for all matched files, not just those tested.
    • \n
    • \n--coverage-flat - do not perform a recursive find of files for coverage report. Requires --coverage-all\n
    • \n
    • \n--coverage-pattern - only report coverage for files with the given pattern in the name. Defaults to pattern. Requires --coverage-all\n
    • \n
    • \n--coverage-predicates - sets custom code coverage predicates.
    • \n
    • \n-C, --colors - enables or disables color output. Defaults to console capabilities.
    • \n
    • \n-d, --dry - dry run. Skips all tests. Use with -v to generate a test catalog. Defaults to false.
    • \n
    • \n-e, --environment - value to set the NODE_ENV environment variable to, defaults to 'test'.
    • \n
    • \n-f, --flat - do not perform a recursive load of test files within the test directory.
    • \n
    • \n-g, --grep - only run tests matching the given pattern which is internally compiled to a RegExp.
    • \n
    • \n-h, --help - show command line usage.
    • \n
    • \n-i, --id - only run the test for the given identifier (or identifiers range, e.g. lab -i 1-3,5). Use lab -dv to print all tests and their identifier without running the tests. This is an alias of ids array property in .labrc file.
    • \n
    • \n-I, --ignore - ignore a list of globals for the leak detection (comma separated), this is an alias of globals property in .labrc file. To ignore symbols, pass the symbol's string representation (e.g. Symbol(special)).
    • \n
    • \n--inspect - start lab in debug mode using the V8 Inspector.
    • \n
    • \n--inspect-brk - see --inspect.
    • \n
    • \n-l, --leaks - disables global variable leak detection.
    • \n
    • \n-L, --lint - run linting rules using linter. Disabled by default.
    • \n
    • \n--lint-errors-threshold - maximum absolute amount of linting errors. Defaults to 0.
    • \n
    • \n--lint-warnings-threshold - maximum absolute amount of linting warnings. Defaults to 0.
    • \n
    • \n--lint-fix - apply any fixes from the linter, requires -L or --lint to be enabled. Disabled by default.
    • \n
    • \n--lint-options - specify options to pass to linting program. It must be a string that is JSON.parse(able).
    • \n
    • \n-m, --timeout - individual tests timeout in milliseconds (zero disables timeout). Defaults to 2 seconds.
    • \n
    • \n-M, --context-timeout - default timeouts for before, after, beforeEach and afterEach in milliseconds. Disabled by default.
    • \n
    • \n-o, --output - file to write the report to, otherwise sent to stdout.
    • \n
    • \n-p, --default-plan-threshold - sets the minimum number of assertions a test must run. Overridable with plan.
    • \n
    • \n-P, --pattern - only load files with the given pattern in the name.
    • \n
    • \n-r, --reporter - the reporter used to generate the test results. Defaults to console. Options are:\n
        \n
      • \nconsole - text report.
      • \n
      • \nhtml - HTML test and code coverage report (sets -c).
      • \n
      • \njson - output results in JSON format.
      • \n
      • \njunit - output results in JUnit XML format.
      • \n
      • \ntap - TAP protocol report.
      • \n
      • \nlcov - output to lcov format.
      • \n
      • \nclover - output results in Clover XML format.
      • \n
      • \nMultiple Reporters - See Below
      • \n
      • \nCustom Reporters - See Below
      • \n
      \n
    • \n
    • \n--req, --require - dependencies to require and run before tests run (useful for things like babel, tsconfig-paths, test setup, etc).
    • \n
    • \n-R, --retries - the number of times to retry a failing test that is explicitly marked with retry. Defaults to 5.
    • \n
    • \n--shuffle - randomize the order that test scripts are executed. Will not work with --id.
    • \n
    • \n--seed - use this seed to randomize the order with --shuffle. This is useful to debug order dependent test failures.
    • \n
    • \n-s, --silence - silence test output, defaults to false.
    • \n
    • \n-S, --sourcemaps - enables sourcemap support for stack traces and code coverage, disabled by default.
    • \n
    • \n-t, --threshold - sets the minimum code test coverage percentage to 100%.
    • \n
    • \n--types-test - sets a single TypeScript definition test file (implies -Y). Use when the test directory contains other TypeScript files that should not be loaded for definition testing.
    • \n
    • \n-T, --transform - javascript file that exports an array of objects ie. [ { ext: \".js\", transform: (content, filename) => { ... } } ]. Note that if you use this option with -c (--coverage), then you must generate sourcemaps and pass sourcemaps option to get proper line numbers.
    • \n
    • \n--typescript - enables the built-in TypeScript transpiler which uses the project own's typescript module and tsconfig.json file (or its other formats).
    • \n
    • \n-v, --verbose - verbose test output, defaults to false.
    • \n
    • \n-V, --version - display lab version information.
    • \n
    • \n-Y, --types - validate the module TypeScript types definitions. This is designed exclusively for JavaScript modules that export a TypeScript definition file.
    • \n
    \n

    Methods

    \n

    Lab.script([options])

    \n

    Generates a test script interface which is used to add experiments and tests, where:

    \n
      \n
    • \noptions - an optional object with the following optional keys:\n
        \n
      • \nschedule - if false, an automatic execution of the script is disabled. Automatic execution allows running lab test scripts directly with Node.js without having to use the CLI (e.g. node test/script.js). When using lab programmatically, this behavior is undesired and can be turned off by setting schedule to false. If you need to see the output with schedule disabled you should set output to process.stdout. Defaults to true.
      • \n
      • \ncli - allows setting command line options within the script. Note that the last script file loaded wins and usage of this is recommended only for temporarily changing the execution of tests. This option is useful for code working with an automatic test engine that run tests on commits. Setting this option has no effect when not using the CLI runner. For example setting cli to { ids: [1] } will only execute the first test loaded.
      • \n
      \n
    • \n
    \n

    script.after([options], action)

    \n

    Executes the provided action after the current experiment block is finished where:

    \n
      \n
    • \noptions - optional flags as describe in script.test().
    • \n
    • \naction - a sync or async function using the signature function(flags) where:\n
        \n
      • \nflags - see Flags\n
      • \n
      \n
    • \n
    \n

    script.afterEach()

    \n

    Executes the provided action after each test is executed in the current experiment block where:

    \n
      \n
    • \noptions - optional flags as describe in script.test().
    • \n
    • \naction - a sync or async function using the signature function(flags) where:\n
        \n
      • \nflags - see Flags\n
      • \n
      \n
    • \n
    \n

    script.before()

    \n

    Executes the provided action before the current experiment block is started where:

    \n
      \n
    • \noptions - optional flags as describe in script.test().
    • \n
    • \naction - a sync or async function using the signature function(flags) where:\n
        \n
      • \nflags - see Flags\n
      • \n
      \n
    • \n
    \n

    script.beforeEach()

    \n

    Executes the provided action before each test is executed in the current experiment block where:

    \n
      \n
    • \noptions - optional flags as describe in script.test().
    • \n
    • \naction - a sync or async function using the signature function(flags) where:\n
        \n
      • \nflags - see Flags\n
      • \n
      \n
    • \n
    \n

    script.describe(title, [options], content)

    \n

    Same as script.experiment().

    \n

    script.experiment(title, [options], content)

    \n

    Sets up an experiment (a group of tests) where:

    \n
      \n
    • \ntitle - the experiment description.
    • \n
    • \noptions - optional settings:\n
        \n
      • \nskip - if true, sets the entire experiment content to be skipped during execution. Defaults to false.
      • \n
      • \nonly - if true, sets all other experiments to skip. Default to false.
      • \n
      • \ntimeout - overrides the default test timeout for tests and other timed operations. Defaults to 2000.
      • \n
      \n
    • \n
    • \ncontent - a function with signature function() which can setup other experiments or tests.
    • \n
    \n

    script.experiment.only(title, [options], content)

    \n

    Same as script.experiment() with the only option set to true.

    \n

    script.experiment.skip(title, [options], content)

    \n

    Same as script.experiment() with the skip option set to true.

    \n

    script.it(title, [options], test)

    \n

    Same as script.test().

    \n

    script.suite(title, [options], content)

    \n

    Same as script.experiment().

    \n

    script.test(title, [options], test)

    \n

    Sets up a test where:

    \n
      \n
    • \ntitle - the test description.
    • \n
    • \noptions - optional settings:\n
        \n
      • \nskip - if true, sets the entire experiment content to be skipped during execution. Defaults to false.
      • \n
      • \nonly - if true, sets all other experiments to skip. Default to false.
      • \n
      • \ntimeout - overrides the default test timeout for tests and other timed operations in milliseconds. Defaults to 2000.
      • \n
      • \nplan - the expected number of assertions the test must execute. This setting should only be used with an assertion library that supports a count() function, like code.
      • \n
      • \nretry - when true or set to a number greater than 0, if the test fails it will be retried retries (defaults to 5) number of times until it passes.
      • \n
      \n
    • \n
    • \ntest - a function with signature function(flags) where:\n
        \n
      • the function can throw if the test failed.
      • \n
      • the function can return a Promise which either resolves (success) or rejects (fails).
      • \n
      • all other return value is ignored.
      • \n
      • \nflags - a set of test utilities described in Flags.
      • \n
      \n
    • \n
    \n
    lab.experiment('my plan', () => {\n\n    lab.test('only a single assertion executes', { plan: 1 }, () => {\n\n        expect(1 + 1).to.equal(2);\n    });\n});
    \n

    script.test.only(title, [options], test)

    \n

    Same as calling script.test() with only option set to true.

    \n

    script.test.skip(title, [options], test)

    \n

    Same as calling script.test() with skip option set to true.

    \n

    Flags

    \n

    The test function is passed a flags object that can be used to create notes or set a function to execute for cleanup operations after the test is complete.

    \n

    context

    \n

    An object that is passed to before and after functions in addition to tests themselves. context is used to set properties inside the before function that can be used by a test function later. It is meant to reduce module level variables that are set by the before / beforeEach functions. The context object is shallow cloned when passed to tests, as well as to child experiments, allowing you to modify it for each experiment individually without conflict through the use of before, beforeEach, after and afterEach.

    \n
    lab.experiment('my experiment', () => {\n\n  lab.before(({ context }) => {\n\n      context.foo = 'bar';\n  })\n\n  lab.test('contains context', ({ context }) => {\n\n      expect(context.foo).to.equal('bar');\n  });\n\n  lab.experiment('a nested experiment', () => {\n\n    lab.before(({ context }) => {\n\n      context.foo = 'baz';\n    });\n\n    lab.test('has the correct context', ({ context }) => {\n\n      expect(context.foo).to.equal('baz');\n      // since this is a shallow clone, changes will not be carried to\n      // future tests or experiments\n      context.foo = 'fizzbuzz';\n    });\n\n    lab.test('receives a clean context', ({ context }) => {\n\n      expect(context.foo).to.equal('baz');\n    });\n  });\n\n  lab.experiment('another nested experiment', () => {\n\n    lab.test('maintains the original context', ({ context }) => {\n\n      expect(context.foo).to.equal('bar');\n    });\n  });\n});
    \n

    mustCall(func, count)

    \n

    Sets a requirement that a function must be called a certain number of times where:

    \n
      \n
    • \nfunc - the function to be called.
    • \n
    • \ncount - the number of required invocations.
    • \n
    \n

    Returns a wrapped copy of the function. After the test is complete, each mustCall assertion will be checked and the test will fail if any function was called the incorrect number of times.

    \n

    Below is an example demonstrating how to use mustCall to verify that fn is called exactly two times.

    \n
    lab.test('fn must be called twice', async (flags) => {\n\n    const fn = () => {};\n    const wrapped = flags.mustCall(fn, 2);\n    wrapped();\n\n    await doSomeAsyncOperation();\n    wrapped();\n});
    \n

    note(note)

    \n

    Adds notes to the test log where:

    \n
      \n
    • \nnote - a string to be included in the console reporter at the end of the output.
    • \n
    \n

    For example, if you would like to add a note with the current time, your test case may look like the following:

    \n
    lab.test('attaches notes', (flags) => {\n\n    expect(1 + 1).to.equal(2);\n    flags.note(`The current time is ${Date.now()}`);\n});
    \n

    Multiple notes can be appended for the same test case by simply calling note() repeatedly.

    \n

    onCleanup

    \n

    A property that can be assigned a cleanup function registered at runtime to be executed after the test completes. The cleanup function will execute even in the event of a timeout or error. Note that the cleanup function will be executed as-is without any timers. The function assigned to onCleanup can return a Promise that will be evaluated.

    \n
    lab.test('cleanups after test', (flags) => {\n\n    flags.onCleanup = () => {\n\n        cleanup_logic();\n    };\n\n    expect(1 + 1).to.equal(2);\n});
    \n

    onUncaughtException

    \n

    A property that can be assigned an override for global exception handling. This can be used to test the code that is explicitly meant to result in uncaught exceptions.

    \n
    lab.test('leaves an uncaught rejection', (flags) => {\n\n    return new Promise((resolve) => {\n\n        flags.onUncaughtException = (err) => {\n\n            expect(err).to.be.an.error('I want this exception to remain uncaught in production');\n            resolve(); // finish the test\n        };\n\n        // sample production code\n        setTimeout(() => {\n\n            throw new Error('I want this exception to remain uncaught in production');\n        });\n    });\n});
    \n

    onUnhandledRejection

    \n

    A property that can be assigned an override function for global rejection handling. This can be used to test the code that is explicitly meant to result in unhandled rejections.

    \n
    lab.test('leaves an unhandled rejection', (flags) => {\n\n    return new Promise((resolve) => {\n\n        flags.onUnhandledRejection = (err) => {\n\n            expect(err).to.be.an.error('I want this rejection to remain unhandled in production');\n            resolve(); // finish the test\n        };\n\n        // sample production code\n        setTimeout(() => {\n\n            Promise.reject(new Error('I want this rejection to remain unhandled in production'));\n        });\n    });\n});
    \n

    \n.labrc.js File

    \n

    lab supports a .labrc.js configuration file for centralizing lab settings. The .labrc.js file can be located in the current working directory, any directory that is the parent of the current working directory, or in the user's home directory. The .labrc.js file needs to be able to be required by Node.js. Therefore, either format it as a JSON file or with a module.exports that exports an object with the keys that are the settings.

    \n

    Below is an example of a .labrc.js file to enable linting and test coverage checking:

    \n
    module.exports = {\n    coverage: true,\n    threshold: 90,\n    lint: true\n};
    \n

    Setting precedent

    \n

    The .labrc.js file will override the lab default settings. Any options passed to the lab runner will override the settings found in .labrc.js. For example, assume you have the following .labrc.js file:

    \n
    module.exports = {\n    coverage: true,\n    threshold: 100\n};
    \n

    If you need to reduce the coverage threshold for a single run, you can execute lab as follows:

    \n
    lab -t 80
    \n

    Available settings

    \n

    The .labrc.js file supports configuration keys that are named with the long name of the command line settings. Therefore, if you need to specify an assert library, you would export a key named \"assert\" with the desired value.

    \n

    In addition, you can use the paths parameter to override the default test directory (i.e. ./test):

    \n
    module.exports = {\n    paths: ['test/lab'],\n};
    \n

    As stated at the beginning of the document, --ignore parameter is an alias for globals option in the .labrc file. Therefore if you wish to ignore specific files you'll need to append a globals setting, not an ignore one, as stated on #641.

    \n

    Linting

    \n

    lab uses a shareable eslint plugin containing a recommended config and several hapi specific linting rules. If you want to extend the default linter you must:

    \n
      \n
    1. \n

      Add @hapi/eslint-plugin as a dependency in your package.json.

      \n
    2. \n
    3. \n

      In your project's eslint configuration, add \"extends\": \"plugin:@hapi/recommended\".

      \n
    4. \n
    \n

    Your project's eslint configuration will now extend the default lab configuration.

    \n

    Ignoring files in linting

    \n

    Since eslint is used to lint, if you don't already have an eslint.config.{js|cjs|mjs|ts|mts|cts} you can create one,\nand add an ignores rule containing paths to be ignored. Here is an example preserving default hapi rules:

    \n
    import HapiPlugin from '@hapi/eslint-plugin';\n\nexport default [\n    {\n        ignores: ['node_modules/*', '**/vendor/*.js'],\n    },\n    ...HapiPlugin.configs.module,\n];
    \n

    Only run linting

    \n

    In order to run linting and not to execute tests you can combine the dry run\nflag with the lint flag.

    \n
    lab -dL\n
    \n

    Integration with an assertion library

    \n

    Using the --assert argument allows you to integrate Lab with your favorite assertion library. Aside from --assert from the CLI you can change the assert option when executing report. Whatever assertion library you specify is imported and assigned to the Lab.assertions property. Here is an example using lab --assert @hapi/code:

    \n
    const lab = exports.lab = Lab.script();\nconst { describe, it } = lab;\n\n// Testing shortcuts\nconst { expect, fail } = require('@hapi/code');\n\ndescribe('expectation', () => {\n\n    it('should be able to expect', () => {\n\n        expect(true).to.be.true();\n    });\n\n    it('should be able to fail (This test should fail)', () => {\n\n        fail('Should fail');\n    });\n});
    \n
    $ lab --assert @hapi/code\n
    \n

    If you use the Code assertion library Lab will let you know if you have any missing assertions. An example of this is:

    \n
    describe('expectation', () => {\n\n    it('Test should pass but get marked as having a missing expectation', () => {\n\n        // Invalid and missing assertion - false is a method, not a property!\n        // This test will pass.\n        Lab.expect(true).to.be.false;\n    });\n});
    \n

    This is an invalid test but it will pass as the .false assertion was not actually called. Lab will report the number of incomplete assertions, their location in your code and return a failure of the tests.

    \n

    Similarly, if you use an assertion library, lab will be able to report the verbosity of your tests. This is a measure of the number of assertions divided by the number of tests. The value will be output when using the console reporter and can be helpful in determining if too many or too few assertions exist in each test. What is too many or too few assertions is entirely up to you.

    \n

    Debuggers

    \n

    lab can be started with the option --inspect which will run it with the V8 Inspector.

    \n

    This debugger can be accessed using the URL that is printed in the console, or used in association with a few Chrome extensions (Node.js V8 Inspector, NIM, etc).

    \n

    As you may know, if your tests are associated with the command npm test, you can already run npm test -- --inspect to run it with the inspector and avoid creating another command. If you want to listen on a specific port for the inspector, pass --inspect={port}.

    \n

    lab also has automatic support for the WebStorm debugger, just start a normal debugging session on your npm test script.

    \n

    Multiple Reporters

    \n

    Multiple reporters can be specified by providing multiple reporter options.

    \n
    $ lab -r console -r html
    \n

    If any output -o is provided, they must match the same number of provided reporter options. The reporters would be paired with an output based on\nthe order in which they were supplied. When specifying multiple outputs, use stdout to send a particular reporter to stdout.

    \n
    $ lab -r console -o stdout -r html -o coverage.html -r lcov -o lcov.info -r json -o data.json
    \n

    In a .labrc.js file, multiple reporters and their associated output paths would be represented as follows:

    \n
    module.exports = {\n    reporter: ['console', 'html', 'lcov', 'json'],\n    output: ['stdout', 'coverage.html', 'lcov.info', 'data.json']\n};
    \n

    Multiple reporters of the same kind are also supported.

    \n
    $ lab -r console -o stdout -r console -o console.log
    \n

    Custom Reporters

    \n

    If the value passed for reporter isn't included with Lab, it is loaded from the filesystem. If the string starts with a period ('./custom-reporter'), it will be loaded relative to the current working directory. If it doesn't start with a period ('custom-reporter'), it will be loaded from the node_modules directory, just like any module installed using npm install.

    \n

    Reporters must be a class with the following methods: start, test and end. options are passed to the class constructor upon initialization.

    \n

    See the json reporter for a good starting point.

    \n

    Coverage

    \n

    ESM support

    \n

    Lab does not support code coverage for ES modules. There are two reasons for this: in order to implement this we would either use V8's builtin coverage or an ESM Loader. Unfortunately the former doesn't support granular branch coverage as we do in lab, and the latter is an experimental API that is still settling. We hope to provide ESM coverage support in the future once one or both of these issues are resolved.

    \n

    In the meantime, we recommend using lab with c8 in order to provide code coverage in ESM projects. Note that c8 does not support granular branch coverage the way we do in lab, for the same reasons listed above. Additionally, lab's coverage inline enabling/disabling and bypass stack are not compatible with c8, which has its own comparable functionality. It's pretty simple to use c8 with lab, though.

    \n

    First install c8:

    \n
    npm install --save-dev c8\n
    \n

    Next update your test command to start with c8. Here's an example in a package.json file switching from lab's coverage to c8's coverage:

    \n
       \"scripts\": {\n-      \"test\": \"lab -a @hapi/code -t 100\"\n+      \"test\": \"c8 --100 lab -a @hapi/code\"\n   },
    \n

    Inline enabling/disabling

    \n

    Sometimes you want to disable code coverage for specific lines, and have the coverage report omit them entirely. To do so, use the $lab:coverage:(off|on)$ comments. For example:

    \n
    // There is no way to cover this in node 0.10\n/* $lab:coverage:off$ */\nif (typeof value === 'symbol') {\n    // do something with value\n}\n/* $lab:coverage:on$ */
    \n

    Coverage bypass stack

    \n

    Disabling code coverage becomes tricky when dealing with machine-generated or machine-altered code. For example, babel can be configured to disable coverage for generated code using the auxiliaryCommentBefore and auxiliaryCommentAfter options. The naïve approach to this uses $lab:coverage:on$ and $lab:coverage:off$, but these directives overwrite any user-specified directives, so that a block where coverage should be disabled may have that coverage unintentionally re-enabled. To work around this issue, lab supports pushing the current code coverage bypass state onto an internal stack using the $lab:coverage:push$ directive, and supports restoring the top of the stack using the $lab:coverage:pop$ directive:

    \n
    // There is no way to cover this in node < 10.0.0\n/* $lab:coverage:off$ */\nconst { types } = Util;\nconst isSet = (types && types.isSet) || (set) => set instanceof Set;\n/* $lab:coverage:on$ */\n\n// When Util is imported using import and babel transpiles to cjs, babel can be\n// configured to use the stack:\n/* $lab:coverage:off$ */\nconst {\n  types\n} =\n/*$lab:coverage:push$/\n/*$lab:coverage:off$*/\n_util\n/*$lab:coverage:pop$/\n.\n/*$lab:coverage:push$/\n/*$lab:coverage:off$*/\ndefault\n/*$lab:coverage:pop$*/\n;\nconst isSet = types && types.isSet || (set) => set instanceof Set;\n/* $lab:coverage:on$ */
    \n

    Semantics:

    \n
      \n
    • \n$lab:coverage:push$ copies the current skip state to the top of the stack, and leaves it as the current state as well
    • \n
    • \n$lab:coverage:pop$ replaces the current skip state with the top of the stack, and removes the top of the stack\n
        \n
      • if the stack is empty, lab will tell you by throwing the error \"unable to pop coverage bypass stack\"\n
      • \n
      \n
    • \n
    \n

    Excluding paths from coverage reporting

    \n

    The --coverage-exclude argument can be repeated multiple times in order to add multiple paths to exclude. By default the node_modules and test directories are excluded. If you want to exclude those as well as a directory named public you can run lab as follows:

    \n
    lab -c --coverage-exclude test --coverage-exclude node_modules --coverage-exclude public
    \n

    Acknowledgements

    \n

    lab initial code borrowed heavily from mocha, including the actual code used to render the coverage report into HTML. lab coverage code was originally adapted from blanket which in turn uses falafel.

    \n", - "intro": "## Introduction\n\n**lab** is a simple test utility for Node.js. Unlike other test utilities, lab uses only async/await features and includes everything you should expect from a modern Node.js test utility. Our goal with **lab** is to keep the execution engine as simple as possible, and not try to build an extensible framework.\n\n**lab** works best with the [**code** assertion library](https://hapi.dev/family/code) but can be used with any assertion library that throws an error when a condition isn't met.\n", - "example": "", - "usage": "## Usage\n\nBy default, **lab** loads all the '\\*.js|cjs|mjs' files inside the local 'test' directory and executes the tests found. To use different directories or files, pass the file or directories as arguments:\n\n```bash\n$ lab unit.js\n```\n\nTest files must require the **lab** module, and export a test script:\n\n```javascript\nconst Code = require('@hapi/code');\nconst Lab = require('@hapi/lab');\n\nconst { expect } = Code;\nconst { it } = exports.lab = Lab.script();\n\nit('returns true when 1 + 1 equals 2', () => {\n\n expect(1 + 1).to.equal(2);\n});\n```\n\nOr\n\n```javascript\nconst Code = require('@hapi/code');\nconst Lab = require('@hapi/lab');\n\nconst { expect } = Code;\nconst lab = exports.lab = Lab.script();\n\nlab.test('returns true when 1 + 1 equals 2', () => {\n\n expect(1 + 1).to.equal(2);\n});\n```\n\nIf a test is performing an asynchronous operation then it should use the `async` / `await` keywords or return a Promise. For example:\n\n```javascript\nlab.test('config file has correct value', async () => {\n\n const file = await fs.readFile('config');\n expect(file.toString()).to.contain('something');\n});\n```\n\nTests can be organized into experiments:\n\n```javascript\nlab.experiment('math', () => {\n\n lab.test('returns true when 1 + 1 equals 2', () => {\n\n expect(1 + 1).to.equal(2);\n });\n});\n```\n\nIf you need to perform some setup operations before or after executing the tests inside an experiment, the `before()` and `after()` methods can be used. To execute code before or after each test in an experiment, use `beforeEach()` and `afterEach()`.\n\n```javascript\nlab.experiment('math', () => {\n\n lab.before(() => {\n\n return new Promise((resolve) => {\n\n // Wait 1 second\n setTimeout(() => {\n\n resolve();\n }, 1000);\n });\n });\n\n lab.beforeEach(() => {\n\n // Run before every single test\n });\n\n lab.test('returns true when 1 + 1 equals 2', () => {\n\n expect(1 + 1).to.equal(2);\n });\n});\n\n```\n\n`test()`, `before()`, `beforeEach()`, `after()` and `afterEach()` also support returning promises just as tests do:\n\n```javascript\nlab.experiment('math', () => {\n\n lab.before(() => {\n\n return aFunctionReturningAPromise();\n });\n\n lab.test('returns true when 1 + 1 equals 2', () => {\n\n return aFunctionReturningAPromise()\n .then((aValue) => {\n\n expect(aValue).to.equal(expectedValue);\n });\n });\n});\n```\n\nBoth `test()` and `experiment()` accept an optional `options` argument which must be an object with the following optional keys:\n- `timeout` - set a test or experiment specific timeout in milliseconds. Defaults to the global timeout (`2000`ms or the value of `-m`).\n- `skip` - skip execution. When used on an experiment, all children will be skipped - even if they are marked with `only`.\n- `only` - marks all other tests or experiments with `skip`.\n\nYou can also append `.only(…)` or `.skip(…)` to `test` and `experiment` instead of using `options`:\n\n```javascript\nlab.experiment('with only', () => {\n\n lab.test.only('only this test will run', () => {\n\n expect(1 + 1).to.equal(2);\n });\n\n lab.test('another test that will not be executed', () => {});\n});\n```\n", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "24.7.1": { - "menu": "- [Usage](#usage)\n - [Behavior Driven Development](#behavior-driven-development)\n - [Test Driven Development](#test-driven-development)\n - [Best practices](#best-practices)\n - [Timeouts](#timeouts)\n - [Transforms](#transforms)\n - [TypeScript](#typescript)\n- [Command Line](#command-line)\n- [Methods](#methods)\n - [`Lab.script()`](#labscriptoptions)\n - [`script.after()`](#scriptafteroptions-action)\n - [`script.afterEach()`](#scriptaftereach)\n - [`script.before()`](#scriptbefore)\n - [`script.beforeEach()`](#scriptbeforeeach)\n - [`script.describe()`](#scriptdescribetitle-options-content)\n - [`script.experiment()`](#scriptexperimenttitle-options-content)\n - [`script.experiment.only()`](#scriptexperimentonlytitle-options-content)\n - [`script.experiment.skip()`](#scriptexperimentskiptitle-options-content)\n - [`script.it()`](#scriptittitle-options-test)\n - [`script.suite()`](#scriptsuitetitle-options-content)\n - [`script.test()`](#scripttesttitle-options-test)\n - [`script.test.only()`](#scripttestonlytitle-options-test)\n - [`script.test.skip()`](#scripttestskiptitle-options-test)\n - [`Flags`](#flags)\n - [`context`](#context)\n - [`mustCall()`](#mustcallfunc-count)\n - [`note()`](#notenote)\n - [`onCleanup`](#oncleanup)\n - [`onUncaughtException`](#onuncaughtexception)\n - [`onUnhandledRejection`](#onunhandledrejection)\n- [`.labrc.js` File](#labrcjs-file)\n - [Setting precedent](#setting-precedent)\n - [Available settings](#available-settings)\n- [Linting](#linting)\n - [Ignoring files in linting](#ignoring-files-in-linting)\n - [Only run linting](#only-run-linting)\n- [Integration with an assertion library](#integration-with-an-assertion-library)\n- [Debuggers](#debuggers)\n- [Multiple Reporters](#multiple-reporters)\n- [Custom Reporters](#custom-reporters)\n- [Coverage](#coverage)\n - [ESM support](#esm-support)\n - [Inline enabling/disabling](#inline-enablingdisabling)\n - [Coverage bypass stack](#coverage-bypass-stack)\n - [Excluding paths from coverage reporting](#excluding-paths-from-coverage-reporting)\n- [Acknowledgements](#acknowledgements)", - "api": "

    Introduction

    \n

    lab is a simple test utility for Node.js. Unlike other test utilities, lab uses only async/await features and includes everything you should expect from a modern Node.js test utility. Our goal with lab is to keep the execution engine as simple as possible, and not try to build an extensible framework.

    \n

    lab works best with the code assertion library but can be used with any assertion library that throws an error when a condition isn't met.

    \n

    Usage

    \n

    By default, lab loads all the '*.js|cjs|mjs' files inside the local 'test' directory and executes the tests found. To use different directories or files, pass the file or directories as arguments:

    \n
    $ lab unit.js
    \n

    Test files must require the lab module, and export a test script:

    \n
    const Code = require('@hapi/code');\nconst Lab = require('@hapi/lab');\n\nconst { expect } = Code;\nconst { it } = exports.lab = Lab.script();\n\nit('returns true when 1 + 1 equals 2', () => {\n\n    expect(1 + 1).to.equal(2);\n});
    \n

    Or

    \n
    const Code = require('@hapi/code');\nconst Lab = require('@hapi/lab');\n\nconst { expect } = Code;\nconst lab = exports.lab = Lab.script();\n\nlab.test('returns true when 1 + 1 equals 2', () => {\n\n    expect(1 + 1).to.equal(2);\n});
    \n

    If a test is performing an asynchronous operation then it should use the async / await keywords or return a Promise. For example:

    \n
    lab.test('config file has correct value', async () => {\n\n    const file = await fs.readFile('config');\n    expect(file.toString()).to.contain('something');\n});
    \n

    Tests can be organized into experiments:

    \n
    lab.experiment('math', () => {\n\n    lab.test('returns true when 1 + 1 equals 2', () => {\n\n        expect(1 + 1).to.equal(2);\n    });\n});
    \n

    If you need to perform some setup operations before or after executing the tests inside an experiment, the before() and after() methods can be used. To execute code before or after each test in an experiment, use beforeEach() and afterEach().

    \n
    lab.experiment('math', () => {\n\n    lab.before(() => {\n\n        return new Promise((resolve) => {\n\n            // Wait 1 second\n            setTimeout(() => {\n\n                resolve();\n            }, 1000);\n        });\n    });\n\n    lab.beforeEach(() => {\n\n        // Run before every single test\n    });\n\n    lab.test('returns true when 1 + 1 equals 2', () => {\n\n        expect(1 + 1).to.equal(2);\n    });\n});
    \n

    test(), before(), beforeEach(), after() and afterEach() also support returning promises just as tests do:

    \n
    lab.experiment('math', () => {\n\n    lab.before(() => {\n\n        return aFunctionReturningAPromise();\n    });\n\n    lab.test('returns true when 1 + 1 equals 2', () => {\n\n        return aFunctionReturningAPromise()\n            .then((aValue) => {\n\n                expect(aValue).to.equal(expectedValue);\n            });\n    });\n});
    \n

    Both test() and experiment() accept an optional options argument which must be an object with the following optional keys:

    \n
      \n
    • \ntimeout - set a test or experiment specific timeout in milliseconds. Defaults to the global timeout (2000ms or the value of -m).
    • \n
    • \nskip - skip execution. When used on an experiment, all children will be skipped - even if they are marked with only.
    • \n
    • \nonly - marks all other tests or experiments with skip.
    • \n
    \n

    You can also append .only(…) or .skip(…) to test and experiment instead of using options:

    \n
    lab.experiment('with only', () => {\n\n    lab.test.only('only this test will run', () => {\n\n        expect(1 + 1).to.equal(2);\n    });\n\n    lab.test('another test that will not be executed', () => {});\n});
    \n

    Behavior Driven Development

    \n

    To make lab look like BDD:

    \n
    const Code = require('@hapi/code');\nconst Lab = require('@hapi/lab');\n\nconst { expect } = Code;\nconst { after, before, describe, it } = exports.lab = Lab.script();\n\ndescribe('math', () => {\n\n    before(() => {});\n\n    after(() => {});\n\n    it('returns true when 1 + 1 equals 2', () => {\n\n        expect(1 + 1).to.equal(2);\n    });\n});
    \n

    Test Driven Development

    \n

    To make lab look like TDD:

    \n
    const Code = require('@hapi/code');\nconst Lab = require('@hapi/lab');\n\nconst { expect } = Code;\nconst { suite, test } = exports.lab = Lab.script();\n\nsuite('math', () => {\n\n    test('returns true when 1 + 1 equals 2', () => {\n\n        expect(1 + 1).to.equal(2);\n    });\n});
    \n

    Best practices

    \n
      \n
    • Add lab as a dev dependency to your project's package.json along with a test script:
    • \n
    \n
    {\n  \"devDependencies\": {\n    \"@hapi/lab\": \"21.x.x\"\n  },\n  \"scripts\": {\n    \"test\": \"lab -t 100\",\n    \"test-cov-html\": \"lab -r html -o coverage.html\"\n  }\n}
    \n

    Note that npm test will execute lab with the -t 100 option which will require 100% code coverage. Run npm run test-cov-html and check the coverage.html file to figure out where coverage is lacking. When coverage is below the threshold, the CLI will exit with code 1 and will result in an npm Error message.

    \n
      \n
    • Run your tests with
    • \n
    \n
    $ npm test
    \n

    Timeouts

    \n

    before(), after(), beforeEach(), afterEach() accept an optional options argument which must be an object with the following optional keys:

    \n
      \n
    • \ntimeout - set a specific timeout in milliseconds. Disabled by default or the value of -M.
    • \n
    \n
    lab.experiment('math', { timeout: 1000 }, () => {\n\n    lab.before({ timeout: 500 }, () =>  {\n\n        doSomething();\n    });\n\n    lab.test('returns true when 1 + 1 equals 2', () =>  {\n\n        expect(1 + 1).to.equal(2);\n    });\n});
    \n

    Transforms

    \n

    To use source transforms, you must specify a file with the -T command line option that tells Lab how to do the transformation. You can specify many extensions with different transform functions such as .ts or .jsx.

    \n

    TypeScript

    \n

    A TypeScript definition file is included with lab to make it easier to use inside of an existing TypeScript project. To enable running test files written in TypeScript use the --typescript CLI option.

    \n
    import * as Lab from '@hapi/lab';\nimport { expect } from '@hapi/code';\n\nconst lab = Lab.script();\nconst { describe, it, before } = lab;\nexport { lab };\n\n\ndescribe('experiment', () => {\n\n    before(() => {});\n\n    it('verifies 1 equals 1', () => {\n\n        expect(1).to.equal(1);\n    });\n});
    \n

    Then the test can be executed using the following command line:

    \n
    $ lab --typescript
    \n

    If your typescript project has custom paths, Lab can be passed tsconfig-paths/register as a requirement before running and it will resolve based on your path config.

    \n
    $ lab --typescript --require 'tsconfig-paths/register'
    \n

    Command Line

    \n

    lab supports the following command line options:

    \n
      \n
    • \n-a, --assert - name of assert library to use. To disable assertion library set to false.
    • \n
    • \n--bail - terminate the process with a non-zero exit code on the first test failure. Defaults to false.
    • \n
    • \n-c, --coverage - enables code coverage analysis.
    • \n
    • \n--coverage-path - sets code coverage path.
    • \n
    • \n--coverage-exclude - sets code coverage excludes.
    • \n
    • \n--coverage-all - report coverage for all matched files, not just those tested.
    • \n
    • \n--coverage-flat - do not perform a recursive find of files for coverage report. Requires --coverage-all\n
    • \n
    • \n--coverage-pattern - only report coverage for files with the given pattern in the name. Defaults to pattern. Requires --coverage-all\n
    • \n
    • \n--coverage-predicates - sets custom code coverage predicates.
    • \n
    • \n-C, --colors - enables or disables color output. Defaults to console capabilities.
    • \n
    • \n-d, --dry - dry run. Skips all tests. Use with -v to generate a test catalog. Defaults to false.
    • \n
    • \n-e, --environment - value to set the NODE_ENV environment variable to, defaults to 'test'.
    • \n
    • \n-f, --flat - do not perform a recursive load of test files within the test directory.
    • \n
    • \n-g, --grep - only run tests matching the given pattern which is internally compiled to a RegExp.
    • \n
    • \n-h, --help - show command line usage.
    • \n
    • \n-i, --id - only run the test for the given identifier (or identifiers range, e.g. lab -i 1-3,5). Use lab -dv to print all tests and their identifier without running the tests. This is an alias of ids array property in .labrc file.
    • \n
    • \n-I, --ignore - ignore a list of globals for the leak detection (comma separated), this is an alias of globals property in .labrc file. To ignore symbols, pass the symbol's string representation (e.g. Symbol(special)).
    • \n
    • \n--inspect - start lab in debug mode using the V8 Inspector.
    • \n
    • \n--inspect-brk - see --inspect.
    • \n
    • \n-l, --leaks - disables global variable leak detection.
    • \n
    • \n-L, --lint - run linting rules using linter. Disabled by default.
    • \n
    • \n--lint-errors-threshold - maximum absolute amount of linting errors. Defaults to 0.
    • \n
    • \n--lint-warnings-threshold - maximum absolute amount of linting warnings. Defaults to 0.
    • \n
    • \n--lint-fix - apply any fixes from the linter, requires -L or --lint to be enabled. Disabled by default.
    • \n
    • \n--lint-options - specify options to pass to linting program. It must be a string that is JSON.parse(able).
    • \n
    • \n-m, --timeout - individual tests timeout in milliseconds (zero disables timeout). Defaults to 2 seconds.
    • \n
    • \n-M, --context-timeout - default timeouts for before, after, beforeEach and afterEach in milliseconds. Disabled by default.
    • \n
    • \n-o, --output - file to write the report to, otherwise sent to stdout.
    • \n
    • \n-p, --default-plan-threshold - sets the minimum number of assertions a test must run. Overridable with plan.
    • \n
    • \n-P, --pattern - only load files with the given pattern in the name.
    • \n
    • \n-r, --reporter - the reporter used to generate the test results. Defaults to console. Options are:\n
        \n
      • \nconsole - text report.
      • \n
      • \nhtml - HTML test and code coverage report (sets -c).
      • \n
      • \njson - output results in JSON format.
      • \n
      • \njunit - output results in JUnit XML format.
      • \n
      • \ntap - TAP protocol report.
      • \n
      • \nlcov - output to lcov format.
      • \n
      • \nclover - output results in Clover XML format.
      • \n
      • \nMultiple Reporters - See Below
      • \n
      • \nCustom Reporters - See Below
      • \n
      \n
    • \n
    • \n--req, --require - dependencies to require and run before tests run (useful for things like babel, tsconfig-paths, test setup, etc).
    • \n
    • \n-R, --retries - the number of times to retry a failing test that is explicitly marked with retry. Defaults to 5.
    • \n
    • \n--shuffle - randomize the order that test scripts are executed. Will not work with --id.
    • \n
    • \n--seed - use this seed to randomize the order with --shuffle. This is useful to debug order dependent test failures.
    • \n
    • \n-s, --silence - silence test output, defaults to false.
    • \n
    • \n-S, --sourcemaps - enables sourcemap support for stack traces and code coverage, disabled by default.
    • \n
    • \n-t, --threshold - sets the minimum code test coverage percentage to 100%.
    • \n
    • \n--types-test - sets a single TypeScript definition test file (implies -Y). Use when the test directory contains other TypeScript files that should not be loaded for definition testing.
    • \n
    • \n-T, --transform - javascript file that exports an array of objects ie. [ { ext: \".js\", transform: (content, filename) => { ... } } ]. Note that if you use this option with -c (--coverage), then you must generate sourcemaps and pass sourcemaps option to get proper line numbers.
    • \n
    • \n--typescript - enables the built-in TypeScript transpiler which uses the project own's typescript module and tsconfig.json file (or its other formats).
    • \n
    • \n-v, --verbose - verbose test output, defaults to false.
    • \n
    • \n-V, --version - display lab version information.
    • \n
    • \n-Y, --types - validate the module TypeScript types definitions. This is designed exclusively for JavaScript modules that export a TypeScript definition file.
    • \n
    \n

    Methods

    \n

    Lab.script([options])

    \n

    Generates a test script interface which is used to add experiments and tests, where:

    \n
      \n
    • \noptions - an optional object with the following optional keys:\n
        \n
      • \nschedule - if false, an automatic execution of the script is disabled. Automatic execution allows running lab test scripts directly with Node.js without having to use the CLI (e.g. node test/script.js). When using lab programmatically, this behavior is undesired and can be turned off by setting schedule to false. If you need to see the output with schedule disabled you should set output to process.stdout. Defaults to true.
      • \n
      • \ncli - allows setting command line options within the script. Note that the last script file loaded wins and usage of this is recommended only for temporarily changing the execution of tests. This option is useful for code working with an automatic test engine that run tests on commits. Setting this option has no effect when not using the CLI runner. For example setting cli to { ids: [1] } will only execute the first test loaded.
      • \n
      \n
    • \n
    \n

    script.after([options], action)

    \n

    Executes the provided action after the current experiment block is finished where:

    \n
      \n
    • \noptions - optional flags as describe in script.test().
    • \n
    • \naction - a sync or async function using the signature function(flags) where:\n
        \n
      • \nflags - see Flags\n
      • \n
      \n
    • \n
    \n

    script.afterEach()

    \n

    Executes the provided action after each test is executed in the current experiment block where:

    \n
      \n
    • \noptions - optional flags as describe in script.test().
    • \n
    • \naction - a sync or async function using the signature function(flags) where:\n
        \n
      • \nflags - see Flags\n
      • \n
      \n
    • \n
    \n

    script.before()

    \n

    Executes the provided action before the current experiment block is started where:

    \n
      \n
    • \noptions - optional flags as describe in script.test().
    • \n
    • \naction - a sync or async function using the signature function(flags) where:\n
        \n
      • \nflags - see Flags\n
      • \n
      \n
    • \n
    \n

    script.beforeEach()

    \n

    Executes the provided action before each test is executed in the current experiment block where:

    \n
      \n
    • \noptions - optional flags as describe in script.test().
    • \n
    • \naction - a sync or async function using the signature function(flags) where:\n
        \n
      • \nflags - see Flags\n
      • \n
      \n
    • \n
    \n

    script.describe(title, [options], content)

    \n

    Same as script.experiment().

    \n

    script.experiment(title, [options], content)

    \n

    Sets up an experiment (a group of tests) where:

    \n
      \n
    • \ntitle - the experiment description.
    • \n
    • \noptions - optional settings:\n
        \n
      • \nskip - if true, sets the entire experiment content to be skipped during execution. Defaults to false.
      • \n
      • \nonly - if true, sets all other experiments to skip. Default to false.
      • \n
      • \ntimeout - overrides the default test timeout for tests and other timed operations. Defaults to 2000.
      • \n
      \n
    • \n
    • \ncontent - a function with signature function() which can setup other experiments or tests.
    • \n
    \n

    script.experiment.only(title, [options], content)

    \n

    Same as script.experiment() with the only option set to true.

    \n

    script.experiment.skip(title, [options], content)

    \n

    Same as script.experiment() with the skip option set to true.

    \n

    script.it(title, [options], test)

    \n

    Same as script.test().

    \n

    script.suite(title, [options], content)

    \n

    Same as script.experiment().

    \n

    script.test(title, [options], test)

    \n

    Sets up a test where:

    \n
      \n
    • \ntitle - the test description.
    • \n
    • \noptions - optional settings:\n
        \n
      • \nskip - if true, sets the entire experiment content to be skipped during execution. Defaults to false.
      • \n
      • \nonly - if true, sets all other experiments to skip. Default to false.
      • \n
      • \ntimeout - overrides the default test timeout for tests and other timed operations in milliseconds. Defaults to 2000.
      • \n
      • \nplan - the expected number of assertions the test must execute. This setting should only be used with an assertion library that supports a count() function, like code.
      • \n
      • \nretry - when true or set to a number greater than 0, if the test fails it will be retried retries (defaults to 5) number of times until it passes.
      • \n
      \n
    • \n
    • \ntest - a function with signature function(flags) where:\n
        \n
      • the function can throw if the test failed.
      • \n
      • the function can return a Promise which either resolves (success) or rejects (fails).
      • \n
      • all other return value is ignored.
      • \n
      • \nflags - a set of test utilities described in Flags.
      • \n
      \n
    • \n
    \n
    lab.experiment('my plan', () => {\n\n    lab.test('only a single assertion executes', { plan: 1 }, () => {\n\n        expect(1 + 1).to.equal(2);\n    });\n});
    \n

    script.test.only(title, [options], test)

    \n

    Same as calling script.test() with only option set to true.

    \n

    script.test.skip(title, [options], test)

    \n

    Same as calling script.test() with skip option set to true.

    \n

    Flags

    \n

    The test function is passed a flags object that can be used to create notes or set a function to execute for cleanup operations after the test is complete.

    \n

    context

    \n

    An object that is passed to before and after functions in addition to tests themselves. context is used to set properties inside the before function that can be used by a test function later. It is meant to reduce module level variables that are set by the before / beforeEach functions. The context object is shallow cloned when passed to tests, as well as to child experiments, allowing you to modify it for each experiment individually without conflict through the use of before, beforeEach, after and afterEach.

    \n
    lab.experiment('my experiment', () => {\n\n  lab.before(({ context }) => {\n\n      context.foo = 'bar';\n  })\n\n  lab.test('contains context', ({ context }) => {\n\n      expect(context.foo).to.equal('bar');\n  });\n\n  lab.experiment('a nested experiment', () => {\n\n    lab.before(({ context }) => {\n\n      context.foo = 'baz';\n    });\n\n    lab.test('has the correct context', ({ context }) => {\n\n      expect(context.foo).to.equal('baz');\n      // since this is a shallow clone, changes will not be carried to\n      // future tests or experiments\n      context.foo = 'fizzbuzz';\n    });\n\n    lab.test('receives a clean context', ({ context }) => {\n\n      expect(context.foo).to.equal('baz');\n    });\n  });\n\n  lab.experiment('another nested experiment', () => {\n\n    lab.test('maintains the original context', ({ context }) => {\n\n      expect(context.foo).to.equal('bar');\n    });\n  });\n});
    \n

    mustCall(func, count)

    \n

    Sets a requirement that a function must be called a certain number of times where:

    \n
      \n
    • \nfunc - the function to be called.
    • \n
    • \ncount - the number of required invocations.
    • \n
    \n

    Returns a wrapped copy of the function. After the test is complete, each mustCall assertion will be checked and the test will fail if any function was called the incorrect number of times.

    \n

    Below is an example demonstrating how to use mustCall to verify that fn is called exactly two times.

    \n
    lab.test('fn must be called twice', async (flags) => {\n\n    const fn = () => {};\n    const wrapped = flags.mustCall(fn, 2);\n    wrapped();\n\n    await doSomeAsyncOperation();\n    wrapped();\n});
    \n

    note(note)

    \n

    Adds notes to the test log where:

    \n
      \n
    • \nnote - a string to be included in the console reporter at the end of the output.
    • \n
    \n

    For example, if you would like to add a note with the current time, your test case may look like the following:

    \n
    lab.test('attaches notes', (flags) => {\n\n    expect(1 + 1).to.equal(2);\n    flags.note(`The current time is ${Date.now()}`);\n});
    \n

    Multiple notes can be appended for the same test case by simply calling note() repeatedly.

    \n

    onCleanup

    \n

    A property that can be assigned a cleanup function registered at runtime to be executed after the test completes. The cleanup function will execute even in the event of a timeout or error. Note that the cleanup function will be executed as-is without any timers. The function assigned to onCleanup can return a Promise that will be evaluated.

    \n
    lab.test('cleanups after test', (flags) => {\n\n    flags.onCleanup = () => {\n\n        cleanup_logic();\n    };\n\n    expect(1 + 1).to.equal(2);\n});
    \n

    onUncaughtException

    \n

    A property that can be assigned an override for global exception handling. This can be used to test the code that is explicitly meant to result in uncaught exceptions.

    \n
    lab.test('leaves an uncaught rejection', (flags) => {\n\n    return new Promise((resolve) => {\n\n        flags.onUncaughtException = (err) => {\n\n            expect(err).to.be.an.error('I want this exception to remain uncaught in production');\n            resolve(); // finish the test\n        };\n\n        // sample production code\n        setTimeout(() => {\n\n            throw new Error('I want this exception to remain uncaught in production');\n        });\n    });\n});
    \n

    onUnhandledRejection

    \n

    A property that can be assigned an override function for global rejection handling. This can be used to test the code that is explicitly meant to result in unhandled rejections.

    \n
    lab.test('leaves an unhandled rejection', (flags) => {\n\n    return new Promise((resolve) => {\n\n        flags.onUnhandledRejection = (err) => {\n\n            expect(err).to.be.an.error('I want this rejection to remain unhandled in production');\n            resolve(); // finish the test\n        };\n\n        // sample production code\n        setTimeout(() => {\n\n            Promise.reject(new Error('I want this rejection to remain unhandled in production'));\n        });\n    });\n});
    \n

    \n.labrc.js File

    \n

    lab supports a .labrc.js configuration file for centralizing lab settings. The .labrc.js file can be located in the current working directory, any directory that is the parent of the current working directory, or in the user's home directory. The .labrc.js file needs to be able to be required by Node.js. Therefore, either format it as a JSON file or with a module.exports that exports an object with the keys that are the settings.

    \n

    Below is an example of a .labrc.js file to enable linting and test coverage checking:

    \n
    module.exports = {\n    coverage: true,\n    threshold: 90,\n    lint: true\n};
    \n

    Setting precedent

    \n

    The .labrc.js file will override the lab default settings. Any options passed to the lab runner will override the settings found in .labrc.js. For example, assume you have the following .labrc.js file:

    \n
    module.exports = {\n    coverage: true,\n    threshold: 100\n};
    \n

    If you need to reduce the coverage threshold for a single run, you can execute lab as follows:

    \n
    lab -t 80
    \n

    Available settings

    \n

    The .labrc.js file supports configuration keys that are named with the long name of the command line settings. Therefore, if you need to specify an assert library, you would export a key named \"assert\" with the desired value.

    \n

    In addition, you can use the paths parameter to override the default test directory (i.e. ./test):

    \n
    module.exports = {\n    paths: ['test/lab'],\n};
    \n

    As stated at the beginning of the document, --ignore parameter is an alias for globals option in the .labrc file. Therefore if you wish to ignore specific files you'll need to append a globals setting, not an ignore one, as stated on #641.

    \n

    Linting

    \n

    lab uses a shareable eslint plugin containing a recommended config and several hapi specific linting rules. If you want to extend the default linter you must:

    \n
      \n
    1. \n

      Add @hapi/eslint-plugin as a dependency in your package.json.

      \n
    2. \n
    3. \n

      In your project's eslint configuration, add \"extends\": \"plugin:@hapi/recommended\".

      \n
    4. \n
    \n

    Your project's eslint configuration will now extend the default lab configuration.

    \n

    Ignoring files in linting

    \n

    Since eslint is used to lint, you can create an .eslintignore containing paths to be ignored:

    \n
    node_modules/*\n**/vendor/*.js\n
    \n

    Only run linting

    \n

    In order to run linting and not to execute tests you can combine the dry run\nflag with the lint flag.

    \n
    lab -dL\n
    \n

    Integration with an assertion library

    \n

    Using the --assert argument allows you to integrate Lab with your favorite assertion library. Aside from --assert from the CLI you can change the assert option when executing report. Whatever assertion library you specify is imported and assigned to the Lab.assertions property. Here is an example using lab --assert @hapi/code:

    \n
    const lab = exports.lab = Lab.script();\nconst { describe, it } = lab;\n\n// Testing shortcuts\nconst { expect, fail } = require('@hapi/code');\n\ndescribe('expectation', () => {\n\n    it('should be able to expect', () => {\n\n        expect(true).to.be.true();\n    });\n\n    it('should be able to fail (This test should fail)', () => {\n\n        fail('Should fail');\n    });\n});
    \n
    $ lab --assert @hapi/code\n
    \n

    If you use the Code assertion library Lab will let you know if you have any missing assertions. An example of this is:

    \n
    describe('expectation', () => {\n\n    it('Test should pass but get marked as having a missing expectation', () => {\n\n        // Invalid and missing assertion - false is a method, not a property!\n        // This test will pass.\n        Lab.expect(true).to.be.false;\n    });\n});
    \n

    This is an invalid test but it will pass as the .false assertion was not actually called. Lab will report the number of incomplete assertions, their location in your code and return a failure of the tests.

    \n

    Similarly, if you use an assertion library, lab will be able to report the verbosity of your tests. This is a measure of the number of assertions divided by the number of tests. The value will be output when using the console reporter and can be helpful in determining if too many or too few assertions exist in each test. What is too many or too few assertions is entirely up to you.

    \n

    Debuggers

    \n

    lab can be started with the option --inspect which will run it with the V8 Inspector.

    \n

    This debugger can be accessed using the URL that is printed in the console, or used in association with a few Chrome extensions (Node.js V8 Inspector, NIM, etc).

    \n

    As you may know, if your tests are associated with the command npm test, you can already run npm test -- --inspect to run it with the inspector and avoid creating another command. If you want to listen on a specific port for the inspector, pass --inspect={port}.

    \n

    lab also has automatic support for the WebStorm debugger, just start a normal debugging session on your npm test script.

    \n

    Multiple Reporters

    \n

    Multiple reporters can be specified by providing multiple reporter options.

    \n
    $ lab -r console -r html
    \n

    If any output -o is provided, they must match the same number of provided reporter options. The reporters would be paired with an output based on\nthe order in which they were supplied. When specifying multiple outputs, use stdout to send a particular reporter to stdout.

    \n
    $ lab -r console -o stdout -r html -o coverage.html -r lcov -o lcov.info -r json -o data.json
    \n

    In a .labrc.js file, multiple reporters and their associated output paths would be represented as follows:

    \n
    module.exports = {\n    reporter: ['console', 'html', 'lcov', 'json'],\n    output: ['stdout', 'coverage.html', 'lcov.info', 'data.json']\n};
    \n

    Multiple reporters of the same kind are also supported.

    \n
    $ lab -r console -o stdout -r console -o console.log
    \n

    Custom Reporters

    \n

    If the value passed for reporter isn't included with Lab, it is loaded from the filesystem. If the string starts with a period ('./custom-reporter'), it will be loaded relative to the current working directory. If it doesn't start with a period ('custom-reporter'), it will be loaded from the node_modules directory, just like any module installed using npm install.

    \n

    Reporters must be a class with the following methods: start, test and end. options are passed to the class constructor upon initialization.

    \n

    See the json reporter for a good starting point.

    \n

    Coverage

    \n

    ESM support

    \n

    Lab does not support code coverage for ES modules. There are two reasons for this: in order to implement this we would either use V8's builtin coverage or an ESM Loader. Unfortunately the former doesn't support granular branch coverage as we do in lab, and the latter is an experimental API that is still settling. We hope to provide ESM coverage support in the future once one or both of these issues are resolved.

    \n

    In the meantime, we recommend using lab with c8 in order to provide code coverage in ESM projects. Note that c8 does not support granular branch coverage the way we do in lab, for the same reasons listed above. Additionally, lab's coverage inline enabling/disabling and bypass stack are not compatible with c8, which has its own comparable functionality. It's pretty simple to use c8 with lab, though.

    \n

    First install c8:

    \n
    npm install --save-dev c8\n
    \n

    Next update your test command to start with c8. Here's an example in a package.json file switching from lab's coverage to c8's coverage:

    \n
       \"scripts\": {\n-      \"test\": \"lab -a @hapi/code -t 100\"\n+      \"test\": \"c8 --100 lab -a @hapi/code\"\n   },
    \n

    Inline enabling/disabling

    \n

    Sometimes you want to disable code coverage for specific lines, and have the coverage report omit them entirely. To do so, use the $lab:coverage:(off|on)$ comments. For example:

    \n
    // There is no way to cover this in node 0.10\n/* $lab:coverage:off$ */\nif (typeof value === 'symbol') {\n    // do something with value\n}\n/* $lab:coverage:on$ */
    \n

    Coverage bypass stack

    \n

    Disabling code coverage becomes tricky when dealing with machine-generated or machine-altered code. For example, babel can be configured to disable coverage for generated code using the auxiliaryCommentBefore and auxiliaryCommentAfter options. The naïve approach to this uses $lab:coverage:on$ and $lab:coverage:off$, but these directives overwrite any user-specified directives, so that a block where coverage should be disabled may have that coverage unintentionally re-enabled. To work around this issue, lab supports pushing the current code coverage bypass state onto an internal stack using the $lab:coverage:push$ directive, and supports restoring the top of the stack using the $lab:coverage:pop$ directive:

    \n
    // There is no way to cover this in node < 10.0.0\n/* $lab:coverage:off$ */\nconst { types } = Util;\nconst isSet = (types && types.isSet) || (set) => set instanceof Set;\n/* $lab:coverage:on$ */\n\n// When Util is imported using import and babel transpiles to cjs, babel can be\n// configured to use the stack:\n/* $lab:coverage:off$ */\nconst {\n  types\n} =\n/*$lab:coverage:push$/\n/*$lab:coverage:off$*/\n_util\n/*$lab:coverage:pop$/\n.\n/*$lab:coverage:push$/\n/*$lab:coverage:off$*/\ndefault\n/*$lab:coverage:pop$*/\n;\nconst isSet = types && types.isSet || (set) => set instanceof Set;\n/* $lab:coverage:on$ */
    \n

    Semantics:

    \n
      \n
    • \n$lab:coverage:push$ copies the current skip state to the top of the stack, and leaves it as the current state as well
    • \n
    • \n$lab:coverage:pop$ replaces the current skip state with the top of the stack, and removes the top of the stack\n
        \n
      • if the stack is empty, lab will tell you by throwing the error \"unable to pop coverage bypass stack\"\n
      • \n
      \n
    • \n
    \n

    Excluding paths from coverage reporting

    \n

    The --coverage-exclude argument can be repeated multiple times in order to add multiple paths to exclude. By default the node_modules and test directories are excluded. If you want to exclude those as well as a directory named public you can run lab as follows:

    \n
    lab -c --coverage-exclude test --coverage-exclude node_modules --coverage-exclude public
    \n

    Acknowledgements

    \n

    lab initial code borrowed heavily from mocha, including the actual code used to render the coverage report into HTML. lab coverage code was originally adapted from blanket which in turn uses falafel.

    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "25.3.2": { - "menu": "- [Usage](#usage)\n - [Behavior Driven Development](#behavior-driven-development)\n - [Test Driven Development](#test-driven-development)\n - [Best practices](#best-practices)\n - [Timeouts](#timeouts)\n - [Transforms](#transforms)\n - [TypeScript](#typescript)\n- [Command Line](#command-line)\n- [Methods](#methods)\n - [`Lab.script()`](#labscriptoptions)\n - [`script.after()`](#scriptafteroptions-action)\n - [`script.afterEach()`](#scriptaftereach)\n - [`script.before()`](#scriptbefore)\n - [`script.beforeEach()`](#scriptbeforeeach)\n - [`script.describe()`](#scriptdescribetitle-options-content)\n - [`script.experiment()`](#scriptexperimenttitle-options-content)\n - [`script.experiment.only()`](#scriptexperimentonlytitle-options-content)\n - [`script.experiment.skip()`](#scriptexperimentskiptitle-options-content)\n - [`script.it()`](#scriptittitle-options-test)\n - [`script.suite()`](#scriptsuitetitle-options-content)\n - [`script.test()`](#scripttesttitle-options-test)\n - [`script.test.only()`](#scripttestonlytitle-options-test)\n - [`script.test.skip()`](#scripttestskiptitle-options-test)\n - [`Flags`](#flags)\n - [`context`](#context)\n - [`mustCall()`](#mustcallfunc-count)\n - [`note()`](#notenote)\n - [`onCleanup`](#oncleanup)\n - [`onUncaughtException`](#onuncaughtexception)\n - [`onUnhandledRejection`](#onunhandledrejection)\n- [`.labrc.js` File](#labrcjs-file)\n - [Setting precedent](#setting-precedent)\n - [Available settings](#available-settings)\n- [Linting](#linting)\n - [Ignoring files in linting](#ignoring-files-in-linting)\n - [Only run linting](#only-run-linting)\n- [Integration with an assertion library](#integration-with-an-assertion-library)\n- [Debuggers](#debuggers)\n- [Multiple Reporters](#multiple-reporters)\n- [Custom Reporters](#custom-reporters)\n- [Coverage](#coverage)\n - [ESM support](#esm-support)\n - [Inline enabling/disabling](#inline-enablingdisabling)\n - [Coverage bypass stack](#coverage-bypass-stack)\n - [Excluding paths from coverage reporting](#excluding-paths-from-coverage-reporting)\n- [Acknowledgements](#acknowledgements)", - "api": "

    Introduction

    \n

    lab is a simple test utility for Node.js. Unlike other test utilities, lab uses only async/await features and includes everything you should expect from a modern Node.js test utility. Our goal with lab is to keep the execution engine as simple as possible, and not try to build an extensible framework.

    \n

    lab works best with the code assertion library but can be used with any assertion library that throws an error when a condition isn't met.

    \n

    Usage

    \n

    By default, lab loads all the '*.js|cjs|mjs' files inside the local 'test' directory and executes the tests found. To use different directories or files, pass the file or directories as arguments:

    \n
    $ lab unit.js
    \n

    Test files must require the lab module, and export a test script:

    \n
    const Code = require('@hapi/code');\nconst Lab = require('@hapi/lab');\n\nconst { expect } = Code;\nconst { it } = exports.lab = Lab.script();\n\nit('returns true when 1 + 1 equals 2', () => {\n\n    expect(1 + 1).to.equal(2);\n});
    \n

    Or

    \n
    const Code = require('@hapi/code');\nconst Lab = require('@hapi/lab');\n\nconst { expect } = Code;\nconst lab = exports.lab = Lab.script();\n\nlab.test('returns true when 1 + 1 equals 2', () => {\n\n    expect(1 + 1).to.equal(2);\n});
    \n

    If a test is performing an asynchronous operation then it should use the async / await keywords or return a Promise. For example:

    \n
    lab.test('config file has correct value', async () => {\n\n    const file = await fs.readFile('config');\n    expect(file.toString()).to.contain('something');\n});
    \n

    Tests can be organized into experiments:

    \n
    lab.experiment('math', () => {\n\n    lab.test('returns true when 1 + 1 equals 2', () => {\n\n        expect(1 + 1).to.equal(2);\n    });\n});
    \n

    If you need to perform some setup operations before or after executing the tests inside an experiment, the before() and after() methods can be used. To execute code before or after each test in an experiment, use beforeEach() and afterEach().

    \n
    lab.experiment('math', () => {\n\n    lab.before(() => {\n\n        return new Promise((resolve) => {\n\n            // Wait 1 second\n            setTimeout(() => {\n\n                resolve();\n            }, 1000);\n        });\n    });\n\n    lab.beforeEach(() => {\n\n        // Run before every single test\n    });\n\n    lab.test('returns true when 1 + 1 equals 2', () => {\n\n        expect(1 + 1).to.equal(2);\n    });\n});
    \n

    test(), before(), beforeEach(), after() and afterEach() also support returning promises just as tests do:

    \n
    lab.experiment('math', () => {\n\n    lab.before(() => {\n\n        return aFunctionReturningAPromise();\n    });\n\n    lab.test('returns true when 1 + 1 equals 2', () => {\n\n        return aFunctionReturningAPromise()\n            .then((aValue) => {\n\n                expect(aValue).to.equal(expectedValue);\n            });\n    });\n});
    \n

    Both test() and experiment() accept an optional options argument which must be an object with the following optional keys:

    \n
      \n
    • \ntimeout - set a test or experiment specific timeout in milliseconds. Defaults to the global timeout (2000ms or the value of -m).
    • \n
    • \nskip - skip execution. When used on an experiment, all children will be skipped - even if they are marked with only.
    • \n
    • \nonly - marks all other tests or experiments with skip.
    • \n
    \n

    You can also append .only(…) or .skip(…) to test and experiment instead of using options:

    \n
    lab.experiment('with only', () => {\n\n    lab.test.only('only this test will run', () => {\n\n        expect(1 + 1).to.equal(2);\n    });\n\n    lab.test('another test that will not be executed', () => {});\n});
    \n

    Behavior Driven Development

    \n

    To make lab look like BDD:

    \n
    const Code = require('@hapi/code');\nconst Lab = require('@hapi/lab');\n\nconst { expect } = Code;\nconst { after, before, describe, it } = exports.lab = Lab.script();\n\ndescribe('math', () => {\n\n    before(() => {});\n\n    after(() => {});\n\n    it('returns true when 1 + 1 equals 2', () => {\n\n        expect(1 + 1).to.equal(2);\n    });\n});
    \n

    Test Driven Development

    \n

    To make lab look like TDD:

    \n
    const Code = require('@hapi/code');\nconst Lab = require('@hapi/lab');\n\nconst { expect } = Code;\nconst { suite, test } = exports.lab = Lab.script();\n\nsuite('math', () => {\n\n    test('returns true when 1 + 1 equals 2', () => {\n\n        expect(1 + 1).to.equal(2);\n    });\n});
    \n

    Best practices

    \n
      \n
    • Add lab as a dev dependency to your project's package.json along with a test script:
    • \n
    \n
    {\n  \"devDependencies\": {\n    \"@hapi/lab\": \"21.x.x\"\n  },\n  \"scripts\": {\n    \"test\": \"lab -t 100\",\n    \"test-cov-html\": \"lab -r html -o coverage.html\"\n  }\n}
    \n

    Note that npm test will execute lab with the -t 100 option which will require 100% code coverage. Run npm run test-cov-html and check the coverage.html file to figure out where coverage is lacking. When coverage is below the threshold, the CLI will exit with code 1 and will result in an npm Error message.

    \n
      \n
    • Run your tests with
    • \n
    \n
    $ npm test
    \n

    Timeouts

    \n

    before(), after(), beforeEach(), afterEach() accept an optional options argument which must be an object with the following optional keys:

    \n
      \n
    • \ntimeout - set a specific timeout in milliseconds. Disabled by default or the value of -M.
    • \n
    \n
    lab.experiment('math', { timeout: 1000 }, () => {\n\n    lab.before({ timeout: 500 }, () =>  {\n\n        doSomething();\n    });\n\n    lab.test('returns true when 1 + 1 equals 2', () =>  {\n\n        expect(1 + 1).to.equal(2);\n    });\n});
    \n

    Transforms

    \n

    To use source transforms, you must specify a file with the -T command line option that tells Lab how to do the transformation. You can specify many extensions with different transform functions such as .ts or .jsx.

    \n

    TypeScript

    \n

    A TypeScript definition file is included with lab to make it easier to use inside of an existing TypeScript project. To enable running test files written in TypeScript use the --typescript CLI option.

    \n
    import * as Lab from '@hapi/lab';\nimport { expect } from '@hapi/code';\n\nconst lab = Lab.script();\nconst { describe, it, before } = lab;\nexport { lab };\n\n\ndescribe('experiment', () => {\n\n    before(() => {});\n\n    it('verifies 1 equals 1', () => {\n\n        expect(1).to.equal(1);\n    });\n});
    \n

    Then the test can be executed using the following command line:

    \n
    $ lab --typescript
    \n

    If your typescript project has custom paths, Lab can be passed tsconfig-paths/register as a requirement before running and it will resolve based on your path config.

    \n
    $ lab --typescript --require 'tsconfig-paths/register'
    \n

    Command Line

    \n

    lab supports the following command line options:

    \n
      \n
    • \n-a, --assert - name of assert library to use. To disable assertion library set to false.
    • \n
    • \n--bail - terminate the process with a non-zero exit code on the first test failure. Defaults to false.
    • \n
    • \n-c, --coverage - enables code coverage analysis.
    • \n
    • \n--coverage-path - sets code coverage path.
    • \n
    • \n--coverage-exclude - sets code coverage excludes.
    • \n
    • \n--coverage-all - report coverage for all matched files, not just those tested.
    • \n
    • \n--coverage-flat - do not perform a recursive find of files for coverage report. Requires --coverage-all\n
    • \n
    • \n--coverage-pattern - only report coverage for files with the given pattern in the name. Defaults to pattern. Requires --coverage-all\n
    • \n
    • \n--coverage-predicates - sets custom code coverage predicates.
    • \n
    • \n-C, --colors - enables or disables color output. Defaults to console capabilities.
    • \n
    • \n-d, --dry - dry run. Skips all tests. Use with -v to generate a test catalog. Defaults to false.
    • \n
    • \n-e, --environment - value to set the NODE_ENV environment variable to, defaults to 'test'.
    • \n
    • \n-f, --flat - do not perform a recursive load of test files within the test directory.
    • \n
    • \n-g, --grep - only run tests matching the given pattern which is internally compiled to a RegExp.
    • \n
    • \n-h, --help - show command line usage.
    • \n
    • \n-i, --id - only run the test for the given identifier (or identifiers range, e.g. lab -i 1-3,5). Use lab -dv to print all tests and their identifier without running the tests. This is an alias of ids array property in .labrc file.
    • \n
    • \n-I, --ignore - ignore a list of globals for the leak detection (comma separated), this is an alias of globals property in .labrc file. To ignore symbols, pass the symbol's string representation (e.g. Symbol(special)).
    • \n
    • \n--inspect - start lab in debug mode using the V8 Inspector.
    • \n
    • \n--inspect-brk - see --inspect.
    • \n
    • \n-l, --leaks - disables global variable leak detection.
    • \n
    • \n-L, --lint - run linting rules using linter. Disabled by default.
    • \n
    • \n--lint-errors-threshold - maximum absolute amount of linting errors. Defaults to 0.
    • \n
    • \n--lint-warnings-threshold - maximum absolute amount of linting warnings. Defaults to 0.
    • \n
    • \n--lint-fix - apply any fixes from the linter, requires -L or --lint to be enabled. Disabled by default.
    • \n
    • \n--lint-options - specify options to pass to linting program. It must be a string that is JSON.parse(able).
    • \n
    • \n-m, --timeout - individual tests timeout in milliseconds (zero disables timeout). Defaults to 2 seconds.
    • \n
    • \n-M, --context-timeout - default timeouts for before, after, beforeEach and afterEach in milliseconds. Disabled by default.
    • \n
    • \n-o, --output - file to write the report to, otherwise sent to stdout.
    • \n
    • \n-p, --default-plan-threshold - sets the minimum number of assertions a test must run. Overridable with plan.
    • \n
    • \n-P, --pattern - only load files with the given pattern in the name.
    • \n
    • \n-r, --reporter - the reporter used to generate the test results. Defaults to console. Options are:\n
        \n
      • \nconsole - text report.
      • \n
      • \nhtml - HTML test and code coverage report (sets -c).
      • \n
      • \njson - output results in JSON format.
      • \n
      • \njunit - output results in JUnit XML format.
      • \n
      • \ntap - TAP protocol report.
      • \n
      • \nlcov - output to lcov format.
      • \n
      • \nclover - output results in Clover XML format.
      • \n
      • \nMultiple Reporters - See Below
      • \n
      • \nCustom Reporters - See Below
      • \n
      \n
    • \n
    • \n--req, --require - dependencies to require and run before tests run (useful for things like babel, tsconfig-paths, test setup, etc).
    • \n
    • \n-R, --retries - the number of times to retry a failing test that is explicitly marked with retry. Defaults to 5.
    • \n
    • \n--shuffle - randomize the order that test scripts are executed. Will not work with --id.
    • \n
    • \n--seed - use this seed to randomize the order with --shuffle. This is useful to debug order dependent test failures.
    • \n
    • \n-s, --silence - silence test output, defaults to false.
    • \n
    • \n-S, --sourcemaps - enables sourcemap support for stack traces and code coverage, disabled by default.
    • \n
    • \n-t, --threshold - sets the minimum code test coverage percentage to 100%.
    • \n
    • \n--types-test - sets a single TypeScript definition test file (implies -Y). Use when the test directory contains other TypeScript files that should not be loaded for definition testing.
    • \n
    • \n-T, --transform - javascript file that exports an array of objects ie. [ { ext: \".js\", transform: (content, filename) => { ... } } ]. Note that if you use this option with -c (--coverage), then you must generate sourcemaps and pass sourcemaps option to get proper line numbers.
    • \n
    • \n--typescript - enables the built-in TypeScript transpiler which uses the project own's typescript module and tsconfig.json file (or its other formats).
    • \n
    • \n-v, --verbose - verbose test output, defaults to false.
    • \n
    • \n-V, --version - display lab version information.
    • \n
    • \n-Y, --types - validate the module TypeScript types definitions. This is designed exclusively for JavaScript modules that export a TypeScript definition file.
    • \n
    \n

    Methods

    \n

    Lab.script([options])

    \n

    Generates a test script interface which is used to add experiments and tests, where:

    \n
      \n
    • \noptions - an optional object with the following optional keys:\n
        \n
      • \nschedule - if false, an automatic execution of the script is disabled. Automatic execution allows running lab test scripts directly with Node.js without having to use the CLI (e.g. node test/script.js). When using lab programmatically, this behavior is undesired and can be turned off by setting schedule to false. If you need to see the output with schedule disabled you should set output to process.stdout. Defaults to true.
      • \n
      • \ncli - allows setting command line options within the script. Note that the last script file loaded wins and usage of this is recommended only for temporarily changing the execution of tests. This option is useful for code working with an automatic test engine that run tests on commits. Setting this option has no effect when not using the CLI runner. For example setting cli to { ids: [1] } will only execute the first test loaded.
      • \n
      \n
    • \n
    \n

    script.after([options], action)

    \n

    Executes the provided action after the current experiment block is finished where:

    \n
      \n
    • \noptions - optional flags as describe in script.test().
    • \n
    • \naction - a sync or async function using the signature function(flags) where:\n
        \n
      • \nflags - see Flags\n
      • \n
      \n
    • \n
    \n

    script.afterEach()

    \n

    Executes the provided action after each test is executed in the current experiment block where:

    \n
      \n
    • \noptions - optional flags as describe in script.test().
    • \n
    • \naction - a sync or async function using the signature function(flags) where:\n
        \n
      • \nflags - see Flags\n
      • \n
      \n
    • \n
    \n

    script.before()

    \n

    Executes the provided action before the current experiment block is started where:

    \n
      \n
    • \noptions - optional flags as describe in script.test().
    • \n
    • \naction - a sync or async function using the signature function(flags) where:\n
        \n
      • \nflags - see Flags\n
      • \n
      \n
    • \n
    \n

    script.beforeEach()

    \n

    Executes the provided action before each test is executed in the current experiment block where:

    \n
      \n
    • \noptions - optional flags as describe in script.test().
    • \n
    • \naction - a sync or async function using the signature function(flags) where:\n
        \n
      • \nflags - see Flags\n
      • \n
      \n
    • \n
    \n

    script.describe(title, [options], content)

    \n

    Same as script.experiment().

    \n

    script.experiment(title, [options], content)

    \n

    Sets up an experiment (a group of tests) where:

    \n
      \n
    • \ntitle - the experiment description.
    • \n
    • \noptions - optional settings:\n
        \n
      • \nskip - if true, sets the entire experiment content to be skipped during execution. Defaults to false.
      • \n
      • \nonly - if true, sets all other experiments to skip. Default to false.
      • \n
      • \ntimeout - overrides the default test timeout for tests and other timed operations. Defaults to 2000.
      • \n
      \n
    • \n
    • \ncontent - a function with signature function() which can setup other experiments or tests.
    • \n
    \n

    script.experiment.only(title, [options], content)

    \n

    Same as script.experiment() with the only option set to true.

    \n

    script.experiment.skip(title, [options], content)

    \n

    Same as script.experiment() with the skip option set to true.

    \n

    script.it(title, [options], test)

    \n

    Same as script.test().

    \n

    script.suite(title, [options], content)

    \n

    Same as script.experiment().

    \n

    script.test(title, [options], test)

    \n

    Sets up a test where:

    \n
      \n
    • \ntitle - the test description.
    • \n
    • \noptions - optional settings:\n
        \n
      • \nskip - if true, sets the entire experiment content to be skipped during execution. Defaults to false.
      • \n
      • \nonly - if true, sets all other experiments to skip. Default to false.
      • \n
      • \ntimeout - overrides the default test timeout for tests and other timed operations in milliseconds. Defaults to 2000.
      • \n
      • \nplan - the expected number of assertions the test must execute. This setting should only be used with an assertion library that supports a count() function, like code.
      • \n
      • \nretry - when true or set to a number greater than 0, if the test fails it will be retried retries (defaults to 5) number of times until it passes.
      • \n
      \n
    • \n
    • \ntest - a function with signature function(flags) where:\n
        \n
      • the function can throw if the test failed.
      • \n
      • the function can return a Promise which either resolves (success) or rejects (fails).
      • \n
      • all other return value is ignored.
      • \n
      • \nflags - a set of test utilities described in Flags.
      • \n
      \n
    • \n
    \n
    lab.experiment('my plan', () => {\n\n    lab.test('only a single assertion executes', { plan: 1 }, () => {\n\n        expect(1 + 1).to.equal(2);\n    });\n});
    \n

    script.test.only(title, [options], test)

    \n

    Same as calling script.test() with only option set to true.

    \n

    script.test.skip(title, [options], test)

    \n

    Same as calling script.test() with skip option set to true.

    \n

    Flags

    \n

    The test function is passed a flags object that can be used to create notes or set a function to execute for cleanup operations after the test is complete.

    \n

    context

    \n

    An object that is passed to before and after functions in addition to tests themselves. context is used to set properties inside the before function that can be used by a test function later. It is meant to reduce module level variables that are set by the before / beforeEach functions. The context object is shallow cloned when passed to tests, as well as to child experiments, allowing you to modify it for each experiment individually without conflict through the use of before, beforeEach, after and afterEach.

    \n
    lab.experiment('my experiment', () => {\n\n  lab.before(({ context }) => {\n\n      context.foo = 'bar';\n  })\n\n  lab.test('contains context', ({ context }) => {\n\n      expect(context.foo).to.equal('bar');\n  });\n\n  lab.experiment('a nested experiment', () => {\n\n    lab.before(({ context }) => {\n\n      context.foo = 'baz';\n    });\n\n    lab.test('has the correct context', ({ context }) => {\n\n      expect(context.foo).to.equal('baz');\n      // since this is a shallow clone, changes will not be carried to\n      // future tests or experiments\n      context.foo = 'fizzbuzz';\n    });\n\n    lab.test('receives a clean context', ({ context }) => {\n\n      expect(context.foo).to.equal('baz');\n    });\n  });\n\n  lab.experiment('another nested experiment', () => {\n\n    lab.test('maintains the original context', ({ context }) => {\n\n      expect(context.foo).to.equal('bar');\n    });\n  });\n});
    \n

    mustCall(func, count)

    \n

    Sets a requirement that a function must be called a certain number of times where:

    \n
      \n
    • \nfunc - the function to be called.
    • \n
    • \ncount - the number of required invocations.
    • \n
    \n

    Returns a wrapped copy of the function. After the test is complete, each mustCall assertion will be checked and the test will fail if any function was called the incorrect number of times.

    \n

    Below is an example demonstrating how to use mustCall to verify that fn is called exactly two times.

    \n
    lab.test('fn must be called twice', async (flags) => {\n\n    const fn = () => {};\n    const wrapped = flags.mustCall(fn, 2);\n    wrapped();\n\n    await doSomeAsyncOperation();\n    wrapped();\n});
    \n

    note(note)

    \n

    Adds notes to the test log where:

    \n
      \n
    • \nnote - a string to be included in the console reporter at the end of the output.
    • \n
    \n

    For example, if you would like to add a note with the current time, your test case may look like the following:

    \n
    lab.test('attaches notes', (flags) => {\n\n    expect(1 + 1).to.equal(2);\n    flags.note(`The current time is ${Date.now()}`);\n});
    \n

    Multiple notes can be appended for the same test case by simply calling note() repeatedly.

    \n

    onCleanup

    \n

    A property that can be assigned a cleanup function registered at runtime to be executed after the test completes. The cleanup function will execute even in the event of a timeout or error. Note that the cleanup function will be executed as-is without any timers. The function assigned to onCleanup can return a Promise that will be evaluated.

    \n
    lab.test('cleanups after test', (flags) => {\n\n    flags.onCleanup = () => {\n\n        cleanup_logic();\n    };\n\n    expect(1 + 1).to.equal(2);\n});
    \n

    onUncaughtException

    \n

    A property that can be assigned an override for global exception handling. This can be used to test the code that is explicitly meant to result in uncaught exceptions.

    \n
    lab.test('leaves an uncaught rejection', (flags) => {\n\n    return new Promise((resolve) => {\n\n        flags.onUncaughtException = (err) => {\n\n            expect(err).to.be.an.error('I want this exception to remain uncaught in production');\n            resolve(); // finish the test\n        };\n\n        // sample production code\n        setTimeout(() => {\n\n            throw new Error('I want this exception to remain uncaught in production');\n        });\n    });\n});
    \n

    onUnhandledRejection

    \n

    A property that can be assigned an override function for global rejection handling. This can be used to test the code that is explicitly meant to result in unhandled rejections.

    \n
    lab.test('leaves an unhandled rejection', (flags) => {\n\n    return new Promise((resolve) => {\n\n        flags.onUnhandledRejection = (err) => {\n\n            expect(err).to.be.an.error('I want this rejection to remain unhandled in production');\n            resolve(); // finish the test\n        };\n\n        // sample production code\n        setTimeout(() => {\n\n            Promise.reject(new Error('I want this rejection to remain unhandled in production'));\n        });\n    });\n});
    \n

    \n.labrc.js File

    \n

    lab supports a .labrc.js configuration file for centralizing lab settings. The .labrc.js file can be located in the current working directory, any directory that is the parent of the current working directory, or in the user's home directory. The .labrc.js file needs to be able to be required by Node.js. Therefore, either format it as a JSON file or with a module.exports that exports an object with the keys that are the settings.

    \n

    Below is an example of a .labrc.js file to enable linting and test coverage checking:

    \n
    module.exports = {\n    coverage: true,\n    threshold: 90,\n    lint: true\n};
    \n

    Setting precedent

    \n

    The .labrc.js file will override the lab default settings. Any options passed to the lab runner will override the settings found in .labrc.js. For example, assume you have the following .labrc.js file:

    \n
    module.exports = {\n    coverage: true,\n    threshold: 100\n};
    \n

    If you need to reduce the coverage threshold for a single run, you can execute lab as follows:

    \n
    lab -t 80
    \n

    Available settings

    \n

    The .labrc.js file supports configuration keys that are named with the long name of the command line settings. Therefore, if you need to specify an assert library, you would export a key named \"assert\" with the desired value.

    \n

    In addition, you can use the paths parameter to override the default test directory (i.e. ./test):

    \n
    module.exports = {\n    paths: ['test/lab'],\n};
    \n

    As stated at the beginning of the document, --ignore parameter is an alias for globals option in the .labrc file. Therefore if you wish to ignore specific files you'll need to append a globals setting, not an ignore one, as stated on #641.

    \n

    Linting

    \n

    lab uses a shareable eslint plugin containing a recommended config and several hapi specific linting rules. If you want to extend the default linter you must:

    \n
      \n
    1. \n

      Add @hapi/eslint-plugin as a dependency in your package.json.

      \n
    2. \n
    3. \n

      In your project's eslint configuration, add \"extends\": \"plugin:@hapi/recommended\".

      \n
    4. \n
    \n

    Your project's eslint configuration will now extend the default lab configuration.

    \n

    Ignoring files in linting

    \n

    Since eslint is used to lint, you can create an .eslintignore containing paths to be ignored:

    \n
    node_modules/*\n**/vendor/*.js\n
    \n

    Only run linting

    \n

    In order to run linting and not to execute tests you can combine the dry run\nflag with the lint flag.

    \n
    lab -dL\n
    \n

    Integration with an assertion library

    \n

    Using the --assert argument allows you to integrate Lab with your favorite assertion library. Aside from --assert from the CLI you can change the assert option when executing report. Whatever assertion library you specify is imported and assigned to the Lab.assertions property. Here is an example using lab --assert @hapi/code:

    \n
    const lab = exports.lab = Lab.script();\nconst { describe, it } = lab;\n\n// Testing shortcuts\nconst { expect, fail } = require('@hapi/code');\n\ndescribe('expectation', () => {\n\n    it('should be able to expect', () => {\n\n        expect(true).to.be.true();\n    });\n\n    it('should be able to fail (This test should fail)', () => {\n\n        fail('Should fail');\n    });\n});
    \n
    $ lab --assert @hapi/code\n
    \n

    If you use the Code assertion library Lab will let you know if you have any missing assertions. An example of this is:

    \n
    describe('expectation', () => {\n\n    it('Test should pass but get marked as having a missing expectation', () => {\n\n        // Invalid and missing assertion - false is a method, not a property!\n        // This test will pass.\n        Lab.expect(true).to.be.false;\n    });\n});
    \n

    This is an invalid test but it will pass as the .false assertion was not actually called. Lab will report the number of incomplete assertions, their location in your code and return a failure of the tests.

    \n

    Similarly, if you use an assertion library, lab will be able to report the verbosity of your tests. This is a measure of the number of assertions divided by the number of tests. The value will be output when using the console reporter and can be helpful in determining if too many or too few assertions exist in each test. What is too many or too few assertions is entirely up to you.

    \n

    Debuggers

    \n

    lab can be started with the option --inspect which will run it with the V8 Inspector.

    \n

    This debugger can be accessed using the URL that is printed in the console, or used in association with a few Chrome extensions (Node.js V8 Inspector, NIM, etc).

    \n

    As you may know, if your tests are associated with the command npm test, you can already run npm test -- --inspect to run it with the inspector and avoid creating another command. If you want to listen on a specific port for the inspector, pass --inspect={port}.

    \n

    lab also has automatic support for the WebStorm debugger, just start a normal debugging session on your npm test script.

    \n

    Multiple Reporters

    \n

    Multiple reporters can be specified by providing multiple reporter options.

    \n
    $ lab -r console -r html
    \n

    If any output -o is provided, they must match the same number of provided reporter options. The reporters would be paired with an output based on\nthe order in which they were supplied. When specifying multiple outputs, use stdout to send a particular reporter to stdout.

    \n
    $ lab -r console -o stdout -r html -o coverage.html -r lcov -o lcov.info -r json -o data.json
    \n

    In a .labrc.js file, multiple reporters and their associated output paths would be represented as follows:

    \n
    module.exports = {\n    reporter: ['console', 'html', 'lcov', 'json'],\n    output: ['stdout', 'coverage.html', 'lcov.info', 'data.json']\n};
    \n

    Multiple reporters of the same kind are also supported.

    \n
    $ lab -r console -o stdout -r console -o console.log
    \n

    Custom Reporters

    \n

    If the value passed for reporter isn't included with Lab, it is loaded from the filesystem. If the string starts with a period ('./custom-reporter'), it will be loaded relative to the current working directory. If it doesn't start with a period ('custom-reporter'), it will be loaded from the node_modules directory, just like any module installed using npm install.

    \n

    Reporters must be a class with the following methods: start, test and end. options are passed to the class constructor upon initialization.

    \n

    See the json reporter for a good starting point.

    \n

    Coverage

    \n

    ESM support

    \n

    Lab does not support code coverage for ES modules. There are two reasons for this: in order to implement this we would either use V8's builtin coverage or an ESM Loader. Unfortunately the former doesn't support granular branch coverage as we do in lab, and the latter is an experimental API that is still settling. We hope to provide ESM coverage support in the future once one or both of these issues are resolved.

    \n

    In the meantime, we recommend using lab with c8 in order to provide code coverage in ESM projects. Note that c8 does not support granular branch coverage the way we do in lab, for the same reasons listed above. Additionally, lab's coverage inline enabling/disabling and bypass stack are not compatible with c8, which has its own comparable functionality. It's pretty simple to use c8 with lab, though.

    \n

    First install c8:

    \n
    npm install --save-dev c8\n
    \n

    Next update your test command to start with c8. Here's an example in a package.json file switching from lab's coverage to c8's coverage:

    \n
       \"scripts\": {\n-      \"test\": \"lab -a @hapi/code -t 100\"\n+      \"test\": \"c8 --100 lab -a @hapi/code\"\n   },
    \n

    Inline enabling/disabling

    \n

    Sometimes you want to disable code coverage for specific lines, and have the coverage report omit them entirely. To do so, use the $lab:coverage:(off|on)$ comments. For example:

    \n
    // There is no way to cover this in node 0.10\n/* $lab:coverage:off$ */\nif (typeof value === 'symbol') {\n    // do something with value\n}\n/* $lab:coverage:on$ */
    \n

    Coverage bypass stack

    \n

    Disabling code coverage becomes tricky when dealing with machine-generated or machine-altered code. For example, babel can be configured to disable coverage for generated code using the auxiliaryCommentBefore and auxiliaryCommentAfter options. The naïve approach to this uses $lab:coverage:on$ and $lab:coverage:off$, but these directives overwrite any user-specified directives, so that a block where coverage should be disabled may have that coverage unintentionally re-enabled. To work around this issue, lab supports pushing the current code coverage bypass state onto an internal stack using the $lab:coverage:push$ directive, and supports restoring the top of the stack using the $lab:coverage:pop$ directive:

    \n
    // There is no way to cover this in node < 10.0.0\n/* $lab:coverage:off$ */\nconst { types } = Util;\nconst isSet = (types && types.isSet) || (set) => set instanceof Set;\n/* $lab:coverage:on$ */\n\n// When Util is imported using import and babel transpiles to cjs, babel can be\n// configured to use the stack:\n/* $lab:coverage:off$ */\nconst {\n  types\n} =\n/*$lab:coverage:push$/\n/*$lab:coverage:off$*/\n_util\n/*$lab:coverage:pop$/\n.\n/*$lab:coverage:push$/\n/*$lab:coverage:off$*/\ndefault\n/*$lab:coverage:pop$*/\n;\nconst isSet = types && types.isSet || (set) => set instanceof Set;\n/* $lab:coverage:on$ */
    \n

    Semantics:

    \n
      \n
    • \n$lab:coverage:push$ copies the current skip state to the top of the stack, and leaves it as the current state as well
    • \n
    • \n$lab:coverage:pop$ replaces the current skip state with the top of the stack, and removes the top of the stack\n
        \n
      • if the stack is empty, lab will tell you by throwing the error \"unable to pop coverage bypass stack\"\n
      • \n
      \n
    • \n
    \n

    Excluding paths from coverage reporting

    \n

    The --coverage-exclude argument can be repeated multiple times in order to add multiple paths to exclude. By default the node_modules and test directories are excluded. If you want to exclude those as well as a directory named public you can run lab as follows:

    \n
    lab -c --coverage-exclude test --coverage-exclude node_modules --coverage-exclude public
    \n

    Acknowledgements

    \n

    lab initial code borrowed heavily from mocha, including the actual code used to render the coverage report into HTML. lab coverage code was originally adapted from blanket which in turn uses falafel.

    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Node test utility.", - "forks": 176, - "stars": 739, - "date": "2024-10-23T08:33:03Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/lab" - }, - "log": { - "name": "log", - "versions": [ - { - "name": "2.0.1", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "2.0.1" - ], - "api": true, - "isPlugin": true, - "2.0.1": { - "menu": " - [Ideas](#ideas)\n- [Log level](#-log-level)\n- [Registration](#-registration)\n - [`additionalFields`](#-additionalfields)\n - [`defaultLevel`](#-defaultlevel)\n - [`events`](#-events)\n - [`ignoreChannels`](#-ignorechannels)\n - [`ignorePaths`](#-ignorepaths)\n - [`ignoreTags`](#-ignoretags)\n - [`level`](#-level)\n - [`logger`](#-logger)\n - [`logLevelMap`](#-loglevelmap)\n - [`onError`](#-onerror)\n- [Stdlogger](#-stdlogger)\n- [Pinologger](#-pinologger)\n- [`server.plugins.log.setLevel()`](#-serverpluginslogsetlevellevel)", - "api": "

    WIP

    \n

    This API is still a WIP. Feedbacks are welcome.

    \n

    Ideas

    \n

    This section will serve as a gathering for all ideas we want to implement or that are open to discussion in this module.

    \n
      \n
    • Dual logging system:\n
        \n
      • A highly performant core integrated with hapi's core:\n
          \n
        • Super fast text streams (inspired from pino)
        • \n
        • Replace the current server.log() and request.log(), maybe by something like server.log.critical(), request.log.debug().
        • \n
        • Should we allow for custom log levels?
        • \n
        • Allow data to be bind to a logger to create a \"child logger\" rather than having to do it by hand every time.
        • \n
        • Allow for default log level and minimum log level threshold.
        • \n
        • A documented log format that would enable logging to stdout / stderr from hapi and piping them to another process for more in depth handling (reformating, shipping, etc.).
        • \n
        \n
      • \n
      • Podium API to subscribe to specific events and a built-in way to pipe everything to stdout.
      • \n
      \n
    • \n
    • Plugins could add support for writing to files with additional features like files rotation, chunking or write to HTTP targets i.e loggly.
    • \n
    • Rework the current server.events and request.events channels to make them more intuitive :\n
        \n
      • Remove the ambiguity with the request event where it makes you think that an event will be triggered when a new request is received whereas it can be done with the onRequest extension point instead.
      • \n
      • Remove the inconsistency between server.log() which emits log events and request.log() which emits request events.
      • \n
      \n
    • \n
    • Keep emitting events when logging (to enable side usage like crash notifications ala Sentry).
    • \n
    • Provide first class API to serialize problematic Node/hapi objects such as the request object using either first class citizen objects or methods like toJSON() :\n
        \n
      • Allow the user to provide paths to data or a redaction function for sensitive information.
      • \n
      \n
    • \n
    • Built in support for ignoring events based on path or tags i.e /health.
    • \n
    \n

    \n Log level

    \n

    This module provides different log levels:

    \n
      \n
    • \nemergency (0): System is unusable
    • \n
    • \nalert (1): Should be corrected immediately
    • \n
    • \ncritical (2): Critical conditions
    • \n
    • \nerror (3): Error conditions
    • \n
    • \nwarning (4): May indicate that an error will occur if action is not taken
    • \n
    • \nnotice (5): Events that are unusual, but not error conditions
    • \n
    • \ninfo (6): Normal operational messages that require no action
    • \n
    • \ndebug (7): Information useful to developers for debugging the application
    • \n
    \n

    \n Registration

    \n

    This plugin accepts several options:

    \n

    \n additionalFields\n

    \n

    Default value: { hostname, pid, node }.

    \n

    A free form object that will be passed to the log function for every elements in events.

    \n

    \n defaultLevel\n

    \n

    Default value: 'info'.

    \n

    A log level string that will be used as the level for the automatic logging performed on events.

    \n

    \n events\n

    \n

    Default value: ['log', 'onRequest', 'request', 'response', 'start', 'stop'].

    \n

    An array of strings where each value represents the name of an event dispatched by hapi or a request lifecycle method. This plugin will log information for all events/lifecycle in this array. The available values are:

    \n
      \n
    • \nlog event
    • \n
    • \nonRequest lifecycle
    • \n
    • \nrequest event
    • \n
    • \nresponse event
    • \n
    • \nstart event
    • \n
    • \nstop event\n
        \n
      • The logger will automatically be closed upon stop event reception whether it is present in the events array or not.
      • \n
      \n
    • \n
    \n

    The automatic logging behavior on log and request event is handled differently from the others. If the received event object contains tags, they will be tested against the log levels. If there are matches and a matched log level has a more severe log level than the default level it will be used instead. When multiple tags match, the one with the most severe log level will be used. If there are no matches, the default level will be used.

    \n

    \n ignoreChannels\n

    \n

    Default value: [].

    \n

    An array of strings whose values are event channels to exclude from logging. These channels will be matched against the channel of the received event object from:

    \n
      \n
    • \nlog event
    • \n
    • \nrequest event
    • \n
    \n

    \n ignorePaths\n

    \n

    Default value: [].

    \n

    An array of strings whose values are route paths to exclude from logging. This option is used only for:

    \n
      \n
    • \nrequest event
    • \n
    • \nresponse event
    • \n
    • \nonRequest lifecycle
    • \n
    \n

    \n ignoreTags\n

    \n

    Default value: [].

    \n

    An array of strings whose values are tags to exclude from logging. Event tags and routes tags will be matched against this option. No log will be performed as long as at least one tag matches from this option. Tags from log and request events will be checked. Route tags filtering will be performed for requests on request, response event and onRequest lifecycle.

    \n

    \n level\n

    \n

    Default value: 'info'.

    \n

    A log level string used to determine the maximum log level allowed, meaning the log level with the highest numerical value allowed. For example let's say you defined this option as level: 'notice', whose numerical value is 5. Afterwards a log event is intercepted by this plugin whose tags contain 'debug' matching with the 8th log level (debug (7)). This event will not be logged since its numerical value is higher than the numerical value of this option.

    \n

    \n logger\n

    \n

    Default value: Stdlogger.

    \n

    An object with several methods to setup and log information:

    \n
      \n
    • \nasync logger.connect() (optional): this method is called during the onPreStart lifecycle.
    • \n
    • \nlogger.close() (optional): this method is called upon reception of the server stop event. It should execute cleanup logic i.e closing files, closing remote communication.
    • \n
    • \nlogger.on(eventName, callback): this method is used to listen to events on the logger object. It is used to listen to an error event when the onError option is provided. It accepts two arguments:\n
        \n
      • \neventName: a string for the event name.
      • \n
      • \ncallback: a function that should be called when an event matching the event name is dispatched.
      • \n
      \n
    • \n
    • \nlogger[level](label, data, additionalFields): methods for every log level in the events option i.e logger.notice() or logger.critical(). These methods will be called with three arguments:\n
        \n
      • \nmessage: the message to log. Can be a string or an object that can be stringified.
      • \n
      • \ndata: an object containing data about the event, undefined when no data are sent.
      • \n
      • \nadditionalFields: the object passed to the additionalFields option.
      • \n
      \n
    • \n
    \n

    \n logLevelMap\n

    \n

    Default value: {}.

    \n

    An object that will be used to create a mapping between different names and the log levels we use. We use a default log level map:

    \n
    {\n  \"emerg\": \"emergency\",\n  \"emergency\": \"emergency\",\n  \"alert\": \"alert\",\n  \"crit\": \"critical\",\n  \"critical\": \"critical\",\n  \"err\": \"error\",\n  \"error\": \"error\",\n  \"warn\": \"warning\",\n  \"warning\": \"warning\",\n  \"notice\": \"notice\",\n  \"info\": \"info\",\n  \"log\": \"info\",\n  \"debug\": \"debug\"\n}
    \n

    The log level map provided in this option takes precedence and is merged over the default one. This allows you to unset values from the default map by setting the value to either undefined or null.

    \n

    It is used only when reading the tags from the request and log events to determine the appropriate log level.

    \n

    \n onError\n

    \n

    Default value: undefined.

    \n

    A function that, if provided, is passed as the callback to the error event of the logger.on() method.

    \n

    \n Stdlogger

    \n

    log exports Stdlogger, which can be constructed and passed as the logger option to log.\nThe constructor takes the following arguments:

    \n

    new Log.StdLogger(stdout, stderr);

    \n

    \n Pinologger

    \n

    log exports Pinologger, which can be constructed and passed as the logger option to log.\nThe output from a hapi server using the Pinologger can be piped to pino-pretty or other pino compatible modules. The constructor takes the following arguments:

    \n

    new Log.Pinologger(stdout);

    \n

    \n server.plugins.log.setLevel(level)\n

    \n

    The log level can be changed after the plugin is registered by using the\nserver.plugins.log.setLevel(level) function. Only valid levels are accepted.\nAfter the level is changed only log events that are below the threshold will be\nlogged.

    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Logging for hapi framework.", - "forks": 5, - "stars": 6, - "date": "2024-10-23T15:40:54Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/log" - }, - "mimos": { - "name": "mimos", - "versions": [ - { - "name": "7.0.1", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "6.0.0", - "branch": "v6", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "7.0.1", - "6.0.0" - ], - "api": true, - "isPlugin": false, - "7.0.1": { - "menu": "- [`new Mimos.Mimos()`](#new-mimosmimosoptions)\n- [`mimos.path()`](#mimospathpath)\n- [`mimos.type()`](#mimostypetype)\n- [Override Example](#override-example)", - "api": "

    Mimos is a convenience class for retrieving mime information objects.

    \n

    new Mimos.Mimos([options])

    \n

    Creates a new Mimos object where:

    \n
      \n
    • \n[options] - an option object the following keys\n
        \n
      • \n[override] - an object hash that is merged into the built in mime information specified here. Each key value pair represents a single mime object. Each override value should follow this schema:\n
          \n
        • \nkey - the key is the lower-cased correct mime-type. (Ex. \"application/javascript\").
        • \n
        • \nvalue - the value should be an object following the specifications outlined here. Additional values include:\n
            \n
          • \ntype - specify the type value of result objects, defaults to key. See the example below for more clarification.
          • \n
          • \npredicate - method with signature function(mime) when this mime type is found in the database, this function will run. This allows you make customizations to mime based on developer criteria.
          • \n
          \n
        • \n
        \n
      • \n
      \n
    • \n
    \n

    mimos.path(path)

    \n

    Lookup file extension from path and return mime object, or an empty object literal {} if not found, where:

    \n
      \n
    • \npath path to file including the file extension. Uses the extension values of the mime objects for lookup.
    • \n
    \n
    const mimos = new Mimos.Mimos();\nconst mime = mimos.path('/static/public/app.js');\n// mime\n/*\n{\n  source: 'iana',\n  charset: 'UTF-8',\n  compressible: true,\n  extensions: [ 'js' ],\n  type: 'application/javascript'\n}\n*/
    \n

    mimos.type(type)

    \n

    Returns mime object where:

    \n
      \n
    • \ntype the content-type to find mime information about. Uses the type values of the mime objects for lookup.
    • \n
    \n
    const mimos = new Mimos.Mimos();\nconst mime = mimos.type('text/plain');\n// mime\n/*\n{\n  source: 'iana',\n  compressible: true,\n  extensions: ['txt', 'text', 'conf', 'def', 'list', 'log', 'in', 'ini'],\n  type: 'text/plain'\n}\n*/
    \n

    Override Example

    \n

    In certain situations, it can be helpful to override the built in mime type information. The optional argument to the Mimos constructor is used to override and add mime information. Below is an example to help understand how this works.

    \n
    const options = {\n    override: {\n        'node/module': {\n            source: 'iana',\n            compressible: true,\n            extensions: ['node', 'module', 'npm'],\n            type: 'node/module'\n        },\n        'application/javascript': {\n            source: 'iana',\n            charset: 'UTF-8',\n            compressible: true,\n            extensions: ['js', 'javascript'],\n            type: 'text/javascript'\n        },\n        'text/html': {\n            predicate: function(mime) {\n                if (someCondition) {\n                    mime.foo = 'test';\n                }\n                else {\n                    mime.foo = 'bar';\n                }\n                return mime;\n            }\n        }\n    }\n}\n\nconst mimos = new Mimos.Mimos(options);\nconsole.dir(mimos.path('./node_modules/mimos.module'));\n/*\n{\n  source: 'iana',\n  compressible: true,\n  extensions: ['node', 'module', 'npm'],\n  type: 'node/module'\n}\n*/\nconsole.dir(mimos.type('application/javascript'));\n/*\nNote: even though we asked for type 'application/javascript', the type value is 'text/javascript' because of the override. Always use the proper content-type for retrieval.\n{\n  source: 'iana',\n  charset: 'UTF-8',\n  compressible: true,\n  extensions: ['js', 'javascript'],\n  type: 'text/javascript'\n}\n*/\nconsole.dir(mimos.type('text/html'));\n/*\nsomeCondition is true:\n{\n  source: 'iana',\n  compressible: true,\n  extensions: ['html','htm'],\n  type: 'test/html',\n  foo: 'test'\n}\n\nsomeCondition is false:\n{\n  source: 'iana',\n  compressible: true,\n  extensions: ['html','htm'],\n  type: 'test/html',\n  foo: 'bar'\n}\n*/
    \n", - "intro": "", - "example": "", - "usage": "## Usage\n", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "6.0.0": { - "menu": "- [Usage](#usage)\n - [`new Mimos.Mimos()`](#new-mimosmimosoptions)\n - [`mimos.path()`](#mimospathpath)\n - [`mimos.type()`](#mimostypetype)\n - [Override Example](#override-example)", - "api": "

    Mimos is a convenience class for retrieving mime information objects.

    \n

    Usage

    \n

    new Mimos.Mimos([options])

    \n

    Creates a new Mimos object where:

    \n
      \n
    • \n[options] - an option object the following keys\n
        \n
      • \n[override] - an object hash that is merged into the built in mime information specified here. Each key value pair represents a single mime object. Each override value should follow this schema:\n
          \n
        • \nkey - the key is the lower-cased correct mime-type. (Ex. \"application/javascript\").
        • \n
        • \nvalue - the value should be an object following the specifications outlined here. Additional values include:\n
            \n
          • \ntype - specify the type value of result objects, defaults to key. See the example below for more clarification.
          • \n
          • \npredicate - method with signature function(mime) when this mime type is found in the database, this function will run. This allows you make customizations to mime based on developer criteria.
          • \n
          \n
        • \n
        \n
      • \n
      \n
    • \n
    \n

    mimos.path(path)

    \n

    Lookup file extension from path and return mime object, or an empty object literal {} if not found, where:

    \n
      \n
    • \npath path to file including the file extension. Uses the extension values of the mime objects for lookup.
    • \n
    \n
    const mimos = new Mimos.Mimos();\nconst mime = mimos.path('/static/public/app.js');\n// mime\n/*\n{\n  source: 'iana',\n  charset: 'UTF-8',\n  compressible: true,\n  extensions: [ 'js' ],\n  type: 'application/javascript'\n}\n*/
    \n

    mimos.type(type)

    \n

    Returns mime object where:

    \n
      \n
    • \ntype the content-type to find mime information about. Uses the type values of the mime objects for lookup.
    • \n
    \n
    const mimos = new Mimos.Mimos();\nconst mime = mimos.type('text/plain');\n// mime\n/*\n{\n  source: 'iana',\n  compressible: true,\n  extensions: ['txt', 'text', 'conf', 'def', 'list', 'log', 'in', 'ini'],\n  type: 'text/plain'\n}\n*/
    \n

    Override Example

    \n

    In certain situations, it can be helpful to override the built in mime type information. The optional argument to the Mimos constructor is used to override and add mime information. Below is an example to help understand how this works.

    \n
    const options = {\n    override: {\n        'node/module': {\n            source: 'iana',\n            compressible: true,\n            extensions: ['node', 'module', 'npm'],\n            type: 'node/module'\n        },\n        'application/javascript': {\n            source: 'iana',\n            charset: 'UTF-8',\n            compressible: true,\n            extensions: ['js', 'javascript'],\n            type: 'text/javascript'\n        },\n        'text/html': {\n            predicate: function(mime) {\n                if (someCondition) {\n                    mime.foo = 'test';\n                }\n                else {\n                    mime.foo = 'bar';\n                }\n                return mime;\n            }\n        }\n    }\n}\n\nconst mimos = new Mimos.Mimos(options);\nconsole.dir(mimos.path('./node_modules/mimos.module'));\n/*\n{\n  source: 'iana',\n  compressible: true,\n  extensions: ['node', 'module', 'npm'],\n  type: 'node/module'\n}\n*/\nconsole.dir(mimos.type('application/javascript'));\n/*\nNote: even though we asked for type 'application/javascript', the type value is 'text/javascript' because of the override. Always use the proper content-type for retrieval.\n{\n  source: 'iana',\n  charset: 'UTF-8',\n  compressible: true,\n  extensions: ['js', 'javascript'],\n  type: 'text/javascript'\n}\n*/\nconsole.dir(mimos.type('text/html'));\n/*\nsomeCondition is true:\n{\n  source: 'iana',\n  compressible: true,\n  extensions: ['html','htm'],\n  type: 'test/html',\n  foo: 'test'\n}\n\nsomeCondition is false:\n{\n  source: 'iana',\n  compressible: true,\n  extensions: ['html','htm'],\n  type: 'test/html',\n  foo: 'bar'\n}\n*/
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Mime database interface.", - "forks": 12, - "stars": 19, - "date": "2024-10-23T21:34:46Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/mimos" - }, - "nes": { - "name": "nes", - "versions": [ - { - "name": "14.0.0", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "14.0.0" - ], - "api": true, - "isPlugin": true, - "14.0.0": { - "menu": "- [Protocol](#protocol)\n- [Examples](#examples)\n - [Route invocation](#route-invocation)\n - [Server](#server)\n - [Client](#client)\n - [Subscriptions](#subscriptions)\n - [Server](#server-1)\n - [Client](#client-1)\n - [Broadcast](#broadcast)\n - [Server](#server-2)\n - [Client](#client-2)\n - [Route authentication](#route-authentication)\n - [Server](#server-3)\n - [Client](#client-3)\n - [Subscription filter](#subscription-filter)\n - [Server](#server-4)\n - [Client](#client-4)\n - [Browser Client](#browser-client)\n- [Registration](#registration)\n- [Server](#server-5)\n - [`await server.broadcast()`](#await-serverbroadcastmessage-options)\n - [`server.subscription()`](#serversubscriptionpath-options)\n - [`await server.publish()`](#await-serverpublishpath-message-options)\n - [`await server.eachSocket()`](#await-servereachsocketeach-options)\n- [Socket](#socket)\n - [`socket.id`](#socketid)\n - [`socket.app`](#socketapp)\n - [`socket.auth`](#socketauth)\n - [`socket.server`](#socketserver)\n - [`socket.connection`](#socketconnection)\n - [`socket.disconnect()`](#socketdisconnect)\n - [`socket.isOpen()`](#socketisopen)\n - [`await socket.send()`](#await-socketsendmessage)\n - [`await socket.publish()`](#await-socketpublishpath-message)\n - [`await socket.revoke()`](#await-socketrevokepath-message-options)\n- [Request](#request)\n - [`request.socket`](#requestsocket)\n- [Client](#client-5)\n - [`new Client()`](#new-clienturl-options)\n - [`client.onError`](#clientonerror)\n - [`client.onConnect`](#clientonconnect)\n - [`client.onDisconnect`](#clientondisconnect)\n - [`client.onHeartbeatTimeout`](#clientonheartbeattimeout)\n - [`client.onUpdate`](#clientonupdate)\n - [`await client.connect()`](#await-clientconnectoptions)\n - [`await client.disconnect()`](#await-clientdisconnect)\n - [`client.id`](#clientid)\n - [`await client.request()`](#await-clientrequestoptions)\n - [`await client.message()`](#await-clientmessagemessage)\n - [`await client.subscribe()`](#await-clientsubscribepath-handler)\n - [`await client.unsubscribe()`](#await-clientunsubscribepath-handler)\n - [`client.subscriptions()`](#clientsubscriptions)\n - [`client.overrideReconnectionAuth()`](#clientoverridereconnectionauthauth)\n - [`await client.reauthenticate()`](#await-clientreauthenticateauth)\n - [Errors](#errors)", - "api": "

    Protocol

    \n

    The nes protocol is described in the Protocol documentation.

    \n

    Examples

    \n

    Route invocation

    \n

    Server

    \n
    const Hapi = require('@hapi/hapi');\nconst Nes = require('@hapi/nes');\n\nconst server = new Hapi.Server();\n\nconst start = async () => {\n\n    await server.register(Nes);\n    server.route({\n        method: 'GET',\n        path: '/h',\n        config: {\n            id: 'hello',\n            handler: (request, h) => {\n\n                return 'world!';\n            }\n        }\n    });\n\n    await server.start();\n};\n\nstart();
    \n

    Client

    \n
    const Nes = require('@hapi/nes');\n\nvar client = new Nes.Client('ws://localhost');\n\nconst start = async () => {\n\n    await client.connect();\n    const payload = await client.request('hello');  // Can also request '/h'\n    // payload -> 'world!'\n};\n\nstart();
    \n

    Subscriptions

    \n

    Server

    \n
    const Hapi = require('@hapi/hapi');\nconst Nes = require('@hapi/nes');\n\nconst server = new Hapi.Server();\n\nconst start = async () => {\n\n    await server.register(Nes);\n    server.subscription('/item/{id}');\n    await server.start();\n    server.publish('/item/5', { id: 5, status: 'complete' });\n    server.publish('/item/6', { id: 6, status: 'initial' });\n};\n\nstart();
    \n

    Client

    \n
    const Nes = require('@hapi/nes');\n\nconst client = new Nes.Client('ws://localhost');\nconst start = async () => {\n\n    await client.connect();\n    const handler = (update, flags) => {\n\n        // update -> { id: 5, status: 'complete' }\n        // Second publish is not received (doesn't match)\n    };\n\n    client.subscribe('/item/5', handler);\n};\n\nstart();
    \n

    Broadcast

    \n

    Server

    \n
    const Hapi = require('@hapi/hapi');\nconst Nes = require('@hapi/nes');\n\nconst server = new Hapi.Server();\n\nconst start = async () => {\n\n    await server.register(Nes);\n    await server.start();\n    server.broadcast('welcome!');\n};\n\nstart();
    \n

    Client

    \n
    const Nes = require('@hapi/nes');\n\nconst client = new Nes.Client('ws://localhost');\nconst start = async () => {\n\n    await client.connect();\n    client.onUpdate = (update) => {\n\n        // update -> 'welcome!'\n    };\n};\n\nstart();
    \n

    Route authentication

    \n

    Server

    \n
    const Hapi = require('@hapi/hapi');\nconst Basic = require('@hapi/basic');\nconst Bcrypt = require('bcrypt');\nconst Nes = require('@hapi/nes');\n\nconst server = new Hapi.Server();\n\nconst start = async () => {\n\n    await server.register([Basic, Nes]);\n\n    // Set up HTTP Basic authentication\n\n    const users = {\n        john: {\n            username: 'john',\n            password: '$2a$10$iqJSHD.BGr0E2IxQwYgJmeP3NvhPrXAeLSaGCj6IR/XU5QtjVu5Tm',   // 'secret'\n            name: 'John Doe',\n            id: '2133d32a'\n        }\n    };\n\n    const validate = async (request, username, password) => {\n\n        const user = users[username];\n        if (!user) {\n            return { isValid: false };\n        }\n\n        const isValid = await Bcrypt.compare(password, user.password);\n        const  credentials = { id: user.id, name: user.name };\n        return { isValid, credentials };\n    };\n\n    server.auth.strategy('simple', 'basic', { validate });\n\n    // Configure route with authentication\n\n    server.route({\n        method: 'GET',\n        path: '/h',\n        config: {\n            id: 'hello',\n            handler: (request, h) => {\n\n                return `Hello ${request.auth.credentials.name}`;\n            }\n        }\n    });\n\n    await server.start();\n};\n\nstart();
    \n

    Client

    \n
    const Nes = require('@hapi/nes');\n\nconst client = new Nes.Client('ws://localhost');\nconst start = async () => {\n\n    await client.connect({ auth: { headers: { authorization: 'Basic am9objpzZWNyZXQ=' } } });\n    const payload = await client.request('hello')  // Can also request '/h'\n    // payload -> 'Hello John Doe'\n};\n\nstart();
    \n

    Subscription filter

    \n

    Server

    \n
    const Hapi = require('@hapi/hapi');\nconst Basic = require('@hapi/basic');\nconst Bcrypt = require('bcrypt');\nconst Nes = require('@hapi/nes');\n\nconst server = new Hapi.Server();\n\nconst start = async () => {\n\n    await server.register([Basic, Nes]);\n\n    // Set up HTTP Basic authentication\n\n    const users = {\n        john: {\n            username: 'john',\n            password: '$2a$10$iqJSHD.BGr0E2IxQwYgJmeP3NvhPrXAeLSaGCj6IR/XU5QtjVu5Tm',   // 'secret'\n            name: 'John Doe',\n            id: '2133d32a'\n        }\n    };\n\n    const validate = async (request, username, password) => {\n\n        const user = users[username];\n        if (!user) {\n            return { isValid: false };\n        }\n\n        const isValid = await Bcrypt.compare(password, user.password);\n        const  credentials = { id: user.id, name: user.name };\n        return { isValid, credentials };\n    };\n\n    server.auth.strategy('simple', 'basic', 'required', { validate });\n\n    // Set up subscription\n\n    server.subscription('/items', {\n        filter: (path, message, options) => {\n\n            return (message.updater !== options.credentials.username);\n        }\n    });\n\n    await server.start();\n    server.publish('/items', { id: 5, status: 'complete', updater: 'john' });\n    server.publish('/items', { id: 6, status: 'initial', updater: 'steve' });\n};\n\nstart();
    \n

    Client

    \n
    const Nes = require('@hapi/nes');\n\nconst client = new Nes.Client('ws://localhost');\n\n// Authenticate as 'john'\n\nconst start = async () => {\n\n    await client.connect({ auth: { headers: { authorization: 'Basic am9objpzZWNyZXQ=' } } });\n    const handler = (update, flags) => {\n\n        // First publish is not received (filtered due to updater key)\n        // update -> { id: 6, status: 'initial', updater: 'steve' }\n    };\n\n    client.subscribe('/items', handler);\n};\n\nstart();
    \n

    Browser Client

    \n

    When you require('@hapi/nes') it loads the full module and adds a lot of extra code that is not needed\nfor the browser. The browser will only need the nes client. If you are using CommonJS you can\nload the client with require('@hapi/nes/lib/client').

    \n

    Registration

    \n

    The nes plugin uses the standard hapi registration process using the server.register()\nmethod. The plugin accepts the following optional registration options:

    \n
      \n
    • \nonConnection - a function with the signature function(socket) invoked for each incoming client\nconnection where:\n
        \n
      • \nsocket - the Socket object of the incoming connection.
      • \n
      \n
    • \n
    • \nonDisconnection - a function with the signature function(socket) invoked for each incoming client\nconnection on disconnect where:\n
        \n
      • \nsocket - the Socket object of the connection.
      • \n
      \n
    • \n
    • \nonMessage - a function with the signature async function(socket, message) used to receive custom\nclient messages (when the client calls client.message()) where:\n
        \n
      • \nsocket - the Socket object of the message source.
      • \n
      • \nmessage - the message sent by the client.
      • \n
      • the function may return a response to the client.
      • \n
      \n
    • \n
    • \nauth - optional plugin authentication options with the following supported values:\n
        \n
      • \nfalse - no client authentication supported.
      • \n
      • an object with the following optional keys:\n
          \n
        • \ntype - the type of authentication flow supported by the server. Each type has a very different\nsecurity profile. The following types are supported:\n
            \n
          • \n'direct' - the plugin configures an internal authentication endpoint which is only called\ninternally by the plugin when the client provides its authentication credentials (or by\npassing an auth option to client.connect()). The\nendpoint returns a copy of the credentials object (along with any artifacts) to the plugin\nwhich is then used for all subsequent client requests and subscriptions. This type requires\nexposing the underlying credentials to the application. Note that if the authentication scheme\nuses the HTTP request method (e.g. hawk or\noz) you need to use 'auth' as the value (and\nnot 'GET'). This is the default value.
          • \n
          • \n'cookie' - the plugin configures a public authentication endpoint which must be called\nby the client application manually before it calls client.connect().\nWhen the endpoint is called with valid credentials, it sets a cookie with the provided\nname which the browser then transmits back to the server when the WebSocket connection\nis made. This type removes the need to expose the authentication credentials to the\nJavaScript layer but requires an additional round trip before establishing a client\nconnection.
          • \n
          • \n'token' - the plugin configures a public authentication endpoint which must be called\nby the client application manually before it calls client.connect().\nWhen the endpoint is called with valid credentials, it returns an encrypted authentication\ntoken which the client can use to authenticate the connection by passing an auth option\nto client.connect() with the token. This type is useful\nwhen the client-side application needs to manage its credentials differently than relying\non cookies (e.g. non-browser clients).
          • \n
          \n
        • \n
        • \nendpoint - the HTTP path of the authentication endpoint. Note that even though the 'direct'\ntype does not exposes the endpoint, it is still created internally and registered using the\nprovided path. Change it only if the default path creates a conflict. Defaults to '/nes/auth'.
        • \n
        • \nid - the authentication endpoint identifier. Change it only if the default id creates a conflict.\nDefaults to nes.auth.
        • \n
        • \nroute - the hapi route config.auth settings. The authentication endpoint must be\nconfigured with at least one authentication strategy which the client is going to use to\nauthenticate. The route value must be set to a valid value supported by the hapi route\nauth configuration. Defaults to the default authentication strategy if one is present,\notherwise no authentication will be possible (clients will fail to authenticate).
        • \n
        • \npassword - the password used by the iron module\nto encrypt the cookie or token values. If no password is provided, one is automatically\ngenerated. However, the password will change every time the process is restarted (as well\nas generate different results on a distributed system). It is recommended that a password\nis manually set and managed by the application.
        • \n
        • \niron - the settings used by the iron module.\nDefaults to the iron defaults.
        • \n
        • \ncookie - the cookie name when using type 'cookie'. Defaults to 'nes'.
        • \n
        • \nisSecure - the cookie secure flag when using type 'cookie'. Defaults to true.
        • \n
        • \nisHttpOnly - the cookie HTTP only flag when using type 'cookie'. Defaults to true.
        • \n
        • \npath - the cookie path when using type 'cookie'. Defaults to '/'.
        • \n
        • \ndomain - the cookie domain when using type 'cookie'. Defaults to no domain.
        • \n
        • \nttl - the cookie expiration milliseconds when using type 'cookie'. Defaults to current\nsession only.
        • \n
        • \nindex - if true, authenticated socket with user property in credentials are mapped\nfor usage in server.broadcast() calls. Defaults to false.
        • \n
        • \ntimeout - number of milliseconds after which a new connection is disconnected if authentication\nis required but the connection has not yet sent a hello message. No timeout if set to false.\nDefaults to 5000 (5 seconds).
        • \n
        • \nmaxConnectionsPerUser - if specified, limits authenticated users to a maximum number of\nclient connections. Requires the index option enabled. Defaults to false.
        • \n
        • \nminAuthVerifyInterval - if specified, waits at least the specificed number of milliseconds\nbetween calls to await server.auth.verify()\nto check if credentials are still valid. Cannot be shorter than heartbeat.interval.\nDefaults to heartbeat.interval or 15000 if heartbeat is disabled.
        • \n
        \n
      • \n
      \n
    • \n
    • \nheaders - an optional array of header field names to include in server responses to the client.\nIf set to '*' (without an array), allows all headers. Defaults to null (no headers).
    • \n
    • \npayload - optional message payload settings where:\n
        \n
      • \nmaxChunkChars - the maximum number of characters (after the full protocol object is converted\nto a string using JSON.stringify()) allowed in a single WebSocket message. This is important\nwhen using the protocol over a slow network (e.g. mobile) with large updates as the transmission\ntime can exceed the timeout or heartbeat limits which will cause the client to disconnect.\nDefaults to false (no limit).
      • \n
      \n
    • \n
    • \nheartbeat - configures connection keep-alive settings where value can be:\n
        \n
      • \nfalse - no heartbeats.
      • \n
      • an object with:\n
          \n
        • \ninterval - time interval between heartbeat messages in milliseconds. Defaults to 15000\n(15 seconds).
        • \n
        • \ntimeout - timeout in milliseconds after a heartbeat is sent to the client and before the\nclient is considered disconnected by the server. Defaults to 5000 (5 seconds).
        • \n
        \n
      • \n
      \n
    • \n
    • \nmaxConnections - if specified, limits the number of simultaneous client connections. Defaults to\nfalse.
    • \n
    • \norigin - an origin string or an array of origin strings incoming client requests must match for\nthe connection to be permitted. Defaults to no origin validation.
    • \n
    \n

    Server

    \n

    The plugin decorates the server with a few new methods for interacting with the incoming WebSocket\nconnections.

    \n

    await server.broadcast(message, [options])

    \n

    Sends a message to all connected clients where:

    \n
      \n
    • \nmessage - the message sent to the clients. Can be any type which can be safely converted to\nstring using JSON.stringify().
    • \n
    • \noptions - optional object with the following:\n
        \n
      • \nuser - optional user filter. When provided, the message will be sent only to authenticated\nsockets with credentials.user equal to user. Requires the auth.index options to be\nconfigured to true.
      • \n
      \n
    • \n
    \n

    Note that in a multi server deployment, only the client connected to the current server will receive\nthe message.

    \n

    server.subscription(path, [options])

    \n

    Declares a subscription path client can subscribe to where:

    \n
      \n
    • \npath - an HTTP-like path. The path must begin with the '/' character. The path may contain\npath parameters as supported by the hapi route path parser.
    • \n
    • \noptions - an optional object where:\n
        \n
      • \nfilter - a publishing filter function for making per-client connection decisions about which\nmatching publication update should be sent to which client. The function uses the signature\nasync function(path, message, options) where:\n
          \n
        • \npath - the path of the published update. The path is provided in case the subscription\ncontains path parameters.
        • \n
        • \nmessage - the message being published.
        • \n
        • \noptions - additional information about the subscription and client:\n
            \n
          • \nsocket - the current socket being published to.
          • \n
          • \ncredentials - the client credentials if authenticated.
          • \n
          • \nparams - the parameters parsed from the publish message path if the subscription\npath contains parameters.
          • \n
          • \ninternal - the internal options data passed to the publish call, if defined.
          • \n
          \n
        • \n
        • the function must return a value of (or a promise that resolves into):\n
            \n
          • \ntrue - to proceed sending the message.
          • \n
          • \nfalse - to skip sending the message.
          • \n
          • \n{ override } - an override message to send to this socket instead of the\npublished one. Note that if you want to modify message, you must clone it first or\nthe changes will apply to all other sockets.
          • \n
          \n
        • \n
        \n
      • \n
      • \nauth - the subscription authentication options with the following supported values:\n
          \n
        • \nfalse - no authentication required to subscribe.
        • \n
        • a configuration object with the following optional keys:\n
            \n
          • \nmode - same as the hapi route auth modes:\n
              \n
            • \n'required' - authentication is required. This is the default value.
            • \n
            • \n'optional' - authentication is optional.
            • \n
            \n
          • \n
          • \nscope - a string or array of string of authentication scope as supported by the\nhapi route authenticate configuration.
          • \n
          • \nentity - the required credentials type as supported by the hapi route\nauthentication configuration:\n
              \n
            • 'user'
            • \n
            • 'app'
            • \n
            • 'any'
            • \n
            \n
          • \n
          • \nindex - if true, authenticated socket with user property in credentials are\nmapped for usage in server.publish() calls.\nDefaults to false.
          • \n
          \n
        • \n
        \n
      • \n
      • \nonSubscribe - a method called when a client subscribes to this subscription endpoint using\nthe signature async function(socket, path, params) where:\n
          \n
        • \nsocket - the Socket object of the incoming connection.
        • \n
        • \npath - the path the client subscribed to
        • \n
        • \nparams - the parameters parsed from the subscription request path if the subscription\npath definition contains parameters.
        • \n
        \n
      • \n
      • \nonUnsubscribe - a method called when a client unsubscribes from this subscription endpoint\nusing the signature async function(socket, path, params) where:\n
          \n
        • \nsocket - the Socket object of the incoming connection.
        • \n
        • \npath - Path of the unsubscribed route.
        • \n
        • \nparams - the parameters parsed from the subscription request path if the subscription\npath definition contains parameters.
        • \n
        \n
      • \n
      \n
    • \n
    \n

    await server.publish(path, message, [options])

    \n

    Sends a message to all the subscribed clients where:

    \n
      \n
    • \npath - the subscription path. The path is matched first against the available subscriptions\nadded via server.subscription() and then against the specific path provided by each client\nat the time of registration (only matter when the subscription path contains parameters). When\na match is found, the subscription filter function is called (if present) to further filter\nwhich client should receive which update.
    • \n
    • \nmessage - the message sent to the clients. Can be any type which can be safely converted to\nstring using JSON.stringify().
    • \n
    • \noptions - optional object that may include\n
        \n
      • \ninternal - Internal data that is passed to filter and may be used to filter messages\non data that is not sent to the client.
      • \n
      • \nuser - optional user filter. When provided, the message will be sent only to authenticated\nsockets with credentials.user equal to user. Requires the subscription auth.index\noptions to be configured to true.
      • \n
      \n
    • \n
    \n

    await server.eachSocket(each, [options])

    \n

    Iterates over all connected sockets, optionally filtering on those that have subscribed to\na given subscription. This operation is synchronous.

    \n
      \n
    • \neach - Iteration method in the form async function(socket).
    • \n
    • \noptions - Optional options object\n
        \n
      • \nsubscription - When set to a string path, limits the results to sockets that are\nsubscribed to that path.
      • \n
      • \nuser - optional user filter. When provided, the each method will be invoked with\nauthenticated sockets with credentials.user equal to user. Requires the subscription\nauth.index options to be configured to true.
      • \n
      \n
    • \n
    \n

    Socket

    \n

    An object representing a client connection.

    \n

    socket.id

    \n

    A unique socket identifier.

    \n

    socket.app

    \n

    An object used to store application state per socket. Provides a safe namespace to avoid conflicts\nwith the socket methods.

    \n

    socket.auth

    \n

    The socket authentication state if any. Similar to the normal hapi request.auth object where:

    \n
      \n
    • \nisAuthenticated - a boolean set to true when authenticated.
    • \n
    • \ncredentials - the authentication credentials used.
    • \n
    • \nartifacts - authentication artifacts specific to the authentication strategy used.
    • \n
    \n

    socket.server

    \n

    The socket's server reference.

    \n

    socket.connection

    \n

    The socket's connection reference.

    \n

    socket.disconnect()

    \n

    Closes a client connection.

    \n

    socket.isOpen()

    \n

    Returns true is the socket connection is in ready state, otherwise false.

    \n

    await socket.send(message)

    \n

    Sends a custom message to the client where:

    \n
      \n
    • \nmessage - the message sent to the client. Can be any type which can be safely converted to\nstring using JSON.stringify().
    • \n
    \n

    await socket.publish(path, message)

    \n

    Sends a subscription update to a specific client where:

    \n
      \n
    • \npath - the subscription string. Note that if the client did not subscribe to the provided path,\nthe client will ignore the update silently.
    • \n
    • \nmessage - the message sent to the client. Can be any type which can be safely converted to\nstring using JSON.stringify().
    • \n
    \n

    await socket.revoke(path, message, [options])

    \n

    Revokes a subscription and optionally includes a last update where:

    \n
      \n
    • \npath - the subscription string. Note that if the client is not subscribe to the provided path,\nthe client will ignore the it silently.
    • \n
    • \nmessage - an optional last subscription update sent to the client. Can be any type which can be\nsafely converted to string using JSON.stringify(). Pass null to revoke the subscription without\nsending a last update.
    • \n
    • \noptions - optional settings:\n
        \n
      • \nignoreClosed - ignore errors if the underlying websocket has been closed. Defaults to false.
      • \n
      \n
    • \n
    \n

    Request

    \n

    The following decorations are available on each request received via the nes connection.

    \n

    request.socket

    \n

    Provides access to the Socket object of the incoming connection.

    \n

    Client

    \n

    The client implements the nes protocol and provides methods for interacting with the server.\nIt supports auto-connect by default as well as authentication.

    \n

    new Client(url, [options])

    \n

    Creates a new client object where:

    \n
      \n
    • \nurl - the WebSocket address to connect to (e.g. 'wss://localhost:8000').
    • \n
    • \noption - optional configuration object where:\n
        \n
      • \nws - available only when the client is used in node.js and passed as-is to the\nws module.
      • \n
      • \ntimeout - server response timeout in milliseconds. Defaults to false (no timeout).
      • \n
      \n
    • \n
    \n

    client.onError

    \n

    A property used to set an error handler with the signature function(err). Invoked whenever an\nerror happens that cannot be associated with a pending request.

    \n

    client.onConnect

    \n

    A property used to set a handler for connection events (initial connection and subsequent\nreconnections) with the signature function().

    \n

    client.onDisconnect

    \n

    A property used to set a handler for disconnection events with the signature function(willReconnect, log)\nwhere:

    \n
      \n
    • \nwillReconnect - a boolean indicating if the client will automatically attempt to reconnect.
    • \n
    • \nlog - an object with the following optional keys:\n
        \n
      • \ncode - the RFC6455 status code.
      • \n
      • \nexplanation - the RFC6455 explanation for the\ncode.
      • \n
      • \nreason - a human-readable text explaining the reason for closing.
      • \n
      • \nwasClean - if false, the socket was closed abnormally.
      • \n
      \n
    • \n
    \n

    client.onHeartbeatTimeout

    \n

    A property used to set a handler for heartbeat timeout events with the signature function(willReconnect)\nwhere:

    \n
      \n
    • \nwillReconnect - a boolean indicating if the client will automatically attempt to reconnect.
    • \n
    \n

    Upon heartbeat timeout, the client will disconnect the websocket. However, the client.onDisconnect() property will only be called (if set) once the server has completed the closing handshake. Users may use this property to be notified immediately and take action (e.g. display a message in the browser).

    \n

    client.onUpdate

    \n

    A property used to set a custom message handler with the signature function(message). Invoked whenever\nthe server calls server.broadcast() or socket.send().

    \n

    await client.connect([options])

    \n

    Connects the client to the server where:

    \n
      \n
    • \noptions - an optional configuration object with the following options:\n
        \n
      • \nauth - sets the credentials used to authenticate. when the server is configured for\n'token' type authentication, the value is the token response received from the\nauthentication endpoint (called manually by the application). When the server is\nconfigured for 'direct' type authentication, the value is the credentials expected\nby the server for the specified authentication strategy used which typically means an\nobject with headers (e.g. { headers: { authorization: 'Basic am9objpzZWNyZXQ=' } }).
      • \n
      • \nreconnect - a boolean that indicates whether the client should try to reconnect. Defaults to true.
      • \n
      • \ndelay - time in milliseconds to wait between each reconnection attempt. The delay time\nis cumulative, meaning that if the value is set to 1000 (1 second), the first wait will\nbe 1 seconds, then 2 seconds, 3 seconds, until the maxDelay value is reached and then\nmaxDelay is used.
      • \n
      • \nmaxDelay - the maximum delay time in milliseconds between reconnections.
      • \n
      • \nretries - number of reconnection attempts. Defaults to Infinity (unlimited).
      • \n
      • \ntimeout - socket connection timeout in milliseconds. Defaults to the WebSocket\nimplementation timeout default.
      • \n
      \n
    • \n
    \n

    await client.disconnect()

    \n

    Disconnects the client from the server and stops future reconnects.

    \n

    client.id

    \n

    The unique socket identifier assigned by the server. The value is set after the connection is\nestablished.

    \n

    await client.request(options)

    \n

    Sends an endpoint request to the server where:

    \n
      \n
    • \noptions - value can be one of:\n
        \n
      • a string with the requested endpoint path or route id (defaults to a GET method).
      • \n
      • an object with the following keys:\n
          \n
        • \npath - the requested endpoint path or route id.
        • \n
        • \nmethod - the requested HTTP method (can also be any method string supported by the\nserver). Defaults to 'GET'.
        • \n
        • \nheaders - an object where each key is a request header and the value the header\ncontent. Cannot include an Authorization header. Defaults to no headers.
        • \n
        • \npayload - the request payload sent to the server.
        • \n
        \n
      • \n
      \n
    • \n
    \n

    Rejects with Error if the request failed.

    \n

    Resolves with object containing:

    \n
      \n
    • \npayload - the server response object.
    • \n
    • \nstatusCode - the HTTP response status code.
    • \n
    • \nheaders - an object containing the HTTP response headers returned by the server (based on\nthe server configuration).
    • \n
    \n

    await client.message(message)

    \n

    Sends a custom message to the server which is received by the server onMessage handler where:

    \n
      \n
    • \nmessage - the message sent to the server. Can be any type which can be safely converted to\nstring using JSON.stringify().
    • \n
    \n

    await client.subscribe(path, handler)

    \n

    Subscribes to a server subscription where:

    \n
      \n
    • \npath - the requested subscription path. Paths are just like HTTP request paths (e.g.\n'/item/5' or '/updates' based on the paths supported by the server).
    • \n
    • \nhandler - the function used to receive subscription updates using the\nsignature function(message, flags) where:\n
        \n
      • \nmessage - the subscription update sent by the server.
      • \n
      • \nflags - an object with the following optional flags:\n
          \n
        • \nrevoked - set to true when the message is the last update from the server due to\na subscription revocation.
        • \n
        \n
      • \n
      \n
    • \n
    \n

    Note that when subscribe() is called before the client connects, any server errors will be\nthrow by connect().

    \n

    await client.unsubscribe(path, handler)

    \n

    Cancels a subscription where:

    \n
      \n
    • \npath - the subscription path used to subscribe.
    • \n
    • \nhandler - remove a specific handler from a subscription or null to remove all handlers for\nthe given path.
    • \n
    \n

    client.subscriptions()

    \n

    Returns an array of the current subscription paths.

    \n

    client.overrideReconnectionAuth(auth)

    \n

    Sets or overrides the authentication credentials used to reconnect the client on disconnect when\nthe client is configured to automatically reconnect, where:

    \n\n

    Returns true if reconnection is enabled, otherwise false (in which case the method was ignored).

    \n

    Note: this will not update the credentials on the server -\nuse client.reauthenticate().

    \n

    await client.reauthenticate(auth)

    \n

    Will issue the reauth message to the server with updated auth details and also\noverride the reconnection information, if reconnection is enabled.\nThe server will respond with an error and drop the connection in case the new auth credentials are\ninvalid.

    \n

    Rejects with Error if the request failed.

    \n

    Resolves with true if the request succeeds.

    \n

    Note: when authentication has a limited lifetime, reauthenticate() should be called early enough to avoid\nthe server dropping the connection.

    \n

    Errors

    \n

    When a client method returns or throws an error, the error is decorated with:

    \n
      \n
    • \ntype - a string indicating the source of the error where:\n
        \n
      • \n'disconnect' - the socket disconnected before the request completed.
      • \n
      • \n'protocol' - the client received an invalid message from the server violating the protocol.
      • \n
      • \n'server' - an error response sent from the server.
      • \n
      • \n'timeout' - a timeout event.
      • \n
      • \n'user' - user error (e.g. incorrect use of the API).
      • \n
      • \n'ws' - a socket error.
      • \n
      \n
    • \n
    \n", - "intro": "## Introduction\n\n**nes** adds native WebSocket support to [**hapi**](https://github.com/hapijs/hapi)-based application\nservers. Instead of treating the WebSocket connections as a separate platform with its own security\nand application context, **nes** builds on top of the existing **hapi** architecture to provide a\nflexible and organic extension.\n\nProtocol version: 2.4.x (different from module version)\n", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "WebSocket adapter plugin for hapi routes.", - "forks": 87, - "stars": 503, - "date": "2024-10-23T15:19:52Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/nes" - }, - "nigel": { - "name": "nigel", - "versions": [ - { - "name": "5.0.1", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "4.0.2", - "branch": "v4", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "5.0.1", - "4.0.2" - ], - "api": false, - "isPlugin": false, - "5.0.1": { - "menu": "", - "api": "", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "4.0.2": { - "menu": "", - "api": "", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Boyer-Moore-Horspool algorithms", - "forks": 10, - "stars": 15, - "date": "2024-10-23T14:49:50Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/nigel" - }, - "oppsy": { - "name": "oppsy", - "versions": [ - { - "name": "3.0.0", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "3.0.0" - ], - "api": true, - "isPlugin": false, - "3.0.0": { - "menu": "- [new Oppsy()](#new-oppsyserver-config)\n - [oppsy.start()](#oppsystartinterval)\n - [oppsy.stop()](#oppsystop)", - "api": "

    new Oppsy(server, [config])

    \n

    Creates a new Oppsy object.

    \n
      \n
    • \nserver - the hapi server to collect information about.
    • \n
    • \n[config] - optional configuration object\n
        \n
      • \nhttpAgents - the list of httpAgents to report socket information about. Can be a single http.Agent or an array of agents objects. Defaults to Http.globalAgent.
      • \n
      • \nhttpsAgents - the list of httpsAgents to report socket information about. Can be a single https.Agent or an array of agents. Defaults to Https.globalAgent.
      • \n
      \n
    • \n
    \n

    The oppsy object is an EventEmitter so it exposes the same API(.on and .emit) as the Node EventEmitter object. After it is started, it emits an \"ops\" event after a set interval with the collected ops information as the event payload.

    \n

    oppsy.start(interval)

    \n

    Starts an Oppsy object collecting network and server information.

    \n
      \n
    • \ninterval - number of milliseconds to wait between each data sampling.
    • \n
    \n

    oppsy.stop()

    \n

    Stops an Oppsy objects collecting.

    \n", - "intro": "", - "example": "", - "usage": "## Usage\n\n```js\nconst Hapi = require('@hapi/hapi');\nconst Oppsy = require('@hapi/oppsy');\n\nconst server = new Hapi.Server();\nconst oppsy = new Oppsy(server);\noppsy.on('ops', (data) => {\n console.log(data);\n});\n\nawait server.start();\n\noppsy.start(1000);\n```\n\nThis creates a new Oppsy object and starts collecting information every 1000 miliseconds\n", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "An EventEmitter useful for collecting hapi server ops information.", - "forks": 22, - "stars": 25, - "date": "2024-10-23T14:52:58Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/oppsy" - }, - "pez": { - "name": "pez", - "versions": [ - { - "name": "6.1.0", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "5.1.0", - "branch": "v5", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "6.1.0", - "5.1.0" - ], - "api": false, - "isPlugin": false, - "6.1.0": { - "menu": "", - "api": "", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "5.1.0": { - "menu": "", - "api": "", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Multipart parser.", - "forks": 17, - "stars": 34, - "date": "2024-10-23T14:43:54Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/pez" - }, - "podium": { - "name": "podium", - "versions": [ - { - "name": "5.0.1", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "4.1.3", - "branch": "v4", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "5.0.1", - "4.1.3" - ], - "api": true, - "isPlugin": false, - "5.0.1": { - "menu": " - [`Using different parameters`](#-using-different-parameters)\n - [`channels`](#channels)\n - [`clone`](#clone)\n - [`spread`](#spread)\n - [`shared`](#shared)\n - [`tag-filter`](#tag-filter)\n - [`count`](#count)\n- [`new Podium()`](#new-podiumevents-options)\n- [`podium.registerEvent()`](#podiumregistereventevents-options)\n- [`podium.emit()`](#podiumemitcriteria-data)\n- [`await podium.gauge()`](#await-podiumgaugecriteria-data)\n- [`podium.on()`](#podiumoncriteria-listener-context)\n- [`podium.addListener()`](#podiumaddlistenercriteria-listener-context)\n- [`podium.once()`](#podiumoncecriteria-listener-context)\n- [`await podium.once()`](#await-podiumoncecriteria)\n- [`podium.few()`](#podiumfewcriteria)\n- [`podium.off()`](#podiumoffname-listener)\n- [`podium.removeListener()`](#podiumremovelistenername-listener)\n- [`podium.removeAllListeners()`](#podiumremovealllistenersname)\n- [`podium.hasListeners()`](#podiumhaslistenersname)\n- [`Podium.validate()`](#podiumvalidateevents)", - "api": "

    \n Using different parameters\n

    \n

    Along with channels, podium allows you to specify other event parameters. Below are more examples:

    \n\n

    \nchannels\n

    \n
    const Podium = require('@hapi/podium');\nconst podiumObject = new Podium.Podium();\n\npodiumObject.registerEvent([\n    {\n        name: 'event1',\n        channels: ['ch1', 'ch2', 'ch3', 'ch4'],\n    },\n    {\n        name: 'event2',\n        channels: ['ch1', 'ch2']\n    }\n]);\nconst listener1 = (data) => {\n\n    console.log('listener1 called', data);\n};\nconst listener2 = (data) => {\n\n    console.log('listener2 called', data);\n};\n\npodiumObject.on({\n    name: 'event1',\n    channels: ['ch1']\n}, listener1);\n\npodiumObject.on({\n    name: 'event1',\n    channels: ['ch3', 'ch4']\n}, listener2);\n\n\npodiumObject.on({ name: 'event1', channels: 'ch2' }, (data) => { // autonomous function\n\n    console.log('auto', data);\n});\n\nvar arr = [0, 1, 2, 3, 4, 4, 5];\n\npodiumObject.emit({\n    name: 'event1',\n    channel: 'ch3'\n});
    \n

    \nclone\n

    \n
    const Podium = require('@hapi/podium');\nconst podiumObject = new Podium.Podium();\n\npodiumObject.registerEvent([\n    {\n        name: 'event1',\n        channels: ['ch1', 'ch2'],\n        clone: true\n    },\n    {\n        name: 'event2',\n        channels: ['ch1', 'ch2']\n    }\n]);\n\nconst listener1 = (data) => {\n\n    data[0] = 55;\n    console.log('listener1 called', data);\n};\nconst listener2 = (data) => {\n\n    data[0] = 100;\n    console.log('listener2 called', data);\n};\n\npodiumObject.on({\n    name: 'event1',\n    channels: ['ch1']\n}, listener1);\n\npodiumObject.on({\n    name: 'event2',\n    channels: ['ch1']\n}, listener2);\n\nvar arr = [0, 1, 2, 3, 4, 4, 5];\n\nconsole.log('initially: ', arr);\n\npodiumObject.emit({\n    name: 'event1',\n    channel: 'ch1'\n});\n\nconsole.log('after event1, ch1: ', arr);\n\npodiumObject.emit({\n    name: 'event2',\n    channel: 'ch1'\n});\n\nconsole.log('after event2, ch1: ', arr);
    \n

    \nspread\n

    \n
    const Podium = require('@hapi/podium');\nconst podiumObject = new Podium.Podium();\n\npodiumObject.registerEvent([\n    {\n        name: 'event1',\n        channels: ['ch1', 'ch2'],\n        spread: true\n    },\n    {\n        name: 'event2',\n        channels: ['ch1', 'ch2']\n    }\n]);\n\nconst listener1 = (data1, data2, data3, data4) => {\n\n    console.log('listener1 called', data1, data2, data3, data4);\n};\n\nconst listener2 = (data) => {\n\n    data[0] = 100;\n    console.log('listener2 called', data);\n};\n\npodiumObject.on({\n    name: 'event1',\n    channels: ['ch1']\n}, listener1);\n\npodiumObject.on({\n    name: 'event2',\n    channels: ['ch1']\n}, listener2);\n\nvar arr = [0, 1, 2, 3, 4, 4, 5];\n\nconsole.log('initially: ', arr);\n\npodiumObject.emit({\n    name: 'event1',\n    channel: 'ch1'\n});\n\nconsole.log('after event1, ch1: ', arr);\n\npodiumObject.emit({\n    name: 'event2',\n    channel: 'ch1'\n});\nconsole.log('after event2, ch1: ', arr);
    \n

    \nshared\n

    \n
    const Podium = require('@hapi/podium');\nconst podiumObject = new Podium.Podium();\n\npodiumObject.registerEvent([\n    {\n        name: 'event1',\n        channels: ['ch1', 'ch2'],\n    }\n]);\npodiumObject.registerEvent([\n    {\n        name: 'event1',\n        channels: ['ch1', 'ch2'],\n        shared: true\n    }\n]);\nconst listener2 = (data) => {\n\n    console.log('listener2 called', data);\n};\n\npodiumObject.on({\n    name: 'event1',\n    channels: ['ch1']\n}, listener2);\n\nvar arr = [0, 1, 2, 3, 4, 4, 5];\n\npodiumObject.emit({\n    name: 'event1',\n    channel: 'ch1'\n});
    \n

    \ntag-filter\n

    \n
    const Podium = require('@hapi/podium');\nconst emitter = new Podium.Podium('test');\n\nconst updates = [];\nemitter.on('test', (data) => updates.push({ id: 1, data }));\nemitter.on({ name: 'test', filter: ['a', 'b'] }, (data) => updates.push({ id: 2, data }));\nemitter.on({ name: 'test', filter: 'b' }, (data) => updates.push({ id: 3, data }));\nemitter.on({ name: 'test', filter: ['c'] }, (data) => updates.push({ id: 4, data }));\nemitter.on({ name: 'test', filter: { tags: ['a', 'b'], all: true } }, (data) => updates.push({ id: 5, data }));\n\nemitter.emit({ name: 'test', tags: 'a' }, 1);\nemitter.emit({ name: 'test', tags: ['b'] }, 2);\nemitter.emit({ name: 'test', tags: ['d'] }, 3);\nemitter.emit({ name: 'test', tags: ['a'] }, 4);\nemitter.emit({ name: 'test', tags: ['a', 'b'] }, 5);\n\nemitter.emit('test', 6, () => {\n\n    console.log(updates);\n});
    \n

    \ncount\n

    \n
    const Podium = require('@hapi/podium');\nconst podiumObject = new Podium();\n\npodiumObject.registerEvent('event1');\n\nconst listener1 = function(data) {\n\n    console.log('listener1 called', data);\n};\n\npodiumObject.on({\n    name: 'event1',\n    count: 2\n}, listener1);\n\npodiumObject.emit('event1', 'emit 1');\npodiumObject.emit('event1', 'emit 2');\npodiumObject.emit('event1', 'emit 3'); // this wont call listener1
    \n

    new Podium(events, options)

    \n

    Creates a new podium emitter where:

    \n\n

    Returns a Podium object.

    \n

    podium.registerEvent(events, options)

    \n

    Register the specified events and their optional configuration. Events must be registered before\nthey can be emitted or subscribed to. This is done to detect event name misspelling and invalid\nevent activities. The events argument can be:

    \n
      \n
    • an event string.
    • \n
    • an event options object with the following optional keys (unless noted otherwise):\n
        \n
      • \nname - the event name string (required).
      • \n
      • \nchannels - a string or array of strings specifying the event channels available. Defaults\nto no channel restrictions (event updates can specify a channel or not).\n
      • \n
      • \nclone - if true, the data object passed to podium.emit()\nis cloned before it is passed to the listeners (unless an override specified by each listener).\nDefaults to false (data is passed as-is).\n
      • \n
      • \nspread - if true, the data object passed to podium.emit()\nmust be an array and the listener method is called with each array element passed as a separate\nargument (unless an override specified by each listener). This should only be used when the emitted\ndata structure is known and predictable.\nDefaults to false (data is emitted as a single argument regardless of its type).\n
      • \n
      • \ntags - if true and the criteria object passed to podium.emit()\nincludes tags, the tags are mapped to an object (where each tag string is the key and\nthe value is true) which is appended to the arguments list at the end. A configuration override can be set by each\nlistener. Defaults to false.\n
      • \n
      • \nshared - if true, the same event name can be registered multiple times where the second\nregistration is ignored. Note that if the registration config is changed between registrations,\nonly the first configuration is used. Defaults to false (a duplicate registration will throw an\nerror). For detailed examples of event parameters see here\n
      • \n
      \n
    • \n
    • an array containing any of the above.
    • \n
    \n

    The options argument is an object with the following optional properties:

    \n
      \n
    • \nvalidate - if false, events are not validated. This is only allowed when the events\nvalue is returned from Podium.validate(). Defaults to true\n
    • \n
    \n

    podium.emit(criteria, data)

    \n

    Emits an event update to all the subscribed listeners where:

    \n
      \n
    • \ncriteria - the event update criteria which must be one of:\n
        \n
      • the event name string.
      • \n
      • an object with the following optional keys (unless noted otherwise):\n
          \n
        • \nname - the event name string (required).
        • \n
        • \nchannel - the channel name string.
        • \n
        • \ntags - a tag string or array of tag strings.
        • \n
        \n
      • \n
      \n
    • \n
    • \ndata - the value emitted to the subscribers.
    • \n
    \n

    await podium.gauge(criteria, data)

    \n

    Behaves identically to podium.emit(), but also returns an array of the results of all the event listeners that run. The return value is that of Promise.allSettled(), where each item in the resulting array is { status: 'fulfilled', value } in the case of a successful handler, or { status: 'rejected', reason } in the case of a handler that throws.

    \n

    Please note that system errors such as a TypeError are not handled specially, and it's recommended to scrutinize any rejections using something like bounce.

    \n

    podium.on(criteria, listener, context)

    \n

    Subscribe a handler to an event where:

    \n
      \n
    • \ncriteria - the subscription criteria which must be one of the following:\n
        \n
      • event name string.
      • \n
      • a criteria object with the following optional keys (unless noted otherwise):\n
          \n
        • \nname - the event name string (required).
        • \n
        • \nchannels - a string or array of strings specifying the event channels to subscribe to.\nIf the event registration specified a list of allowed channels, the channels array must\nmatch the allowed channels. If channels are specified, event updates without any\nchannel designation will not be included in the subscription. Defaults to no channels\nfilter.\n
        • \n
        • \nclone - if true, the data object passed to podium.emit()\nis cloned before it is passed to the listener method. Defaults to the event\nregistration option (which defaults to false).\n
        • \n
        • \ncount - a positive integer indicating the number of times the listener can be called\nafter which the subscription is automatically removed. A count of 1 is the same as\ncalling podium.once(). Defaults to no limit.\n
        • \n
        • \nfilter - the event tags (if present) to subscribe to which can be one of the following:\n
            \n
          • a tag string.
          • \n
          • an array of tag strings.
          • \n
          • an object with the following:\n
              \n
            • \ntags - a tag string or array of tag strings.
            • \n
            • \nall - if true, all tags must be present for the event update to match the\nsubscription. Defaults to false (at least one matching tag).\n
            • \n
            \n
          • \n
          \n
        • \n
        • \nspread - if true, and the data object passed to podium.emit()\nis an array, the listener method is called with each array element passed as a separate\nargument. This should only be used when the emitted data structure is known and predictable.\nDefaults to the event registration option (which defaults to false).\n
        • \n
        • \ntags - if true and the criteria object passed to podium.emit()\nincludes tags, the tags are mapped to an object (where each tag string is the key and\nthe value is true) which is appended to the arguments list at the end. Defaults to the event registration option\n(which defaults to false).\n
        • \n
        \n
      • \n
      \n
    • \n
    • \nlistener - the handler method set to receive event updates. The function signature depends\non the spread, and tags options.
    • \n
    • \ncontext - an object that binds to the listener handler.
    • \n
    \n

    podium.addListener(criteria, listener, context)

    \n

    Same as podium.on().

    \n

    podium.once(criteria, listener, context)

    \n

    Same as calling podium.on() with the count option set to 1.

    \n

    await podium.once(criteria)

    \n

    Subscribes to an event by returning a promise that resolves when the event is emitted. criteria can be specified\nin any format supported by podium.on(), except for the count option that is set to 1.

    \n

    Return a promise that resolves when the event is emitted. The resolution value is an array of emitted arguments.

    \n

    podium.few(criteria)

    \n

    Subscribes to an event by returning a promise that resolves when the event is emitted count times. criteria can only be specified\nin the object format supported by podium.on() and the count option is required.

    \n

    Returns a promise that resolves when the event is emitted count times. The resolution value is an array where each item is an array of emitted arguments.

    \n

    podium.off(name, listener)

    \n

    Removes all listeners subscribed to a given event name matching the provided listener method where:

    \n
      \n
    • \nname - the event name string.
    • \n
    • \nlistener - the function reference provided when subscribed.
    • \n
    \n

    podium.removeListener(name, listener)

    \n

    Same as podium.off().

    \n

    Returns a reference to the current emitter.

    \n

    podium.removeAllListeners(name)

    \n

    Removes all listeners subscribed to a given event name where:

    \n
      \n
    • \nname - the event name string.
    • \n
    \n

    Returns a reference to the current emitter.

    \n

    podium.hasListeners(name)

    \n

    Returns whether an event has any listeners subscribed where:

    \n
      \n
    • \nname - the event name string.
    • \n
    \n

    Returns true if the event name has any listeners, otherwise false.

    \n

    Podium.validate(events)

    \n

    Validates that events are declared in the correct format. Events can be declared\nin any of the formats supported by the podium.registerEvent() method.\nWhen the declaration is valid, the array of events returned can be passed to the podium.registerEvent()\nmethod with validations disabled, otherwise a validation error is thrown.

    \n", - "intro": "## Introduction\n\n**podium** is an event emitter with support for tags, filters, channels, event update cloning,\narguments spreading, and other features useful when building large scale applications.\nWhile node's native [`EventEmitter`](https://nodejs.org/docs/latest-v12.x/api/events.html#events_class_eventemitter) is strictly focused on maximum performance,\nit lacks many features that do not belong in the core implementation. **podium** is not restricted by\nnode's performance requirement as it is designed for application layer needs where its overhead\nis largely insignificant as implementing these features will have similar cost on top of the native emitter.\n", - "example": "## Example\n\n```js\nconst Podium = require('@hapi/podium');\n\nconst emitter = new Podium.Podium()\n\nconst context = { count: 0 }\n\nemitter.registerEvent({\n name: 'event',\n channels: ['ch1', 'ch2']\n})\n\nconst handler1 = function () {\n\n ++this.count\n console.log(this.count)\n};\n\nconst handler2 = function () {\n\n this.count = this.count + 2\n console.log(this.count)\n}\n\nemitter.on({\n name: 'event',\n channels: ['ch1']\n}, handler1, context);\n\nemitter.on({\n name: 'event',\n channels: ['ch2']\n}, handler2, context)\n\nemitter.emit({\n name: 'event',\n channel: 'ch1'\n})\n\nemitter.emit({\n name: 'event',\n channel: 'ch2'\n})\n\nemitter.hasListeners('event') // true\n\nemitter.removeAllListeners('event') // Removes all listeners subscribed to 'event'\n```\n\nThe above example uses podium's channel event parameter to restrict the event update to only the specified channel.\n\nFirst you register the event by calling the `registerEvent()` method. Here, you name the event `'event'` and give it channels `['ch1', 'ch2']`.\n\nNext you specify your listener handlers. These will be called when an event is updated. Here you make use of podium's listener context, data that you can bind to your listener handlers.\nIn this case, `handler1` will add 1 to count, which is specified as `{ count: 0 }`, while `handler2` will add 2.\n\nNext you call the `on()` method to subscribe a handler to an event. You use the same event name, but two different channels. `'ch1'` will use handler1 and `'ch2'` will use handler2.\n\nLastly, you use `emit()` to emit and event update to the subscribers.\n\n", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "4.1.3": { - "menu": "- [Introduction](#introduction)\n- [Example](#example)\n - [`Using different parameters`](#-using-different-parameters)\n - [`channels`](#channels)\n - [`clone`](#clone)\n - [`spread`](#spread)\n - [`shared`](#shared)\n - [`tag-filter`](#tag-filter)\n - [`count`](#count)\n- [`new Podium()`](#new-podiumevents-options)\n- [`podium.registerEvent()`](#podiumregistereventevents-options)\n- [`podium.registerPodium()`](#podiumregisterpodiumpodiums)\n- [`podium.emit()`](#podiumemitcriteria-data)\n- [`podium.on()`](#podiumoncriteria-listener-context)\n- [`podium.addListener()`](#podiumaddlistenercriteria-listener-context)\n- [`podium.once()`](#podiumoncecriteria-listener-context)\n- [`await podium.once()`](#await-podiumoncecriteria)\n- [`podium.few()`](#podiumfewcriteria)\n- [`podium.removeListener()`](#podiumremovelistenername-listener)\n- [`podium.removeAllListeners()`](#podiumremovealllistenersname)\n- [`podium.hasListeners()`](#podiumhaslistenersname)\n- [`Podium.validate()`](#podiumvalidateevents)", - "api": "

    Introduction

    \n

    podium is an event emitter with support for tags, filters, channels, event update cloning,\narguments spreading, and other features useful when building large scale applications.\nWhile node's native EventEmitter is strictly focused on maximum performance,\nit lacks many features that do not belong in the core implementation. podium is not restricted by\nnode's performance requirement as it is designed for application layer needs where its overhead\nis largely insignificant as implementing these features will have similar cost on top of the native emitter.

    \n

    Example

    \n
    const Podium = require('@hapi/podium');\n\nconst emitter = new Podium()\n\nconst context = { count: 0 }\n\nemitter.registerEvent({\n    name: 'event',\n    channels: ['ch1', 'ch2']\n})\n\nconst handler1 = function () {\n\n    ++this.count\n    console.log(this.count)\n};\n\nconst handler2 = function () {\n\n    this.count = this.count + 2\n    console.log(this.count)\n}\n\nemitter.on({\n    name: 'event',\n    channels: ['ch1']\n}, handler1, context);\n\nemitter.on({\n    name: 'event',\n    channels: ['ch2']\n}, handler2, context)\n\nemitter.emit({\n    name: 'event',\n    channel: 'ch1'\n})\n\nemitter.emit({\n    name: 'event',\n    channel: 'ch2'\n})\n\nemitter.hasListeners('event') // true\n\nemitter.removeAllListeners('event') // Removes all listeners subscribed to 'event'
    \n

    The above example uses podium's channel event parameter to restrict the event update to only the specified channel.

    \n

    First you register the event by calling the registerEvent() method. Here, you name the event 'event' and give it channels ['ch1', 'ch2'].

    \n

    Next you specify your listener handlers. These will be called when an event is updated. Here you make use of podium's listener context, data that you can bind to your listener handlers.\nIn this case, handler1 will add 1 to count, which is specified as { count: 0 }, while handler2 will add 2.

    \n

    Next you call the on() method to subscribe a handler to an event. You use the same event name, but two different channels. 'ch1' will use handler1 and 'ch2' will use handler2.

    \n

    Lastly, you use emit() to emit and event update to the subscribers.

    \n

    \n Using different parameters\n

    \n

    Along with channels, podium allows you to specify other event parameters. Below are more examples:

    \n\n

    \nchannels\n

    \n
    const Podium = require('@hapi/podium');\nconst podiumObject = new Podium();\n\npodiumObject.registerEvent([\n    {\n        name: 'event1',\n        channels: ['ch1', 'ch2', 'ch3', 'ch4'],\n    },\n    {\n        name: 'event2',\n        channels: ['ch1', 'ch2']\n    }\n]);\nconst listener1 = (data) => {\n\n    console.log('listener1 called', data);\n};\nconst listener2 = (data) => {\n\n    console.log('listener2 called', data);\n};\n\npodiumObject.on({\n    name: 'event1',\n    channels: ['ch1']\n}, listener1);\n\npodiumObject.on({\n    name: 'event1',\n    channels: ['ch3', 'ch4']\n}, listener2);\n\n\npodiumObject.on({ name: 'event1', channels: 'ch2' }, (data) => { // autonomous function\n\n    console.log('auto', data);\n});\n\nvar arr = [0, 1, 2, 3, 4, 4, 5];\n\npodiumObject.emit({\n    name: 'event1',\n    channel: 'ch3'\n});
    \n

    \nclone\n

    \n
    const Podium = require('@hapi/podium');\nconst podiumObject = new Podium();\n\npodiumObject.registerEvent([\n    {\n        name: 'event1',\n        channels: ['ch1', 'ch2'],\n        clone: true\n    },\n    {\n        name: 'event2',\n        channels: ['ch1', 'ch2']\n    }\n]);\n\nconst listener1 = (data) => {\n\n    data[0] = 55;\n    console.log('listener1 called', data);\n};\nconst listener2 = (data) => {\n\n    data[0] = 100;\n    console.log('listener2 called', data);\n};\n\npodiumObject.on({\n    name: 'event1',\n    channels: ['ch1']\n}, listener1);\n\npodiumObject.on({\n    name: 'event2',\n    channels: ['ch1']\n}, listener2);\n\nvar arr = [0, 1, 2, 3, 4, 4, 5];\n\nconsole.log('initially: ', arr);\n\npodiumObject.emit({\n    name: 'event1',\n    channel: 'ch1'\n});\n\nconsole.log('after event1, ch1: ', arr);\n\npodiumObject.emit({\n    name: 'event2',\n    channel: 'ch1'\n});\n\nconsole.log('after event2, ch1: ', arr);
    \n

    \nspread\n

    \n
    const Podium = require('@hapi/podium');\nconst podiumObject = new Podium();\n\npodiumObject.registerEvent([\n    {\n        name: 'event1',\n        channels: ['ch1', 'ch2'],\n        spread: true\n    },\n    {\n        name: 'event2',\n        channels: ['ch1', 'ch2']\n    }\n]);\n\nconst listener1 = (data1, data2, data3, data4) => {\n\n    console.log('listener1 called', data1, data2, data3, data4);\n};\n\nconst listener2 = (data) => {\n\n    data[0] = 100;\n    console.log('listener2 called', data);\n};\n\npodiumObject.on({\n    name: 'event1',\n    channels: ['ch1']\n}, listener1);\n\npodiumObject.on({\n    name: 'event2',\n    channels: ['ch1']\n}, listener2);\n\nvar arr = [0, 1, 2, 3, 4, 4, 5];\n\nconsole.log('initially: ', arr);\n\npodiumObject.emit({\n    name: 'event1',\n    channel: 'ch1'\n});\n\nconsole.log('after event1, ch1: ', arr);\n\npodiumObject.emit({\n    name: 'event2',\n    channel: 'ch1'\n});\nconsole.log('after event2, ch1: ', arr);
    \n

    \nshared\n

    \n
    const Podium = require('@hapi/podium');\nconst podiumObject = new Podium();\n\npodiumObject.registerEvent([\n    {\n        name: 'event1',\n        channels: ['ch1', 'ch2'],\n    }\n]);\npodiumObject.registerEvent([\n    {\n        name: 'event1',\n        channels: ['ch1', 'ch2'],\n        shared: true\n    }\n]);\nconst listener2 = (data) => {\n\n    console.log('listener2 called', data);\n};\n\npodiumObject.on({\n    name: 'event1',\n    channels: ['ch1']\n}, listener2);\n\nvar arr = [0, 1, 2, 3, 4, 4, 5];\n\npodiumObject.emit({\n    name: 'event1',\n    channel: 'ch1'\n});
    \n

    \ntag-filter\n

    \n
    const Podium = require('@hapi/podium');\nconst emitter = new Podium('test');\n\nconst updates = [];\nemitter.on('test', (data) => updates.push({ id: 1, data }));\nemitter.on({ name: 'test', filter: ['a', 'b'] }, (data) => updates.push({ id: 2, data }));\nemitter.on({ name: 'test', filter: 'b' }, (data) => updates.push({ id: 3, data }));\nemitter.on({ name: 'test', filter: ['c'] }, (data) => updates.push({ id: 4, data }));\nemitter.on({ name: 'test', filter: { tags: ['a', 'b'], all: true } }, (data) => updates.push({ id: 5, data }));\n\nemitter.emit({ name: 'test', tags: 'a' }, 1);\nemitter.emit({ name: 'test', tags: ['b'] }, 2);\nemitter.emit({ name: 'test', tags: ['d'] }, 3);\nemitter.emit({ name: 'test', tags: ['a'] }, 4);\nemitter.emit({ name: 'test', tags: ['a', 'b'] }, 5);\n\nemitter.emit('test', 6, () => {\n\n    console.log(updates);\n});
    \n

    \ncount\n

    \n
    const Podium = require('@hapi/podium');\nconst podiumObject = new Podium();\n\npodiumObject.registerEvent('event1');\n\nconst listener1 = function(data) {\n\n    console.log('listener1 called', data);\n};\n\npodiumObject.on({\n    name: 'event1',\n    count: 2\n}, listener1);\n\npodiumObject.emit('event1', 'emit 1');\npodiumObject.emit('event1', 'emit 2');\npodiumObject.emit('event1', 'emit 3'); // this wont call listener1
    \n

    new Podium(events, options)

    \n

    Creates a new podium emitter where:

    \n\n

    Returns a Podium object.

    \n

    podium.registerEvent(events, options)

    \n

    Register the specified events and their optional configuration. Events must be registered before\nthey can be emitted or subscribed to. This is done to detect event name misspelling and invalid\nevent activities. The events argument can be:

    \n
      \n
    • an event string.
    • \n
    • an event options object with the following optional keys (unless noted otherwise):\n
        \n
      • \nname - the event name string (required).
      • \n
      • \nchannels - a string or array of strings specifying the event channels available. Defaults\nto no channel restrictions (event updates can specify a channel or not).\n
      • \n
      • \nclone - if true, the data object passed to podium.emit()\nis cloned before it is passed to the listeners (unless an override specified by each listener).\nDefaults to false (data is passed as-is).\n
      • \n
      • \nspread - if true, the data object passed to podium.emit()\nmust be an array and the listener method is called with each array element passed as a separate\nargument (unless an override specified by each listener). This should only be used when the emitted\ndata structure is known and predictable.\nDefaults to false (data is emitted as a single argument regardless of its type).\n
      • \n
      • \ntags - if true and the criteria object passed to podium.emit()\nincludes tags, the tags are mapped to an object (where each tag string is the key and\nthe value is true) which is appended to the arguments list at the end. A configuration override can be set by each\nlistener. Defaults to false.\n
      • \n
      • \nshared - if true, the same event name can be registered multiple times where the second\nregistration is ignored. Note that if the registration config is changed between registrations,\nonly the first configuration is used. Defaults to false (a duplicate registration will throw an\nerror). For detailed examples of event parameters see here\n
      • \n
      \n
    • \n
    • a Podium object which is passed to podium.registerPodium().
    • \n
    • an array containing any of the above.
    • \n
    \n

    The options argument is an object with the following optional properties:

    \n
      \n
    • \nvalidate - if false, events are not validated. This is only allowed when the events\nvalue is returned from Podium.validate(). Defaults to true\n
    • \n
    \n

    podium.registerPodium(podiums)

    \n

    Registers another emitter as an event source for the current emitter (any event update emitted by the\nsource emitter is passed to any subscriber of the current emitter) where:

    \n
      \n
    • \npodiums - a Podium object or an array of objects, each added as a source.
    • \n
    \n

    Note that any events registered with a source emitter are automatically added to the current emitter.\nIf the events are already registered, they are left as-is.

    \n

    podium.emit(criteria, data)

    \n

    Emits an event update to all the subscribed listeners where:

    \n
      \n
    • \ncriteria - the event update criteria which must be one of:\n
        \n
      • the event name string.
      • \n
      • an object with the following optional keys (unless noted otherwise):\n
          \n
        • \nname - the event name string (required).
        • \n
        • \nchannel - the channel name string.
        • \n
        • \ntags - a tag string or array of tag strings.
        • \n
        \n
      • \n
      \n
    • \n
    • \ndata - the value emitted to the subscribers.
    • \n
    \n

    podium.on(criteria, listener, context)

    \n

    Subscribe a handler to an event where:

    \n
      \n
    • \ncriteria - the subscription criteria which must be one of the following:\n
        \n
      • event name string.
      • \n
      • a criteria object with the following optional keys (unless noted otherwise):\n
          \n
        • \nname - the event name string (required).
        • \n
        • \nchannels - a string or array of strings specifying the event channels to subscribe to.\nIf the event registration specified a list of allowed channels, the channels array must\nmatch the allowed channels. If channels are specified, event updates without any\nchannel designation will not be included in the subscription. Defaults to no channels\nfilter.\n
        • \n
        • \nclone - if true, the data object passed to podium.emit()\nis cloned before it is passed to the listener method. Defaults to the event\nregistration option (which defaults to false).\n
        • \n
        • \ncount - a positive integer indicating the number of times the listener can be called\nafter which the subscription is automatically removed. A count of 1 is the same as\ncalling podium.once(). Defaults to no limit.\n
        • \n
        • \nfilter - the event tags (if present) to subscribe to which can be one of the following:\n
            \n
          • a tag string.
          • \n
          • an array of tag strings.
          • \n
          • an object with the following:\n
              \n
            • \ntags - a tag string or array of tag strings.
            • \n
            • \nall - if true, all tags must be present for the event update to match the\nsubscription. Defaults to false (at least one matching tag).\n
            • \n
            \n
          • \n
          \n
        • \n
        • \nspread - if true, and the data object passed to podium.emit()\nis an array, the listener method is called with each array element passed as a separate\nargument. This should only be used when the emitted data structure is known and predictable.\nDefaults to the event registration option (which defaults to false).\n
        • \n
        • \ntags - if true and the criteria object passed to podium.emit()\nincludes tags, the tags are mapped to an object (where each tag string is the key and\nthe value is true) which is appended to the arguments list at the end. Defaults to the event registration option\n(which defaults to false).\n
        • \n
        \n
      • \n
      \n
    • \n
    • \nlistener - the handler method set to receive event updates. The function signature depends\non the spread, and tags options.
    • \n
    • \ncontext - an object that binds to the listener handler.
    • \n
    \n

    podium.addListener(criteria, listener, context)

    \n

    Same as podium.on().

    \n

    podium.once(criteria, listener, context)

    \n

    Same as calling podium.on() with the count option set to 1.

    \n

    await podium.once(criteria)

    \n

    Subscribes to an event by returning a promise that resolves when the event is emitted. criteria can be specified\nin any format supported by podium.on(), except for the count option that is set to 1.

    \n

    Return a promise that resolves when the event is emitted. The resolution value is an array of emitted arguments.

    \n

    podium.few(criteria)

    \n

    Subscribes to an event by returning a promise that resolves when the event is emitted count times. criteria can only be specified\nin the object format supported by podium.on() and the count option is required.

    \n

    Returns a promise that resolves when the event is emitted count times. The resolution value is an array where each item is an array of emitted arguments.

    \n

    podium.removeListener(name, listener)

    \n

    Removes all listeners subscribed to a given event name matching the provided listener method where:

    \n
      \n
    • \nname - the event name string.
    • \n
    • \nlistener - the function reference provided when subscribed.
    • \n
    \n

    Returns a reference to the current emitter.

    \n

    podium.removeAllListeners(name)

    \n

    Removes all listeners subscribed to a given event name where:

    \n
      \n
    • \nname - the event name string.
    • \n
    \n

    Returns a reference to the current emitter.

    \n

    podium.hasListeners(name)

    \n

    Returns whether an event has any listeners subscribed where:

    \n
      \n
    • \nname - the event name string.
    • \n
    \n

    Returns true if the event name has any listeners, otherwise false.

    \n

    Podium.validate(events)

    \n

    Validates that events are declared in the correct format. Events can be declared\nin any of the formats supported by the podium.registerEvent() method.\nWhen the declaration is valid, the array of events returned can be passed to the podium.registerEvent()\nmethod with validations disabled, otherwise a validation error is thrown.

    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Event emitter with async features.", - "forks": 21, - "stars": 87, - "date": "2024-10-23T15:41:48Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/podium" - }, - "scooter": { - "name": "scooter", - "versions": [ - { - "name": "7.0.0", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "6.0.1", - "branch": "v6", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "7.0.0", - "6.0.1" - ], - "api": true, - "isPlugin": true, - "7.0.0": { - "menu": "- [Usage](#usage)", - "api": "

    Scooter uses the [useragent] package to provide user-agent information. For\nmore details of what information scooter provides, please see the useragent.

    \n

    Usage

    \n
    const Hapi = require('@hapi/hapi');\nconst Scooter = require('@hapi/scooter');\n\nconst start = async () => {\n\n    const server = new Hapi.Server();\n\n    server.route({\n        method: 'GET',\n        path: '/user-agent',\n        handler: (request, h) => {\n\n            return request.plugins.scooter;\n        }\n    });\n\n    await server.register(Scooter);\n    await server.start();\n    console.log(server.info.uri + '/user-agent');\n};\n\nstart();
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "6.0.1": { - "menu": "- [Usage](#usage)", - "api": "

    Scooter uses the [useragent] package to provide user-agent information. For\nmore details of what information scooter provides, please see the useragent.

    \n

    Usage

    \n
    const Hapi = require('@hapi/hapi');\nconst Scooter = require('@hapi/scooter');\n\nconst start = async () => {\n\n    const server = new Hapi.Server();\n\n    server.route({\n        method: 'GET',\n        path: '/user-agent',\n        handler: (request, h) => {\n\n            return request.plugins.scooter;\n        }\n    });\n\n    await server.register(Scooter);\n    await server.start();\n    console.log(server.info.uri + '/user-agent');\n};\n\nstart();
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "User-agent information plugin.", - "forks": 23, - "stars": 46, - "date": "2023-11-11T10:34:45Z", - "updated": "Sat Nov 11 2023", - "link": "https://github.com/hapijs/scooter" - }, - "shot": { - "name": "shot", - "versions": [ - { - "name": "6.0.1", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "6.0.1" - ], - "api": true, - "isPlugin": false, - "6.0.1": { - "menu": "- [Methods](#methods)\n - [`await Shot.inject()`](#await-shotinjectdispatchfunc-options)\n - [`Shot.isInjection()`](#shotisinjectionobj)", - "api": "

    Methods

    \n

    await Shot.inject(dispatchFunc, options)

    \n

    Injects a fake request into an HTTP server.

    \n
      \n
    • \ndispatchFunc - listener function. The same as you would pass to Http.createServer when making a node HTTP server. Has the signature function (req, res) where:\n
        \n
      • \nreq - a simulated request object. Inherits from Stream.Readable.
      • \n
      • \nres - a simulated response object. Inherits from node's Http.ServerResponse.
      • \n
      \n
    • \n
    • \noptions - request options object where:\n
        \n
      • \nurl - a string specifying the request URL.
      • \n
      • \nmethod - a string specifying the HTTP request method, defaulting to 'GET'.
      • \n
      • \nauthority - a string specifying the HTTP HOST header value to be used if no header is provided, and the url\ndoes not include an authority component. Defaults to 'localhost'.
      • \n
      • \nheaders - an optional object containing request headers.
      • \n
      • \nremoteAddress - an optional string specifying the client remote address. Defaults to '127.0.0.1'.
      • \n
      • \npayload - an optional request payload. Can be a string, Buffer, Stream or object.
      • \n
      • \nsimulate - an object containing flags to simulate various conditions:\n
          \n
        • \nend - indicates whether the request will fire an end event. Defaults to undefined, meaning an end event will fire.
        • \n
        • \nsplit - indicates whether the request payload will be split into chunks. Defaults to undefined, meaning payload will not be chunked.
        • \n
        • \nerror - whether the request will emit an error event. Defaults to undefined, meaning no error event will be emitted. If set to true, the emitted error will have a message of 'Simulated'.
        • \n
        • \nclose - whether the request will emit a close event. Defaults to undefined, meaning no close event will be emitted.
        • \n
        \n
      • \n
      • \nvalidate - Optional flag to validate this options object. Defaults to true.
      • \n
      \n
    • \n
    \n

    Returns a response object where:

    \n
      \n
    • \nraw - an object containing the raw request and response objects where:\n
        \n
      • \nreq - the simulated request object.
      • \n
      • \nres - the simulated response object.
      • \n
      \n
    • \n
    • \nheaders - an object containing the response headers.
    • \n
    • \nstatusCode - the HTTP status code.
    • \n
    • \nstatusMessage - the HTTP status message.
    • \n
    • \npayload - the payload as a UTF-8 encoded string.
    • \n
    • \nrawPayload - the raw payload as a Buffer.
    • \n
    • \ntrailers - an object containing the response trailers.
    • \n
    \n

    Shot.isInjection(obj)

    \n

    Checks if given object obj is a Shot Request object.

    \n", - "intro": "## Introduction\n\nInjects a fake HTTP request/response into a node HTTP server for simulating server logic, writing tests, or debugging. Does not use a socket\nconnection so can be run against an inactive server (server not in listen mode).\n", - "example": "## Example\n\n```javascript\nconst Http = require('http');\nconst Shot = require('@hapi/shot');\n\n\nconst internals = {};\n\n\ninternals.main = async function () {\n\n const dispatch = function (req, res) {\n\n const reply = 'Hello World';\n res.writeHead(200, { 'Content-Type': 'text/plain', 'Content-Length': reply.length });\n res.end(reply);\n };\n\n const server = Http.createServer(dispatch);\n\n const res = await Shot.inject(dispatch, { method: 'get', url: '/' });\n console.log(res.payload);\n};\n\n\ninternals.main();\n```\n\nNote how `server.listen` is never called.\n", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Injects a fake HTTP request/response into your node server logic.", - "forks": 42, - "stars": 198, - "date": "2024-10-23T15:02:09Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/shot" - }, - "somever": { - "name": "somever", - "versions": [ - { - "name": "4.1.1", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "3.0.1", - "branch": "v3", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "4.1.1", - "3.0.1" - ], - "api": false, - "isPlugin": false, - "4.1.1": { - "menu": "", - "api": "", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "3.0.1": { - "menu": "", - "api": "", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Semantic versioning rules parser, compatible with version ranges used in package.json files and the canonical [semver](https://www.npmjs.com/package/semver) module.", - "forks": 10, - "stars": 0, - "date": "2024-10-23T14:45:10Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/somever" - }, - "statehood": { - "name": "statehood", - "versions": [ - { - "name": "8.1.1", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "7.0.4", - "branch": "v7", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "8.1.1", - "7.0.4" - ], - "api": false, - "isPlugin": false, - "8.1.1": { - "menu": "", - "api": "", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "7.0.4": { - "menu": "", - "api": "", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "HTTP State Management Utilities.", - "forks": 26, - "stars": 20, - "date": "2024-10-23T14:46:14Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/statehood" - }, - "subtext": { - "name": "subtext", - "versions": [ - { - "name": "8.1.0", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "7.1.0", - "branch": "v7", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "8.1.0", - "7.1.0" - ], - "api": true, - "isPlugin": false, - "8.1.0": { - "menu": "- [Methods](#methods)\n - [`Subtext.parse()`](#subtextparserequest-tap-options)", - "api": "

    Methods

    \n

    Subtext.parse(request, tap, options)

    \n

    Parses the request body and returns it in a promise.

    \n

    options are the following:

    \n
      \n
    • \nparse: (required) boolean
    • \n
    • \noutput: (required) 'data', 'stream', 'file'
    • \n
    • \nmaxBytes: int
    • \n
    • \nmaxParts: int
    • \n
    • \noverride: string
    • \n
    • \ndefaultContentType: string
    • \n
    • \nallow: string, only allow a certain media type
    • \n
    • \ntimeout: integer, limit time spent buffering request
    • \n
    • \nqs: object, to pass into the qs module
    • \n
    • \nuploads: string, directory for file uploads
    • \n
    • \ndecoders: an object mapping content-encoding names to their corresponding decoder functions
    • \n
    • \ncompression: an object mapping content-encoding names to their corresponding options passed to the decoders functions
    • \n
    \n

    returns the following:

    \n
      \n
    • \npayload: the parsed payload, or null if no payload
    • \n
    • \nmime: the content type of the request
    • \n
    \n", - "intro": "## Introduction\n\n`subtext` parses the request body and returns it in a promise.\n", - "example": "## Example\n\n```javascript\nconst Http = require('http');\nconst Subtext = require('@hapi/subtext');\n\nHttp.createServer(async (request, response) => {\n\n const { payload, mime } = await Subtext.parse(request, null, { parse: true, output: 'data' });\n\n response.writeHead(200, { 'Content-Type': 'text/plain' });\n response.end(`Payload contains: ${JSON.stringify(payload)}`);\n\n}).listen(1337, '127.0.0.1');\n\nconsole.log('Server running at http://127.0.0.1:1337/');\n\n```\n", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "7.1.0": { - "menu": "- [Introduction](#introduction)\n- [Example](#example)\n- [Methods](#methods)\n - [`Subtext.parse()`](#subtextparserequest-tap-options)", - "api": "

    Introduction

    \n

    subtext parses the request body and returns it in a promise.

    \n

    Example

    \n
    const Http = require('http');\nconst Subtext = require('@hapi/subtext');\n\nHttp.createServer(async (request, response) => {\n\n  const { payload, mime } = await Subtext.parse(request, null, { parse: true, output: 'data' });\n\n  response.writeHead(200, { 'Content-Type': 'text/plain' });\n  response.end(`Payload contains: ${JSON.stringify(payload)}`);\n\n}).listen(1337, '127.0.0.1');\n\nconsole.log('Server running at http://127.0.0.1:1337/');
    \n

    Methods

    \n

    Subtext.parse(request, tap, options)

    \n

    Parses the request body and returns it in a promise.

    \n

    options are the following:

    \n
      \n
    • \nparse: (required) boolean
    • \n
    • \noutput: (required) 'data', 'stream', 'file'
    • \n
    • \nmaxBytes: int
    • \n
    • \nmaxParts: int
    • \n
    • \noverride: string
    • \n
    • \ndefaultContentType: string
    • \n
    • \nallow: string, only allow a certain media type
    • \n
    • \ntimeout: integer, limit time spent buffering request
    • \n
    • \nqs: object, to pass into the qs module
    • \n
    • \nuploads: string, directory for file uploads
    • \n
    • \ndecoders: an object mapping content-encoding names to their corresponding decoder functions
    • \n
    • \ncompression: an object mapping content-encoding names to their corresponding options passed to the decoders functions
    • \n
    \n

    returns the following:

    \n
      \n
    • \npayload: the parsed payload, or null if no payload
    • \n
    • \nmime: the content type of the request
    • \n
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "HTTP payload parser.", - "forks": 25, - "stars": 24, - "date": "2024-10-23T15:43:42Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/subtext" - }, - "teamwork": { - "name": "teamwork", - "versions": [ - { - "name": "6.0.0", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "5.1.1", - "branch": "v5", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "6.0.0", - "5.1.1" - ], - "api": false, - "isPlugin": false, - "6.0.0": { - "menu": "", - "api": "", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "5.1.1": { - "menu": "", - "api": "", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Wait for multiple callbacks", - "forks": 13, - "stars": 14, - "date": "2024-10-23T14:37:54Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/teamwork" - }, - "topo": { - "name": "topo", - "versions": [ - { - "name": "6.0.2", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "5.1.0", - "branch": "v5", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "6.0.2", - "5.1.0" - ], - "api": true, - "isPlugin": false, - "6.0.2": { - "menu": "- [Methods](#methods)\n - [`new Sorter()`](#new-sorter)\n - [`sorter.add()`](#sorteraddnodes-options)\n - [`sorter.nodes`](#sorternodes)\n - [`sorter.merge()`](#sortermergeothers)\n - [`sorter.sort()`](#sortersort)", - "api": "

    Methods

    \n

    new Sorter()

    \n

    Creates a new Sorter object.

    \n

    sorter.add(nodes, [options])

    \n

    Specifies an additional node or list of nodes to be topologically sorted where:

    \n
      \n
    • \nnodes - a mixed value or array of mixed values to be added as nodes to the topologically sorted list.
    • \n
    • \noptions - optional sorting information about the nodes:\n
        \n
      • \ngroup - a string naming the group to which nodes should be assigned. The group name '?' is reserved.
      • \n
      • \nbefore - a string or array of strings specifying the groups that nodes must precede in the topological sort.
      • \n
      • \nafter - a string or array of strings specifying the groups that nodes must succeed in the topological sort.
      • \n
      • \nsort - a numerical value used to sort items when performing a sorter.merge().
      • \n
      • \nmanual - if true, the array is not sorted automatically and sorter.sort() must be called when done adding items.
      • \n
      \n
    • \n
    \n

    Returns an array of the topologically sorted nodes (unless manual is used in which case the array is left unchanged).

    \n

    sorter.nodes

    \n

    An array of the topologically sorted nodes. This list is renewed upon each call to sorter.add() unless\nmanual is used.

    \n

    sorter.merge(others)

    \n

    Merges another Sorter object into the current object where:

    \n
      \n
    • \nothers - the other object or array of objects to be merged into the current one. null\nvalues are ignored.
    • \n
    \n

    Returns an array of the topologically sorted nodes. Will throw if a dependency error is found as a result of the\ncombined items.

    \n

    If the order in which items have been added to each list matters, use the sort option in sorter.add() with an incrementing\nvalue providing an absolute sort order among all items added to either object.

    \n

    sorter.sort()

    \n

    Sorts the array. Only needed if the manual option is used when add() is called.

    \n

    Returns an array of the topologically sorted nodes. Will throw if a dependency error is found.

    \n", - "intro": "## Introduction\n\nThe `Topo` object is the container for topologically sorting a list of nodes with non-circular interdependencies.\n", - "example": "## Example\n\n```js\nconst Topo = require('@hapi/topo');\n\nconst morning = new Topo.Sorter();\n\nmorning.add('Nap', { after: ['breakfast', 'prep'] });\n\nmorning.add([\n 'Make toast',\n 'Pour juice'\n], { before: 'breakfast', group: 'prep' });\n\nmorning.add('Eat breakfast', { group: 'breakfast' });\n\nmorning.nodes; // ['Make toast', 'Pour juice', 'Eat breakfast', 'Nap']\n```\n", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "5.1.0": { - "menu": "- [Example](#example)\n- [Methods](#methods)\n - [`new Sorter()`](#new-sorter)\n - [`sorter.add()`](#sorteraddnodes-options)\n - [`sorter.nodes`](#sorternodes)\n - [`sorter.merge()`](#sortermergeothers)\n - [`sorter.sort()`](#sortersort)", - "api": "

    Introduction

    \n

    The Topo object is the container for topologically sorting a list of nodes with non-circular interdependencies.

    \n

    Example

    \n
    const Topo = require('@hapi/topo');\n\nconst morning = new Topo.Sorter();\n\nmorning.add('Nap', { after: ['breakfast', 'prep'] });\n\nmorning.add([\n    'Make toast',\n    'Pour juice'\n], { before: 'breakfast', group: 'prep' });\n\nmorning.add('Eat breakfast', { group: 'breakfast' });\n\nmorning.nodes;        // ['Make toast', 'Pour juice', 'Eat breakfast', 'Nap']
    \n

    Methods

    \n

    new Sorter()

    \n

    Creates a new Sorter object.

    \n

    sorter.add(nodes, [options])

    \n

    Specifies an additional node or list of nodes to be topologically sorted where:

    \n
      \n
    • \nnodes - a mixed value or array of mixed values to be added as nodes to the topologically sorted list.
    • \n
    • \noptions - optional sorting information about the nodes:\n
        \n
      • \ngroup - a string naming the group to which nodes should be assigned. The group name '?' is reserved.
      • \n
      • \nbefore - a string or array of strings specifying the groups that nodes must precede in the topological sort.
      • \n
      • \nafter - a string or array of strings specifying the groups that nodes must succeed in the topological sort.
      • \n
      • \nsort - a numerical value used to sort items when performing a sorter.merge().
      • \n
      • \nmanual - if true, the array is not sorted automatically and sorter.sort() must be called when done adding items.
      • \n
      \n
    • \n
    \n

    Returns an array of the topologically sorted nodes (unless manual is used in which case the array is left unchanged).

    \n

    sorter.nodes

    \n

    An array of the topologically sorted nodes. This list is renewed upon each call to sorter.add() unless\nmanual is used.

    \n

    sorter.merge(others)

    \n

    Merges another Sorter object into the current object where:

    \n
      \n
    • \nothers - the other object or array of objects to be merged into the current one. null\nvalues are ignored.
    • \n
    \n

    Returns an array of the topologically sorted nodes. Will throw if a dependency error is found as a result of the\ncombined items.

    \n

    If the order in which items have been added to each list matters, use the sort option in sorter.add() with an incrementing\nvalue providing an absolute sort order among all items added to either object.

    \n

    sorter.sort()

    \n

    Sorts the array. Only needed if the manual option is used when add() is called.

    \n

    Returns an array of the topologically sorted nodes. Will throw if a dependency error is found.

    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Topological sorting with grouping support.", - "forks": 26, - "stars": 108, - "date": "2024-10-23T15:22:31Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/topo" - }, - "vise": { - "name": "vise", - "versions": [ - { - "name": "5.0.1", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "4.0.0", - "branch": "v4", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "5.0.1", - "4.0.0" - ], - "api": false, - "isPlugin": false, - "5.0.1": { - "menu": "", - "api": "", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "4.0.0": { - "menu": "", - "api": "", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Treat multiple buffers as one.", - "forks": 13, - "stars": 7, - "date": "2024-10-23T15:41:23Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/vise" - }, - "vision": { - "name": "vision", - "versions": [ - { - "name": "7.0.3", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "6.1.0", - "branch": "v6", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "7.0.3", - "6.1.0" - ], - "api": true, - "isPlugin": true, - "7.0.3": { - "menu": " - [EJS](#ejs)\n - [Handlebars](#handlebars)\n - [Pug](#pug)\n - [Marko](#marko)\n - [Mustache](#mustache)\n - [Nunjucks](#nunjucks)\n - [Twig](#twig)\n - [Eta](#eta)\n- [Registration](#registration)\n- [Views Manager](#views-manager)\n- [`options`](#options)\n- [`manager.registerHelper()`](#managerregisterhelpername-helper)\n- [`manager.render()`](#managerrendertemplate-context-options-callback)\n- [`manager.getEngine()`](#managergetengineext)\n- [`manager.clearCache()`](#managerclearcachetemplate-engine)\n- [Server](#server)\n - [`server.views()`](#serverviewsoptions)\n - [`server.render()`](#serverrendertemplate-context-options-callback)\n - [`server.getViewsManager()`](#servergetviewsmanager)\n- [Requests](#requests)\n - [`request.render()`](#requestrendertemplate-context-options-callback)\n - [`request.getViewsManager()`](#requestgetviewsmanager)\n- [The view handler](#the-view-handler)\n- [Response Toolkit Interface](#response-toolkit-interface)\n - [`h.view()`](#hviewtemplate-context-options)\n - [`h.getViewsManager()`](#hgetviewsmanager)\n - [Ex template used in these docs](#ex-template-used-in-these-docs)\n- [Typescript](#typescript)", - "api": "

    EJS

    \n
    const Ejs = require('ejs');\nconst Hapi = require('@hapi/hapi');\nconst Vision = require('@hapi/vision');\n\nconst server = Hapi.Server({ port: 3000 });\n\nconst rootHandler = (request, h) => {\n\n    return h.view('index', {\n        title: 'examples/ejs/templates/basic | Hapi ' + request.server.version,\n        message: 'Hello Ejs!'\n    });\n};\n\nconst provision = async () => {\n\n    await server.register(Vision);\n\n    server.views({\n        engines: { ejs: Ejs },\n        relativeTo: __dirname,\n        path: 'examples/ejs/templates/basic'\n    });\n\n    server.route({ method: 'GET', path: '/', handler: rootHandler });\n\n    await server.start();\n    console.log('Server running at:', server.info.uri);\n};\n\nprovision();
    \n

    Handlebars

    \n
    const Handlebars = require('handlebars');\nconst Hapi = require('@hapi/hapi');\nconst Vision = require('@hapi/vision');\n\nconst server = Hapi.Server({ port: 3000 });\n\nconst rootHandler = (request, h) => {\n\n    return h.view('index', {\n        title: 'examples/handlebars/templates/basic | hapi ' + request.server.version,\n        message: 'Hello Handlebars!'\n    });\n};\n\nconst provision = async () => {\n\n    await server.register(Vision);\n\n    server.views({\n        engines: { html: Handlebars },\n        relativeTo: __dirname,\n        path: 'examples/handlebars/templates/basic'\n    });\n\n    server.route({ method: 'GET', path: '/', handler: rootHandler });\n\n    await server.start();\n    console.log('Server running at:', server.info.uri);\n};\n\nprovision();
    \n

    Pug

    \n
    const Path = require('path');\n\nconst Hapi = require('@hapi/hapi');\nconst Pug = require('pug');\nconst Vision = require('@hapi/vision');\n\nconst server = Hapi.Server({ port: 3000 });\n\nconst rootHandler = (request, h) => {\n\n    return h.view('index', {\n        title: 'examples/pug/templates | Hapi ' + request.server.version,\n        message: 'Hello Pug!'\n    });\n};\n\nconst provision = async () => {\n\n    await server.register(Vision);\n\n    server.views({\n        engines: { pug: Pug },\n        relativeTo: __dirname,\n        path: 'examples/pug/templates',\n        compileOptions: {\n            // By default Pug uses relative paths (e.g. ../root.pug), when using absolute paths (e.g. include /root.pug), basedir is prepended.\n            // https://pugjs.org/language/includes.html\n            basedir: Path.join(__dirname, 'examples/pug/templates')\n        }\n    });\n\n    server.route({ method: 'GET', path: '/', handler: rootHandler });\n\n    await server.start();\n    console.log('Server running at:', server.info.uri);\n};\n\nprovision();
    \n

    Marko

    \n
    const Hapi = require('@hapi/hapi');\nconst Marko = require('marko');\nconst Vision = require('@hapi/vision');\n\nconst server = Hapi.Server({ port: 3000 });\n\nconst rootHandler = (request, h) => {\n\n    return h.view('index', {\n        title: 'examples/marko/templates | Hapi ' + request.server.version,\n        message: 'Hello Marko!'\n    });\n};\n\nconst provision = async () => {\n\n    await server.register(Vision);\n\n    server.views({\n        engines: {\n            marko: {\n                compile: (src, options) => {\n\n                    const opts = { preserveWhitespace: true, writeToDisk: false };\n\n                    const template = Marko.load(options.filename, opts);\n\n                    return (context) => {\n\n                        return template.renderToString(context);\n                    };\n                }\n            }\n        },\n        relativeTo: __dirname,\n        path: 'examples/marko/templates'\n    });\n\n    server.route({ method: 'GET', path: '/', handler: rootHandler });\n\n    await server.start();\n    console.log('Server running at:', server.info.uri);\n};\n\nprovision();
    \n

    Mustache

    \n
    const Hapi = require('@hapi/hapi');\nconst Mustache = require('mustache');\nconst Vision = require('@hapi/vision');\n\nconst server = Hapi.Server({ port: 3000 });\n\nconst rootHandler = (request, h) => {\n\n    return h.view('index', {\n        title: 'examples/mustache/templates/basic | Hapi ' + request.server.version,\n        message: 'Hello Mustache!'\n    });\n};\n\nconst provision = async () => {\n\n    await server.register(Vision);\n\n    server.views({\n        engines: {\n            html: {\n                compile: (template) => {\n\n                    Mustache.parse(template);\n\n                    return (context) => {\n\n                        return Mustache.render(template, context);\n                    };\n                }\n            }\n        },\n        relativeTo: __dirname,\n        path: 'examples/mustache/templates/basic'\n    });\n\n    server.route({ method: 'GET', path: '/', handler: rootHandler });\n\n    await server.start();\n    console.log('Server running at:', server.info.uri);\n};\n\nprovision();
    \n

    Nunjucks

    \n
    const Hapi = require('@hapi/hapi');\nconst Nunjucks = require('nunjucks');\nconst Vision = require('@hapi/vision');\n\nconst server = Hapi.Server({ port: 3000 });\n\nconst rootHandler = (request, h) => {\n\n    return h.view('index', {\n        title: 'examples/nunjucks/templates | Hapi ' + request.server.version,\n        message: 'Hello Nunjucks!'\n    });\n};\n\nconst provision = async () => {\n\n    await server.register(Vision);\n\n    server.views({\n        engines: {\n            html: {\n                compile: (src, options) => {\n\n                    const template = Nunjucks.compile(src, options.environment);\n\n                    return (context) => {\n\n                        return template.render(context);\n                    };\n                },\n\n                prepare: (options, next) => {\n\n                    options.compileOptions.environment = Nunjucks.configure(options.path, { watch : false });\n\n                    return next();\n                }\n            }\n        },\n        relativeTo: __dirname,\n        path: 'examples/nunjucks/templates'\n    });\n\n    server.route({ method: 'GET', path: '/', handler: rootHandler });\n\n    await server.start();\n    console.log('Server running at:', server.info.uri);\n};\n\nprovision();
    \n

    Twig

    \n
    const Hapi = require('@hapi/hapi');\nconst Twig = require('twig');\nconst Vision = require('@hapi/vision');\n\nconst server = Hapi.Server({ port: 3000 });\n\nconst rootHandler = (request, h) => {\n\n    return h.view('index', {\n        title: 'examples/twig/templates | Hapi ' + request.server.version,\n        message: 'Hello Twig!'\n    });\n};\n\nconst provision = async () => {\n\n    await server.register(Vision);\n\n    server.views({\n        engines: {\n            twig: {\n                compile: (src, options) => {\n\n                    const template = Twig.twig({ id: options.filename, data: src });\n\n                    return (context) => {\n\n                        return template.render(context);\n                    };\n                }\n            }\n        },\n        relativeTo: __dirname,\n        path: 'examples/twig/templates'\n    });\n\n    server.route({ method: 'GET', path: '/', handler: rootHandler });\n\n    await server.start();\n    console.log('Server running at:', server.info.uri);\n};\n\nprovision();
    \n

    Eta

    \n
    const Hapi = require('@hapi/hapi');\nconst Eta = require('eta');\nconst Vision = require('@hapi/vision');\n\nconst server = Hapi.Server({ port: 3000 });\n\nconst rootHandler = (request, h) => {\n\n    return h.view('index', {\n        title: 'examples/eta/templates | Hapi ' + request.server.version,\n        message: 'Hello Eta!'\n    });\n};\n\nconst provision = async () => {\n\n    await server.register(Vision);\n\n    server.views({\n        engines: {\n            eta: {\n                compile: (src, options) => {\n\n                    const compiled = Eta.compile(src, options);\n\n                    return (context) => {\n\n                        return Eta.render(compiled, context);\n                    };\n                }\n            }\n        },\n        /**\n         * This is the config object that gets passed to the compile function\n         * defined above. This should contain the eta configuration object\n         * described at https://eta.js.org/docs/api/configuration Only some of\n         * the configuration are relevant when using with hapijs.\n         */\n        compileOptions: {\n            autoEscape: true,\n            tags: ['{{', '}}']\n        },\n        relativeTo: __dirname,\n        path: 'examples/eta/templates'\n    });\n\n    server.route({ method: 'GET', path: '/', handler: rootHandler });\n\n    await server.start();\n    console.log('Server running at:', server.info.uri);\n};\n\nprovision();
    \n

    Registration

    \n

    Vision can be registered multiple times and receives views manager options as registration options.

    \n

    Example:

    \n
    internals.provision = async () => {\n\n    await server.register({\n        plugin: require('@hapi/vision'),\n        options: {\n            engines: { html: require('handlebars') },\n            path: __dirname + '/templates'\n        }\n    })\n\n    const context = {\n        title: 'Registration Example',\n        message: 'Hello, World'\n    };\n\n    return server.render('hello', context);\n};\n\ninternals.provision();\n
    \n

    Views Manager

    \n

    The Views Manager is configured with registration options or by calling server.views(options)

    \n

    options

    \n
      \n
    • \n

      engines - required object where each key is a file extension (e.g. 'html', 'hbr'), mapped\nto the npm module used for rendering the templates. Alternatively, the extension can be\nmapped to an object with the following options:

      \n
        \n
      • \nmodule - the npm module used for rendering the templates. The module object must\ncontain the compile() function:\n
          \n
        • \ncompile() - the rendering function. The required function signature depends on the\ncompileMode settings (see below). If compileMode is 'sync', the signature is\ncompile(template, options), the return value is a function with signature\nfunction(context, options) (the compiled sync template), and the method is allowed to throw errors. If\ncompileMode is 'async', the signature is compile(template, options, next)\nwhere next has the signature function(err, compiled), compiled is a\nfunction with signature function(context, options, callback) (the compiled async template) and callback has the\nsignature function(err, rendered).
        • \n
        • \nprepare(config, next) - initializes additional engine state.\nThe config object is the engine configuration object allowing updates to be made.\nThis is useful for engines like Nunjucks that rely on additional state for rendering.\nnext has the signature function(err).
        • \n
        • \nregisterPartial(name, src) - registers a partial for use during template rendering.\nThe name is the partial path that templates should use to reference the partial and\nsrc is the uncompiled template string for the partial.
        • \n
        • \nregisterHelper(name, helper) - registers a helper for use during template rendering.\nThe name is the name that templates should use to reference the helper and helper\nis the function that will be invoked when the helper is called.
        • \n
        \n
      • \n
      • any of the views options listed below (except defaultExtension) to override the\ndefaults for a specific engine.
      • \n
      \n
    • \n
    • \n

      compileMode - specify whether the engine compile() method is 'sync' or 'async'.\nDefaults to 'sync'.

      \n
    • \n
    • \n

      defaultExtension - defines the default filename extension to append to template names when\nmultiple engines are configured and not explicit extension is provided for a given template.\nNo default value.

      \n
    • \n
    • \n

      path - the root file path, or array of file paths, used to resolve and load the templates identified when calling\nh.view().\nDefaults to current working directory.

      \n
    • \n
    • \n

      partialsPath - the root file path, or array of file paths, where partials are located. Partials are small segments\nof template code that can be nested and reused throughout other templates. Defaults to no\npartials support (empty path).

      \n
    • \n
    • \n

      helpersPath - the directory path, or array of directory paths, where helpers are located. Helpers are functions used\nwithin templates to perform transformations and other data manipulations using the template\ncontext or other inputs. Each valid template file in the helpers directory is loaded and the file name\nis used as the helper name. The files must export a single method with the signature\nfunction(context) and return a string. Sub-folders are not supported and are ignored.\nDefaults to no helpers support (empty path). Note that pug does not support loading helpers\nthis way.

      \n
    • \n
    • \n

      relativeTo - a base path used as prefix for path and partialsPath. No default.

      \n
    • \n
    • \n

      layout - if set to true or a layout filename, layout support is enabled. A layout is a\nsingle template file used as the parent template for other view templates in the same engine.\nIf true, the layout template name must be 'layout.ext' where 'ext' is the engine's\nextension. Otherwise, the provided filename is suffixed with the engine's extension and\nloaded. Disable layout when using Jade as it will handle including any layout files\nindependently. Defaults to false.

      \n
    • \n
    • \n

      layoutPath - the root file path, or array of file paths, where layout templates are located (using the relativeTo\nprefix if present). Defaults to path.

      \n
    • \n
    • \n

      layoutKeyword - the key used by the template engine to denote where primary template\ncontent should go. Defaults to 'content'.

      \n
    • \n
    • \n

      encoding - the text encoding used by the templates when reading the files and outputting\nthe result. Defaults to 'utf8'.

      \n
    • \n
    • \n

      isCached - if set to false, templates will not be cached (thus will be read from file on\nevery use). Defaults to true.

      \n
    • \n
    • \n

      allowAbsolutePaths - if set to true, allows absolute template paths passed to\nh.view().\nDefaults to false.

      \n
    • \n
    • \n

      allowInsecureAccess - if set to true, allows template paths passed to\nh.view()\nto contain '../'. Defaults to false.

      \n
    • \n
    • \n

      compileOptions - options object passed to the engine's compile function. Defaults to empty\noptions {}.

      \n
    • \n
    • \n

      runtimeOptions - options object passed to the returned function from the compile operation.\nDefaults to empty options {}.

      \n
    • \n
    • \n

      contentType - the content type of the engine results. Defaults to 'text/html'.

      \n
    • \n
    • \n

      context - a global context used with all templates. The global context option can be either\nan object or a function (can be async or return a promise) that takes the request\nas its only argument and returns a context object. The request object is only provided when using\nthe view handler or h.view(). When using\nserver.render() or\nrequest.render(), the request argument will be null. When rendering\nviews, the global context will be merged with any context object specified on the handler or using\nh.view(). When multiple context objects are used, values from the global\ncontext always have lowest precedence.

      \n
    • \n
    \n

    manager.registerHelper(name, helper)

    \n

    Registers a helper, on all configured engines that have a registerHelper() method, for use during template rendering. Engines without a registerHelper() method will be skipped. The name is the name that templates should use to reference the helper and helper is the function that will be invoked when the helper is called.

    \n

    manager.render(template, context, options, [callback])

    \n

    Renders a template. This is typically not needed and it is usually more convenient to use server.render().

    \n

    manager.getEngine(ext)

    \n
      \n
    • \next- The extension used when registering the engine -- check the keys used when configuring engines in views manager options\n
    • \n
    \n

    manager.clearCache(template, [engine])

    \n
      \n
    • \ntemplate - the template filename and path, relative to the views manager templates path (path\nor relativeTo).
    • \n
    • \nengine - the engine returned by manager.getEngine(ext)\n
    • \n
    \n

    Server

    \n

    server.views(options)

    \n
      \n
    • Initializes a plugin's view manager by receiving manager options\n
    • \n
    • Returns the newly created view manager for the plugin that called it.
    • \n
    \n

    server.render(template, context, [options], [callback])

    \n

    Uses the server views manager to render a template where:

    \n
      \n
    • \ntemplate - the template filename and path, relative to the views manager templates path (path\nor relativeTo).
    • \n
    • \ncontext - optional object used by the template to render context-specific result. Defaults to\nno context ({}).
    • \n
    • \noptions - optional object used to override the views manager configuration.
    • \n
    • callback - the callback function with signature function (err, rendered, config) where:\n
        \n
      • \nerr - the rendering error if any.
      • \n
      • \nrendered - the result view string.
      • \n
      • \nconfig - the configuration used to render the template.
      • \n
      \n
    • \n
    \n

    If no callback is provided, a Promise object is returned. The returned promise is resolved with only the\nrendered content and not the configuration object.

    \n
    const Hapi = require('@hapi/hapi');\nconst server = Hapi.Server({ port: 3000 });\n\nconst internals = {};\n\ninternals.provision = async () => {\n\n    await server.register(require('@hapi/vision'));\n\n    server.views({\n        engines: { html: require('handlebars') },\n        path: __dirname + '/templates'\n    });\n\n    const context = {\n        title: 'Views Example',\n        message: 'Hello, World'\n    };\n\n    return server.render('hello', context);\n};\n\ninternals.provision();
    \n

    server.getViewsManager()

    \n

    Returns the closest Views manager to your realm (either on your realm or inherited from an ancestor realm)

    \n

    Requests

    \n

    request.render(template, context, [options], [callback])

    \n

    request.render() works the same way as server.render()\nbut is for use inside of request handlers. server.render()\ndoes not work inside request handlers when called via request.server.render() if the view manager was created\nby a plugin. This is because the request.server object does not have access to the plugin realm where the\nview manager was configured. request.render() gets its realm from the route that the request was bound to.

    \n

    Note that this will not work in onRequest extensions added by the plugin because the route isn't yet set at\nthis point in the request lifecycle and the request.render() method will produce the same limited results\nserver.render() can. When using the onRequest extension, use the h response toolkit interface instead.

    \n
    const Hapi = require('@hapi/hapi');\nconst server = Hapi.Server({ port: 3000 });\n\nconst internals = {};\n\ninternals.provision = async () => {\n\n    await server.register(require('@hapi/vision'));\n\n    server.views({\n        engines: { html: require('handlebars') },\n        path: __dirname + '/templates'\n    });\n\n    server.route({\n        method: 'GET',\n        path: '/view',\n        handler: function (request, h) {\n\n            return request.render('test', { message: 'hello' });\n        }\n    });\n};\n\ninternals.provision();
    \n

    request.getViewsManager()

    \n

    Returns the closest Views manager to your realm (either on your realm or inherited from an ancestor realm)

    \n

    The view handler

    \n

    The view handler can be used with routes registered in the same realm as the view manager. The\nhandler takes an options parameter that can be either a string or an object. When the options\nparameter is a string, it should be the filename and path of the template relative to the templates\npath configured via the views manager. When the options parameter is an object, it may have the\nfollowing keys:

    \n
      \n
    • \ntemplate - the template filename and path, relative to the templates path configured via the\nserver views manager.
    • \n
    • \ncontext - optional object used by the template to render context-specific result. Defaults to\nno context {}.
    • \n
    • \noptions - optional object used to override the server's views manager configuration for this\nresponse. Cannot override isCached, partialsPath, or helpersPath which are only loaded at\ninitialization.
    • \n
    \n

    The rendering context contains the params, payload, query, and pre values from the\nrequest by default (these\ncan be overriden by values explicitly set via the options).

    \n
    const Hapi = require('@hapi/hapi');\nconst server = Hapi.Server({ port: 3000 });\n\nconst internals = {};\n\ninternals.provision = async () => {\n\n    await server.register(require('@hapi/vision'));\n\n    server.views({\n        engines: { html: require('handlebars') },\n        path: __dirname + '/templates'\n    });\n\n    server.route({\n        method: 'GET',\n        path: '/',\n        handler: {\n            view: {\n                template: 'hello',\n                context: {\n                    title: 'Views Example',\n                    message: 'Hello, World'\n                }\n            }\n        }\n    });\n};\n\ninternals.provision();
    \n

    Response Toolkit Interface

    \n

    h.view(template, [context, [options]])

    \n

    Uses the response toolkit interface by means of returning control over to the router with a templatized view\nresponse where:

    \n
      \n
    • \ntemplate - the template filename and path, relative to the templates path configured via the\nserver views manager.
    • \n
    • \ncontext - optional object used by the template to render context-specific result. Defaults to\nno context {}.
    • \n
    • \noptions - optional object used to override the server's views manager configuration for this\nresponse. Cannot override isCached, partialsPath, or helpersPath which are only loaded at\ninitialization.
    • \n
    \n

    Returns a response object.\nThe generated response will have the variety property set to view.

    \n

    The same lifecycle workflow applies.

    \n
    const Hapi = require('@hapi/hapi');\nconst server = Hapi.Server({ port: 3000 });\n\nconst internals = {};\n\ninternals.provision = async () => {\n\n    await server.register(require('@hapi/vision'));\n\n    server.views({\n        engines: { html: require('handlebars') },\n        path: __dirname + '/templates'\n    });\n\n    const rootHandler = function (request, h) {\n\n        const context = {\n            title: 'Views Example',\n            message: 'Hello, World'\n        };\n\n        return h.view('hello', context);\n    };\n\n    server.route({ method: 'GET', path: '/', handler: rootHandler });\n};\n\ninternals.provision();
    \n

    h.getViewsManager()

    \n

    Returns the closest Views manager to your realm (either on your realm or inherited from an ancestor realm)

    \n

    Ex template used in these docs

    \n

    templates/hello.html

    \n
    <html>\n    <head>\n        <title>{{title}}</title>\n    </head>\n    <body>\n        <div>\n            <h1>{{message}}</h1>\n        </div>\n    </body>\n</html>
    \n

    Typescript

    \n

    If you'd like to type out the way Vision is used, you can do so with the following interfaces:

    \n
    declare module '@hapi/vision' {\n\n    // User defined\n    type CustomTemplates = (\n        'test' | 'hello' | 'temp1'\n    );\n\n    // User defined\n    type CustomLayout = (\n        'auth' | 'unauth' | 'admin'\n    )\n\n    interface ViewTypes {\n        template: CustomTemplates\n        layout: CustomLayout\n    }\n}
    \n

    You should now get typings on your response handler (only), and anywhere where layouts is an option

    \n
    const route = {\n    ...\n    handler: {\n        view: {\n            template: 'test', // should autocomplete\n            options: { layout: 'auth' } // should autocomplete\n        }\n    }\n}
    \n

    If you'd like to also type check the decorated handlers, you can augment the following interfaces:

    \n
    declare module '@hapi/vision' {\n\n    // User defined\n    type CustomTemplates = (\n        'test' | 'hello' | 'temp1'\n    );\n\n    // User defined\n    type CustomLayout = (\n        'auth' | 'unauth' | 'admin'\n    )\n\n    // server.render(...)\n    interface RenderMethod {\n        (template: CustomTemplates, context?: string): Promise<string>\n    }\n\n    // { handler: (req) => req.render(...) }\n    interface RequestRenderMethod {\n        (template: CustomTemplates, context?: string): Promise<string>\n    }\n\n    // { handler: (req, h) => h.view(...) }\n    interface ToolkitRenderMethod {\n        (template: CustomTemplates, context?: string): ResponseObject\n    }\n\n}
    \n

    This is useful for when you may want to make strict checks against template / context combinations:

    \n
        // { handler: (req, h) => h.view(...) }\n    interface ToolkitRenderMethod {\n        (template: 'test', context: { apples: 5 }): ResponseObject\n        (template: 'hello', context: { oranges: true }): ResponseObject\n        (template: 'temp1', context: { bananas: 'green' }): ResponseObject\n    }
    \n", - "intro": "## Introduction\n\n**vision** decorates the [server](https://hapi.dev/api#server),\n[request](https://hapi.dev/api#request), and\n`h` response [toolkit](https://hapi.dev/api#response-toolkit) interfaces with additional\nmethods for managing view engines that can be used to render templated responses.\n\n**vision** also provides a built-in [handler](https://hapi.dev/api#-serverdecoratetype-property-method-options) implementation for creating templated responses.\n\nMost interaction with **vision** is done via the `h` [response toolkit](https://hapi.dev/api#response-toolkit)\nand [server](https://hapi.dev/api#server) interfaces.\n", - "example": "## Example\n\n```js\nconst Hapi = require('@hapi/hapi');\nconst Vision = require('@hapi/vision');\n\nconst server = Hapi.Server({ port: 3000 });\n\nconst provision = async () => {\n\n await server.register(Vision);\n await server.start();\n\n console.log('Server running at:', server.info.uri);\n};\n\nprovision();\n```\n\nThe examples in the `examples` folder can be run with `node`.\n\n```\ngit clone https://github.com/hapijs/vision.git && cd vision\nnpm install\n\nnode examples/handlebars\n```\n\n:point_up: That command will run the handlebars basic template.\nThere are three more examples in there: for helpers, layout, and partials.\n\nUse this hierarchy to know which commands to run, e.g.\n```\nnode examples/mustache\nnode examples/mustache/partials\nnode examples/jsx\n```\n\n```\n- cms // A bare-bones Content Management System with a WYSIWYG editor\n- ejs\n - layout\n- handlebars\n - helpers\n - layout\n - partials\n- jsx // React server-side rendering with `hapi-react-views`\n- marko\n- mixed // Using multiple render engines (handlebars and pug)\n- mustache\n - layout\n - partials\n- nunjucks\n- pug\n- twig\n```\n\n**vision** is compatible with most major templating engines out of the box. Engines that don't follow\nthe normal API pattern can still be used by mapping their API to the [**vision** API](https://hapi.dev/family/vision/). Some of the examples below use the `compile` and `prepare` methods which are part of the API.\n", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "6.1.0": { - "menu": "- [Introduction](#introduction)\n- [Example](#example)\n - [EJS](#ejs)\n - [Handlebars](#handlebars)\n - [Pug](#pug)\n - [Marko](#marko)\n - [Mustache](#mustache)\n - [Nunjucks](#nunjucks)\n - [Twig](#twig)\n- [Registration](#registration)\n- [Views Manager](#views-manager)\n- [`options`](#options)\n- [`manager.registerHelper()`](#managerregisterhelpername-helper)\n- [`manager.render()`](#managerrendertemplate-context-options-callback)\n- [`manager.getEngine()`](#managergetengineext)\n- [`manager.clearCache()`](#managerclearcachetemplate-engine)\n- [Server](#server)\n - [`server.views()`](#serverviewsoptions)\n - [`server.render()`](#serverrendertemplate-context-options-callback)\n - [`server.getViewsManager()`](#servergetviewsmanager)\n- [Requests](#requests)\n - [`request.render()`](#requestrendertemplate-context-options-callback)\n - [`request.getViewsManager()`](#requestgetviewsmanager)\n- [The view handler](#the-view-handler)\n- [Response Toolkit Interface](#response-toolkit-interface)\n - [`h.view()`](#hviewtemplate-context-options)\n - [`h.getViewsManager()`](#hgetviewsmanager)\n - [Ex template used in these docs](#ex-template-used-in-these-docs)", - "api": "

    Introduction

    \n

    vision decorates the server,\nrequest, and\nh response toolkit interfaces with additional\nmethods for managing view engines that can be used to render templated responses.

    \n

    vision also provides a built-in handler implementation for creating templated responses.

    \n

    Most interaction with vision is done via the h response toolkit\nand server interfaces.

    \n

    Example

    \n
    const Hapi = require('@hapi/hapi');\nconst Vision = require('@hapi/vision');\n\nconst server = Hapi.Server({ port: 3000 });\n\nconst provision = async () => {\n\n    await server.register(Vision);\n    await server.start();\n\n    console.log('Server running at:', server.info.uri);\n};\n\nprovision();
    \n

    The examples in the examples folder can be run with node.

    \n
    git clone https://github.com/hapijs/vision.git && cd vision\nnpm install\n\nnode examples/handlebars\n
    \n

    ☝️ That command will run the handlebars basic template.\nThere are three more examples in there: for helpers, layout, and partials.

    \n

    Use this hierarchy to know which commands to run, e.g.

    \n
    node examples/mustache\nnode examples/mustache/partials\nnode examples/jsx\n
    \n
    - cms // A bare-bones Content Management System with a WYSIWYG editor\n- ejs\n  - layout\n- handlebars\n  - helpers\n  - layout\n  - partials\n- jsx // React server-side rendering with `hapi-react-views`\n- marko\n- mixed // Using multiple render engines (handlebars and pug)\n- mustache\n  - layout\n  - partials\n- nunjucks\n- pug\n- twig\n
    \n

    vision is compatible with most major templating engines out of the box. Engines that don't follow\nthe normal API pattern can still be used by mapping their API to the vision API. Some of the examples below use the compile and prepare methods which are part of the API.

    \n

    EJS

    \n
    const Ejs = require('ejs');\nconst Hapi = require('@hapi/hapi');\nconst Vision = require('@hapi/vision');\n\nconst server = Hapi.Server({ port: 3000 });\n\nconst rootHandler = (request, h) => {\n\n    return h.view('index', {\n        title: 'examples/ejs/templates/basic | Hapi ' + request.server.version,\n        message: 'Hello Ejs!'\n    });\n};\n\nconst provision = async () => {\n\n    await server.register(Vision);\n\n    server.views({\n        engines: { ejs: Ejs },\n        relativeTo: __dirname,\n        path: 'examples/ejs/templates/basic'\n    });\n\n    server.route({ method: 'GET', path: '/', handler: rootHandler });\n\n    await server.start();\n    console.log('Server running at:', server.info.uri);\n};\n\nprovision();
    \n

    Handlebars

    \n
    const Handlebars = require('handlebars');\nconst Hapi = require('@hapi/hapi');\nconst Vision = require('@hapi/vision');\n\nconst server = Hapi.Server({ port: 3000 });\n\nconst rootHandler = (request, h) => {\n\n    return h.view('index', {\n        title: 'examples/handlebars/templates/basic | hapi ' + request.server.version,\n        message: 'Hello Handlebars!'\n    });\n};\n\nconst provision = async () => {\n\n    await server.register(Vision);\n\n    server.views({\n        engines: { html: Handlebars },\n        relativeTo: __dirname,\n        path: 'examples/handlebars/templates/basic'\n    });\n\n    server.route({ method: 'GET', path: '/', handler: rootHandler });\n\n    await server.start();\n    console.log('Server running at:', server.info.uri);\n};\n\nprovision();
    \n

    Pug

    \n
    const Path = require('path');\n\nconst Hapi = require('@hapi/hapi');\nconst Pug = require('pug');\nconst Vision = require('@hapi/vision');\n\nconst server = Hapi.Server({ port: 3000 });\n\nconst rootHandler = (request, h) => {\n\n    return h.view('index', {\n        title: 'examples/pug/templates | Hapi ' + request.server.version,\n        message: 'Hello Pug!'\n    });\n};\n\nconst provision = async () => {\n\n    await server.register(Vision);\n\n    server.views({\n        engines: { pug: Pug },\n        relativeTo: __dirname,\n        path: 'examples/pug/templates',\n        compileOptions: {\n            // By default Pug uses relative paths (e.g. ../root.pug), when using absolute paths (e.g. include /root.pug), basedir is prepended.\n            // https://pugjs.org/language/includes.html\n            basedir: Path.join(__dirname, 'examples/pug/templates')\n        }\n    });\n\n    server.route({ method: 'GET', path: '/', handler: rootHandler });\n\n    await server.start();\n    console.log('Server running at:', server.info.uri);\n};\n\nprovision();
    \n

    Marko

    \n
    const Hapi = require('@hapi/hapi');\nconst Marko = require('marko');\nconst Vision = require('@hapi/vision');\n\nconst server = Hapi.Server({ port: 3000 });\n\nconst rootHandler = (request, h) => {\n\n    return h.view('index', {\n        title: 'examples/marko/templates | Hapi ' + request.server.version,\n        message: 'Hello Marko!'\n    });\n};\n\nconst provision = async () => {\n\n    await server.register(Vision);\n\n    server.views({\n        engines: {\n            marko: {\n                compile: (src, options) => {\n\n                    const opts = { preserveWhitespace: true, writeToDisk: false };\n\n                    const template = Marko.load(options.filename, opts);\n\n                    return (context) => {\n\n                        return template.renderToString(context);\n                    };\n                }\n            }\n        },\n        relativeTo: __dirname,\n        path: 'examples/marko/templates'\n    });\n\n    server.route({ method: 'GET', path: '/', handler: rootHandler });\n\n    await server.start();\n    console.log('Server running at:', server.info.uri);\n};\n\nprovision();
    \n

    Mustache

    \n
    const Hapi = require('@hapi/hapi');\nconst Mustache = require('mustache');\nconst Vision = require('@hapi/vision');\n\nconst server = Hapi.Server({ port: 3000 });\n\nconst rootHandler = (request, h) => {\n\n    return h.view('index', {\n        title: 'examples/mustache/templates/basic | Hapi ' + request.server.version,\n        message: 'Hello Mustache!'\n    });\n};\n\nconst provision = async () => {\n\n    await server.register(Vision);\n\n    server.views({\n        engines: {\n            html: {\n                compile: (template) => {\n\n                    Mustache.parse(template);\n\n                    return (context) => {\n\n                        return Mustache.render(template, context);\n                    };\n                }\n            }\n        },\n        relativeTo: __dirname,\n        path: 'examples/mustache/templates/basic'\n    });\n\n    server.route({ method: 'GET', path: '/', handler: rootHandler });\n\n    await server.start();\n    console.log('Server running at:', server.info.uri);\n};\n\nprovision();
    \n

    Nunjucks

    \n
    const Hapi = require('@hapi/hapi');\nconst Nunjucks = require('nunjucks');\nconst Vision = require('@hapi/vision');\n\nconst server = Hapi.Server({ port: 3000 });\n\nconst rootHandler = (request, h) => {\n\n    return h.view('index', {\n        title: 'examples/nunjucks/templates | Hapi ' + request.server.version,\n        message: 'Hello Nunjucks!'\n    });\n};\n\nconst provision = async () => {\n\n    await server.register(Vision);\n\n    server.views({\n        engines: {\n            html: {\n                compile: (src, options) => {\n\n                    const template = Nunjucks.compile(src, options.environment);\n\n                    return (context) => {\n\n                        return template.render(context);\n                    };\n                },\n\n                prepare: (options, next) => {\n\n                    options.compileOptions.environment = Nunjucks.configure(options.path, { watch : false });\n\n                    return next();\n                }\n            }\n        },\n        relativeTo: __dirname,\n        path: 'examples/nunjucks/templates'\n    });\n\n    server.route({ method: 'GET', path: '/', handler: rootHandler });\n\n    await server.start();\n    console.log('Server running at:', server.info.uri);\n};\n\nprovision();
    \n

    Twig

    \n
    const Hapi = require('@hapi/hapi');\nconst Twig = require('twig');\nconst Vision = require('@hapi/vision');\n\nconst server = Hapi.Server({ port: 3000 });\n\nconst rootHandler = (request, h) => {\n\n    return h.view('index', {\n        title: 'examples/twig/templates | Hapi ' + request.server.version,\n        message: 'Hello Twig!'\n    });\n};\n\nconst provision = async () => {\n\n    await server.register(Vision);\n\n    server.views({\n        engines: {\n            twig: {\n                compile: (src, options) => {\n\n                    const template = Twig.twig({ id: options.filename, data: src });\n\n                    return (context) => {\n\n                        return template.render(context);\n                    };\n                }\n            }\n        },\n        relativeTo: __dirname,\n        path: 'examples/twig/templates'\n    });\n\n    server.route({ method: 'GET', path: '/', handler: rootHandler });\n\n    await server.start();\n    console.log('Server running at:', server.info.uri);\n};\n\nprovision();
    \n

    Registration

    \n

    Vision can be registered multiple times and receives views manager options as registration options.

    \n

    Example:

    \n
    internals.provision = async () => {\n\n    await server.register({\n        plugin: require('@hapi/vision'),\n        options: {\n            engines: { html: require('handlebars') },\n            path: __dirname + '/templates'\n        }\n    })\n\n    const context = {\n        title: 'Registration Example',\n        message: 'Hello, World'\n    };\n\n    return server.render('hello', context);\n};\n\ninternals.provision();\n
    \n

    Views Manager

    \n

    The Views Manager is configured with registration options or by calling server.views(options)

    \n

    options

    \n
      \n
    • \n

      engines - required object where each key is a file extension (e.g. 'html', 'hbr'), mapped\nto the npm module used for rendering the templates. Alternatively, the extension can be\nmapped to an object with the following options:

      \n
        \n
      • \nmodule - the npm module used for rendering the templates. The module object must\ncontain the compile() function:\n
          \n
        • \ncompile() - the rendering function. The required function signature depends on the\ncompileMode settings (see below). If compileMode is 'sync', the signature is\ncompile(template, options), the return value is a function with signature\nfunction(context, options) (the compiled sync template), and the method is allowed to throw errors. If\ncompileMode is 'async', the signature is compile(template, options, next)\nwhere next has the signature function(err, compiled), compiled is a\nfunction with signature function(context, options, callback) (the compiled async template) and callback has the\nsignature function(err, rendered).
        • \n
        • \nprepare(config, next) - initializes additional engine state.\nThe config object is the engine configuration object allowing updates to be made.\nThis is useful for engines like Nunjucks that rely on additional state for rendering.\nnext has the signature function(err).
        • \n
        • \nregisterPartial(name, src) - registers a partial for use during template rendering.\nThe name is the partial path that templates should use to reference the partial and\nsrc is the uncompiled template string for the partial.
        • \n
        • \nregisterHelper(name, helper) - registers a helper for use during template rendering.\nThe name is the name that templates should use to reference the helper and helper\nis the function that will be invoked when the helper is called.
        • \n
        \n
      • \n
      • any of the views options listed below (except defaultExtension) to override the\ndefaults for a specific engine.
      • \n
      \n
    • \n
    • \n

      compileMode - specify whether the engine compile() method is 'sync' or 'async'.\nDefaults to 'sync'.

      \n
    • \n
    • \n

      defaultExtension - defines the default filename extension to append to template names when\nmultiple engines are configured and not explicit extension is provided for a given template.\nNo default value.

      \n
    • \n
    • \n

      path - the root file path, or array of file paths, used to resolve and load the templates identified when calling\nh.view().\nDefaults to current working directory.

      \n
    • \n
    • \n

      partialsPath - the root file path, or array of file paths, where partials are located. Partials are small segments\nof template code that can be nested and reused throughout other templates. Defaults to no\npartials support (empty path).

      \n
    • \n
    • \n

      helpersPath - the directory path, or array of directory paths, where helpers are located. Helpers are functions used\nwithin templates to perform transformations and other data manipulations using the template\ncontext or other inputs. Each valid template file in the helpers directory is loaded and the file name\nis used as the helper name. The files must export a single method with the signature\nfunction(context) and return a string. Sub-folders are not supported and are ignored.\nDefaults to no helpers support (empty path). Note that pug does not support loading helpers\nthis way.

      \n
    • \n
    • \n

      relativeTo - a base path used as prefix for path and partialsPath. No default.

      \n
    • \n
    • \n

      layout - if set to true or a layout filename, layout support is enabled. A layout is a\nsingle template file used as the parent template for other view templates in the same engine.\nIf true, the layout template name must be 'layout.ext' where 'ext' is the engine's\nextension. Otherwise, the provided filename is suffixed with the engine's extension and\nloaded. Disable layout when using Jade as it will handle including any layout files\nindependently. Defaults to false.

      \n
    • \n
    • \n

      layoutPath - the root file path, or array of file paths, where layout templates are located (using the relativeTo\nprefix if present). Defaults to path.

      \n
    • \n
    • \n

      layoutKeyword - the key used by the template engine to denote where primary template\ncontent should go. Defaults to 'content'.

      \n
    • \n
    • \n

      encoding - the text encoding used by the templates when reading the files and outputting\nthe result. Defaults to 'utf8'.

      \n
    • \n
    • \n

      isCached - if set to false, templates will not be cached (thus will be read from file on\nevery use). Defaults to true.

      \n
    • \n
    • \n

      allowAbsolutePaths - if set to true, allows absolute template paths passed to\nh.view().\nDefaults to false.

      \n
    • \n
    • \n

      allowInsecureAccess - if set to true, allows template paths passed to\nh.view()\nto contain '../'. Defaults to false.

      \n
    • \n
    • \n

      compileOptions - options object passed to the engine's compile function. Defaults to empty\noptions {}.

      \n
    • \n
    • \n

      runtimeOptions - options object passed to the returned function from the compile operation.\nDefaults to empty options {}.

      \n
    • \n
    • \n

      contentType - the content type of the engine results. Defaults to 'text/html'.

      \n
    • \n
    • \n

      context - a global context used with all templates. The global context option can be either\nan object or a function (can be async or return a promise) that takes the request\nas its only argument and returns a context object. The request object is only provided when using\nthe view handler or h.view(). When using\nserver.render() or\nrequest.render(), the request argument will be null. When rendering\nviews, the global context will be merged with any context object specified on the handler or using\nh.view(). When multiple context objects are used, values from the global\ncontext always have lowest precedence.

      \n
    • \n
    \n

    manager.registerHelper(name, helper)

    \n

    Registers a helper, on all configured engines that have a registerHelper() method, for use during template rendering. Engines without a registerHelper() method will be skipped. The name is the name that templates should use to reference the helper and helper is the function that will be invoked when the helper is called.

    \n

    manager.render(template, context, options, [callback])

    \n

    Renders a template. This is typically not needed and it is usually more convenient to use server.render().

    \n

    manager.getEngine(ext)

    \n
      \n
    • \next- The extension used when registering the engine -- check the keys used when configuring engines in views manager options\n
    • \n
    \n

    manager.clearCache(template, [engine])

    \n
      \n
    • \ntemplate - the template filename and path, relative to the views manager templates path (path\nor relativeTo).
    • \n
    • \nengine - the engine returned by manager.getEngine(ext)\n
    • \n
    \n

    Server

    \n

    server.views(options)

    \n
      \n
    • Initializes a plugin's view manager by receiving manager options\n
    • \n
    • Returns the newly created view manager for the plugin that called it.
    • \n
    \n

    server.render(template, context, [options], [callback])

    \n

    Uses the server views manager to render a template where:

    \n
      \n
    • \ntemplate - the template filename and path, relative to the views manager templates path (path\nor relativeTo).
    • \n
    • \ncontext - optional object used by the template to render context-specific result. Defaults to\nno context ({}).
    • \n
    • \noptions - optional object used to override the views manager configuration.
    • \n
    • callback - the callback function with signature function (err, rendered, config) where:\n
        \n
      • \nerr - the rendering error if any.
      • \n
      • \nrendered - the result view string.
      • \n
      • \nconfig - the configuration used to render the template.
      • \n
      \n
    • \n
    \n

    If no callback is provided, a Promise object is returned. The returned promise is resolved with only the\nrendered content and not the configuration object.

    \n
    const Hapi = require('@hapi/hapi');\nconst server = Hapi.Server({ port: 3000 });\n\nconst internals = {};\n\ninternals.provision = async () => {\n\n    await server.register(require('@hapi/vision'));\n\n    server.views({\n        engines: { html: require('handlebars') },\n        path: __dirname + '/templates'\n    });\n\n    const context = {\n        title: 'Views Example',\n        message: 'Hello, World'\n    };\n\n    return server.render('hello', context);\n};\n\ninternals.provision();
    \n

    server.getViewsManager()

    \n

    Returns the closest Views manager to your realm (either on your realm or inherited from an ancestor realm)

    \n

    Requests

    \n

    request.render(template, context, [options], [callback])

    \n

    request.render() works the same way as server.render()\nbut is for use inside of request handlers. server.render()\ndoes not work inside request handlers when called via request.server.render() if the view manager was created\nby a plugin. This is because the request.server object does not have access to the plugin realm where the\nview manager was configured. request.render() gets its realm from the route that the request was bound to.

    \n

    Note that this will not work in onRequest extensions added by the plugin because the route isn't yet set at\nthis point in the request lifecycle and the request.render() method will produce the same limited results\nserver.render() can. When using the onRequest extension, use the h response toolkit interface instead.

    \n
    const Hapi = require('@hapi/hapi');\nconst server = Hapi.Server({ port: 3000 });\n\nconst internals = {};\n\ninternals.provision = async () => {\n\n    await server.register(require('@hapi/vision'));\n\n    server.views({\n        engines: { html: require('handlebars') },\n        path: __dirname + '/templates'\n    });\n\n    server.route({\n        method: 'GET',\n        path: '/view',\n        handler: function (request, h) {\n\n            return request.render('test', { message: 'hello' });\n        }\n    });\n};\n\ninternals.provision();
    \n

    request.getViewsManager()

    \n

    Returns the closest Views manager to your realm (either on your realm or inherited from an ancestor realm)

    \n

    The view handler

    \n

    The view handler can be used with routes registered in the same realm as the view manager. The\nhandler takes an options parameter that can be either a string or an object. When the options\nparameter is a string, it should be the filename and path of the template relative to the templates\npath configured via the views manager. When the options parameter is an object, it may have the\nfollowing keys:

    \n
      \n
    • \ntemplate - the template filename and path, relative to the templates path configured via the\nserver views manager.
    • \n
    • \ncontext - optional object used by the template to render context-specific result. Defaults to\nno context {}.
    • \n
    • \noptions - optional object used to override the server's views manager configuration for this\nresponse. Cannot override isCached, partialsPath, or helpersPath which are only loaded at\ninitialization.
    • \n
    \n

    The rendering context contains the params, payload, query, and pre values from the\nrequest by default (these\ncan be overriden by values explicitly set via the options).

    \n
    const Hapi = require('@hapi/hapi');\nconst server = Hapi.Server({ port: 3000 });\n\nconst internals = {};\n\ninternals.provision = async () => {\n\n    await server.register(require('@hapi/vision'));\n\n    server.views({\n        engines: { html: require('handlebars') },\n        path: __dirname + '/templates'\n    });\n\n    server.route({\n        method: 'GET',\n        path: '/',\n        handler: {\n            view: {\n                template: 'hello',\n                context: {\n                    title: 'Views Example',\n                    message: 'Hello, World'\n                }\n            }\n        }\n    });\n};\n\ninternals.provision();
    \n

    Response Toolkit Interface

    \n

    h.view(template, [context, [options]])

    \n

    Uses the response toolkit interface by means of returning control over to the router with a templatized view\nresponse where:

    \n
      \n
    • \ntemplate - the template filename and path, relative to the templates path configured via the\nserver views manager.
    • \n
    • \ncontext - optional object used by the template to render context-specific result. Defaults to\nno context {}.
    • \n
    • \noptions - optional object used to override the server's views manager configuration for this\nresponse. Cannot override isCached, partialsPath, or helpersPath which are only loaded at\ninitialization.
    • \n
    \n

    Returns a response object.\nThe generated response will have the variety property set to view.

    \n

    The same lifecycle workflow applies.

    \n
    const Hapi = require('@hapi/hapi');\nconst server = Hapi.Server({ port: 3000 });\n\nconst internals = {};\n\ninternals.provision = async () => {\n\n    await server.register(require('@hapi/vision'));\n\n    server.views({\n        engines: { html: require('handlebars') },\n        path: __dirname + '/templates'\n    });\n\n    const rootHandler = function (request, h) {\n\n        const context = {\n            title: 'Views Example',\n            message: 'Hello, World'\n        };\n\n        return h.view('hello', context);\n    };\n\n    server.route({ method: 'GET', path: '/', handler: rootHandler });\n};\n\ninternals.provision();
    \n

    h.getViewsManager()

    \n

    Returns the closest Views manager to your realm (either on your realm or inherited from an ancestor realm)

    \n

    Ex template used in these docs

    \n

    templates/hello.html

    \n
    <html>\n    <head>\n        <title>{{title}}</title>\n    </head>\n    <body>\n        <div>\n            <h1>{{message}}</h1>\n        </div>\n    </body>\n</html>
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "Template rendering support for hapi.js.", - "forks": 69, - "stars": 196, - "date": "2024-10-23T21:57:52Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/vision" - }, - "wreck": { - "name": "wreck", - "versions": [ - { - "name": "18.1.0", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "17.2.0", - "branch": "v17", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "18.1.0", - "17.2.0" - ], - "api": true, - "isPlugin": false, - "18.1.0": { - "menu": "- [`defaults()`](#defaultsoptions)\n- [`request()`](#requestmethod-uri-options)\n- [`read()`](#readresponse-options)\n - [Notes about gunzip](#notes-about-gunzip)\n- [`get()`](#geturi-options)\n- [`post()`](#posturi-options)\n- [`patch()`](#patchuri-options)\n- [`put()`](#puturi-options)\n- [`delete()`](#deleteuri-options)\n- [`toReadableStream()`](#toreadablestreampayload-encoding)\n- [`parseCacheControl()`](#parsecachecontrolfield)\n- [`agents`](#agents)\n- [Events](#events)\n - [`preRequest`](#prerequest)\n - [`request`](#request)\n - [`response`](#response)", - "api": "

    defaults(options)

    \n

    Returns a new instance of Wreck which merges the provided options with those provided on a per-request basis. You can call defaults repeatedly to build up multiple clients.

    \n
      \n
    • \noptions - Config object containing settings for both request and read operations as well as:\n
        \n
      • \nagents - an object that contains the agents for pooling connections with the following required keys:\n\n
      • \n
      • \nevents - if true, enables events. Events are available via the events emitter property.
      • \n
      \n
    • \n
    \n

    request(method, uri, [options])

    \n

    Initiate an HTTP request.

    \n
      \n
    • \n

      method - a string specifying the HTTP request method. Defaults to 'GET'.

      \n
    • \n
    • \n

      uri - the URI of the requested resource.

      \n
    • \n
    • \n

      options - optional configuration object with the following keys:

      \n
        \n
      • \n

        agent - Node Core http.Agent. Defaults to either wreck.agents.http or wreck.agents.https. Setting to false disables agent pooling.

        \n
      • \n
      • \n

        baseUrl - fully qualified URL string used as the base URL. Most useful with Wreck.defaults() when making multiple requests to the same domain. For example, if baseUrl is https://example.com/api/, then requesting /end/point?test=true will fetch https://example.com/end/point?test=true. Any query string in the baseUrl will be overwritten with the query string in the uri When baseUrl is given, uri must also be a string. In order to retain the /api/ portion of the baseUrl in the example, the path must not start with a leading / and the baseUrl must end with a trailing /.

        \n
      • \n
      • \n

        beforeRedirect - a function to call before a redirect is triggered, using the signature async function(redirectMethod, statusCode, location, resHeaders, redirectOptions, next) where:

        \n
          \n
        • \nredirectMethod - A string specifying the redirect method.
        • \n
        • \nstatusCode - HTTP status code of the response that triggered the redirect.
        • \n
        • \nlocation - The redirect location string.
        • \n
        • \nresHeaders - An object with the headers received as part of the redirection response.
        • \n
        • \nredirectOptions - Options that will be applied to the redirect request. Changes to this object are applied to the redirection request.
        • \n
        • \nnext - the callback function called to perform the redirection using signature function(err). Passing an error into callback will stop the redirect request.
        • \n
        \n
      • \n
      • \n

        ciphers - TLS list of TLS ciphers to override node's default. The possible values depend on your installation of OpenSSL. Read the official OpenSSL docs for possible TLS_CIPHERS.

        \n
      • \n
      • \n

        headers - an object containing the request headers.

        \n
      • \n
      • \n

        payload - the request body as a string, Buffer, readable stream, or an object that can be serialized using JSON.stringify().

        \n
      • \n
      • \n

        redirect303 - if true, a HTTP 303 status code will redirect using a GET method. Defaults to false (no redirection on 303).

        \n
      • \n
      • \n

        redirected - a function to call when a redirect was triggered, using the signature function(statusCode, location, req) where:

        \n
          \n
        • \nstatusCode - HTTP status code of the response that triggered the redirect.
        • \n
        • \nlocation - The redirected location string.
        • \n
        • \nreq - The new ClientRequest object which replaces the one initially returned.
        • \n
        \n
      • \n
      • \n

        redirectMethod - override the HTTP method used when following 301 and 302 redirections. Defaults to the original method.

        \n
      • \n
      • \n

        redirects - the maximum number of redirects to follow. Default to false (no redirects).

        \n
      • \n
      • \n

        rejectUnauthorized - TLS flag indicating whether the client should reject a response from a server with invalid certificates. This cannot be set at the same time as the agent option is set.

        \n
      • \n
      • \n

        secureProtocol - TLS flag indicating the SSL method to use, e.g. SSLv3_method to force SSL version 3. The possible values depend on your installation of OpenSSL. Read the official OpenSSL docs for possible SSL_METHODS.

        \n
      • \n
      • \n

        socketPath - a UNIX socket path string for direct server connection.

        \n
      • \n
      • \n

        timeout - number of milliseconds to wait without receiving a response before aborting the request. Defaults to 0 (no limit).

        \n
      • \n
      • \n

        lookup - DNS lookup function. see http.request(url[,options][,callback]). Defaults to dns.lookup().

        \n
      • \n
      • \n

        family - IP address family to use when resolving host or hostname. Valid values are 4 or 6. When unspecified, both IP v4 and v6 will be used.

        \n
      • \n
      • \n

        hints - Optional dns.lookup() hints.

        \n
      • \n
      \n
    • \n
    \n

    Returns a promise that resolves into a node response object. The promise has a req property which is the instance of the node.js ClientRequest object.

    \n

    read(response, options)

    \n
      \n
    • \n

      response - An HTTP Incoming Message object.

      \n
    • \n
    • \n

      options - null or a configuration object with the following optional keys:

      \n
        \n
      • \n

        gunzip - determines how to handle gzipped payloads. Defaults to false.

        \n
          \n
        • \ntrue - only try to gunzip if the response indicates a gzip content-encoding.
        • \n
        • \nfalse - explicitly disable gunzipping.
        • \n
        • \nforce - try to gunzip regardless of the content-encoding header.
        • \n
        \n
      • \n
      • \n

        json - determines how to parse the payload as JSON:

        \n
          \n
        • \nfalse - leaves payload raw. This is the default value.
        • \n
        • \ntrue - only try JSON.parse if the response indicates a JSON content-type.
        • \n
        • \n'strict' - as true, except returns an error for non-JSON content-type.
        • \n
        • \n'force' - try JSON.parse regardless of the content-type header.
        • \n
        \n
      • \n
      • \n

        maxBytes - the maximum allowed response payload size. Defaults to 0 (no limit).

        \n
      • \n
      • \n

        timeout - the number of milliseconds to wait while reading data before aborting handling of the response. Defaults to 0.

        \n
      • \n
      \n
    • \n
    \n

    Returns a promise that resolves into the payload in the form of a Buffer or (optionally) parsed JavaScript object (JSON).

    \n

    Notes about gunzip

    \n

    When using gunzip, HTTP headers Content-Encoding, Content-Length, Content-Range and ETag won't reflect the reality as the payload has been uncompressed.

    \n

    get(uri, [options])

    \n

    Convenience method for GET operations.

    \n
      \n
    • \nuri - The URI of the requested resource.
    • \n
    • \noptions - Optional config object containing settings for both request and\nread operations.
    • \n
    \n

    Returns a promise that resolves into an object with the following properties:

    \n
      \n
    • \nres - The HTTP Incoming Message\nobject, which is a readable stream that has \"ended\" and contains no more data to read.
    • \n
    • \npayload - The payload in the form of a Buffer or (optionally) parsed JavaScript object (JSON).
    • \n
    \n

    Throws any error that may have occurred during handling of the request or a Boom error object if the response has an error status\ncode (i.e. 4xx or 5xx). If the error is a boom error object it will have the following properties in addition to the standard boom\nproperties:

    \n
      \n
    • \ndata.isResponseError - boolean, indicates if the error is a result of an error response status code
    • \n
    • \ndata.headers - object containing the response headers
    • \n
    • \ndata.payload - the payload in the form of a Buffer or as a parsed object
    • \n
    • \ndata.res - the HTTP Incoming Message object
    • \n
    \n

    post(uri, [options])

    \n

    Convenience method for POST operations.

    \n
      \n
    • \nuri - The URI of the requested resource.
    • \n
    • \noptions - Optional config object containing settings for both request and\nread operations.
    • \n
    \n

    Returns a promise that resolves into an object with the following properties:

    \n
      \n
    • \nres - The HTTP Incoming Message\nobject, which is a readable stream that has \"ended\" and contains no more data to read.
    • \n
    • \npayload - The payload in the form of a Buffer or (optionally) parsed JavaScript object (JSON).
    • \n
    \n

    Throws any error that may have occurred during handling of the request or a Boom error object if the response has an error status\ncode (i.e. 4xx or 5xx). If the error is a boom error object it will have the following properties in addition to the standard boom\nproperties:

    \n
      \n
    • \ndata.isResponseError - boolean, indicates if the error is a result of an error response status code
    • \n
    • \ndata.headers - object containing the response headers
    • \n
    • \ndata.payload - the payload in the form of a Buffer or as a parsed object
    • \n
    • \ndata.res - the HTTP Incoming Message object
    • \n
    \n

    patch(uri, [options])

    \n

    Convenience method for PATCH operations.

    \n
      \n
    • \nuri - The URI of the requested resource.
    • \n
    • \noptions - Optional config object containing settings for both request and\nread operations.
    • \n
    \n

    Returns a promise that resolves into an object with the following properties:

    \n
      \n
    • \nres - The HTTP Incoming Message\nobject, which is a readable stream that has \"ended\" and contains no more data to read.
    • \n
    • \npayload - The payload in the form of a Buffer or (optionally) parsed JavaScript object (JSON).
    • \n
    \n

    Throws any error that may have occurred during handling of the request or a Boom error object if the response has an error status\ncode (i.e. 4xx or 5xx). If the error is a boom error object it will have the following properties in addition to the standard boom\nproperties:

    \n
      \n
    • \ndata.isResponseError - boolean, indicates if the error is a result of an error response status code
    • \n
    • \ndata.headers - object containing the response headers
    • \n
    • \ndata.payload - the payload in the form of a Buffer or as a parsed object
    • \n
    • \ndata.res - the HTTP Incoming Message object
    • \n
    \n

    put(uri, [options])

    \n

    Convenience method for PUT operations.

    \n
      \n
    • \nuri - The URI of the requested resource.
    • \n
    • \noptions - Optional config object containing settings for both request and\nread operations.
    • \n
    \n

    Returns a promise that resolves into an object with the following properties:

    \n
      \n
    • \nres - The HTTP Incoming Message\nobject, which is a readable stream that has \"ended\" and contains no more data to read.
    • \n
    • \npayload - The payload in the form of a Buffer or (optionally) parsed JavaScript object (JSON).
    • \n
    \n

    Throws any error that may have occurred during handling of the request or a Boom error object if the response has an error status\ncode (i.e. 4xx or 5xx). If the error is a boom error object it will have the following properties in addition to the standard boom\nproperties:

    \n
      \n
    • \ndata.isResponseError - boolean, indicates if the error is a result of an error response status code
    • \n
    • \ndata.headers - object containing the response headers
    • \n
    • \ndata.payload - the payload in the form of a Buffer or as a parsed object
    • \n
    • \ndata.res - the HTTP Incoming Message object
    • \n
    \n

    delete(uri, [options])

    \n

    Convenience method for DELETE operations.

    \n
      \n
    • \nuri - The URI of the requested resource.
    • \n
    • \noptions - Optional config object containing settings for both request and\nread operations.
    • \n
    \n

    Returns a promise that resolves into an object with the following properties:

    \n
      \n
    • \nres - The HTTP Incoming Message\nobject, which is a readable stream that has \"ended\" and contains no more data to read.
    • \n
    • \npayload - The payload in the form of a Buffer or (optionally) parsed JavaScript object (JSON).
    • \n
    \n

    Throws any error that may have occurred during handling of the request or a Boom error object if the response has an error status\ncode (i.e. 4xx or 5xx). If the error is a boom error object it will have the following properties in addition to the standard boom\nproperties:

    \n
      \n
    • \ndata.isResponseError - boolean, indicates if the error is a result of an error response status code
    • \n
    • \ndata.headers - object containing the response headers
    • \n
    • \ndata.payload - the payload in the form of a Buffer or as a parsed object
    • \n
    • \ndata.res - the HTTP Incoming Message object
    • \n
    \n

    toReadableStream(payload, [encoding])

    \n

    Creates a readable stream\nfor the provided payload and encoding.

    \n
      \n
    • \npayload - The Buffer or string to be wrapped in a readable stream.
    • \n
    • \nencoding - The encoding to use. Must be a valid Buffer encoding, such as 'utf8' or 'ascii'.
    • \n
    \n\n\n
    const stream = Wreck.toReadableStream(Buffer.from('Hello', 'ascii'), 'ascii');\nconst read = stream.read();\n// read -> 'Hello'
    \n

    parseCacheControl(field)

    \n

    Parses the provided cache-control request header value into an object containing\na property for each directive and it's value. Boolean directives, such as \"private\"\nor \"no-cache\" will be set to the boolean true.

    \n
      \n
    • \nfield - The header cache control value to be parsed.
    • \n
    \n\n\n
    const result = Wreck.parseCacheControl('private, max-age=0, no-cache');\n// result.private -> true\n// result['max-age'] -> 0\n// result['no-cache'] -> true
    \n

    agents

    \n

    An object containing the node agents used for pooling connections for http and https. The properties are http, https, and httpsAllowUnauthorized which is an https agent with rejectUnauthorized set to false. All agents have maxSockets configured to Infinity. They are each instances of the Node.js Agent and expose the standard properties.

    \n

    For example, the following code demonstrates changing maxSockets on the http agent.

    \n
    const Wreck = require('@hapi/wreck');\n\nWreck.agents.http.maxSockets = 20;
    \n

    Below is another example that sets the certificate details for all HTTPS requests.

    \n
    const HTTPS = require('https');\nconst Wreck = require('@hapi/wreck');\n\nWreck.agents.https = new HTTPS.Agent({\n    cert,\n    key,\n    ca\n});
    \n

    Events

    \n

    To enable events, use Wreck.defaults({ events: true }). Events are available via the events emitter attached to the client returned by Wreck.defaults().

    \n

    preRequest

    \n

    The request event is emitted just before wreck creates a request. The\nhandler should accept the following arguments (uri, options) where:

    \n
      \n
    • \nuri - the result of new URL(uri). This will provide information about\nthe resource requested. Also includes the headers and method.
    • \n
    • \noptions - the options passed into the request function. This will include\na payload if there is one.
    • \n
    \n

    Since the preRequest event executes on a global event handler, you can intercept\nand decorate uri and options before a request is created.

    \n

    request

    \n

    The request event is emitted just after wreck creates a request. The handler should accept the following arguments (req) where:

    \n
      \n
    • \nreq - the raw ClientRequest object created from the uri, before end has been called.
    • \n
    \n

    Since the request event executes on a global event handler, you can intercept\nand add listeners to a request.

    \n

    response

    \n

    The response event is always emitted for any request that wreck makes. The\nhandler should accept the following arguments (err, details) where:

    \n
      \n
    • \nerr - a Boom error
    • \n
    • \ndetails - object with the following properties\n
        \n
      • \nreq - the raw ClientHttp request object
      • \n
      • \nres - the raw IncomingMessage response object
      • \n
      • \nstart - the time that the request was initiated
      • \n
      • \nuri - the result of new URL(uri). This will provide information about\nthe resource requested. Also includes the headers and method.
      • \n
      \n
    • \n
    \n

    This event is useful for logging all requests that go through wreck. The err\nand res arguments can be undefined depending on if an error occurs. Please\nbe aware that if multiple modules are depending on the same cached wreck\nmodule that this event can fire for each request made across all modules. The\nstart property is the timestamp when the request was started. This can be\nuseful for determining how long it takes wreck to get a response back and\nprocessed.

    \n", - "intro": "", - "example": "", - "usage": "## Usage\n\n```javascript\nconst Wreck = require('@hapi/wreck');\n\nconst example = async function () {\n\n const { res, payload } = await Wreck.get('http://example.com');\n console.log(payload.toString());\n};\n\ntry {\n example();\n}\ncatch (ex) {\n console.error(ex);\n}\n```\n", - "faq": "", - "advanced": "### Advanced\n\n```javascript\nconst Wreck = require('@hapi/wreck');\n\nconst method = 'GET'; // GET, POST, PUT, DELETE\nconst uri = '/';\nconst readableStream = Wreck.toReadableStream('foo=bar');\n\nconst wreck = Wreck.defaults({\n headers: { 'x-foo-bar': 123 },\n agents: {\n https: new Https.Agent({ maxSockets: 100 }),\n http: new Http.Agent({ maxSockets: 1000 }),\n httpsAllowUnauthorized: new Https.Agent({ maxSockets: 100, rejectUnauthorized: false })\n }\n});\n\n// cascading example -- does not alter `wreck`\n// inherits `headers` and `agents` specified above\nconst wreckWithTimeout = wreck.defaults({\n timeout: 5\n});\n\n// all attributes are optional\nconst options = {\n baseUrl: 'https://www.example.com',\n payload: readableStream || 'foo=bar' || Buffer.from('foo=bar'),\n headers: { /* http headers */ },\n redirects: 3,\n beforeRedirect: (redirectMethod, statusCode, location, resHeaders, redirectOptions, next) => next(),\n redirected: function (statusCode, location, req) {},\n timeout: 1000, // 1 second, default: unlimited\n maxBytes: 1048576, // 1 MB, default: unlimited\n rejectUnauthorized: true || false,\n agent: null, // Node Core http.Agent\n secureProtocol: 'SSLv3_method', // The SSL method to use\n ciphers: 'DES-CBC3-SHA' // The TLS ciphers to support\n};\n\nconst example = async function () {\n\n const promise = wreck.request(method, uri, options);\n try {\n const res = await promise;\n const body = await Wreck.read(res, options);\n console.log(body.toString());\n }\n catch (err) {\n // Handle errors\n }\n};\n```\n\nUse `promise.req.abort()` to terminate the request early. Note that this is limited to the initial request only.\nIf the request was already redirected, aborting the original request will not abort execution of pending redirections.\n", - "license": "BSD" - }, - "17.2.0": { - "menu": "- [Advanced](#advanced)\n- [`defaults()`](#defaultsoptions)\n- [`request()`](#requestmethod-uri-options)\n- [`read()`](#readresponse-options)\n - [Notes about gunzip](#notes-about-gunzip)\n- [`get()`](#geturi-options)\n- [`post()`](#posturi-options)\n- [`patch()`](#patchuri-options)\n- [`put()`](#puturi-options)\n- [`delete()`](#deleteuri-options)\n- [`toReadableStream()`](#toreadablestreampayload-encoding)\n- [`parseCacheControl()`](#parsecachecontrolfield)\n- [`agents`](#agents)\n- [Events](#events)\n - [`preRequest`](#prerequest)\n - [`request`](#request)\n - [`response`](#response)", - "api": "

    Usage

    \n
    const Wreck = require('@hapi/wreck');\n\nconst example = async function () {\n\n    const { res, payload } = await Wreck.get('http://example.com');\n    console.log(payload.toString());\n};\n\ntry {\n    example();\n}\ncatch (ex) {\n    console.error(ex);\n}
    \n

    Advanced

    \n
    const Wreck = require('@hapi/wreck');\n\nconst method = 'GET'; // GET, POST, PUT, DELETE\nconst uri = '/';\nconst readableStream = Wreck.toReadableStream('foo=bar');\n\nconst wreck = Wreck.defaults({\n    headers: { 'x-foo-bar': 123 },\n    agents: {\n        https: new Https.Agent({ maxSockets: 100 }),\n        http: new Http.Agent({ maxSockets: 1000 }),\n        httpsAllowUnauthorized: new Https.Agent({ maxSockets: 100, rejectUnauthorized: false })\n    }\n});\n\n// cascading example -- does not alter `wreck`\n// inherits `headers` and `agents` specified above\nconst wreckWithTimeout = wreck.defaults({\n    timeout: 5\n});\n\n// all attributes are optional\nconst options = {\n    baseUrl: 'https://www.example.com',\n    payload: readableStream || 'foo=bar' || Buffer.from('foo=bar'),\n    headers: { /* http headers */ },\n    redirects: 3,\n    beforeRedirect: (redirectMethod, statusCode, location, resHeaders, redirectOptions, next) => next(),\n    redirected: function (statusCode, location, req) {},\n    timeout: 1000,    // 1 second, default: unlimited\n    maxBytes: 1048576, // 1 MB, default: unlimited\n    rejectUnauthorized: true || false,\n    agent: null,         // Node Core http.Agent\n    secureProtocol: 'SSLv3_method', // The SSL method to use\n    ciphers: 'DES-CBC3-SHA' // The TLS ciphers to support\n};\n\nconst example = async function () {\n\n    const promise = wreck.request(method, uri, options);\n    try {\n        const res = await promise;\n        const body = await Wreck.read(res, options);\n        console.log(body.toString());\n    }\n    catch (err) {\n        // Handle errors\n    }\n};
    \n

    Use promise.req.abort() to terminate the request early. Note that this is limited to the initial request only.\nIf the request was already redirected, aborting the original request will not abort execution of pending redirections.

    \n

    defaults(options)

    \n

    Returns a new instance of Wreck which merges the provided options with those provided on a per-request basis. You can call defaults repeatedly to build up multiple clients.

    \n
      \n
    • \noptions - Config object containing settings for both request and read operations as well as:\n
        \n
      • \nagents - an object that contains the agents for pooling connections with the following required keys:\n\n
      • \n
      • \nevents - if true, enables events. Events are available via the events emitter property.
      • \n
      \n
    • \n
    \n

    request(method, uri, [options])

    \n

    Initiate an HTTP request.

    \n
      \n
    • \n

      method - a string specifying the HTTP request method. Defaults to 'GET'.

      \n
    • \n
    • \n

      uri - the URI of the requested resource.

      \n
    • \n
    • \n

      options - optional configuration object with the following keys:

      \n
        \n
      • \n

        agent - Node Core http.Agent. Defaults to either wreck.agents.http or wreck.agents.https. Setting to false disables agent pooling.

        \n
      • \n
      • \n

        baseUrl - fully qualified URL string used as the base URL. Most useful with Wreck.defaults() when making multiple requests to the same domain. For example, if baseUrl is https://example.com/api/, then requesting /end/point?test=true will fetch https://example.com/end/point?test=true. Any query string in the baseUrl will be overwritten with the query string in the uri When baseUrl is given, uri must also be a string. In order to retain the /api/ portion of the baseUrl in the example, the path must not start with a leading / and the baseUrl must end with a trailing /.

        \n
      • \n
      • \n

        beforeRedirect - a function to call before a redirect is triggered, using the signature async function(redirectMethod, statusCode, location, resHeaders, redirectOptions, next) where:\n- redirectMethod - A string specifying the redirect method.\n- statusCode - HTTP status code of the response that triggered the redirect.\n- location - The redirect location string.\n- resHeaders - An object with the headers received as part of the redirection response.\n- redirectOptions - Options that will be applied to the redirect request. Changes to this object are applied to the redirection request.\n- next - the callback function called to perform the redirection using signature function(err). Passing an error into callback will stop the redirect request.

        \n
      • \n
      • \n

        ciphers - TLS list of TLS ciphers to override node's default. The possible values depend on your installation of OpenSSL. Read the official OpenSSL docs for possible TLS_CIPHERS.

        \n
      • \n
      • \n

        headers - an object containing the request headers.

        \n
      • \n
      • \n

        payload - the request body as a string, Buffer, readable stream, or an object that can be serialized using JSON.stringify().

        \n
      • \n
      • \n

        redirect303 - if true, a HTTP 303 status code will redirect using a GET method. Defaults to false (no redirection on 303).

        \n
      • \n
      • \n

        redirected - a function to call when a redirect was triggered, using the signature function(statusCode, location, req) where:

        \n
          \n
        • \nstatusCode - HTTP status code of the response that triggered the redirect.
        • \n
        • \nlocation - The redirected location string.
        • \n
        • \nreq - The new ClientRequest object which replaces the one initially returned.
        • \n
        \n
      • \n
      • \n

        redirectMethod - override the HTTP method used when following 301 and 302 redirections. Defaults to the original method.

        \n
      • \n
      • \n

        redirects - the maximum number of redirects to follow. Default to false (no redirects).

        \n
      • \n
      • \n

        rejectUnauthorized - TLS flag indicating whether the client should reject a response from a server with invalid certificates. This cannot be set at the same time as the agent option is set.

        \n
      • \n
      • \n

        secureProtocol - TLS flag indicating the SSL method to use, e.g. SSLv3_method to force SSL version 3. The possible values depend on your installation of OpenSSL. Read the official OpenSSL docs for possible SSL_METHODS.

        \n
      • \n
      • \n

        socketPath - a UNIX socket path string for direct server connection.

        \n
      • \n
      • \n

        timeout - number of milliseconds to wait without receiving a response before aborting the request. Defaults to 0 (no limit).

        \n
      • \n
      \n
    • \n
    \n

    Returns a promise that resolves into a node response object. The promise has a req property which is the instance of the node.js ClientRequest object.

    \n

    read(response, options)

    \n
      \n
    • \n

      response - An HTTP Incoming Message object.

      \n
    • \n
    • \n

      options - null or a configuration object with the following optional keys:

      \n
        \n
      • \n

        gunzip - determines how to handle gzipped payloads. Defaults to false.

        \n
          \n
        • \ntrue - only try to gunzip if the response indicates a gzip content-encoding.
        • \n
        • \nfalse - explicitly disable gunzipping.
        • \n
        • \nforce - try to gunzip regardless of the content-encoding header.
        • \n
        \n
      • \n
      • \n

        json - determines how to parse the payload as JSON:

        \n
          \n
        • \nfalse - leaves payload raw. This is the default value.
        • \n
        • \ntrue - only try JSON.parse if the response indicates a JSON content-type.
        • \n
        • \n'strict' - as true, except returns an error for non-JSON content-type.
        • \n
        • \n'force' - try JSON.parse regardless of the content-type header.
        • \n
        \n
      • \n
      • \n

        maxBytes - the maximum allowed response payload size. Defaults to 0 (no limit).

        \n
      • \n
      • \n

        timeout - the number of milliseconds to wait while reading data before aborting handling of the response. Defaults to 0.

        \n
      • \n
      \n
    • \n
    \n

    Returns a promise that resolves into the payload in the form of a Buffer or (optionally) parsed JavaScript object (JSON).

    \n

    Notes about gunzip

    \n

    When using gunzip, HTTP headers Content-Encoding, Content-Length, Content-Range and ETag won't reflect the reality as the payload has been uncompressed.

    \n

    get(uri, [options])

    \n

    Convenience method for GET operations.

    \n
      \n
    • \nuri - The URI of the requested resource.
    • \n
    • \noptions - Optional config object containing settings for both request and\nread operations.
    • \n
    \n

    Returns a promise that resolves into an object with the following properties:\n- res - The HTTP Incoming Message\nobject, which is a readable stream that has \"ended\" and contains no more data to read.\n- payload - The payload in the form of a Buffer or (optionally) parsed JavaScript object (JSON).

    \n

    Throws any error that may have occurred during handling of the request or a Boom error object if the response has an error status\ncode (i.e. 4xx or 5xx). If the error is a boom error object it will have the following properties in addition to the standard boom\nproperties:\n- data.isResponseError - boolean, indicates if the error is a result of an error response status code\n- data.headers - object containing the response headers\n- data.payload - the payload in the form of a Buffer or as a parsed object\n- data.res - the HTTP Incoming Message object

    \n

    post(uri, [options])

    \n

    Convenience method for POST operations.

    \n
      \n
    • \nuri - The URI of the requested resource.
    • \n
    • \noptions - Optional config object containing settings for both request and\nread operations.
    • \n
    \n

    Returns a promise that resolves into an object with the following properties:\n- res - The HTTP Incoming Message\nobject, which is a readable stream that has \"ended\" and contains no more data to read.\n- payload - The payload in the form of a Buffer or (optionally) parsed JavaScript object (JSON).

    \n

    Throws any error that may have occurred during handling of the request or a Boom error object if the response has an error status\ncode (i.e. 4xx or 5xx). If the error is a boom error object it will have the following properties in addition to the standard boom\nproperties:\n- data.isResponseError - boolean, indicates if the error is a result of an error response status code\n- data.headers - object containing the response headers\n- data.payload - the payload in the form of a Buffer or as a parsed object\n- data.res - the HTTP Incoming Message object

    \n

    patch(uri, [options])

    \n

    Convenience method for PATCH operations.

    \n
      \n
    • \nuri - The URI of the requested resource.
    • \n
    • \noptions - Optional config object containing settings for both request and\nread operations.
    • \n
    \n

    Returns a promise that resolves into an object with the following properties:\n- res - The HTTP Incoming Message\nobject, which is a readable stream that has \"ended\" and contains no more data to read.\n- payload - The payload in the form of a Buffer or (optionally) parsed JavaScript object (JSON).

    \n

    Throws any error that may have occurred during handling of the request or a Boom error object if the response has an error status\ncode (i.e. 4xx or 5xx). If the error is a boom error object it will have the following properties in addition to the standard boom\nproperties:\n- data.isResponseError - boolean, indicates if the error is a result of an error response status code\n- data.headers - object containing the response headers\n- data.payload - the payload in the form of a Buffer or as a parsed object\n- data.res - the HTTP Incoming Message object

    \n

    put(uri, [options])

    \n

    Convenience method for PUT operations.

    \n
      \n
    • \nuri - The URI of the requested resource.
    • \n
    • \noptions - Optional config object containing settings for both request and\nread operations.
    • \n
    \n

    Returns a promise that resolves into an object with the following properties:\n- res - The HTTP Incoming Message\nobject, which is a readable stream that has \"ended\" and contains no more data to read.\n- payload - The payload in the form of a Buffer or (optionally) parsed JavaScript object (JSON).

    \n

    Throws any error that may have occurred during handling of the request or a Boom error object if the response has an error status\ncode (i.e. 4xx or 5xx). If the error is a boom error object it will have the following properties in addition to the standard boom\nproperties:\n- data.isResponseError - boolean, indicates if the error is a result of an error response status code\n- data.headers - object containing the response headers\n- data.payload - the payload in the form of a Buffer or as a parsed object\n- data.res - the HTTP Incoming Message object

    \n

    delete(uri, [options])

    \n

    Convenience method for DELETE operations.

    \n
      \n
    • \nuri - The URI of the requested resource.
    • \n
    • \noptions - Optional config object containing settings for both request and\nread operations.
    • \n
    \n

    Returns a promise that resolves into an object with the following properties:\n- res - The HTTP Incoming Message\nobject, which is a readable stream that has \"ended\" and contains no more data to read.\n- payload - The payload in the form of a Buffer or (optionally) parsed JavaScript object (JSON).

    \n

    Throws any error that may have occurred during handling of the request or a Boom error object if the response has an error status\ncode (i.e. 4xx or 5xx). If the error is a boom error object it will have the following properties in addition to the standard boom\nproperties:\n- data.isResponseError - boolean, indicates if the error is a result of an error response status code\n- data.headers - object containing the response headers\n- data.payload - the payload in the form of a Buffer or as a parsed object\n- data.res - the HTTP Incoming Message object

    \n

    toReadableStream(payload, [encoding])

    \n

    Creates a readable stream\nfor the provided payload and encoding.

    \n
      \n
    • \npayload - The Buffer or string to be wrapped in a readable stream.
    • \n
    • \nencoding - The encoding to use. Must be a valid Buffer encoding, such as 'utf8' or 'ascii'.
    • \n
    \n\n\n
    const stream = Wreck.toReadableStream(Buffer.from('Hello', 'ascii'), 'ascii');\nconst read = stream.read();\n// read -> 'Hello'
    \n

    parseCacheControl(field)

    \n

    Parses the provided cache-control request header value into an object containing\na property for each directive and it's value. Boolean directives, such as \"private\"\nor \"no-cache\" will be set to the boolean true.

    \n
      \n
    • \nfield - The header cache control value to be parsed.
    • \n
    \n\n\n
    const result = Wreck.parseCacheControl('private, max-age=0, no-cache');\n// result.private -> true\n// result['max-age'] -> 0\n// result['no-cache'] -> true
    \n

    agents

    \n

    An object containing the node agents used for pooling connections for http and https. The properties are http, https, and httpsAllowUnauthorized which is an https agent with rejectUnauthorized set to false. All agents have maxSockets configured to Infinity. They are each instances of the Node.js Agent and expose the standard properties.

    \n

    For example, the following code demonstrates changing maxSockets on the http agent.

    \n
    const Wreck = require('@hapi/wreck');\n\nWreck.agents.http.maxSockets = 20;
    \n

    Below is another example that sets the certificate details for all HTTPS requests.

    \n
    const HTTPS = require('https');\nconst Wreck = require('@hapi/wreck');\n\nWreck.agents.https = new HTTPS.Agent({\n    cert,\n    key,\n    ca\n});
    \n

    Events

    \n

    To enable events, use Wreck.defaults({ events: true }). Events are available via the events emitter attached to the client returned by Wreck.defaults().

    \n

    preRequest

    \n

    The request event is emitted just before wreck creates a request. The\nhandler should accept the following arguments (uri, options) where:

    \n
      \n
    • \nuri - the result of new URL(uri). This will provide information about\nthe resource requested. Also includes the headers and method.
    • \n
    • \noptions - the options passed into the request function. This will include\na payload if there is one.
    • \n
    \n

    Since the preRequest event executes on a global event handler, you can intercept\nand decorate uri and options before a request is created.

    \n

    request

    \n

    The request event is emitted just after wreck creates a request. The handler should accept the following arguments (req) where:

    \n
      \n
    • \nreq - the raw ClientRequest object created from the uri, before end has been called.
    • \n
    \n

    Since the request event executes on a global event handler, you can intercept\nand add listeners to a request.

    \n

    response

    \n

    The response event is always emitted for any request that wreck makes. The\nhandler should accept the following arguments (err, details) where:

    \n
      \n
    • \nerr - a Boom error
    • \n
    • \ndetails - object with the following properties\n
        \n
      • \nreq - the raw ClientHttp request object
      • \n
      • \nres - the raw IncomingMessage response object
      • \n
      • \nstart - the time that the request was initiated
      • \n
      • \nuri - the result of new URL(uri). This will provide information about\nthe resource requested. Also includes the headers and method.
      • \n
      \n
    • \n
    \n

    This event is useful for logging all requests that go through wreck. The err\nand res arguments can be undefined depending on if an error occurs. Please\nbe aware that if multiple modules are depending on the same cached wreck\nmodule that this event can fire for each request made across all modules. The\nstart property is the timestamp when the request was started. This can be\nuseful for determining how long it takes wreck to get a response back and\nprocessed.

    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "HTTP client utilities.", - "forks": 103, - "stars": 383, - "date": "2024-04-10T17:35:00Z", - "updated": "Wed Apr 10 2024", - "link": "https://github.com/hapijs/wreck" - }, - "yar": { - "name": "yar", - "versions": [ - { - "name": "11.0.2", - "branch": "master", - "license": "BSD", - "node": "16, 18, 20" - }, - { - "name": "10.1.1", - "branch": "v11", - "license": "BSD", - "node": "16, 18, 20" - } - ], - "versionsArray": [ - "11.0.2", - "10.1.1" - ], - "api": true, - "isPlugin": true, - "11.0.2": { - "menu": " - [Differences from @hapi/cookie](#differences-from-hapicookie)\n- [Password considerations](#password-considerations)\n- [Cookie Options](#cookie-options)\n - [isSecure](#issecure)\n - [ignoreErrors](#ignoreerrors)\n - [clearInvalid](#clearinvalid)\n- [Options](#options)\n - [Route Options](#route-options)\n - [Methods](#methods)", - "api": "

    Differences from @hapi/cookie

    \n

    The @hapi/cookie plugin provides similar facilities to yar. The approach of the two projects does differ in some regards, though.

    \n
      \n
    1. \nyar is focused on session support, and does not require that a user be logged in to have a session. @hapi/cookie only provides session storage for logged in users. If you need session handling for non-authenticated users, use yar.
    2. \n
    3. \nyar is capable of handling larger data sizes without any additional setup. If your session data gets larger than cookies can handle yar will push the data out to the server cache for you. By default this is memory storage, but can be any catbox supported cache storage, including mongo, redis, local disk, and more. @hapi/cookie can support larger session size as well, but requires you to handle connecting the cookie based session with your external data storage.
    4. \n
    \n

    Password considerations

    \n

    Keep in mind some things in regard to your password:

    \n
      \n
    1. It should never be committed to the repository or hard coded in your code. Instead pass the password via environment variables or some other server configuration management option.
    2. \n
    3. In some situations it is possible that your password could be attacked remotely. So choose a password that is randomly generated. Use a random password generator to create something rather than creating your own. Make sure it is long and includes special characters.
    4. \n
    5. Consider rotating your cookie session password on a regular basis.
    6. \n
    \n

    Cookie Options

    \n

    You can read about more cookie options in the cookie options section.

    \n

    isSecure

    \n

    Set isSecure (default true) to false if you are using standard http. Take care to do this in development mode only though. You don't want to use cookies sent over insecure channels for session management. One way to take care of this is to use the NODE_ENV environment variable like this:

    \n
    let options = {\n    cookieOptions: {\n        isSecure: process.env.NODE_ENV !== 'development',\n        ...\n    }\n};
    \n

    ignoreErrors

    \n

    ignoreErrors (default true) tells hapi that it should not respond with a HTTP 400 error if the session cookie cannot decrypt. This could happen if the cookie is changed on the client, or more likely, if you change the cookie password in your settings. If you want to make this condition send an error like it did in prior versions, change this to false, but be aware that if you change your cookie password you will cause 400 errors to be returned to end users. In that case you should probably change this back to true for a short time to allow session cookies to get reset for the best user experience.

    \n

    You may turn this off, false, and try to use the hapi route state config option of failAction to instead get an event whenever a bad session cookie is encountered. This can allow more sophisticated handling strategies or even allow for mitigation of brute force attacks on your cookie password. See server.state() documentation for more details.

    \n

    clearInvalid

    \n

    clearInvalid (default true) tells hapi that if a session cookie is invalid for any reason, to clear it from the browser. This prevents hapi from having to reprocess the bad cookie on future requests. In general you'll probably want this on, but if you'd prefer that session cookies be dealt with in some other way you may set this to false.

    \n

    Options

    \n
      \n
    • \nname - determines the name of the cookie used to store session information. Defaults to session.
    • \n
    • \nmaxCookieSize - maximum cookie size before using server-side storage. Defaults to 1K. Set to zero to always use server-side storage.
    • \n
    • \nstoreBlank - determines whether to store empty session before they've been modified. Defaults to true.
    • \n
    • \nerrorOnCacheNotReady - will cause yar to throw an exception if trying to persist to cache when the cache is unavailable. Setting this to false will allow applications using yar to run uninterrupted if the cache is not ready (however sessions will not be saving). Defaults to true.
    • \n
    • \ncache - hapi cache options which includes\n(among other options):\n
        \n
      • \nexpiresIn - server-side storage expiration (defaults to 1 day).
      • \n
      \n
    • \n
    • \ncookieOptions - the configuration for cookie-specific features:\n
        \n
      • \npassword - (Required) used to encrypt and sign the cookie data.
      • \n
      • \npath - determines the cookie path. Defaults to '/'.
      • \n
      • \nisSameSite - enables the same-site cookie parameter. Default to 'Lax'. Can be 'Strict'|'Lax'|'None'|false.
      • \n
      • \nisSecure - determines whether or not to transfer using TLS/SSL. Defaults to true.
      • \n
      • \nisHttpOnly - determines whether or not to set HttpOnly option in cookie. Defaults to false.
      • \n
      • \nttl - sets the time for the cookie to live in the browser, in milliseconds. Defaults to null (session time-life - cookies are deleted when the browser is closed).
      • \n
      • \ncontextualize - a function using the signature async function(definition, request) used to override a request-specific cookie settings where:\n
          \n
        • \ndefinition - a copy of the options to be used for formatting the cookie that can be manipulated by the function to customize the request cookie header. Note that changing the definition.contextualize property will be ignored.
        • \n
        • \nrequest - the current request object.
        • \n
        \n
      • \n
      \n
    • \n
    • \ncustomSessionIDGenerator - an optional function to create custom session IDs. Must return a string and have the signature function (request) where:\n
        \n
      • \nrequest - (optional) is the original request received from the client.
      • \n
      \n
    • \n
    \n

    Route Options

    \n

    You can also add these options on a route per route basis at config.plugins.yar:

    \n
      \n
    • \nskip - a boolean value which, if true, means no session will be attached to the request (defaults to false).
    • \n
    \n

    Methods

    \n

    yar adds the yar property to every request object and initializes the yar.id on the first request from each browser. The request.yar interface provides the following methods:

    \n
      \n
    • \nreset() - clears the session and assigns a new session id.
    • \n
    • \nset(key, value) - assigns a value (string, object, etc) to a given key which will persist across requests. Returns the value.
    • \n
    • \nset(keysObject) - assigns values to multiple keys using each 'keysObject' top-level property. Returns the keysObject.
    • \n
    • \nget(key, clear) - retrieve value using a key. If 'clear' is 'true', key is cleared on return.
    • \n
    • \nclear(key) - clears key.
    • \n
    • \ntouch() - Manually notify the session of changes (when using get() and changing the content of the returned reference directly without calling set()).
    • \n
    • \nflash(type, message, isOverride) - stores volatile data - data that should be deleted once read. When given no arguments, it will return all of the flash messages and delete the originals. When given only a type, it will return all of the flash messages of that type and delete the originals. When given a type and a message, it will set or append that message to the given type. 'isOverride' used to indicate that the message provided should replace any existing value instead of being appended to it (defaults to false).
    • \n
    • \nlazy(enabled) - if set to 'true', enables lazy mode. In lazy mode, request.yar can be modified directly (e.g. setting request.yar.myKey to an object value), and those keys will be stored and loaded back. Lazy mode isn't as fast as the normal get/set because it has to store the session state on every responses regardless of any changes being made.
    • \n
    • \nawait commit(h) - used to manually prepare the session state and commit it into the response when the response is taken over in an onPreResponse handler. Normally, the yar onPreResponse handler performs the commit, but if an application extension handler takes over, yar doesn't get a chance to commit the state before the response goes out. The method requires the hapi h toolkit argument available in the extension handler.
    • \n
    \n

    yar adds the yar property to the server instance. The server.yar interface provides the following methods:

    \n
      \n
    • \nrevoke(id) - revokes the specified session.
    • \n
    \n", - "intro": "## Introduction\n\n**yar** add session support to hapi - a persistent state across multiple browser requests using an [iron](https://hapi.dev/module/iron) encrypted cookie and server-side storage. **yar** tries to fit session data into a session cookie based on a configured maximum size. If the content is too big to fit, it uses server storage via the [hapi plugin cache](https://hapi.dev/api#server.cache()) interface.\n", - "example": "## Example\n\nFor example, the first handler sets a session key and the second gets it:\n```js\nlet handler1 = (request, reply) => {\n\n request.yar.set('example', { key: 'value' });\n\n return null;\n};\n\nlet handler2 = (request, reply) => {\n\n const example = request.yar.get('example');\n return example.key; // Will send back 'value'\n};\n```\n\nThe plugin requires a password for encryption that must be at least 32 characters long:\n```js\nlet options = {\n storeBlank: false,\n cookieOptions: {\n password: 'the-password-must-be-at-least-32-characters-long',\n isSecure: true\n }\n};\n/*\nPlease note that there are other default cookie options that can impact your security.\nPlease look at the description of the cookie options below to make sure this is doing\nwhat you expect.\n*/\n\nconst server = new Hapi.Server();\n\ntry {\n await server.register({\n plugin: require('@hapi/yar'),\n options: options\n });\n} catch(err) {\n console.error(err);\n}\n\nawait server.start();\n```\n", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "10.1.1": { - "menu": "- [Introduction](#introduction)\n - [Differences from @hapi/cookie](#differences-from-hapicookie)\n- [Example](#example)\n- [Password considerations](#password-considerations)\n- [Cookie Options](#cookie-options)\n - [isSecure](#issecure)\n - [ignoreErrors](#ignoreerrors)\n - [clearInvalid](#clearinvalid)\n- [Options](#options)\n - [Route Options](#route-options)\n - [Methods](#methods)", - "api": "

    Introduction

    \n

    yar add session support to hapi - a persistent state across multiple browser requests using an iron encrypted cookie and server-side storage. yar tries to fit session data into a session cookie based on a configured maximum size. If the content is too big to fit, it uses server storage via the hapi plugin cache interface.

    \n

    Differences from @hapi/cookie

    \n

    The @hapi/cookie plugin provides similar facilities to yar. The approach of the two projects does differ in some regards, though.

    \n
      \n
    1. \nyar is focused on session support, and does not require that a user be logged in to have a session. @hapi/cookie only provides session storage for logged in users. If you need session handling for non-authenticated users, use yar.
    2. \n
    3. \nyar is capable of handling larger data sizes without any additional setup. If your session data gets larger than cookies can handle yar will push the data out to the server cache for you. By default this is memory storage, but can be any catbox supported cache storage, including mongo, redis, local disk, and more. @hapi/cookie can support larger session size as well, but requires you to handle connecting the cookie based session with your external data storage.
    4. \n
    \n

    Example

    \n

    For example, the first handler sets a session key and the second gets it:

    \n
    let handler1 = (request, reply) => {\n\n    request.yar.set('example', { key: 'value' });\n\n    return null;\n};\n\nlet handler2 = (request, reply) => {\n\n    const example = request.yar.get('example');\n    return example.key;     // Will send back 'value'\n};
    \n

    The plugin requires a password for encryption that must be at least 32 characters long:

    \n
    let options = {\n    storeBlank: false,\n    cookieOptions: {\n        password: 'the-password-must-be-at-least-32-characters-long',\n        isSecure: true\n    }\n};\n/*\nPlease note that there are other default cookie options that can impact your security.\nPlease look at the description of the cookie options below to make sure this is doing\nwhat you expect.\n*/\n\nconst server = new Hapi.Server();\n\ntry {\n  await server.register({\n      plugin: require('@hapi/yar'),\n      options: options\n  });\n} catch(err) {\n    console.error(err);\n}\n\nawait server.start();
    \n

    Password considerations

    \n

    Keep in mind some things in regard to your password:

    \n
      \n
    1. It should never be committed to the repository or hard coded in your code. Instead pass the password via environment variables or some other server configuration management option.
    2. \n
    3. In some situations it is possible that your password could be attacked remotely. So choose a password that is randomly generated. Use a random password generator to create something rather than creating your own. Make sure it is long and includes special characters.
    4. \n
    5. Consider rotating your cookie session password on a regular basis.
    6. \n
    \n

    Cookie Options

    \n

    You can read about more cookie options in the cookie options section.

    \n

    isSecure

    \n

    Set isSecure (default true) to false if you are using standard http. Take care to do this in development mode only though. You don't want to use cookies sent over insecure channels for session management. One way to take care of this is to use the NODE_ENV environment variable like this:

    \n
    let options = {\n    cookieOptions: {\n        isSecure: process.env.NODE_ENV !== 'development',\n        ...\n    }\n};
    \n

    ignoreErrors

    \n

    ignoreErrors (default true) tells hapi that it should not respond with a HTTP 400 error if the session cookie cannot decrypt. This could happen if the cookie is changed on the client, or more likely, if you change the cookie password in your settings. If you want to make this condition send an error like it did in prior versions, change this to false, but be aware that if you change your cookie password you will cause 400 errors to be returned to end users. In that case you should probably change this back to true for a short time to allow session cookies to get reset for the best user experience.

    \n

    You may turn this off, false, and try to use the hapi route state config option of failAction to instead get an event whenever a bad session cookie is encountered. This can allow more sophisticated handling strategies or even allow for mitigation of brute force attacks on your cookie password. See server.state() documentation for more details.

    \n

    clearInvalid

    \n

    clearInvalid (default true) tells hapi that if a session cookie is invalid for any reason, to clear it from the browser. This prevents hapi from having to reprocess the bad cookie on future requests. In general you'll probably want this on, but if you'd prefer that session cookies be dealt with in some other way you may set this to false.

    \n

    Options

    \n
      \n
    • \nname - determines the name of the cookie used to store session information. Defaults to session.
    • \n
    • \nmaxCookieSize - maximum cookie size before using server-side storage. Defaults to 1K. Set to zero to always use server-side storage.
    • \n
    • \nstoreBlank - determines whether to store empty session before they've been modified. Defaults to true.
    • \n
    • \nerrorOnCacheNotReady - will cause yar to throw an exception if trying to persist to cache when the cache is unavailable. Setting this to false will allow applications using yar to run uninterrupted if the cache is not ready (however sessions will not be saving). Defaults to true.
    • \n
    • \ncache - hapi cache options which includes\n(among other options):\n
        \n
      • \nexpiresIn - server-side storage expiration (defaults to 1 day).
      • \n
      \n
    • \n
    • \ncookieOptions - the configuration for cookie-specific features:\n
        \n
      • \npassword - (Required) used to encrypt and sign the cookie data.
      • \n
      • \npath - determines the cookie path. Defaults to '/'.
      • \n
      • \nisSameSite - enables the same-site cookie parameter. Default to 'Lax'. Can be 'Strict'|'Lax'|'None'|false.
      • \n
      • \nisSecure - determines whether or not to transfer using TLS/SSL. Defaults to true.
      • \n
      • \nisHttpOnly - determines whether or not to set HttpOnly option in cookie. Defaults to false.
      • \n
      • \nttl - sets the time for the cookie to live in the browser, in milliseconds. Defaults to null (session time-life - cookies are deleted when the browser is closed).
      • \n
      • \ncontextualize - a function using the signature async function(definition, request) used to override a request-specific cookie settings where:\n
          \n
        • \ndefinition - a copy of the options to be used for formatting the cookie that can be manipulated by the function to customize the request cookie header. Note that changing the definition.contextualize property will be ignored.
        • \n
        • \nrequest - the current request object.
        • \n
        \n
      • \n
      \n
    • \n
    • \ncustomSessionIDGenerator - an optional function to create custom session IDs. Must return a string and have the signature function (request) where:\n
        \n
      • \nrequest - (optional) is the original request received from the client.
      • \n
      \n
    • \n
    \n

    Route Options

    \n

    You can also add these options on a route per route basis at config.plugins.yar:

    \n
      \n
    • \nskip - a boolean value which, if true, means no session will be attached to the request (defaults to false).
    • \n
    \n

    Methods

    \n

    yar adds the yar property to every request object and initializes the yar.id on the first request from each browser. The request.yar interface provides the following methods:

    \n
      \n
    • \nreset() - clears the session and assigns a new session id.
    • \n
    • \nset(key, value) - assigns a value (string, object, etc) to a given key which will persist across requests. Returns the value.
    • \n
    • \nset(keysObject) - assigns values to multiple keys using each 'keysObject' top-level property. Returns the keysObject.
    • \n
    • \nget(key, clear) - retrieve value using a key. If 'clear' is 'true', key is cleared on return.
    • \n
    • \nclear(key) - clears key.
    • \n
    • \ntouch() - Manually notify the session of changes (when using get() and changing the content of the returned reference directly without calling set()).
    • \n
    • \nflash(type, message, isOverride) - stores volatile data - data that should be deleted once read. When given no arguments, it will return all of the flash messages and delete the originals. When given only a type, it will return all of the flash messages of that type and delete the originals. When given a type and a message, it will set or append that message to the given type. 'isOverride' used to indicate that the message provided should replace any existing value instead of being appended to it (defaults to false).
    • \n
    • \nlazy(enabled) - if set to 'true', enables lazy mode. In lazy mode, request.yar can be modified directly (e.g. setting request.yar.myKey to an object value), and those keys will be stored and loaded back. Lazy mode isn't as fast as the normal get/set because it has to store the session state on every responses regardless of any changes being made.
    • \n
    • \nawait commit(h) - used to manually prepare the session state and commit it into the response when the response is taken over in an onPreResponse handler. Normally, the yar onPreResponse handler performs the commit, but if an application extension handler takes over, yar doesn't get a chance to commit the state before the response goes out. The method requires the hapi h toolkit argument available in the extension handler.
    • \n
    \n

    yar adds the yar property to the server instance. The server.yar interface provides the following methods:

    \n
      \n
    • \nrevoke(id) - revokes the specified session.
    • \n
    \n", - "intro": "", - "example": "", - "usage": "", - "faq": "", - "advanced": "", - "license": "BSD" - }, - "slogan": "A hapi session manager.", - "forks": 59, - "stars": 133, - "date": "2024-10-23T21:37:22Z", - "updated": "Wed Oct 23 2024", - "link": "https://github.com/hapijs/yar" - } -} \ No newline at end of file diff --git a/static/lib/resources.md b/static/lib/resources.md deleted file mode 100644 index df531705..00000000 --- a/static/lib/resources.md +++ /dev/null @@ -1,163 +0,0 @@ -## Books - -* [Practical Hapi ](https://www.amazon.com/Practical-hapi-Build-Industry-Studies/dp/1484258045) - - This book walks you through an end to end implementation of hapi, nodejs and asynchronous programming, right through Node JS Event Loop, Rest API best practices, Hapi Server Setup, Routing, Post and Get Requests with Payload and Parameters, Database Connectivity, Sequelize, Validation, Plugin Architecture, npm repository and its optimum use, swaggerui Integration, Postman tricks, Tricks and Tips for Neater Code, Constructs like await, fetch etc., Nodemon and much much more!!!! A capstone project with industry level challenges is what takes the cake in explaining Hapi in context. The framework is a great choice since it was tried and tested for high production demands and is backed by the best. With further releases coming, this framework is here to stay and is certainly an addition to your skills. - -* [Developing a hapi Edge ](http://www.amazon.com/Developing-hapi-Edge-Framework-Services-ebook/dp/B013CWI3MY) - - This book shows you how to build enterprise-quality web applications using the hapi service and application framework. By walking through the creation of a real web application, hapi-plugins.com, you will learn how to configure and start hapi, build out APIs, perform authentication, validation, caching, and so much more. You will also discover tips and tricks used in production hapi deployments regarding plugins, testing, debugging, and security. hapi was developed and is used within Walmart and has been battle tested during the most critical days of the year for e-commerce websites, Black Friday. It has proven itself to not only handle extremely high production loads at a breeze but is also a pleasure to work with. The aim of the framework was to address pitfalls in the other established out there, and it has done so without fail. - -* [Getting Started with hapi.js ](https://www.packtpub.com/web-development/getting-started-hapijs) - - This book introduces hapi.js and walks through the creation of your first working application using the out-of-the-box features hapi.js provides. Packed with real-world problems and examples, this book covers some of the basic concepts of hapi.js and Node.js and takes you through the typical journey you'll face when developing an application. Starting with easier concepts such as routing requests, building APIs serving JSON, using templates to build websites and applications, and connecting databases, we then move on to more complex problems such as authentication, model validation, caching, and techniques for structuring your codebase to scale gracefully. You will also develop skills to ensure your application's reliability through testing, code coverage, and logging. By the end of this book, you'll be equipped with all the skills you need to build your first fully featured application. This book will be invaluable if you are investigating Node.js frameworks or planning on using hapi.js in your next project. - -* [hapi.js in Action ](http://manning.com/harrison) - - Packed with examples, this book takes you from your first simple server through the skills you'll need to build a complete application. In it, you'll learn how to build websites and APIs, implement caching, authentication, validation, error handling, and a lot more. You'll also explore vital techniques for production applications, such as testing, monitoring, deployment, and documentation. - -* [hapi with TypeScript ](http://hapibook.jjude.com) - - This book introduces TypeScript into developing web applications with hapi. TypeScript, a language developed by Microsoft, brings the benefits of strong types and object-oriented programming to JavaScript. With ample code samples, this book teaches all aspects of developing a web application in hapi with TypeScript. It also introduces, hapidock, a docker container with all required components for developing in hapi. With hapidock, you can develop and test hapi applications in a production-like environment. Through this book, you will learn to build stable enterprise-level server applications. The book is free to read at http://hapibook.jjude.com. E-books (pdf, mobi, and epub) and fully executable code samples are available after purchase. - -* [Hapi.js Handbook ](https://leanpub.com/hapi-handbook) - - This handbook is a collection of tutorials for Hapi.js framework. You can find tutorials about validation, working with 3rd plugins, sending/getting data, template engines, integrations with DB and etc. - -## Boilerplates - -* [appy](https://github.com/JKHeadley/appy) - - A user system leveraging rest-hapi to bootstrap your app. - -* [aqua](https://github.com/jedireza/aqua) - - A website and user system. Implemented with React and Flux. - -* [frame](https://github.com/jedireza/frame) - - A user system API. Bring your own front-end. - -* [generator-hapi-service](https://github.com/normative/generator-hapi-service) - - Yeoman generator for hapi web services. - -* [generator-hapi-style](https://github.com/jedireza/generator-hapi-style) - - Yeoman generator for scaffolding hapi apps and plugins. - -* [hanx.js](https://github.com/youhusam/hanx.js) - - Full-stack boilerplate with Node.js, hapi, PostgreSQL and AngularJS (MEAN.js port) - -* [hapi-angular-quickstart](https://github.com/ptpaterson/hapi-angular-quickstart) - - Angular2 Quickstart example wrapped into a Hapi plugin. - -* [hapi-api](https://github.com/rjmreis/hapi-api) - - Lean hapi API Boilerplate with an opinionated view on project structure - -* [hapi-cli](https://github.com/AMoreaux/hapi-cli) - - Boilerplate for hapi with mongodb, mongoose. Work with Hapi V17. - -* [hapi-dash](https://github.com/smaxwellstewart/hapi-dash) - - A boilerplate hapi web and API server example, with frontend dashboard - -* [hapi-moon](https://github.com/metoikos/hapi-moon) - - Hassle-free and production ready hapi.js Server boilerplate - -* [hapi-ninja](https://github.com/poeticninja/hapi-ninja) - - Boilerplate hapi server example. Node.js, hapi, and Swig. - -* [hapi-react-starter-kit](https://github.com/Dindaleon/hapi-react-starter-kit) - - A hapi React Starter kit with react-router, redux, react-transform. - -* [hapi-starter-kit](https://github.com/Codigami/hapi-starter-kit) - - Hapi.js based REST boilerplate which uses latest ES7/ES8 features (async/await) with code coverage and follows best pratices - -* [hapi-struct](https://github.com/MarcHanin/hapi-struct) - - Simple Hapi server boilerplate with user authentication (MongoDB) - -* [hapify boilerplate](https://github.com/Tractr/boilerplate-hapijs/) - - Dynamic boilerplate providing an API built with HapiJS, MongoDB and Docker (build for [Hapify.io](https://hub.hapify.io/)) - -* [hapitodo](https://github.com/genediazjr/hapitodo) - - A TodoMVC jQuery front-end with a Hapi back-end. - -* [jolly](https://github.com/ravisuhag/jolly) - - Production ready boilerplate for hapi.js - -* [mullet](https://github.com/lynnaloo/mullet) - - Boilerplate hapi Server with Facebook and React - -* [the pal boilerplate](https://github.com/hapipal/boilerplate) - - A friendly, proven starting place for your next hapi plugin or deployment - -* [rest-hapi](https://github.com/JKHeadley/rest-hapi) - - A RESTful API generator built around the hapi framework and mongoose ODM. - -* [rutha](https://github.com/molekilla/rutha) - - frontend stack for hapi (server, api) and Angular (client) - -* [snowflake-hapi-openshift](https://github.com/bartonhammond/snowflake-hapi-openshift) - - Hapi Server running on OpenShift/local backed by MongoDB & Redis - Performance Tested with BlazeMeter & JMeter - -* [start-hapiness](https://github.com/thebergamo/start-hapiness) - - A Boilerplate that help you to create fast project with Hapi + MongoDB - -* [testing-hapi](https://github.com/pashariger/testing-hapi) - - Hapi API Server with Swagger Docs, Testing and Travis CI - -* [typehapily](https://github.com/tejzpr/typehapily) - - A TypeScript based boilerplate for HAPIJS with TypeORM & Dynamic Linting - -## Projects built with hapi.js - -* [Colonizers](https://github.com/colonizers/colonizers) - - A HTML5 multiplayer game, based on the popular board game "Catan" by Klaus Teuber. - -* [MasteryJS](https://github.com/labibramadhan/mastery) - - Scalable API Server framework build on top of Hapi and Sequelize. - -* [Paydash](https://github.com/hks-epod/paydash) - - Worker payments dashboard for MGNREGA, India's employment guarantee programme. - -* [Postmile](https://github.com/hueniverse/postmile) - - Postmile is a collaborative list making tool built using hapi.js, Node.js, and MongoDB. - -## Videos - -* [Hapi Days Conf 2014 Videos](https://www.youtube.com/playlist?list=PLzc1AUDlJ7WvcMnv3NaEwgh0i2nJKl0GX) - - hapi days is a one day conference that's focused on hapi and the people that use it. - -* [Modern backend with TypeScript, Hapi, PostgreSQL and Prisma](https://www.youtube.com/watch?v=d9v7umfMNkM&list=PLn2e1F9Rfr6k7ULe0gzQvtaXLoXrPqpki&index=2&ab_channel=Prisma) - - A series of live streams and articles on building a backend with TypeScript, Hapi, PostgreSQL, and Prisma. - -* [Nodevember Conf 2014 hapi.js Workshop](https://www.youtube.com/watch?v=TEKFocYepFY) - - A hapi from Scratch Tutorial By Ben Acker And Wyatt Preul at Nodevember Conf. diff --git a/static/lib/supportPolicy.md b/static/lib/supportPolicy.md deleted file mode 100644 index cf35bb2c..00000000 --- a/static/lib/supportPolicy.md +++ /dev/null @@ -1,43 +0,0 @@ -# **hapi** modules LTS support policy - -The hapi core module and its dependencies are published under the following support rules: - -Every **major** version of the [core module](https://github.com/hapijs/hapi) receives at least one year of support from the time of publication of the first `x.0.0` release. When a new **major** version is published, the previous **major** version gets at least 3 months of support from that moment. There are typically one to three major releases each year and most are simple to upgrade. Core dependencies are maintained as long as they are used by a supported core version. - -## Current versions - -The full and up to date list of supported modules under a free open source license is available at the [module status page](https://hapi.dev/resources/status/). - -## Latest version - -The latest version of the `hapi` module published to [npm](https://www.npmjs.com/package/hapi) is the current actively supported version. It receives bug fixes, security patches, and new features on an ongoing basis. - -Only the latest published module of the current **major** version is actively supported. For example, if the current published version is `v10.2.3`, it is the only supported version of the `v10.x.x` branch. If you are using an older version of `v10.x.x` such as `v10.0.4`, you must upgrade to `v10.2.3` before opening issues and seeking support. - -## Previous **major** version - -Once a new major version is published, the previous major version goes into LTS maintenance mode. Versions in maintenance mode receive critical bug fixes and security patches but do not receive new features. - -Each major version branch stays in maintenance mode for whichever is the **longer** period: -- 1 year from the day of the first publication of **this** major version, or -- 3 months from the day of the first publication of the **following** major version. - -For example, if: -- version `v9.0.0` was published on January 1st, 2010, and -- version `v10.0.0` was published on May 1st, 2010 - -Support for `v9.x.x` will end on January 1st, 2011 (one year from time of initial publication of the `v9.0.0` release). - -However, if: -- version `v9.0.0` was published on January 1st, 2010, and -- version `v10.0.0` was published on December 1st, 2010 - -Support for `v9.x.x` will end on March 1st, 2011 (three months from time of initial publication of the `v10.0.0` release). - -## Deprecated versions - -When a version is no longer supported, it will be marked as `deprecated` in the npm registry. You may continue using it at your own risk, ignoring the warning messages. - -## Commercial support - -Every module used by hapi v16 to v19 has a maintained LTS version available under a commercial license. For more information, visit the [commercial support issue](https://github.com/hapijs/hapi/issues/4114) or contact [Sideway Support](mailto:support@sideway.com). diff --git a/static/lib/tutorials/.eslintrc b/static/lib/tutorials/.eslintrc deleted file mode 100644 index 4c6637f9..00000000 --- a/static/lib/tutorials/.eslintrc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "rules": { - "hapi/hapi-scope-start": 0, - "strict": 0, - "no-unused-vars": 0, - "no-undef": 0, - "object-shorthand": 0, - "indent": 0 - } -} diff --git a/static/lib/tutorials/en_US/community.md b/static/lib/tutorials/en_US/community.md deleted file mode 100644 index 85dcda48..00000000 --- a/static/lib/tutorials/en_US/community.md +++ /dev/null @@ -1,51 +0,0 @@ -# Community Tutorials - -* [Authentication and Authorization with hapi](https://medium.com/@poeticninja/authentication-and-authorization-with-hapi-5529b5ecc8ec) - - Article on how to secure your hapi application. - -* [Building a Chat Application with hapi.js, Socket.io and Redis](https://github.com/dwyl/hapi-socketio-redis-chat-example) - - Real-time chat application built using hapi.js, Socket.io and Redis Pub/Sub with end-to-end tests. - -* [Building a modern backend with TypeScript, Hapi, PostgreSQL and Prisma](https://www.prisma.io/blog/series/modern-backend-bdes2ps5kibb) - - A series of live streams and articles on building a backend with TypeScript, Hapi, PostgreSQL, and Prisma. - The series covers data modeling, CRUD, aggregations, REST, validation with Joi, testing, authentication, authorization, integration with other APIs, continuous integration and deployment with GitHub Actions and Heroku. - The series explores and demonstrates different patterns, problems, and architectures for a modern backend by solving a concrete problem: a grading system for online courses. This is a good example because it features diverse relations types and is complex enough to represent a real-world use case. - -* [Handling plugin dependencies](https://hapipal.com/best-practices/handling-plugin-dependencies) - - In celebration of hapi plugin boundaries, here we offer a concrete approach to taming inter-plugin dependencies. - -* [hapi tutorial series (30+ tutorials)](https://futurestud.io/tutorials/hapi-get-your-server-up-and-running) - - This in-depth tutorial series on hapi covers route setup, authentication, plugins, request & response handling, and much more. - -* [hapi.js tutorials covering various topics](https://content.nanobox.io/tag/hapi.js/) - - A growing list of tutorials covering hapi.js application development, deployment, optimization, and production management (scaling, monitoring, etc.). - -* [How to create a REST API with hapi](http://blog.webkid.io/how-to-create-a-rest-api-with-hapi/) - - Tutorial about how to create a RESTful API with the Plugins Dogwater (Waterline ORM) and Bedwetter. - -* [The joys of server / plugin separation](https://hapipal.com/best-practices/server-plugin-separation) - - The joyful act of decoupling your application plugin from its deployment will make your hapi app more portable and simpler to test. - -* [rate-limiter-flexible-plugin-example](https://github.com/animir/node-rate-limiter-flexible/wiki/Hapi-plugin) - - Plugin example of rate limiting and DDoS protection with rate-limiter-flexible package - -* [Run hapi.js on Google Cloud Platform](https://cloud.google.com/nodejs/resources/frameworks/hapi) - - Tutorial and cloneable sample app showing how to create and deploy a hapi.js application on Google App Engine. - -* [Catbox-Redis and Cookie Auth Example](https://github.com/johnmanko/catbox-redis-example) - - Demonstrate how to use @hapi/catbox-redis and @hapi/cookie. - -* [WittCode's Hapi Tutorial Series](https://youtube.com/playlist?list=PLkqiWyX-_LotaQ9AuppIAXl0xyV-P5Ms-) - - 10 videos starting from creating a Hapi server, adding routes, plugins, through to using Sequelize/MySQL and cookie authentication. diff --git a/static/lib/tutorials/en_US/index.js b/static/lib/tutorials/en_US/index.js deleted file mode 100644 index 46b9c47a..00000000 --- a/static/lib/tutorials/en_US/index.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict' - -export const auth = require('./auth.md') - -export const caching = require('./caching.md') - -export const cookies = require('./cookies.md') - -export const community = require('./community.md') - -export const gettingstarted = require('./gettingstarted.md') - -export const logging= require('./logging.md') - -export const plugins = require('./plugins.md') - -export const routing = require('./routing.md') - -export const servermethods = require('./servermethods.md') - -export const servingfiles = require('./servingfiles.md') - -export const testing = require('./testing.md') - -export const validation = require('./validation.md') - -export const views = require('./views.md') - -export const expresstohapi = require('./expresstohapi.md') diff --git a/static/lib/tutorials/index.js b/static/lib/tutorials/index.js deleted file mode 100644 index f2c9acaa..00000000 --- a/static/lib/tutorials/index.js +++ /dev/null @@ -1,7 +0,0 @@ -'use strict' - -exports.en_US = require('./en_US') -exports.pt_BR = require('./pt_BR') -exports.ko_KR = require('./ko_KR') -exports.tr_TR = require('./tr_TR') -exports.zh_CN = require('./zh_CN') diff --git a/static/lib/tutorials/ko_KR/index.js b/static/lib/tutorials/ko_KR/index.js deleted file mode 100644 index d58502fe..00000000 --- a/static/lib/tutorials/ko_KR/index.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict' - -exports.auth = require('./auth.md') - -exports.caching = require('./caching.md') - -exports.cookies = require('./cookies.md') - -exports.community = require('./community.md') - -exports.gettingstarted = require('./gettingstarted.md') - -exports.logging= require('./logging.md') - -exports.plugins = require('./plugins.md') - -exports.routing = require('./routing.md') - -exports.servermethods = require('./servermethods.md') - -exports.servingfiles = require('./servingfiles.md') - -exports.testing = require('./testing.md') - -exports.validation = require('./validation.md') - -exports.views = require('./views.md') - -exports.expresstohapi = require('./expresstohapi.md') diff --git a/static/lib/tutorials/pt_BR/index.js b/static/lib/tutorials/pt_BR/index.js deleted file mode 100644 index d58502fe..00000000 --- a/static/lib/tutorials/pt_BR/index.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict' - -exports.auth = require('./auth.md') - -exports.caching = require('./caching.md') - -exports.cookies = require('./cookies.md') - -exports.community = require('./community.md') - -exports.gettingstarted = require('./gettingstarted.md') - -exports.logging= require('./logging.md') - -exports.plugins = require('./plugins.md') - -exports.routing = require('./routing.md') - -exports.servermethods = require('./servermethods.md') - -exports.servingfiles = require('./servingfiles.md') - -exports.testing = require('./testing.md') - -exports.validation = require('./validation.md') - -exports.views = require('./views.md') - -exports.expresstohapi = require('./expresstohapi.md') diff --git a/static/lib/tutorials/tr_TR/index.js b/static/lib/tutorials/tr_TR/index.js deleted file mode 100644 index d58502fe..00000000 --- a/static/lib/tutorials/tr_TR/index.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict' - -exports.auth = require('./auth.md') - -exports.caching = require('./caching.md') - -exports.cookies = require('./cookies.md') - -exports.community = require('./community.md') - -exports.gettingstarted = require('./gettingstarted.md') - -exports.logging= require('./logging.md') - -exports.plugins = require('./plugins.md') - -exports.routing = require('./routing.md') - -exports.servermethods = require('./servermethods.md') - -exports.servingfiles = require('./servingfiles.md') - -exports.testing = require('./testing.md') - -exports.validation = require('./validation.md') - -exports.views = require('./views.md') - -exports.expresstohapi = require('./expresstohapi.md') diff --git a/static/lib/tutorials/zh_CN/index.js b/static/lib/tutorials/zh_CN/index.js deleted file mode 100644 index d58502fe..00000000 --- a/static/lib/tutorials/zh_CN/index.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict' - -exports.auth = require('./auth.md') - -exports.caching = require('./caching.md') - -exports.cookies = require('./cookies.md') - -exports.community = require('./community.md') - -exports.gettingstarted = require('./gettingstarted.md') - -exports.logging= require('./logging.md') - -exports.plugins = require('./plugins.md') - -exports.routing = require('./routing.md') - -exports.servermethods = require('./servermethods.md') - -exports.servingfiles = require('./servingfiles.md') - -exports.testing = require('./testing.md') - -exports.validation = require('./validation.md') - -exports.views = require('./views.md') - -exports.expresstohapi = require('./expresstohapi.md') diff --git a/store/README.md b/store/README.md deleted file mode 100644 index 1972d277..00000000 --- a/store/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# STORE - -**This directory is not required, you can delete it if you don't want to use it.** - -This directory contains your Vuex Store files. -Vuex Store option is implemented in the Nuxt.js framework. - -Creating a file in this directory automatically activates the option in the framework. - -More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/vuex-store). diff --git a/store/index.js b/store/index.js deleted file mode 100644 index ac0ace53..00000000 --- a/store/index.js +++ /dev/null @@ -1,163 +0,0 @@ -const start = require("../static/lib/tutorials/en_US"); - -export const state = () => ({ - page: start.gettingstarted.default, - display: "home", - language: "en_US", - version: "", - example: false, - intro: false, - usage: false, - faq: false, - advanced: false, - family: "joi", - schema: - "//Insert your joi schema here \n" + - "Joi.object({\n" + - " username: Joi.string().alphanum().min(3).max(30).required(),\n" + - " password: Joi.string().pattern(/^[a-zA-Z0-9]{3,30}$/),\n" + - ' repeat_password: Joi.ref("password"),\n' + - " access_token: [Joi.string(), Joi.number()],\n" + - " birth_year: Joi.number().integer().min(1900).max(2013),\n" + - ' email: Joi.string().email({ minDomainSegments: 2, tlds: { allow: ["com", "net"] } } )\n' + - "}).with('username', 'birth_year').xor('password', 'access_token').with('password', 'repeat_password')", - validate: - "//Insert data to validate here \n" + - "{ \n" + - ' username: "abc",\n' + - ' password: "password",\n' + - ' repeat_password: "password",\n' + - " birth_year: 1994\n" + - "}", - modules: [ - "accept", - "ammo", - "b64", - "basic", - "bell", - "boom", - "bossy", - "bounce", - "bourne", - "call", - "catbox", - "catbox-memcached", - "catbox-memory", - "catbox-object", - "catbox-redis", - "code", - "content", - "cookie", - "crumb", - "cryptiles", - "eslint-plugin", - "file", - "glue", - "h2o2", - "heavy", - "hoek", - "inert", - "iron", - "jwt", - "lab", - "log", - "mimos", - "nes", - "nigel", - "oppsy", - "pez", - "podium", - "scooter", - "shot", - "somever", - "statehood", - "subtext", - "teamwork", - "topo", - "vise", - "vision", - "wreck", - "yar" - ] -}); - -export const mutations = { - setPage(state, page) { - state.page = page; - }, - setDisplay(state, display) { - state.display = display; - }, - setLanguage(state, language) { - state.language = language; - }, - setVersion(state, version) { - state.version = version; - }, - setExample(state, example) { - state.example = example; - }, - setIntro(state, intro) { - state.intro = intro; - }, - setUsage(state, usage) { - state.usage = usage; - }, - setFaq(state, faq) { - state.faq = faq; - }, - setAdvanced(state, advanced) { - state.advanced = advanced; - }, - setFamily(state, family) { - state.family = family; - }, - setSchema(state, schema) { - state.schema = schema; - }, - setValidate(state, validate) { - state.validate = validate; - } -}; - -export const getters = { - loadPage(state) { - return state.page; - }, - loadDisplay(state) { - return state.display; - }, - loadLanguage(state) { - return state.language; - }, - loadVersion(state) { - return state.version; - }, - loadModules(state) { - return state.modules; - }, - loadExample(state) { - return state.example; - }, - loadIntro(state) { - return state.intro; - }, - loadUsage(state) { - return state.usage; - }, - loadFaq(state) { - return state.faq; - }, - loadAdvanced(state) { - return state.advanced; - }, - loadFamily(state) { - return state.family; - }, - loadSchema(state) { - return state.schema; - }, - loadValidate(state) { - return state.validate; - } -}; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..cd90d999 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,13 @@ +{ + "include": [".vitepress/**/*.ts", "**/*.ts", "**/*.tsx"], + "compilerOptions": { + "target": "es2024", + "module": "node20", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true, + "types": ["node", "./env.d.ts"] + } +} diff --git a/utils/clipboard.js b/utils/clipboard.js deleted file mode 100644 index 30b1fb47..00000000 --- a/utils/clipboard.js +++ /dev/null @@ -1,36 +0,0 @@ -export function copyToClipboard(content) { - const el = document.createElement("textarea"); - el.value = content; - document.body.appendChild(el); - el.select(); - document.execCommand("copy"); - document.body.removeChild(el); -} - -export function setCodeClipboards(listeners) { - const snippets = document.querySelectorAll(".highlight-source-js"); - - for (let snippet of snippets) { - const copyClipBoardElement = document.createElement("span"); - copyClipBoardElement.classList.add( - "copy-clipboard", - "copy-clipboard-absolute" - ); - copyClipBoardElement.title = "Copy code snippet"; - - const eventListener = function() { - const code = snippet.firstChild.textContent; - copyToClipboard(code); - - copyClipBoardElement.classList.add("copy-clipboard-checked"); - setTimeout(() => { - copyClipBoardElement.classList.remove("copy-clipboard-checked"); - }, 3000); - }; - copyClipBoardElement.addEventListener("click", eventListener); - - listeners.set(copyClipBoardElement, eventListener); - - snippet.appendChild(copyClipBoardElement); - } -}