Merge pull request #76 from Maria-Aidarus/main

API Microservice
main
Nilesh 2023-12-05 09:21:52 +05:30 zatwierdzone przez GitHub
commit c26bb6dbe7
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
7 zmienionych plików z 10692 dodań i 57 usunięć

2
netlify.toml 100644
Wyświetl plik

@ -0,0 +1,2 @@
[build]
functions = "netlify/functions/"

Wyświetl plik

@ -0,0 +1,128 @@
<!DOCTYPE html>
<html>
<head>
<title>Invoke Netlify Function</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f5f5f5;
text-align: center;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
}
h1 {
color: #000;
}
form {
background-color: #fff;
padding: 20px;
border-radius: 5px;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.2);
max-width: 400px;
width: 100%;
text-align: left; /* Left-align form elements */
}
label {
display: block;
margin-bottom: 8px;
color: #555;
font-weight: bold;
}
input[type="text"] {
width: 100%;
padding: 12px;
margin-bottom: 20px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
.button-container {
display: flex;
justify-content: center;
}
input[type="submit"] {
background-color: #3fbfff;
color: #fff;
border: none;
padding: 12px 24px;
cursor: pointer;
border-radius: 4px;
font-weight: bold;
margin: 0 auto; /* Center the button horizontally */
}
input[type="submit"]:hover {
background-color: #1177e4;
}
#result {
margin-top: 20px;
padding: 10px;
background-color: transparent;
border: none;
max-width: 400px;
width: 100%;
white-space: nowrap; /* Prevent wrapping to the next line */
/* overflow: hidden; Hide the overflow */
text-align: center; /* Center-align text in result div */
margin-left: auto; /* Move to the center horizontally */
margin-right: auto; /* Move to the center horizontally */
}
</style>
</head>
<body>
<h1>Invoke Netlify Function</h1>
<form id="invokeForm" action="https://main--radiant-entremet-3fce83.netlify.app/.netlify/functions/handleMetadata" method="POST" onsubmit="invokeFunction(event)">
<label for="url">URL:</label>
<input type="text" id="url" name="url" value="https://example.com">
<label for="apiKey">API Key:</label>
<input type="text" id="apiKey" name="apiKey" value="your-api-key">
<div class="button-container">
<input type="submit" value="Invoke Function">
</div>
</form>
<div id="result"></div>
<script>
async function invokeFunction(event) {
event.preventDefault(); // Prevent the default form submission behavior
const url = document.getElementById("url").value;
const apiKey = document.getElementById("apiKey").value;
const formData = { url, apiKey };
try {
const response = await fetch("https://main--radiant-entremet-3fce83.netlify.app/.netlify/functions/handleMetadata", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(formData)
});
const data = await response.json();
// Display the result in the "result" div
document.getElementById("result").innerHTML = JSON.stringify(data, null, 2);
} catch (error) {
console.error("Error:", error);
}
}
</script>
</body>
</html>

Wyświetl plik

