ソースを参照

Update implementation

Test implementation on both client-side and server-side.
master
コミット
1840679d3c
10個のファイルの変更414行の追加98行の削除
  1. +5
    -2
      packages/iceform-next-sandbox/next.config.js
  2. +3
    -0
      packages/iceform-next-sandbox/package.json
  3. +34
    -0
      packages/iceform-next-sandbox/src/components/ActionButton.tsx
  4. +41
    -0
      packages/iceform-next-sandbox/src/components/MultilineTextInput.tsx
  5. +36
    -0
      packages/iceform-next-sandbox/src/components/TextInput.tsx
  6. +72
    -48
      packages/iceform-next-sandbox/src/pages/notes/[noteId].tsx
  7. +146
    -35
      packages/iceform-next-sandbox/src/pages/notes/index.tsx
  8. +3
    -0
      packages/iceform-next-sandbox/tailwind.config.ts
  9. +1
    -1
      packages/iceform-next/src/server/action.ts
  10. +73
    -12
      pnpm-lock.yaml

+ 5
- 2
packages/iceform-next-sandbox/next.config.js ファイルの表示

@@ -1,6 +1,9 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
}
experimental: {
optimizeCss: true,
},
};

module.exports = nextConfig
module.exports = nextConfig;

+ 3
- 0
packages/iceform-next-sandbox/package.json ファイルの表示

@@ -23,5 +23,8 @@
"react-dom": "18.2.0",
"tailwindcss": "3.3.3",
"typescript": "5.2.2"
},
"devDependencies": {
"critters": "^0.0.20"
}
}

+ 34
- 0
packages/iceform-next-sandbox/src/components/ActionButton.tsx ファイルの表示

@@ -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';

+ 41
- 0
packages/iceform-next-sandbox/src/components/MultilineTextInput.tsx ファイルの表示

@@ -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';

+ 36
- 0
packages/iceform-next-sandbox/src/components/TextInput.tsx ファイルの表示

@@ -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';

+ 72
- 48
packages/iceform-next-sandbox/src/pages/notes/[noteId].tsx ファイルの表示

@@ -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>
);
};


+ 146
- 35
packages/iceform-next-sandbox/src/pages/notes/index.tsx ファイルの表示

@@ -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;

+ 3
- 0
packages/iceform-next-sandbox/tailwind.config.ts ファイルの表示

@@ -13,6 +13,9 @@ const config: Config = {
'gradient-conic':
'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
},
minHeight: {
12: '3rem',
},
},
},
plugins: [],


+ 1
- 1
packages/iceform-next/src/server/action.ts ファイルの表示

@@ -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,


+ 73
- 12
pnpm-lock.yaml ファイルの表示

@@ -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==}


読み込み中…
キャンセル
保存