Browse Source

Implement auth and tests

master
TheoryOfNekomata 3 years ago
parent
commit
a6d1ba6332
31 changed files with 913 additions and 55 deletions
  1. +0
    -2
      .gitignore
  2. +27
    -12
      REQUIREMENTS.md
  3. +3
    -1
      packages/app-web/cypress.json
  4. +5
    -0
      packages/app-web/cypress/fixtures/example.json
  5. +22
    -1
      packages/app-web/cypress/integration/login.ts
  6. +22
    -0
      packages/app-web/cypress/integration/ringtone.ts
  7. +5
    -0
      packages/app-web/cypress/plugins/index.ts
  8. +3
    -0
      packages/app-web/package.json
  9. +41
    -0
      packages/app-web/src/components/molecules/brand/Brand/index.tsx
  10. +3
    -3
      packages/app-web/src/components/molecules/forms/TextArea/index.tsx
  11. +1
    -0
      packages/app-web/src/components/molecules/forms/TextInput/index.tsx
  12. +20
    -0
      packages/app-web/src/components/organisms/forms/CreateRingtone/index.tsx
  13. +10
    -3
      packages/app-web/src/components/organisms/forms/Omnisearch/index.tsx
  14. +21
    -1
      packages/app-web/src/components/templates/CreateRingtone/index.tsx
  15. +12
    -2
      packages/app-web/src/modules/ringtone/client.ts
  16. +57
    -0
      packages/app-web/src/modules/ringtone/endpoints.ts
  17. +4
    -0
      packages/app-web/src/pages/_app.tsx
  18. +3
    -0
      packages/app-web/src/pages/api/auth/[...auth0].ts
  19. +10
    -5
      packages/app-web/src/pages/index.tsx
  20. +33
    -3
      packages/app-web/src/pages/my/create/ringtone/index.tsx
  21. +40
    -0
      packages/app-web/src/pages/ringtones/index.tsx
  22. +3
    -3
      packages/app-web/src/utils/api/fetch.ts
  23. +538
    -4
      packages/app-web/yarn.lock
  24. +1
    -0
      packages/service-core/package.json
  25. +1
    -1
      packages/service-core/src/modules/ringtone/controller.ts
  26. +2
    -2
      packages/service-core/src/modules/ringtone/repository.ts
  27. +8
    -0
      packages/service-core/src/plugins/cors.ts
  28. +0
    -9
      packages/service-core/src/routes/example/index.ts
  29. +0
    -1
      packages/service-core/test/helper.ts
  30. +10
    -2
      packages/service-core/test/routes/api/ringtones.test.ts
  31. +8
    -0
      packages/service-core/yarn.lock

+ 0
- 2
.gitignore View File

@@ -73,8 +73,6 @@ com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
.idea/httpRequests
.idea/caches/build_file_checksums.ser
.DS_Store
.AppleDouble
.LSOverride


+ 27
- 12
REQUIREMENTS.md View File

@@ -3,27 +3,41 @@
## Authentication

- As a client, I want to log in to the service.
- [ ] In the front-end, the client provides a username, and a password to request login to the back-end.
- [ ] In the back-end, the server processes the login request from the front-end.
- [X] In the front-end, the client provides a username, and a password to request login to the back-end.
- [X] In the back-end, the server processes the login request from the front-end.
- As a client, I want to log out from the service.
- [ ] In the front-end, the client requests logout to the backend.
- [ ] In the back-end, the server processes the logout request from the front-end.
- [X] In the front-end, the client requests logout to the backend.
- [X] In the back-end, the server processes the logout request from the front-end.

## Ringtone

- As a client, I want to download a ringtone.
- [ ] In the front-end, the client provides a ringtone ID to request a ringtone from the back-end.
- [ ] In the back-end, the server sends the ringtone data to the front-end.
- As a client, I want to search for composers and ringtones.
- [ ] In the front-end, the client requests provides a search keyword to request for composers and ringtones from the back-end.
- [ ] In the back-end, the server retrieves the composers and ringtones whose name matches the search keyword provided
by the front-end.
- As a client, I want to browse ringtones.
- [ ] In the front-end, the client provides an optional skip and take arguments to request multiple ringtones from the back-end.
- [ ] In the front-end, the client provides an optional skip and take arguments to request multiple ringtones from the
back-end.
- [X] In the back-end, the server sends the ringtones to the front-end.
- As a client, I want to view the ringtones made by a composer.
- [ ] In the front-end
- [ ] In the back-end

## Search

- As a client, I want to search for ringtones.
- [ ] In the front-end, the client requests provides a search keyword to request for ringtones from the back-end.
- [X] In the back-end, the server retrieves the ringtones whose name matches the search keyword provided by the
front-end.
- As a client, I want to search for composers.
- [ ] In the front-end, the client requests provides a search keyword to request for composers from the back-end.
- [ ] In the back-end, the server retrieves the composers whose name matches the search keyword provided by the
front-end.

## Composer

- As a composer, I want to create a ringtone.
- [ ] In the front-end, the client inputs ringtone data to the view.
- [ ] In the front-end, the client sends the ringtone data to the back-end.
- [X] In the front-end, the client inputs ringtone data to the view.
- [X] In the front-end, the client sends the ringtone data to the back-end.
- [X] In the back-end, the server stores the ringtone data.
- As a composer, I want to update a ringtone.
- [ ] In the front-end, the client modifies the ringtone data retrieved from the back-end and loaded on the view.
@@ -37,4 +51,5 @@
- [X] In the back-end, the server untags a ringtone as deleted if its ID matches the one provided by the front-end.
- As a composer, I want to hard-delete of a ringtone.
- [ ] In the front-end, the client provides a ringtone ID to request a ringtone's deletion rollback to the back-end.
- [X] In the back-end, the server removes a ringtone in the database if its ID matches the one provided by the front-end.
- [X] In the back-end, the server removes a ringtone in the database if its ID matches the one provided by the
front-end.

+ 3
- 1
packages/app-web/cypress.json View File

@@ -1 +1,3 @@
{}
{
"baseUrl": "http://localhost:3000"
}

+ 5
- 0
packages/app-web/cypress/fixtures/example.json View File

@@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}

+ 22
- 1
packages/app-web/cypress/integration/login.ts View File

@@ -1,5 +1,26 @@
describe('login', () => {
beforeEach(() => {
cy
.visit('/api/auth/logout')
})

it('should log the current user in', () => {
cy.visit('http://localhost:3000')
cy
.visit('/api/auth/login')

cy
.get('input[name="email"]')
.type(Cypress.env('USERNAME'))

cy
.get('input[name="password"]')
.type(Cypress.env('PASSWORD'))

cy
.get('form')
.submit()
.wait(3000)
.location('href')
.should('equal', 'http://localhost:3000')
})
})

+ 22
- 0
packages/app-web/cypress/integration/ringtone.ts View File

