mirror of
https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
synced 2025-10-09 19:46:37 +08:00
Amplify
This commit is contained in:
parent
f021826220
commit
d44bb47efd
@ -1,4 +1,9 @@
|
|||||||
|
|
||||||
|
USER_POOL_ID=
|
||||||
|
|
||||||
|
USER_POOL_CLIENT_ID=
|
||||||
|
|
||||||
|
|
||||||
# Your openai api key. (required)
|
# Your openai api key. (required)
|
||||||
OPENAI_API_KEY=sk-xxxx
|
OPENAI_API_KEY=sk-xxxx
|
||||||
|
|
||||||
|
4
app/auth/layout.module.scss
Normal file
4
app/auth/layout.module.scss
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
.container {
|
||||||
|
background-color: white;
|
||||||
|
/* 其他样式 */
|
||||||
|
}
|
23
app/auth/layout.tsx
Normal file
23
app/auth/layout.tsx
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// app\auth\layout.tsx
|
||||||
|
|
||||||
|
import styles from "./layout.module.scss";
|
||||||
|
|
||||||
|
export default function AuthLayout({
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta
|
||||||
|
name="viewport"
|
||||||
|
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
||||||
|
/>
|
||||||
|
<link rel="manifest" href="/site.webmanifest"></link>
|
||||||
|
<script src="/serviceWorkerRegister.js" defer></script>
|
||||||
|
</head>
|
||||||
|
<body className={styles.container}>{children}</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
}
|
89
app/auth/login.module.scss
Normal file
89
app/auth/login.module.scss
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
.loginContainer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.authenticator {
|
||||||
|
// /* 覆盖全局样式 */
|
||||||
|
input[type="number"],
|
||||||
|
input[type="text"],
|
||||||
|
input[type="password"] {
|
||||||
|
-webkit-appearance: none !important;
|
||||||
|
-moz-appearance: none !important;
|
||||||
|
appearance: none !important;
|
||||||
|
border-radius: var(
|
||||||
|
--amplify-components-fieldcontrol-border-radius
|
||||||
|
) !important;
|
||||||
|
border: var(--amplify-components-fieldcontrol-border) !important;
|
||||||
|
min-height: 36px !important;
|
||||||
|
box-sizing: border-box !important;
|
||||||
|
background: var(--amplify-components-fieldcontrol-background) !important;
|
||||||
|
color: var(--amplify-components-fieldcontrol-color) !important;
|
||||||
|
padding: var(--amplify-components-fieldcontrol-padding) !important;
|
||||||
|
max-width: 100% !important;
|
||||||
|
font-family: inherit !important;
|
||||||
|
font-size: var(--amplify-components-fieldcontrol-font-size) !important;
|
||||||
|
line-height: var(--amplify-components-fieldcontrol-line-height) !important;
|
||||||
|
-webkit-padding-before: var(
|
||||||
|
--amplify-components-fieldcontrol-padding-block-start
|
||||||
|
) !important;
|
||||||
|
padding-block-start: var(
|
||||||
|
--amplify-components-fieldcontrol-padding-block-start
|
||||||
|
) !important;
|
||||||
|
-webkit-padding-after: var(
|
||||||
|
--amplify-components-fieldcontrol-padding-block-end
|
||||||
|
) !important;
|
||||||
|
padding-block-end: var(
|
||||||
|
--amplify-components-fieldcontrol-padding-block-end
|
||||||
|
) !important;
|
||||||
|
-webkit-padding-start: var(
|
||||||
|
--amplify-components-fieldcontrol-padding-inline-start
|
||||||
|
) !important;
|
||||||
|
padding-inline-start: var(
|
||||||
|
--amplify-components-fieldcontrol-padding-inline-start
|
||||||
|
) !important;
|
||||||
|
-webkit-padding-end: var(
|
||||||
|
--amplify-components-fieldcontrol-padding-inline-end
|
||||||
|
) !important;
|
||||||
|
padding-inline-end: var(
|
||||||
|
--amplify-components-fieldcontrol-padding-inline-end
|
||||||
|
) !important;
|
||||||
|
transition: all var(--amplify-components-fieldcontrol-transition-duration) !important;
|
||||||
|
width: 100% !important;
|
||||||
|
border-color: var(
|
||||||
|
--amplify-components-fieldcontrol-border-color
|
||||||
|
) !important;
|
||||||
|
border-style: var(
|
||||||
|
--amplify-components-fieldcontrol-border-style
|
||||||
|
) !important;
|
||||||
|
border-width: var(
|
||||||
|
--amplify-components-fieldcontrol-border-width
|
||||||
|
) !important;
|
||||||
|
outline-color: var(
|
||||||
|
--amplify-components-fieldcontrol-outline-color
|
||||||
|
) !important;
|
||||||
|
outline-style: var(
|
||||||
|
--amplify-components-fieldcontrol-outline-style
|
||||||
|
) !important;
|
||||||
|
outline-width: var(
|
||||||
|
--amplify-components-fieldcontrol-outline-width
|
||||||
|
) !important;
|
||||||
|
outline-offset: var(
|
||||||
|
--amplify-components-fieldcontrol-outline-offset
|
||||||
|
) !important;
|
||||||
|
-webkit-user-select: text !important;
|
||||||
|
-moz-user-select: text !important;
|
||||||
|
user-select: text !important;
|
||||||
|
display: inline-block !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="password"]::-ms-reveal,
|
||||||
|
input[type="password"]::-ms-clear,
|
||||||
|
input[type="password"]::-webkit-search-cancel-button,
|
||||||
|
input[type="password"]::-webkit-search-decoration {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
89
app/auth/login.tsx
Normal file
89
app/auth/login.tsx
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
"use client";
|
||||||
|
// app\auth\login.tsx
|
||||||
|
import { Authenticator, useAuthenticator } from "@aws-amplify/ui-react";
|
||||||
|
import { Amplify, type ResourcesConfig } from "aws-amplify";
|
||||||
|
import { Hub } from "aws-amplify/utils";
|
||||||
|
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
import { Path } from "../constant";
|
||||||
|
import styles from "./login.module.scss";
|
||||||
|
import "@aws-amplify/ui-react/styles.css";
|
||||||
|
import {
|
||||||
|
confirmSignIn,
|
||||||
|
type ConfirmSignInInput,
|
||||||
|
type ConfirmSignInOutput,
|
||||||
|
} from "aws-amplify/auth";
|
||||||
|
|
||||||
|
// Hub.listen("auth", ({ payload }) => {
|
||||||
|
// switch (payload.event) {
|
||||||
|
// case "signedIn":
|
||||||
|
// console.log("user have been signedIn successfully.");
|
||||||
|
// const router = useRouter();
|
||||||
|
// router.push(Path.Home);
|
||||||
|
// break;
|
||||||
|
// case "signedOut":
|
||||||
|
// console.log("user have been signedOut successfully.");
|
||||||
|
// break;
|
||||||
|
// case "tokenRefresh":
|
||||||
|
// console.log("auth tokens have been refreshed.");
|
||||||
|
// break;
|
||||||
|
// case "tokenRefresh_failure":
|
||||||
|
// console.log("failure while refreshing auth tokens.");
|
||||||
|
// break;
|
||||||
|
// case "signInWithRedirect":
|
||||||
|
// console.log("signInWithRedirect API has successfully been resolved.");
|
||||||
|
// break;
|
||||||
|
// case "signInWithRedirect_failure":
|
||||||
|
// console.log("failure while trying to resolve signInWithRedirect API.");
|
||||||
|
// break;
|
||||||
|
// case "customOAuthState":
|
||||||
|
// console.info("custom state returned from CognitoHosted UI");
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
const authConfig: ResourcesConfig["Auth"] = {
|
||||||
|
Cognito: {
|
||||||
|
userPoolId: "eu-central-1_vu74Tv7SY",
|
||||||
|
userPoolClientId: "6f4c2hie09ms17uvmo2qn1kmkh",
|
||||||
|
//identityPoolId: "eu-central-1:d988e88f-5c19-4c89-841b-63c7a8d50b27",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Amplify.configure({
|
||||||
|
Auth: authConfig,
|
||||||
|
});
|
||||||
|
|
||||||
|
export function Login() {
|
||||||
|
// const services = {
|
||||||
|
// async handleConfirmSignIn(
|
||||||
|
// input: ConfirmSignInInput,
|
||||||
|
// ): Promise<ConfirmSignInOutput> {
|
||||||
|
// try {
|
||||||
|
// console.log("Confirming sign in", input);
|
||||||
|
// const result = await confirmSignIn(input);
|
||||||
|
// console.log("Sign in confirmed", result);
|
||||||
|
// router.push(Path.Home);
|
||||||
|
// return result;
|
||||||
|
// } catch (error) {
|
||||||
|
// console.error("Error confirming sign in", error);
|
||||||
|
// throw error; // Ensure to throw the error to match the expected return type
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// };
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.loginContainer}>
|
||||||
|
<Authenticator
|
||||||
|
loginMechanisms={["email"]}
|
||||||
|
socialProviders={["apple", "google"]}
|
||||||
|
signUpAttributes={["name"]}
|
||||||
|
//services={services}
|
||||||
|
//variation="modal"
|
||||||
|
className={styles.authenticator}
|
||||||
|
></Authenticator>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
10
app/auth/page.tsx
Normal file
10
app/auth/page.tsx
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
//app\auth\page.tsx
|
||||||
|
import { Login } from "./login";
|
||||||
|
import { Authenticator } from "@aws-amplify/ui-react";
|
||||||
|
export default function AuthPage() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Login />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
@ -231,10 +231,12 @@
|
|||||||
|
|
||||||
animation: slide-in ease 0.3s;
|
animation: slide-in ease 0.3s;
|
||||||
|
|
||||||
$linear: linear-gradient(to right,
|
$linear: linear-gradient(
|
||||||
rgba(0, 0, 0, 0),
|
to right,
|
||||||
rgba(0, 0, 0, 1),
|
rgba(0, 0, 0, 0),
|
||||||
rgba(0, 0, 0, 0));
|
rgba(0, 0, 0, 1),
|
||||||
|
rgba(0, 0, 0, 0)
|
||||||
|
);
|
||||||
mask-image: $linear;
|
mask-image: $linear;
|
||||||
|
|
||||||
@mixin show {
|
@mixin show {
|
||||||
@ -367,7 +369,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-message-user>.chat-message-container {
|
.chat-message-user > .chat-message-container {
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,9 +452,8 @@
|
|||||||
border: rgba($color: #888, $alpha: 0.2) 1px solid;
|
border: rgba($color: #888, $alpha: 0.2) 1px solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@media only screen and (max-width: 600px) {
|
@media only screen and (max-width: 600px) {
|
||||||
$calc-image-width: calc(100vw/3*2/var(--image-count));
|
$calc-image-width: calc(100vw / 3 * 2 / var(--image-count));
|
||||||
|
|
||||||
.chat-message-item-image-multi {
|
.chat-message-item-image-multi {
|
||||||
width: $calc-image-width;
|
width: $calc-image-width;
|
||||||
@ -460,13 +461,18 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.chat-message-item-image {
|
.chat-message-item-image {
|
||||||
max-width: calc(100vw/3*2);
|
max-width: calc(100vw / 3 * 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 600px) {
|
@media screen and (min-width: 600px) {
|
||||||
$max-image-width: calc(calc(1200px - var(--sidebar-width))/3*2/var(--image-count));
|
$max-image-width: calc(
|
||||||
$image-width: calc(calc(var(--window-width) - var(--sidebar-width))/3*2/var(--image-count));
|
calc(1200px - var(--sidebar-width)) / 3 * 2 / var(--image-count)
|
||||||
|
);
|
||||||
|
$image-width: calc(
|
||||||
|
calc(var(--window-width) - var(--sidebar-width)) / 3 * 2 /
|
||||||
|
var(--image-count)
|
||||||
|
);
|
||||||
|
|
||||||
.chat-message-item-image-multi {
|
.chat-message-item-image-multi {
|
||||||
width: $image-width;
|
width: $image-width;
|
||||||
@ -476,7 +482,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.chat-message-item-image {
|
.chat-message-item-image {
|
||||||
max-width: calc(calc(1200px - var(--sidebar-width))/3*2);
|
max-width: calc(calc(1200px - var(--sidebar-width)) / 3 * 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -494,7 +500,7 @@
|
|||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-message-user>.chat-message-container>.chat-message-item {
|
.chat-message-user > .chat-message-container > .chat-message-item {
|
||||||
background-color: var(--second);
|
background-color: var(--second);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
@ -605,7 +611,8 @@
|
|||||||
min-height: 68px;
|
min-height: 68px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-input:focus {}
|
.chat-input:focus {
|
||||||
|
}
|
||||||
|
|
||||||
.chat-input-send {
|
.chat-input-send {
|
||||||
background-color: var(--primary);
|
background-color: var(--primary);
|
||||||
|
@ -128,6 +128,7 @@ function Screen() {
|
|||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const isHome = location.pathname === Path.Home;
|
const isHome = location.pathname === Path.Home;
|
||||||
const isAuth = location.pathname === Path.Auth;
|
const isAuth = location.pathname === Path.Auth;
|
||||||
|
//const isLogin = location.pathname === Path.Login;
|
||||||
const isMobileScreen = useMobileScreen();
|
const isMobileScreen = useMobileScreen();
|
||||||
const shouldTightBorder =
|
const shouldTightBorder =
|
||||||
getClientConfig()?.isApp || (config.tightBorder && !isMobileScreen);
|
getClientConfig()?.isApp || (config.tightBorder && !isMobileScreen);
|
||||||
|
@ -15,12 +15,13 @@ export const ANTHROPIC_BASE_URL = "https://api.anthropic.com";
|
|||||||
export const GEMINI_BASE_URL = "https://generativelanguage.googleapis.com/";
|
export const GEMINI_BASE_URL = "https://generativelanguage.googleapis.com/";
|
||||||
|
|
||||||
export enum Path {
|
export enum Path {
|
||||||
|
Login = "/login",
|
||||||
Home = "/",
|
Home = "/",
|
||||||
Chat = "/chat",
|
Chat = "/chat",
|
||||||
Settings = "/settings",
|
Settings = "/settings",
|
||||||
NewChat = "/new-chat",
|
NewChat = "/new-chat",
|
||||||
Masks = "/masks",
|
Masks = "/masks",
|
||||||
Auth = "/auth",
|
Auth = "/b-auth", //暂时修改
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ApiPath {
|
export enum ApiPath {
|
||||||
@ -182,6 +183,7 @@ const bedrockModels = [
|
|||||||
"claude-3-haiku",
|
"claude-3-haiku",
|
||||||
"claude-3-sonnet",
|
"claude-3-sonnet",
|
||||||
"claude-3-opus",
|
"claude-3-opus",
|
||||||
|
"knowledge-base-regulations",
|
||||||
];
|
];
|
||||||
|
|
||||||
export const DEFAULT_MODELS = [
|
export const DEFAULT_MODELS = [
|
||||||
|
2
app/global.d.ts
vendored
2
app/global.d.ts
vendored
@ -21,7 +21,7 @@ declare interface Window {
|
|||||||
writeBinaryFile(path: string, data: Uint8Array): Promise<void>;
|
writeBinaryFile(path: string, data: Uint8Array): Promise<void>;
|
||||||
writeTextFile(path: string, data: string): Promise<void>;
|
writeTextFile(path: string, data: string): Promise<void>;
|
||||||
};
|
};
|
||||||
notification:{
|
notification: {
|
||||||
requestPermission(): Promise<Permission>;
|
requestPermission(): Promise<Permission>;
|
||||||
isPermissionGranted(): Promise<boolean>;
|
isPermissionGranted(): Promise<boolean>;
|
||||||
sendNotification(options: string | Options): void;
|
sendNotification(options: string | Options): void;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
/* eslint-disable @next/next/no-page-custom-font */
|
/* eslint-disable @next/next/no-page-custom-font */
|
||||||
|
// app\layout.tsx
|
||||||
import "./styles/globals.scss";
|
import "./styles/globals.scss";
|
||||||
import "./styles/markdown.scss";
|
import "./styles/markdown.scss";
|
||||||
import "./styles/highlight.scss";
|
import "./styles/highlight.scss";
|
||||||
@ -7,6 +8,7 @@ import { type Metadata } from "next";
|
|||||||
import { SpeedInsights } from "@vercel/speed-insights/next";
|
import { SpeedInsights } from "@vercel/speed-insights/next";
|
||||||
import { getServerSideConfig } from "./config/server";
|
import { getServerSideConfig } from "./config/server";
|
||||||
import { GoogleTagManager } from "@next/third-parties/google";
|
import { GoogleTagManager } from "@next/third-parties/google";
|
||||||
|
import { Authenticator } from "@aws-amplify/ui-react";
|
||||||
const serverConfig = getServerSideConfig();
|
const serverConfig = getServerSideConfig();
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
@ -36,7 +38,10 @@ export default function RootLayout({
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta name="config" content={JSON.stringify(getClientConfig())} />
|
<meta name="config" content={JSON.stringify(getClientConfig())} />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
<meta
|
||||||
|
name="viewport"
|
||||||
|
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
||||||
|
/>
|
||||||
<link rel="manifest" href="/site.webmanifest"></link>
|
<link rel="manifest" href="/site.webmanifest"></link>
|
||||||
<script src="/serviceWorkerRegister.js" defer></script>
|
<script src="/serviceWorkerRegister.js" defer></script>
|
||||||
</head>
|
</head>
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
|
// app\page.tsx
|
||||||
import { Analytics } from "@vercel/analytics/react";
|
import { Analytics } from "@vercel/analytics/react";
|
||||||
|
|
||||||
import { Home } from "./components/home";
|
import { Home } from "./components/home";
|
||||||
|
|
||||||
import { getServerSideConfig } from "./config/server";
|
import { getServerSideConfig } from "./config/server";
|
||||||
|
|
||||||
const serverConfig = getServerSideConfig();
|
const serverConfig = getServerSideConfig();
|
||||||
|
@ -366,7 +366,10 @@ export const useChatStore = createPersistStore(
|
|||||||
var api: ClientApi;
|
var api: ClientApi;
|
||||||
if (modelConfig.model.startsWith("gemini")) {
|
if (modelConfig.model.startsWith("gemini")) {
|
||||||
api = new ClientApi(ModelProvider.GeminiPro);
|
api = new ClientApi(ModelProvider.GeminiPro);
|
||||||
} else if (modelConfig.model.startsWith("claude")) {
|
} else if (
|
||||||
|
modelConfig.model.startsWith("claude") ||
|
||||||
|
modelConfig.model.startsWith("knowledge-base")
|
||||||
|
) {
|
||||||
api = new ClientApi(ModelProvider.Bedrock);
|
api = new ClientApi(ModelProvider.Bedrock);
|
||||||
//api = new ClientApi(ModelProvider.Claude);
|
//api = new ClientApi(ModelProvider.Claude);
|
||||||
} else {
|
} else {
|
||||||
|
26
middleware.ts
Normal file
26
middleware.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
//Next.js请求中间件
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import type { NextRequest } from "next/server";
|
||||||
|
import { fetchAuthSession } from "aws-amplify/auth";
|
||||||
|
|
||||||
|
// 如果在该函数中使用 "await",则可将其标记为 "async"。
|
||||||
|
export async function middleware(request: NextRequest) {
|
||||||
|
try {
|
||||||
|
const session = await fetchAuthSession();
|
||||||
|
console.log("session", session);
|
||||||
|
if (session) {
|
||||||
|
//return NextResponse.redirect(new URL("/auth", request.url));
|
||||||
|
return NextResponse.next();
|
||||||
|
} else {
|
||||||
|
return NextResponse.redirect(new URL("/auth", request.url));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
return NextResponse.redirect(new URL("/auth", request.url));
|
||||||
|
}
|
||||||
|
// return NextResponse.redirect(new URL("/", request.url));
|
||||||
|
}
|
||||||
|
|
||||||
|
// See "Matching Paths" below to learn more
|
||||||
|
export const config = {
|
||||||
|
matcher: ["/((?!auth).*)"], // Apply middleware to all paths except /auth
|
||||||
|
};
|
@ -16,12 +16,14 @@
|
|||||||
"proxy-dev": "sh ./scripts/init-proxy.sh && proxychains -f ./scripts/proxychains.conf yarn dev"
|
"proxy-dev": "sh ./scripts/init-proxy.sh && proxychains -f ./scripts/proxychains.conf yarn dev"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@aws-amplify/ui-react": "^6.1.12",
|
||||||
"@fortaine/fetch-event-source": "^3.0.6",
|
"@fortaine/fetch-event-source": "^3.0.6",
|
||||||
"@hello-pangea/dnd": "^16.5.0",
|
"@hello-pangea/dnd": "^16.5.0",
|
||||||
"@next/third-parties": "^14.1.0",
|
"@next/third-parties": "^14.1.0",
|
||||||
"@svgr/webpack": "^6.5.1",
|
"@svgr/webpack": "^6.5.1",
|
||||||
"@vercel/analytics": "^0.1.11",
|
"@vercel/analytics": "^0.1.11",
|
||||||
"@vercel/speed-insights": "^1.0.2",
|
"@vercel/speed-insights": "^1.0.2",
|
||||||
|
"aws-amplify": "^6.3.6",
|
||||||
"emoji-picker-react": "^4.9.2",
|
"emoji-picker-react": "^4.9.2",
|
||||||
"fuse.js": "^7.0.0",
|
"fuse.js": "^7.0.0",
|
||||||
"heic2any": "^0.0.4",
|
"heic2any": "^0.0.4",
|
||||||
@ -45,6 +47,8 @@
|
|||||||
"zustand": "^4.3.8"
|
"zustand": "^4.3.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@aws-amplify/backend": "^1.0.3",
|
||||||
|
"@aws-amplify/backend-cli": "^1.0.4",
|
||||||
"@tauri-apps/cli": "1.5.11",
|
"@tauri-apps/cli": "1.5.11",
|
||||||
"@types/node": "^20.11.30",
|
"@types/node": "^20.11.30",
|
||||||
"@types/react": "^18.2.70",
|
"@types/react": "^18.2.70",
|
||||||
|
Loading…
Reference in New Issue
Block a user