gcharanteja commited on
Commit ·
de703f2
1
Parent(s): c3f4433
feat: add Swagger documentation for API endpoints and integrate Swagger UI
Browse files- Added Swagger UI and Swagger JSDoc dependencies to package.json
- Configured Swagger in server.js to serve API documentation
- Documented health check, product, and order endpoints with Swagger annotations
- Enhanced error handling in product endpoints
- .env +1 -1
- app.py +270 -0
- package-lock.json +478 -1
- package.json +3 -1
- server.js +181 -1
.env
CHANGED
|
@@ -6,4 +6,4 @@ DB_URL=https://maxxcarl-sqllite.hf.space
|
|
| 6 |
DATABASE=ecommerce
|
| 7 |
|
| 8 |
# Express server port
|
| 9 |
-
PORT=
|
|
|
|
| 6 |
DATABASE=ecommerce
|
| 7 |
|
| 8 |
# Express server port
|
| 9 |
+
PORT=3001
|
app.py
CHANGED
|
@@ -67,6 +67,276 @@ def read_root():
|
|
| 67 |
</html>
|
| 68 |
"""
|
| 69 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 70 |
@app.get("/health")
|
| 71 |
def health_check():
|
| 72 |
try:
|
|
|
|
| 67 |
</html>
|
| 68 |
"""
|
| 69 |
|
| 70 |
+
@app.get("/portal", response_class=HTMLResponse)
|
| 71 |
+
def portal():
|
| 72 |
+
return """
|
| 73 |
+
<!doctype html>
|
| 74 |
+
<html lang="en">
|
| 75 |
+
<head>
|
| 76 |
+
<meta charset="utf-8" />
|
| 77 |
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
| 78 |
+
<title>SQLite Portal</title>
|
| 79 |
+
<style>
|
| 80 |
+
body {
|
| 81 |
+
font-family: Arial, sans-serif;
|
| 82 |
+
margin: 24px;
|
| 83 |
+
color: #1f2328;
|
| 84 |
+
background: #f6f8fa;
|
| 85 |
+
}
|
| 86 |
+
h1 { margin: 0 0 8px; }
|
| 87 |
+
.meta { color: #57606a; margin-bottom: 16px; }
|
| 88 |
+
.grid {
|
| 89 |
+
display: grid;
|
| 90 |
+
gap: 16px;
|
| 91 |
+
grid-template-columns: 280px 1fr;
|
| 92 |
+
}
|
| 93 |
+
section {
|
| 94 |
+
background: #ffffff;
|
| 95 |
+
border: 1px solid #d0d7de;
|
| 96 |
+
border-radius: 8px;
|
| 97 |
+
padding: 16px;
|
| 98 |
+
}
|
| 99 |
+
textarea {
|
| 100 |
+
width: 100%;
|
| 101 |
+
min-height: 160px;
|
| 102 |
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
|
| 103 |
+
"Liberation Mono", "Courier New", monospace;
|
| 104 |
+
border: 1px solid #d0d7de;
|
| 105 |
+
border-radius: 6px;
|
| 106 |
+
padding: 8px;
|
| 107 |
+
box-sizing: border-box;
|
| 108 |
+
}
|
| 109 |
+
button {
|
| 110 |
+
background: #0969da;
|
| 111 |
+
color: #ffffff;
|
| 112 |
+
border: none;
|
| 113 |
+
border-radius: 6px;
|
| 114 |
+
padding: 8px 12px;
|
| 115 |
+
cursor: pointer;
|
| 116 |
+
}
|
| 117 |
+
button.secondary { background: #6e7781; }
|
| 118 |
+
#tables { list-style: none; padding: 0; margin: 12px 0 0; }
|
| 119 |
+
#tables li { padding: 6px 8px; border-bottom: 1px solid #d8dee4; }
|
| 120 |
+
#tables li:last-child { border-bottom: none; }
|
| 121 |
+
.actions { display: flex; gap: 8px; margin-top: 8px; }
|
| 122 |
+
#status { margin-top: 12px; color: #57606a; white-space: pre-wrap; }
|
| 123 |
+
table { width: 100%; border-collapse: collapse; margin-top: 12px; }
|
| 124 |
+
th, td {
|
| 125 |
+
border: 1px solid #d0d7de;
|
| 126 |
+
padding: 6px 8px;
|
| 127 |
+
text-align: left;
|
| 128 |
+
vertical-align: top;
|
| 129 |
+
font-size: 14px;
|
| 130 |
+
}
|
| 131 |
+
th { background: #f6f8fa; }
|
| 132 |
+
pre {
|
| 133 |
+
background: #f6f8fa;
|
| 134 |
+
border: 1px solid #d0d7de;
|
| 135 |
+
border-radius: 6px;
|
| 136 |
+
padding: 12px;
|
| 137 |
+
overflow: auto;
|
| 138 |
+
}
|
| 139 |
+
@media (max-width: 900px) {
|
| 140 |
+
.grid { grid-template-columns: 1fr; }
|
| 141 |
+
}
|
| 142 |
+
</style>
|
| 143 |
+
</head>
|
| 144 |
+
<body>
|
| 145 |
+
<h1>SQLite Portal</h1>
|
| 146 |
+
<div class="meta" id="meta">Loading database info...</div>
|
| 147 |
+
<div class="grid">
|
| 148 |
+
<section>
|
| 149 |
+
<h2>Projects</h2>
|
| 150 |
+
<select id="project"></select>
|
| 151 |
+
<div class="actions">
|
| 152 |
+
<button id="refresh">Refresh</button>
|
| 153 |
+
</div>
|
| 154 |
+
<h3>Tables</h3>
|
| 155 |
+
<ul id="tables"></ul>
|
| 156 |
+
</section>
|
| 157 |
+
<section>
|
| 158 |
+
<h2>SQL Editor</h2>
|
| 159 |
+
<textarea id="sql">SELECT * FROM products LIMIT 50;</textarea>
|
| 160 |
+
<div class="actions">
|
| 161 |
+
<button id="run">Run</button>
|
| 162 |
+
<button id="clear" class="secondary">Clear Output</button>
|
| 163 |
+
</div>
|
| 164 |
+
<div id="status"></div>
|
| 165 |
+
<div id="results"></div>
|
| 166 |
+
</section>
|
| 167 |
+
</div>
|
| 168 |
+
|
| 169 |
+
<script>
|
| 170 |
+
const projectEl = document.getElementById("project");
|
| 171 |
+
const tablesEl = document.getElementById("tables");
|
| 172 |
+
const metaEl = document.getElementById("meta");
|
| 173 |
+
const statusEl = document.getElementById("status");
|
| 174 |
+
const resultsEl = document.getElementById("results");
|
| 175 |
+
const sqlEl = document.getElementById("sql");
|
| 176 |
+
|
| 177 |
+
function setStatus(message) {
|
| 178 |
+
statusEl.textContent = message || "";
|
| 179 |
+
}
|
| 180 |
+
|
| 181 |
+
function clearResults() {
|
| 182 |
+
resultsEl.innerHTML = "";
|
| 183 |
+
setStatus("");
|
| 184 |
+
}
|
| 185 |
+
|
| 186 |
+
async function fetchJson(url, options) {
|
| 187 |
+
const response = await fetch(url, options);
|
| 188 |
+
const data = await response.json();
|
| 189 |
+
if (!response.ok) {
|
| 190 |
+
const errorMessage = data.detail || data.error || data.message || response.statusText;
|
| 191 |
+
throw new Error(errorMessage);
|
| 192 |
+
}
|
| 193 |
+
return data;
|
| 194 |
+
}
|
| 195 |
+
|
| 196 |
+
function renderTable(rows) {
|
| 197 |
+
if (!Array.isArray(rows) || rows.length === 0) {
|
| 198 |
+
resultsEl.innerHTML = "<em>No rows returned.</em>";
|
| 199 |
+
return;
|
| 200 |
+
}
|
| 201 |
+
const columns = Object.keys(rows[0]);
|
| 202 |
+
const table = document.createElement("table");
|
| 203 |
+
const thead = document.createElement("thead");
|
| 204 |
+
const headerRow = document.createElement("tr");
|
| 205 |
+
columns.forEach((col) => {
|
| 206 |
+
const th = document.createElement("th");
|
| 207 |
+
th.textContent = col;
|
| 208 |
+
headerRow.appendChild(th);
|
| 209 |
+
});
|
| 210 |
+
thead.appendChild(headerRow);
|
| 211 |
+
table.appendChild(thead);
|
| 212 |
+
|
| 213 |
+
const tbody = document.createElement("tbody");
|
| 214 |
+
rows.forEach((row) => {
|
| 215 |
+
const tr = document.createElement("tr");
|
| 216 |
+
columns.forEach((col) => {
|
| 217 |
+
const td = document.createElement("td");
|
| 218 |
+
const value = row[col] === null || row[col] === undefined ? "" : row[col];
|
| 219 |
+
td.textContent = value;
|
| 220 |
+
tr.appendChild(td);
|
| 221 |
+
});
|
| 222 |
+
tbody.appendChild(tr);
|
| 223 |
+
});
|
| 224 |
+
table.appendChild(tbody);
|
| 225 |
+
resultsEl.innerHTML = "";
|
| 226 |
+
resultsEl.appendChild(table);
|
| 227 |
+
}
|
| 228 |
+
|
| 229 |
+
function currentProject() {
|
| 230 |
+
return projectEl.value || "default";
|
| 231 |
+
}
|
| 232 |
+
|
| 233 |
+
async function loadInfo() {
|
| 234 |
+
try {
|
| 235 |
+
metaEl.textContent = `Server: ${window.location.origin} | Project: ${currentProject()}`;
|
| 236 |
+
} catch (err) {
|
| 237 |
+
metaEl.textContent = `Failed to load info: ${err.message}`;
|
| 238 |
+
}
|
| 239 |
+
}
|
| 240 |
+
|
| 241 |
+
async function loadProjects() {
|
| 242 |
+
projectEl.innerHTML = "";
|
| 243 |
+
try {
|
| 244 |
+
const data = await fetchJson("/api/v1/projects");
|
| 245 |
+
const projects = Array.isArray(data)
|
| 246 |
+
? data
|
| 247 |
+
: data.projects || data.data || [];
|
| 248 |
+
const names = projects
|
| 249 |
+
.map((p) => (typeof p === "string" ? p : p.name))
|
| 250 |
+
.filter(Boolean);
|
| 251 |
+
const uniqueNames = names.length ? names : ["default"];
|
| 252 |
+
uniqueNames.forEach((name) => {
|
| 253 |
+
const option = document.createElement("option");
|
| 254 |
+
option.value = name;
|
| 255 |
+
option.textContent = name;
|
| 256 |
+
projectEl.appendChild(option);
|
| 257 |
+
});
|
| 258 |
+
} catch (err) {
|
| 259 |
+
const option = document.createElement("option");
|
| 260 |
+
option.value = "default";
|
| 261 |
+
option.textContent = "default";
|
| 262 |
+
projectEl.appendChild(option);
|
| 263 |
+
setStatus(`Failed to load projects: ${err.message}`);
|
| 264 |
+
}
|
| 265 |
+
}
|
| 266 |
+
|
| 267 |
+
async function loadTables() {
|
| 268 |
+
tablesEl.innerHTML = "";
|
| 269 |
+
try {
|
| 270 |
+
const project = currentProject();
|
| 271 |
+
const data = await fetchJson(`/api/v1/tables?project=${project}`);
|
| 272 |
+
const tables = data.tables || data.data || [];
|
| 273 |
+
const names = tables
|
| 274 |
+
.map((t) => (typeof t === "string" ? t : t.name))
|
| 275 |
+
.filter(Boolean);
|
| 276 |
+
if (!names.length) {
|
| 277 |
+
tablesEl.innerHTML = "<li>No tables found.</li>";
|
| 278 |
+
return;
|
| 279 |
+
}
|
| 280 |
+
names.forEach((name) => {
|
| 281 |
+
const li = document.createElement("li");
|
| 282 |
+
li.textContent = name;
|
| 283 |
+
li.addEventListener("click", () => {
|
| 284 |
+
sqlEl.value = `SELECT * FROM ${name} LIMIT 50;`;
|
| 285 |
+
});
|
| 286 |
+
tablesEl.appendChild(li);
|
| 287 |
+
});
|
| 288 |
+
} catch (err) {
|
| 289 |
+
tablesEl.innerHTML = `<li>Error: ${err.message}</li>`;
|
| 290 |
+
}
|
| 291 |
+
}
|
| 292 |
+
|
| 293 |
+
async function runSql() {
|
| 294 |
+
clearResults();
|
| 295 |
+
const sql = sqlEl.value.trim();
|
| 296 |
+
if (!sql) {
|
| 297 |
+
setStatus("Enter SQL to run.");
|
| 298 |
+
return;
|
| 299 |
+
}
|
| 300 |
+
setStatus("Running...");
|
| 301 |
+
const verb = sql.split(/\s+/)[0]?.toUpperCase();
|
| 302 |
+
const isQuery = ["SELECT", "PRAGMA", "WITH", "EXPLAIN"].includes(verb);
|
| 303 |
+
const endpoint = isQuery ? "/api/v1/query" : "/api/v1/execute";
|
| 304 |
+
const project = currentProject();
|
| 305 |
+
try {
|
| 306 |
+
const result = await fetchJson(endpoint, {
|
| 307 |
+
method: "POST",
|
| 308 |
+
headers: { "Content-Type": "application/json" },
|
| 309 |
+
body: JSON.stringify({ sql, project }),
|
| 310 |
+
});
|
| 311 |
+
if (isQuery) {
|
| 312 |
+
const rows = result.data || [];
|
| 313 |
+
setStatus(`Query returned ${rows.length} rows.`);
|
| 314 |
+
renderTable(rows);
|
| 315 |
+
} else {
|
| 316 |
+
setStatus(`Statement executed.`);
|
| 317 |
+
resultsEl.innerHTML = `<pre>${JSON.stringify(result, null, 2)}</pre>`;
|
| 318 |
+
}
|
| 319 |
+
} catch (err) {
|
| 320 |
+
setStatus(`Error: ${err.message}`);
|
| 321 |
+
}
|
| 322 |
+
}
|
| 323 |
+
|
| 324 |
+
document.getElementById("refresh").addEventListener("click", () => {
|
| 325 |
+
loadProjects().then(loadTables).then(loadInfo);
|
| 326 |
+
});
|
| 327 |
+
projectEl.addEventListener("change", () => {
|
| 328 |
+
loadTables();
|
| 329 |
+
loadInfo();
|
| 330 |
+
});
|
| 331 |
+
document.getElementById("run").addEventListener("click", runSql);
|
| 332 |
+
document.getElementById("clear").addEventListener("click", clearResults);
|
| 333 |
+
|
| 334 |
+
loadProjects().then(loadTables).then(loadInfo);
|
| 335 |
+
</script>
|
| 336 |
+
</body>
|
| 337 |
+
</html>
|
| 338 |
+
"""
|
| 339 |
+
|
| 340 |
@app.get("/health")
|
| 341 |
def health_check():
|
| 342 |
try:
|
package-lock.json
CHANGED
|
@@ -10,9 +10,81 @@
|
|
| 10 |
"dependencies": {
|
| 11 |
"axios": "^1.17.0",
|
| 12 |
"dotenv": "^16.0.3",
|
| 13 |
-
"express": "^4.18.2"
|
|
|
|
|
|
|
| 14 |
}
|
| 15 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
"node_modules/accepts": {
|
| 17 |
"version": "1.3.8",
|
| 18 |
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
|
@@ -61,6 +133,42 @@
|
|
| 61 |
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
| 62 |
"license": "MIT"
|
| 63 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
"node_modules/array-flatten": {
|
| 65 |
"version": "1.1.1",
|
| 66 |
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
|
@@ -85,6 +193,15 @@
|
|
| 85 |
"proxy-from-env": "^2.1.0"
|
| 86 |
}
|
| 87 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 88 |
"node_modules/body-parser": {
|
| 89 |
"version": "1.20.5",
|
| 90 |
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.5.tgz",
|
|
@@ -109,6 +226,18 @@
|
|
| 109 |
"npm": "1.2.8000 || >= 1.4.16"
|
| 110 |
}
|
| 111 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 112 |
"node_modules/bytes": {
|
| 113 |
"version": "3.1.2",
|
| 114 |
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
|
@@ -147,6 +276,12 @@
|
|
| 147 |
"url": "https://github.com/sponsors/ljharb"
|
| 148 |
}
|
| 149 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 150 |
"node_modules/combined-stream": {
|
| 151 |
"version": "1.0.8",
|
| 152 |
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
|
@@ -159,6 +294,15 @@
|
|
| 159 |
"node": ">= 0.8"
|
| 160 |
}
|
| 161 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 162 |
"node_modules/content-disposition": {
|
| 163 |
"version": "0.5.4",
|
| 164 |
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
|
@@ -195,6 +339,20 @@
|
|
| 195 |
"integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==",
|
| 196 |
"license": "MIT"
|
| 197 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 198 |
"node_modules/debug": {
|
| 199 |
"version": "2.6.9",
|
| 200 |
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
|
@@ -232,6 +390,18 @@
|
|
| 232 |
"npm": "1.2.8000 || >= 1.4.16"
|
| 233 |
}
|
| 234 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 235 |
"node_modules/dotenv": {
|
| 236 |
"version": "16.6.1",
|
| 237 |
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
|
|
@@ -324,6 +494,15 @@
|
|
| 324 |
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
|
| 325 |
"license": "MIT"
|
| 326 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 327 |
"node_modules/etag": {
|
| 328 |
"version": "1.8.1",
|
| 329 |
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
|
@@ -379,6 +558,28 @@
|
|
| 379 |
"url": "https://opencollective.com/express"
|
| 380 |
}
|
| 381 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 382 |
"node_modules/finalhandler": {
|
| 383 |
"version": "1.3.2",
|
| 384 |
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz",
|
|
@@ -417,6 +618,22 @@
|
|
| 417 |
}
|
| 418 |
}
|
| 419 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 420 |
"node_modules/form-data": {
|
| 421 |
"version": "4.0.5",
|
| 422 |
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
|
|
@@ -497,6 +714,30 @@
|
|
| 497 |
"node": ">= 0.4"
|
| 498 |
}
|
| 499 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 500 |
"node_modules/gopd": {
|
| 501 |
"version": "1.2.0",
|
| 502 |
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
|
@@ -631,6 +872,70 @@
|
|
| 631 |
"node": ">= 0.10"
|
| 632 |
}
|
| 633 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 634 |
"node_modules/math-intrinsics": {
|
| 635 |
"version": "1.1.0",
|
| 636 |
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
|
@@ -700,6 +1005,30 @@
|
|
| 700 |
"node": ">= 0.6"
|
| 701 |
}
|
| 702 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 703 |
"node_modules/ms": {
|
| 704 |
"version": "2.0.0",
|
| 705 |
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
|
@@ -739,6 +1068,19 @@
|
|
| 739 |
"node": ">= 0.8"
|
| 740 |
}
|
| 741 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 742 |
"node_modules/parseurl": {
|
| 743 |
"version": "1.3.3",
|
| 744 |
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
|
@@ -748,6 +1090,31 @@
|
|
| 748 |
"node": ">= 0.8"
|
| 749 |
}
|
| 750 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 751 |
"node_modules/path-to-regexp": {
|
| 752 |
"version": "0.1.13",
|
| 753 |
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz",
|
|
@@ -815,6 +1182,15 @@
|
|
| 815 |
"node": ">= 0.8"
|
| 816 |
}
|
| 817 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 818 |
"node_modules/safe-buffer": {
|
| 819 |
"version": "5.2.1",
|
| 820 |
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
|
@@ -892,6 +1268,27 @@
|
|
| 892 |
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
|
| 893 |
"license": "ISC"
|
| 894 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 895 |
"node_modules/side-channel": {
|
| 896 |
"version": "1.1.0",
|
| 897 |
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
|
|
@@ -964,6 +1361,18 @@
|
|
| 964 |
"url": "https://github.com/sponsors/ljharb"
|
| 965 |
}
|
| 966 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 967 |
"node_modules/statuses": {
|
| 968 |
"version": "2.0.2",
|
| 969 |
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
|
|
@@ -973,6 +1382,50 @@
|
|
| 973 |
"node": ">= 0.8"
|
| 974 |
}
|
| 975 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 976 |
"node_modules/toidentifier": {
|
| 977 |
"version": "1.0.1",
|
| 978 |
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
|
@@ -1021,6 +1474,30 @@
|
|
| 1021 |
"engines": {
|
| 1022 |
"node": ">= 0.8"
|
| 1023 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1024 |
}
|
| 1025 |
}
|
| 1026 |
}
|
|
|
|
| 10 |
"dependencies": {
|
| 11 |
"axios": "^1.17.0",
|
| 12 |
"dotenv": "^16.0.3",
|
| 13 |
+
"express": "^4.18.2",
|
| 14 |
+
"swagger-jsdoc": "^6.3.0",
|
| 15 |
+
"swagger-ui-express": "^5.0.1"
|
| 16 |
}
|
| 17 |
},
|
| 18 |
+
"node_modules/@apidevtools/json-schema-ref-parser": {
|
| 19 |
+
"version": "14.0.1",
|
| 20 |
+
"resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-14.0.1.tgz",
|
| 21 |
+
"integrity": "sha512-Oc96zvmxx1fqoSEdUmfmvvb59/KDOnUoJ7s2t7bISyAn0XEz57LCCw8k2Y4Pf3mwKaZLMciESALORLgfe2frCw==",
|
| 22 |
+
"license": "MIT",
|
| 23 |
+
"dependencies": {
|
| 24 |
+
"@types/json-schema": "^7.0.15",
|
| 25 |
+
"js-yaml": "^4.1.0"
|
| 26 |
+
},
|
| 27 |
+
"engines": {
|
| 28 |
+
"node": ">= 16"
|
| 29 |
+
},
|
| 30 |
+
"funding": {
|
| 31 |
+
"url": "https://github.com/sponsors/philsturgeon"
|
| 32 |
+
}
|
| 33 |
+
},
|
| 34 |
+
"node_modules/@apidevtools/openapi-schemas": {
|
| 35 |
+
"version": "2.1.0",
|
| 36 |
+
"resolved": "https://registry.npmjs.org/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz",
|
| 37 |
+
"integrity": "sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==",
|
| 38 |
+
"license": "MIT",
|
| 39 |
+
"engines": {
|
| 40 |
+
"node": ">=10"
|
| 41 |
+
}
|
| 42 |
+
},
|
| 43 |
+
"node_modules/@apidevtools/swagger-methods": {
|
| 44 |
+
"version": "3.0.2",
|
| 45 |
+
"resolved": "https://registry.npmjs.org/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz",
|
| 46 |
+
"integrity": "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==",
|
| 47 |
+
"license": "MIT"
|
| 48 |
+
},
|
| 49 |
+
"node_modules/@apidevtools/swagger-parser": {
|
| 50 |
+
"version": "12.1.0",
|
| 51 |
+
"resolved": "https://registry.npmjs.org/@apidevtools/swagger-parser/-/swagger-parser-12.1.0.tgz",
|
| 52 |
+
"integrity": "sha512-e5mJoswsnAX0jG+J09xHFYQXb/bUc5S3pLpMxUuRUA2H8T2kni3yEoyz2R3Dltw5f4A6j6rPNMpWTK+iVDFlng==",
|
| 53 |
+
"license": "MIT",
|
| 54 |
+
"dependencies": {
|
| 55 |
+
"@apidevtools/json-schema-ref-parser": "14.0.1",
|
| 56 |
+
"@apidevtools/openapi-schemas": "^2.1.0",
|
| 57 |
+
"@apidevtools/swagger-methods": "^3.0.2",
|
| 58 |
+
"ajv": "^8.17.1",
|
| 59 |
+
"ajv-draft-04": "^1.0.0",
|
| 60 |
+
"call-me-maybe": "^1.0.2"
|
| 61 |
+
},
|
| 62 |
+
"peerDependencies": {
|
| 63 |
+
"openapi-types": ">=7"
|
| 64 |
+
}
|
| 65 |
+
},
|
| 66 |
+
"node_modules/@isaacs/cliui": {
|
| 67 |
+
"version": "9.0.0",
|
| 68 |
+
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz",
|
| 69 |
+
"integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==",
|
| 70 |
+
"license": "BlueOak-1.0.0",
|
| 71 |
+
"engines": {
|
| 72 |
+
"node": ">=18"
|
| 73 |
+
}
|
| 74 |
+
},
|
| 75 |
+
"node_modules/@scarf/scarf": {
|
| 76 |
+
"version": "1.4.0",
|
| 77 |
+
"resolved": "https://registry.npmjs.org/@scarf/scarf/-/scarf-1.4.0.tgz",
|
| 78 |
+
"integrity": "sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==",
|
| 79 |
+
"hasInstallScript": true,
|
| 80 |
+
"license": "Apache-2.0"
|
| 81 |
+
},
|
| 82 |
+
"node_modules/@types/json-schema": {
|
| 83 |
+
"version": "7.0.15",
|
| 84 |
+
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
|
| 85 |
+
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
|
| 86 |
+
"license": "MIT"
|
| 87 |
+
},
|
| 88 |
"node_modules/accepts": {
|
| 89 |
"version": "1.3.8",
|
| 90 |
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
|
|
|
| 133 |
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
| 134 |
"license": "MIT"
|
| 135 |
},
|
| 136 |
+
"node_modules/ajv": {
|
| 137 |
+
"version": "8.20.0",
|
| 138 |
+
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz",
|
| 139 |
+
"integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==",
|
| 140 |
+
"license": "MIT",
|
| 141 |
+
"dependencies": {
|
| 142 |
+
"fast-deep-equal": "^3.1.3",
|
| 143 |
+
"fast-uri": "^3.0.1",
|
| 144 |
+
"json-schema-traverse": "^1.0.0",
|
| 145 |
+
"require-from-string": "^2.0.2"
|
| 146 |
+
},
|
| 147 |
+
"funding": {
|
| 148 |
+
"type": "github",
|
| 149 |
+
"url": "https://github.com/sponsors/epoberezkin"
|
| 150 |
+
}
|
| 151 |
+
},
|
| 152 |
+
"node_modules/ajv-draft-04": {
|
| 153 |
+
"version": "1.0.0",
|
| 154 |
+
"resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz",
|
| 155 |
+
"integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==",
|
| 156 |
+
"license": "MIT",
|
| 157 |
+
"peerDependencies": {
|
| 158 |
+
"ajv": "^8.5.0"
|
| 159 |
+
},
|
| 160 |
+
"peerDependenciesMeta": {
|
| 161 |
+
"ajv": {
|
| 162 |
+
"optional": true
|
| 163 |
+
}
|
| 164 |
+
}
|
| 165 |
+
},
|
| 166 |
+
"node_modules/argparse": {
|
| 167 |
+
"version": "2.0.1",
|
| 168 |
+
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
| 169 |
+
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
| 170 |
+
"license": "Python-2.0"
|
| 171 |
+
},
|
| 172 |
"node_modules/array-flatten": {
|
| 173 |
"version": "1.1.1",
|
| 174 |
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
|
|
|
| 193 |
"proxy-from-env": "^2.1.0"
|
| 194 |
}
|
| 195 |
},
|
| 196 |
+
"node_modules/balanced-match": {
|
| 197 |
+
"version": "4.0.4",
|
| 198 |
+
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
|
| 199 |
+
"integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
|
| 200 |
+
"license": "MIT",
|
| 201 |
+
"engines": {
|
| 202 |
+
"node": "18 || 20 || >=22"
|
| 203 |
+
}
|
| 204 |
+
},
|
| 205 |
"node_modules/body-parser": {
|
| 206 |
"version": "1.20.5",
|
| 207 |
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.5.tgz",
|
|
|
|
| 226 |
"npm": "1.2.8000 || >= 1.4.16"
|
| 227 |
}
|
| 228 |
},
|
| 229 |
+
"node_modules/brace-expansion": {
|
| 230 |
+
"version": "5.0.6",
|
| 231 |
+
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz",
|
| 232 |
+
"integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==",
|
| 233 |
+
"license": "MIT",
|
| 234 |
+
"dependencies": {
|
| 235 |
+
"balanced-match": "^4.0.2"
|
| 236 |
+
},
|
| 237 |
+
"engines": {
|
| 238 |
+
"node": "18 || 20 || >=22"
|
| 239 |
+
}
|
| 240 |
+
},
|
| 241 |
"node_modules/bytes": {
|
| 242 |
"version": "3.1.2",
|
| 243 |
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
|
|
|
| 276 |
"url": "https://github.com/sponsors/ljharb"
|
| 277 |
}
|
| 278 |
},
|
| 279 |
+
"node_modules/call-me-maybe": {
|
| 280 |
+
"version": "1.0.2",
|
| 281 |
+
"resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz",
|
| 282 |
+
"integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==",
|
| 283 |
+
"license": "MIT"
|
| 284 |
+
},
|
| 285 |
"node_modules/combined-stream": {
|
| 286 |
"version": "1.0.8",
|
| 287 |
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
|
|
|
| 294 |
"node": ">= 0.8"
|
| 295 |
}
|
| 296 |
},
|
| 297 |
+
"node_modules/commander": {
|
| 298 |
+
"version": "6.2.0",
|
| 299 |
+
"resolved": "https://registry.npmjs.org/commander/-/commander-6.2.0.tgz",
|
| 300 |
+
"integrity": "sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q==",
|
| 301 |
+
"license": "MIT",
|
| 302 |
+
"engines": {
|
| 303 |
+
"node": ">= 6"
|
| 304 |
+
}
|
| 305 |
+
},
|
| 306 |
"node_modules/content-disposition": {
|
| 307 |
"version": "0.5.4",
|
| 308 |
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
|
|
|
| 339 |
"integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==",
|
| 340 |
"license": "MIT"
|
| 341 |
},
|
| 342 |
+
"node_modules/cross-spawn": {
|
| 343 |
+
"version": "7.0.6",
|
| 344 |
+
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
| 345 |
+
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
| 346 |
+
"license": "MIT",
|
| 347 |
+
"dependencies": {
|
| 348 |
+
"path-key": "^3.1.0",
|
| 349 |
+
"shebang-command": "^2.0.0",
|
| 350 |
+
"which": "^2.0.1"
|
| 351 |
+
},
|
| 352 |
+
"engines": {
|
| 353 |
+
"node": ">= 8"
|
| 354 |
+
}
|
| 355 |
+
},
|
| 356 |
"node_modules/debug": {
|
| 357 |
"version": "2.6.9",
|
| 358 |
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
|
|
|
| 390 |
"npm": "1.2.8000 || >= 1.4.16"
|
| 391 |
}
|
| 392 |
},
|
| 393 |
+
"node_modules/doctrine": {
|
| 394 |
+
"version": "3.0.0",
|
| 395 |
+
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
|
| 396 |
+
"integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
|
| 397 |
+
"license": "Apache-2.0",
|
| 398 |
+
"dependencies": {
|
| 399 |
+
"esutils": "^2.0.2"
|
| 400 |
+
},
|
| 401 |
+
"engines": {
|
| 402 |
+
"node": ">=6.0.0"
|
| 403 |
+
}
|
| 404 |
+
},
|
| 405 |
"node_modules/dotenv": {
|
| 406 |
"version": "16.6.1",
|
| 407 |
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
|
|
|
|
| 494 |
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
|
| 495 |
"license": "MIT"
|
| 496 |
},
|
| 497 |
+
"node_modules/esutils": {
|
| 498 |
+
"version": "2.0.3",
|
| 499 |
+
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
|
| 500 |
+
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
|
| 501 |
+
"license": "BSD-2-Clause",
|
| 502 |
+
"engines": {
|
| 503 |
+
"node": ">=0.10.0"
|
| 504 |
+
}
|
| 505 |
+
},
|
| 506 |
"node_modules/etag": {
|
| 507 |
"version": "1.8.1",
|
| 508 |
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
|
|
|
| 558 |
"url": "https://opencollective.com/express"
|
| 559 |
}
|
| 560 |
},
|
| 561 |
+
"node_modules/fast-deep-equal": {
|
| 562 |
+
"version": "3.1.3",
|
| 563 |
+
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
| 564 |
+
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
| 565 |
+
"license": "MIT"
|
| 566 |
+
},
|
| 567 |
+
"node_modules/fast-uri": {
|
| 568 |
+
"version": "3.1.2",
|
| 569 |
+
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz",
|
| 570 |
+
"integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==",
|
| 571 |
+
"funding": [
|
| 572 |
+
{
|
| 573 |
+
"type": "github",
|
| 574 |
+
"url": "https://github.com/sponsors/fastify"
|
| 575 |
+
},
|
| 576 |
+
{
|
| 577 |
+
"type": "opencollective",
|
| 578 |
+
"url": "https://opencollective.com/fastify"
|
| 579 |
+
}
|
| 580 |
+
],
|
| 581 |
+
"license": "BSD-3-Clause"
|
| 582 |
+
},
|
| 583 |
"node_modules/finalhandler": {
|
| 584 |
"version": "1.3.2",
|
| 585 |
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz",
|
|
|
|
| 618 |
}
|
| 619 |
}
|
| 620 |
},
|
| 621 |
+
"node_modules/foreground-child": {
|
| 622 |
+
"version": "3.3.1",
|
| 623 |
+
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
|
| 624 |
+
"integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
|
| 625 |
+
"license": "ISC",
|
| 626 |
+
"dependencies": {
|
| 627 |
+
"cross-spawn": "^7.0.6",
|
| 628 |
+
"signal-exit": "^4.0.1"
|
| 629 |
+
},
|
| 630 |
+
"engines": {
|
| 631 |
+
"node": ">=14"
|
| 632 |
+
},
|
| 633 |
+
"funding": {
|
| 634 |
+
"url": "https://github.com/sponsors/isaacs"
|
| 635 |
+
}
|
| 636 |
+
},
|
| 637 |
"node_modules/form-data": {
|
| 638 |
"version": "4.0.5",
|
| 639 |
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
|
|
|
|
| 714 |
"node": ">= 0.4"
|
| 715 |
}
|
| 716 |
},
|
| 717 |
+
"node_modules/glob": {
|
| 718 |
+
"version": "11.1.0",
|
| 719 |
+
"resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz",
|
| 720 |
+
"integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==",
|
| 721 |
+
"deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
|
| 722 |
+
"license": "BlueOak-1.0.0",
|
| 723 |
+
"dependencies": {
|
| 724 |
+
"foreground-child": "^3.3.1",
|
| 725 |
+
"jackspeak": "^4.1.1",
|
| 726 |
+
"minimatch": "^10.1.1",
|
| 727 |
+
"minipass": "^7.1.2",
|
| 728 |
+
"package-json-from-dist": "^1.0.0",
|
| 729 |
+
"path-scurry": "^2.0.0"
|
| 730 |
+
},
|
| 731 |
+
"bin": {
|
| 732 |
+
"glob": "dist/esm/bin.mjs"
|
| 733 |
+
},
|
| 734 |
+
"engines": {
|
| 735 |
+
"node": "20 || >=22"
|
| 736 |
+
},
|
| 737 |
+
"funding": {
|
| 738 |
+
"url": "https://github.com/sponsors/isaacs"
|
| 739 |
+
}
|
| 740 |
+
},
|
| 741 |
"node_modules/gopd": {
|
| 742 |
"version": "1.2.0",
|
| 743 |
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
|
|
|
| 872 |
"node": ">= 0.10"
|
| 873 |
}
|
| 874 |
},
|
| 875 |
+
"node_modules/isexe": {
|
| 876 |
+
"version": "2.0.0",
|
| 877 |
+
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
| 878 |
+
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
| 879 |
+
"license": "ISC"
|
| 880 |
+
},
|
| 881 |
+
"node_modules/jackspeak": {
|
| 882 |
+
"version": "4.2.3",
|
| 883 |
+
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz",
|
| 884 |
+
"integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==",
|
| 885 |
+
"license": "BlueOak-1.0.0",
|
| 886 |
+
"dependencies": {
|
| 887 |
+
"@isaacs/cliui": "^9.0.0"
|
| 888 |
+
},
|
| 889 |
+
"engines": {
|
| 890 |
+
"node": "20 || >=22"
|
| 891 |
+
},
|
| 892 |
+
"funding": {
|
| 893 |
+
"url": "https://github.com/sponsors/isaacs"
|
| 894 |
+
}
|
| 895 |
+
},
|
| 896 |
+
"node_modules/js-yaml": {
|
| 897 |
+
"version": "4.2.0",
|
| 898 |
+
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz",
|
| 899 |
+
"integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==",
|
| 900 |
+
"funding": [
|
| 901 |
+
{
|
| 902 |
+
"type": "github",
|
| 903 |
+
"url": "https://github.com/sponsors/puzrin"
|
| 904 |
+
},
|
| 905 |
+
{
|
| 906 |
+
"type": "github",
|
| 907 |
+
"url": "https://github.com/sponsors/nodeca"
|
| 908 |
+
}
|
| 909 |
+
],
|
| 910 |
+
"license": "MIT",
|
| 911 |
+
"dependencies": {
|
| 912 |
+
"argparse": "^2.0.1"
|
| 913 |
+
},
|
| 914 |
+
"bin": {
|
| 915 |
+
"js-yaml": "bin/js-yaml.js"
|
| 916 |
+
}
|
| 917 |
+
},
|
| 918 |
+
"node_modules/json-schema-traverse": {
|
| 919 |
+
"version": "1.0.0",
|
| 920 |
+
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
|
| 921 |
+
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
|
| 922 |
+
"license": "MIT"
|
| 923 |
+
},
|
| 924 |
+
"node_modules/lodash.mergewith": {
|
| 925 |
+
"version": "4.6.2",
|
| 926 |
+
"resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
|
| 927 |
+
"integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==",
|
| 928 |
+
"license": "MIT"
|
| 929 |
+
},
|
| 930 |
+
"node_modules/lru-cache": {
|
| 931 |
+
"version": "11.5.1",
|
| 932 |
+
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.1.tgz",
|
| 933 |
+
"integrity": "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==",
|
| 934 |
+
"license": "BlueOak-1.0.0",
|
| 935 |
+
"engines": {
|
| 936 |
+
"node": "20 || >=22"
|
| 937 |
+
}
|
| 938 |
+
},
|
| 939 |
"node_modules/math-intrinsics": {
|
| 940 |
"version": "1.1.0",
|
| 941 |
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
|
|
|
| 1005 |
"node": ">= 0.6"
|
| 1006 |
}
|
| 1007 |
},
|
| 1008 |
+
"node_modules/minimatch": {
|
| 1009 |
+
"version": "10.2.5",
|
| 1010 |
+
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
|
| 1011 |
+
"integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
|
| 1012 |
+
"license": "BlueOak-1.0.0",
|
| 1013 |
+
"dependencies": {
|
| 1014 |
+
"brace-expansion": "^5.0.5"
|
| 1015 |
+
},
|
| 1016 |
+
"engines": {
|
| 1017 |
+
"node": "18 || 20 || >=22"
|
| 1018 |
+
},
|
| 1019 |
+
"funding": {
|
| 1020 |
+
"url": "https://github.com/sponsors/isaacs"
|
| 1021 |
+
}
|
| 1022 |
+
},
|
| 1023 |
+
"node_modules/minipass": {
|
| 1024 |
+
"version": "7.1.3",
|
| 1025 |
+
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz",
|
| 1026 |
+
"integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==",
|
| 1027 |
+
"license": "BlueOak-1.0.0",
|
| 1028 |
+
"engines": {
|
| 1029 |
+
"node": ">=16 || 14 >=14.17"
|
| 1030 |
+
}
|
| 1031 |
+
},
|
| 1032 |
"node_modules/ms": {
|
| 1033 |
"version": "2.0.0",
|
| 1034 |
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
|
|
|
| 1068 |
"node": ">= 0.8"
|
| 1069 |
}
|
| 1070 |
},
|
| 1071 |
+
"node_modules/openapi-types": {
|
| 1072 |
+
"version": "12.1.3",
|
| 1073 |
+
"resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz",
|
| 1074 |
+
"integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==",
|
| 1075 |
+
"license": "MIT",
|
| 1076 |
+
"peer": true
|
| 1077 |
+
},
|
| 1078 |
+
"node_modules/package-json-from-dist": {
|
| 1079 |
+
"version": "1.0.1",
|
| 1080 |
+
"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
|
| 1081 |
+
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
|
| 1082 |
+
"license": "BlueOak-1.0.0"
|
| 1083 |
+
},
|
| 1084 |
"node_modules/parseurl": {
|
| 1085 |
"version": "1.3.3",
|
| 1086 |
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
|
|
|
| 1090 |
"node": ">= 0.8"
|
| 1091 |
}
|
| 1092 |
},
|
| 1093 |
+
"node_modules/path-key": {
|
| 1094 |
+
"version": "3.1.1",
|
| 1095 |
+
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
| 1096 |
+
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
| 1097 |
+
"license": "MIT",
|
| 1098 |
+
"engines": {
|
| 1099 |
+
"node": ">=8"
|
| 1100 |
+
}
|
| 1101 |
+
},
|
| 1102 |
+
"node_modules/path-scurry": {
|
| 1103 |
+
"version": "2.0.2",
|
| 1104 |
+
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz",
|
| 1105 |
+
"integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
|
| 1106 |
+
"license": "BlueOak-1.0.0",
|
| 1107 |
+
"dependencies": {
|
| 1108 |
+
"lru-cache": "^11.0.0",
|
| 1109 |
+
"minipass": "^7.1.2"
|
| 1110 |
+
},
|
| 1111 |
+
"engines": {
|
| 1112 |
+
"node": "18 || 20 || >=22"
|
| 1113 |
+
},
|
| 1114 |
+
"funding": {
|
| 1115 |
+
"url": "https://github.com/sponsors/isaacs"
|
| 1116 |
+
}
|
| 1117 |
+
},
|
| 1118 |
"node_modules/path-to-regexp": {
|
| 1119 |
"version": "0.1.13",
|
| 1120 |
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz",
|
|
|
|
| 1182 |
"node": ">= 0.8"
|
| 1183 |
}
|
| 1184 |
},
|
| 1185 |
+
"node_modules/require-from-string": {
|
| 1186 |
+
"version": "2.0.2",
|
| 1187 |
+
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
|
| 1188 |
+
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
|
| 1189 |
+
"license": "MIT",
|
| 1190 |
+
"engines": {
|
| 1191 |
+
"node": ">=0.10.0"
|
| 1192 |
+
}
|
| 1193 |
+
},
|
| 1194 |
"node_modules/safe-buffer": {
|
| 1195 |
"version": "5.2.1",
|
| 1196 |
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
|
|
|
| 1268 |
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
|
| 1269 |
"license": "ISC"
|
| 1270 |
},
|
| 1271 |
+
"node_modules/shebang-command": {
|
| 1272 |
+
"version": "2.0.0",
|
| 1273 |
+
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
| 1274 |
+
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
| 1275 |
+
"license": "MIT",
|
| 1276 |
+
"dependencies": {
|
| 1277 |
+
"shebang-regex": "^3.0.0"
|
| 1278 |
+
},
|
| 1279 |
+
"engines": {
|
| 1280 |
+
"node": ">=8"
|
| 1281 |
+
}
|
| 1282 |
+
},
|
| 1283 |
+
"node_modules/shebang-regex": {
|
| 1284 |
+
"version": "3.0.0",
|
| 1285 |
+
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
| 1286 |
+
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
| 1287 |
+
"license": "MIT",
|
| 1288 |
+
"engines": {
|
| 1289 |
+
"node": ">=8"
|
| 1290 |
+
}
|
| 1291 |
+
},
|
| 1292 |
"node_modules/side-channel": {
|
| 1293 |
"version": "1.1.0",
|
| 1294 |
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
|
|
|
|
| 1361 |
"url": "https://github.com/sponsors/ljharb"
|
| 1362 |
}
|
| 1363 |
},
|
| 1364 |
+
"node_modules/signal-exit": {
|
| 1365 |
+
"version": "4.1.0",
|
| 1366 |
+
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
|
| 1367 |
+
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
|
| 1368 |
+
"license": "ISC",
|
| 1369 |
+
"engines": {
|
| 1370 |
+
"node": ">=14"
|
| 1371 |
+
},
|
| 1372 |
+
"funding": {
|
| 1373 |
+
"url": "https://github.com/sponsors/isaacs"
|
| 1374 |
+
}
|
| 1375 |
+
},
|
| 1376 |
"node_modules/statuses": {
|
| 1377 |
"version": "2.0.2",
|
| 1378 |
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
|
|
|
|
| 1382 |
"node": ">= 0.8"
|
| 1383 |
}
|
| 1384 |
},
|
| 1385 |
+
"node_modules/swagger-jsdoc": {
|
| 1386 |
+
"version": "6.3.0",
|
| 1387 |
+
"resolved": "https://registry.npmjs.org/swagger-jsdoc/-/swagger-jsdoc-6.3.0.tgz",
|
| 1388 |
+
"integrity": "sha512-I+iQjVGV3t28pOkQUJv2MncthvOtkEactOn8R76SvSYhxgtIn7FoqfDHwQaN+GBnQdXQLrhgDXseKitmJcHMsA==",
|
| 1389 |
+
"license": "MIT",
|
| 1390 |
+
"dependencies": {
|
| 1391 |
+
"@apidevtools/swagger-parser": "^12.1.0",
|
| 1392 |
+
"commander": "6.2.0",
|
| 1393 |
+
"doctrine": "3.0.0",
|
| 1394 |
+
"glob": "11.1.0",
|
| 1395 |
+
"lodash.mergewith": "^4.6.2",
|
| 1396 |
+
"yaml": "2.0.0-1"
|
| 1397 |
+
},
|
| 1398 |
+
"bin": {
|
| 1399 |
+
"swagger-jsdoc": "bin/swagger-jsdoc.js"
|
| 1400 |
+
},
|
| 1401 |
+
"engines": {
|
| 1402 |
+
"node": ">=20.0.0"
|
| 1403 |
+
}
|
| 1404 |
+
},
|
| 1405 |
+
"node_modules/swagger-ui-dist": {
|
| 1406 |
+
"version": "5.32.6",
|
| 1407 |
+
"resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.32.6.tgz",
|
| 1408 |
+
"integrity": "sha512-75ttZNaYCLoFPnozPZcTUU6mS3wKT8l7WLjU5zJSHFeJa23i5vtnze6IiCl4jDMPeQTXVXIgovq4M11NNfQvSA==",
|
| 1409 |
+
"license": "Apache-2.0",
|
| 1410 |
+
"dependencies": {
|
| 1411 |
+
"@scarf/scarf": "=1.4.0"
|
| 1412 |
+
}
|
| 1413 |
+
},
|
| 1414 |
+
"node_modules/swagger-ui-express": {
|
| 1415 |
+
"version": "5.0.1",
|
| 1416 |
+
"resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-5.0.1.tgz",
|
| 1417 |
+
"integrity": "sha512-SrNU3RiBGTLLmFU8GIJdOdanJTl4TOmT27tt3bWWHppqYmAZ6IDuEuBvMU6nZq0zLEe6b/1rACXCgLZqO6ZfrA==",
|
| 1418 |
+
"license": "MIT",
|
| 1419 |
+
"dependencies": {
|
| 1420 |
+
"swagger-ui-dist": ">=5.0.0"
|
| 1421 |
+
},
|
| 1422 |
+
"engines": {
|
| 1423 |
+
"node": ">= v0.10.32"
|
| 1424 |
+
},
|
| 1425 |
+
"peerDependencies": {
|
| 1426 |
+
"express": ">=4.0.0 || >=5.0.0-beta"
|
| 1427 |
+
}
|
| 1428 |
+
},
|
| 1429 |
"node_modules/toidentifier": {
|
| 1430 |
"version": "1.0.1",
|
| 1431 |
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
|
|
|
| 1474 |
"engines": {
|
| 1475 |
"node": ">= 0.8"
|
| 1476 |
}
|
| 1477 |
+
},
|
| 1478 |
+
"node_modules/which": {
|
| 1479 |
+
"version": "2.0.2",
|
| 1480 |
+
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
| 1481 |
+
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
| 1482 |
+
"license": "ISC",
|
| 1483 |
+
"dependencies": {
|
| 1484 |
+
"isexe": "^2.0.0"
|
| 1485 |
+
},
|
| 1486 |
+
"bin": {
|
| 1487 |
+
"node-which": "bin/node-which"
|
| 1488 |
+
},
|
| 1489 |
+
"engines": {
|
| 1490 |
+
"node": ">= 8"
|
| 1491 |
+
}
|
| 1492 |
+
},
|
| 1493 |
+
"node_modules/yaml": {
|
| 1494 |
+
"version": "2.0.0-1",
|
| 1495 |
+
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.0.0-1.tgz",
|
| 1496 |
+
"integrity": "sha512-W7h5dEhywMKenDJh2iX/LABkbFnBxasD27oyXWDS/feDsxiw0dD5ncXdYXgkvAsXIY2MpW/ZKkr9IU30DBdMNQ==",
|
| 1497 |
+
"license": "ISC",
|
| 1498 |
+
"engines": {
|
| 1499 |
+
"node": ">= 6"
|
| 1500 |
+
}
|
| 1501 |
}
|
| 1502 |
}
|
| 1503 |
}
|
package.json
CHANGED
|
@@ -11,6 +11,8 @@
|
|
| 11 |
"dependencies": {
|
| 12 |
"axios": "^1.17.0",
|
| 13 |
"dotenv": "^16.0.3",
|
| 14 |
-
"express": "^4.18.2"
|
|
|
|
|
|
|
| 15 |
}
|
| 16 |
}
|
|
|
|
| 11 |
"dependencies": {
|
| 12 |
"axios": "^1.17.0",
|
| 13 |
"dotenv": "^16.0.3",
|
| 14 |
+
"express": "^4.18.2",
|
| 15 |
+
"swagger-jsdoc": "^6.3.0",
|
| 16 |
+
"swagger-ui-express": "^5.0.1"
|
| 17 |
}
|
| 18 |
}
|
server.js
CHANGED
|
@@ -1,10 +1,35 @@
|
|
| 1 |
const express = require("express");
|
| 2 |
const axios = require("axios");
|
|
|
|
|
|
|
| 3 |
require("dotenv").config();
|
| 4 |
|
| 5 |
const app = express();
|
| 6 |
app.use(express.json());
|
| 7 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
// Environment variables
|
| 9 |
const SQLITE_SERVER = process.env.DB_URL || "http://localhost:8000";
|
| 10 |
const DATABASE = process.env.DATABASE || "default";
|
|
@@ -32,6 +57,18 @@ async function querySQLite(sql, method = "POST", endpoint = "/api/v1/query") {
|
|
| 32 |
}
|
| 33 |
|
| 34 |
// Health check
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
app.get("/health", async (req, res) => {
|
| 36 |
try {
|
| 37 |
const response = await axios.get(`${SQLITE_SERVER}/api/v1/heartbeat`);
|
|
@@ -46,6 +83,18 @@ app.get("/health", async (req, res) => {
|
|
| 46 |
});
|
| 47 |
|
| 48 |
// Get all products
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
app.get("/api/products", async (req, res) => {
|
| 50 |
try {
|
| 51 |
const result = await querySQLite(
|
|
@@ -55,11 +104,30 @@ app.get("/api/products", async (req, res) => {
|
|
| 55 |
);
|
| 56 |
res.status(200).json(result.data || []);
|
| 57 |
} catch (err) {
|
| 58 |
-
|
|
|
|
| 59 |
}
|
| 60 |
});
|
| 61 |
|
| 62 |
// Get product by ID
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 63 |
app.get("/api/products/:id", async (req, res) => {
|
| 64 |
try {
|
| 65 |
const result = await querySQLite(
|
|
@@ -78,6 +146,31 @@ app.get("/api/products/:id", async (req, res) => {
|
|
| 78 |
});
|
| 79 |
|
| 80 |
// Create product
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 81 |
app.post("/api/products", async (req, res) => {
|
| 82 |
try {
|
| 83 |
const { name, price, stock } = req.body;
|
|
@@ -102,6 +195,34 @@ app.post("/api/products", async (req, res) => {
|
|
| 102 |
});
|
| 103 |
|
| 104 |
// Update product
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
app.put("/api/products/:id", async (req, res) => {
|
| 106 |
try {
|
| 107 |
const { name, price, stock } = req.body;
|
|
@@ -129,6 +250,22 @@ app.put("/api/products/:id", async (req, res) => {
|
|
| 129 |
});
|
| 130 |
|
| 131 |
// Delete product
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 132 |
app.delete("/api/products/:id", async (req, res) => {
|
| 133 |
try {
|
| 134 |
const sql = `DELETE FROM products WHERE id = ${req.params.id}`;
|
|
@@ -145,6 +282,16 @@ app.delete("/api/products/:id", async (req, res) => {
|
|
| 145 |
});
|
| 146 |
|
| 147 |
// Get all orders
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 148 |
app.get("/api/orders", async (req, res) => {
|
| 149 |
try {
|
| 150 |
const result = await querySQLite(
|
|
@@ -159,6 +306,29 @@ app.get("/api/orders", async (req, res) => {
|
|
| 159 |
});
|
| 160 |
|
| 161 |
// Create order
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 162 |
app.post("/api/orders", async (req, res) => {
|
| 163 |
try {
|
| 164 |
const { customer_name, total, status } = req.body;
|
|
@@ -183,6 +353,16 @@ app.post("/api/orders", async (req, res) => {
|
|
| 183 |
});
|
| 184 |
|
| 185 |
// Get database info
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 186 |
app.get("/api/info", async (req, res) => {
|
| 187 |
try {
|
| 188 |
const response = await axios.get(
|
|
|
|
| 1 |
const express = require("express");
|
| 2 |
const axios = require("axios");
|
| 3 |
+
const swaggerUi = require("swagger-ui-express");
|
| 4 |
+
const swaggerJsdoc = require("swagger-jsdoc");
|
| 5 |
require("dotenv").config();
|
| 6 |
|
| 7 |
const app = express();
|
| 8 |
app.use(express.json());
|
| 9 |
|
| 10 |
+
// Swagger configuration
|
| 11 |
+
const swaggerOptions = {
|
| 12 |
+
definition: {
|
| 13 |
+
openapi: "3.0.0",
|
| 14 |
+
info: {
|
| 15 |
+
title: "SQLite Express API",
|
| 16 |
+
version: "1.0.0",
|
| 17 |
+
description: "Express.js server connected to remote SQLite database",
|
| 18 |
+
},
|
| 19 |
+
servers: [
|
| 20 |
+
{
|
| 21 |
+
url: `http://localhost:${process.env.PORT || 3000}`,
|
| 22 |
+
description: "Development server",
|
| 23 |
+
},
|
| 24 |
+
],
|
| 25 |
+
},
|
| 26 |
+
apis: ["./server.js"],
|
| 27 |
+
};
|
| 28 |
+
|
| 29 |
+
const swaggerSpec = swaggerJsdoc(swaggerOptions);
|
| 30 |
+
app.use("/swagger", swaggerUi.serve, swaggerUi.setup(swaggerSpec));
|
| 31 |
+
app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(swaggerSpec));
|
| 32 |
+
|
| 33 |
// Environment variables
|
| 34 |
const SQLITE_SERVER = process.env.DB_URL || "http://localhost:8000";
|
| 35 |
const DATABASE = process.env.DATABASE || "default";
|
|
|
|
| 57 |
}
|
| 58 |
|
| 59 |
// Health check
|
| 60 |
+
/**
|
| 61 |
+
* @swagger
|
| 62 |
+
* /health:
|
| 63 |
+
* get:
|
| 64 |
+
* summary: Health check
|
| 65 |
+
* description: Check if server and database are healthy
|
| 66 |
+
* responses:
|
| 67 |
+
* 200:
|
| 68 |
+
* description: Server is healthy
|
| 69 |
+
* 500:
|
| 70 |
+
* description: Server error
|
| 71 |
+
*/
|
| 72 |
app.get("/health", async (req, res) => {
|
| 73 |
try {
|
| 74 |
const response = await axios.get(`${SQLITE_SERVER}/api/v1/heartbeat`);
|
|
|
|
| 83 |
});
|
| 84 |
|
| 85 |
// Get all products
|
| 86 |
+
/**
|
| 87 |
+
* @swagger
|
| 88 |
+
* /api/products:
|
| 89 |
+
* get:
|
| 90 |
+
* summary: Get all products
|
| 91 |
+
* description: Retrieve all products from the database
|
| 92 |
+
* responses:
|
| 93 |
+
* 200:
|
| 94 |
+
* description: List of products
|
| 95 |
+
* 500:
|
| 96 |
+
* description: Failed to fetch products
|
| 97 |
+
*/
|
| 98 |
app.get("/api/products", async (req, res) => {
|
| 99 |
try {
|
| 100 |
const result = await querySQLite(
|
|
|
|
| 104 |
);
|
| 105 |
res.status(200).json(result.data || []);
|
| 106 |
} catch (err) {
|
| 107 |
+
console.error("GET /api/products error:", err.message);
|
| 108 |
+
res.status(500).json({ error: err.message || "Failed to fetch products" });
|
| 109 |
}
|
| 110 |
});
|
| 111 |
|
| 112 |
// Get product by ID
|
| 113 |
+
/**
|
| 114 |
+
* @swagger
|
| 115 |
+
* /api/products/{id}:
|
| 116 |
+
* get:
|
| 117 |
+
* summary: Get product by ID
|
| 118 |
+
* description: Retrieve a specific product
|
| 119 |
+
* parameters:
|
| 120 |
+
* - in: path
|
| 121 |
+
* name: id
|
| 122 |
+
* required: true
|
| 123 |
+
* schema:
|
| 124 |
+
* type: integer
|
| 125 |
+
* responses:
|
| 126 |
+
* 200:
|
| 127 |
+
* description: Product found
|
| 128 |
+
* 404:
|
| 129 |
+
* description: Product not found
|
| 130 |
+
*/
|
| 131 |
app.get("/api/products/:id", async (req, res) => {
|
| 132 |
try {
|
| 133 |
const result = await querySQLite(
|
|
|
|
| 146 |
});
|
| 147 |
|
| 148 |
// Create product
|
| 149 |
+
/**
|
| 150 |
+
* @swagger
|
| 151 |
+
* /api/products:
|
| 152 |
+
* post:
|
| 153 |
+
* summary: Create a new product
|
| 154 |
+
* description: Add a new product to the database
|
| 155 |
+
* requestBody:
|
| 156 |
+
* required: true
|
| 157 |
+
* content:
|
| 158 |
+
* application/json:
|
| 159 |
+
* schema:
|
| 160 |
+
* type: object
|
| 161 |
+
* properties:
|
| 162 |
+
* name:
|
| 163 |
+
* type: string
|
| 164 |
+
* price:
|
| 165 |
+
* type: number
|
| 166 |
+
* stock:
|
| 167 |
+
* type: integer
|
| 168 |
+
* responses:
|
| 169 |
+
* 201:
|
| 170 |
+
* description: Product created
|
| 171 |
+
* 400:
|
| 172 |
+
* description: Missing required fields
|
| 173 |
+
*/
|
| 174 |
app.post("/api/products", async (req, res) => {
|
| 175 |
try {
|
| 176 |
const { name, price, stock } = req.body;
|
|
|
|
| 195 |
});
|
| 196 |
|
| 197 |
// Update product
|
| 198 |
+
/**
|
| 199 |
+
* @swagger
|
| 200 |
+
* /api/products/{id}:
|
| 201 |
+
* put:
|
| 202 |
+
* summary: Update a product
|
| 203 |
+
* description: Update product information
|
| 204 |
+
* parameters:
|
| 205 |
+
* - in: path
|
| 206 |
+
* name: id
|
| 207 |
+
* required: true
|
| 208 |
+
* schema:
|
| 209 |
+
* type: integer
|
| 210 |
+
* requestBody:
|
| 211 |
+
* content:
|
| 212 |
+
* application/json:
|
| 213 |
+
* schema:
|
| 214 |
+
* type: object
|
| 215 |
+
* properties:
|
| 216 |
+
* name:
|
| 217 |
+
* type: string
|
| 218 |
+
* price:
|
| 219 |
+
* type: number
|
| 220 |
+
* stock:
|
| 221 |
+
* type: integer
|
| 222 |
+
* responses:
|
| 223 |
+
* 200:
|
| 224 |
+
* description: Product updated
|
| 225 |
+
*/
|
| 226 |
app.put("/api/products/:id", async (req, res) => {
|
| 227 |
try {
|
| 228 |
const { name, price, stock } = req.body;
|
|
|
|
| 250 |
});
|
| 251 |
|
| 252 |
// Delete product
|
| 253 |
+
/**
|
| 254 |
+
* @swagger
|
| 255 |
+
* /api/products/{id}:
|
| 256 |
+
* delete:
|
| 257 |
+
* summary: Delete a product
|
| 258 |
+
* description: Remove a product from the database
|
| 259 |
+
* parameters:
|
| 260 |
+
* - in: path
|
| 261 |
+
* name: id
|
| 262 |
+
* required: true
|
| 263 |
+
* schema:
|
| 264 |
+
* type: integer
|
| 265 |
+
* responses:
|
| 266 |
+
* 200:
|
| 267 |
+
* description: Product deleted
|
| 268 |
+
*/
|
| 269 |
app.delete("/api/products/:id", async (req, res) => {
|
| 270 |
try {
|
| 271 |
const sql = `DELETE FROM products WHERE id = ${req.params.id}`;
|
|
|
|
| 282 |
});
|
| 283 |
|
| 284 |
// Get all orders
|
| 285 |
+
/**
|
| 286 |
+
* @swagger
|
| 287 |
+
* /api/orders:
|
| 288 |
+
* get:
|
| 289 |
+
* summary: Get all orders
|
| 290 |
+
* description: Retrieve all orders from the database
|
| 291 |
+
* responses:
|
| 292 |
+
* 200:
|
| 293 |
+
* description: List of orders
|
| 294 |
+
*/
|
| 295 |
app.get("/api/orders", async (req, res) => {
|
| 296 |
try {
|
| 297 |
const result = await querySQLite(
|
|
|
|
| 306 |
});
|
| 307 |
|
| 308 |
// Create order
|
| 309 |
+
/**
|
| 310 |
+
* @swagger
|
| 311 |
+
* /api/orders:
|
| 312 |
+
* post:
|
| 313 |
+
* summary: Create a new order
|
| 314 |
+
* description: Add a new order to the database
|
| 315 |
+
* requestBody:
|
| 316 |
+
* required: true
|
| 317 |
+
* content:
|
| 318 |
+
* application/json:
|
| 319 |
+
* schema:
|
| 320 |
+
* type: object
|
| 321 |
+
* properties:
|
| 322 |
+
* customer_name:
|
| 323 |
+
* type: string
|
| 324 |
+
* total:
|
| 325 |
+
* type: number
|
| 326 |
+
* status:
|
| 327 |
+
* type: string
|
| 328 |
+
* responses:
|
| 329 |
+
* 201:
|
| 330 |
+
* description: Order created
|
| 331 |
+
*/
|
| 332 |
app.post("/api/orders", async (req, res) => {
|
| 333 |
try {
|
| 334 |
const { customer_name, total, status } = req.body;
|
|
|
|
| 353 |
});
|
| 354 |
|
| 355 |
// Get database info
|
| 356 |
+
/**
|
| 357 |
+
* @swagger
|
| 358 |
+
* /api/info:
|
| 359 |
+
* get:
|
| 360 |
+
* summary: Get database info
|
| 361 |
+
* description: Retrieve database schema and server information
|
| 362 |
+
* responses:
|
| 363 |
+
* 200:
|
| 364 |
+
* description: Database information
|
| 365 |
+
*/
|
| 366 |
app.get("/api/info", async (req, res) => {
|
| 367 |
try {
|
| 368 |
const response = await axios.get(
|