@@ -0,0 +1,22 @@
describe('ringtone', () => {
beforeEach(() => {
cy.visit('/my/create/ringtone')
})

it('should be created', () => {
cy.intercept('POST', new URL('/api/ringtones', Cypress.env('API_BASE_URL')).toString()).as('request')
cy
.get('input[name="name"]')
.type('Happy Birthday')

cy
.get('textarea[name="data"]')
.type('8g1 8g1 4a1 4g1 4c2 2b1 8g1 8g1 4a1 4g1 4d2 2c2 8g1 8g1 4g2 4e2 8c2 8c2 4b1 4a1 8f2 8f2 4e2 4c2 4d2 2c2')

cy
.get('form[aria-label="Create Ringtone"]')
.submit()

cy.wait('@request').its('response.statusCode').should('equal', 201)
})
})

+ 5
- 0
packages/app-web/cypress/plugins/index.ts View File

@@ -12,6 +12,8 @@
// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)

import dotenvPlugin = require('cypress-dotenv')

/**
* @type {Cypress.PluginConfig}
*/
@@ -19,4 +21,7 @@
export default (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config

config = dotenvPlugin(config)
return config
}

+ 3
- 0
packages/app-web/package.json View File

@@ -10,6 +10,7 @@
"e2e": "cypress"
},
"dependencies": {
"@auth0/nextjs-auth0": "^1.3.1",
"@tesseract-design/viewfinder": "^0.1.1",
"@theoryofnekomata/formxtr": "^0.1.2",
"next": "10.2.0",
@@ -25,6 +26,8 @@
"@types/react": "^17.0.5",
"@types/styled-components": "^5.1.9",
"cypress": "^7.3.0",
"cypress-dotenv": "^1.2.2",
"dotenv": "^9.0.2",
"jest": "^26.6.3",
"ts-jest": "^26.5.6",
"typescript": "^4.2.4"


+ 41
- 0
packages/app-web/src/components/molecules/brand/Brand/index.tsx View File

@@ -0,0 +1,41 @@
import styled from 'styled-components'
import Link from '../../navigation/Link'

const BrandBase = styled(Link)({
display: 'block',
textDecoration: 'none',
fontSize: '1.5rem',
fontWeight: 'bold',
fontStretch: '75%',
textTransform: 'uppercase',
width: '2rem',
textAlign: 'center',
'@media (min-width: 720px)': {
width: '8rem',
textAlign: 'left',
},
})

const Hide = styled('span')({
display: 'none',
'@media (min-width: 720px)': {
display: 'inline',
},
})

const Brand = () => {
return (
<BrandBase
href={{
pathname: '/',
}}
>
T
<Hide>
onality
</Hide>
</BrandBase>
)
}

export default Brand

+ 3
- 3
packages/app-web/src/components/molecules/forms/TextArea/index.tsx View File

@@ -2,7 +2,6 @@ import {FC} from 'react'
import styled from 'styled-components'

const Base = styled('div')({
height: '3rem',
borderRadius: '0.25rem',
overflow: 'hidden',
position: 'relative',
@@ -34,9 +33,9 @@ const Label = styled('span')({
const Input = styled('textarea')({
display: 'block',
width: '100%',
height: '100%',
minHeight: '3rem',
margin: 0,
padding: '0 1rem',
padding: '1rem 1rem',
boxSizing: 'border-box',
font: 'inherit',
border: 0,
@@ -51,6 +50,7 @@ type Props = {
className?: string,
block?: boolean,
placeholder?: string,
defaultValue?: string | number | readonly string[],
}

const TextArea: FC<Props> = ({


+ 1
- 0
packages/app-web/src/components/molecules/forms/TextInput/index.tsx View File

@@ -51,6 +51,7 @@ type Props = {
className?: string,
block?: boolean,
placeholder?: string,
defaultValue?: string | number | readonly string[],
type?: 'email' | 'url' | 'text' | 'tel',
}



+ 20
- 0
packages/app-web/src/components/organisms/forms/CreateRingtone/index.tsx View File

@@ -1,4 +1,5 @@
import {FC, FormEventHandler} from 'react'
import {models} from '@tonality/library-common'
import styled from 'styled-components'
import TextInput from '../../../molecules/forms/TextInput'
import TextArea from '../../../molecules/forms/TextArea'
@@ -13,12 +14,14 @@ type Props = {
onSubmit?: FormEventHandler,
action?: string,
labels: Record<string, string>,
defaultValues?: Partial<models.Ringtone>,
}

const CreateRingtoneForm: FC<Props> = ({
onSubmit,
action,
labels,
defaultValues = {},
}) => {
return (
<Form
@@ -27,15 +30,32 @@ const CreateRingtoneForm: FC<Props> = ({
action={action}
aria-label={labels['form']}
>
{
typeof (defaultValues.id as unknown) === 'string'
&& (
<input
type="hidden"
name="id"
defaultValue={defaultValues.id}
/>
)
}
<input
type="hidden"
name="composerId"
defaultValue={defaultValues.composerId}
/>
<TextInput
label={labels['name'] || 'Name'}
name="name"
block
defaultValue={defaultValues.name}
/>
<TextArea
label={labels['data'] || 'Data'}
name="data"
block
defaultValue={defaultValues.data}
/>
<ActionButton
type="submit"


+ 10
- 3
packages/app-web/src/components/organisms/forms/Omnisearch/index.tsx View File

@@ -1,6 +1,13 @@
import {FC, FormEventHandler} from 'react'
import styled from 'styled-components'
import TextInput from '../../../molecules/forms/TextInput'
import ActionButton from '../../../molecules/forms/ActionButton';
import ActionButton from '../../../molecules/forms/ActionButton'

const Form = styled('form')({
display: 'grid',
gridTemplateColumns: '1fr auto',
gap: '1rem',
})

type Props = {
onSubmit?: FormEventHandler,
@@ -14,7 +21,7 @@ const OmnisearchForm: FC<Props> = ({
action,
}) => {
return (
<form
<Form
method="get"
onSubmit={onSubmit}
action={action}
@@ -31,7 +38,7 @@ const OmnisearchForm: FC<Props> = ({
>
Search
</ActionButton>
</form>
</Form>
)
}



+ 21
- 1
packages/app-web/src/components/templates/CreateRingtone/index.tsx View File

@@ -1,20 +1,36 @@
import {FC, FormEventHandler} from 'react'
import { LeftSidebarWithMenu } from '@tesseract-design/viewfinder'
import {models} from '@tonality/library-common'
import CreateRingtoneForm from '../../organisms/forms/CreateRingtone'
import Link from '../../molecules/navigation/Link'
import OmnisearchForm from '../../organisms/forms/Omnisearch'
import Brand from '../../molecules/brand/Brand'

type Props = {
onSearch?: FormEventHandler,
onSubmit?: FormEventHandler
onSubmit?: FormEventHandler,
composer: models.Composer,
currentRingtone?: models.Ringtone,
composerRingtones: models.Ringtone[],
}

const CreateRingtoneTemplate: FC<Props> = ({
onSearch,
onSubmit,
composer,
currentRingtone = {},
composerRingtones = [],
}) => {
return (
<LeftSidebarWithMenu.Layout
brand={
<Brand />
}
userLink={
<div>
User
</div>
}
topBarCenter={
<OmnisearchForm
labels={{
@@ -81,6 +97,10 @@ const CreateRingtoneTemplate: FC<Props> = ({
<LeftSidebarWithMenu.ContentContainer>
<CreateRingtoneForm
onSubmit={onSubmit}
defaultValues={{
...currentRingtone,
composerId: composer.id,
}}
action="/api/a/create/ringtone"
labels={{
form: 'Create Ringtone',


+ 12
- 2
packages/app-web/src/modules/ringtone/client.ts View File

@@ -1,10 +1,20 @@
import getFormValues from '@theoryofnekomata/formxtr'
import {FormEvent} from 'react'
import {createFetchClient, FetchClient} from '../../utils/api/fetch'
import * as endpoints from './endpoints'

export default class RingtoneClient {
async save(e: FormEvent & { submitter: HTMLInputElement | HTMLButtonElement }) {
private readonly fetchClient: FetchClient
constructor() {
this.fetchClient = createFetchClient({
baseUrl: process.env.NEXT_PUBLIC_API_BASE_URL,
})
}

save = async (e: FormEvent & { submitter: HTMLInputElement | HTMLButtonElement }) => {
e.preventDefault()
const values = getFormValues(e.target as HTMLFormElement, e.submitter)
console.log(values)
const response = await this.fetchClient(endpoints.create(values))
alert(response.statusText)
}
}

+ 57
- 0
packages/app-web/src/modules/ringtone/endpoints.ts View File

@@ -0,0 +1,57 @@
import {models} from '@tonality/library-common';
import {FetchClientParams, Method} from '../../utils/api/fetch';

export const create = (body: Partial<models.Ringtone>): FetchClientParams => ({
method: Method.POST,
url: ['', 'api', 'ringtones'].join('/'),
body: JSON.stringify(body),
headers: {
'Content-Type': 'application/json',
},
})

export const get = (id: string): FetchClientParams => ({
method: Method.GET,
url: ['', 'api', 'ringtones', encodeURIComponent(id)].join('/'),
})

export const browse = ({ skip, take, }: { skip?: number, take?: number }): FetchClientParams => ({
method: Method.GET,
url: ['', 'api', 'ringtones'].join('/'),
query: {
skip: typeof skip === 'number' ? skip.toString() : undefined,
take: typeof take === 'number' ? take.toString() : undefined,
},
})

export const update = (id: string) => (body: Partial<models.Ringtone>): FetchClientParams => ({
method: Method.PATCH,
url: ['', 'api', 'ringtones', encodeURIComponent(id)].join('/'),
body: JSON.stringify(body),
headers: {
'Content-Type': 'application/json',
},
})

export const softDelete = (id: string): FetchClientParams => ({
method: Method.POST,
url: ['', 'api', 'ringtones', encodeURIComponent(id), 'delete'].join('/'),
})

export const undoDelete = (id: string): FetchClientParams => ({
method: Method.DELETE,
url: ['', 'api', 'ringtones', encodeURIComponent(id), 'delete'].join('/'),
})

export const hardDelete = (id: string): FetchClientParams => ({
method: Method.DELETE,
url: ['', 'api', 'ringtones', encodeURIComponent(id)].join('/'),
})

export const search = (q: string): FetchClientParams => ({
method: Method.PATCH,
url: ['', 'api', 'search', 'ringtones'].join('/'),
query: {
q,
},
})

+ 4
- 0
packages/app-web/src/pages/_app.tsx View File

@@ -6,10 +6,14 @@ const GlobalStyle = createGlobalStyle({
'--color-fg': 'black',
color: 'var(--color-fg, black)',
backgroundColor: 'var(--color-bg, white)',
fontFamily: 'system-ui, sans-serif',
},
'body': {
margin: 0,
},
'a': {
color: 'inherit',
},
'@media (prefers-color-scheme: dark)': {
':root': {
'--color-bg': 'black',


+ 3
- 0
packages/app-web/src/pages/api/auth/[...auth0].ts View File

@@ -0,0 +1,3 @@
import { handleAuth } from '@auth0/nextjs-auth0'

export default handleAuth()

+ 10
- 5
packages/app-web/src/pages/index.tsx View File

@@ -1,13 +1,18 @@
import {NextPage} from 'next';

import {GetServerSideProps, NextPage} from 'next';
type Props = {}

const IndexPage: NextPage<Props> = () => {
return (
<div>
Hello
</div>
<>
Landing Page Here
</>
);
};

export const getServerSideProps: GetServerSideProps = async (ctx) => {
return {
props: {}
}
}

export default IndexPage;

+ 33
- 3
packages/app-web/src/pages/my/create/ringtone/index.tsx View File

@@ -1,17 +1,47 @@
import {NextPage} from 'next'
import {GetServerSideProps, NextPage} from 'next'
import {useRef} from 'react'
import {models} from '@tonality/library-common'
import CreateRingtoneTemplate from '../../../../components/templates/CreateRingtone'
import RingtoneClient from '../../../../modules/ringtone/client'
import {getSession, withPageAuthRequired} from '@auth0/nextjs-auth0';

type Props = {}
type Props = {
user: models.Composer,
composerRingtones: models.Ringtone[],
}

const MyCreateRingtonePage: NextPage<Props> = () => {
const MyCreateRingtonePage: NextPage<Props> = ({
user,
composerRingtones,
}) => {
const ringtoneClient = useRef(new RingtoneClient())
return (
<CreateRingtoneTemplate
composer={user}
composerRingtones={composerRingtones}
onSubmit={ringtoneClient.current.save}
/>
)
}

export const getServerSideProps: GetServerSideProps = withPageAuthRequired({
getServerSideProps: async (ctx) => {
const session = getSession(ctx.req, ctx.res)
const { user } = session
const composerRingtones = []

return {
props: {
user: {
id: user.sub,
name: user.nickname,
bio: '',
},
composerRingtones,
},
}
},
returnTo: '/my/create/ringtone'
})

export default MyCreateRingtonePage

+ 40
- 0
packages/app-web/src/pages/ringtones/index.tsx View File

@@ -0,0 +1,40 @@
import {GetServerSideProps, NextPage} from 'next'
import {useRef} from 'react'
import {models} from '@tonality/library-common'
import RingtoneClient from '../../modules/ringtone/client'

type Props = {
user: models.Composer,
composerRingtones: models.Ringtone[],
}

const MyCreateRingtonePage: NextPage<Props> = ({
user,
composerRingtones,
}) => {
const ringtoneClient = useRef(new RingtoneClient())
return (
<div>
Hello
</div>
)
}

export const getServerSideProps: GetServerSideProps = async () => {
const user = {
id: '00000000-0000-0000-000000000000',
name: 'TheoryOfNekomata',
bio: '',
}

const composerRingtones = []

return {
props: {
user,
composerRingtones,
},
}
}

export default MyCreateRingtonePage

+ 3
- 3
packages/app-web/src/utils/api/fetch.ts View File

@@ -1,6 +1,6 @@
import {URLSearchParams} from 'url';

enum Method {
export enum Method {
HEAD = 'HEAD',
GET = 'GET',
POST = 'POST',
@@ -14,7 +14,7 @@ type Fetch = (input: RequestInfo, init?: RequestInit) => Promise<Response>
type CreateFetchClientOptions = {
baseUrl: string,
headers?: HeadersInit,
fetch: Fetch,
fetch?: Fetch,
}

export type FetchClientParams = {
@@ -26,7 +26,7 @@ export type FetchClientParams = {
fetch?: Fetch,
}

type FetchClient = (params: FetchClientParams) => Promise<Response>
export type FetchClient = (params: FetchClientParams) => Promise<Response>

type CreateFetchClient = (options: CreateFetchClientOptions) => FetchClient



+ 538
- 4
packages/app-web/yarn.lock View File

@@ -2,6 +2,23 @@
# yarn lockfile v1


"@auth0/nextjs-auth0@^1.3.1":
version "1.3.1"
resolved "https://registry.yarnpkg.com/@auth0/nextjs-auth0/-/nextjs-auth0-1.3.1.tgz#9e90d9eaa1105f816c3c3458c954c15eb03ffcd1"
integrity sha512-oO4YEaZ3PXNi5LM23nRM2zOfEs6rPAv2VCGPhGOzSIZbrVkHVkwa/+ySJt4OC1xZEbAvq8hjb/uBWYtowtQ9eQ==
dependencies:
base64url "^3.0.1"
cookie "^0.4.1"
debug "^4.3.1"
futoin-hkdf "^1.3.2"
http-errors "^1.8.0"
joi "^17.4.0"
jose "^2.0.5"
on-headers "^1.0.2"
openid-client "^4.2.3"
tslib "^2.1.0"
url-join "^4.0.1"

"@babel/code-frame@7.12.11":
version "7.12.11"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f"
@@ -421,11 +438,18 @@
dependencies:
"@hapi/hoek" "9.x.x"

"@hapi/hoek@9.x.x":
"@hapi/hoek@9.x.x", "@hapi/hoek@^9.0.0":
version "9.2.0"
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.2.0.tgz#f3933a44e365864f4dad5db94158106d511e8131"
integrity sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug==

"@hapi/topo@^5.0.0":
version "5.0.0"
resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.0.0.tgz#c19af8577fa393a06e9c77b60995af959be721e7"
integrity sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw==
dependencies:
"@hapi/hoek" "^9.0.0"

"@istanbuljs/load-nyc-config@^1.0.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced"
@@ -657,6 +681,11 @@
resolved "https://registry.yarnpkg.com/@opentelemetry/context-base/-/context-base-0.14.0.tgz#c67fc20a4d891447ca1a855d7d70fa79a3533001"
integrity sha512-sDOAZcYwynHFTbLo6n8kIbLiVF3a3BLkrmehJUyEbT9F+Smbi47kLGS2gG2g0fjBLR/Lr1InPD7kXL7FaTqEkw==

"@panva/asn1.js@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@panva/asn1.js/-/asn1.js-1.0.0.tgz#dd55ae7b8129e02049f009408b97c61ccf9032f6"
integrity sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw==

"@samverschueren/stream-to-observable@^0.3.0":
version "0.3.1"
resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.1.tgz#a21117b19ee9be70c379ec1877537ef2e1c63301"
@@ -664,6 +693,28 @@
dependencies:
any-observable "^0.3.0"

"@sideway/address@^4.1.0":
version "4.1.2"
resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.2.tgz#811b84333a335739d3969cfc434736268170cad1"
integrity sha512-idTz8ibqWFrPU8kMirL0CoPH/A29XOzzAzpyN3zQ4kAWnzmNfFmRaoMNN6VI8ske5M73HZyhIaW4OuSFIdM4oA==
dependencies:
"@hapi/hoek" "^9.0.0"

"@sideway/formula@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.0.tgz#fe158aee32e6bd5de85044be615bc08478a0a13c"
integrity sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==

"@sideway/pinpoint@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df"
integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==

"@sindresorhus/is@^4.0.0":
version "4.0.1"
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.0.1.tgz#d26729db850fa327b7cacc5522252194404226f5"
integrity sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g==

"@sinonjs/commons@^1.7.0":
version "1.8.3"
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d"
@@ -678,6 +729,13 @@
dependencies:
"@sinonjs/commons" "^1.7.0"

"@szmarczak/http-timer@^4.0.5":
version "4.0.5"
resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.5.tgz#bfbd50211e9dfa51ba07da58a14cdfd333205152"
integrity sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==
dependencies:
defer-to-connect "^2.0.0"

"@tesseract-design/viewfinder@^0.1.1":
version "0.1.1"
resolved "https://js.pack.modal.sh/@tesseract-design%2fviewfinder/-/viewfinder-0.1.1.tgz#edb72601756e9762084aef49ad3a61c3815cdcc4"
@@ -762,6 +820,16 @@
dependencies:
"@babel/types" "^7.3.0"

"@types/cacheable-request@^6.0.1":
version "6.0.1"
resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.1.tgz#5d22f3dded1fd3a84c0bbeb5039a7419c2c91976"
integrity sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ==
dependencies:
"@types/http-cache-semantics" "*"
"@types/keyv" "*"
"@types/node" "*"
"@types/responselike" "*"

"@types/graceful-fs@^4.1.2":
version "4.1.5"
resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15"
@@ -777,6 +845,11 @@
"@types/react" "*"
hoist-non-react-statics "^3.3.0"

"@types/http-cache-semantics@*":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz#9140779736aa2655635ee756e2467d787cfe8a2a"
integrity sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A==

"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1":
version "2.0.3"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762"
@@ -804,6 +877,13 @@
jest-diff "^26.0.0"
pretty-format "^26.0.0"

"@types/keyv@*":
version "3.1.1"
resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.1.tgz#e45a45324fca9dab716ab1230ee249c9fb52cfa7"
integrity sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==
dependencies:
"@types/node" "*"

"@types/node@*", "@types/node@^15.0.2":
version "15.0.2"
resolved "https://registry.yarnpkg.com/@types/node/-/node-15.0.2.tgz#51e9c0920d1b45936ea04341aa3e2e58d339fb67"
@@ -838,6 +918,13 @@
"@types/scheduler" "*"
csstype "^3.0.2"

"@types/responselike@*", "@types/responselike@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29"
integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==
dependencies:
"@types/node" "*"

"@types/scheduler@*":
version "0.16.1"
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275"
@@ -914,6 +1001,14 @@ acorn@^8.1.0:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.2.4.tgz#caba24b08185c3b56e3168e97d15ed17f4d31fd0"
integrity sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg==

aggregate-error@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a"
integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==
dependencies:
clean-stack "^2.0.0"
indent-string "^4.0.0"

ajv@^6.12.3:
version "6.12.6"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
@@ -1214,6 +1309,11 @@ base64-js@^1.0.2:
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==

base64url@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/base64url/-/base64url-3.0.1.tgz#6399d572e2bc3f90a9a8b22d5dbb0a32d33f788d"
integrity sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==

base@^0.11.1:
version "0.11.2"
resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f"
@@ -1459,6 +1559,24 @@ cache-base@^1.0.1:
union-value "^1.0.0"
unset-value "^1.0.0"

cacheable-lookup@^5.0.3:
version "5.0.4"
resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005"
integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==

cacheable-request@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.1.tgz#062031c2856232782ed694a257fa35da93942a58"
integrity sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw==
dependencies:
clone-response "^1.0.2"
get-stream "^5.1.0"
http-cache-semantics "^4.0.0"
keyv "^4.0.0"
lowercase-keys "^2.0.0"
normalize-url "^4.1.0"
responselike "^2.0.0"

cachedir@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.3.0.tgz#0c75892a052198f0b21c7c1804d8331edfcae0e8"
@@ -1616,6 +1734,11 @@ classnames@2.2.6:
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==

clean-stack@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b"
integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==

cli-cursor@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987"
@@ -1657,6 +1780,13 @@ cliui@^6.0.0:
strip-ansi "^6.0.0"
wrap-ansi "^6.2.0"

clone-response@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b"
integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=
dependencies:
mimic-response "^1.0.0"

co@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
@@ -1773,6 +1903,11 @@ convert-source-map@1.7.0, convert-source-map@^1.4.0, convert-source-map@^1.6.0,
dependencies:
safe-buffer "~5.1.1"

cookie@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1"
integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==

copy-descriptor@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
@@ -1920,6 +2055,15 @@ csstype@^3.0.2:
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340"
integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==

cypress-dotenv@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/cypress-dotenv/-/cypress-dotenv-1.2.2.tgz#c40f23a11648382a79029c718594d2c793494f4e"
integrity sha512-T6Z2IWnG64FusDjUPKWKEyGxhlAX1vbJIj1t4s17a2PuhK5Pw58iS3wdthol8g4BRZIsQ+QDX3GN5NgjmJ4/KA==
dependencies:
camelcase "^5.3.1"
dotenv-parse-variables "^0.2.3"
lodash.clonedeep "^2.0.0"

cypress@^7.3.0:
version "7.3.0"
resolved "https://registry.yarnpkg.com/cypress/-/cypress-7.3.0.tgz#17345b8d18681c120f033e7d8fd0f0271e9d0d51"
@@ -2017,7 +2161,7 @@ debug@^3.1.0:
dependencies:
ms "^2.1.1"

debug@^4.1.0, debug@^4.1.1:
debug@^4.1.0, debug@^4.1.1, debug@^4.3.1:
version "4.3.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
@@ -2039,6 +2183,13 @@ decode-uri-component@^0.2.0:
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=

decompress-response@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc"
integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==
dependencies:
mimic-response "^3.1.0"

deep-is@~0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
@@ -2049,6 +2200,11 @@ deepmerge@^4.2.2:
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==

defer-to-connect@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587"
integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==

define-properties@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
@@ -2137,6 +2293,18 @@ domexception@^2.0.1:
dependencies:
webidl-conversions "^5.0.0"

dotenv-parse-variables@^0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/dotenv-parse-variables/-/dotenv-parse-variables-0.2.3.tgz#9f509c74b952f3c8dbfda6674fb060398d0ed7fc"
integrity sha512-cuog/uu2sD6AGTExLldBqN4kUWNjGG86cSpYGYgZrzgSiy37HkB3OOpMv7cTiQ7SKCMu8WryUS9P6lqwrh0pLg==
dependencies:
debug "^4.1.1"

dotenv@^9.0.2:
version "9.0.2"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-9.0.2.tgz#dacc20160935a37dea6364aa1bef819fb9b6ab05"
integrity sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==

ecc-jsbn@~0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
@@ -2568,6 +2736,11 @@ function-bind@^1.1.1:
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==

futoin-hkdf@^1.3.2:
version "1.3.3"
resolved "https://registry.yarnpkg.com/futoin-hkdf/-/futoin-hkdf-1.3.3.tgz#6ee1c9c105dfa0995ba4f80633cf1c0c32defcb2"
integrity sha512-oR75fYk3B3X9/B02Y6vusrBKucrpC6VjxhRL+C6B7FwUpuSRHbhBNG3AZbcE/xPyJmEQWsyqUFp3VeNNbA3S7A==

gensync@^1.0.0-beta.2:
version "1.0.0-beta.2"
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
@@ -2606,7 +2779,7 @@ get-stream@^4.0.0:
dependencies:
pump "^3.0.0"

get-stream@^5.0.0:
get-stream@^5.0.0, get-stream@^5.1.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3"
integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==
@@ -2668,6 +2841,23 @@ globals@^11.1.0:
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==

got@^11.8.0:
version "11.8.2"
resolved "https://registry.yarnpkg.com/got/-/got-11.8.2.tgz#7abb3959ea28c31f3576f1576c1effce23f33599"
integrity sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ==
dependencies:
"@sindresorhus/is" "^4.0.0"
"@szmarczak/http-timer" "^4.0.5"
"@types/cacheable-request" "^6.0.1"
"@types/responselike" "^1.0.0"
cacheable-lookup "^5.0.3"
cacheable-request "^7.0.1"
decompress-response "^6.0.0"
http2-wrapper "^1.0.0-beta.5.2"
lowercase-keys "^2.0.0"
p-cancelable "^2.0.0"
responselike "^2.0.0"

graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4:
version "4.2.6"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
@@ -2811,6 +3001,11 @@ html-escaper@^2.0.0:
resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453"
integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==

http-cache-semantics@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390"
integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==

http-errors@1.7.3:
version "1.7.3"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06"
@@ -2822,6 +3017,17 @@ http-errors@1.7.3:
statuses ">= 1.5.0 < 2"
toidentifier "1.0.0"

http-errors@^1.8.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.0.tgz#75d1bbe497e1044f51e4ee9e704a62f28d336507"
integrity sha512-4I8r0C5JDhT5VkvI47QktDW75rNlGVsUf/8hzjCC/wkWI/jdTRmBb9aI7erSG82r1bjKY3F6k28WnsVxB1C73A==
dependencies:
depd "~1.1.2"
inherits "2.0.4"
setprototypeof "1.2.0"
statuses ">= 1.5.0 < 2"
toidentifier "1.0.0"

http-signature@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
@@ -2831,6 +3037,14 @@ http-signature@~1.2.0:
jsprim "^1.2.2"
sshpk "^1.7.0"

http2-wrapper@^1.0.0-beta.5.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d"
integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==
dependencies:
quick-lru "^5.1.1"
resolve-alpn "^1.0.0"

https-browserify@1.0.0, https-browserify@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
@@ -3660,6 +3874,24 @@ jest@^26.6.3:
import-local "^3.0.2"
jest-cli "^26.6.3"

joi@^17.4.0:
version "17.4.0"
resolved "https://registry.yarnpkg.com/joi/-/joi-17.4.0.tgz#b5c2277c8519e016316e49ababd41a1908d9ef20"
integrity sha512-F4WiW2xaV6wc1jxete70Rw4V/VuMd6IN+a5ilZsxG4uYtUXWu2kq9W5P2dz30e7Gmw8RCbY/u/uk+dMPma9tAg==
dependencies:
"@hapi/hoek" "^9.0.0"
"@hapi/topo" "^5.0.0"
"@sideway/address" "^4.1.0"
"@sideway/formula" "^3.0.0"
"@sideway/pinpoint" "^2.0.0"

jose@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/jose/-/jose-2.0.5.tgz#29746a18d9fff7dcf9d5d2a6f62cb0c7cd27abd3"
integrity sha512-BAiDNeDKTMgk4tvD0BbxJ8xHEHBZgpeRZ1zGPPsitSyMgjoMWiLGYAE7H7NpP5h0lPppQajQs871E8NHUrzVPA==
dependencies:
"@panva/asn1.js" "^1.0.0"

"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
@@ -3715,6 +3947,11 @@ jsesc@^2.5.1:
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==

json-buffer@3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==

json-parse-even-better-errors@^2.3.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d"
@@ -3768,6 +4005,13 @@ jsprim@^1.2.2:
json-schema "0.2.3"
verror "1.10.0"

keyv@^4.0.0:
version "4.0.3"
resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.3.tgz#4f3aa98de254803cafcd2896734108daa35e4254"
integrity sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==
dependencies:
json-buffer "3.0.1"

kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0:
version "3.2.2"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
@@ -3880,6 +4124,204 @@ locate-path@^5.0.0:
dependencies:
p-locate "^4.1.0"

lodash._arraypool@~2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash._arraypool/-/lodash._arraypool-2.4.1.tgz#e88eecb92e2bb84c9065612fd958a0719cd47f94"
integrity sha1-6I7suS4ruEyQZWEv2VigcZzUf5Q=

lodash._basebind@~2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash._basebind/-/lodash._basebind-2.4.1.tgz#e940b9ebdd27c327e0a8dab1b55916c5341e9575"
integrity sha1-6UC5690nwyfgqNqxtVkWxTQelXU=
dependencies:
lodash._basecreate "~2.4.1"
lodash._setbinddata "~2.4.1"
lodash._slice "~2.4.1"
lodash.isobject "~2.4.1"

lodash._baseclone@~2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash._baseclone/-/lodash._baseclone-2.4.1.tgz#30f823e57e17e3735d383bd62b60b387543b4186"
integrity sha1-MPgj5X4X43NdODvWK2Czh1Q7QYY=
dependencies:
lodash._getarray "~2.4.1"
lodash._releasearray "~2.4.1"
lodash._slice "~2.4.1"
lodash.assign "~2.4.1"
lodash.foreach "~2.4.1"
lodash.forown "~2.4.1"
lodash.isarray "~2.4.1"
lodash.isobject "~2.4.1"

lodash._basecreate@~2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-2.4.1.tgz#f8e6f5b578a9e34e541179b56b8eeebf4a287e08"
integrity sha1-+Ob1tXip405UEXm1a47uv0oofgg=
dependencies:
lodash._isnative "~2.4.1"
lodash.isobject "~2.4.1"
lodash.noop "~2.4.1"

lodash._basecreatecallback@~2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash._basecreatecallback/-/lodash._basecreatecallback-2.4.1.tgz#7d0b267649cb29e7a139d0103b7c11fae84e4851"
integrity sha1-fQsmdknLKeehOdAQO3wR+uhOSFE=
dependencies:
lodash._setbinddata "~2.4.1"
lodash.bind "~2.4.1"
lodash.identity "~2.4.1"
lodash.support "~2.4.1"

lodash._basecreatewrapper@~2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash._basecreatewrapper/-/lodash._basecreatewrapper-2.4.1.tgz#4d31f2e7de7e134fbf2803762b8150b32519666f"
integrity sha1-TTHy595+E0+/KAN2K4FQsyUZZm8=
dependencies:
lodash._basecreate "~2.4.1"
lodash._setbinddata "~2.4.1"
lodash._slice "~2.4.1"
lodash.isobject "~2.4.1"

lodash._createwrapper@~2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash._createwrapper/-/lodash._createwrapper-2.4.1.tgz#51d6957973da4ed556e37290d8c1a18c53de1607"
integrity sha1-UdaVeXPaTtVW43KQ2MGhjFPeFgc=
dependencies:
lodash._basebind "~2.4.1"
lodash._basecreatewrapper "~2.4.1"
lodash._slice "~2.4.1"
lodash.isfunction "~2.4.1"

lodash._getarray@~2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash._getarray/-/lodash._getarray-2.4.1.tgz#faf1f7f810fa985a251c2187404481094839e5ee"
integrity sha1-+vH3+BD6mFolHCGHQESBCUg55e4=
dependencies:
lodash._arraypool "~2.4.1"

lodash._isnative@~2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash._isnative/-/lodash._isnative-2.4.1.tgz#3ea6404b784a7be836c7b57580e1cdf79b14832c"
integrity sha1-PqZAS3hKe+g2x7V1gOHN95sUgyw=

lodash._maxpoolsize@~2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash._maxpoolsize/-/lodash._maxpoolsize-2.4.1.tgz#9d482f463b8e66afbe59c2c14edb117060172334"
integrity sha1-nUgvRjuOZq++WcLBTtsRcGAXIzQ=

lodash._objecttypes@~2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz#7c0b7f69d98a1f76529f890b0cdb1b4dfec11c11"
integrity sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=

lodash._releasearray@~2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash._releasearray/-/lodash._releasearray-2.4.1.tgz#a6139630d76d1536b07ddc80962889b082f6a641"
integrity sha1-phOWMNdtFTawfdyAliiJsIL2pkE=
dependencies:
lodash._arraypool "~2.4.1"
lodash._maxpoolsize "~2.4.1"

lodash._setbinddata@~2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash._setbinddata/-/lodash._setbinddata-2.4.1.tgz#f7c200cd1b92ef236b399eecf73c648d17aa94d2"
integrity sha1-98IAzRuS7yNrOZ7s9zxkjReqlNI=
dependencies:
lodash._isnative "~2.4.1"
lodash.noop "~2.4.1"

lodash._shimkeys@~2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz#6e9cc9666ff081f0b5a6c978b83e242e6949d203"
integrity sha1-bpzJZm/wgfC1psl4uD4kLmlJ0gM=
dependencies:
lodash._objecttypes "~2.4.1"

lodash._slice@~2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash._slice/-/lodash._slice-2.4.1.tgz#745cf41a53597b18f688898544405efa2b06d90f"
integrity sha1-dFz0GlNZexj2iImFREBe+isG2Q8=

lodash.assign@~2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-2.4.1.tgz#84c39596dd71181a97b0652913a7c9675e49b1aa"
integrity sha1-hMOVlt1xGBqXsGUpE6fJZ15Jsao=
dependencies:
lodash._basecreatecallback "~2.4.1"
lodash._objecttypes "~2.4.1"
lodash.keys "~2.4.1"

lodash.bind@~2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-2.4.1.tgz#5d19fa005c8c4d236faf4742c7b7a1fcabe29267"
integrity sha1-XRn6AFyMTSNvr0dCx7eh/Kvikmc=
dependencies:
lodash._createwrapper "~2.4.1"
lodash._slice "~2.4.1"

lodash.clonedeep@^2.0.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-2.4.1.tgz#f29203b40b12fee0a45d3631648259bebabc7868"
integrity sha1-8pIDtAsS/uCkXTYxZIJZvrq8eGg=
dependencies:
lodash._baseclone "~2.4.1"
lodash._basecreatecallback "~2.4.1"

lodash.foreach@~2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-2.4.1.tgz#fe3fc3a34c86c94cab6f9522560282741e016309"
integrity sha1-/j/Do0yGyUyrb5UiVgKCdB4BYwk=
dependencies:
lodash._basecreatecallback "~2.4.1"
lodash.forown "~2.4.1"

lodash.forown@~2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash.forown/-/lodash.forown-2.4.1.tgz#78b41eafe1405fa966459ea4193fd502d084524b"
integrity sha1-eLQer+FAX6lmRZ6kGT/VAtCEUks=
dependencies:
lodash._basecreatecallback "~2.4.1"
lodash._objecttypes "~2.4.1"
lodash.keys "~2.4.1"

lodash.identity@~2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash.identity/-/lodash.identity-2.4.1.tgz#6694cffa65fef931f7c31ce86c74597cf560f4f1"
integrity sha1-ZpTP+mX++TH3wxzobHRZfPVg9PE=

lodash.isarray@~2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-2.4.1.tgz#b52a326c1f62f6d7da73a31d5401df6ef44f0fa1"
integrity sha1-tSoybB9i9tfac6MdVAHfbvRPD6E=
dependencies:
lodash._isnative "~2.4.1"

lodash.isfunction@~2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash.isfunction/-/lodash.isfunction-2.4.1.tgz#2cfd575c73e498ab57e319b77fa02adef13a94d1"
integrity sha1-LP1XXHPkmKtX4xm3f6Aq3vE6lNE=

lodash.isobject@~2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-2.4.1.tgz#5a2e47fe69953f1ee631a7eba1fe64d2d06558f5"
integrity sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU=
dependencies:
lodash._objecttypes "~2.4.1"

lodash.keys@~2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-2.4.1.tgz#48dea46df8ff7632b10d706b8acb26591e2b3727"
integrity sha1-SN6kbfj/djKxDXBrissmWR4rNyc=
dependencies:
lodash._isnative "~2.4.1"
lodash._shimkeys "~2.4.1"
lodash.isobject "~2.4.1"

lodash.noop@~2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash.noop/-/lodash.noop-2.4.1.tgz#4fb54f816652e5ae10e8f72f717a388c7326538a"
integrity sha1-T7VPgWZS5a4Q6PcvcXo4jHMmU4o=

lodash.once@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
@@ -3890,6 +4332,13 @@ lodash.sortby@^4.7.0:
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=

lodash.support@~2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/lodash.support/-/lodash.support-2.4.1.tgz#320e0b67031673c28d7a2bb5d9e0331a45240515"
integrity sha1-Mg4LZwMWc8KNeiu12eAzGkUkBRU=
dependencies:
lodash._isnative "~2.4.1"

lodash@4.x, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.7.0:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
@@ -3926,6 +4375,11 @@ loose-envify@^1.1.0, loose-envify@^1.4.0:
dependencies:
js-tokens "^3.0.0 || ^4.0.0"

lowercase-keys@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==

lru-cache@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
@@ -3945,7 +4399,7 @@ make-dir@^3.0.0, make-dir@^3.0.2:
dependencies:
semver "^6.0.0"

make-error@1.x:
make-error@1.x, make-error@^1.3.6:
version "1.3.6"
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
@@ -4040,6 +4494,16 @@ mimic-fn@^2.1.0:
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==

mimic-response@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==

mimic-response@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9"
integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==

min-indent@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869"
@@ -4287,6 +4751,11 @@ normalize-path@^3.0.0, normalize-path@~3.0.0:
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==

normalize-url@^4.1.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129"
integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==

npm-run-path@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
@@ -4330,6 +4799,11 @@ object-copy@^0.1.0:
define-property "^0.2.5"
kind-of "^3.0.3"

object-hash@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.1.1.tgz#9447d0279b4fcf80cff3259bf66a1dc73afabe09"
integrity sha512-VOJmgmS+7wvXf8CjbQmimtCnEx3IAoLxI3fp2fbWehxrWBcAQFbk+vcwb6vzR0VZv/eNCJ/27j151ZTwqW/JeQ==

object-inspect@^1.9.0:
version "1.10.3"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.3.tgz#c2aa7d2d09f50c99375704f7a0adf24c5782d369"
@@ -4372,6 +4846,16 @@ object.pick@^1.3.0:
dependencies:
isobject "^3.0.1"

oidc-token-hash@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/oidc-token-hash/-/oidc-token-hash-5.0.1.tgz#ae6beec3ec20f0fd885e5400d175191d6e2f10c6"
integrity sha512-EvoOtz6FIEBzE+9q253HsLCVRiK/0doEJ2HCvvqMQb3dHZrP3WlJKYtJ55CRTw4jmYomzH4wkPuCj/I3ZvpKxQ==

on-headers@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f"
integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==

once@^1.3.0, once@^1.3.1, once@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
@@ -4398,6 +4882,19 @@ onetime@^5.1.0:
dependencies:
mimic-fn "^2.1.0"

openid-client@^4.2.3:
version "4.7.3"
resolved "https://registry.yarnpkg.com/openid-client/-/openid-client-4.7.3.tgz#ea4f6f9ff6203dfbbe3d9bb4415d5dce751b0a70"
integrity sha512-YLwZQLSjo3gdSVxw/G25ddoRp9oCpXkREZXssmenlejZQPsnTq+yQtFUcBmC7u3VVkx+gwqXZF7X0CtAAJrRRg==
dependencies:
aggregate-error "^3.1.0"
got "^11.8.0"
jose "^2.0.5"
lru-cache "^6.0.0"
make-error "^1.3.6"
object-hash "^2.0.1"
oidc-token-hash "^5.0.1"

optionator@^0.8.1:
version "0.8.3"
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495"
@@ -4420,6 +4917,11 @@ ospath@^1.2.2:
resolved "https://registry.yarnpkg.com/ospath/-/ospath-1.2.2.tgz#1276639774a3f8ef2572f7fe4280e0ea4550c07b"
integrity sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs=

p-cancelable@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf"
integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==

p-each-series@^2.1.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.2.0.tgz#105ab0357ce72b202a8a8b94933672657b5e2a9a"
@@ -4715,6 +5217,11 @@ querystring@^0.2.0:
resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.1.tgz#40d77615bb09d16902a85c3e38aa8b5ed761c2dd"
integrity sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==

quick-lru@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932"
integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==

ramda@~0.27.1:
version "0.27.1"
resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.27.1.tgz#66fc2df3ef873874ffc2da6aa8984658abacf5c9"
@@ -4920,6 +5427,11 @@ require-main-filename@^2.0.0:
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==

resolve-alpn@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.1.2.tgz#30b60cfbb0c0b8dc897940fe13fe255afcdd4d28"
integrity sha512-8OyfzhAtA32LVUsJSke3auIyINcwdh5l3cvYKdKO0nvsYSKuiLfTM5i78PJswFPT8y6cPW+L1v6/hE95chcpDA==

resolve-cwd@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d"
@@ -4945,6 +5457,13 @@ resolve@^1.10.0, resolve@^1.18.1:
is-core-module "^2.2.0"
path-parse "^1.0.6"

responselike@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.0.tgz#26391bcc3174f750f9a79eacc40a12a5c42d7723"
integrity sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==
dependencies:
lowercase-keys "^2.0.0"

restore-cursor@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541"
@@ -5087,6 +5606,11 @@ setprototypeof@1.1.1:
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683"
integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==

setprototypeof@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==

sha.js@^2.4.0, sha.js@^2.4.8:
version "2.4.11"
resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7"
@@ -5713,6 +6237,11 @@ tslib@^1.9.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==

tslib@^2.1.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c"
integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==

tty-browserify@0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
@@ -5844,6 +6373,11 @@ urix@^0.1.0:
resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=

url-join@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.1.tgz#b642e21a2646808ffa178c4c5fda39844e12cde7"
integrity sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==

url@^0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"


+ 1
- 0
packages/service-core/package.json View File

@@ -21,6 +21,7 @@
"fastify": "^3.0.0",
"fastify-autoload": "^3.3.1",
"fastify-cli": "^2.11.0",
"fastify-cors": "^6.0.1",
"fastify-plugin": "^3.0.0",
"fastify-sensible": "^3.1.0",
"knex": "^0.95.5",


+ 1
- 1
packages/service-core/src/modules/ringtone/controller.ts View File

@@ -72,8 +72,8 @@ export class RingtoneController {
create = async (request: any, reply: any) => {
try {
const data = await this.ringtoneService.create(request.body)
reply.status(201)
reply.raw.statusMessage = 'Ringtone Created'
reply.raw.statusCode = 201
return {
data,
}


+ 2
- 2
packages/service-core/src/modules/ringtone/repository.ts View File

@@ -60,9 +60,9 @@ export class RingtoneRepository {
SELECT *
FROM ringtone r
JOIN composer c ON r.composerId = c.id
WHERE r.name LIKE ? ESCAPE '\';
WHERE LOWER(r.name) LIKE ? ESCAPE '\';
`,
[`%${q.replace('\\', '\\\\')}%`],
[`%${q.toLowerCase().replace('\\', '\\\\')}%`],
(err, result) => {
if (err) {
reject(err)


+ 8
- 0
packages/service-core/src/plugins/cors.ts View File

@@ -0,0 +1,8 @@
import FastifyCors, { FastifyCorsOptions } from 'fastify-cors';
import fp from 'fastify-plugin';

export default fp<FastifyCorsOptions>(async (fastify, opts) => {
fastify.register(FastifyCors, {
origin: process.env.APP_BASE_URL,
})
});

+ 0
- 9
packages/service-core/src/routes/example/index.ts View File

@@ -1,9 +0,0 @@
import {FastifyPluginAsync} from "fastify";

const example: FastifyPluginAsync = async (fastify, opts): Promise<void> => {
fastify.get('/', async function (request, reply) {
return 'this is an example';
});
};

export default example;

+ 0
- 1
packages/service-core/test/helper.ts View File

@@ -19,4 +19,3 @@ export const build = async () => {
await app.ready()
return app
}


+ 10
- 2
packages/service-core/test/routes/api/ringtones.test.ts View File

@@ -19,7 +19,7 @@ describe('ringtone', () => {
},
{
id: '00000000-0000-0000-000000000001',
name: 'Ringtone 2',
name: 'Unique Ringtone 2',
data: '4c4 8c4',
createdAt: new Date('2021-05-01'),
updatedAt: new Date('2021-05-01'),
@@ -46,7 +46,15 @@ describe('ringtone', () => {

describe('on searching', () => {
it('should send the data to the front-end', async () => {
// TODO
const res = await app.inject({
url: '/api/search/ringtones',
query: {
q: 'Unique',
},
method: 'GET',
})
const parsedPayload = JSON.parse(res.payload)
expect(Array.isArray(parsedPayload.data)).toBe(true)
})
})



+ 8
- 0
packages/service-core/yarn.lock View File

@@ -1815,6 +1815,14 @@ fastify-cli@^2.11.0:
split2 "^3.1.1"
yargs-parser "^20.0.0"
fastify-cors@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/fastify-cors/-/fastify-cors-6.0.1.tgz#300e0f1cbeedda19d9de284e9cf05c65842c182b"
integrity sha512-eeNTdQNmBsqHL87we+X74n9+H0hTDX0cXGVdyZjGf9om2pZfigAZwuSxaUUE2pLP9tp5+rEd5kejKQ8+ZCvAoA==
dependencies:
fastify-plugin "^3.0.0"
vary "^1.1.2"
fastify-error@^0.3.0:
version "0.3.1"
resolved "https://registry.yarnpkg.com/fastify-error/-/fastify-error-0.3.1.tgz#8eb993e15e3cf57f0357fc452af9290f1c1278d2"


Loading…
Cancel
Save