mirror of
https://github.com/Yidadaa/ChatGPT-Next-Web.git
synced 2025-09-07 00:16:58 +08:00
Compare commits
41 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
b972a0d081 | ||
|
20749355da | ||
|
dad122199a | ||
|
9fb8fbcc65 | ||
|
78e7ea72dc | ||
|
4640060891 | ||
|
9b0a705055 | ||
|
163fc9e3a3 | ||
|
b6735bffe4 | ||
|
1d8fd480ca | ||
|
da2e2372aa | ||
|
bf3bc3c7e9 | ||
|
38664487a0 | ||
|
de1111286c | ||
|
d89a12aa05 | ||
|
754acd7c26 | ||
|
c3e2f3b714 | ||
|
22ef3d3a46 | ||
|
7f3516f44f | ||
|
bfdb47a7ed | ||
|
f55f04ab4f | ||
|
01c9dbc1fd | ||
|
0aa807df19 | ||
|
48d44ece58 | ||
|
e58cb2b0db | ||
|
bffd9d9173 | ||
|
8688842984 | ||
|
cf29a8f2c8 | ||
|
1e00c89988 | ||
|
0eccb547b5 | ||
|
4789a7f6a9 | ||
|
0bf758afd4 | ||
|
6612550c06 | ||
|
d411159124 | ||
|
fffbee80e8 | ||
|
9d7ce207b6 | ||
|
2d1f0c9f57 | ||
|
c10447df79 | ||
|
5bf402710f | ||
|
2053db4cfc | ||
|
754303e7c7 |
@@ -58,7 +58,7 @@ CMD if [ -n "$PROXY_URL" ]; then \
|
|||||||
echo "[ProxyList]" >> $conf; \
|
echo "[ProxyList]" >> $conf; \
|
||||||
echo "$protocol $host $port" >> $conf; \
|
echo "$protocol $host $port" >> $conf; \
|
||||||
cat /etc/proxychains.conf; \
|
cat /etc/proxychains.conf; \
|
||||||
proxychains -f $conf node server.js; \
|
proxychains -f $conf node server.js --host 0.0.0.0; \
|
||||||
else \
|
else \
|
||||||
node server.js; \
|
node server.js; \
|
||||||
fi
|
fi
|
||||||
|
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2023 Zhang Yifei
|
Copyright (c) 2023-2024 Zhang Yifei
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@@ -245,13 +245,17 @@ To control custom models, use `+` to add a custom model, use `-` to hide a model
|
|||||||
|
|
||||||
User `-all` to disable all default models, `+all` to enable all default models.
|
User `-all` to disable all default models, `+all` to enable all default models.
|
||||||
|
|
||||||
### `WHITE_WEBDEV_ENDPOINTS` (可选)
|
### `WHITE_WEBDEV_ENDPOINTS` (optional)
|
||||||
|
|
||||||
You can use this option if you want to increase the number of webdav service addresses you are allowed to access, as required by the format:
|
You can use this option if you want to increase the number of webdav service addresses you are allowed to access, as required by the format:
|
||||||
- Each address must be a complete endpoint
|
- Each address must be a complete endpoint
|
||||||
> `https://xxxx/yyy`
|
> `https://xxxx/yyy`
|
||||||
- Multiple addresses are connected by ', '
|
- Multiple addresses are connected by ', '
|
||||||
|
|
||||||
|
### `DEFAULT_INPUT_TEMPLATE` (optional)
|
||||||
|
|
||||||
|
Customize the default template used to initialize the User Input Preprocessing configuration item in Settings.
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
NodeJS >= 18, Docker >= 20
|
NodeJS >= 18, Docker >= 20
|
||||||
|
@@ -156,6 +156,9 @@ anthropic claude Api Url.
|
|||||||
|
|
||||||
用来控制模型列表,使用 `+` 增加一个模型,使用 `-` 来隐藏一个模型,使用 `模型名=展示名` 来自定义模型的展示名,用英文逗号隔开。
|
用来控制模型列表,使用 `+` 增加一个模型,使用 `-` 来隐藏一个模型,使用 `模型名=展示名` 来自定义模型的展示名,用英文逗号隔开。
|
||||||
|
|
||||||
|
### `DEFAULT_INPUT_TEMPLATE` (可选)
|
||||||
|
自定义默认的 template,用于初始化『设置』中的『用户输入预处理』配置项
|
||||||
|
|
||||||
## 开发
|
## 开发
|
||||||
|
|
||||||
点击下方按钮,开始二次开发:
|
点击下方按钮,开始二次开发:
|
||||||
|
@@ -9,6 +9,14 @@ const mergedAllowedWebDavEndpoints = [
|
|||||||
...config.allowedWebDevEndpoints,
|
...config.allowedWebDevEndpoints,
|
||||||
].filter((domain) => Boolean(domain.trim()));
|
].filter((domain) => Boolean(domain.trim()));
|
||||||
|
|
||||||
|
const normalizeUrl = (url: string) => {
|
||||||
|
try {
|
||||||
|
return new URL(url);
|
||||||
|
} catch (err) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
async function handle(
|
async function handle(
|
||||||
req: NextRequest,
|
req: NextRequest,
|
||||||
{ params }: { params: { path: string[] } },
|
{ params }: { params: { path: string[] } },
|
||||||
@@ -24,9 +32,15 @@ async function handle(
|
|||||||
|
|
||||||
// Validate the endpoint to prevent potential SSRF attacks
|
// Validate the endpoint to prevent potential SSRF attacks
|
||||||
if (
|
if (
|
||||||
!mergedAllowedWebDavEndpoints.some(
|
!endpoint ||
|
||||||
(allowedEndpoint) => endpoint?.startsWith(allowedEndpoint),
|
!mergedAllowedWebDavEndpoints.some((allowedEndpoint) => {
|
||||||
)
|
const normalizedAllowedEndpoint = normalizeUrl(allowedEndpoint);
|
||||||
|
const normalizedEndpoint = normalizeUrl(endpoint as string);
|
||||||
|
|
||||||
|
return normalizedEndpoint &&
|
||||||
|
normalizedEndpoint.hostname === normalizedAllowedEndpoint?.hostname &&
|
||||||
|
normalizedEndpoint.pathname.startsWith(normalizedAllowedEndpoint.pathname);
|
||||||
|
})
|
||||||
) {
|
) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{
|
{
|
||||||
|
@@ -59,9 +59,10 @@ import {
|
|||||||
getMessageTextContent,
|
getMessageTextContent,
|
||||||
getMessageImages,
|
getMessageImages,
|
||||||
isVisionModel,
|
isVisionModel,
|
||||||
compressImage,
|
|
||||||
} from "../utils";
|
} from "../utils";
|
||||||
|
|
||||||
|
import { compressImage } from "@/app/utils/chat";
|
||||||
|
|
||||||
import dynamic from "next/dynamic";
|
import dynamic from "next/dynamic";
|
||||||
|
|
||||||
import { ChatControllerPool } from "../client/controller";
|
import { ChatControllerPool } from "../client/controller";
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import tauriConfig from "../../src-tauri/tauri.conf.json";
|
import tauriConfig from "../../src-tauri/tauri.conf.json";
|
||||||
|
import { DEFAULT_INPUT_TEMPLATE } from "../constant";
|
||||||
|
|
||||||
export const getBuildConfig = () => {
|
export const getBuildConfig = () => {
|
||||||
if (typeof process === "undefined") {
|
if (typeof process === "undefined") {
|
||||||
@@ -38,6 +39,7 @@ export const getBuildConfig = () => {
|
|||||||
...commitInfo,
|
...commitInfo,
|
||||||
buildMode,
|
buildMode,
|
||||||
isApp,
|
isApp,
|
||||||
|
template: process.env.DEFAULT_INPUT_TEMPLATE ?? DEFAULT_INPUT_TEMPLATE,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -34,6 +34,9 @@ declare global {
|
|||||||
|
|
||||||
// google tag manager
|
// google tag manager
|
||||||
GTM_ID?: string;
|
GTM_ID?: string;
|
||||||
|
|
||||||
|
// custom template for preprocessing user input
|
||||||
|
DEFAULT_INPUT_TEMPLATE?: string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -149,12 +149,13 @@ const openaiModels = [
|
|||||||
"gpt-4o",
|
"gpt-4o",
|
||||||
"gpt-4o-2024-05-13",
|
"gpt-4o-2024-05-13",
|
||||||
"gpt-4-vision-preview",
|
"gpt-4-vision-preview",
|
||||||
"gpt-4-turbo-2024-04-09"
|
"gpt-4-turbo-2024-04-09",
|
||||||
];
|
];
|
||||||
|
|
||||||
const googleModels = [
|
const googleModels = [
|
||||||
"gemini-1.0-pro",
|
"gemini-1.0-pro",
|
||||||
"gemini-1.5-pro-latest",
|
"gemini-1.5-pro-latest",
|
||||||
|
"gemini-1.5-flash-latest",
|
||||||
"gemini-pro-vision",
|
"gemini-pro-vision",
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -165,6 +166,7 @@ const anthropicModels = [
|
|||||||
"claude-3-sonnet-20240229",
|
"claude-3-sonnet-20240229",
|
||||||
"claude-3-opus-20240229",
|
"claude-3-opus-20240229",
|
||||||
"claude-3-haiku-20240307",
|
"claude-3-haiku-20240307",
|
||||||
|
"claude-3-5-sonnet-20240620",
|
||||||
];
|
];
|
||||||
|
|
||||||
export const DEFAULT_MODELS = [
|
export const DEFAULT_MODELS = [
|
||||||
@@ -206,6 +208,7 @@ export const internalAllowedWebDavEndpoints = [
|
|||||||
"https://dav.dropdav.com/",
|
"https://dav.dropdav.com/",
|
||||||
"https://dav.box.com/dav",
|
"https://dav.box.com/dav",
|
||||||
"https://nanao.teracloud.jp/dav/",
|
"https://nanao.teracloud.jp/dav/",
|
||||||
|
"https://bora.teracloud.jp/dav/",
|
||||||
"https://webdav.4shared.com/",
|
"https://webdav.4shared.com/",
|
||||||
"https://dav.idrivesync.com",
|
"https://dav.idrivesync.com",
|
||||||
"https://webdav.yandex.com",
|
"https://webdav.yandex.com",
|
||||||
|
@@ -428,14 +428,13 @@ export const useChatStore = createPersistStore(
|
|||||||
getMemoryPrompt() {
|
getMemoryPrompt() {
|
||||||
const session = get().currentSession();
|
const session = get().currentSession();
|
||||||
|
|
||||||
|
if (session.memoryPrompt.length) {
|
||||||
return {
|
return {
|
||||||
role: "system",
|
role: "system",
|
||||||
content:
|
content: Locale.Store.Prompt.History(session.memoryPrompt),
|
||||||
session.memoryPrompt.length > 0
|
|
||||||
? Locale.Store.Prompt.History(session.memoryPrompt)
|
|
||||||
: "",
|
|
||||||
date: "",
|
date: "",
|
||||||
} as ChatMessage;
|
} as ChatMessage;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getMessagesWithMemory() {
|
getMessagesWithMemory() {
|
||||||
@@ -471,16 +470,15 @@ export const useChatStore = createPersistStore(
|
|||||||
systemPrompts.at(0)?.content ?? "empty",
|
systemPrompts.at(0)?.content ?? "empty",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
const memoryPrompt = get().getMemoryPrompt();
|
||||||
// long term memory
|
// long term memory
|
||||||
const shouldSendLongTermMemory =
|
const shouldSendLongTermMemory =
|
||||||
modelConfig.sendMemory &&
|
modelConfig.sendMemory &&
|
||||||
session.memoryPrompt &&
|
session.memoryPrompt &&
|
||||||
session.memoryPrompt.length > 0 &&
|
session.memoryPrompt.length > 0 &&
|
||||||
session.lastSummarizeIndex > clearContextIndex;
|
session.lastSummarizeIndex > clearContextIndex;
|
||||||
const longTermMemoryPrompts = shouldSendLongTermMemory
|
const longTermMemoryPrompts =
|
||||||
? [get().getMemoryPrompt()]
|
shouldSendLongTermMemory && memoryPrompt ? [memoryPrompt] : [];
|
||||||
: [];
|
|
||||||
const longTermMemoryStartIndex = session.lastSummarizeIndex;
|
const longTermMemoryStartIndex = session.lastSummarizeIndex;
|
||||||
|
|
||||||
// short term memory
|
// short term memory
|
||||||
@@ -605,9 +603,11 @@ export const useChatStore = createPersistStore(
|
|||||||
Math.max(0, n - modelConfig.historyMessageCount),
|
Math.max(0, n - modelConfig.historyMessageCount),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
const memoryPrompt = get().getMemoryPrompt();
|
||||||
|
if (memoryPrompt) {
|
||||||
// add memory prompt
|
// add memory prompt
|
||||||
toBeSummarizedMsgs.unshift(get().getMemoryPrompt());
|
toBeSummarizedMsgs.unshift(memoryPrompt);
|
||||||
|
}
|
||||||
|
|
||||||
const lastSummarizeIndex = session.messages.length;
|
const lastSummarizeIndex = session.messages.length;
|
||||||
|
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
import { LLMModel } from "../client/api";
|
import { LLMModel } from "../client/api";
|
||||||
import { isMacOS } from "../utils";
|
|
||||||
import { getClientConfig } from "../config/client";
|
import { getClientConfig } from "../config/client";
|
||||||
import {
|
import {
|
||||||
DEFAULT_INPUT_TEMPLATE,
|
DEFAULT_INPUT_TEMPLATE,
|
||||||
@@ -25,6 +24,8 @@ export enum Theme {
|
|||||||
Light = "light",
|
Light = "light",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const config = getClientConfig();
|
||||||
|
|
||||||
export const DEFAULT_CONFIG = {
|
export const DEFAULT_CONFIG = {
|
||||||
lastUpdate: Date.now(), // timestamp, to merge state
|
lastUpdate: Date.now(), // timestamp, to merge state
|
||||||
|
|
||||||
@@ -32,7 +33,7 @@ export const DEFAULT_CONFIG = {
|
|||||||
avatar: "1f603",
|
avatar: "1f603",
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
theme: Theme.Auto as Theme,
|
theme: Theme.Auto as Theme,
|
||||||
tightBorder: !!getClientConfig()?.isApp,
|
tightBorder: !!config?.isApp,
|
||||||
sendPreviewBubble: true,
|
sendPreviewBubble: true,
|
||||||
enableAutoGenerateTitle: true,
|
enableAutoGenerateTitle: true,
|
||||||
sidebarWidth: DEFAULT_SIDEBAR_WIDTH,
|
sidebarWidth: DEFAULT_SIDEBAR_WIDTH,
|
||||||
@@ -56,7 +57,7 @@ export const DEFAULT_CONFIG = {
|
|||||||
historyMessageCount: 4,
|
historyMessageCount: 4,
|
||||||
compressMessageLengthThreshold: 1000,
|
compressMessageLengthThreshold: 1000,
|
||||||
enableInjectSystemPrompts: true,
|
enableInjectSystemPrompts: true,
|
||||||
template: DEFAULT_INPUT_TEMPLATE,
|
template: config?.template ?? DEFAULT_INPUT_TEMPLATE,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -132,7 +133,7 @@ export const useAppConfig = createPersistStore(
|
|||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
name: StoreKey.Config,
|
name: StoreKey.Config,
|
||||||
version: 3.8,
|
version: 3.9,
|
||||||
migrate(persistedState, version) {
|
migrate(persistedState, version) {
|
||||||
const state = persistedState as ChatConfig;
|
const state = persistedState as ChatConfig;
|
||||||
|
|
||||||
@@ -163,6 +164,13 @@ export const useAppConfig = createPersistStore(
|
|||||||
state.lastUpdate = Date.now();
|
state.lastUpdate = Date.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (version < 3.9) {
|
||||||
|
state.modelConfig.template =
|
||||||
|
state.modelConfig.template !== DEFAULT_INPUT_TEMPLATE
|
||||||
|
? state.modelConfig.template
|
||||||
|
: config?.template ?? DEFAULT_INPUT_TEMPLATE;
|
||||||
|
}
|
||||||
|
|
||||||
return state as any;
|
return state as any;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
52
app/utils.ts
52
app/utils.ts
@@ -83,48 +83,6 @@ export async function downloadAs(text: string, filename: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function compressImage(file: File, maxSize: number): Promise<string> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const reader = new FileReader();
|
|
||||||
reader.onload = (readerEvent: any) => {
|
|
||||||
const image = new Image();
|
|
||||||
image.onload = () => {
|
|
||||||
let canvas = document.createElement("canvas");
|
|
||||||
let ctx = canvas.getContext("2d");
|
|
||||||
let width = image.width;
|
|
||||||
let height = image.height;
|
|
||||||
let quality = 0.9;
|
|
||||||
let dataUrl;
|
|
||||||
|
|
||||||
do {
|
|
||||||
canvas.width = width;
|
|
||||||
canvas.height = height;
|
|
||||||
ctx?.clearRect(0, 0, canvas.width, canvas.height);
|
|
||||||
ctx?.drawImage(image, 0, 0, width, height);
|
|
||||||
dataUrl = canvas.toDataURL("image/jpeg", quality);
|
|
||||||
|
|
||||||
if (dataUrl.length < maxSize) break;
|
|
||||||
|
|
||||||
if (quality > 0.5) {
|
|
||||||
// Prioritize quality reduction
|
|
||||||
quality -= 0.1;
|
|
||||||
} else {
|
|
||||||
// Then reduce the size
|
|
||||||
width *= 0.9;
|
|
||||||
height *= 0.9;
|
|
||||||
}
|
|
||||||
} while (dataUrl.length > maxSize);
|
|
||||||
|
|
||||||
resolve(dataUrl);
|
|
||||||
};
|
|
||||||
image.onerror = reject;
|
|
||||||
image.src = readerEvent.target.result;
|
|
||||||
};
|
|
||||||
reader.onerror = reject;
|
|
||||||
reader.readAsDataURL(file);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function readFromFile() {
|
export function readFromFile() {
|
||||||
return new Promise<string>((res, rej) => {
|
return new Promise<string>((res, rej) => {
|
||||||
const fileInput = document.createElement("input");
|
const fileInput = document.createElement("input");
|
||||||
@@ -290,17 +248,19 @@ export function getMessageImages(message: RequestMessage): string[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function isVisionModel(model: string) {
|
export function isVisionModel(model: string) {
|
||||||
|
// Note: This is a better way using the TypeScript feature instead of `&&` or `||` (ts v5.5.0-dev.20240314 I've been using)
|
||||||
|
|
||||||
const visionKeywords = [
|
const visionKeywords = [
|
||||||
"vision",
|
"vision",
|
||||||
"claude-3",
|
"claude-3",
|
||||||
"gemini-1.5-pro",
|
"gemini-1.5-pro",
|
||||||
"gpt-4-turbo",
|
"gemini-1.5-flash",
|
||||||
"gpt-4o",
|
"gpt-4o",
|
||||||
];
|
];
|
||||||
const isGpt4TurboPreview = model === "gpt-4-turbo-preview";
|
const isGpt4Turbo =
|
||||||
|
model.includes("gpt-4-turbo") && !model.includes("preview");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
visionKeywords.some((keyword) => model.includes(keyword)) &&
|
visionKeywords.some((keyword) => model.includes(keyword)) || isGpt4Turbo
|
||||||
!isGpt4TurboPreview
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
54
app/utils/chat.ts
Normal file
54
app/utils/chat.ts
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import heic2any from "heic2any";
|
||||||
|
|
||||||
|
export function compressImage(file: File, maxSize: number): Promise<string> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = (readerEvent: any) => {
|
||||||
|
const image = new Image();
|
||||||
|
image.onload = () => {
|
||||||
|
let canvas = document.createElement("canvas");
|
||||||
|
let ctx = canvas.getContext("2d");
|
||||||
|
let width = image.width;
|
||||||
|
let height = image.height;
|
||||||
|
let quality = 0.9;
|
||||||
|
let dataUrl;
|
||||||
|
|
||||||
|
do {
|
||||||
|
canvas.width = width;
|
||||||
|
canvas.height = height;
|
||||||
|
ctx?.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
ctx?.drawImage(image, 0, 0, width, height);
|
||||||
|
dataUrl = canvas.toDataURL("image/jpeg", quality);
|
||||||
|
|
||||||
|
if (dataUrl.length < maxSize) break;
|
||||||
|
|
||||||
|
if (quality > 0.5) {
|
||||||
|
// Prioritize quality reduction
|
||||||
|
quality -= 0.1;
|
||||||
|
} else {
|
||||||
|
// Then reduce the size
|
||||||
|
width *= 0.9;
|
||||||
|
height *= 0.9;
|
||||||
|
}
|
||||||
|
} while (dataUrl.length > maxSize);
|
||||||
|
|
||||||
|
resolve(dataUrl);
|
||||||
|
};
|
||||||
|
image.onerror = reject;
|
||||||
|
image.src = readerEvent.target.result;
|
||||||
|
};
|
||||||
|
reader.onerror = reject;
|
||||||
|
|
||||||
|
if (file.type.includes("heic")) {
|
||||||
|
heic2any({ blob: file, toType: "image/jpeg" })
|
||||||
|
.then((blob) => {
|
||||||
|
reader.readAsDataURL(blob as Blob);
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
reject(e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
});
|
||||||
|
}
|
@@ -93,14 +93,17 @@ export function createUpstashClient(store: SyncStore) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let url;
|
let url;
|
||||||
if (proxyUrl.length > 0 || proxyUrl === "/") {
|
const pathPrefix = "/api/upstash/";
|
||||||
let u = new URL(proxyUrl + "/api/upstash/" + path);
|
|
||||||
|
try {
|
||||||
|
let u = new URL(proxyUrl + pathPrefix + path);
|
||||||
// add query params
|
// add query params
|
||||||
u.searchParams.append("endpoint", config.endpoint);
|
u.searchParams.append("endpoint", config.endpoint);
|
||||||
url = u.toString();
|
url = u.toString();
|
||||||
} else {
|
} catch (e) {
|
||||||
url = "/api/upstash/" + path + "?endpoint=" + config.endpoint;
|
url = pathPrefix + path + "?endpoint=" + config.endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
7. 在 "Build Settings" 中,选择 "Framework presets" 选项并选择 "Next.js"。
|
7. 在 "Build Settings" 中,选择 "Framework presets" 选项并选择 "Next.js"。
|
||||||
8. 由于 node:buffer 的 bug,暂时不要使用默认的 "Build command"。请使用以下命令:
|
8. 由于 node:buffer 的 bug,暂时不要使用默认的 "Build command"。请使用以下命令:
|
||||||
```
|
```
|
||||||
npx @cloudflare/next-on-pages@1.5.0
|
npx @cloudflare/next-on-pages --experimental-minify
|
||||||
```
|
```
|
||||||
9. 对于 "Build output directory",使用默认值并且不要修改。
|
9. 对于 "Build output directory",使用默认值并且不要修改。
|
||||||
10. 不要修改 "Root Directory"。
|
10. 不要修改 "Root Directory"。
|
||||||
|
@@ -12,7 +12,9 @@ Bifurca el proyecto en Github, luego inicia sesión en dash.cloudflare.com y ve
|
|||||||
6. Para "Nombre del proyecto" y "Rama de producción", puede utilizar los valores predeterminados o cambiarlos según sea necesario.
|
6. Para "Nombre del proyecto" y "Rama de producción", puede utilizar los valores predeterminados o cambiarlos según sea necesario.
|
||||||
7. En Configuración de compilación, seleccione la opción Ajustes preestablecidos de Framework y seleccione Siguiente.js.
|
7. En Configuración de compilación, seleccione la opción Ajustes preestablecidos de Framework y seleccione Siguiente.js.
|
||||||
8. Debido a los errores de node:buffer, no use el "comando Construir" predeterminado por ahora. Utilice el siguiente comando:
|
8. Debido a los errores de node:buffer, no use el "comando Construir" predeterminado por ahora. Utilice el siguiente comando:
|
||||||
npx https://prerelease-registry.devprod.cloudflare.dev/next-on-pages/runs/4930842298/npm-package-next-on-pages-230 --experimental-minify
|
```
|
||||||
|
npx @cloudflare/next-on-pages --experimental-minify
|
||||||
|
```
|
||||||
9. Para "Generar directorio de salida", utilice los valores predeterminados y no los modifique.
|
9. Para "Generar directorio de salida", utilice los valores predeterminados y no los modifique.
|
||||||
10. No modifique el "Directorio raíz".
|
10. No modifique el "Directorio raíz".
|
||||||
11. Para "Variables de entorno", haga clic en ">" y luego haga clic en "Agregar variable". Rellene la siguiente información:
|
11. Para "Variables de entorno", haga clic en ">" y luego haga clic en "Agregar variable". Rellene la siguiente información:
|
||||||
|
@@ -12,7 +12,7 @@ GitHub でこのプロジェクトをフォークし、dash.cloudflare.com に
|
|||||||
7. "Build Settings" で、"Framework presets" オプションを選択し、"Next.js" を選択します。
|
7. "Build Settings" で、"Framework presets" オプションを選択し、"Next.js" を選択します。
|
||||||
8. node:buffer のバグのため、デフォルトの "Build command" は使用しないでください。代わりに、以下のコマンドを使用してください:
|
8. node:buffer のバグのため、デフォルトの "Build command" は使用しないでください。代わりに、以下のコマンドを使用してください:
|
||||||
```
|
```
|
||||||
npx https://prerelease-registry.devprod.cloudflare.dev/next-on-pages/runs/4930842298/npm-package-next-on-pages-230 --experimental-minify
|
npx @cloudflare/next-on-pages --experimental-minify
|
||||||
```
|
```
|
||||||
9. "Build output directory" はデフォルト値を使用し、変更しない。
|
9. "Build output directory" はデフォルト値を使用し、変更しない。
|
||||||
10. "Root Directory" を変更しない。
|
10. "Root Directory" を変更しない。
|
||||||
|
@@ -11,8 +11,8 @@
|
|||||||
6. "프로젝트 이름" 및 "프로덕션 브랜치"의 기본값을 사용하거나 필요에 따라 변경합니다.
|
6. "프로젝트 이름" 및 "프로덕션 브랜치"의 기본값을 사용하거나 필요에 따라 변경합니다.
|
||||||
7. "빌드 설정"에서 "프레임워크 프리셋" 옵션을 선택하고 "Next.js"를 선택합니다.
|
7. "빌드 설정"에서 "프레임워크 프리셋" 옵션을 선택하고 "Next.js"를 선택합니다.
|
||||||
8. node:buffer 버그로 인해 지금은 기본 "빌드 명령어"를 사용하지 마세요. 다음 명령을 사용하세요:
|
8. node:buffer 버그로 인해 지금은 기본 "빌드 명령어"를 사용하지 마세요. 다음 명령을 사용하세요:
|
||||||
``
|
```
|
||||||
npx https://prerelease-registry.devprod.cloudflare.dev/next-on-pages/runs/4930842298/npm-package-next-on-pages-230 --experimental- minify
|
npx @cloudflare/next-on-pages --experimental-minify
|
||||||
```
|
```
|
||||||
9. "빌드 출력 디렉토리"의 경우 기본값을 사용하고 수정하지 마십시오.
|
9. "빌드 출력 디렉토리"의 경우 기본값을 사용하고 수정하지 마십시오.
|
||||||
10. "루트 디렉토리"는 수정하지 마십시오.
|
10. "루트 디렉토리"는 수정하지 마십시오.
|
||||||
|
@@ -24,6 +24,7 @@
|
|||||||
"@vercel/speed-insights": "^1.0.2",
|
"@vercel/speed-insights": "^1.0.2",
|
||||||
"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",
|
||||||
"html-to-image": "^1.11.11",
|
"html-to-image": "^1.11.11",
|
||||||
"mermaid": "^10.6.1",
|
"mermaid": "^10.6.1",
|
||||||
"nanoid": "^5.0.3",
|
"nanoid": "^5.0.3",
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
},
|
},
|
||||||
"package": {
|
"package": {
|
||||||
"productName": "NextChat",
|
"productName": "NextChat",
|
||||||
"version": "2.12.3"
|
"version": "2.12.4"
|
||||||
},
|
},
|
||||||
"tauri": {
|
"tauri": {
|
||||||
"allowlist": {
|
"allowlist": {
|
||||||
|
@@ -3669,6 +3669,11 @@ heap@^0.2.6:
|
|||||||
resolved "https://registry.npmmirror.com/heap/-/heap-0.2.7.tgz#1e6adf711d3f27ce35a81fe3b7bd576c2260a8fc"
|
resolved "https://registry.npmmirror.com/heap/-/heap-0.2.7.tgz#1e6adf711d3f27ce35a81fe3b7bd576c2260a8fc"
|
||||||
integrity sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==
|
integrity sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==
|
||||||
|
|
||||||
|
heic2any@^0.0.4:
|
||||||
|
version "0.0.4"
|
||||||
|
resolved "https://registry.npmmirror.com/heic2any/-/heic2any-0.0.4.tgz#eddb8e6fec53c8583a6e18b65069bb5e8d19028a"
|
||||||
|
integrity sha512-3lLnZiDELfabVH87htnRolZ2iehX9zwpRyGNz22GKXIu0fznlblf0/ftppXKNqS26dqFSeqfIBhAmAj/uSp0cA==
|
||||||
|
|
||||||
highlight.js@~11.7.0:
|
highlight.js@~11.7.0:
|
||||||
version "11.7.0"
|
version "11.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.7.0.tgz#3ff0165bc843f8c9bce1fd89e2fda9143d24b11e"
|
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.7.0.tgz#3ff0165bc843f8c9bce1fd89e2fda9143d24b11e"
|
||||||
|
Reference in New Issue
Block a user