├── .gitignore
├── LICENSE.md
├── client
├── .env.example
├── .gitignore
├── package-lock.json
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── components
│ │ ├── App
│ │ │ ├── App.css
│ │ │ ├── App.test.tsx
│ │ │ └── App.tsx
│ │ ├── PromptInput
│ │ │ ├── PromptInput.css
│ │ │ └── PromptInput.tsx
│ │ └── PromptResponseList
│ │ │ ├── PromptResponseList.css
│ │ │ ├── PromptResponseList.tsx
│ │ │ └── response-interface.ts
│ ├── img
│ │ ├── chatgpt.png
│ │ ├── demo2.gif
│ │ └── me.png
│ ├── index.tsx
│ ├── react-app-env.d.ts
│ ├── reportWebVitals.ts
│ └── setupTests.ts
└── tsconfig.json
├── readme.md
└── server
├── .env.sample
├── .gitignore
├── index.js
├── package-lock.json
└── package.json
/.gitignore:
--------------------------------------------------------------------------------
1 | /.idea
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (c) 2023 Ioan Moldovan
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/client/.env.example:
--------------------------------------------------------------------------------
1 | REACT_APP_BACKEND_URL=http://localhost:3001/
--------------------------------------------------------------------------------
/client/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env
17 | .env.local
18 | .env.development.local
19 | .env.test.local
20 | .env.production.local
21 |
22 | npm-debug.log*
23 | yarn-debug.log*
24 | yarn-error.log*
25 |
--------------------------------------------------------------------------------
/client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "chatgpt-client",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.16.5",
7 | "@testing-library/react": "^13.4.0",
8 | "@testing-library/user-event": "^13.5.0",
9 | "@types/jest": "^27.5.2",
10 | "@types/node": "^16.18.12",
11 | "@types/react": "^18.0.27",
12 | "@types/react-dom": "^18.0.10",
13 | "axios": "^1.3.2",
14 | "highlight.js": "^11.7.0",
15 | "react": "^18.2.0",
16 | "react-contenteditable": "^3.3.6",
17 | "react-dom": "^18.2.0",
18 | "react-markdown": "^8.0.5",
19 | "react-scripts": "5.0.1",
20 | "typescript": "^4.9.5",
21 | "web-vitals": "^2.1.4"
22 | },
23 | "scripts": {
24 | "start": "react-scripts start",
25 | "build": "react-scripts build",
26 | "test": "react-scripts test",
27 | "eject": "react-scripts eject"
28 | },
29 | "eslintConfig": {
30 | "extends": [
31 | "react-app",
32 | "react-app/jest"
33 | ]
34 | },
35 | "browserslist": {
36 | "production": [
37 | ">0.2%",
38 | "not dead",
39 | "not op_mini all"
40 | ],
41 | "development": [
42 | "last 1 chrome version",
43 | "last 1 firefox version",
44 | "last 1 safari version"
45 | ]
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ioanmo226/chatgpt-react-application/422a93d52df5d8b194923d7e515f74ba3e7bd630/client/public/favicon.ico
--------------------------------------------------------------------------------
/client/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | ChatGPT Web Application
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/client/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ioanmo226/chatgpt-react-application/422a93d52df5d8b194923d7e515f74ba3e7bd630/client/public/logo192.png
--------------------------------------------------------------------------------
/client/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ioanmo226/chatgpt-react-application/422a93d52df5d8b194923d7e515f74ba3e7bd630/client/public/logo512.png
--------------------------------------------------------------------------------
/client/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/client/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/client/src/components/App/App.css:
--------------------------------------------------------------------------------
1 | html, body, #root, .App {
2 | height: 100%;
3 | }
4 | .App {
5 | display: flex;
6 | flex-direction: column;
7 | }
8 | /* Add background color to the body */
9 | body {
10 | background-color: rgba(68, 70, 84, 1.0);
11 | display: flex;
12 | flex-direction: column;
13 | justify-content: space-between;
14 | margin: 0;
15 | }
16 |
17 | /* Remove border color from the response list container */
18 | #response-list {
19 | border: none;
20 | overflow-y: auto;
21 | flex: 1;
22 | }
23 |
24 | .chatgpt-response {
25 | background-color: rgba(68, 70, 84, 1);
26 | }
27 |
28 | .my-question {
29 | background-color: rgba(52, 53, 65, 1);
30 | }
31 | /* Change background color of the input container */
32 | #input-container {
33 | display: flex;
34 | align-items: center;
35 | justify-content: space-between;
36 | padding: 10px;
37 | background-color: rgba(64, 65, 79, 1);
38 | border-color: rgba(32,33,35,.5);
39 | border-radius: 5px;
40 | margin: 10px 200px;
41 | }
42 |
43 |
44 | /* Remove background color and add an SVG background for the submit button */
45 | #submit-button {
46 | background: transparent url("data:image/svg+xml,") no-repeat center center;
47 | color: white;
48 | width: 40px;
49 | height: 40px;
50 | border: none;
51 | border-radius: 5px;
52 | cursor: pointer;
53 | }
54 |
55 | #regenerate-button-container {
56 | display: flex;
57 | flex-direction: row;
58 | justify-content: center;
59 | margin-bottom: 10px;
60 | }
61 |
62 | #regenerate-response-button {
63 | color: white;
64 | border: none;
65 | background: #10A37F;
66 | border-radius: 4px;
67 | padding: 10px 20px;
68 | cursor: pointer;
69 | }
70 |
71 | .loading {
72 | opacity: 0.5;
73 | cursor: not-allowed;
74 | pointer-events: none;
75 | }
76 |
77 | #model-select-container {
78 | margin: 10px 200px;
79 | color: white;
80 | }
81 |
82 | #model-select-container select {
83 | background: transparent;
84 | border: none;
85 | outline: none;
86 | color: white;
87 | }
88 |
89 | #model-select-container select option:not(:checked) {
90 | background: rgba(32,33,35,.8);
91 | }
92 |
93 | #model-select-container select option {
94 | background: rgba(32,33,35,.5);
95 | }
96 |
--------------------------------------------------------------------------------
/client/src/components/App/App.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render, screen } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | render();
7 | const linkElement = screen.getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/client/src/components/App/App.tsx:
--------------------------------------------------------------------------------
1 | import {useState} from 'react';
2 | import axios from "axios";
3 | import PromptInput from "../PromptInput/PromptInput";
4 | import './App.css';
5 | import {ResponseInterface} from "../PromptResponseList/response-interface";
6 | import PromptResponseList from "../PromptResponseList/PromptResponseList";
7 |
8 | type ModelValueType = 'gpt' | 'codex' | 'image';
9 | const App = () => {
10 |
11 | const [responseList, setResponseList] = useState([]);
12 | const [prompt, setPrompt] = useState('');
13 | const [promptToRetry, setPromptToRetry] = useState(null);
14 | const [uniqueIdToRetry, setUniqueIdToRetry] = useState(null);
15 | const [modelValue, setModelValue] = useState('gpt');
16 | const [isLoading, setIsLoading] = useState(false);
17 | let loadInterval: number | undefined;
18 |
19 | const generateUniqueId = () => {
20 | const timestamp = Date.now();
21 | const randomNumber = Math.random();
22 | const hexadecimalString = randomNumber.toString(16);
23 |
24 | return `id-${timestamp}-${hexadecimalString}`;
25 | }
26 |
27 | const htmlToText = (html: string) => {
28 | const temp = document.createElement('div');
29 | temp.innerHTML = html;
30 | return temp.textContent;
31 | }
32 |
33 | const delay = (ms: number) => {
34 | return new Promise( resolve => setTimeout(resolve, ms) );
35 | }
36 |
37 | const addLoader = (uid: string) => {
38 | const element = document.getElementById(uid) as HTMLElement;
39 | element.textContent = ''
40 |
41 | // @ts-ignore
42 | loadInterval = setInterval(() => {
43 | // Update the text content of the loading indicator
44 | element.textContent += '.';
45 |
46 | // If the loading indicator has reached three dots, reset it
47 | if (element.textContent === '....') {
48 | element.textContent = '';
49 | }
50 | }, 300);
51 | }
52 |
53 |
54 | const addResponse = (selfFlag: boolean, response?: string) => {
55 | const uid = generateUniqueId()
56 | setResponseList(prevResponses => [
57 | ...prevResponses,
58 | {
59 | id: uid,
60 | response,
61 | selfFlag
62 | },
63 | ]);
64 | return uid;
65 | }
66 |
67 | const updateResponse = (uid: string, updatedObject: Record) => {
68 | setResponseList(prevResponses => {
69 | const updatedList = [...prevResponses]
70 | const index = prevResponses.findIndex((response) => response.id === uid);
71 | if (index > -1) {
72 | updatedList[index] = {
73 | ...updatedList[index],
74 | ...updatedObject
75 | }
76 | }
77 | return updatedList;
78 | });
79 | }
80 |
81 | const regenerateResponse = async () => {
82 | await getGPTResult(promptToRetry, uniqueIdToRetry);
83 | }
84 |
85 | const getGPTResult = async (_promptToRetry?: string | null, _uniqueIdToRetry?: string | null) => {
86 | // Get the prompt input
87 | const _prompt = _promptToRetry ?? htmlToText(prompt);
88 |
89 | // If a response is already being generated or the prompt is empty, return
90 | if (isLoading || !_prompt) {
91 | return;
92 | }
93 |
94 | setIsLoading(true);
95 |
96 | // Clear the prompt input
97 | setPrompt('');
98 |
99 | let uniqueId: string;
100 | if (_uniqueIdToRetry) {
101 | uniqueId = _uniqueIdToRetry;
102 | } else {
103 | // Add the self prompt to the response list
104 | addResponse(true, _prompt);
105 | uniqueId = addResponse(false);
106 | await delay(50);
107 | addLoader(uniqueId);
108 | }
109 |
110 | try {
111 | // Send a POST request to the API with the prompt in the request body
112 | const response = await axios.post('get-prompt-result', {
113 | prompt: _prompt,
114 | model: modelValue
115 | });
116 | if (modelValue === 'image') {
117 | // Show image for `Create image` model
118 | updateResponse(uniqueId, {
119 | image: response.data,
120 | });
121 | } else {
122 | updateResponse(uniqueId, {
123 | response: response.data.trim(),
124 | });
125 | }
126 |
127 | setPromptToRetry(null);
128 | setUniqueIdToRetry(null);
129 | } catch (err) {
130 | setPromptToRetry(_prompt);
131 | setUniqueIdToRetry(uniqueId);
132 | updateResponse(uniqueId, {
133 | // @ts-ignore
134 | response: `Error: ${err.message}`,
135 | error: true
136 | });
137 | } finally {
138 | // Clear the loader interval
139 | clearInterval(loadInterval);
140 | setIsLoading(false);
141 | }
142 | }
143 |
144 | return (
145 |
146 |
149 | { uniqueIdToRetry &&
150 | (
151 |
154 |
155 | )
156 | }
157 |
158 |
159 |
165 |
166 |
175 |
176 | );
177 | }
178 |
179 | export default App;
180 |
--------------------------------------------------------------------------------
/client/src/components/PromptInput/PromptInput.css:
--------------------------------------------------------------------------------
1 | /* Style for the prompt input */
2 | #prompt-input {
3 | flex-grow: 1;
4 | padding: 10px;
5 | border-radius: 5px;
6 | min-height: 20px;
7 | color: white;
8 | overflow: auto;
9 | }
10 |
11 | #prompt-input:focus {
12 | outline: none !important;
13 | }
--------------------------------------------------------------------------------
/client/src/components/PromptInput/PromptInput.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef, useCallback } from 'react';
2 | import ContentEditable from 'react-contenteditable';
3 | import './PromptInput.css';
4 |
5 | interface PromptInputProps {
6 | prompt: string;
7 | onSubmit: () => void;
8 | updatePrompt: (prompt: string) => void;
9 | }
10 |
11 | const PromptInput: React.FC = ({ prompt, onSubmit, updatePrompt }) => {
12 | const checkKeyPress = useCallback((e: KeyboardEvent) => {
13 | if (e.key === 'Enter') {
14 | e.preventDefault();
15 | if (e.ctrlKey || e.shiftKey) {
16 | document.execCommand('insertHTML', false, '
');
17 | } else {
18 | onSubmit();
19 | }
20 | }
21 | // eslint-disable-next-line react-hooks/exhaustive-deps
22 | }, [prompt]);
23 |
24 | const contentEditableRef = useRef(null);
25 |
26 | useEffect(() => {
27 | window.addEventListener("keydown", checkKeyPress);
28 | return () => {
29 | window.removeEventListener("keydown", checkKeyPress);
30 | };
31 | }, [checkKeyPress]);
32 |
33 | return (
34 | updatePrompt(event.target.value)}
41 | />
42 | );
43 | };
44 |
45 | export default PromptInput;
46 |
--------------------------------------------------------------------------------
/client/src/components/PromptResponseList/PromptResponseList.css:
--------------------------------------------------------------------------------
1 | /* Style for each response element in the list */
2 | .response-container {
3 | margin-bottom: 10px;
4 | color: white;
5 | padding: 15px 200px;
6 | font-size: 1rem;
7 | display: flex;
8 | }
9 |
10 | .response-container .avatar-image {
11 | width: 30px;
12 | height: 30px;
13 | margin-right: 15px;
14 | }
15 |
16 | .response-container .response-content {
17 | display: flex;
18 | flex-direction: column;
19 | }
20 |
21 | .response-container pre {
22 | max-width: 100%;
23 | margin: 0 !important;
24 | white-space: break-spaces;
25 | }
26 |
27 | .response-container .prompt-content {
28 | background: transparent !important;
29 | color: white;
30 | padding: 0 !important;
31 | margin-top: 5px;
32 | }
33 |
34 | .response-container .prompt-content p:first-child {
35 | margin-top: 0;
36 | }
37 |
38 | .ai-image {
39 | width: 500px;
40 | height: auto;
41 | }
42 |
43 | .error-response {
44 | color: rgb(220, 0, 0) !important;
45 | }
46 |
47 | /* Override hljs to match for chatgpt */
48 | .hljs {
49 | background: rgb(0,0,0) !important;
50 | color: white !important;
51 | display: block;
52 | padding: 10px;
53 | border-radius: 6px;
54 | }
55 |
56 | .hljs-section, .hljs-title {
57 | color: #f22c3d !important;
58 | }
59 |
60 | .hljs-deletion, .hljs-number, .hljs-quote, .hljs-selector-class, .hljs-selector-id, .hljs-string, .hljs-template-tag, .hljs-type {
61 | color: #df3079 !important;
62 | }
63 |
64 | .hljs-addition, .hljs-built_in, .hljs-bullet, .hljs-code {
65 | color: #e9950c !important;
66 | }
67 |
68 | .hljs-link, .hljs-operator, .hljs-regexp, .hljs-selector-attr, .hljs-selector-pseudo, .hljs-symbol, .hljs-template-variable, .hljs-variable {
69 | color: white !important;
70 | }
--------------------------------------------------------------------------------
/client/src/components/PromptResponseList/PromptResponseList.tsx:
--------------------------------------------------------------------------------
1 | import React, {FC, useEffect, useRef} from 'react';
2 | import ChatGptImg from '../../img/chatgpt.png';
3 | import MyImg from '../../img/me.png';
4 | import ReactMarkdown from 'react-markdown';
5 | import {ResponseInterface} from "./response-interface";
6 | import hljs from 'highlight.js';
7 | import './PromptResponseList.css';
8 |
9 | interface PromptResponseListProps {
10 | responseList: ResponseInterface[];
11 | }
12 |
13 | const PromptResponseList: FC = ({ responseList }) => {
14 | const responseListRef = useRef(null);
15 |
16 | useEffect(() => {
17 | hljs.highlightAll();
18 | })
19 |
20 | useEffect(() => {
21 | hljs.highlightAll();
22 | }, [responseList]);
23 |
24 | return (
25 |
26 | {responseList.map((responseData) => (
27 |
28 |

29 |
30 | { responseData.image &&
31 |

32 | }
33 | { responseData.response &&
34 |
40 | {children}
41 |
42 | )
43 | }
44 | }}
45 | />
46 | }
47 |
48 |
49 | ))}
50 |
51 | );
52 | };
53 |
54 | export default PromptResponseList;
55 |
--------------------------------------------------------------------------------
/client/src/components/PromptResponseList/response-interface.ts:
--------------------------------------------------------------------------------
1 | export interface ResponseInterface {
2 | id: string;
3 | response?: string;
4 | selfFlag: boolean;
5 | error?: boolean;
6 | image?: string;
7 | }
8 |
--------------------------------------------------------------------------------
/client/src/img/chatgpt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ioanmo226/chatgpt-react-application/422a93d52df5d8b194923d7e515f74ba3e7bd630/client/src/img/chatgpt.png
--------------------------------------------------------------------------------
/client/src/img/demo2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ioanmo226/chatgpt-react-application/422a93d52df5d8b194923d7e515f74ba3e7bd630/client/src/img/demo2.gif
--------------------------------------------------------------------------------
/client/src/img/me.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ioanmo226/chatgpt-react-application/422a93d52df5d8b194923d7e515f74ba3e7bd630/client/src/img/me.png
--------------------------------------------------------------------------------
/client/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import App from './components/App/App';
4 | import reportWebVitals from './reportWebVitals';
5 | import axios from "axios";
6 |
7 | axios.defaults.baseURL = process.env.REACT_APP_BACKEND_URL;
8 |
9 | const root = ReactDOM.createRoot(
10 | document.getElementById('root') as HTMLElement
11 | );
12 | root.render(
13 |
14 |
15 |
16 | );
17 |
18 | // If you want to start measuring performance in your app, pass a function
19 | // to log results (for example: reportWebVitals(console.log))
20 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
21 | reportWebVitals();
22 |
--------------------------------------------------------------------------------
/client/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/client/src/reportWebVitals.ts:
--------------------------------------------------------------------------------
1 | import { ReportHandler } from 'web-vitals';
2 |
3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => {
4 | if (onPerfEntry && onPerfEntry instanceof Function) {
5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
6 | getCLS(onPerfEntry);
7 | getFID(onPerfEntry);
8 | getFCP(onPerfEntry);
9 | getLCP(onPerfEntry);
10 | getTTFB(onPerfEntry);
11 | });
12 | }
13 | };
14 |
15 | export default reportWebVitals;
16 |
--------------------------------------------------------------------------------
/client/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/client/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "esModuleInterop": true,
12 | "allowSyntheticDefaultImports": true,
13 | "strict": true,
14 | "forceConsistentCasingInFileNames": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "module": "esnext",
17 | "moduleResolution": "node",
18 | "resolveJsonModule": true,
19 | "isolatedModules": true,
20 | "noEmit": true,
21 | "jsx": "react-jsx"
22 | },
23 | "include": [
24 | "src"
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # ChatGPT Web Application
2 |
3 | A web application that allows users to interact with OpenAI's GPT-3 language model through a simple and user-friendly interface.
4 | This app is for demo purpose to test OpenAI API and may contain issues/bugs.
5 |
6 | If you are looking for a simple HTML/vanilla JavaScript version, check [here](https://github.com/ioanmo226/chatgpt-web-application)
7 |
8 | 
9 |
10 |
11 |
12 |
13 | ## Features
14 | - User-friendly interface for making requests to the OpenAI API
15 | - Responses are displayed in a chat-like format
16 | - Select Models (Davinci, Codex, Create Image) based on your needs
17 | - Highlight code syntax
18 |
19 | ## Technologies Used
20 | - For client, I used React.js.
21 | - For server, I used express.
22 |
23 | ## Setup Introduction
24 | This guide will help you set up the repository on your local machine. Please follow these steps carefully to ensure a smooth setup process.
25 |
26 | ### Cloning the repository
27 | Use the following command to clone the repository:
28 | ```sh
29 | git clone https://github.com/ioanmo226/chatgpt-web-application
30 | ```
31 |
32 | ### Backend Setup
33 |
34 | - Navigate to server directory
35 | ```sh
36 | cd server # Navigate to the server directory:
37 | ```
38 | - Install dependencies
39 | ```sh
40 | npm install #install the backend dependencies
41 | ```
42 | - Set the OPENAI_API_KEY in the .env file:
43 | ```sh
44 | OPENAI_API_KEY=YOUR_OPENAI_API_KEY
45 | ```
46 |
47 | - Start the backend server by running the following command:
48 | ```sh
49 | node index.js
50 | ```
51 |
52 | ### Frontend Setup
53 |
54 | - Navigate to the client directory:
55 | ```sh
56 | cd client
57 | ```
58 |
59 | - Run the following command to install the frontend dependencies:
60 | ```sh
61 | npm install
62 | ```
63 |
64 | - Set the `REACT_APP_BACKEND_URL` in the `.env` file to the URL of your backend server. For local development, use the following URL:
65 | ```sh
66 | REACT_APP_BACKEND_URL=http://localhost:3001/
67 | ```
68 |
69 | - Start the frontend app by running the following command:
70 | ```sh
71 | npm start
72 | ```
73 |
74 | ### Hosting Backend and Frontend in Same Port/URL
75 |
76 | If you wish to host both the backend and frontend on the same port/URL, follow these steps:
77 |
78 | - Build the frontend by running the following command in the `client` directory:
79 | ```sh
80 | npm run build
81 | ```
82 | - Copy the `build` directory to the `server` directory and rename it to `frontend`.
83 |
84 | - Start the backend server using the instructions in the "Backend Setup" section.
85 |
86 | - Once the setup process is complete, the frontend will be accessible at the URL of your backend server.
87 |
88 | ## Usage
89 | - Type in the input field and press enter or click on the send button to make a request to the OpenAI API
90 | - Use control+enter to add line breaks in the input field
91 | - Responses are displayed in the chat-like format on top of the page
92 | - Generate code, including translating natural language to code
93 | - You can also create AI images using DALL·E models
94 |
95 | ## Contributing
96 |
97 | This project welcomes contributions and suggestions for improvements. If you have any ideas, please feel free to open an issue or create a pull request.
98 |
99 | Thank you for your consideration.
100 |
101 |
102 |
--------------------------------------------------------------------------------
/server/.env.sample:
--------------------------------------------------------------------------------
1 | OPENAI_API_KEY=
--------------------------------------------------------------------------------
/server/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .env
--------------------------------------------------------------------------------
/server/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const {Configuration, OpenAIApi} = require("openai");
3 | const app = express();
4 | const cors = require('cors');
5 | require("dotenv").config();
6 | const configuration = new Configuration({
7 | apiKey: process.env.OPENAI_API_KEY,
8 | });
9 | const openai = new OpenAIApi(configuration);
10 |
11 | app.use(cors());
12 | app.use(express.json());
13 | app.use('/', express.static(__dirname + '/frontend')); // Serves resources from client folder
14 |
15 | app.post('/get-prompt-result', async (req, res) => {
16 | // Get the prompt from the request body
17 | const {prompt, model = 'gpt'} = req.body;
18 |
19 | // Check if prompt is present in the request
20 | if (!prompt) {
21 | // Send a 400 status code and a message indicating that the prompt is missing
22 | return res.status(400).send({error: 'Prompt is missing in the request'});
23 | }
24 |
25 | try {
26 | // Use the OpenAI SDK to create a completion
27 | // with the given prompt, model and maximum tokens
28 | if (model === 'image') {
29 | const result = await openai.createImage({
30 | prompt,
31 | response_format: 'url',
32 | size: '512x512'
33 | });
34 | return res.send(result.data.data[0].url);
35 | }
36 | const completion = await openai.createCompletion({
37 | model: model === 'gpt' ? "text-davinci-003" : 'code-davinci-002', // model name
38 | prompt: `Please reply below question in markdown format.\n ${prompt}`, // input prompt
39 | max_tokens: model === 'gpt' ? 4000 : 8000 // Use max 8000 tokens for codex model
40 | });
41 | // Send the generated text as the response
42 | return res.send(completion.data.choices[0].text);
43 | } catch (error) {
44 | const errorMsg = error.response ? error.response.data.error : `${error}`;
45 | console.error(errorMsg);
46 | // Send a 500 status code and the error message as the response
47 | return res.status(500).send(errorMsg);
48 | }
49 | });
50 |
51 | const port = process.env.PORT || 3001;
52 | app.listen(port, () => console.log(`Listening on port ${port}`));
53 |
--------------------------------------------------------------------------------
/server/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "chatgpt-server",
3 | "version": "1.0.0",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "chatgpt-server",
9 | "version": "1.0.0",
10 | "license": "ISC",
11 | "dependencies": {
12 | "cors": "^2.8.5",
13 | "dotenv": "^16.0.3",
14 | "express": "^4.18.2",
15 | "openai": "^3.1.0"
16 | }
17 | },
18 | "node_modules/accepts": {
19 | "version": "1.3.8",
20 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
21 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
22 | "dependencies": {
23 | "mime-types": "~2.1.34",
24 | "negotiator": "0.6.3"
25 | },
26 | "engines": {
27 | "node": ">= 0.6"
28 | }
29 | },
30 | "node_modules/array-flatten": {
31 | "version": "1.1.1",
32 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
33 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
34 | },
35 | "node_modules/asynckit": {
36 | "version": "0.4.0",
37 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
38 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
39 | },
40 | "node_modules/axios": {
41 | "version": "0.26.1",
42 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz",
43 | "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==",
44 | "dependencies": {
45 | "follow-redirects": "^1.14.8"
46 | }
47 | },
48 | "node_modules/body-parser": {
49 | "version": "1.20.1",
50 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
51 | "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
52 | "dependencies": {
53 | "bytes": "3.1.2",
54 | "content-type": "~1.0.4",
55 | "debug": "2.6.9",
56 | "depd": "2.0.0",
57 | "destroy": "1.2.0",
58 | "http-errors": "2.0.0",
59 | "iconv-lite": "0.4.24",
60 | "on-finished": "2.4.1",
61 | "qs": "6.11.0",
62 | "raw-body": "2.5.1",
63 | "type-is": "~1.6.18",
64 | "unpipe": "1.0.0"
65 | },
66 | "engines": {
67 | "node": ">= 0.8",
68 | "npm": "1.2.8000 || >= 1.4.16"
69 | }
70 | },
71 | "node_modules/bytes": {
72 | "version": "3.1.2",
73 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
74 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
75 | "engines": {
76 | "node": ">= 0.8"
77 | }
78 | },
79 | "node_modules/call-bind": {
80 | "version": "1.0.2",
81 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
82 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
83 | "dependencies": {
84 | "function-bind": "^1.1.1",
85 | "get-intrinsic": "^1.0.2"
86 | },
87 | "funding": {
88 | "url": "https://github.com/sponsors/ljharb"
89 | }
90 | },
91 | "node_modules/combined-stream": {
92 | "version": "1.0.8",
93 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
94 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
95 | "dependencies": {
96 | "delayed-stream": "~1.0.0"
97 | },
98 | "engines": {
99 | "node": ">= 0.8"
100 | }
101 | },
102 | "node_modules/content-disposition": {
103 | "version": "0.5.4",
104 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
105 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
106 | "dependencies": {
107 | "safe-buffer": "5.2.1"
108 | },
109 | "engines": {
110 | "node": ">= 0.6"
111 | }
112 | },
113 | "node_modules/content-type": {
114 | "version": "1.0.4",
115 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
116 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
117 | "engines": {
118 | "node": ">= 0.6"
119 | }
120 | },
121 | "node_modules/cookie": {
122 | "version": "0.5.0",
123 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
124 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
125 | "engines": {
126 | "node": ">= 0.6"
127 | }
128 | },
129 | "node_modules/cookie-signature": {
130 | "version": "1.0.6",
131 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
132 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
133 | },
134 | "node_modules/cors": {
135 | "version": "2.8.5",
136 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
137 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
138 | "dependencies": {
139 | "object-assign": "^4",
140 | "vary": "^1"
141 | },
142 | "engines": {
143 | "node": ">= 0.10"
144 | }
145 | },
146 | "node_modules/debug": {
147 | "version": "2.6.9",
148 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
149 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
150 | "dependencies": {
151 | "ms": "2.0.0"
152 | }
153 | },
154 | "node_modules/delayed-stream": {
155 | "version": "1.0.0",
156 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
157 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
158 | "engines": {
159 | "node": ">=0.4.0"
160 | }
161 | },
162 | "node_modules/depd": {
163 | "version": "2.0.0",
164 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
165 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
166 | "engines": {
167 | "node": ">= 0.8"
168 | }
169 | },
170 | "node_modules/destroy": {
171 | "version": "1.2.0",
172 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
173 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
174 | "engines": {
175 | "node": ">= 0.8",
176 | "npm": "1.2.8000 || >= 1.4.16"
177 | }
178 | },
179 | "node_modules/dotenv": {
180 | "version": "16.0.3",
181 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz",
182 | "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==",
183 | "engines": {
184 | "node": ">=12"
185 | }
186 | },
187 | "node_modules/ee-first": {
188 | "version": "1.1.1",
189 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
190 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
191 | },
192 | "node_modules/encodeurl": {
193 | "version": "1.0.2",
194 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
195 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
196 | "engines": {
197 | "node": ">= 0.8"
198 | }
199 | },
200 | "node_modules/escape-html": {
201 | "version": "1.0.3",
202 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
203 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
204 | },
205 | "node_modules/etag": {
206 | "version": "1.8.1",
207 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
208 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
209 | "engines": {
210 | "node": ">= 0.6"
211 | }
212 | },
213 | "node_modules/express": {
214 | "version": "4.18.2",
215 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
216 | "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
217 | "dependencies": {
218 | "accepts": "~1.3.8",
219 | "array-flatten": "1.1.1",
220 | "body-parser": "1.20.1",
221 | "content-disposition": "0.5.4",
222 | "content-type": "~1.0.4",
223 | "cookie": "0.5.0",
224 | "cookie-signature": "1.0.6",
225 | "debug": "2.6.9",
226 | "depd": "2.0.0",
227 | "encodeurl": "~1.0.2",
228 | "escape-html": "~1.0.3",
229 | "etag": "~1.8.1",
230 | "finalhandler": "1.2.0",
231 | "fresh": "0.5.2",
232 | "http-errors": "2.0.0",
233 | "merge-descriptors": "1.0.1",
234 | "methods": "~1.1.2",
235 | "on-finished": "2.4.1",
236 | "parseurl": "~1.3.3",
237 | "path-to-regexp": "0.1.7",
238 | "proxy-addr": "~2.0.7",
239 | "qs": "6.11.0",
240 | "range-parser": "~1.2.1",
241 | "safe-buffer": "5.2.1",
242 | "send": "0.18.0",
243 | "serve-static": "1.15.0",
244 | "setprototypeof": "1.2.0",
245 | "statuses": "2.0.1",
246 | "type-is": "~1.6.18",
247 | "utils-merge": "1.0.1",
248 | "vary": "~1.1.2"
249 | },
250 | "engines": {
251 | "node": ">= 0.10.0"
252 | }
253 | },
254 | "node_modules/finalhandler": {
255 | "version": "1.2.0",
256 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
257 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
258 | "dependencies": {
259 | "debug": "2.6.9",
260 | "encodeurl": "~1.0.2",
261 | "escape-html": "~1.0.3",
262 | "on-finished": "2.4.1",
263 | "parseurl": "~1.3.3",
264 | "statuses": "2.0.1",
265 | "unpipe": "~1.0.0"
266 | },
267 | "engines": {
268 | "node": ">= 0.8"
269 | }
270 | },
271 | "node_modules/follow-redirects": {
272 | "version": "1.15.2",
273 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
274 | "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
275 | "funding": [
276 | {
277 | "type": "individual",
278 | "url": "https://github.com/sponsors/RubenVerborgh"
279 | }
280 | ],
281 | "engines": {
282 | "node": ">=4.0"
283 | },
284 | "peerDependenciesMeta": {
285 | "debug": {
286 | "optional": true
287 | }
288 | }
289 | },
290 | "node_modules/form-data": {
291 | "version": "4.0.0",
292 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
293 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
294 | "dependencies": {
295 | "asynckit": "^0.4.0",
296 | "combined-stream": "^1.0.8",
297 | "mime-types": "^2.1.12"
298 | },
299 | "engines": {
300 | "node": ">= 6"
301 | }
302 | },
303 | "node_modules/forwarded": {
304 | "version": "0.2.0",
305 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
306 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
307 | "engines": {
308 | "node": ">= 0.6"
309 | }
310 | },
311 | "node_modules/fresh": {
312 | "version": "0.5.2",
313 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
314 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
315 | "engines": {
316 | "node": ">= 0.6"
317 | }
318 | },
319 | "node_modules/function-bind": {
320 | "version": "1.1.1",
321 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
322 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
323 | },
324 | "node_modules/get-intrinsic": {
325 | "version": "1.2.0",
326 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz",
327 | "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==",
328 | "dependencies": {
329 | "function-bind": "^1.1.1",
330 | "has": "^1.0.3",
331 | "has-symbols": "^1.0.3"
332 | },
333 | "funding": {
334 | "url": "https://github.com/sponsors/ljharb"
335 | }
336 | },
337 | "node_modules/has": {
338 | "version": "1.0.3",
339 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
340 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
341 | "dependencies": {
342 | "function-bind": "^1.1.1"
343 | },
344 | "engines": {
345 | "node": ">= 0.4.0"
346 | }
347 | },
348 | "node_modules/has-symbols": {
349 | "version": "1.0.3",
350 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
351 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
352 | "engines": {
353 | "node": ">= 0.4"
354 | },
355 | "funding": {
356 | "url": "https://github.com/sponsors/ljharb"
357 | }
358 | },
359 | "node_modules/http-errors": {
360 | "version": "2.0.0",
361 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
362 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
363 | "dependencies": {
364 | "depd": "2.0.0",
365 | "inherits": "2.0.4",
366 | "setprototypeof": "1.2.0",
367 | "statuses": "2.0.1",
368 | "toidentifier": "1.0.1"
369 | },
370 | "engines": {
371 | "node": ">= 0.8"
372 | }
373 | },
374 | "node_modules/iconv-lite": {
375 | "version": "0.4.24",
376 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
377 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
378 | "dependencies": {
379 | "safer-buffer": ">= 2.1.2 < 3"
380 | },
381 | "engines": {
382 | "node": ">=0.10.0"
383 | }
384 | },
385 | "node_modules/inherits": {
386 | "version": "2.0.4",
387 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
388 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
389 | },
390 | "node_modules/ipaddr.js": {
391 | "version": "1.9.1",
392 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
393 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
394 | "engines": {
395 | "node": ">= 0.10"
396 | }
397 | },
398 | "node_modules/media-typer": {
399 | "version": "0.3.0",
400 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
401 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
402 | "engines": {
403 | "node": ">= 0.6"
404 | }
405 | },
406 | "node_modules/merge-descriptors": {
407 | "version": "1.0.1",
408 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
409 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
410 | },
411 | "node_modules/methods": {
412 | "version": "1.1.2",
413 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
414 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
415 | "engines": {
416 | "node": ">= 0.6"
417 | }
418 | },
419 | "node_modules/mime": {
420 | "version": "1.6.0",
421 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
422 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
423 | "bin": {
424 | "mime": "cli.js"
425 | },
426 | "engines": {
427 | "node": ">=4"
428 | }
429 | },
430 | "node_modules/mime-db": {
431 | "version": "1.52.0",
432 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
433 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
434 | "engines": {
435 | "node": ">= 0.6"
436 | }
437 | },
438 | "node_modules/mime-types": {
439 | "version": "2.1.35",
440 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
441 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
442 | "dependencies": {
443 | "mime-db": "1.52.0"
444 | },
445 | "engines": {
446 | "node": ">= 0.6"
447 | }
448 | },
449 | "node_modules/ms": {
450 | "version": "2.0.0",
451 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
452 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
453 | },
454 | "node_modules/negotiator": {
455 | "version": "0.6.3",
456 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
457 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
458 | "engines": {
459 | "node": ">= 0.6"
460 | }
461 | },
462 | "node_modules/object-assign": {
463 | "version": "4.1.1",
464 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
465 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
466 | "engines": {
467 | "node": ">=0.10.0"
468 | }
469 | },
470 | "node_modules/object-inspect": {
471 | "version": "1.12.3",
472 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
473 | "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
474 | "funding": {
475 | "url": "https://github.com/sponsors/ljharb"
476 | }
477 | },
478 | "node_modules/on-finished": {
479 | "version": "2.4.1",
480 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
481 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
482 | "dependencies": {
483 | "ee-first": "1.1.1"
484 | },
485 | "engines": {
486 | "node": ">= 0.8"
487 | }
488 | },
489 | "node_modules/openai": {
490 | "version": "3.1.0",
491 | "resolved": "https://registry.npmjs.org/openai/-/openai-3.1.0.tgz",
492 | "integrity": "sha512-v5kKFH5o+8ld+t0arudj833Mgm3GcgBnbyN9946bj6u7bvel4Yg6YFz2A4HLIYDzmMjIo0s6vSG9x73kOwvdCg==",
493 | "dependencies": {
494 | "axios": "^0.26.0",
495 | "form-data": "^4.0.0"
496 | }
497 | },
498 | "node_modules/parseurl": {
499 | "version": "1.3.3",
500 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
501 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
502 | "engines": {
503 | "node": ">= 0.8"
504 | }
505 | },
506 | "node_modules/path-to-regexp": {
507 | "version": "0.1.7",
508 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
509 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
510 | },
511 | "node_modules/proxy-addr": {
512 | "version": "2.0.7",
513 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
514 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
515 | "dependencies": {
516 | "forwarded": "0.2.0",
517 | "ipaddr.js": "1.9.1"
518 | },
519 | "engines": {
520 | "node": ">= 0.10"
521 | }
522 | },
523 | "node_modules/qs": {
524 | "version": "6.11.0",
525 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
526 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
527 | "dependencies": {
528 | "side-channel": "^1.0.4"
529 | },
530 | "engines": {
531 | "node": ">=0.6"
532 | },
533 | "funding": {
534 | "url": "https://github.com/sponsors/ljharb"
535 | }
536 | },
537 | "node_modules/range-parser": {
538 | "version": "1.2.1",
539 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
540 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
541 | "engines": {
542 | "node": ">= 0.6"
543 | }
544 | },
545 | "node_modules/raw-body": {
546 | "version": "2.5.1",
547 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
548 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
549 | "dependencies": {
550 | "bytes": "3.1.2",
551 | "http-errors": "2.0.0",
552 | "iconv-lite": "0.4.24",
553 | "unpipe": "1.0.0"
554 | },
555 | "engines": {
556 | "node": ">= 0.8"
557 | }
558 | },
559 | "node_modules/safe-buffer": {
560 | "version": "5.2.1",
561 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
562 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
563 | "funding": [
564 | {
565 | "type": "github",
566 | "url": "https://github.com/sponsors/feross"
567 | },
568 | {
569 | "type": "patreon",
570 | "url": "https://www.patreon.com/feross"
571 | },
572 | {
573 | "type": "consulting",
574 | "url": "https://feross.org/support"
575 | }
576 | ]
577 | },
578 | "node_modules/safer-buffer": {
579 | "version": "2.1.2",
580 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
581 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
582 | },
583 | "node_modules/send": {
584 | "version": "0.18.0",
585 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
586 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
587 | "dependencies": {
588 | "debug": "2.6.9",
589 | "depd": "2.0.0",
590 | "destroy": "1.2.0",
591 | "encodeurl": "~1.0.2",
592 | "escape-html": "~1.0.3",
593 | "etag": "~1.8.1",
594 | "fresh": "0.5.2",
595 | "http-errors": "2.0.0",
596 | "mime": "1.6.0",
597 | "ms": "2.1.3",
598 | "on-finished": "2.4.1",
599 | "range-parser": "~1.2.1",
600 | "statuses": "2.0.1"
601 | },
602 | "engines": {
603 | "node": ">= 0.8.0"
604 | }
605 | },
606 | "node_modules/send/node_modules/ms": {
607 | "version": "2.1.3",
608 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
609 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
610 | },
611 | "node_modules/serve-static": {
612 | "version": "1.15.0",
613 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
614 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
615 | "dependencies": {
616 | "encodeurl": "~1.0.2",
617 | "escape-html": "~1.0.3",
618 | "parseurl": "~1.3.3",
619 | "send": "0.18.0"
620 | },
621 | "engines": {
622 | "node": ">= 0.8.0"
623 | }
624 | },
625 | "node_modules/setprototypeof": {
626 | "version": "1.2.0",
627 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
628 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
629 | },
630 | "node_modules/side-channel": {
631 | "version": "1.0.4",
632 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
633 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
634 | "dependencies": {
635 | "call-bind": "^1.0.0",
636 | "get-intrinsic": "^1.0.2",
637 | "object-inspect": "^1.9.0"
638 | },
639 | "funding": {
640 | "url": "https://github.com/sponsors/ljharb"
641 | }
642 | },
643 | "node_modules/statuses": {
644 | "version": "2.0.1",
645 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
646 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
647 | "engines": {
648 | "node": ">= 0.8"
649 | }
650 | },
651 | "node_modules/toidentifier": {
652 | "version": "1.0.1",
653 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
654 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
655 | "engines": {
656 | "node": ">=0.6"
657 | }
658 | },
659 | "node_modules/type-is": {
660 | "version": "1.6.18",
661 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
662 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
663 | "dependencies": {
664 | "media-typer": "0.3.0",
665 | "mime-types": "~2.1.24"
666 | },
667 | "engines": {
668 | "node": ">= 0.6"
669 | }
670 | },
671 | "node_modules/unpipe": {
672 | "version": "1.0.0",
673 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
674 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
675 | "engines": {
676 | "node": ">= 0.8"
677 | }
678 | },
679 | "node_modules/utils-merge": {
680 | "version": "1.0.1",
681 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
682 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
683 | "engines": {
684 | "node": ">= 0.4.0"
685 | }
686 | },
687 | "node_modules/vary": {
688 | "version": "1.1.2",
689 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
690 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
691 | "engines": {
692 | "node": ">= 0.8"
693 | }
694 | }
695 | },
696 | "dependencies": {
697 | "accepts": {
698 | "version": "1.3.8",
699 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
700 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
701 | "requires": {
702 | "mime-types": "~2.1.34",
703 | "negotiator": "0.6.3"
704 | }
705 | },
706 | "array-flatten": {
707 | "version": "1.1.1",
708 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
709 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
710 | },
711 | "asynckit": {
712 | "version": "0.4.0",
713 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
714 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
715 | },
716 | "axios": {
717 | "version": "0.26.1",
718 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz",
719 | "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==",
720 | "requires": {
721 | "follow-redirects": "^1.14.8"
722 | }
723 | },
724 | "body-parser": {
725 | "version": "1.20.1",
726 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
727 | "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
728 | "requires": {
729 | "bytes": "3.1.2",
730 | "content-type": "~1.0.4",
731 | "debug": "2.6.9",
732 | "depd": "2.0.0",
733 | "destroy": "1.2.0",
734 | "http-errors": "2.0.0",
735 | "iconv-lite": "0.4.24",
736 | "on-finished": "2.4.1",
737 | "qs": "6.11.0",
738 | "raw-body": "2.5.1",
739 | "type-is": "~1.6.18",
740 | "unpipe": "1.0.0"
741 | }
742 | },
743 | "bytes": {
744 | "version": "3.1.2",
745 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
746 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="
747 | },
748 | "call-bind": {
749 | "version": "1.0.2",
750 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
751 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
752 | "requires": {
753 | "function-bind": "^1.1.1",
754 | "get-intrinsic": "^1.0.2"
755 | }
756 | },
757 | "combined-stream": {
758 | "version": "1.0.8",
759 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
760 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
761 | "requires": {
762 | "delayed-stream": "~1.0.0"
763 | }
764 | },
765 | "content-disposition": {
766 | "version": "0.5.4",
767 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
768 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
769 | "requires": {
770 | "safe-buffer": "5.2.1"
771 | }
772 | },
773 | "content-type": {
774 | "version": "1.0.4",
775 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
776 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
777 | },
778 | "cookie": {
779 | "version": "0.5.0",
780 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
781 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw=="
782 | },
783 | "cookie-signature": {
784 | "version": "1.0.6",
785 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
786 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
787 | },
788 | "cors": {
789 | "version": "2.8.5",
790 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
791 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
792 | "requires": {
793 | "object-assign": "^4",
794 | "vary": "^1"
795 | }
796 | },
797 | "debug": {
798 | "version": "2.6.9",
799 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
800 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
801 | "requires": {
802 | "ms": "2.0.0"
803 | }
804 | },
805 | "delayed-stream": {
806 | "version": "1.0.0",
807 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
808 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
809 | },
810 | "depd": {
811 | "version": "2.0.0",
812 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
813 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
814 | },
815 | "destroy": {
816 | "version": "1.2.0",
817 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
818 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="
819 | },
820 | "dotenv": {
821 | "version": "16.0.3",
822 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz",
823 | "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ=="
824 | },
825 | "ee-first": {
826 | "version": "1.1.1",
827 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
828 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
829 | },
830 | "encodeurl": {
831 | "version": "1.0.2",
832 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
833 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="
834 | },
835 | "escape-html": {
836 | "version": "1.0.3",
837 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
838 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
839 | },
840 | "etag": {
841 | "version": "1.8.1",
842 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
843 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="
844 | },
845 | "express": {
846 | "version": "4.18.2",
847 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
848 | "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
849 | "requires": {
850 | "accepts": "~1.3.8",
851 | "array-flatten": "1.1.1",
852 | "body-parser": "1.20.1",
853 | "content-disposition": "0.5.4",
854 | "content-type": "~1.0.4",
855 | "cookie": "0.5.0",
856 | "cookie-signature": "1.0.6",
857 | "debug": "2.6.9",
858 | "depd": "2.0.0",
859 | "encodeurl": "~1.0.2",
860 | "escape-html": "~1.0.3",
861 | "etag": "~1.8.1",
862 | "finalhandler": "1.2.0",
863 | "fresh": "0.5.2",
864 | "http-errors": "2.0.0",
865 | "merge-descriptors": "1.0.1",
866 | "methods": "~1.1.2",
867 | "on-finished": "2.4.1",
868 | "parseurl": "~1.3.3",
869 | "path-to-regexp": "0.1.7",
870 | "proxy-addr": "~2.0.7",
871 | "qs": "6.11.0",
872 | "range-parser": "~1.2.1",
873 | "safe-buffer": "5.2.1",
874 | "send": "0.18.0",
875 | "serve-static": "1.15.0",
876 | "setprototypeof": "1.2.0",
877 | "statuses": "2.0.1",
878 | "type-is": "~1.6.18",
879 | "utils-merge": "1.0.1",
880 | "vary": "~1.1.2"
881 | }
882 | },
883 | "finalhandler": {
884 | "version": "1.2.0",
885 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
886 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
887 | "requires": {
888 | "debug": "2.6.9",
889 | "encodeurl": "~1.0.2",
890 | "escape-html": "~1.0.3",
891 | "on-finished": "2.4.1",
892 | "parseurl": "~1.3.3",
893 | "statuses": "2.0.1",
894 | "unpipe": "~1.0.0"
895 | }
896 | },
897 | "follow-redirects": {
898 | "version": "1.15.2",
899 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
900 | "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
901 | },
902 | "form-data": {
903 | "version": "4.0.0",
904 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
905 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
906 | "requires": {
907 | "asynckit": "^0.4.0",
908 | "combined-stream": "^1.0.8",
909 | "mime-types": "^2.1.12"
910 | }
911 | },
912 | "forwarded": {
913 | "version": "0.2.0",
914 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
915 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
916 | },
917 | "fresh": {
918 | "version": "0.5.2",
919 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
920 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="
921 | },
922 | "function-bind": {
923 | "version": "1.1.1",
924 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
925 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
926 | },
927 | "get-intrinsic": {
928 | "version": "1.2.0",
929 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz",
930 | "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==",
931 | "requires": {
932 | "function-bind": "^1.1.1",
933 | "has": "^1.0.3",
934 | "has-symbols": "^1.0.3"
935 | }
936 | },
937 | "has": {
938 | "version": "1.0.3",
939 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
940 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
941 | "requires": {
942 | "function-bind": "^1.1.1"
943 | }
944 | },
945 | "has-symbols": {
946 | "version": "1.0.3",
947 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
948 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
949 | },
950 | "http-errors": {
951 | "version": "2.0.0",
952 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
953 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
954 | "requires": {
955 | "depd": "2.0.0",
956 | "inherits": "2.0.4",
957 | "setprototypeof": "1.2.0",
958 | "statuses": "2.0.1",
959 | "toidentifier": "1.0.1"
960 | }
961 | },
962 | "iconv-lite": {
963 | "version": "0.4.24",
964 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
965 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
966 | "requires": {
967 | "safer-buffer": ">= 2.1.2 < 3"
968 | }
969 | },
970 | "inherits": {
971 | "version": "2.0.4",
972 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
973 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
974 | },
975 | "ipaddr.js": {
976 | "version": "1.9.1",
977 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
978 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
979 | },
980 | "media-typer": {
981 | "version": "0.3.0",
982 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
983 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="
984 | },
985 | "merge-descriptors": {
986 | "version": "1.0.1",
987 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
988 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
989 | },
990 | "methods": {
991 | "version": "1.1.2",
992 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
993 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w=="
994 | },
995 | "mime": {
996 | "version": "1.6.0",
997 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
998 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
999 | },
1000 | "mime-db": {
1001 | "version": "1.52.0",
1002 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
1003 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
1004 | },
1005 | "mime-types": {
1006 | "version": "2.1.35",
1007 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
1008 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
1009 | "requires": {
1010 | "mime-db": "1.52.0"
1011 | }
1012 | },
1013 | "ms": {
1014 | "version": "2.0.0",
1015 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
1016 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
1017 | },
1018 | "negotiator": {
1019 | "version": "0.6.3",
1020 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
1021 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="
1022 | },
1023 | "object-assign": {
1024 | "version": "4.1.1",
1025 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
1026 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
1027 | },
1028 | "object-inspect": {
1029 | "version": "1.12.3",
1030 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
1031 | "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g=="
1032 | },
1033 | "on-finished": {
1034 | "version": "2.4.1",
1035 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
1036 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
1037 | "requires": {
1038 | "ee-first": "1.1.1"
1039 | }
1040 | },
1041 | "openai": {
1042 | "version": "3.1.0",
1043 | "resolved": "https://registry.npmjs.org/openai/-/openai-3.1.0.tgz",
1044 | "integrity": "sha512-v5kKFH5o+8ld+t0arudj833Mgm3GcgBnbyN9946bj6u7bvel4Yg6YFz2A4HLIYDzmMjIo0s6vSG9x73kOwvdCg==",
1045 | "requires": {
1046 | "axios": "^0.26.0",
1047 | "form-data": "^4.0.0"
1048 | }
1049 | },
1050 | "parseurl": {
1051 | "version": "1.3.3",
1052 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
1053 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
1054 | },
1055 | "path-to-regexp": {
1056 | "version": "0.1.7",
1057 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
1058 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
1059 | },
1060 | "proxy-addr": {
1061 | "version": "2.0.7",
1062 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
1063 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
1064 | "requires": {
1065 | "forwarded": "0.2.0",
1066 | "ipaddr.js": "1.9.1"
1067 | }
1068 | },
1069 | "qs": {
1070 | "version": "6.11.0",
1071 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
1072 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
1073 | "requires": {
1074 | "side-channel": "^1.0.4"
1075 | }
1076 | },
1077 | "range-parser": {
1078 | "version": "1.2.1",
1079 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
1080 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
1081 | },
1082 | "raw-body": {
1083 | "version": "2.5.1",
1084 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
1085 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
1086 | "requires": {
1087 | "bytes": "3.1.2",
1088 | "http-errors": "2.0.0",
1089 | "iconv-lite": "0.4.24",
1090 | "unpipe": "1.0.0"
1091 | }
1092 | },
1093 | "safe-buffer": {
1094 | "version": "5.2.1",
1095 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
1096 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
1097 | },
1098 | "safer-buffer": {
1099 | "version": "2.1.2",
1100 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1101 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
1102 | },
1103 | "send": {
1104 | "version": "0.18.0",
1105 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
1106 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
1107 | "requires": {
1108 | "debug": "2.6.9",
1109 | "depd": "2.0.0",
1110 | "destroy": "1.2.0",
1111 | "encodeurl": "~1.0.2",
1112 | "escape-html": "~1.0.3",
1113 | "etag": "~1.8.1",
1114 | "fresh": "0.5.2",
1115 | "http-errors": "2.0.0",
1116 | "mime": "1.6.0",
1117 | "ms": "2.1.3",
1118 | "on-finished": "2.4.1",
1119 | "range-parser": "~1.2.1",
1120 | "statuses": "2.0.1"
1121 | },
1122 | "dependencies": {
1123 | "ms": {
1124 | "version": "2.1.3",
1125 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1126 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
1127 | }
1128 | }
1129 | },
1130 | "serve-static": {
1131 | "version": "1.15.0",
1132 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
1133 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
1134 | "requires": {
1135 | "encodeurl": "~1.0.2",
1136 | "escape-html": "~1.0.3",
1137 | "parseurl": "~1.3.3",
1138 | "send": "0.18.0"
1139 | }
1140 | },
1141 | "setprototypeof": {
1142 | "version": "1.2.0",
1143 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
1144 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
1145 | },
1146 | "side-channel": {
1147 | "version": "1.0.4",
1148 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
1149 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
1150 | "requires": {
1151 | "call-bind": "^1.0.0",
1152 | "get-intrinsic": "^1.0.2",
1153 | "object-inspect": "^1.9.0"
1154 | }
1155 | },
1156 | "statuses": {
1157 | "version": "2.0.1",
1158 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
1159 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="
1160 | },
1161 | "toidentifier": {
1162 | "version": "1.0.1",
1163 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
1164 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
1165 | },
1166 | "type-is": {
1167 | "version": "1.6.18",
1168 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
1169 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
1170 | "requires": {
1171 | "media-typer": "0.3.0",
1172 | "mime-types": "~2.1.24"
1173 | }
1174 | },
1175 | "unpipe": {
1176 | "version": "1.0.0",
1177 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
1178 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="
1179 | },
1180 | "utils-merge": {
1181 | "version": "1.0.1",
1182 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
1183 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="
1184 | },
1185 | "vary": {
1186 | "version": "1.1.2",
1187 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
1188 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="
1189 | }
1190 | }
1191 | }
1192 |
--------------------------------------------------------------------------------
/server/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "chatgpt-server",
3 | "version": "1.0.0",
4 | "description": "ChatGpt Server",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [
10 | "chatgpt"
11 | ],
12 | "author": "Super",
13 | "license": "ISC",
14 | "dependencies": {
15 | "cors": "^2.8.5",
16 | "dotenv": "^16.0.3",
17 | "express": "^4.18.2",
18 | "openai": "^3.1.0"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------