@ -0,0 +1,170 @@
const fetch = require('node-fetch'); // Import for webscraping in fetchContentFromURL()
import { OpenAIApi, Configuration } from 'openai';
// const { Configuration, OpenAIApi } = require('openai');
// Function to fetch content from URL using a web scraping service
async function fetchContentFromURL(url) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.text();
} catch (error) {
console.error(`Could not fetch content from URL: ${error}`);
throw error;
}
}
function simplifyContent(content) {
// Preserve the title tag and its content
let title = content.match(/<title.*?>(.*?)<\/title>/i);
title = title ? title[1] : '';
// Extract the body content, if present
let bodyContent = '';
const bodyMatch = content.match(/<body.*?>([\s\S]*)<\/body>/i);
if (bodyMatch) {
bodyContent = bodyMatch[1];
} else {
// If no body tag, assume entire content is body
bodyContent = content;
}
// Remove script and style elements and their content
bodyContent = bodyContent.replace(/<script.*?>.*?<\/script>/gms, '');
bodyContent = bodyContent.replace(/<style.*?>.*?<\/style>/gms, '');
// Remove all remaining HTML tags, except for title, body, h1-h6, p, and a
bodyContent = bodyContent.replace(/<(?!\/?(title|body|h[1-6]|p|a)( [^>]*)?>)([^>]+)>/g, '');
// Manually replace common HTML entities
bodyContent = bodyContent
.replace(/&amp;/g, '&')
.replace(/&lt;/g, '<')
.replace(/&gt;/g, '>')
.replace(/&quot;/g, '"')
.replace(/&#39;/g, "'");
// Remove inline CSS and JavaScript event handlers
bodyContent = bodyContent.replace(/style\s*=\s*'.*?'/gi, '');
bodyContent = bodyContent.replace(/on\w+\s*=\s*".*?"/gi, '');
// Normalize whitespace without removing sentence punctuation
bodyContent = bodyContent.replace(/\s+/g, ' ').trim();
// Condense multiple line breaks into a single one
bodyContent = bodyContent.replace(/(\r\n|\r|\n){2,}/g, '\n');
// Reconstruct content with title and body
const simplifiedContent = `<title>${title}</title><body>${bodyContent}</body>`;
return simplifiedContent;
}
// Placeholder function to perform GPT analysis for media type and topics using Mistral-7b via OpenRouter
async function performGPTAnalysis(simplifiedContent, apiKey) {
// Implement logic to send content to Mistral-7b via OpenRouter for GPT analysis
// Send content and receive GPT analysis response
// this is the code that we tried to use for the GPT Analysis
// try {
// const configuration = new Configuration({
// apiKey: apiKey, // Use the provided API key
// baseURL: "https://openrouter.ai/api/v1" // Your custom API endpoint
// });
// const openai = new OpenAIApi(configuration);
// // Using the specified prompt
// const prompt = `
// Analyze the following text for content categorization:
// Text: "${simplifiedContent}"
// Please provide:
// 1. The most likely media type (e.g., article, book, audio, video, chat, research_paper, wiki, etc.)
// 2. Key topics covered in the text (list up to 5 main topics).
// `;
// const completion = await openai.createCompletion({
// model: "mistralai/mistral-7b-instruct",
// prompt: prompt,
// max_tokens: 150 // Adjust as needed
// });
// //return completion.data.choices[0].text.trim();
// return inferredMediaType;
// } catch (error) {
// console.error('Error with OpenAI completion:', error);
// throw error;
// }
// however, it gives the error below:
// { "error": "Something went wrong", "details": "Configuration is not a constructor" }
// Placeholder code
const inferredMediaType = ["article"];
const extractedTopics = ["topic1", "topic2"];
return { inferredMediaType, extractedTopics };
}
// Placeholder function to map inferred values to predefined formats and topics
function mapInferredValues(mediaType, topics) {
// Implement logic to map inferred media type and topics to predefined formats and topics
// Match inferred values with predefined taxonomy
// Placeholder code
const predefinedMediaType = "Article";
const predefinedTopics = ["Topic 1", "Topic 2"];
return { predefinedMediaType, predefinedTopics };
}
// Placeholder function to format the response
function formatResponse(predefinedMediaType, predefinedTopics) {
// Implement logic to format the extracted metadata into the desired response structure
// Construct the response object
// Placeholder code
const response = {
format: predefinedMediaType,
topics: predefinedTopics,
};
return response;
}
export async function handler(event) {
try {
// Extract URL and API Key from the request body
const { url, apiKey } = JSON.parse(event.body);
// Validate if URL and API Key are present
if (!url || !apiKey) {
return {
statusCode: 400,
body: JSON.stringify({ error: 'URL and API Key are required' }),
};
}
// Step 1: Fetch content from the URL using a web scraping service
const fetchedContent = await fetchContentFromURL(url);
// Step 2: Simplify the fetched content for GPT analysis
const simplifiedContent = simplifyContent(fetchedContent);
// Step 3: Perform GPT analysis for media type and topics
const { inferredMediaType, extractedTopics } = await performGPTAnalysis(simplifiedContent, apiKey);
// Step 4: Map inferred values to predefined formats and topics
const { predefinedMediaType, predefinedTopics } = mapInferredValues(inferredMediaType, extractedTopics);
// Step 5: Format the response
const formattedResponse = formatResponse(predefinedMediaType, predefinedTopics);
// Return the formatted response
return {
statusCode: 200,
// returning the output of the simplifyContent function, to test the function
body: JSON.stringify(simplifiedContent),
};
} catch (error) {
console.error('Error occurred:', error.message);
return {
statusCode: 500,
body: JSON.stringify({ error: 'Something went wrong', details: error.message }),
};
}
}

299
netlify/functions/package-lock.json wygenerowano 100644
Wyświetl plik

@ -0,0 +1,299 @@
{
"name": "handle-metadata-function",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "handle-metadata-function",
"version": "1.0.0",
"dependencies": {
"he": "^1.2.0",
"node-fetch": "^2.7.0",
"openai": "4.20.0"
}
},
"node_modules/@types/node": {
"version": "18.18.13",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.13.tgz",
"integrity": "sha512-vXYZGRrSCreZmq1rEjMRLXJhiy8MrIeVasx+PCVlP414N7CJLHnMf+juVvjdprHyH+XRy3zKZLHeNueOpJCn0g==",
"dependencies": {
"undici-types": "~5.26.4"
}
},
"node_modules/@types/node-fetch": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.9.tgz",
"integrity": "sha512-bQVlnMLFJ2d35DkPNjEPmd9ueO/rh5EiaZt2bhqiSarPjZIuIV6bPQVqcrEyvNo+AfTrRGVazle1tl597w3gfA==",
"dependencies": {
"@types/node": "*",
"form-data": "^4.0.0"
}
},
"node_modules/abort-controller": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
"dependencies": {
"event-target-shim": "^5.0.0"
},
"engines": {
"node": ">=6.5"
}
},
"node_modules/agentkeepalive": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz",
"integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==",
"dependencies": {
"humanize-ms": "^1.2.1"
},
"engines": {
"node": ">= 8.0.0"
}
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/base-64": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz",
"integrity": "sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA=="
},
"node_modules/charenc": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
"integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==",
"engines": {
"node": "*"
}
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/crypt": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
"integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==",
"engines": {
"node": "*"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/digest-fetch": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-1.3.0.tgz",
"integrity": "sha512-CGJuv6iKNM7QyZlM2T3sPAdZWd/p9zQiRNS9G+9COUCwzWFTs0Xp8NF5iePx7wtvhDykReiRRrSeNb4oMmB8lA==",
"dependencies": {
"base-64": "^0.1.0",
"md5": "^2.3.0"
}
},
"node_modules/event-target-shim": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
"engines": {
"node": ">=6"
}
},
"node_modules/form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/form-data-encoder": {
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz",
"integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A=="
},
"node_modules/formdata-node": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz",
"integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==",
"dependencies": {
"node-domexception": "1.0.0",
"web-streams-polyfill": "4.0.0-beta.3"
},
"engines": {
"node": ">= 12.20"
}
},
"node_modules/formdata-node/node_modules/web-streams-polyfill": {
"version": "4.0.0-beta.3",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz",
"integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==",
"engines": {
"node": ">= 14"
}
},
"node_modules/he": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
"bin": {
"he": "bin/he"
}
},
"node_modules/humanize-ms": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
"integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
"dependencies": {
"ms": "^2.0.0"
}
},
"node_modules/is-buffer": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
},
"node_modules/md5": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz",
"integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==",
"dependencies": {
"charenc": "0.0.2",
"crypt": "0.0.2",
"is-buffer": "~1.1.6"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"node_modules/node-domexception": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "github",
"url": "https://paypal.me/jimmywarting"
}
],
"engines": {
"node": ">=10.5.0"
}
},
"node_modules/node-fetch": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/openai": {
"version": "4.20.0",
"resolved": "https://registry.npmjs.org/openai/-/openai-4.20.0.tgz",
"integrity": "sha512-VbAYerNZFfIIeESS+OL9vgDkK8Mnri55n+jN0UN/HZeuM0ghGh6nDN6UGRZxslNgyJ7XmY/Ca9DO4YYyvrszGA==",
"dependencies": {
"@types/node": "^18.11.18",
"@types/node-fetch": "^2.6.4",
"abort-controller": "^3.0.0",
"agentkeepalive": "^4.2.1",
"digest-fetch": "^1.3.0",
"form-data-encoder": "1.7.2",
"formdata-node": "^4.3.2",
"node-fetch": "^2.6.7",
"web-streams-polyfill": "^3.2.1"
},
"bin": {
"openai": "bin/cli"
}
},
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
},
"node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
},
"node_modules/web-streams-polyfill": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz",
"integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==",
"engines": {
"node": ">= 8"
}
},
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
},
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
}
}
}

Wyświetl plik

@ -0,0 +1,14 @@
{
"name": "handle-metadata-function",
"version": "1.0.0",
"description": "A Netlify function to handle metadata extraction and analysis",
"main": "handleMetadata.js",
"scripts": {
"start": "node handleMetadata.js"
},
"dependencies": {
"he": "^1.2.0",
"node-fetch": "^2.7.0",
"openai": "^4.20.0"
}
}

10130
package-lock.json wygenerowano

Plik diff jest za duży Load Diff

Wyświetl plik

@ -23,7 +23,7 @@
"svelte-bricks": "^0.2.1",
"svelte-preprocess": "^5.0.4",
"tailwindcss": "^3.3.3",
"vite": "^4.4.9"
"vite": "^4.5.0"
},
"overrides": {
"@rgossiaux/svelte-headlessui": {
@ -35,6 +35,10 @@
},
"dependencies": {
"@tailwindcss/typography": "^0.5.10",
"firebase-admin": "^11.11.1",
"firebase-functions-test": "^3.1.0",
"node-fetch": "^2.7.0",
"openai": "^4.20.0",
"svelvet": "8.1.0"
}
}