diff options
| author | Kevin Hoerr <kjhoerr@noreply.cybr.es> | 2022-08-14 21:35:45 +0000 |
|---|---|---|
| committer | Kevin Hoerr <kjhoerr@noreply.cybr.es> | 2022-08-14 21:35:45 +0000 |
| commit | c04674fa74c2e43535181431aef5d891f8839619 (patch) | |
| tree | 2f7ce3b61590b39254bc22ac96272b7533ed96d2 | |
| parent | 461b1fa053bcc86d06156574ab59fa7000dbf69e (diff) | |
| download | pantry-c04674fa74c2e43535181431aef5d891f8839619.tar.gz pantry-c04674fa74c2e43535181431aef5d891f8839619.tar.bz2 pantry-c04674fa74c2e43535181431aef5d891f8839619.zip | |
Merge planner code (#3)
Reviewed-on: https://git.submelon.dev/kjhoerr/pantry/pulls/3
| -rw-r--r-- | .eslintrc.json | 3 | ||||
| -rw-r--r-- | .gitignore | 36 | ||||
| -rw-r--r-- | next-env.d.ts | 5 | ||||
| -rw-r--r-- | next.config.js | 6 | ||||
| -rw-r--r-- | orval.config.ts | 28 | ||||
| -rw-r--r-- | package.json | 31 | ||||
| -rw-r--r-- | src/components/add-item.tsx | 101 | ||||
| -rw-r--r-- | src/conf/mutator.ts | 29 | ||||
| -rw-r--r-- | src/conf/openapi-pantry.yaml | 87 | ||||
| -rw-r--r-- | src/index.ts | 2 | ||||
| -rw-r--r-- | src/model/index.ts | 1 | ||||
| -rw-r--r-- | src/model/pantryItem.ts | 14 | ||||
| -rw-r--r-- | src/pages/_app.tsx | 16 | ||||
| -rw-r--r-- | src/pages/index.tsx | 162 | ||||
| -rw-r--r-- | src/styles/Home.module.css | 4 | ||||
| -rw-r--r-- | src/styles/globals.css | 16 | ||||
| -rw-r--r-- | src/util/pantry-item-resource.ts | 212 | ||||
| -rw-r--r-- | tsconfig.json | 20 | ||||
| -rw-r--r-- | yarn.lock | 4229 |
19 files changed, 5001 insertions, 1 deletions
diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..bffb357 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "next/core-web-vitals" +} @@ -38,4 +38,38 @@ nb-configuration.xml *.rej # Local environment -.env +.env* +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# vercel +.vercel + +# typescript +*.tsbuildinfo + +# build files of NextJS passed into Quarkus +/src/main/resources/META-INF/resources/ diff --git a/next-env.d.ts b/next-env.d.ts new file mode 100644 index 0000000..4f11a03 --- /dev/null +++ b/next-env.d.ts @@ -0,0 +1,5 @@ +/// <reference types="next" /> +/// <reference types="next/image-types/global" /> + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/next.config.js b/next.config.js new file mode 100644 index 0000000..a843cbe --- /dev/null +++ b/next.config.js @@ -0,0 +1,6 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + reactStrictMode: true, +} + +module.exports = nextConfig diff --git a/orval.config.ts b/orval.config.ts new file mode 100644 index 0000000..7151ef3 --- /dev/null +++ b/orval.config.ts @@ -0,0 +1,28 @@ +import { defineConfig } from 'orval'; + +export default defineConfig({ + pantry: { + input: './src/conf/openapi-pantry.yaml', + output: { + mode: "tags", + workspace: "./src", + target: "./util/pantry.ts", + schemas: "./model", + client: "react-query", + prettier: true, + override: { + useDates: true, + mutator: { + path: "./conf/mutator.ts", + name: "useMutator", + }, + query: { + useQuery: true, + }, + }, + }, + hooks: { + afterAllFilesWrite: 'prettier --write', + }, + }, +});
\ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..5938380 --- /dev/null +++ b/package.json @@ -0,0 +1,31 @@ +{ + "name": "pantry", + "scripts": { + "dev": "next dev", + "build": "next build && next export", + "start": "next start", + "lint": "next lint", + "codegen": "orval --clean && prettier --write 'src/**/*.(ts|tsx)'", + "inject": "rm -rf src/main/resources/META-INF/resources && yarn build && cp -R out src/main/resources/META-INF/resources", + "develop": "yarn inject && mvn quarkus:dev" + }, + "dependencies": { + "@tanstack/react-query": "^4.1.3", + "axios": "^0.27.2", + "immutable": "^4.1.0", + "next": "12.2.5", + "orval": "^6.9.6", + "prettier": "^2.7.1", + "react": "18.2.0", + "react-dom": "18.2.0", + "semantic-ui-css": "^2.4.1", + "semantic-ui-react": "^2.1.3" + }, + "devDependencies": { + "@types/node": "18.7.3", + "@types/react": "18.0.17", + "eslint": "8.22.0", + "eslint-config-next": "12.2.5", + "typescript": "4.7.4" + } +} diff --git a/src/components/add-item.tsx b/src/components/add-item.tsx new file mode 100644 index 0000000..9c4a998 --- /dev/null +++ b/src/components/add-item.tsx @@ -0,0 +1,101 @@ +import { ChangeEvent, useMemo, useState } from "react"; +import { Button, Form, InputOnChangeData, Segment } from "semantic-ui-react"; +import { PantryItem } from "../model"; + +const defaultPantryItem = () => + ({ + name: "", + description: "", + quantity: 1, + quantityUnitType: "oz", + } as PantryItem); + +interface AddItemProps { + addItem: (item: PantryItem) => Promise<void>; +} + +const AddItem = ({ addItem }: AddItemProps) => { + const [additionItem, setAdditionItem] = useState<PantryItem | undefined>(); + const [additionItemLoading, setAdditionItemLoading] = useState(false); + + const handleItemChange = ( + _: ChangeEvent<HTMLInputElement>, + { name, value }: InputOnChangeData + ) => + setAdditionItem((item) => ({ + ...(item !== undefined ? item : defaultPantryItem()), + [name]: value, + })); + + const newItem = useMemo( + () => additionItem ?? defaultPantryItem(), + [additionItem] + ); + + return ( + <> + <Segment attached="top" hidden={additionItem !== undefined}> + <Button primary onClick={() => setAdditionItem(defaultPantryItem())}> + Add Item + </Button> + </Segment> + <Segment attached="top" hidden={additionItem === undefined}> + <Form + loading={additionItemLoading} + onSubmit={() => { + setAdditionItemLoading(true); + addItem(newItem).then(() => { + setAdditionItem(undefined); + setAdditionItemLoading(false); + }); + }} + > + <Form.Group widths="equal"> + <Form.Input + name="name" + label="Item Name" + placeholder="Item name" + value={newItem.name} + onChange={handleItemChange} + /> + <Form.Input + fluid + name="description" + label="Item Description" + placeholder="Item description" + value={newItem.description} + onChange={handleItemChange} + /> + <Form.Input + fluid + name="quantity" + label="Item Quantity" + placeholder="Item quantity" + value={newItem.quantity} + onChange={handleItemChange} + /> + <Form.Input + name="quantityUnitType" + label="Quantity Type" + placeholder="Quantity type" + value={newItem.quantityUnitType} + onChange={handleItemChange} + /> + </Form.Group> + <Form.Group> + <Form.Button primary content="Submit Item" type="submit" /> + <Form.Button + content="Cancel" + onClick={(e) => { + e.preventDefault(); + setAdditionItem(undefined); + }} + /> + </Form.Group> + </Form> + </Segment> + </> + ); +}; + +export default AddItem; diff --git a/src/conf/mutator.ts b/src/conf/mutator.ts new file mode 100644 index 0000000..74f29e3 --- /dev/null +++ b/src/conf/mutator.ts @@ -0,0 +1,29 @@ +import Axios, { AxiosError, AxiosRequestConfig } from "axios"; + +export const AXIOS_PANTRY_INSTANCE = Axios.create({ + baseURL: process.env.REACT_APP_API_SERVER!, +}); + +export const useMutator = <T>(): (( + config: AxiosRequestConfig +) => Promise<T>) => { + return (config: AxiosRequestConfig) => { + const source = Axios.CancelToken.source(); + const promise = AXIOS_PANTRY_INSTANCE({ + ...config, + cancelToken: source.token, + }).then(({ data }) => data); + + // @ts-ignore + promise.cancel = () => { + source.cancel("Query was cancelled by React Query!"); + }; + + return promise; + }; +}; + +export default useMutator; + +// In some case with react-query and swr you want to be able to override the return error type so you can also do it here like this +export type ErrorType<Error> = AxiosError<Error>; diff --git a/src/conf/openapi-pantry.yaml b/src/conf/openapi-pantry.yaml new file mode 100644 index 0000000..8409064 --- /dev/null +++ b/src/conf/openapi-pantry.yaml @@ -0,0 +1,87 @@ +--- +openapi: 3.0.3 +info: + title: pantry API + version: 1.0.0-SNAPSHOT +paths: + /items: + get: + tags: + - Pantry Item Resource + responses: + "200": + description: OK + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/PantryItem' + post: + tags: + - Pantry Item Resource + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PantryItem' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/PantryItem' + /items/{id}: + put: + tags: + - Pantry Item Resource + parameters: + - name: id + in: path + required: true + schema: + format: int64 + type: integer + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PantryItem' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/PantryItem' + delete: + tags: + - Pantry Item Resource + parameters: + - name: id + in: path + required: true + schema: + format: int64 + type: integer + responses: + "204": + description: No Content +components: + schemas: + PantryItem: + type: object + properties: + id: + format: int64 + type: integer + name: + type: string + description: + type: string + quantity: + format: double + type: number + quantityUnitType: + type: string diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..f298f13 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,2 @@ +export * from "./model"; +export * from "./util/pantry-item-resource"; diff --git a/src/model/index.ts b/src/model/index.ts new file mode 100644 index 0000000..a60da79 --- /dev/null +++ b/src/model/index.ts @@ -0,0 +1 @@ +export * from "./pantryItem"; diff --git a/src/model/pantryItem.ts b/src/model/pantryItem.ts new file mode 100644 index 0000000..c3a6347 --- /dev/null +++ b/src/model/pantryItem.ts @@ -0,0 +1,14 @@ +/** + * Generated by orval v6.9.6 🍺 + * Do not edit manually. + * pantry API + * OpenAPI spec version: 1.0.0-SNAPSHOT + */ + +export interface PantryItem { + id?: number; + name?: string; + description?: string; + quantity?: number; + quantityUnitType?: string; +} diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx new file mode 100644 index 0000000..10121ab --- /dev/null +++ b/src/pages/_app.tsx @@ -0,0 +1,16 @@ +import "semantic-ui-css/semantic.min.css"; +import "../styles/globals.css"; +import type { AppProps } from "next/app"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; + +const queryClient = new QueryClient(); + +function MyApp({ Component, pageProps }: AppProps) { + return ( + <QueryClientProvider client={queryClient}> + <Component {...pageProps} /> + </QueryClientProvider> + ); +} + +export default MyApp; diff --git a/src/pages/index.tsx b/src/pages/index.tsx new file mode 100644 index 0000000..674878a --- /dev/null +++ b/src/pages/index.tsx @@ -0,0 +1,162 @@ +import type { NextPage } from "next"; +import Head from "next/head"; +import { List } from "immutable"; +import { + Header, + Table, + Message, + Container, + Pagination, +} from "semantic-ui-react"; + +import styles from "../styles/Home.module.css"; +import { useMemo, useState } from "react"; +import AddItem from "../components/add-item"; +import { + getGetItemsQueryKey, + useGetItems, + usePostItemsHook, +} from "../util/pantry-item-resource"; +import { PantryItem } from "../model"; +import { useMutation, useQueryClient } from "@tanstack/react-query"; + +const ENTRIES_PER_PAGE = Number(process.env.ENTRIES_PER_PAGE ?? "10"); + +interface SortStateProps { + field: keyof PantryItem; + order: "ascending" | "descending"; +} + +const Home: NextPage = () => { + const { data, error } = useGetItems(); + const postItems = usePostItemsHook(); + const queryClient = useQueryClient(); + const { mutate } = useMutation(postItems, { + onSuccess: async (item) => { + queryClient.setQueryData( + getGetItemsQueryKey(), + (data ?? []).concat(item) + ); + }, + }); + const [activePage, setActivePage] = useState(1); + const [sortState, setSortState] = useState<SortStateProps>({ + field: "name", + order: "ascending", + }); + + const hasEntries = useMemo( + () => error === null && (data === undefined || data.length > 0), + [error, data] + ); + const entries = useMemo(() => { + const list = List<PantryItem>(data); + // case insensitive sort + const sorted = list.sortBy((item) => + item[sortState.field]?.toString().toUpperCase() + ); + + return sortState.order === "ascending" ? sorted : sorted.reverse(); + }, [data, sortState]); + const handleSortChange = (field: keyof PantryItem) => { + setSortState((state) => + state.field === field + ? { + ...state, + order: state.order === "ascending" ? "descending" : "ascending", + } + : { field: field, order: "ascending" } + ); + }; + + return ( + <Container className={styles.container}> + <Head> + <title>Pantry</title> + <meta + name="description" + content="Meal planning with inventory management" + /> + <link rel="icon" href="/favicon.ico" /> + </Head> + + <Header as="h1" className="title"> + Pantry + </Header> + + <AddItem addItem={(newItem) => Promise.resolve(mutate(newItem))} /> + <Message error={error !== null} attached hidden={hasEntries}> + {error !== null + ? error.message !== undefined + ? `Network error occurred: ${error.message}` + : "Unknown network error occurred" + : "Nothing's in the pantry at the moment!"} + </Message> + <Table sortable attached="bottom"> + <Table.Header> + <Table.Row> + <Table.HeaderCell + sorted={sortState.field === "name" ? sortState.order : undefined} + onClick={() => handleSortChange("name")} + > + Name + </Table.HeaderCell> + <Table.HeaderCell + sorted={ + sortState.field === "description" ? sortState.order : undefined + } + onClick={() => handleSortChange("description")} + > + Description + </Table.HeaderCell> + <Table.HeaderCell + sorted={ + sortState.field === "quantity" ? sortState.order : undefined + } + onClick={() => handleSortChange("quantity")} + > + Quantity + </Table.HeaderCell> + </Table.Row> + </Table.Header> + <Table.Body> + {entries + .valueSeq() + .slice( + (activePage - 1) * ENTRIES_PER_PAGE, + activePage * ENTRIES_PER_PAGE + ) + .map((item: PantryItem) => ( + <Table.Row key={item.id}> + <Table.Cell>{item.name}</Table.Cell> + <Table.Cell> + {item.description === "" ? "—" : item.description} + </Table.Cell> + <Table.Cell> + {item.quantity} {item.quantityUnitType} + </Table.Cell> + </Table.Row> + ))} + </Table.Body> + <Table.Footer> + <Table.Row> + <Table.HeaderCell colSpan="3"> + <Pagination + activePage={activePage} + onPageChange={(_, { activePage }) => + setActivePage(Number(activePage ?? 1)) + } + totalPages={Math.max( + 1, + Math.ceil(entries.size / ENTRIES_PER_PAGE) + )} + /> + </Table.HeaderCell> + </Table.Row> + </Table.Footer> + </Table> + </Container> + ); +}; + +export default Home; diff --git a/src/styles/Home.module.css b/src/styles/Home.module.css new file mode 100644 index 0000000..ae734f6 --- /dev/null +++ b/src/styles/Home.module.css @@ -0,0 +1,4 @@ +.action { + margin-top: 20px; + margin-bottom: 20px; +} diff --git a/src/styles/globals.css b/src/styles/globals.css new file mode 100644 index 0000000..344cd26 --- /dev/null +++ b/src/styles/globals.css @@ -0,0 +1,16 @@ +html, +body { + padding: 20px 0; + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, + Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; +} + +a { + color: inherit; + text-decoration: none; +} + +* { + box-sizing: border-box; +} diff --git a/src/util/pantry-item-resource.ts b/src/util/pantry-item-resource.ts new file mode 100644 index 0000000..aedb286 --- /dev/null +++ b/src/util/pantry-item-resource.ts @@ -0,0 +1,212 @@ +/** + * Generated by orval v6.9.6 🍺 + * Do not edit manually. + * pantry API + * OpenAPI spec version: 1.0.0-SNAPSHOT + */ +import { useQuery, useMutation } from "@tanstack/react-query"; +import type { + UseQueryOptions, + UseMutationOptions, + QueryFunction, + MutationFunction, + UseQueryResult, + QueryKey, +} from "@tanstack/react-query"; +import type { PantryItem } from "../model"; +import { useMutator } from "../conf/mutator"; +import type { ErrorType } from "../conf/mutator"; + +export const useGetItemsHook = () => { + const getItems = useMutator<PantryItem[]>(); + + return (signal?: AbortSignal) => { + return getItems({ url: `/items`, method: "get", signal }); + }; +}; + +export const getGetItemsQueryKey = () => [`/items`]; + +export type GetItemsQueryResult = NonNullable< + Awaited<ReturnType<ReturnType<typeof useGetItemsHook>>> +>; +export type GetItemsQueryError = ErrorType<unknown>; + +export const useGetItems = < + TData = Awaited<ReturnType<ReturnType<typeof useGetItemsHook>>>, + TError = ErrorType<unknown> +>(options?: { + query?: UseQueryOptions< + Awaited<ReturnType<ReturnType<typeof useGetItemsHook>>>, + TError, + TData + >; +}): UseQueryResult<TData, TError> & { queryKey: QueryKey } => { + const { query: queryOptions } = options ?? {}; + + const queryKey = queryOptions?.queryKey ?? getGetItemsQueryKey(); + + const getItems = useGetItemsHook(); + + const queryFn: QueryFunction< + Awaited<ReturnType<ReturnType<typeof useGetItemsHook>>> + > = ({ signal }) => getItems(signal); + + const query = useQuery< + Awaited<ReturnType<ReturnType<typeof useGetItemsHook>>>, + TError, + TData + >(queryKey, queryFn, queryOptions) as UseQueryResult<TData, TError> & { + queryKey: QueryKey; + }; + + query.queryKey = queryKey; + + return query; +}; + +export const usePostItemsHook = () => { + const postItems = useMutator<PantryItem>(); + + return (pantryItem: PantryItem) => { + return postItems({ + url: `/items`, + method: "post", + headers: { "Content-Type": "application/json" }, + data: pantryItem, + }); + }; +}; + +export type PostItemsMutationResult = NonNullable< + Awaited<ReturnType<ReturnType<typeof usePostItemsHook>>> +>; +export type PostItemsMutationBody = PantryItem; +export type PostItemsMutationError = ErrorType<unknown>; + +export const usePostItems = < + TError = ErrorType<unknown>, + TContext = unknown +>(options?: { + mutation?: UseMutationOptions< + Awaited<ReturnType<ReturnType<typeof usePostItemsHook>>>, + TError, + { data: PantryItem }, + TContext + >; +}) => { + const { mutation: mutationOptions } = options ?? {}; + + const postItems = usePostItemsHook(); + + const mutationFn: MutationFunction< + Awaited<ReturnType<ReturnType<typeof usePostItemsHook>>>, + { data: PantryItem } + > = (props) => { + const { data } = props ?? {}; + + return postItems(data); + }; + + return useMutation< + Awaited<ReturnType<typeof postItems>>, + TError, + { data: PantryItem }, + TContext + >(mutationFn, mutationOptions); +}; +export const usePutItemsIdHook = () => { + const putItemsId = useMutator<PantryItem>(); + + return (id: number, pantryItem: PantryItem) => { + return putItemsId({ + url: `/items/${id}`, + method: "put", + headers: { "Content-Type": "application/json" }, + data: pantryItem, + }); + }; +}; + +export type PutItemsIdMutationResult = NonNullable< + Awaited<ReturnType<ReturnType<typeof usePutItemsIdHook>>> +>; +export type PutItemsIdMutationBody = PantryItem; +export type PutItemsIdMutationError = ErrorType<unknown>; + +export const usePutItemsId = < + TError = ErrorType<unknown>, + TContext = unknown +>(options?: { + mutation?: UseMutationOptions< + Awaited<ReturnType<ReturnType<typeof usePutItemsIdHook>>>, + TError, + { id: number; data: PantryItem }, + TContext + >; +}) => { + const { mutation: mutationOptions } = options ?? {}; + + const putItemsId = usePutItemsIdHook(); + + const mutationFn: MutationFunction< + Awaited<ReturnType<ReturnType<typeof usePutItemsIdHook>>>, + { id: number; data: PantryItem } + > = (props) => { + const { id, data } = props ?? {}; + + return putItemsId(id, data); + }; + + return useMutation< + Awaited<ReturnType<typeof putItemsId>>, + TError, + { id: number; data: PantryItem }, + TContext + >(mutationFn, mutationOptions); +}; +export const useDeleteItemsIdHook = () => { + const deleteItemsId = useMutator<void>(); + + return (id: number) => { + return deleteItemsId({ url: `/items/${id}`, method: "delete" }); + }; +}; + +export type DeleteItemsIdMutationResult = NonNullable< + Awaited<ReturnType<ReturnType<typeof useDeleteItemsIdHook>>> +>; + +export type DeleteItemsIdMutationError = ErrorType<unknown>; + +export const useDeleteItemsId = < + TError = ErrorType<unknown>, + TContext = unknown +>(options?: { + mutation?: UseMutationOptions< + Awaited<ReturnType<ReturnType<typeof useDeleteItemsIdHook>>>, + TError, + { id: number }, + TContext + >; +}) => { + const { mutation: mutationOptions } = options ?? {}; + + const deleteItemsId = useDeleteItemsIdHook(); + + const mutationFn: MutationFunction< + Awaited<ReturnType<ReturnType<typeof useDeleteItemsIdHook>>>, + { id: number } + > = (props) => { + const { id } = props ?? {}; + + return deleteItemsId(id); + }; + + return useMutation< + Awaited<ReturnType<typeof deleteItemsId>>, + TError, + { id: number }, + TContext + >(mutationFn, mutationOptions); +}; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..99710e8 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "exclude": ["node_modules"] +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..aba29fd --- /dev/null +++ b/yarn.lock @@ -0,0 +1,4229 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@apidevtools/json-schema-ref-parser@9.0.6": + version "9.0.6" + resolved "https://registry.yarnpkg.com/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.0.6.tgz#5d9000a3ac1fd25404da886da6b266adcd99cf1c" + integrity sha512-M3YgsLjI0lZxvrpeGVk9Ap032W6TPQkH6pRAZz81Ac3WUNF79VQooAFnp8umjvVzUmD93NkogxEwbSce7qMsUg== + dependencies: + "@jsdevtools/ono" "^7.1.3" + call-me-maybe "^1.0.1" + js-yaml "^3.13.1" + +"@apidevtools/openapi-schemas@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz#9fa08017fb59d80538812f03fc7cac5992caaa17" + integrity sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ== + +"@apidevtools/swagger-methods@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz#b789a362e055b0340d04712eafe7027ddc1ac267" + integrity sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg== + +"@apidevtools/swagger-parser@^10.1.0": + version "10.1.0" + resolved "https://registry.yarnpkg.com/@apidevtools/swagger-parser/-/swagger-parser-10.1.0.tgz#a987d71e5be61feb623203be0c96e5985b192ab6" + integrity sha512-9Kt7EuS/7WbMAUv2gSziqjvxwDbFSg3Xeyfuj5laUODX8o/k/CpsAKiQ8W7/R88eXFTMbJYg6+7uAmOWNKmwnw== + dependencies: + "@apidevtools/json-schema-ref-parser" "9.0.6" + "@apidevtools/openapi-schemas" "^2.1.0" + "@apidevtools/swagger-methods" "^3.0.2" + "@jsdevtools/ono" "^7.1.3" + ajv "^8.6.3" + ajv-draft-04 "^1.0.0" + call-me-maybe "^1.0.1" + +"@asyncapi/specs@^2.14.0": + version "2.14.0" + resolved "https://registry.yarnpkg.com/@asyncapi/specs/-/specs-2.14.0.tgz#a4535fedde931181f20d41356ed1906d0fb73d48" + integrity sha512-hHsYF6XsYNIKb1P2rXaooF4H+uKKQ4b/Ljxrk3rZ3riEDiSxMshMEfb1fUlw9Yj4V4OmJhjXwkNvw8W59AXv1A== + +"@babel/runtime-corejs3@^7.10.2": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.16.8.tgz#ea533d96eda6fdc76b1812248e9fbd0c11d4a1a7" + integrity sha512-3fKhuICS1lMz0plI5ktOE/yEtBRMVxplzRkdn6mJQ197XiY0JnrzYV0+Mxozq3JZ8SBV9Ecurmw1XsGbwOf+Sg== + dependencies: + core-js-pure "^3.20.2" + regenerator-runtime "^0.13.4" + +"@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.10.5", "@babel/runtime@^7.16.3": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa" + integrity sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ== + dependencies: + regenerator-runtime "^0.13.4" + +"@esbuild/linux-loong64@0.14.54": + version "0.14.54" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz#de2a4be678bd4d0d1ffbb86e6de779cde5999028" + integrity sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw== + +"@eslint/eslintrc@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.0.tgz#29f92c30bb3e771e4a2048c95fa6855392dfac4f" + integrity sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.3.2" + globals "^13.15.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + +"@exodus/schemasafe@^1.0.0-rc.2": + version "1.0.0-rc.7" + resolved "https://registry.yarnpkg.com/@exodus/schemasafe/-/schemasafe-1.0.0-rc.7.tgz#aded6839c2369883dafa46608a135c82b42ed76b" + integrity sha512-+1mBLsa+vvlV0lwEAP1hwgmOPkjMnoJ8hyCMfCCJga0sVDwDzrPJjnxZwdDaUmOh/vbFHQGBTk+FxsVjoI/CjQ== + +"@fluentui/react-component-event-listener@~0.63.0": + version "0.63.1" + resolved "https://registry.yarnpkg.com/@fluentui/react-component-event-listener/-/react-component-event-listener-0.63.1.tgz#c2af94893671f1d6b |
