@@ -1,6 +1,9 @@ | |||
/** @type {import('next').NextConfig} */ | |||
const nextConfig = { | |||
reactStrictMode: true, | |||
} | |||
experimental: { | |||
optimizeCss: true, | |||
}, | |||
}; | |||
module.exports = nextConfig | |||
module.exports = nextConfig; |
@@ -23,5 +23,8 @@ | |||
"react-dom": "18.2.0", | |||
"tailwindcss": "3.3.3", | |||
"typescript": "5.2.2" | |||
}, | |||
"devDependencies": { | |||
"critters": "^0.0.20" | |||
} | |||
} |
@@ -0,0 +1,34 @@ | |||
import * as React from 'react'; | |||
export const ActionButtonDerivedElementComponent = 'button' as const; | |||
export type ActionButtonDerivedElement = HTMLElementTagNameMap[typeof ActionButtonDerivedElementComponent]; | |||
export interface ActionButtonProps extends React.HTMLProps<ActionButtonDerivedElement> { | |||
primary?: boolean; | |||
} | |||
type ButtonType = 'button' | 'reset' | 'submit' | undefined; | |||
export const ActionButton = React.forwardRef<ActionButtonDerivedElement, ActionButtonProps>(({ | |||
primary, | |||
children, | |||
type, | |||
className, | |||
...etcProps | |||
}, forwardedRef) => { | |||
return ( | |||
<button | |||
{...etcProps} | |||
ref={forwardedRef} | |||
type={type as ButtonType} | |||
className={`h-12 px-4 border rounded ${className ?? ''}`.trim()} | |||
> | |||
<span> | |||
{children} | |||
</span> | |||
</button> | |||
) | |||
}); | |||
ActionButton.displayName = 'ActionButton'; |
@@ -0,0 +1,41 @@ | |||
import * as React from 'react'; | |||
export const MultilineTextInputDerivedElementComponent = 'textarea' as const; | |||
export type MultilineTextInputDerivedElement = HTMLElementTagNameMap[typeof MultilineTextInputDerivedElementComponent]; | |||
export interface MultilineTextInputProps extends Omit<React.HTMLProps<MultilineTextInputDerivedElement>, 'label'> { | |||
label?: React.ReactNode; | |||
} | |||
export const MultilineTextInput = React.forwardRef<MultilineTextInputDerivedElement, MultilineTextInputProps>(({ | |||
className = 'inline-block', | |||
style, | |||
label, | |||
rows = 3, | |||
...etcProps | |||
}, forwardedRef) => { | |||
return ( | |||
<div | |||
className={className} | |||
style={style} | |||
> | |||
<label className="relative block"> | |||
<span className="after:block pointer-events-none absolute top-0 left-0 text-xs px-1"> | |||
{label} | |||
</span> | |||
<MultilineTextInputDerivedElementComponent | |||
{...etcProps} | |||
ref={forwardedRef} | |||
rows={rows} | |||
style={{ | |||
height: `${(rows * 1.5) + 2}rem` | |||
}} | |||
className="border rounded min-h-12 px-4 py-4 block w-full resize-y" | |||
/> | |||
</label> | |||
</div> | |||
); | |||
}); | |||
MultilineTextInput.displayName = 'TextInput'; |
@@ -0,0 +1,36 @@ | |||
import * as React from 'react'; | |||
export const TextInputDerivedElementComponent = 'input' as const; | |||
export type TextInputDerivedElement = HTMLElementTagNameMap[typeof TextInputDerivedElementComponent]; | |||
export interface TextInputProps extends Omit<React.HTMLProps<TextInputDerivedElement>, 'label'> { | |||
label?: React.ReactNode; | |||
} | |||
export const TextInput = React.forwardRef<TextInputDerivedElement, TextInputProps>(({ | |||
className = 'inline-block', | |||
style, | |||
label, | |||
...etcProps | |||
}, forwardedRef) => { | |||
return ( | |||
<div | |||
className={className} | |||
style={style} | |||
> | |||
<label className="relative block"> | |||
<span className="after:block pointer-events-none absolute top-0 left-0 text-xs px-1"> | |||
{label} | |||
</span> | |||
<TextInputDerivedElementComponent | |||
{...etcProps} | |||
ref={forwardedRef} | |||
className="border rounded min-h-12 h-12 px-4 block w-full" | |||
/> | |||
</label> | |||
</div> | |||
); | |||
}); | |||
TextInput.displayName = 'TextInput'; |
@@ -1,6 +1,9 @@ | |||
import * as Iceform from '@modal-sh/iceform-next'; | |||
import * as React from 'react'; | |||
import { useRouter } from 'next/router'; | |||
import { TextInput } from '@/components/TextInput'; | |||
import { MultilineTextInput } from '@/components/MultilineTextInput'; | |||
import { ActionButton } from '@/components/ActionButton'; | |||
export interface NotesItemPageProps { | |||
note: { | |||
@@ -38,54 +41,75 @@ const NotesItemPage: Iceform.NextPage<NotesItemPageProps> = ({ | |||
}, [response]); | |||
return ( | |||
<div> | |||
<Iceform.Form | |||
{...isoformProps} | |||
className="contents" | |||
method="post" | |||
action={`/a/notes/${req.query.noteId}`} | |||
clientAction={`/api/notes/${req.query.noteId}`} | |||
clientMethod="put" | |||
refresh={defaultRefresh} | |||
> | |||
<div> | |||
<label> | |||
<span className="after:block">Title</span> | |||
<input type="text" name="title" defaultValue={body.title as string} /> | |||
</label> | |||
</div> | |||
<div> | |||
<label> | |||
<span className="after:block">Image</span> | |||
<input type="file" name="image" /> | |||
</label> | |||
</div> | |||
<div> | |||
<label> | |||
<span className="after:block">Content</span> | |||
<textarea name="content" defaultValue={body.content as string} /> | |||
</label> | |||
</div> | |||
<div> | |||
<button type="submit">Submit</button> | |||
</div> | |||
</Iceform.Form> | |||
<Iceform.Form | |||
{...isoformProps} | |||
method="post" | |||
action={`/a/notes/${req.query.noteId}`} | |||
clientAction={`/api/notes/${req.query.noteId}`} | |||
clientMethod="delete" | |||
className="contents" | |||
refresh={async (response) => { | |||
defaultRefresh(response); | |||
await router.push('/notes'); | |||
}} | |||
> | |||
<div> | |||
<button type="submit">Delete</button> | |||
</div> | |||
</Iceform.Form> | |||
<div className="my-24"> | |||
<div className="px-8 max-w-screen-sm mx-auto"> | |||
<Iceform.Form | |||
{...isoformProps} | |||
className="contents" | |||
method="post" | |||
action={`/a/notes/${req.query.noteId}`} | |||
clientAction={`/api/notes/${req.query.noteId}`} | |||
clientMethod="put" | |||
refresh={defaultRefresh} | |||
aria-label="Edit Existing Note" | |||
> | |||
<fieldset | |||
className="contents" | |||
> | |||
<legend | |||
className="sr-only" | |||
> | |||
Edit Note | |||
</legend> | |||
<div className="flex flex-col gap-4"> | |||
<div> | |||
<TextInput | |||
type="text" | |||
name="title" | |||
label="Title" | |||
className="block" | |||
defaultValue={body.title as string} | |||
/> | |||
</div> | |||
<div> | |||
<label> | |||
<span className="after:block">Image</span> | |||
<input type="file" name="image" /> | |||
</label> | |||
</div> | |||
<div> | |||
<MultilineTextInput | |||
name="content" | |||
label="Content" | |||
className="block" | |||
defaultValue={body.content as string} | |||
/> | |||
</div> | |||
<div className="flex justify-end gap-4"> | |||
<div> | |||
<ActionButton type="submit" className="bg-white text-black">Update</ActionButton> | |||
</div> | |||
<div> | |||
<ActionButton type="submit" form="delete-note-form">Delete</ActionButton> | |||
</div> | |||
</div> | |||
</div> | |||
</fieldset> | |||
</Iceform.Form> | |||
<Iceform.Form | |||
{...isoformProps} | |||
method="post" | |||
action={`/a/notes/${req.query.noteId}`} | |||
clientAction={`/api/notes/${req.query.noteId}`} | |||
clientMethod="delete" | |||
className="contents" | |||
refresh={async (response) => { | |||
defaultRefresh(response); | |||
await router.push('/notes'); | |||
}} | |||
id="delete-note-form" | |||
/> | |||
</div> | |||
</div> | |||
); | |||
}; | |||
@@ -1,46 +1,157 @@ | |||
import { NextPage } from 'next'; | |||
import { GetServerSideProps, NextPage } from 'next'; | |||
import * as Iceform from '@modal-sh/iceform-next'; | |||
import { useRouter } from 'next/router'; | |||
import { TextInput } from '@/components/TextInput'; | |||
import { MultilineTextInput } from '@/components/MultilineTextInput'; | |||
import { ActionButton } from '@/components/ActionButton'; | |||
import * as React from 'react'; | |||
const NotesPage: NextPage = () => { | |||
export interface NotesPageProps { | |||
notes: { | |||
id: string; | |||
title: string; | |||
content: string; | |||
image: string; | |||
}[]; | |||
} | |||
const NotesPage: NextPage<NotesPageProps> = ({ | |||
notes, | |||
}) => { | |||
const router = useRouter(); | |||
return ( | |||
<Iceform.Form | |||
method="post" | |||
action="/a/notes" | |||
clientAction="/api/notes" | |||
refresh={async (response) => { | |||
if (response.status !== 201) { | |||
return; | |||
} | |||
const { id } = await response.json(); | |||
await router.push(`/notes/${id}`); | |||
}} | |||
> | |||
<div> | |||
<label> | |||
<span className="after:block">Title</span> | |||
<input type="text" name="title" /> | |||
</label> | |||
</div> | |||
<div> | |||
<label> | |||
<span className="after:block">Image</span> | |||
<input type="file" name="image" /> | |||
</label> | |||
</div> | |||
<div> | |||
<label> | |||
<span className="after:block">Content</span> | |||
<textarea name="content" /> | |||
</label> | |||
</div> | |||
<div> | |||
<button type="submit">Submit</button> | |||
<div className="my-24"> | |||
<div className="px-8 max-w-screen-sm mx-auto"> | |||
<Iceform.Form | |||
method="post" | |||
action="/a/notes" | |||
clientAction="/api/notes" | |||
refresh={async (response) => { | |||
if (response.status !== 201) { | |||
return; | |||
} | |||
const { id } = await response.json(); | |||
await router.push(`/notes/${id}`); | |||
}} | |||
aria-label="Create New Note" | |||
className="contents" | |||
> | |||
<fieldset | |||
className="contents" | |||
> | |||
<legend | |||
className="sr-only" | |||
> | |||
New Note | |||
</legend> | |||
<div className="flex flex-col gap-4"> | |||
<div> | |||
<TextInput | |||
type="text" | |||
name="title" | |||
label="Title" | |||
className="block" | |||
/> | |||
</div> | |||
<div> | |||
<label> | |||
<span className="after:block">Image</span> | |||
<input type="file" name="image" /> | |||
</label> | |||
</div> | |||
<div> | |||
<MultilineTextInput | |||
name="content" | |||
label="Content" | |||
className="block" | |||
/> | |||
</div> | |||
<div className="text-right"> | |||
<ActionButton type="submit" className="bg-white text-black">Submit</ActionButton> | |||
</div> | |||
</div> | |||
</fieldset> | |||
</Iceform.Form> | |||
<div className="mt-24 flex flex-col gap-4"> | |||
{notes.map((note) => ( | |||
<div | |||
key={note.id} | |||
className="border rounded p-4" | |||
> | |||
<div className="flex gap-4 justify-end"> | |||
<form | |||
method="get" | |||
action={`/notes/${note.id}`} | |||
className="contents" | |||
> | |||
<div> | |||
<ActionButton type="submit"> | |||
Edit | |||
</ActionButton> | |||
</div> | |||
</form> | |||
<Iceform.Form | |||
method="post" | |||
action={`/a/notes/${note.id}`} | |||
clientAction={`/api/notes/${note.id}`} | |||
clientMethod="delete" | |||
className="contents" | |||
refresh={async () => { | |||
await router.push('/notes'); | |||
}} | |||
> | |||
<div> | |||
<ActionButton type="submit"> | |||
Delete | |||
</ActionButton> | |||
</div> | |||
</Iceform.Form> | |||
</div> | |||
<div | |||
className="font-bold" | |||
> | |||
{note.title} | |||
</div> | |||
<div> | |||
{note.content} | |||
</div> | |||
</div> | |||
))} | |||
</div> | |||
</div> | |||
</Iceform.Form> | |||
</div> | |||
) | |||
}; | |||
export const getServerSideProps: GetServerSideProps = async (ctx) => { | |||
let origin: string; | |||
if (ctx.req.headers.referer) { | |||
const refererUrl = new URL(ctx.req.headers.referer as string); | |||
origin = refererUrl.origin; | |||
} else { | |||
// TODO how to get the scheme? | |||
const scheme = 'http'; | |||
origin = `${scheme}://${ctx.req.headers.host}`; | |||
} | |||
const url = new URL(`/api/notes`, origin); | |||
const noteResponse = await fetch(url.toString(), { | |||
headers: { | |||
'Accept': 'application/json', | |||
} | |||
}); | |||
if (noteResponse.ok) { | |||
const notes = await noteResponse.json(); | |||
return { | |||
props: { | |||
notes, | |||
}, | |||
}; | |||
} | |||
return { | |||
notFound: true, | |||
}; | |||
}; | |||
export default NotesPage; |
@@ -13,6 +13,9 @@ const config: Config = { | |||
'gradient-conic': | |||
'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))', | |||
}, | |||
minHeight: { | |||
12: '3rem', | |||
}, | |||
}, | |||
}, | |||
plugins: [], | |||
@@ -54,7 +54,7 @@ export const wrapApiHandler = ( | |||
options: ActionWrapperOptions, | |||
): NextApiHandler => async (req, res) => { | |||
const reqMut = req as unknown as Record<string, unknown>; | |||
if (METHODS_WITH_BODY.includes(req.method?.toLowerCase() as typeof METHODS_WITH_BODY[number])) { | |||
if (METHODS_WITH_BODY.includes(req.method?.toUpperCase() as typeof METHODS_WITH_BODY[number])) { | |||
reqMut.body = await deserializeBody({ | |||
req, | |||
deserializers: options.deserializers, | |||
@@ -132,6 +132,10 @@ importers: | |||
typescript: | |||
specifier: 5.2.2 | |||
version: 5.2.2 | |||
devDependencies: | |||
critters: | |||
specifier: ^0.0.20 | |||
version: 0.0.20 | |||
packages: | |||
@@ -1302,7 +1306,6 @@ packages: | |||
typescript: 4.9.5 | |||
transitivePeerDependencies: | |||
- supports-color | |||
dev: true | |||
/@typescript-eslint/parser@6.7.0(eslint@8.49.0)(typescript@5.2.2): | |||
resolution: {integrity: sha512-jZKYwqNpNm5kzPVP5z1JXAuxjtl2uG+5NpaMocFPTNC2EdYIgbXIPImObOkhbONxtFTTdoZstLZefbaK+wXZng==} | |||
@@ -1331,7 +1334,6 @@ packages: | |||
dependencies: | |||
'@typescript-eslint/types': 5.62.0 | |||
'@typescript-eslint/visitor-keys': 5.62.0 | |||
dev: true | |||
/@typescript-eslint/scope-manager@6.7.0: | |||
resolution: {integrity: sha512-lAT1Uau20lQyjoLUQ5FUMSX/dS07qux9rYd5FGzKz/Kf8W8ccuvMyldb8hadHdK/qOI7aikvQWqulnEq2nCEYA==} | |||
@@ -1364,7 +1366,6 @@ packages: | |||
/@typescript-eslint/types@5.62.0: | |||
resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==} | |||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} | |||
dev: true | |||
/@typescript-eslint/types@6.7.0: | |||
resolution: {integrity: sha512-ihPfvOp7pOcN/ysoj0RpBPOx3HQTJTrIN8UZK+WFd3/iDeFHHqeyYxa4hQk4rMhsz9H9mXpR61IzwlBVGXtl9Q==} | |||
@@ -1390,7 +1391,6 @@ packages: | |||
typescript: 4.9.5 | |||
transitivePeerDependencies: | |||
- supports-color | |||
dev: true | |||
/@typescript-eslint/typescript-estree@6.7.0(typescript@5.2.2): | |||
resolution: {integrity: sha512-dPvkXj3n6e9yd/0LfojNU8VMUGHWiLuBZvbM6V6QYD+2qxqInE7J+J/ieY2iGwR9ivf/R/haWGkIj04WVUeiSQ==} | |||
@@ -1439,7 +1439,6 @@ packages: | |||
dependencies: | |||
'@typescript-eslint/types': 5.62.0 | |||
eslint-visitor-keys: 3.4.3 | |||
dev: true | |||
/@typescript-eslint/visitor-keys@6.7.0: | |||
resolution: {integrity: sha512-/C1RVgKFDmGMcVGeD8HjKv2bd72oI1KxQDeY8uc66gw9R0OK0eMq48cA+jv9/2Ag6cdrsUGySm1yzYmfz0hxwQ==} | |||
@@ -2032,6 +2031,18 @@ packages: | |||
engines: {node: '>= 0.6'} | |||
dev: true | |||
/critters@0.0.20: | |||
resolution: {integrity: sha512-CImNRorKOl5d8TWcnAz5n5izQ6HFsvz29k327/ELy6UFcmbiZNOsinaKvzv16WZR0P6etfSWYzE47C4/56B3Uw==} | |||
dependencies: | |||
chalk: 4.1.2 | |||
css-select: 5.1.0 | |||
dom-serializer: 2.0.0 | |||
domhandler: 5.0.3 | |||
htmlparser2: 8.0.2 | |||
postcss: 8.4.29 | |||
pretty-bytes: 5.6.0 | |||
dev: true | |||
/cross-spawn@7.0.3: | |||
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} | |||
engines: {node: '>= 8'} | |||
@@ -2045,6 +2056,21 @@ packages: | |||
engines: {node: '>=8'} | |||
dev: true | |||
/css-select@5.1.0: | |||
resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} | |||
dependencies: | |||
boolbase: 1.0.0 | |||
css-what: 6.1.0 | |||
domhandler: 5.0.3 | |||
domutils: 3.1.0 | |||
nth-check: 2.1.1 | |||
dev: true | |||
/css-what@6.1.0: | |||
resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} | |||
engines: {node: '>= 6'} | |||
dev: true | |||
/css.escape@1.5.1: | |||
resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} | |||
dev: true | |||
@@ -2245,6 +2271,18 @@ packages: | |||
resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} | |||
dev: true | |||
/dom-serializer@2.0.0: | |||
resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} | |||
dependencies: | |||
domelementtype: 2.3.0 | |||
domhandler: 5.0.3 | |||
entities: 4.5.0 | |||
dev: true | |||
/domelementtype@2.3.0: | |||
resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} | |||
dev: true | |||
/domexception@4.0.0: | |||
resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} | |||
engines: {node: '>=12'} | |||
@@ -2252,6 +2290,21 @@ packages: | |||
webidl-conversions: 7.0.0 | |||
dev: true | |||
/domhandler@5.0.3: | |||
resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} | |||
engines: {node: '>= 4'} | |||
dependencies: | |||
domelementtype: 2.3.0 | |||
dev: true | |||
/domutils@3.1.0: | |||
resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} | |||
dependencies: | |||
dom-serializer: 2.0.0 | |||
domelementtype: 2.3.0 | |||
domhandler: 5.0.3 | |||
dev: true | |||
/dot-prop@5.3.0: | |||
resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} | |||
engines: {node: '>=8'} | |||
@@ -2624,7 +2677,6 @@ packages: | |||
- eslint-import-resolver-node | |||
- eslint-import-resolver-webpack | |||
- supports-color | |||
dev: true | |||
/eslint-import-resolver-typescript@3.6.0(@typescript-eslint/parser@6.7.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.28.1)(eslint@8.49.0): | |||
resolution: {integrity: sha512-QTHR9ddNnn35RTxlaEnx2gCxqFlF2SEN0SE2d17SqwyM7YOSI2GHWRYp5BiRkObTUNYPupC/3Fq2a0PpT+EKpg==} | |||
@@ -2677,7 +2729,6 @@ packages: | |||
eslint-import-resolver-typescript: 3.6.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.28.1)(eslint@8.49.0) | |||
transitivePeerDependencies: | |||
- supports-color | |||
dev: true | |||
/eslint-module-utils@2.8.0(@typescript-eslint/parser@6.7.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.0)(eslint@8.49.0): | |||
resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} | |||
@@ -2758,7 +2809,6 @@ packages: | |||
- eslint-import-resolver-typescript | |||
- eslint-import-resolver-webpack | |||
- supports-color | |||
dev: true | |||
/eslint-plugin-import@2.28.1(@typescript-eslint/parser@6.7.0)(eslint-import-resolver-typescript@3.6.0)(eslint@8.49.0): | |||
resolution: {integrity: sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==} | |||
@@ -2779,7 +2829,7 @@ packages: | |||
doctrine: 2.1.0 | |||
eslint: 8.49.0 | |||
eslint-import-resolver-node: 0.3.9 | |||
eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.7.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.0)(eslint@8.49.0) | |||
eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.0)(eslint@8.49.0) | |||
has: 1.0.3 | |||
is-core-module: 2.13.0 | |||
is-glob: 4.0.3 | |||
@@ -3376,6 +3426,15 @@ packages: | |||
resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} | |||
dev: true | |||
/htmlparser2@8.0.2: | |||
resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} | |||
dependencies: | |||
domelementtype: 2.3.0 | |||
domhandler: 5.0.3 | |||
domutils: 3.1.0 | |||
entities: 4.5.0 | |||
dev: true | |||
/http-errors@2.0.0: | |||
resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} | |||
engines: {node: '>= 0.8'} | |||
@@ -4486,6 +4545,11 @@ packages: | |||
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} | |||
engines: {node: '>= 0.8.0'} | |||
/pretty-bytes@5.6.0: | |||
resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==} | |||
engines: {node: '>=6'} | |||
dev: true | |||
/pretty-bytes@6.1.1: | |||
resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==} | |||
engines: {node: ^14.13.1 || >=16.0.0} | |||
@@ -5214,7 +5278,6 @@ packages: | |||
/tslib@1.14.1: | |||
resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} | |||
dev: true | |||
/tslib@2.5.0: | |||
resolution: {integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==} | |||
@@ -5227,7 +5290,6 @@ packages: | |||
dependencies: | |||
tslib: 1.14.1 | |||
typescript: 4.9.5 | |||
dev: true | |||
/type-check@0.4.0: | |||
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} | |||
@@ -5296,7 +5358,6 @@ packages: | |||
resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} | |||
engines: {node: '>=4.2.0'} | |||
hasBin: true | |||
dev: true | |||
/typescript@5.2.2: | |||
resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} | |||