├── .gitignore
├── README.md
├── assets
└── banner.png
├── plantilla-node-express
├── package-lock.json
├── package.json
└── src
│ └── index.js
├── plantilla-react-base
├── .gitignore
├── README.md
├── eslint.config.js
├── index.html
├── package-lock.json
├── package.json
├── public
│ └── vite.svg
├── src
│ ├── App.css
│ ├── App.jsx
│ ├── assets
│ │ └── react.svg
│ ├── index.css
│ └── main.jsx
└── vite.config.js
├── prueba-axios
├── .gitignore
├── Desafios_Dominar_Axios.pdf
├── README.md
├── Retos_Axios_Endpoints_Reales.pdf
├── eslint.config.js
├── index.html
├── package-lock.json
├── package.json
├── public
│ └── vite.svg
├── src
│ ├── App.css
│ ├── App.jsx
│ ├── assets
│ │ └── react.svg
│ ├── index.css
│ └── main.jsx
└── vite.config.js
├── prueba-final
├── .gitignore
├── Guia_Consumo_API_Productos.pdf
├── README.md
├── eslint.config.js
├── index.html
├── package-lock.json
├── package.json
├── public
│ └── vite.svg
├── src
│ ├── App.css
│ ├── App.jsx
│ ├── assets
│ │ └── react.svg
│ ├── index.css
│ └── main.jsx
└── vite.config.js
├── prueba1-formulario-registro
├── .gitignore
├── README.md
├── eslint.config.js
├── index.html
├── package-lock.json
├── package.json
├── public
│ └── vite.svg
├── src
│ ├── App.css
│ ├── App.jsx
│ ├── assets
│ │ └── react.svg
│ ├── index.css
│ └── main.jsx
└── vite.config.js
├── prueba2-api-productos
├── README.md
├── package-lock.json
├── package.json
└── src
│ ├── controllers
│ └── productosController.js
│ ├── index.js
│ └── routes
│ └── productos.js
├── prueba3-tareas-zustand
├── .gitignore
├── README.md
├── eslint.config.js
├── index.html
├── package-lock.json
├── package.json
├── public
│ └── vite.svg
├── src
│ ├── App.css
│ ├── App.jsx
│ ├── assets
│ │ └── react.svg
│ ├── index.css
│ ├── main.jsx
│ └── store
│ │ └── tareas.jsx
└── vite.config.js
└── prueba4-postgreSql
├── README.md
├── package-lock.json
├── package.json
└── src
├── controllers
└── productosController.js
├── db
└── db.js
├── index.js
└── routes
└── productos.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # Node.js dependencies
2 | node_modules/
3 | npm-debug.log*
4 | yarn-debug.log*
5 | yarn-error.log*
6 |
7 | # Logs
8 | logs/
9 | *.log
10 | *.log.*
11 |
12 | # Environment variables
13 | .env
14 |
15 | # Build outputs
16 | dist/
17 | build/
18 |
19 | # System files
20 | .DS_Store
21 | Thumbs.db
22 |
23 | # IDE files
24 | .vscode/
25 | .idea/
26 | *.iml
27 |
28 | # Temporary files
29 | *.tmp
30 | *.swp
31 | *.swo
32 | *.bak
33 |
34 | # Coverage reports
35 | coverage/
36 |
37 | # Miscellaneous
38 | *.out
39 | *.lock
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohanBoDev/mini-pruebas-fullstack/ecbbae8fe61f7dd6d52f1fb23641461beaf3385e/README.md
--------------------------------------------------------------------------------
/assets/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohanBoDev/mini-pruebas-fullstack/ecbbae8fe61f7dd6d52f1fb23641461beaf3385e/assets/banner.png
--------------------------------------------------------------------------------
/plantilla-node-express/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "plantilla-node-express",
3 | "version": "1.0.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "plantilla-node-express",
9 | "version": "1.0.0",
10 | "license": "ISC",
11 | "dependencies": {
12 | "cors": "^2.8.5",
13 | "dotenv": "^16.5.0",
14 | "express": "^5.1.0",
15 | "nodemon": "^3.1.9"
16 | }
17 | },
18 | "node_modules/accepts": {
19 | "version": "2.0.0",
20 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
21 | "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
22 | "dependencies": {
23 | "mime-types": "^3.0.0",
24 | "negotiator": "^1.0.0"
25 | },
26 | "engines": {
27 | "node": ">= 0.6"
28 | }
29 | },
30 | "node_modules/anymatch": {
31 | "version": "3.1.3",
32 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
33 | "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
34 | "dependencies": {
35 | "normalize-path": "^3.0.0",
36 | "picomatch": "^2.0.4"
37 | },
38 | "engines": {
39 | "node": ">= 8"
40 | }
41 | },
42 | "node_modules/balanced-match": {
43 | "version": "1.0.2",
44 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
45 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
46 | },
47 | "node_modules/binary-extensions": {
48 | "version": "2.3.0",
49 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
50 | "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
51 | "engines": {
52 | "node": ">=8"
53 | },
54 | "funding": {
55 | "url": "https://github.com/sponsors/sindresorhus"
56 | }
57 | },
58 | "node_modules/body-parser": {
59 | "version": "2.2.0",
60 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
61 | "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
62 | "dependencies": {
63 | "bytes": "^3.1.2",
64 | "content-type": "^1.0.5",
65 | "debug": "^4.4.0",
66 | "http-errors": "^2.0.0",
67 | "iconv-lite": "^0.6.3",
68 | "on-finished": "^2.4.1",
69 | "qs": "^6.14.0",
70 | "raw-body": "^3.0.0",
71 | "type-is": "^2.0.0"
72 | },
73 | "engines": {
74 | "node": ">=18"
75 | }
76 | },
77 | "node_modules/brace-expansion": {
78 | "version": "1.1.11",
79 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
80 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
81 | "dependencies": {
82 | "balanced-match": "^1.0.0",
83 | "concat-map": "0.0.1"
84 | }
85 | },
86 | "node_modules/braces": {
87 | "version": "3.0.3",
88 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
89 | "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
90 | "dependencies": {
91 | "fill-range": "^7.1.1"
92 | },
93 | "engines": {
94 | "node": ">=8"
95 | }
96 | },
97 | "node_modules/bytes": {
98 | "version": "3.1.2",
99 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
100 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
101 | "engines": {
102 | "node": ">= 0.8"
103 | }
104 | },
105 | "node_modules/call-bind-apply-helpers": {
106 | "version": "1.0.2",
107 | "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
108 | "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
109 | "dependencies": {
110 | "es-errors": "^1.3.0",
111 | "function-bind": "^1.1.2"
112 | },
113 | "engines": {
114 | "node": ">= 0.4"
115 | }
116 | },
117 | "node_modules/call-bound": {
118 | "version": "1.0.4",
119 | "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
120 | "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
121 | "dependencies": {
122 | "call-bind-apply-helpers": "^1.0.2",
123 | "get-intrinsic": "^1.3.0"
124 | },
125 | "engines": {
126 | "node": ">= 0.4"
127 | },
128 | "funding": {
129 | "url": "https://github.com/sponsors/ljharb"
130 | }
131 | },
132 | "node_modules/chokidar": {
133 | "version": "3.6.0",
134 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
135 | "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
136 | "dependencies": {
137 | "anymatch": "~3.1.2",
138 | "braces": "~3.0.2",
139 | "glob-parent": "~5.1.2",
140 | "is-binary-path": "~2.1.0",
141 | "is-glob": "~4.0.1",
142 | "normalize-path": "~3.0.0",
143 | "readdirp": "~3.6.0"
144 | },
145 | "engines": {
146 | "node": ">= 8.10.0"
147 | },
148 | "funding": {
149 | "url": "https://paulmillr.com/funding/"
150 | },
151 | "optionalDependencies": {
152 | "fsevents": "~2.3.2"
153 | }
154 | },
155 | "node_modules/concat-map": {
156 | "version": "0.0.1",
157 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
158 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
159 | },
160 | "node_modules/content-disposition": {
161 | "version": "1.0.0",
162 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
163 | "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==",
164 | "dependencies": {
165 | "safe-buffer": "5.2.1"
166 | },
167 | "engines": {
168 | "node": ">= 0.6"
169 | }
170 | },
171 | "node_modules/content-type": {
172 | "version": "1.0.5",
173 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
174 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
175 | "engines": {
176 | "node": ">= 0.6"
177 | }
178 | },
179 | "node_modules/cookie": {
180 | "version": "0.7.2",
181 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
182 | "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
183 | "engines": {
184 | "node": ">= 0.6"
185 | }
186 | },
187 | "node_modules/cookie-signature": {
188 | "version": "1.2.2",
189 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
190 | "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
191 | "engines": {
192 | "node": ">=6.6.0"
193 | }
194 | },
195 | "node_modules/cors": {
196 | "version": "2.8.5",
197 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
198 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
199 | "dependencies": {
200 | "object-assign": "^4",
201 | "vary": "^1"
202 | },
203 | "engines": {
204 | "node": ">= 0.10"
205 | }
206 | },
207 | "node_modules/debug": {
208 | "version": "4.4.0",
209 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
210 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
211 | "dependencies": {
212 | "ms": "^2.1.3"
213 | },
214 | "engines": {
215 | "node": ">=6.0"
216 | },
217 | "peerDependenciesMeta": {
218 | "supports-color": {
219 | "optional": true
220 | }
221 | }
222 | },
223 | "node_modules/depd": {
224 | "version": "2.0.0",
225 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
226 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
227 | "engines": {
228 | "node": ">= 0.8"
229 | }
230 | },
231 | "node_modules/dotenv": {
232 | "version": "16.5.0",
233 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz",
234 | "integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==",
235 | "engines": {
236 | "node": ">=12"
237 | },
238 | "funding": {
239 | "url": "https://dotenvx.com"
240 | }
241 | },
242 | "node_modules/dunder-proto": {
243 | "version": "1.0.1",
244 | "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
245 | "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
246 | "dependencies": {
247 | "call-bind-apply-helpers": "^1.0.1",
248 | "es-errors": "^1.3.0",
249 | "gopd": "^1.2.0"
250 | },
251 | "engines": {
252 | "node": ">= 0.4"
253 | }
254 | },
255 | "node_modules/ee-first": {
256 | "version": "1.1.1",
257 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
258 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
259 | },
260 | "node_modules/encodeurl": {
261 | "version": "2.0.0",
262 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
263 | "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
264 | "engines": {
265 | "node": ">= 0.8"
266 | }
267 | },
268 | "node_modules/es-define-property": {
269 | "version": "1.0.1",
270 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
271 | "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
272 | "engines": {
273 | "node": ">= 0.4"
274 | }
275 | },
276 | "node_modules/es-errors": {
277 | "version": "1.3.0",
278 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
279 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
280 | "engines": {
281 | "node": ">= 0.4"
282 | }
283 | },
284 | "node_modules/es-object-atoms": {
285 | "version": "1.1.1",
286 | "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
287 | "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
288 | "dependencies": {
289 | "es-errors": "^1.3.0"
290 | },
291 | "engines": {
292 | "node": ">= 0.4"
293 | }
294 | },
295 | "node_modules/escape-html": {
296 | "version": "1.0.3",
297 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
298 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
299 | },
300 | "node_modules/etag": {
301 | "version": "1.8.1",
302 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
303 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
304 | "engines": {
305 | "node": ">= 0.6"
306 | }
307 | },
308 | "node_modules/express": {
309 | "version": "5.1.0",
310 | "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz",
311 | "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==",
312 | "dependencies": {
313 | "accepts": "^2.0.0",
314 | "body-parser": "^2.2.0",
315 | "content-disposition": "^1.0.0",
316 | "content-type": "^1.0.5",
317 | "cookie": "^0.7.1",
318 | "cookie-signature": "^1.2.1",
319 | "debug": "^4.4.0",
320 | "encodeurl": "^2.0.0",
321 | "escape-html": "^1.0.3",
322 | "etag": "^1.8.1",
323 | "finalhandler": "^2.1.0",
324 | "fresh": "^2.0.0",
325 | "http-errors": "^2.0.0",
326 | "merge-descriptors": "^2.0.0",
327 | "mime-types": "^3.0.0",
328 | "on-finished": "^2.4.1",
329 | "once": "^1.4.0",
330 | "parseurl": "^1.3.3",
331 | "proxy-addr": "^2.0.7",
332 | "qs": "^6.14.0",
333 | "range-parser": "^1.2.1",
334 | "router": "^2.2.0",
335 | "send": "^1.1.0",
336 | "serve-static": "^2.2.0",
337 | "statuses": "^2.0.1",
338 | "type-is": "^2.0.1",
339 | "vary": "^1.1.2"
340 | },
341 | "engines": {
342 | "node": ">= 18"
343 | },
344 | "funding": {
345 | "type": "opencollective",
346 | "url": "https://opencollective.com/express"
347 | }
348 | },
349 | "node_modules/fill-range": {
350 | "version": "7.1.1",
351 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
352 | "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
353 | "dependencies": {
354 | "to-regex-range": "^5.0.1"
355 | },
356 | "engines": {
357 | "node": ">=8"
358 | }
359 | },
360 | "node_modules/finalhandler": {
361 | "version": "2.1.0",
362 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
363 | "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==",
364 | "dependencies": {
365 | "debug": "^4.4.0",
366 | "encodeurl": "^2.0.0",
367 | "escape-html": "^1.0.3",
368 | "on-finished": "^2.4.1",
369 | "parseurl": "^1.3.3",
370 | "statuses": "^2.0.1"
371 | },
372 | "engines": {
373 | "node": ">= 0.8"
374 | }
375 | },
376 | "node_modules/forwarded": {
377 | "version": "0.2.0",
378 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
379 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
380 | "engines": {
381 | "node": ">= 0.6"
382 | }
383 | },
384 | "node_modules/fresh": {
385 | "version": "2.0.0",
386 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
387 | "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
388 | "engines": {
389 | "node": ">= 0.8"
390 | }
391 | },
392 | "node_modules/fsevents": {
393 | "version": "2.3.3",
394 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
395 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
396 | "hasInstallScript": true,
397 | "optional": true,
398 | "os": [
399 | "darwin"
400 | ],
401 | "engines": {
402 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
403 | }
404 | },
405 | "node_modules/function-bind": {
406 | "version": "1.1.2",
407 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
408 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
409 | "funding": {
410 | "url": "https://github.com/sponsors/ljharb"
411 | }
412 | },
413 | "node_modules/get-intrinsic": {
414 | "version": "1.3.0",
415 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
416 | "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
417 | "dependencies": {
418 | "call-bind-apply-helpers": "^1.0.2",
419 | "es-define-property": "^1.0.1",
420 | "es-errors": "^1.3.0",
421 | "es-object-atoms": "^1.1.1",
422 | "function-bind": "^1.1.2",
423 | "get-proto": "^1.0.1",
424 | "gopd": "^1.2.0",
425 | "has-symbols": "^1.1.0",
426 | "hasown": "^2.0.2",
427 | "math-intrinsics": "^1.1.0"
428 | },
429 | "engines": {
430 | "node": ">= 0.4"
431 | },
432 | "funding": {
433 | "url": "https://github.com/sponsors/ljharb"
434 | }
435 | },
436 | "node_modules/get-proto": {
437 | "version": "1.0.1",
438 | "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
439 | "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
440 | "dependencies": {
441 | "dunder-proto": "^1.0.1",
442 | "es-object-atoms": "^1.0.0"
443 | },
444 | "engines": {
445 | "node": ">= 0.4"
446 | }
447 | },
448 | "node_modules/glob-parent": {
449 | "version": "5.1.2",
450 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
451 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
452 | "dependencies": {
453 | "is-glob": "^4.0.1"
454 | },
455 | "engines": {
456 | "node": ">= 6"
457 | }
458 | },
459 | "node_modules/gopd": {
460 | "version": "1.2.0",
461 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
462 | "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
463 | "engines": {
464 | "node": ">= 0.4"
465 | },
466 | "funding": {
467 | "url": "https://github.com/sponsors/ljharb"
468 | }
469 | },
470 | "node_modules/has-flag": {
471 | "version": "3.0.0",
472 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
473 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
474 | "engines": {
475 | "node": ">=4"
476 | }
477 | },
478 | "node_modules/has-symbols": {
479 | "version": "1.1.0",
480 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
481 | "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
482 | "engines": {
483 | "node": ">= 0.4"
484 | },
485 | "funding": {
486 | "url": "https://github.com/sponsors/ljharb"
487 | }
488 | },
489 | "node_modules/hasown": {
490 | "version": "2.0.2",
491 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
492 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
493 | "dependencies": {
494 | "function-bind": "^1.1.2"
495 | },
496 | "engines": {
497 | "node": ">= 0.4"
498 | }
499 | },
500 | "node_modules/http-errors": {
501 | "version": "2.0.0",
502 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
503 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
504 | "dependencies": {
505 | "depd": "2.0.0",
506 | "inherits": "2.0.4",
507 | "setprototypeof": "1.2.0",
508 | "statuses": "2.0.1",
509 | "toidentifier": "1.0.1"
510 | },
511 | "engines": {
512 | "node": ">= 0.8"
513 | }
514 | },
515 | "node_modules/iconv-lite": {
516 | "version": "0.6.3",
517 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
518 | "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
519 | "dependencies": {
520 | "safer-buffer": ">= 2.1.2 < 3.0.0"
521 | },
522 | "engines": {
523 | "node": ">=0.10.0"
524 | }
525 | },
526 | "node_modules/ignore-by-default": {
527 | "version": "1.0.1",
528 | "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
529 | "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA=="
530 | },
531 | "node_modules/inherits": {
532 | "version": "2.0.4",
533 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
534 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
535 | },
536 | "node_modules/ipaddr.js": {
537 | "version": "1.9.1",
538 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
539 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
540 | "engines": {
541 | "node": ">= 0.10"
542 | }
543 | },
544 | "node_modules/is-binary-path": {
545 | "version": "2.1.0",
546 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
547 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
548 | "dependencies": {
549 | "binary-extensions": "^2.0.0"
550 | },
551 | "engines": {
552 | "node": ">=8"
553 | }
554 | },
555 | "node_modules/is-extglob": {
556 | "version": "2.1.1",
557 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
558 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
559 | "engines": {
560 | "node": ">=0.10.0"
561 | }
562 | },
563 | "node_modules/is-glob": {
564 | "version": "4.0.3",
565 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
566 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
567 | "dependencies": {
568 | "is-extglob": "^2.1.1"
569 | },
570 | "engines": {
571 | "node": ">=0.10.0"
572 | }
573 | },
574 | "node_modules/is-number": {
575 | "version": "7.0.0",
576 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
577 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
578 | "engines": {
579 | "node": ">=0.12.0"
580 | }
581 | },
582 | "node_modules/is-promise": {
583 | "version": "4.0.0",
584 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
585 | "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="
586 | },
587 | "node_modules/math-intrinsics": {
588 | "version": "1.1.0",
589 | "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
590 | "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
591 | "engines": {
592 | "node": ">= 0.4"
593 | }
594 | },
595 | "node_modules/media-typer": {
596 | "version": "1.1.0",
597 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
598 | "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
599 | "engines": {
600 | "node": ">= 0.8"
601 | }
602 | },
603 | "node_modules/merge-descriptors": {
604 | "version": "2.0.0",
605 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
606 | "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
607 | "engines": {
608 | "node": ">=18"
609 | },
610 | "funding": {
611 | "url": "https://github.com/sponsors/sindresorhus"
612 | }
613 | },
614 | "node_modules/mime-db": {
615 | "version": "1.54.0",
616 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
617 | "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
618 | "engines": {
619 | "node": ">= 0.6"
620 | }
621 | },
622 | "node_modules/mime-types": {
623 | "version": "3.0.1",
624 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
625 | "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
626 | "dependencies": {
627 | "mime-db": "^1.54.0"
628 | },
629 | "engines": {
630 | "node": ">= 0.6"
631 | }
632 | },
633 | "node_modules/minimatch": {
634 | "version": "3.1.2",
635 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
636 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
637 | "dependencies": {
638 | "brace-expansion": "^1.1.7"
639 | },
640 | "engines": {
641 | "node": "*"
642 | }
643 | },
644 | "node_modules/ms": {
645 | "version": "2.1.3",
646 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
647 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
648 | },
649 | "node_modules/negotiator": {
650 | "version": "1.0.0",
651 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
652 | "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
653 | "engines": {
654 | "node": ">= 0.6"
655 | }
656 | },
657 | "node_modules/nodemon": {
658 | "version": "3.1.9",
659 | "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.9.tgz",
660 | "integrity": "sha512-hdr1oIb2p6ZSxu3PB2JWWYS7ZQ0qvaZsc3hK8DR8f02kRzc8rjYmxAIvdz+aYC+8F2IjNaB7HMcSDg8nQpJxyg==",
661 | "dependencies": {
662 | "chokidar": "^3.5.2",
663 | "debug": "^4",
664 | "ignore-by-default": "^1.0.1",
665 | "minimatch": "^3.1.2",
666 | "pstree.remy": "^1.1.8",
667 | "semver": "^7.5.3",
668 | "simple-update-notifier": "^2.0.0",
669 | "supports-color": "^5.5.0",
670 | "touch": "^3.1.0",
671 | "undefsafe": "^2.0.5"
672 | },
673 | "bin": {
674 | "nodemon": "bin/nodemon.js"
675 | },
676 | "engines": {
677 | "node": ">=10"
678 | },
679 | "funding": {
680 | "type": "opencollective",
681 | "url": "https://opencollective.com/nodemon"
682 | }
683 | },
684 | "node_modules/normalize-path": {
685 | "version": "3.0.0",
686 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
687 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
688 | "engines": {
689 | "node": ">=0.10.0"
690 | }
691 | },
692 | "node_modules/object-assign": {
693 | "version": "4.1.1",
694 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
695 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
696 | "engines": {
697 | "node": ">=0.10.0"
698 | }
699 | },
700 | "node_modules/object-inspect": {
701 | "version": "1.13.4",
702 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
703 | "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
704 | "engines": {
705 | "node": ">= 0.4"
706 | },
707 | "funding": {
708 | "url": "https://github.com/sponsors/ljharb"
709 | }
710 | },
711 | "node_modules/on-finished": {
712 | "version": "2.4.1",
713 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
714 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
715 | "dependencies": {
716 | "ee-first": "1.1.1"
717 | },
718 | "engines": {
719 | "node": ">= 0.8"
720 | }
721 | },
722 | "node_modules/once": {
723 | "version": "1.4.0",
724 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
725 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
726 | "dependencies": {
727 | "wrappy": "1"
728 | }
729 | },
730 | "node_modules/parseurl": {
731 | "version": "1.3.3",
732 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
733 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
734 | "engines": {
735 | "node": ">= 0.8"
736 | }
737 | },
738 | "node_modules/path-to-regexp": {
739 | "version": "8.2.0",
740 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz",
741 | "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==",
742 | "engines": {
743 | "node": ">=16"
744 | }
745 | },
746 | "node_modules/picomatch": {
747 | "version": "2.3.1",
748 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
749 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
750 | "engines": {
751 | "node": ">=8.6"
752 | },
753 | "funding": {
754 | "url": "https://github.com/sponsors/jonschlinkert"
755 | }
756 | },
757 | "node_modules/proxy-addr": {
758 | "version": "2.0.7",
759 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
760 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
761 | "dependencies": {
762 | "forwarded": "0.2.0",
763 | "ipaddr.js": "1.9.1"
764 | },
765 | "engines": {
766 | "node": ">= 0.10"
767 | }
768 | },
769 | "node_modules/pstree.remy": {
770 | "version": "1.1.8",
771 | "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
772 | "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w=="
773 | },
774 | "node_modules/qs": {
775 | "version": "6.14.0",
776 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
777 | "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
778 | "dependencies": {
779 | "side-channel": "^1.1.0"
780 | },
781 | "engines": {
782 | "node": ">=0.6"
783 | },
784 | "funding": {
785 | "url": "https://github.com/sponsors/ljharb"
786 | }
787 | },
788 | "node_modules/range-parser": {
789 | "version": "1.2.1",
790 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
791 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
792 | "engines": {
793 | "node": ">= 0.6"
794 | }
795 | },
796 | "node_modules/raw-body": {
797 | "version": "3.0.0",
798 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
799 | "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
800 | "dependencies": {
801 | "bytes": "3.1.2",
802 | "http-errors": "2.0.0",
803 | "iconv-lite": "0.6.3",
804 | "unpipe": "1.0.0"
805 | },
806 | "engines": {
807 | "node": ">= 0.8"
808 | }
809 | },
810 | "node_modules/readdirp": {
811 | "version": "3.6.0",
812 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
813 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
814 | "dependencies": {
815 | "picomatch": "^2.2.1"
816 | },
817 | "engines": {
818 | "node": ">=8.10.0"
819 | }
820 | },
821 | "node_modules/router": {
822 | "version": "2.2.0",
823 | "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
824 | "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
825 | "dependencies": {
826 | "debug": "^4.4.0",
827 | "depd": "^2.0.0",
828 | "is-promise": "^4.0.0",
829 | "parseurl": "^1.3.3",
830 | "path-to-regexp": "^8.0.0"
831 | },
832 | "engines": {
833 | "node": ">= 18"
834 | }
835 | },
836 | "node_modules/safe-buffer": {
837 | "version": "5.2.1",
838 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
839 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
840 | "funding": [
841 | {
842 | "type": "github",
843 | "url": "https://github.com/sponsors/feross"
844 | },
845 | {
846 | "type": "patreon",
847 | "url": "https://www.patreon.com/feross"
848 | },
849 | {
850 | "type": "consulting",
851 | "url": "https://feross.org/support"
852 | }
853 | ]
854 | },
855 | "node_modules/safer-buffer": {
856 | "version": "2.1.2",
857 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
858 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
859 | },
860 | "node_modules/semver": {
861 | "version": "7.7.1",
862 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
863 | "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
864 | "bin": {
865 | "semver": "bin/semver.js"
866 | },
867 | "engines": {
868 | "node": ">=10"
869 | }
870 | },
871 | "node_modules/send": {
872 | "version": "1.2.0",
873 | "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
874 | "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
875 | "dependencies": {
876 | "debug": "^4.3.5",
877 | "encodeurl": "^2.0.0",
878 | "escape-html": "^1.0.3",
879 | "etag": "^1.8.1",
880 | "fresh": "^2.0.0",
881 | "http-errors": "^2.0.0",
882 | "mime-types": "^3.0.1",
883 | "ms": "^2.1.3",
884 | "on-finished": "^2.4.1",
885 | "range-parser": "^1.2.1",
886 | "statuses": "^2.0.1"
887 | },
888 | "engines": {
889 | "node": ">= 18"
890 | }
891 | },
892 | "node_modules/serve-static": {
893 | "version": "2.2.0",
894 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
895 | "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
896 | "dependencies": {
897 | "encodeurl": "^2.0.0",
898 | "escape-html": "^1.0.3",
899 | "parseurl": "^1.3.3",
900 | "send": "^1.2.0"
901 | },
902 | "engines": {
903 | "node": ">= 18"
904 | }
905 | },
906 | "node_modules/setprototypeof": {
907 | "version": "1.2.0",
908 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
909 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
910 | },
911 | "node_modules/side-channel": {
912 | "version": "1.1.0",
913 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
914 | "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
915 | "dependencies": {
916 | "es-errors": "^1.3.0",
917 | "object-inspect": "^1.13.3",
918 | "side-channel-list": "^1.0.0",
919 | "side-channel-map": "^1.0.1",
920 | "side-channel-weakmap": "^1.0.2"
921 | },
922 | "engines": {
923 | "node": ">= 0.4"
924 | },
925 | "funding": {
926 | "url": "https://github.com/sponsors/ljharb"
927 | }
928 | },
929 | "node_modules/side-channel-list": {
930 | "version": "1.0.0",
931 | "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
932 | "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
933 | "dependencies": {
934 | "es-errors": "^1.3.0",
935 | "object-inspect": "^1.13.3"
936 | },
937 | "engines": {
938 | "node": ">= 0.4"
939 | },
940 | "funding": {
941 | "url": "https://github.com/sponsors/ljharb"
942 | }
943 | },
944 | "node_modules/side-channel-map": {
945 | "version": "1.0.1",
946 | "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
947 | "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
948 | "dependencies": {
949 | "call-bound": "^1.0.2",
950 | "es-errors": "^1.3.0",
951 | "get-intrinsic": "^1.2.5",
952 | "object-inspect": "^1.13.3"
953 | },
954 | "engines": {
955 | "node": ">= 0.4"
956 | },
957 | "funding": {
958 | "url": "https://github.com/sponsors/ljharb"
959 | }
960 | },
961 | "node_modules/side-channel-weakmap": {
962 | "version": "1.0.2",
963 | "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
964 | "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
965 | "dependencies": {
966 | "call-bound": "^1.0.2",
967 | "es-errors": "^1.3.0",
968 | "get-intrinsic": "^1.2.5",
969 | "object-inspect": "^1.13.3",
970 | "side-channel-map": "^1.0.1"
971 | },
972 | "engines": {
973 | "node": ">= 0.4"
974 | },
975 | "funding": {
976 | "url": "https://github.com/sponsors/ljharb"
977 | }
978 | },
979 | "node_modules/simple-update-notifier": {
980 | "version": "2.0.0",
981 | "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz",
982 | "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==",
983 | "dependencies": {
984 | "semver": "^7.5.3"
985 | },
986 | "engines": {
987 | "node": ">=10"
988 | }
989 | },
990 | "node_modules/statuses": {
991 | "version": "2.0.1",
992 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
993 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
994 | "engines": {
995 | "node": ">= 0.8"
996 | }
997 | },
998 | "node_modules/supports-color": {
999 | "version": "5.5.0",
1000 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
1001 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
1002 | "dependencies": {
1003 | "has-flag": "^3.0.0"
1004 | },
1005 | "engines": {
1006 | "node": ">=4"
1007 | }
1008 | },
1009 | "node_modules/to-regex-range": {
1010 | "version": "5.0.1",
1011 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
1012 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
1013 | "dependencies": {
1014 | "is-number": "^7.0.0"
1015 | },
1016 | "engines": {
1017 | "node": ">=8.0"
1018 | }
1019 | },
1020 | "node_modules/toidentifier": {
1021 | "version": "1.0.1",
1022 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
1023 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
1024 | "engines": {
1025 | "node": ">=0.6"
1026 | }
1027 | },
1028 | "node_modules/touch": {
1029 | "version": "3.1.1",
1030 | "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz",
1031 | "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==",
1032 | "bin": {
1033 | "nodetouch": "bin/nodetouch.js"
1034 | }
1035 | },
1036 | "node_modules/type-is": {
1037 | "version": "2.0.1",
1038 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
1039 | "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
1040 | "dependencies": {
1041 | "content-type": "^1.0.5",
1042 | "media-typer": "^1.1.0",
1043 | "mime-types": "^3.0.0"
1044 | },
1045 | "engines": {
1046 | "node": ">= 0.6"
1047 | }
1048 | },
1049 | "node_modules/undefsafe": {
1050 | "version": "2.0.5",
1051 | "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
1052 | "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA=="
1053 | },
1054 | "node_modules/unpipe": {
1055 | "version": "1.0.0",
1056 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
1057 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
1058 | "engines": {
1059 | "node": ">= 0.8"
1060 | }
1061 | },
1062 | "node_modules/vary": {
1063 | "version": "1.1.2",
1064 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
1065 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
1066 | "engines": {
1067 | "node": ">= 0.8"
1068 | }
1069 | },
1070 | "node_modules/wrappy": {
1071 | "version": "1.0.2",
1072 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1073 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
1074 | }
1075 | }
1076 | }
1077 |
--------------------------------------------------------------------------------
/plantilla-node-express/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "plantilla-node-express",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "type": "module",
6 |
7 | "scripts": {
8 | "dev": "nodemon src/index.js"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "ISC",
13 | "description": "",
14 | "dependencies": {
15 | "cors": "^2.8.5",
16 | "dotenv": "^16.5.0",
17 | "express": "^5.1.0",
18 | "nodemon": "^3.1.9"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/plantilla-node-express/src/index.js:
--------------------------------------------------------------------------------
1 | // src/index.js
2 | import express from "express";
3 | import cors from "cors";
4 | import dotenv from "dotenv";
5 |
6 | dotenv.config();
7 |
8 | const app = express();
9 | app.use(cors());
10 | app.use(express.json());
11 |
12 | app.get("/", (req, res) => {
13 | res.send("API funcionando 🚀");
14 | });
15 |
16 | const PORT = process.env.PORT || 3000;
17 | app.listen(PORT, () => {
18 | console.log(`Servidor corriendo en http://localhost:${PORT}`);
19 | });
20 |
--------------------------------------------------------------------------------
/plantilla-react-base/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/plantilla-react-base/README.md:
--------------------------------------------------------------------------------
1 | # React + Vite
2 |
3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4 |
5 | Currently, two official plugins are available:
6 |
7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh
8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9 |
10 | ## Expanding the ESLint configuration
11 |
12 | If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project.
13 |
--------------------------------------------------------------------------------
/plantilla-react-base/eslint.config.js:
--------------------------------------------------------------------------------
1 | import js from '@eslint/js'
2 | import globals from 'globals'
3 | import reactHooks from 'eslint-plugin-react-hooks'
4 | import reactRefresh from 'eslint-plugin-react-refresh'
5 |
6 | export default [
7 | { ignores: ['dist'] },
8 | {
9 | files: ['**/*.{js,jsx}'],
10 | languageOptions: {
11 | ecmaVersion: 2020,
12 | globals: globals.browser,
13 | parserOptions: {
14 | ecmaVersion: 'latest',
15 | ecmaFeatures: { jsx: true },
16 | sourceType: 'module',
17 | },
18 | },
19 | plugins: {
20 | 'react-hooks': reactHooks,
21 | 'react-refresh': reactRefresh,
22 | },
23 | rules: {
24 | ...js.configs.recommended.rules,
25 | ...reactHooks.configs.recommended.rules,
26 | 'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
27 | 'react-refresh/only-export-components': [
28 | 'warn',
29 | { allowConstantExport: true },
30 | ],
31 | },
32 | },
33 | ]
34 |
--------------------------------------------------------------------------------
/plantilla-react-base/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + React
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/plantilla-react-base/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "plantilla-react-base",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "lint": "eslint .",
10 | "preview": "vite preview"
11 | },
12 | "dependencies": {
13 | "@chakra-ui/react": "^2.10.7",
14 | "@emotion/react": "^11.14.0",
15 | "@emotion/styled": "^11.14.0",
16 | "@tailwindcss/postcss": "^4.1.4",
17 | "framer-motion": "^12.7.4",
18 | "react": "^19.0.0",
19 | "react-dom": "^19.0.0",
20 | "react-hook-form": "^7.56.1",
21 | "react-icons": "^5.5.0",
22 | "zustand": "^5.0.3"
23 | },
24 | "devDependencies": {
25 | "@eslint/js": "^9.22.0",
26 | "@tailwindcss/vite": "^4.1.4",
27 | "@types/react": "^19.0.10",
28 | "@types/react-dom": "^19.0.4",
29 | "@vitejs/plugin-react": "^4.3.4",
30 | "autoprefixer": "^10.4.21",
31 | "eslint": "^9.22.0",
32 | "eslint-plugin-react-hooks": "^5.2.0",
33 | "eslint-plugin-react-refresh": "^0.4.19",
34 | "globals": "^16.0.0",
35 | "postcss": "^8.5.3",
36 | "tailwindcss": "^4.1.4",
37 | "vite": "^6.3.1"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/plantilla-react-base/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/plantilla-react-base/src/App.css:
--------------------------------------------------------------------------------
1 | #root {
2 | max-width: 1280px;
3 | margin: 0 auto;
4 | padding: 2rem;
5 | text-align: center;
6 | }
7 |
8 | .logo {
9 | height: 6em;
10 | padding: 1.5em;
11 | will-change: filter;
12 | transition: filter 300ms;
13 | }
14 | .logo:hover {
15 | filter: drop-shadow(0 0 2em #646cffaa);
16 | }
17 | .logo.react:hover {
18 | filter: drop-shadow(0 0 2em #61dafbaa);
19 | }
20 |
21 | @keyframes logo-spin {
22 | from {
23 | transform: rotate(0deg);
24 | }
25 | to {
26 | transform: rotate(360deg);
27 | }
28 | }
29 |
30 | @media (prefers-reduced-motion: no-preference) {
31 | a:nth-of-type(2) .logo {
32 | animation: logo-spin infinite 20s linear;
33 | }
34 | }
35 |
36 | .card {
37 | padding: 2em;
38 | }
39 |
40 | .read-the-docs {
41 | color: #888;
42 | }
43 |
--------------------------------------------------------------------------------
/plantilla-react-base/src/App.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from 'react'
2 | import reactLogo from './assets/react.svg'
3 | import viteLogo from '/vite.svg'
4 | import './App.css'
5 | import { Box, Text, Stack } from '@chakra-ui/react';
6 |
7 |
8 | function App() {
9 | const [count, setCount] = useState(0)
10 |
11 | return (
12 |
13 |
14 | Título en grande
15 |
16 |
17 |
18 | Caja 1
19 | Caja 2
20 |
21 |
22 | )
23 | }
24 |
25 | export default App
26 |
--------------------------------------------------------------------------------
/plantilla-react-base/src/assets/react.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/plantilla-react-base/src/index.css:
--------------------------------------------------------------------------------
1 | @import "tailwindcss";
2 |
--------------------------------------------------------------------------------
/plantilla-react-base/src/main.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom/client'
3 | import App from './App.jsx'
4 | import './index.css'
5 | import { ChakraProvider } from '@chakra-ui/react'
6 |
7 | ReactDOM.createRoot(document.getElementById('root')).render(
8 |
9 |
10 |
11 |
12 | ,
13 | )
14 |
--------------------------------------------------------------------------------
/plantilla-react-base/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 | import tailwindcss from "@tailwindcss/vite";
4 |
5 | // https://vitejs.dev/config/
6 | export default defineConfig({
7 | plugins: [react(), tailwindcss()],
8 | })
9 |
--------------------------------------------------------------------------------
/prueba-axios/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/prueba-axios/Desafios_Dominar_Axios.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohanBoDev/mini-pruebas-fullstack/ecbbae8fe61f7dd6d52f1fb23641461beaf3385e/prueba-axios/Desafios_Dominar_Axios.pdf
--------------------------------------------------------------------------------
/prueba-axios/README.md:
--------------------------------------------------------------------------------
1 | # React + Vite
2 |
3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4 |
5 | Currently, two official plugins are available:
6 |
7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh
8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9 |
10 | ## Expanding the ESLint configuration
11 |
12 | If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project.
13 |
--------------------------------------------------------------------------------
/prueba-axios/Retos_Axios_Endpoints_Reales.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohanBoDev/mini-pruebas-fullstack/ecbbae8fe61f7dd6d52f1fb23641461beaf3385e/prueba-axios/Retos_Axios_Endpoints_Reales.pdf
--------------------------------------------------------------------------------
/prueba-axios/eslint.config.js:
--------------------------------------------------------------------------------
1 | import js from '@eslint/js'
2 | import globals from 'globals'
3 | import reactHooks from 'eslint-plugin-react-hooks'
4 | import reactRefresh from 'eslint-plugin-react-refresh'
5 |
6 | export default [
7 | { ignores: ['dist'] },
8 | {
9 | files: ['**/*.{js,jsx}'],
10 | languageOptions: {
11 | ecmaVersion: 2020,
12 | globals: globals.browser,
13 | parserOptions: {
14 | ecmaVersion: 'latest',
15 | ecmaFeatures: { jsx: true },
16 | sourceType: 'module',
17 | },
18 | },
19 | plugins: {
20 | 'react-hooks': reactHooks,
21 | 'react-refresh': reactRefresh,
22 | },
23 | rules: {
24 | ...js.configs.recommended.rules,
25 | ...reactHooks.configs.recommended.rules,
26 | 'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
27 | 'react-refresh/only-export-components': [
28 | 'warn',
29 | { allowConstantExport: true },
30 | ],
31 | },
32 | },
33 | ]
34 |
--------------------------------------------------------------------------------
/prueba-axios/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + React
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/prueba-axios/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "plantilla-react-base",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "lint": "eslint .",
10 | "preview": "vite preview"
11 | },
12 | "dependencies": {
13 | "@chakra-ui/react": "^2.10.7",
14 | "@emotion/react": "^11.14.0",
15 | "@emotion/styled": "^11.14.0",
16 | "@tailwindcss/postcss": "^4.1.4",
17 | "axios": "^1.9.0",
18 | "framer-motion": "^12.7.4",
19 | "react": "^19.0.0",
20 | "react-dom": "^19.0.0",
21 | "react-hook-form": "^7.56.1",
22 | "react-icons": "^5.5.0",
23 | "zustand": "^5.0.3"
24 | },
25 | "devDependencies": {
26 | "@eslint/js": "^9.22.0",
27 | "@tailwindcss/vite": "^4.1.4",
28 | "@types/react": "^19.0.10",
29 | "@types/react-dom": "^19.0.4",
30 | "@vitejs/plugin-react": "^4.3.4",
31 | "autoprefixer": "^10.4.21",
32 | "eslint": "^9.22.0",
33 | "eslint-plugin-react-hooks": "^5.2.0",
34 | "eslint-plugin-react-refresh": "^0.4.19",
35 | "globals": "^16.0.0",
36 | "postcss": "^8.5.3",
37 | "tailwindcss": "^4.1.4",
38 | "vite": "^6.3.1"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/prueba-axios/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/prueba-axios/src/App.css:
--------------------------------------------------------------------------------
1 | #root {
2 | max-width: 1280px;
3 | margin: 0 auto;
4 | padding: 2rem;
5 | text-align: center;
6 | }
7 |
8 | .logo {
9 | height: 6em;
10 | padding: 1.5em;
11 | will-change: filter;
12 | transition: filter 300ms;
13 | }
14 | .logo:hover {
15 | filter: drop-shadow(0 0 2em #646cffaa);
16 | }
17 | .logo.react:hover {
18 | filter: drop-shadow(0 0 2em #61dafbaa);
19 | }
20 |
21 | @keyframes logo-spin {
22 | from {
23 | transform: rotate(0deg);
24 | }
25 | to {
26 | transform: rotate(360deg);
27 | }
28 | }
29 |
30 | @media (prefers-reduced-motion: no-preference) {
31 | a:nth-of-type(2) .logo {
32 | animation: logo-spin infinite 20s linear;
33 | }
34 | }
35 |
36 | .card {
37 | padding: 2em;
38 | }
39 |
40 | .read-the-docs {
41 | color: #888;
42 | }
43 |
--------------------------------------------------------------------------------
/prueba-axios/src/App.jsx:
--------------------------------------------------------------------------------
1 | import { useState, useEffect, use } from 'react'
2 | import reactLogo from './assets/react.svg'
3 | import viteLogo from '/vite.svg'
4 | import './App.css'
5 | import axios from 'axios'
6 |
7 |
8 | function App() {
9 | const [lista, setLista] = useState([])
10 | const [title, setTitle] = useState("")
11 | const [body, setBody] = useState("")
12 | const [publicacion, setPublicacion] = useState([])
13 | const [id, setId] = useState(0)
14 | const [comentarios, setComentarios] = useState([])
15 |
16 | const obtenerUsuarios = async () => {
17 | try {
18 | const usuarios = await axios.get("https://jsonplaceholder.typicode.com/users")
19 | setLista(usuarios.data)
20 | } catch (error) {
21 | console.log(error.message)
22 | }
23 | }
24 |
25 | const obtenerPublicacion = async () => {
26 | try {
27 | const getPublicacion = await axios.get("https://jsonplaceholder.typicode.com/posts")
28 | setPublicacion(getPublicacion.data)
29 | } catch (error) {
30 | console.log(error.message)
31 | }
32 | }
33 |
34 | const actualizarPublicacion = async () => {
35 | try {
36 | const publicacionActualizada = await axios.put("https://jsonplaceholder.typicode.com/posts/1",
37 | {
38 | title: title
39 | }
40 | )
41 | console.log("Titulo actualziado correctamente")
42 | } catch (error) {
43 | console.log(error.message)
44 | }
45 |
46 | }
47 |
48 | const crearPublicacion = async () => {
49 | try {
50 | const publicacionCreada = await axios.post("https://jsonplaceholder.typicode.com/posts",
51 | {
52 | title: title,
53 | body: body,
54 | id: id
55 | }
56 | )
57 |
58 | console.log("Se creo correctamente")
59 | } catch (error) {
60 | console.log(error.message)
61 | }
62 | }
63 |
64 | const eliminarPublicacion = async () => {
65 | try {
66 | const eliminada = await axios.delete("https://jsonplaceholder.typicode.com/posts/1")
67 | alert("Publicacion eliminadad correctamente")
68 | setPublicacion(prev => prev.filter((p) => p.id !== 1));
69 | } catch (error) {
70 | console.log(error.message)
71 | }
72 | }
73 |
74 | const obtenerComentarios = async () => {
75 | try {
76 | const comentarios = await axios.get("https://jsonplaceholder.typicode.com/posts/1/comments")
77 | alert("Comentario obtenido")
78 | setComentarios(comentarios.data)
79 | } catch (error) {
80 | console.log(error.message)
81 | }
82 | }
83 |
84 | useEffect(() => {
85 | obtenerUsuarios();
86 | obtenerPublicacion();
87 | obtenerComentarios();
88 | }, [])
89 | return (
90 |
91 | {/* Formulario de la publicacion */}
92 |
103 | {/*Seccion de usuarios*/}
104 |
105 |
106 | {
107 | lista.map((usuario) => (
108 | -
109 |
{usuario.username}
110 | {usuario.email}
111 |
112 | ))
113 | }
114 |
115 |
116 | {/* Seccion de publicaciones */}
117 |
118 | Publicaciones
119 |
120 | {
121 | publicacion.map((p) => (
122 | -
123 |
{p.title}
{p.id}
124 |
125 | ))
126 | }
127 |
128 |
129 |
130 |
131 |
132 | {/* Formulario que actualiza el post*/}
133 |
138 |
139 | {/* Seccion de comentarios */}
140 |
141 | Comentarios
142 |
143 | {
144 | comentarios.map((c)=>(
145 | -
146 |
{c.name}
147 |
148 | ))
149 | }
150 |
151 |
152 |
153 |
154 |
155 | )
156 | }
157 |
158 | export default App
159 |
--------------------------------------------------------------------------------
/prueba-axios/src/assets/react.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/prueba-axios/src/index.css:
--------------------------------------------------------------------------------
1 | @import "tailwindcss";
2 |
--------------------------------------------------------------------------------
/prueba-axios/src/main.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom/client'
3 | import App from './App.jsx'
4 | import './index.css'
5 |
6 |
7 | ReactDOM.createRoot(document.getElementById('root')).render(
8 |
9 |
10 | ,
11 | )
12 |
--------------------------------------------------------------------------------
/prueba-axios/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 | import tailwindcss from "@tailwindcss/vite";
4 |
5 | // https://vitejs.dev/config/
6 | export default defineConfig({
7 | plugins: [react(), tailwindcss()],
8 | })
9 |
--------------------------------------------------------------------------------
/prueba-final/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/prueba-final/Guia_Consumo_API_Productos.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohanBoDev/mini-pruebas-fullstack/ecbbae8fe61f7dd6d52f1fb23641461beaf3385e/prueba-final/Guia_Consumo_API_Productos.pdf
--------------------------------------------------------------------------------
/prueba-final/README.md:
--------------------------------------------------------------------------------
1 | // 🔍 Obtener todos los productos
2 | http://localhost:3000/api/productos
3 |
4 | // 🔍 Obtener un producto por ID
5 | http://localhost:3000/api/productos/:id
6 |
7 | // 📝 Crear un nuevo producto
8 | http://localhost:3000/api/productos
9 |
10 | // ✏️ Actualizar un producto por ID
11 | http://localhost:3000/api/productos/:id
12 |
13 | // ❌ Eliminar un producto por ID
14 | http://localhost:3000/api/productos/:id
15 |
--------------------------------------------------------------------------------
/prueba-final/eslint.config.js:
--------------------------------------------------------------------------------
1 | import js from '@eslint/js'
2 | import globals from 'globals'
3 | import reactHooks from 'eslint-plugin-react-hooks'
4 | import reactRefresh from 'eslint-plugin-react-refresh'
5 |
6 | export default [
7 | { ignores: ['dist'] },
8 | {
9 | files: ['**/*.{js,jsx}'],
10 | languageOptions: {
11 | ecmaVersion: 2020,
12 | globals: globals.browser,
13 | parserOptions: {
14 | ecmaVersion: 'latest',
15 | ecmaFeatures: { jsx: true },
16 | sourceType: 'module',
17 | },
18 | },
19 | plugins: {
20 | 'react-hooks': reactHooks,
21 | 'react-refresh': reactRefresh,
22 | },
23 | rules: {
24 | ...js.configs.recommended.rules,
25 | ...reactHooks.configs.recommended.rules,
26 | 'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
27 | 'react-refresh/only-export-components': [
28 | 'warn',
29 | { allowConstantExport: true },
30 | ],
31 | },
32 | },
33 | ]
34 |
--------------------------------------------------------------------------------
/prueba-final/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + React
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/prueba-final/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "plantilla-react-base",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "lint": "eslint .",
10 | "preview": "vite preview"
11 | },
12 | "dependencies": {
13 | "@chakra-ui/react": "^2.10.7",
14 | "@emotion/react": "^11.14.0",
15 | "@emotion/styled": "^11.14.0",
16 | "@tailwindcss/postcss": "^4.1.4",
17 | "axios": "^1.9.0",
18 | "framer-motion": "^12.7.4",
19 | "react": "^19.0.0",
20 | "react-dom": "^19.0.0",
21 | "react-hook-form": "^7.56.1",
22 | "react-icons": "^5.5.0",
23 | "zustand": "^5.0.3"
24 | },
25 | "devDependencies": {
26 | "@eslint/js": "^9.22.0",
27 | "@tailwindcss/vite": "^4.1.4",
28 | "@types/react": "^19.0.10",
29 | "@types/react-dom": "^19.0.4",
30 | "@vitejs/plugin-react": "^4.3.4",
31 | "autoprefixer": "^10.4.21",
32 | "eslint": "^9.22.0",
33 | "eslint-plugin-react-hooks": "^5.2.0",
34 | "eslint-plugin-react-refresh": "^0.4.19",
35 | "globals": "^16.0.0",
36 | "postcss": "^8.5.3",
37 | "tailwindcss": "^4.1.4",
38 | "vite": "^6.3.1"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/prueba-final/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/prueba-final/src/App.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohanBoDev/mini-pruebas-fullstack/ecbbae8fe61f7dd6d52f1fb23641461beaf3385e/prueba-final/src/App.css
--------------------------------------------------------------------------------
/prueba-final/src/App.jsx:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from 'react'
2 | import axios from 'axios'
3 | import {
4 | Box,
5 | Heading,
6 | Text,
7 | Input,
8 | Button,
9 | Stack,
10 | SimpleGrid,
11 | Card,
12 | CardBody,
13 | CardHeader,
14 | useToast,
15 | Container
16 | } from '@chakra-ui/react'
17 |
18 | function App() {
19 | const [productos, setProductos] = useState([])
20 | const [producto, setProducto] = useState(null)
21 | const [nombre, setNombre] = useState("")
22 | const [precio, setPrecio] = useState(0)
23 | const [categoria, setCategoria] = useState("")
24 | const [id, setId] = useState("")
25 | const toast = useToast()
26 |
27 | const crearProducto = async () => {
28 | if (!nombre || !precio || !categoria) {
29 | toast({
30 | title: "Campos incompletos.",
31 | status: "warning",
32 | isClosable: true,
33 | })
34 | return;
35 | }
36 |
37 | try {
38 | const res = await axios.post("http://localhost:3000/api/productos", {
39 | nombre,
40 | precio,
41 | categoria
42 | })
43 |
44 | toast({
45 | title: "Producto creado.",
46 | description: `Se agregó ${res.data.nombre}`,
47 | status: "success",
48 | isClosable: true,
49 | })
50 |
51 | setNombre("")
52 | setPrecio(0)
53 | setCategoria("")
54 | obtenerProductos()
55 | } catch (error) {
56 | toast({
57 | title: "Error al crear producto.",
58 | description: error.message,
59 | status: "error",
60 | isClosable: true,
61 | })
62 | }
63 | }
64 |
65 | const eliminarProducto = async (id) => {
66 | try {
67 | await axios.delete(`http://localhost:3000/api/productos/${id}`)
68 | obtenerProductos()
69 | toast({
70 | title: "Producto eliminado.",
71 | status: "info",
72 | isClosable: true,
73 | })
74 | } catch (error) {
75 | toast({
76 | title: "Error al eliminar producto.",
77 | description: error.message,
78 | status: "error",
79 | isClosable: true,
80 | })
81 | }
82 | }
83 |
84 | const obtenerProductos = async () => {
85 | try {
86 | const res = await axios.get("http://localhost:3000/api/productos/")
87 | setProductos(res.data)
88 | } catch (error) {
89 | console.log(error.message)
90 | }
91 | }
92 |
93 | const obtenerProductoPorId = async (id) => {
94 | try {
95 | const res = await axios.get(`http://localhost:3000/api/productos/${id}`)
96 | setProducto(res.data)
97 | } catch (error) {
98 | setProducto(null)
99 | }
100 | }
101 |
102 | useEffect(() => {
103 | obtenerProductos()
104 | }, [])
105 |
106 | return (
107 |
108 |
109 |
110 | Todos los productos disponibles
111 |
112 |
113 | {productos.length > 0 ? (
114 |
115 | {productos.map((producto) => (
116 |
117 |
118 | {producto.nombre}
119 |
120 |
121 | Precio: ${producto.precio}
122 | Categoría: {producto.categoria}
123 |
132 |
133 |
134 | ))}
135 |
136 | ) : (
137 | No tienes productos todavía
138 | )}
139 |
140 |
141 |
142 | Crear producto
143 |
144 | setNombre(e.target.value)} />
145 | setPrecio(Number(e.target.value))} />
146 | setCategoria(e.target.value)} />
147 |
148 |
149 |
150 |
151 |
152 | Buscar por ID
153 |
159 |
160 |
161 |
162 | {producto ? (
163 |
164 | Producto encontrado
165 | Nombre: {producto.nombre}
166 | Precio: ${producto.precio}
167 |
168 | ) : (
169 |
170 | Producto no encontrado
171 |
172 | )}
173 |
174 |
175 |
176 |
177 | )
178 | }
179 |
180 | export default App
181 |
--------------------------------------------------------------------------------
/prueba-final/src/assets/react.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/prueba-final/src/index.css:
--------------------------------------------------------------------------------
1 | @import "tailwindcss";
2 |
--------------------------------------------------------------------------------
/prueba-final/src/main.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom/client'
3 | import App from './App.jsx'
4 | import './index.css'
5 | import { ChakraProvider } from '@chakra-ui/react'
6 |
7 |
8 | ReactDOM.createRoot(document.getElementById('root')).render(
9 |
10 |
11 |
12 |
13 |
14 | ,
15 | )
16 |
--------------------------------------------------------------------------------
/prueba-final/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 | import tailwindcss from "@tailwindcss/vite";
4 |
5 | // https://vitejs.dev/config/
6 | export default defineConfig({
7 | plugins: [react(), tailwindcss()],
8 | })
9 |
--------------------------------------------------------------------------------
/prueba1-formulario-registro/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/prueba1-formulario-registro/README.md:
--------------------------------------------------------------------------------
1 | # 🧪 Prueba 1 – Formulario de Registro con Validación (React + Tailwind)
2 |
3 | ## 📋 Descripción
4 |
5 | Esta prueba consiste en desarrollar un formulario de registro utilizando **React** y **Tailwind CSS**, aplicando validaciones para garantizar la calidad de los datos ingresados por el usuario.
6 |
7 | ---
8 |
9 | ## ✅ Requisitos funcionales
10 |
11 | - Crear un formulario con los siguientes campos:
12 | - **Nombre**
13 | - **Correo electrónico**
14 | - **Contraseña**
15 |
16 | - Aplicar validaciones:
17 | - El **correo electrónico** debe tener un formato válido.
18 | - La **contraseña** debe tener **mínimo 6 caracteres**.
19 | - Todos los campos deben ser obligatorios.
20 |
21 | - Mostrar mensajes de error claros si las validaciones fallan.
22 |
23 | ---
24 |
25 | ## 🎨 Requisitos de estilo
26 |
27 | - Utilizar **Tailwind CSS v4** para todo el diseño del formulario.
28 | - El formulario debe ser **responsive** y tener un diseño limpio.
29 | - Puede usarse **Chakra UI** opcionalmente para algunos componentes visuales (botones, inputs, etc.).
30 |
31 | ---
32 |
33 | ## 💡 Tecnologías permitidas
34 |
35 | - React + Vite
36 | - Tailwind CSS v4
37 | - Chakra UI (opcional)
38 | - Zustand (opcional si se quiere persistir el estado del usuario registrado)
39 |
40 | ---
41 |
42 | ## 🚀 Objetivo
43 |
44 | Crear un formulario funcional y visualmente agradable que valide correctamente los datos de entrada y pueda ser base para una futura autenticación o registro de usuarios.
45 |
46 | ---
47 |
48 |
49 | ## 📝 Notas
50 |
51 | - No es necesario conectarse a un backend en esta prueba.
52 | - El foco está en la validación, estructura y presentación del formulario.
53 |
--------------------------------------------------------------------------------
/prueba1-formulario-registro/eslint.config.js:
--------------------------------------------------------------------------------
1 | import js from '@eslint/js'
2 | import globals from 'globals'
3 | import reactHooks from 'eslint-plugin-react-hooks'
4 | import reactRefresh from 'eslint-plugin-react-refresh'
5 |
6 | export default [
7 | { ignores: ['dist'] },
8 | {
9 | files: ['**/*.{js,jsx}'],
10 | languageOptions: {
11 | ecmaVersion: 2020,
12 | globals: globals.browser,
13 | parserOptions: {
14 | ecmaVersion: 'latest',
15 | ecmaFeatures: { jsx: true },
16 | sourceType: 'module',
17 | },
18 | },
19 | plugins: {
20 | 'react-hooks': reactHooks,
21 | 'react-refresh': reactRefresh,
22 | },
23 | rules: {
24 | ...js.configs.recommended.rules,
25 | ...reactHooks.configs.recommended.rules,
26 | 'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
27 | 'react-refresh/only-export-components': [
28 | 'warn',
29 | { allowConstantExport: true },
30 | ],
31 | },
32 | },
33 | ]
34 |
--------------------------------------------------------------------------------
/prueba1-formulario-registro/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + React
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/prueba1-formulario-registro/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "plantilla-react-base",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "lint": "eslint .",
10 | "preview": "vite preview"
11 | },
12 | "dependencies": {
13 | "@chakra-ui/react": "^2.10.7",
14 | "@emotion/react": "^11.14.0",
15 | "@emotion/styled": "^11.14.0",
16 | "@tailwindcss/postcss": "^4.1.4",
17 | "framer-motion": "^12.7.4",
18 | "react": "^19.0.0",
19 | "react-dom": "^19.0.0",
20 | "react-hook-form": "^7.56.1",
21 | "react-icons": "^5.5.0",
22 | "zustand": "^5.0.3"
23 | },
24 | "devDependencies": {
25 | "@eslint/js": "^9.22.0",
26 | "@tailwindcss/vite": "^4.1.4",
27 | "@types/react": "^19.0.10",
28 | "@types/react-dom": "^19.0.4",
29 | "@vitejs/plugin-react": "^4.3.4",
30 | "autoprefixer": "^10.4.21",
31 | "eslint": "^9.22.0",
32 | "eslint-plugin-react-hooks": "^5.2.0",
33 | "eslint-plugin-react-refresh": "^0.4.19",
34 | "globals": "^16.0.0",
35 | "postcss": "^8.5.3",
36 | "tailwindcss": "^4.1.4",
37 | "vite": "^6.3.1"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/prueba1-formulario-registro/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/prueba1-formulario-registro/src/App.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohanBoDev/mini-pruebas-fullstack/ecbbae8fe61f7dd6d52f1fb23641461beaf3385e/prueba1-formulario-registro/src/App.css
--------------------------------------------------------------------------------
/prueba1-formulario-registro/src/App.jsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from "react";
2 |
3 | function App() {
4 | const [usuarios, setUsuarios] = useState([]);
5 |
6 | useEffect(() => {
7 | fetch("https://jsonplaceholder.typicode.com/users") // Llama a la API al montar
8 | .then((res) => res.json()) // Convierte a JSON
9 | .then((data) => setUsuarios(data)); // Guarda los datos en el estado
10 | }, []); // Solo se ejecuta una vez (como al iniciar)
11 |
12 | return (
13 |
14 | {usuarios.map((u) => (
15 | {u.name}
{u.email}
16 | ))}
17 |
18 | );
19 | }
20 | export default App
--------------------------------------------------------------------------------
/prueba1-formulario-registro/src/assets/react.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/prueba1-formulario-registro/src/index.css:
--------------------------------------------------------------------------------
1 | @import "tailwindcss";
2 |
3 |
--------------------------------------------------------------------------------
/prueba1-formulario-registro/src/main.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom/client'
3 | import App from './App.jsx'
4 | import './index.css'
5 |
6 | ReactDOM.createRoot(document.getElementById('root')).render(
7 |
8 |
9 | ,
10 | )
11 |
--------------------------------------------------------------------------------
/prueba1-formulario-registro/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 | import tailwindcss from "@tailwindcss/vite";
4 |
5 | // https://vitejs.dev/config/
6 | export default defineConfig({
7 | plugins: [react(), tailwindcss()],
8 | })
9 |
--------------------------------------------------------------------------------
/prueba2-api-productos/README.md:
--------------------------------------------------------------------------------
1 | # 🧪 Prueba 2 – API REST de Productos (Node.js + Express)
2 |
3 | ## 📋 Descripción
4 |
5 | Esta prueba consiste en desarrollar una **API REST utilizando Node.js y Express** que permita gestionar productos a través de operaciones CRUD (Crear, Leer, Actualizar, Eliminar). No es necesario usar una base de datos; los datos pueden mantenerse en un array en memoria.
6 |
7 | ---
8 |
9 | ## ✅ Requisitos funcionales
10 |
11 | - Crear una API con las siguientes rutas:
12 | - `GET /api/productos` → Obtener todos los productos
13 | - `GET /api/productos/:id` → Obtener un producto por ID
14 | - `POST /api/productos` → Crear un nuevo producto
15 | - `PUT /api/productos/:id` → Actualizar un producto existente
16 | - `DELETE /api/productos/:id` → Eliminar un producto
17 |
18 | - Cada producto debe tener:
19 | - `id`: número o string único
20 | - `nombre`: string
21 | - `precio`: número
22 | - `categoría`: string (opcional)
23 |
24 | ---
25 |
26 | ## 💡 Consideraciones técnicas
27 |
28 | - Los productos deben almacenarse en un array en memoria.
29 | - Validar que el cuerpo de los `POST` y `PUT` incluya `nombre` y `precio`.
30 | - Se puede usar `uuid` para generar IDs si se desea.
31 | - El servidor debe correr en el puerto `3000`.
32 |
33 | ---
34 |
35 | ## 🧱 Tecnologías usadas
36 |
37 | - 🟢 Node.js
38 | - ⚙️ Express.js
39 | - 🔄 Cors
40 | - 📦 dotenv
41 | - (Opcional: `uuid` para generar IDs únicos)
42 |
43 | ---
44 |
45 | ## 🚀 Instalación y ejecución
46 |
47 | ```bash
48 | npm install
49 | npm run dev
50 |
--------------------------------------------------------------------------------
/prueba2-api-productos/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "plantilla-node-express",
3 | "version": "1.0.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "plantilla-node-express",
9 | "version": "1.0.0",
10 | "license": "ISC",
11 | "dependencies": {
12 | "cors": "^2.8.5",
13 | "dotenv": "^16.5.0",
14 | "express": "^5.1.0",
15 | "nodemon": "^3.1.9"
16 | }
17 | },
18 | "node_modules/accepts": {
19 | "version": "2.0.0",
20 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
21 | "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
22 | "dependencies": {
23 | "mime-types": "^3.0.0",
24 | "negotiator": "^1.0.0"
25 | },
26 | "engines": {
27 | "node": ">= 0.6"
28 | }
29 | },
30 | "node_modules/anymatch": {
31 | "version": "3.1.3",
32 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
33 | "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
34 | "dependencies": {
35 | "normalize-path": "^3.0.0",
36 | "picomatch": "^2.0.4"
37 | },
38 | "engines": {
39 | "node": ">= 8"
40 | }
41 | },
42 | "node_modules/balanced-match": {
43 | "version": "1.0.2",
44 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
45 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
46 | },
47 | "node_modules/binary-extensions": {
48 | "version": "2.3.0",
49 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
50 | "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
51 | "engines": {
52 | "node": ">=8"
53 | },
54 | "funding": {
55 | "url": "https://github.com/sponsors/sindresorhus"
56 | }
57 | },
58 | "node_modules/body-parser": {
59 | "version": "2.2.0",
60 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
61 | "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
62 | "dependencies": {
63 | "bytes": "^3.1.2",
64 | "content-type": "^1.0.5",
65 | "debug": "^4.4.0",
66 | "http-errors": "^2.0.0",
67 | "iconv-lite": "^0.6.3",
68 | "on-finished": "^2.4.1",
69 | "qs": "^6.14.0",
70 | "raw-body": "^3.0.0",
71 | "type-is": "^2.0.0"
72 | },
73 | "engines": {
74 | "node": ">=18"
75 | }
76 | },
77 | "node_modules/brace-expansion": {
78 | "version": "1.1.11",
79 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
80 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
81 | "dependencies": {
82 | "balanced-match": "^1.0.0",
83 | "concat-map": "0.0.1"
84 | }
85 | },
86 | "node_modules/braces": {
87 | "version": "3.0.3",
88 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
89 | "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
90 | "dependencies": {
91 | "fill-range": "^7.1.1"
92 | },
93 | "engines": {
94 | "node": ">=8"
95 | }
96 | },
97 | "node_modules/bytes": {
98 | "version": "3.1.2",
99 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
100 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
101 | "engines": {
102 | "node": ">= 0.8"
103 | }
104 | },
105 | "node_modules/call-bind-apply-helpers": {
106 | "version": "1.0.2",
107 | "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
108 | "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
109 | "dependencies": {
110 | "es-errors": "^1.3.0",
111 | "function-bind": "^1.1.2"
112 | },
113 | "engines": {
114 | "node": ">= 0.4"
115 | }
116 | },
117 | "node_modules/call-bound": {
118 | "version": "1.0.4",
119 | "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
120 | "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
121 | "dependencies": {
122 | "call-bind-apply-helpers": "^1.0.2",
123 | "get-intrinsic": "^1.3.0"
124 | },
125 | "engines": {
126 | "node": ">= 0.4"
127 | },
128 | "funding": {
129 | "url": "https://github.com/sponsors/ljharb"
130 | }
131 | },
132 | "node_modules/chokidar": {
133 | "version": "3.6.0",
134 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
135 | "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
136 | "dependencies": {
137 | "anymatch": "~3.1.2",
138 | "braces": "~3.0.2",
139 | "glob-parent": "~5.1.2",
140 | "is-binary-path": "~2.1.0",
141 | "is-glob": "~4.0.1",
142 | "normalize-path": "~3.0.0",
143 | "readdirp": "~3.6.0"
144 | },
145 | "engines": {
146 | "node": ">= 8.10.0"
147 | },
148 | "funding": {
149 | "url": "https://paulmillr.com/funding/"
150 | },
151 | "optionalDependencies": {
152 | "fsevents": "~2.3.2"
153 | }
154 | },
155 | "node_modules/concat-map": {
156 | "version": "0.0.1",
157 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
158 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
159 | },
160 | "node_modules/content-disposition": {
161 | "version": "1.0.0",
162 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
163 | "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==",
164 | "dependencies": {
165 | "safe-buffer": "5.2.1"
166 | },
167 | "engines": {
168 | "node": ">= 0.6"
169 | }
170 | },
171 | "node_modules/content-type": {
172 | "version": "1.0.5",
173 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
174 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
175 | "engines": {
176 | "node": ">= 0.6"
177 | }
178 | },
179 | "node_modules/cookie": {
180 | "version": "0.7.2",
181 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
182 | "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
183 | "engines": {
184 | "node": ">= 0.6"
185 | }
186 | },
187 | "node_modules/cookie-signature": {
188 | "version": "1.2.2",
189 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
190 | "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
191 | "engines": {
192 | "node": ">=6.6.0"
193 | }
194 | },
195 | "node_modules/cors": {
196 | "version": "2.8.5",
197 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
198 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
199 | "dependencies": {
200 | "object-assign": "^4",
201 | "vary": "^1"
202 | },
203 | "engines": {
204 | "node": ">= 0.10"
205 | }
206 | },
207 | "node_modules/debug": {
208 | "version": "4.4.0",
209 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
210 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
211 | "dependencies": {
212 | "ms": "^2.1.3"
213 | },
214 | "engines": {
215 | "node": ">=6.0"
216 | },
217 | "peerDependenciesMeta": {
218 | "supports-color": {
219 | "optional": true
220 | }
221 | }
222 | },
223 | "node_modules/depd": {
224 | "version": "2.0.0",
225 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
226 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
227 | "engines": {
228 | "node": ">= 0.8"
229 | }
230 | },
231 | "node_modules/dotenv": {
232 | "version": "16.5.0",
233 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz",
234 | "integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==",
235 | "engines": {
236 | "node": ">=12"
237 | },
238 | "funding": {
239 | "url": "https://dotenvx.com"
240 | }
241 | },
242 | "node_modules/dunder-proto": {
243 | "version": "1.0.1",
244 | "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
245 | "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
246 | "dependencies": {
247 | "call-bind-apply-helpers": "^1.0.1",
248 | "es-errors": "^1.3.0",
249 | "gopd": "^1.2.0"
250 | },
251 | "engines": {
252 | "node": ">= 0.4"
253 | }
254 | },
255 | "node_modules/ee-first": {
256 | "version": "1.1.1",
257 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
258 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
259 | },
260 | "node_modules/encodeurl": {
261 | "version": "2.0.0",
262 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
263 | "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
264 | "engines": {
265 | "node": ">= 0.8"
266 | }
267 | },
268 | "node_modules/es-define-property": {
269 | "version": "1.0.1",
270 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
271 | "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
272 | "engines": {
273 | "node": ">= 0.4"
274 | }
275 | },
276 | "node_modules/es-errors": {
277 | "version": "1.3.0",
278 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
279 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
280 | "engines": {
281 | "node": ">= 0.4"
282 | }
283 | },
284 | "node_modules/es-object-atoms": {
285 | "version": "1.1.1",
286 | "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
287 | "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
288 | "dependencies": {
289 | "es-errors": "^1.3.0"
290 | },
291 | "engines": {
292 | "node": ">= 0.4"
293 | }
294 | },
295 | "node_modules/escape-html": {
296 | "version": "1.0.3",
297 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
298 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
299 | },
300 | "node_modules/etag": {
301 | "version": "1.8.1",
302 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
303 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
304 | "engines": {
305 | "node": ">= 0.6"
306 | }
307 | },
308 | "node_modules/express": {
309 | "version": "5.1.0",
310 | "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz",
311 | "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==",
312 | "dependencies": {
313 | "accepts": "^2.0.0",
314 | "body-parser": "^2.2.0",
315 | "content-disposition": "^1.0.0",
316 | "content-type": "^1.0.5",
317 | "cookie": "^0.7.1",
318 | "cookie-signature": "^1.2.1",
319 | "debug": "^4.4.0",
320 | "encodeurl": "^2.0.0",
321 | "escape-html": "^1.0.3",
322 | "etag": "^1.8.1",
323 | "finalhandler": "^2.1.0",
324 | "fresh": "^2.0.0",
325 | "http-errors": "^2.0.0",
326 | "merge-descriptors": "^2.0.0",
327 | "mime-types": "^3.0.0",
328 | "on-finished": "^2.4.1",
329 | "once": "^1.4.0",
330 | "parseurl": "^1.3.3",
331 | "proxy-addr": "^2.0.7",
332 | "qs": "^6.14.0",
333 | "range-parser": "^1.2.1",
334 | "router": "^2.2.0",
335 | "send": "^1.1.0",
336 | "serve-static": "^2.2.0",
337 | "statuses": "^2.0.1",
338 | "type-is": "^2.0.1",
339 | "vary": "^1.1.2"
340 | },
341 | "engines": {
342 | "node": ">= 18"
343 | },
344 | "funding": {
345 | "type": "opencollective",
346 | "url": "https://opencollective.com/express"
347 | }
348 | },
349 | "node_modules/fill-range": {
350 | "version": "7.1.1",
351 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
352 | "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
353 | "dependencies": {
354 | "to-regex-range": "^5.0.1"
355 | },
356 | "engines": {
357 | "node": ">=8"
358 | }
359 | },
360 | "node_modules/finalhandler": {
361 | "version": "2.1.0",
362 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
363 | "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==",
364 | "dependencies": {
365 | "debug": "^4.4.0",
366 | "encodeurl": "^2.0.0",
367 | "escape-html": "^1.0.3",
368 | "on-finished": "^2.4.1",
369 | "parseurl": "^1.3.3",
370 | "statuses": "^2.0.1"
371 | },
372 | "engines": {
373 | "node": ">= 0.8"
374 | }
375 | },
376 | "node_modules/forwarded": {
377 | "version": "0.2.0",
378 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
379 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
380 | "engines": {
381 | "node": ">= 0.6"
382 | }
383 | },
384 | "node_modules/fresh": {
385 | "version": "2.0.0",
386 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
387 | "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
388 | "engines": {
389 | "node": ">= 0.8"
390 | }
391 | },
392 | "node_modules/fsevents": {
393 | "version": "2.3.3",
394 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
395 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
396 | "hasInstallScript": true,
397 | "optional": true,
398 | "os": [
399 | "darwin"
400 | ],
401 | "engines": {
402 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
403 | }
404 | },
405 | "node_modules/function-bind": {
406 | "version": "1.1.2",
407 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
408 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
409 | "funding": {
410 | "url": "https://github.com/sponsors/ljharb"
411 | }
412 | },
413 | "node_modules/get-intrinsic": {
414 | "version": "1.3.0",
415 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
416 | "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
417 | "dependencies": {
418 | "call-bind-apply-helpers": "^1.0.2",
419 | "es-define-property": "^1.0.1",
420 | "es-errors": "^1.3.0",
421 | "es-object-atoms": "^1.1.1",
422 | "function-bind": "^1.1.2",
423 | "get-proto": "^1.0.1",
424 | "gopd": "^1.2.0",
425 | "has-symbols": "^1.1.0",
426 | "hasown": "^2.0.2",
427 | "math-intrinsics": "^1.1.0"
428 | },
429 | "engines": {
430 | "node": ">= 0.4"
431 | },
432 | "funding": {
433 | "url": "https://github.com/sponsors/ljharb"
434 | }
435 | },
436 | "node_modules/get-proto": {
437 | "version": "1.0.1",
438 | "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
439 | "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
440 | "dependencies": {
441 | "dunder-proto": "^1.0.1",
442 | "es-object-atoms": "^1.0.0"
443 | },
444 | "engines": {
445 | "node": ">= 0.4"
446 | }
447 | },
448 | "node_modules/glob-parent": {
449 | "version": "5.1.2",
450 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
451 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
452 | "dependencies": {
453 | "is-glob": "^4.0.1"
454 | },
455 | "engines": {
456 | "node": ">= 6"
457 | }
458 | },
459 | "node_modules/gopd": {
460 | "version": "1.2.0",
461 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
462 | "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
463 | "engines": {
464 | "node": ">= 0.4"
465 | },
466 | "funding": {
467 | "url": "https://github.com/sponsors/ljharb"
468 | }
469 | },
470 | "node_modules/has-flag": {
471 | "version": "3.0.0",
472 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
473 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
474 | "engines": {
475 | "node": ">=4"
476 | }
477 | },
478 | "node_modules/has-symbols": {
479 | "version": "1.1.0",
480 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
481 | "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
482 | "engines": {
483 | "node": ">= 0.4"
484 | },
485 | "funding": {
486 | "url": "https://github.com/sponsors/ljharb"
487 | }
488 | },
489 | "node_modules/hasown": {
490 | "version": "2.0.2",
491 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
492 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
493 | "dependencies": {
494 | "function-bind": "^1.1.2"
495 | },
496 | "engines": {
497 | "node": ">= 0.4"
498 | }
499 | },
500 | "node_modules/http-errors": {
501 | "version": "2.0.0",
502 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
503 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
504 | "dependencies": {
505 | "depd": "2.0.0",
506 | "inherits": "2.0.4",
507 | "setprototypeof": "1.2.0",
508 | "statuses": "2.0.1",
509 | "toidentifier": "1.0.1"
510 | },
511 | "engines": {
512 | "node": ">= 0.8"
513 | }
514 | },
515 | "node_modules/iconv-lite": {
516 | "version": "0.6.3",
517 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
518 | "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
519 | "dependencies": {
520 | "safer-buffer": ">= 2.1.2 < 3.0.0"
521 | },
522 | "engines": {
523 | "node": ">=0.10.0"
524 | }
525 | },
526 | "node_modules/ignore-by-default": {
527 | "version": "1.0.1",
528 | "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
529 | "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA=="
530 | },
531 | "node_modules/inherits": {
532 | "version": "2.0.4",
533 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
534 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
535 | },
536 | "node_modules/ipaddr.js": {
537 | "version": "1.9.1",
538 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
539 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
540 | "engines": {
541 | "node": ">= 0.10"
542 | }
543 | },
544 | "node_modules/is-binary-path": {
545 | "version": "2.1.0",
546 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
547 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
548 | "dependencies": {
549 | "binary-extensions": "^2.0.0"
550 | },
551 | "engines": {
552 | "node": ">=8"
553 | }
554 | },
555 | "node_modules/is-extglob": {
556 | "version": "2.1.1",
557 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
558 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
559 | "engines": {
560 | "node": ">=0.10.0"
561 | }
562 | },
563 | "node_modules/is-glob": {
564 | "version": "4.0.3",
565 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
566 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
567 | "dependencies": {
568 | "is-extglob": "^2.1.1"
569 | },
570 | "engines": {
571 | "node": ">=0.10.0"
572 | }
573 | },
574 | "node_modules/is-number": {
575 | "version": "7.0.0",
576 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
577 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
578 | "engines": {
579 | "node": ">=0.12.0"
580 | }
581 | },
582 | "node_modules/is-promise": {
583 | "version": "4.0.0",
584 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
585 | "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="
586 | },
587 | "node_modules/math-intrinsics": {
588 | "version": "1.1.0",
589 | "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
590 | "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
591 | "engines": {
592 | "node": ">= 0.4"
593 | }
594 | },
595 | "node_modules/media-typer": {
596 | "version": "1.1.0",
597 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
598 | "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
599 | "engines": {
600 | "node": ">= 0.8"
601 | }
602 | },
603 | "node_modules/merge-descriptors": {
604 | "version": "2.0.0",
605 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
606 | "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
607 | "engines": {
608 | "node": ">=18"
609 | },
610 | "funding": {
611 | "url": "https://github.com/sponsors/sindresorhus"
612 | }
613 | },
614 | "node_modules/mime-db": {
615 | "version": "1.54.0",
616 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
617 | "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
618 | "engines": {
619 | "node": ">= 0.6"
620 | }
621 | },
622 | "node_modules/mime-types": {
623 | "version": "3.0.1",
624 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
625 | "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
626 | "dependencies": {
627 | "mime-db": "^1.54.0"
628 | },
629 | "engines": {
630 | "node": ">= 0.6"
631 | }
632 | },
633 | "node_modules/minimatch": {
634 | "version": "3.1.2",
635 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
636 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
637 | "dependencies": {
638 | "brace-expansion": "^1.1.7"
639 | },
640 | "engines": {
641 | "node": "*"
642 | }
643 | },
644 | "node_modules/ms": {
645 | "version": "2.1.3",
646 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
647 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
648 | },
649 | "node_modules/negotiator": {
650 | "version": "1.0.0",
651 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
652 | "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
653 | "engines": {
654 | "node": ">= 0.6"
655 | }
656 | },
657 | "node_modules/nodemon": {
658 | "version": "3.1.9",
659 | "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.9.tgz",
660 | "integrity": "sha512-hdr1oIb2p6ZSxu3PB2JWWYS7ZQ0qvaZsc3hK8DR8f02kRzc8rjYmxAIvdz+aYC+8F2IjNaB7HMcSDg8nQpJxyg==",
661 | "dependencies": {
662 | "chokidar": "^3.5.2",
663 | "debug": "^4",
664 | "ignore-by-default": "^1.0.1",
665 | "minimatch": "^3.1.2",
666 | "pstree.remy": "^1.1.8",
667 | "semver": "^7.5.3",
668 | "simple-update-notifier": "^2.0.0",
669 | "supports-color": "^5.5.0",
670 | "touch": "^3.1.0",
671 | "undefsafe": "^2.0.5"
672 | },
673 | "bin": {
674 | "nodemon": "bin/nodemon.js"
675 | },
676 | "engines": {
677 | "node": ">=10"
678 | },
679 | "funding": {
680 | "type": "opencollective",
681 | "url": "https://opencollective.com/nodemon"
682 | }
683 | },
684 | "node_modules/normalize-path": {
685 | "version": "3.0.0",
686 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
687 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
688 | "engines": {
689 | "node": ">=0.10.0"
690 | }
691 | },
692 | "node_modules/object-assign": {
693 | "version": "4.1.1",
694 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
695 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
696 | "engines": {
697 | "node": ">=0.10.0"
698 | }
699 | },
700 | "node_modules/object-inspect": {
701 | "version": "1.13.4",
702 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
703 | "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
704 | "engines": {
705 | "node": ">= 0.4"
706 | },
707 | "funding": {
708 | "url": "https://github.com/sponsors/ljharb"
709 | }
710 | },
711 | "node_modules/on-finished": {
712 | "version": "2.4.1",
713 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
714 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
715 | "dependencies": {
716 | "ee-first": "1.1.1"
717 | },
718 | "engines": {
719 | "node": ">= 0.8"
720 | }
721 | },
722 | "node_modules/once": {
723 | "version": "1.4.0",
724 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
725 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
726 | "dependencies": {
727 | "wrappy": "1"
728 | }
729 | },
730 | "node_modules/parseurl": {
731 | "version": "1.3.3",
732 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
733 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
734 | "engines": {
735 | "node": ">= 0.8"
736 | }
737 | },
738 | "node_modules/path-to-regexp": {
739 | "version": "8.2.0",
740 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz",
741 | "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==",
742 | "engines": {
743 | "node": ">=16"
744 | }
745 | },
746 | "node_modules/picomatch": {
747 | "version": "2.3.1",
748 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
749 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
750 | "engines": {
751 | "node": ">=8.6"
752 | },
753 | "funding": {
754 | "url": "https://github.com/sponsors/jonschlinkert"
755 | }
756 | },
757 | "node_modules/proxy-addr": {
758 | "version": "2.0.7",
759 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
760 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
761 | "dependencies": {
762 | "forwarded": "0.2.0",
763 | "ipaddr.js": "1.9.1"
764 | },
765 | "engines": {
766 | "node": ">= 0.10"
767 | }
768 | },
769 | "node_modules/pstree.remy": {
770 | "version": "1.1.8",
771 | "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
772 | "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w=="
773 | },
774 | "node_modules/qs": {
775 | "version": "6.14.0",
776 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
777 | "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
778 | "dependencies": {
779 | "side-channel": "^1.1.0"
780 | },
781 | "engines": {
782 | "node": ">=0.6"
783 | },
784 | "funding": {
785 | "url": "https://github.com/sponsors/ljharb"
786 | }
787 | },
788 | "node_modules/range-parser": {
789 | "version": "1.2.1",
790 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
791 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
792 | "engines": {
793 | "node": ">= 0.6"
794 | }
795 | },
796 | "node_modules/raw-body": {
797 | "version": "3.0.0",
798 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
799 | "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
800 | "dependencies": {
801 | "bytes": "3.1.2",
802 | "http-errors": "2.0.0",
803 | "iconv-lite": "0.6.3",
804 | "unpipe": "1.0.0"
805 | },
806 | "engines": {
807 | "node": ">= 0.8"
808 | }
809 | },
810 | "node_modules/readdirp": {
811 | "version": "3.6.0",
812 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
813 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
814 | "dependencies": {
815 | "picomatch": "^2.2.1"
816 | },
817 | "engines": {
818 | "node": ">=8.10.0"
819 | }
820 | },
821 | "node_modules/router": {
822 | "version": "2.2.0",
823 | "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
824 | "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
825 | "dependencies": {
826 | "debug": "^4.4.0",
827 | "depd": "^2.0.0",
828 | "is-promise": "^4.0.0",
829 | "parseurl": "^1.3.3",
830 | "path-to-regexp": "^8.0.0"
831 | },
832 | "engines": {
833 | "node": ">= 18"
834 | }
835 | },
836 | "node_modules/safe-buffer": {
837 | "version": "5.2.1",
838 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
839 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
840 | "funding": [
841 | {
842 | "type": "github",
843 | "url": "https://github.com/sponsors/feross"
844 | },
845 | {
846 | "type": "patreon",
847 | "url": "https://www.patreon.com/feross"
848 | },
849 | {
850 | "type": "consulting",
851 | "url": "https://feross.org/support"
852 | }
853 | ]
854 | },
855 | "node_modules/safer-buffer": {
856 | "version": "2.1.2",
857 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
858 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
859 | },
860 | "node_modules/semver": {
861 | "version": "7.7.1",
862 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
863 | "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
864 | "bin": {
865 | "semver": "bin/semver.js"
866 | },
867 | "engines": {
868 | "node": ">=10"
869 | }
870 | },
871 | "node_modules/send": {
872 | "version": "1.2.0",
873 | "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
874 | "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
875 | "dependencies": {
876 | "debug": "^4.3.5",
877 | "encodeurl": "^2.0.0",
878 | "escape-html": "^1.0.3",
879 | "etag": "^1.8.1",
880 | "fresh": "^2.0.0",
881 | "http-errors": "^2.0.0",
882 | "mime-types": "^3.0.1",
883 | "ms": "^2.1.3",
884 | "on-finished": "^2.4.1",
885 | "range-parser": "^1.2.1",
886 | "statuses": "^2.0.1"
887 | },
888 | "engines": {
889 | "node": ">= 18"
890 | }
891 | },
892 | "node_modules/serve-static": {
893 | "version": "2.2.0",
894 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
895 | "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
896 | "dependencies": {
897 | "encodeurl": "^2.0.0",
898 | "escape-html": "^1.0.3",
899 | "parseurl": "^1.3.3",
900 | "send": "^1.2.0"
901 | },
902 | "engines": {
903 | "node": ">= 18"
904 | }
905 | },
906 | "node_modules/setprototypeof": {
907 | "version": "1.2.0",
908 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
909 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
910 | },
911 | "node_modules/side-channel": {
912 | "version": "1.1.0",
913 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
914 | "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
915 | "dependencies": {
916 | "es-errors": "^1.3.0",
917 | "object-inspect": "^1.13.3",
918 | "side-channel-list": "^1.0.0",
919 | "side-channel-map": "^1.0.1",
920 | "side-channel-weakmap": "^1.0.2"
921 | },
922 | "engines": {
923 | "node": ">= 0.4"
924 | },
925 | "funding": {
926 | "url": "https://github.com/sponsors/ljharb"
927 | }
928 | },
929 | "node_modules/side-channel-list": {
930 | "version": "1.0.0",
931 | "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
932 | "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
933 | "dependencies": {
934 | "es-errors": "^1.3.0",
935 | "object-inspect": "^1.13.3"
936 | },
937 | "engines": {
938 | "node": ">= 0.4"
939 | },
940 | "funding": {
941 | "url": "https://github.com/sponsors/ljharb"
942 | }
943 | },
944 | "node_modules/side-channel-map": {
945 | "version": "1.0.1",
946 | "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
947 | "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
948 | "dependencies": {
949 | "call-bound": "^1.0.2",
950 | "es-errors": "^1.3.0",
951 | "get-intrinsic": "^1.2.5",
952 | "object-inspect": "^1.13.3"
953 | },
954 | "engines": {
955 | "node": ">= 0.4"
956 | },
957 | "funding": {
958 | "url": "https://github.com/sponsors/ljharb"
959 | }
960 | },
961 | "node_modules/side-channel-weakmap": {
962 | "version": "1.0.2",
963 | "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
964 | "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
965 | "dependencies": {
966 | "call-bound": "^1.0.2",
967 | "es-errors": "^1.3.0",
968 | "get-intrinsic": "^1.2.5",
969 | "object-inspect": "^1.13.3",
970 | "side-channel-map": "^1.0.1"
971 | },
972 | "engines": {
973 | "node": ">= 0.4"
974 | },
975 | "funding": {
976 | "url": "https://github.com/sponsors/ljharb"
977 | }
978 | },
979 | "node_modules/simple-update-notifier": {
980 | "version": "2.0.0",
981 | "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz",
982 | "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==",
983 | "dependencies": {
984 | "semver": "^7.5.3"
985 | },
986 | "engines": {
987 | "node": ">=10"
988 | }
989 | },
990 | "node_modules/statuses": {
991 | "version": "2.0.1",
992 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
993 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
994 | "engines": {
995 | "node": ">= 0.8"
996 | }
997 | },
998 | "node_modules/supports-color": {
999 | "version": "5.5.0",
1000 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
1001 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
1002 | "dependencies": {
1003 | "has-flag": "^3.0.0"
1004 | },
1005 | "engines": {
1006 | "node": ">=4"
1007 | }
1008 | },
1009 | "node_modules/to-regex-range": {
1010 | "version": "5.0.1",
1011 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
1012 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
1013 | "dependencies": {
1014 | "is-number": "^7.0.0"
1015 | },
1016 | "engines": {
1017 | "node": ">=8.0"
1018 | }
1019 | },
1020 | "node_modules/toidentifier": {
1021 | "version": "1.0.1",
1022 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
1023 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
1024 | "engines": {
1025 | "node": ">=0.6"
1026 | }
1027 | },
1028 | "node_modules/touch": {
1029 | "version": "3.1.1",
1030 | "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz",
1031 | "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==",
1032 | "bin": {
1033 | "nodetouch": "bin/nodetouch.js"
1034 | }
1035 | },
1036 | "node_modules/type-is": {
1037 | "version": "2.0.1",
1038 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
1039 | "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
1040 | "dependencies": {
1041 | "content-type": "^1.0.5",
1042 | "media-typer": "^1.1.0",
1043 | "mime-types": "^3.0.0"
1044 | },
1045 | "engines": {
1046 | "node": ">= 0.6"
1047 | }
1048 | },
1049 | "node_modules/undefsafe": {
1050 | "version": "2.0.5",
1051 | "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
1052 | "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA=="
1053 | },
1054 | "node_modules/unpipe": {
1055 | "version": "1.0.0",
1056 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
1057 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
1058 | "engines": {
1059 | "node": ">= 0.8"
1060 | }
1061 | },
1062 | "node_modules/vary": {
1063 | "version": "1.1.2",
1064 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
1065 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
1066 | "engines": {
1067 | "node": ">= 0.8"
1068 | }
1069 | },
1070 | "node_modules/wrappy": {
1071 | "version": "1.0.2",
1072 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1073 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
1074 | }
1075 | }
1076 | }
1077 |
--------------------------------------------------------------------------------
/prueba2-api-productos/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "plantilla-node-express",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "type": "module",
6 |
7 | "scripts": {
8 | "dev": "nodemon src/index.js"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "ISC",
13 | "description": "",
14 | "dependencies": {
15 | "cors": "^2.8.5",
16 | "dotenv": "^16.5.0",
17 | "express": "^5.1.0",
18 | "nodemon": "^3.1.9"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/prueba2-api-productos/src/controllers/productosController.js:
--------------------------------------------------------------------------------
1 | // src/controllers/productosController.js
2 |
3 | let productos = []; // array temporal
4 |
5 | export const obtenerProductos = (req, res) => {
6 | if(productos.length >= 1){
7 | res.json(productos);
8 | }
9 | return res.status(404).json({message: "No tienes productos"})
10 | };
11 |
12 | export const obtenerProductoPorId = (req, res) => {
13 | const { id } = req.params;
14 | const producto = productos.find((p) => p.id === id);
15 | if (!producto) return res.status(404).json({ mensaje: "No encontrado" });
16 | res.json(producto);
17 | };
18 |
19 | export const crearProducto = (req, res) => {
20 | const { nombre, precio, categoria } = req.body;
21 | if (!nombre || !precio) {
22 | return res.status(400).json({ mensaje: "Nombre y precio son requeridos" });
23 | }
24 |
25 | const nuevoProducto = {
26 | id: Date.now().toString(), // ID único
27 | nombre,
28 | precio,
29 | categoria: categoria || "",
30 | };
31 |
32 | productos.push(nuevoProducto);
33 | res.status(201).json(nuevoProducto);
34 | };
35 |
36 | export const actualizarProducto = (req, res) => {
37 | const { id } = req.params;
38 | const index = productos.findIndex((p) => p.id === id);
39 | if (index === -1) return res.status(404).json({ mensaje: "No encontrado" });
40 |
41 | const { nombre, precio, categoria } = req.body;
42 | productos[index] = {
43 | ...productos[index],
44 | nombre: nombre || productos[index].nombre,
45 | precio: precio || productos[index].precio,
46 | categoria: categoria || productos[index].categoria,
47 | };
48 |
49 | res.json(productos[index]);
50 | };
51 |
52 | export const eliminarProducto = (req, res) => {
53 | const { id } = req.params;
54 |
55 | const existe = productos.some((p) => p.id === id);
56 | if (!existe) {
57 | return res.status(404).json({ mensaje: "Producto no encontrado" });
58 | }
59 |
60 | productos = productos.filter((p) => p.id !== id);
61 | res.json({ mensaje: "Producto eliminado" });
62 | };
63 |
--------------------------------------------------------------------------------
/prueba2-api-productos/src/index.js:
--------------------------------------------------------------------------------
1 | import express from "express";
2 | import cors from "cors";
3 | import dotenv from "dotenv";
4 | import productosRoutes from "./routes/productos.js";
5 |
6 | dotenv.config();
7 | const app = express();
8 | app.use(cors());
9 | app.use(express.json());
10 |
11 | app.use("/api/productos", productosRoutes);
12 |
13 | const PORT = process.env.PORT || 3100;
14 | app.listen(PORT, () => {
15 | console.log(`Servidor corriendo en http://localhost:${PORT}`);
16 | });
17 |
--------------------------------------------------------------------------------
/prueba2-api-productos/src/routes/productos.js:
--------------------------------------------------------------------------------
1 | import express from "express";
2 | import {
3 | obtenerProductos,
4 | obtenerProductoPorId,
5 | crearProducto,
6 | actualizarProducto,
7 | eliminarProducto,
8 | } from "../controllers/productosController.js";
9 |
10 | const router = express.Router();
11 |
12 | router.get("/", obtenerProductos);
13 | router.get("/:id", obtenerProductoPorId);
14 | router.post("/", crearProducto);
15 | router.put("/:id", actualizarProducto);
16 | router.delete("/:id", eliminarProducto);
17 |
18 | export default router;
19 |
--------------------------------------------------------------------------------
/prueba3-tareas-zustand/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/prueba3-tareas-zustand/README.md:
--------------------------------------------------------------------------------
1 | # 🧪 Prueba 3 – Lista de Tareas con Zustand
2 |
3 | ## 📋 Descripción
4 |
5 | En esta prueba se debe desarrollar una aplicación en React que permita gestionar una **lista de tareas** (To-Do List) utilizando el gestor de estado global **Zustand**.
6 |
7 | ---
8 |
9 | ## ✅ Requisitos funcionales
10 |
11 | - El usuario debe poder:
12 | - Añadir una nueva tarea con un texto.
13 | - Marcar una tarea como completada.
14 | - Eliminar una tarea.
15 |
16 | - Las tareas deben tener al menos:
17 | - `id`: único
18 | - `texto`: contenido de la tarea
19 | - `completada`: booleano
20 |
21 | ---
22 |
23 | ## 💡 Consideraciones técnicas
24 |
25 | - Utilizar Zustand para manejar el estado de las tareas.
26 | - No es necesario usar bases de datos (puede mantenerse todo en memoria).
27 | - Las tareas pueden ser visibles en una lista.
28 | - Puede usarse Tailwind CSS y/o Chakra UI para los estilos.
29 | - Se recomienda uso de componentes reutilizables para cada tarea.
30 |
31 | ---
32 |
33 | ## 🧱 Tecnologías usadas
34 |
35 | - ⚛️ React + Vite
36 | - 🎨 Tailwind CSS v4
37 | - 📦 Zustand
38 | - (Opcional) Chakra UI
39 |
40 | ---
41 |
42 | ## 🚀 Instalación y ejecución
43 |
44 | ```bash
45 | npm install
46 | npm run dev
47 |
--------------------------------------------------------------------------------
/prueba3-tareas-zustand/eslint.config.js:
--------------------------------------------------------------------------------
1 | import js from '@eslint/js'
2 | import globals from 'globals'
3 | import reactHooks from 'eslint-plugin-react-hooks'
4 | import reactRefresh from 'eslint-plugin-react-refresh'
5 |
6 | export default [
7 | { ignores: ['dist'] },
8 | {
9 | files: ['**/*.{js,jsx}'],
10 | languageOptions: {
11 | ecmaVersion: 2020,
12 | globals: globals.browser,
13 | parserOptions: {
14 | ecmaVersion: 'latest',
15 | ecmaFeatures: { jsx: true },
16 | sourceType: 'module',
17 | },
18 | },
19 | plugins: {
20 | 'react-hooks': reactHooks,
21 | 'react-refresh': reactRefresh,
22 | },
23 | rules: {
24 | ...js.configs.recommended.rules,
25 | ...reactHooks.configs.recommended.rules,
26 | 'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
27 | 'react-refresh/only-export-components': [
28 | 'warn',
29 | { allowConstantExport: true },
30 | ],
31 | },
32 | },
33 | ]
34 |
--------------------------------------------------------------------------------
/prueba3-tareas-zustand/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + React
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/prueba3-tareas-zustand/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "plantilla-react-base",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "lint": "eslint .",
10 | "preview": "vite preview"
11 | },
12 | "dependencies": {
13 | "@chakra-ui/react": "^2.10.7",
14 | "@emotion/react": "^11.14.0",
15 | "@emotion/styled": "^11.14.0",
16 | "@tailwindcss/postcss": "^4.1.4",
17 | "framer-motion": "^12.7.4",
18 | "react": "^19.0.0",
19 | "react-dom": "^19.0.0",
20 | "react-hook-form": "^7.56.1",
21 | "react-icons": "^5.5.0",
22 | "zustand": "^5.0.3"
23 | },
24 | "devDependencies": {
25 | "@eslint/js": "^9.22.0",
26 | "@tailwindcss/vite": "^4.1.4",
27 | "@types/react": "^19.0.10",
28 | "@types/react-dom": "^19.0.4",
29 | "@vitejs/plugin-react": "^4.3.4",
30 | "autoprefixer": "^10.4.21",
31 | "eslint": "^9.22.0",
32 | "eslint-plugin-react-hooks": "^5.2.0",
33 | "eslint-plugin-react-refresh": "^0.4.19",
34 | "globals": "^16.0.0",
35 | "postcss": "^8.5.3",
36 | "tailwindcss": "^4.1.4",
37 | "vite": "^6.3.1"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/prueba3-tareas-zustand/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/prueba3-tareas-zustand/src/App.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohanBoDev/mini-pruebas-fullstack/ecbbae8fe61f7dd6d52f1fb23641461beaf3385e/prueba3-tareas-zustand/src/App.css
--------------------------------------------------------------------------------
/prueba3-tareas-zustand/src/App.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from 'react'
2 | import reactLogo from './assets/react.svg'
3 | import viteLogo from '/vite.svg'
4 | import './App.css'
5 | import useTareas from './store/tareas'
6 |
7 | function App() {
8 | const [texto, setTexto] = useState("")
9 | const { agregarTarea, tareas, marcarTarea, eliminarTarea } = useTareas();
10 |
11 | const handleAgregar = () => {
12 | if (texto.trim() !== "") {
13 | agregarTarea(texto);
14 | setTexto("")
15 | }
16 | else {
17 | alert("Llena el campo")
18 | }
19 |
20 | };
21 |
22 | return (
23 |
24 |
TodoAPP
25 |
26 |
setTexto(e.target.value)}
30 | placeholder='Crea una tarea...'
31 | className='bg-white/40 rounded-xl pl-3 py-2 text-white'
32 | />
33 |
34 |
35 | {
36 | (tareas.length === 0 ?
No tienes tareas
37 | :
38 |
58 | )
59 | }
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | );
68 | }
69 |
70 | export default App
71 |
--------------------------------------------------------------------------------
/prueba3-tareas-zustand/src/assets/react.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/prueba3-tareas-zustand/src/index.css:
--------------------------------------------------------------------------------
1 | @import "tailwindcss";
2 |
--------------------------------------------------------------------------------
/prueba3-tareas-zustand/src/main.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom/client'
3 | import App from './App.jsx'
4 | import './index.css'
5 |
6 | ReactDOM.createRoot(document.getElementById('root')).render(
7 |
8 |
9 | ,
10 | )
11 |
--------------------------------------------------------------------------------
/prueba3-tareas-zustand/src/store/tareas.jsx:
--------------------------------------------------------------------------------
1 | // src/store/tareas.js
2 | import { create } from 'zustand';
3 |
4 | const useTareas = create((set) => ({
5 | tareas: [],
6 | agregarTarea: (texto) =>
7 | set((state) => ({
8 | tareas: [
9 | ...state.tareas,
10 | {
11 | id: Date.now(),
12 | texto,
13 | completada: false
14 | }
15 | ]
16 | })),
17 | marcarTarea: (id) =>
18 | set((state) => ({
19 | tareas: state.tareas.map((tarea) =>
20 | tarea.id === id
21 | ? { ...tarea, completada: !tarea.completada }
22 | : tarea
23 | ),
24 | })),
25 | eliminarTarea: (id) =>
26 | set((state) => ({
27 | tareas: state.tareas.filter((tarea) => tarea.id !== id)
28 | }))
29 | }));
30 |
31 | export default useTareas;
32 |
--------------------------------------------------------------------------------
/prueba3-tareas-zustand/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 | import tailwindcss from "@tailwindcss/vite";
4 |
5 | // https://vitejs.dev/config/
6 | export default defineConfig({
7 | plugins: [react(), tailwindcss()],
8 | })
9 |
--------------------------------------------------------------------------------
/prueba4-postgreSql/README.md:
--------------------------------------------------------------------------------
1 | # 🧪 Prueba 4: API de Productos con PostgreSQL (Node.js + Express)
2 |
3 | ## 📝 Descripción
4 |
5 | Esta prueba consiste en adaptar una API REST de productos utilizando Node.js, Express y PostgreSQL como base de datos, reemplazando el almacenamiento en memoria por persistencia real. Se utiliza la librería `pg` para conectarse a PostgreSQL.
6 |
7 | ---
8 |
9 | ## 📦 Instalación
10 |
11 | 1. Copia la plantilla base:
12 |
13 | ```bash
14 | cp -r prueba2-api-productos prueba4-postgresql
15 | cd prueba4-postgresql
16 | ```
17 |
18 | 2. Instala las dependencias:
19 |
20 | ```bash
21 | npm install
22 | ```
23 |
24 | 3. Crea una base de datos PostgreSQL:
25 |
26 | Puedes llamarla por ejemplo `productosdb`.
27 |
28 | 4. Ejecuta esta consulta para crear la tabla de productos:
29 |
30 | ```sql
31 | CREATE TABLE productos (
32 | id SERIAL PRIMARY KEY,
33 | nombre VARCHAR(100) NOT NULL,
34 | precio NUMERIC(10, 2) NOT NULL,
35 | categoria VARCHAR(50) NOT NULL
36 | );
37 | ```
38 |
39 | ---
40 |
41 | ## ⚙️ Variables de entorno
42 |
43 | Crea un archivo `.env` con el siguiente contenido:
44 |
45 | ```env
46 | DATABASE_URL=postgresql://usuario:contraseña@localhost:5432/productosdb
47 | PORT=3000
48 | ```
49 |
50 | Reemplaza `usuario` y `contraseña` por los de tu base de datos.
51 |
52 | ---
53 |
54 | ## 🚀 Ejecutar el servidor
55 |
56 | ```bash
57 | npm run dev
58 | ```
59 |
60 | ---
61 |
62 | ## 📁 Endpoints disponibles
63 |
64 | - `GET /api/productos` → Lista todos los productos.
65 | - `POST /api/productos` → Crea un nuevo producto.
66 | - `PUT /api/productos/:id` → Actualiza un producto por ID.
67 | - `DELETE /api/productos/:id` → Elimina un producto por ID.
68 |
69 | ---
70 |
71 | ## 🛠️ Tecnologías usadas
72 |
73 | - Node.js
74 | - Express
75 | - PostgreSQL
76 | - pg
77 | - dotenv
78 | - nodemon (opcional)
--------------------------------------------------------------------------------
/prueba4-postgreSql/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "plantilla-node-express",
3 | "version": "1.0.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "plantilla-node-express",
9 | "version": "1.0.0",
10 | "license": "ISC",
11 | "dependencies": {
12 | "cors": "^2.8.5",
13 | "dotenv": "^16.5.0",
14 | "express": "^5.1.0",
15 | "nodemon": "^3.1.9",
16 | "pg": "^8.15.5"
17 | }
18 | },
19 | "node_modules/accepts": {
20 | "version": "2.0.0",
21 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
22 | "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
23 | "dependencies": {
24 | "mime-types": "^3.0.0",
25 | "negotiator": "^1.0.0"
26 | },
27 | "engines": {
28 | "node": ">= 0.6"
29 | }
30 | },
31 | "node_modules/anymatch": {
32 | "version": "3.1.3",
33 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
34 | "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
35 | "dependencies": {
36 | "normalize-path": "^3.0.0",
37 | "picomatch": "^2.0.4"
38 | },
39 | "engines": {
40 | "node": ">= 8"
41 | }
42 | },
43 | "node_modules/balanced-match": {
44 | "version": "1.0.2",
45 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
46 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
47 | },
48 | "node_modules/binary-extensions": {
49 | "version": "2.3.0",
50 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
51 | "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
52 | "engines": {
53 | "node": ">=8"
54 | },
55 | "funding": {
56 | "url": "https://github.com/sponsors/sindresorhus"
57 | }
58 | },
59 | "node_modules/body-parser": {
60 | "version": "2.2.0",
61 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
62 | "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
63 | "dependencies": {
64 | "bytes": "^3.1.2",
65 | "content-type": "^1.0.5",
66 | "debug": "^4.4.0",
67 | "http-errors": "^2.0.0",
68 | "iconv-lite": "^0.6.3",
69 | "on-finished": "^2.4.1",
70 | "qs": "^6.14.0",
71 | "raw-body": "^3.0.0",
72 | "type-is": "^2.0.0"
73 | },
74 | "engines": {
75 | "node": ">=18"
76 | }
77 | },
78 | "node_modules/brace-expansion": {
79 | "version": "1.1.11",
80 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
81 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
82 | "dependencies": {
83 | "balanced-match": "^1.0.0",
84 | "concat-map": "0.0.1"
85 | }
86 | },
87 | "node_modules/braces": {
88 | "version": "3.0.3",
89 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
90 | "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
91 | "dependencies": {
92 | "fill-range": "^7.1.1"
93 | },
94 | "engines": {
95 | "node": ">=8"
96 | }
97 | },
98 | "node_modules/bytes": {
99 | "version": "3.1.2",
100 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
101 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
102 | "engines": {
103 | "node": ">= 0.8"
104 | }
105 | },
106 | "node_modules/call-bind-apply-helpers": {
107 | "version": "1.0.2",
108 | "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
109 | "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
110 | "dependencies": {
111 | "es-errors": "^1.3.0",
112 | "function-bind": "^1.1.2"
113 | },
114 | "engines": {
115 | "node": ">= 0.4"
116 | }
117 | },
118 | "node_modules/call-bound": {
119 | "version": "1.0.4",
120 | "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
121 | "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
122 | "dependencies": {
123 | "call-bind-apply-helpers": "^1.0.2",
124 | "get-intrinsic": "^1.3.0"
125 | },
126 | "engines": {
127 | "node": ">= 0.4"
128 | },
129 | "funding": {
130 | "url": "https://github.com/sponsors/ljharb"
131 | }
132 | },
133 | "node_modules/chokidar": {
134 | "version": "3.6.0",
135 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
136 | "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
137 | "dependencies": {
138 | "anymatch": "~3.1.2",
139 | "braces": "~3.0.2",
140 | "glob-parent": "~5.1.2",
141 | "is-binary-path": "~2.1.0",
142 | "is-glob": "~4.0.1",
143 | "normalize-path": "~3.0.0",
144 | "readdirp": "~3.6.0"
145 | },
146 | "engines": {
147 | "node": ">= 8.10.0"
148 | },
149 | "funding": {
150 | "url": "https://paulmillr.com/funding/"
151 | },
152 | "optionalDependencies": {
153 | "fsevents": "~2.3.2"
154 | }
155 | },
156 | "node_modules/concat-map": {
157 | "version": "0.0.1",
158 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
159 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
160 | },
161 | "node_modules/content-disposition": {
162 | "version": "1.0.0",
163 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
164 | "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==",
165 | "dependencies": {
166 | "safe-buffer": "5.2.1"
167 | },
168 | "engines": {
169 | "node": ">= 0.6"
170 | }
171 | },
172 | "node_modules/content-type": {
173 | "version": "1.0.5",
174 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
175 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
176 | "engines": {
177 | "node": ">= 0.6"
178 | }
179 | },
180 | "node_modules/cookie": {
181 | "version": "0.7.2",
182 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
183 | "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
184 | "engines": {
185 | "node": ">= 0.6"
186 | }
187 | },
188 | "node_modules/cookie-signature": {
189 | "version": "1.2.2",
190 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
191 | "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
192 | "engines": {
193 | "node": ">=6.6.0"
194 | }
195 | },
196 | "node_modules/cors": {
197 | "version": "2.8.5",
198 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
199 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
200 | "dependencies": {
201 | "object-assign": "^4",
202 | "vary": "^1"
203 | },
204 | "engines": {
205 | "node": ">= 0.10"
206 | }
207 | },
208 | "node_modules/debug": {
209 | "version": "4.4.0",
210 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
211 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
212 | "dependencies": {
213 | "ms": "^2.1.3"
214 | },
215 | "engines": {
216 | "node": ">=6.0"
217 | },
218 | "peerDependenciesMeta": {
219 | "supports-color": {
220 | "optional": true
221 | }
222 | }
223 | },
224 | "node_modules/depd": {
225 | "version": "2.0.0",
226 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
227 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
228 | "engines": {
229 | "node": ">= 0.8"
230 | }
231 | },
232 | "node_modules/dotenv": {
233 | "version": "16.5.0",
234 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz",
235 | "integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==",
236 | "engines": {
237 | "node": ">=12"
238 | },
239 | "funding": {
240 | "url": "https://dotenvx.com"
241 | }
242 | },
243 | "node_modules/dunder-proto": {
244 | "version": "1.0.1",
245 | "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
246 | "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
247 | "dependencies": {
248 | "call-bind-apply-helpers": "^1.0.1",
249 | "es-errors": "^1.3.0",
250 | "gopd": "^1.2.0"
251 | },
252 | "engines": {
253 | "node": ">= 0.4"
254 | }
255 | },
256 | "node_modules/ee-first": {
257 | "version": "1.1.1",
258 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
259 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
260 | },
261 | "node_modules/encodeurl": {
262 | "version": "2.0.0",
263 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
264 | "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
265 | "engines": {
266 | "node": ">= 0.8"
267 | }
268 | },
269 | "node_modules/es-define-property": {
270 | "version": "1.0.1",
271 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
272 | "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
273 | "engines": {
274 | "node": ">= 0.4"
275 | }
276 | },
277 | "node_modules/es-errors": {
278 | "version": "1.3.0",
279 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
280 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
281 | "engines": {
282 | "node": ">= 0.4"
283 | }
284 | },
285 | "node_modules/es-object-atoms": {
286 | "version": "1.1.1",
287 | "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
288 | "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
289 | "dependencies": {
290 | "es-errors": "^1.3.0"
291 | },
292 | "engines": {
293 | "node": ">= 0.4"
294 | }
295 | },
296 | "node_modules/escape-html": {
297 | "version": "1.0.3",
298 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
299 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
300 | },
301 | "node_modules/etag": {
302 | "version": "1.8.1",
303 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
304 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
305 | "engines": {
306 | "node": ">= 0.6"
307 | }
308 | },
309 | "node_modules/express": {
310 | "version": "5.1.0",
311 | "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz",
312 | "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==",
313 | "dependencies": {
314 | "accepts": "^2.0.0",
315 | "body-parser": "^2.2.0",
316 | "content-disposition": "^1.0.0",
317 | "content-type": "^1.0.5",
318 | "cookie": "^0.7.1",
319 | "cookie-signature": "^1.2.1",
320 | "debug": "^4.4.0",
321 | "encodeurl": "^2.0.0",
322 | "escape-html": "^1.0.3",
323 | "etag": "^1.8.1",
324 | "finalhandler": "^2.1.0",
325 | "fresh": "^2.0.0",
326 | "http-errors": "^2.0.0",
327 | "merge-descriptors": "^2.0.0",
328 | "mime-types": "^3.0.0",
329 | "on-finished": "^2.4.1",
330 | "once": "^1.4.0",
331 | "parseurl": "^1.3.3",
332 | "proxy-addr": "^2.0.7",
333 | "qs": "^6.14.0",
334 | "range-parser": "^1.2.1",
335 | "router": "^2.2.0",
336 | "send": "^1.1.0",
337 | "serve-static": "^2.2.0",
338 | "statuses": "^2.0.1",
339 | "type-is": "^2.0.1",
340 | "vary": "^1.1.2"
341 | },
342 | "engines": {
343 | "node": ">= 18"
344 | },
345 | "funding": {
346 | "type": "opencollective",
347 | "url": "https://opencollective.com/express"
348 | }
349 | },
350 | "node_modules/fill-range": {
351 | "version": "7.1.1",
352 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
353 | "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
354 | "dependencies": {
355 | "to-regex-range": "^5.0.1"
356 | },
357 | "engines": {
358 | "node": ">=8"
359 | }
360 | },
361 | "node_modules/finalhandler": {
362 | "version": "2.1.0",
363 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
364 | "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==",
365 | "dependencies": {
366 | "debug": "^4.4.0",
367 | "encodeurl": "^2.0.0",
368 | "escape-html": "^1.0.3",
369 | "on-finished": "^2.4.1",
370 | "parseurl": "^1.3.3",
371 | "statuses": "^2.0.1"
372 | },
373 | "engines": {
374 | "node": ">= 0.8"
375 | }
376 | },
377 | "node_modules/forwarded": {
378 | "version": "0.2.0",
379 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
380 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
381 | "engines": {
382 | "node": ">= 0.6"
383 | }
384 | },
385 | "node_modules/fresh": {
386 | "version": "2.0.0",
387 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
388 | "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
389 | "engines": {
390 | "node": ">= 0.8"
391 | }
392 | },
393 | "node_modules/fsevents": {
394 | "version": "2.3.3",
395 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
396 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
397 | "hasInstallScript": true,
398 | "optional": true,
399 | "os": [
400 | "darwin"
401 | ],
402 | "engines": {
403 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
404 | }
405 | },
406 | "node_modules/function-bind": {
407 | "version": "1.1.2",
408 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
409 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
410 | "funding": {
411 | "url": "https://github.com/sponsors/ljharb"
412 | }
413 | },
414 | "node_modules/get-intrinsic": {
415 | "version": "1.3.0",
416 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
417 | "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
418 | "dependencies": {
419 | "call-bind-apply-helpers": "^1.0.2",
420 | "es-define-property": "^1.0.1",
421 | "es-errors": "^1.3.0",
422 | "es-object-atoms": "^1.1.1",
423 | "function-bind": "^1.1.2",
424 | "get-proto": "^1.0.1",
425 | "gopd": "^1.2.0",
426 | "has-symbols": "^1.1.0",
427 | "hasown": "^2.0.2",
428 | "math-intrinsics": "^1.1.0"
429 | },
430 | "engines": {
431 | "node": ">= 0.4"
432 | },
433 | "funding": {
434 | "url": "https://github.com/sponsors/ljharb"
435 | }
436 | },
437 | "node_modules/get-proto": {
438 | "version": "1.0.1",
439 | "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
440 | "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
441 | "dependencies": {
442 | "dunder-proto": "^1.0.1",
443 | "es-object-atoms": "^1.0.0"
444 | },
445 | "engines": {
446 | "node": ">= 0.4"
447 | }
448 | },
449 | "node_modules/glob-parent": {
450 | "version": "5.1.2",
451 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
452 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
453 | "dependencies": {
454 | "is-glob": "^4.0.1"
455 | },
456 | "engines": {
457 | "node": ">= 6"
458 | }
459 | },
460 | "node_modules/gopd": {
461 | "version": "1.2.0",
462 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
463 | "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
464 | "engines": {
465 | "node": ">= 0.4"
466 | },
467 | "funding": {
468 | "url": "https://github.com/sponsors/ljharb"
469 | }
470 | },
471 | "node_modules/has-flag": {
472 | "version": "3.0.0",
473 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
474 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
475 | "engines": {
476 | "node": ">=4"
477 | }
478 | },
479 | "node_modules/has-symbols": {
480 | "version": "1.1.0",
481 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
482 | "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
483 | "engines": {
484 | "node": ">= 0.4"
485 | },
486 | "funding": {
487 | "url": "https://github.com/sponsors/ljharb"
488 | }
489 | },
490 | "node_modules/hasown": {
491 | "version": "2.0.2",
492 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
493 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
494 | "dependencies": {
495 | "function-bind": "^1.1.2"
496 | },
497 | "engines": {
498 | "node": ">= 0.4"
499 | }
500 | },
501 | "node_modules/http-errors": {
502 | "version": "2.0.0",
503 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
504 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
505 | "dependencies": {
506 | "depd": "2.0.0",
507 | "inherits": "2.0.4",
508 | "setprototypeof": "1.2.0",
509 | "statuses": "2.0.1",
510 | "toidentifier": "1.0.1"
511 | },
512 | "engines": {
513 | "node": ">= 0.8"
514 | }
515 | },
516 | "node_modules/iconv-lite": {
517 | "version": "0.6.3",
518 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
519 | "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
520 | "dependencies": {
521 | "safer-buffer": ">= 2.1.2 < 3.0.0"
522 | },
523 | "engines": {
524 | "node": ">=0.10.0"
525 | }
526 | },
527 | "node_modules/ignore-by-default": {
528 | "version": "1.0.1",
529 | "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
530 | "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA=="
531 | },
532 | "node_modules/inherits": {
533 | "version": "2.0.4",
534 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
535 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
536 | },
537 | "node_modules/ipaddr.js": {
538 | "version": "1.9.1",
539 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
540 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
541 | "engines": {
542 | "node": ">= 0.10"
543 | }
544 | },
545 | "node_modules/is-binary-path": {
546 | "version": "2.1.0",
547 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
548 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
549 | "dependencies": {
550 | "binary-extensions": "^2.0.0"
551 | },
552 | "engines": {
553 | "node": ">=8"
554 | }
555 | },
556 | "node_modules/is-extglob": {
557 | "version": "2.1.1",
558 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
559 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
560 | "engines": {
561 | "node": ">=0.10.0"
562 | }
563 | },
564 | "node_modules/is-glob": {
565 | "version": "4.0.3",
566 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
567 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
568 | "dependencies": {
569 | "is-extglob": "^2.1.1"
570 | },
571 | "engines": {
572 | "node": ">=0.10.0"
573 | }
574 | },
575 | "node_modules/is-number": {
576 | "version": "7.0.0",
577 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
578 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
579 | "engines": {
580 | "node": ">=0.12.0"
581 | }
582 | },
583 | "node_modules/is-promise": {
584 | "version": "4.0.0",
585 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
586 | "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="
587 | },
588 | "node_modules/math-intrinsics": {
589 | "version": "1.1.0",
590 | "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
591 | "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
592 | "engines": {
593 | "node": ">= 0.4"
594 | }
595 | },
596 | "node_modules/media-typer": {
597 | "version": "1.1.0",
598 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
599 | "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
600 | "engines": {
601 | "node": ">= 0.8"
602 | }
603 | },
604 | "node_modules/merge-descriptors": {
605 | "version": "2.0.0",
606 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
607 | "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
608 | "engines": {
609 | "node": ">=18"
610 | },
611 | "funding": {
612 | "url": "https://github.com/sponsors/sindresorhus"
613 | }
614 | },
615 | "node_modules/mime-db": {
616 | "version": "1.54.0",
617 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
618 | "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
619 | "engines": {
620 | "node": ">= 0.6"
621 | }
622 | },
623 | "node_modules/mime-types": {
624 | "version": "3.0.1",
625 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
626 | "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
627 | "dependencies": {
628 | "mime-db": "^1.54.0"
629 | },
630 | "engines": {
631 | "node": ">= 0.6"
632 | }
633 | },
634 | "node_modules/minimatch": {
635 | "version": "3.1.2",
636 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
637 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
638 | "dependencies": {
639 | "brace-expansion": "^1.1.7"
640 | },
641 | "engines": {
642 | "node": "*"
643 | }
644 | },
645 | "node_modules/ms": {
646 | "version": "2.1.3",
647 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
648 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
649 | },
650 | "node_modules/negotiator": {
651 | "version": "1.0.0",
652 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
653 | "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
654 | "engines": {
655 | "node": ">= 0.6"
656 | }
657 | },
658 | "node_modules/nodemon": {
659 | "version": "3.1.9",
660 | "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.9.tgz",
661 | "integrity": "sha512-hdr1oIb2p6ZSxu3PB2JWWYS7ZQ0qvaZsc3hK8DR8f02kRzc8rjYmxAIvdz+aYC+8F2IjNaB7HMcSDg8nQpJxyg==",
662 | "dependencies": {
663 | "chokidar": "^3.5.2",
664 | "debug": "^4",
665 | "ignore-by-default": "^1.0.1",
666 | "minimatch": "^3.1.2",
667 | "pstree.remy": "^1.1.8",
668 | "semver": "^7.5.3",
669 | "simple-update-notifier": "^2.0.0",
670 | "supports-color": "^5.5.0",
671 | "touch": "^3.1.0",
672 | "undefsafe": "^2.0.5"
673 | },
674 | "bin": {
675 | "nodemon": "bin/nodemon.js"
676 | },
677 | "engines": {
678 | "node": ">=10"
679 | },
680 | "funding": {
681 | "type": "opencollective",
682 | "url": "https://opencollective.com/nodemon"
683 | }
684 | },
685 | "node_modules/normalize-path": {
686 | "version": "3.0.0",
687 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
688 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
689 | "engines": {
690 | "node": ">=0.10.0"
691 | }
692 | },
693 | "node_modules/object-assign": {
694 | "version": "4.1.1",
695 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
696 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
697 | "engines": {
698 | "node": ">=0.10.0"
699 | }
700 | },
701 | "node_modules/object-inspect": {
702 | "version": "1.13.4",
703 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
704 | "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
705 | "engines": {
706 | "node": ">= 0.4"
707 | },
708 | "funding": {
709 | "url": "https://github.com/sponsors/ljharb"
710 | }
711 | },
712 | "node_modules/on-finished": {
713 | "version": "2.4.1",
714 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
715 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
716 | "dependencies": {
717 | "ee-first": "1.1.1"
718 | },
719 | "engines": {
720 | "node": ">= 0.8"
721 | }
722 | },
723 | "node_modules/once": {
724 | "version": "1.4.0",
725 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
726 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
727 | "dependencies": {
728 | "wrappy": "1"
729 | }
730 | },
731 | "node_modules/parseurl": {
732 | "version": "1.3.3",
733 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
734 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
735 | "engines": {
736 | "node": ">= 0.8"
737 | }
738 | },
739 | "node_modules/path-to-regexp": {
740 | "version": "8.2.0",
741 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz",
742 | "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==",
743 | "engines": {
744 | "node": ">=16"
745 | }
746 | },
747 | "node_modules/pg": {
748 | "version": "8.15.5",
749 | "resolved": "https://registry.npmjs.org/pg/-/pg-8.15.5.tgz",
750 | "integrity": "sha512-EpAhHFQc+aH9VfeffWIVC+XXk6lmAhS9W1FxtxcPXs94yxhrI1I6w/zkWfIOII/OkBv3Be04X3xMOj0kQ78l6w==",
751 | "dependencies": {
752 | "pg-connection-string": "^2.8.5",
753 | "pg-pool": "^3.9.5",
754 | "pg-protocol": "^1.9.5",
755 | "pg-types": "^2.1.0",
756 | "pgpass": "1.x"
757 | },
758 | "engines": {
759 | "node": ">= 8.0.0"
760 | },
761 | "optionalDependencies": {
762 | "pg-cloudflare": "^1.2.5"
763 | },
764 | "peerDependencies": {
765 | "pg-native": ">=3.0.1"
766 | },
767 | "peerDependenciesMeta": {
768 | "pg-native": {
769 | "optional": true
770 | }
771 | }
772 | },
773 | "node_modules/pg-cloudflare": {
774 | "version": "1.2.5",
775 | "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.2.5.tgz",
776 | "integrity": "sha512-OOX22Vt0vOSRrdoUPKJ8Wi2OpE/o/h9T8X1s4qSkCedbNah9ei2W2765be8iMVxQUsvgT7zIAT2eIa9fs5+vtg==",
777 | "optional": true
778 | },
779 | "node_modules/pg-connection-string": {
780 | "version": "2.8.5",
781 | "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.8.5.tgz",
782 | "integrity": "sha512-Ni8FuZ8yAF+sWZzojvtLE2b03cqjO5jNULcHFfM9ZZ0/JXrgom5pBREbtnAw7oxsxJqHw9Nz/XWORUEL3/IFow=="
783 | },
784 | "node_modules/pg-int8": {
785 | "version": "1.0.1",
786 | "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
787 | "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==",
788 | "engines": {
789 | "node": ">=4.0.0"
790 | }
791 | },
792 | "node_modules/pg-pool": {
793 | "version": "3.9.5",
794 | "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.9.5.tgz",
795 | "integrity": "sha512-DxyAlOgvUzRFpFAZjbCc8fUfG7BcETDHgepFPf724B0i08k9PAiZV1tkGGgQIL0jbMEuR9jW1YN7eX+WgXxCsQ==",
796 | "peerDependencies": {
797 | "pg": ">=8.0"
798 | }
799 | },
800 | "node_modules/pg-protocol": {
801 | "version": "1.9.5",
802 | "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.9.5.tgz",
803 | "integrity": "sha512-DYTWtWpfd5FOro3UnAfwvhD8jh59r2ig8bPtc9H8Ds7MscE/9NYruUQWFAOuraRl29jwcT2kyMFQ3MxeaVjUhg=="
804 | },
805 | "node_modules/pg-types": {
806 | "version": "2.2.0",
807 | "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
808 | "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
809 | "dependencies": {
810 | "pg-int8": "1.0.1",
811 | "postgres-array": "~2.0.0",
812 | "postgres-bytea": "~1.0.0",
813 | "postgres-date": "~1.0.4",
814 | "postgres-interval": "^1.1.0"
815 | },
816 | "engines": {
817 | "node": ">=4"
818 | }
819 | },
820 | "node_modules/pgpass": {
821 | "version": "1.0.5",
822 | "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz",
823 | "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==",
824 | "dependencies": {
825 | "split2": "^4.1.0"
826 | }
827 | },
828 | "node_modules/picomatch": {
829 | "version": "2.3.1",
830 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
831 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
832 | "engines": {
833 | "node": ">=8.6"
834 | },
835 | "funding": {
836 | "url": "https://github.com/sponsors/jonschlinkert"
837 | }
838 | },
839 | "node_modules/postgres-array": {
840 | "version": "2.0.0",
841 | "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
842 | "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
843 | "engines": {
844 | "node": ">=4"
845 | }
846 | },
847 | "node_modules/postgres-bytea": {
848 | "version": "1.0.0",
849 | "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
850 | "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==",
851 | "engines": {
852 | "node": ">=0.10.0"
853 | }
854 | },
855 | "node_modules/postgres-date": {
856 | "version": "1.0.7",
857 | "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
858 | "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
859 | "engines": {
860 | "node": ">=0.10.0"
861 | }
862 | },
863 | "node_modules/postgres-interval": {
864 | "version": "1.2.0",
865 | "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
866 | "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
867 | "dependencies": {
868 | "xtend": "^4.0.0"
869 | },
870 | "engines": {
871 | "node": ">=0.10.0"
872 | }
873 | },
874 | "node_modules/proxy-addr": {
875 | "version": "2.0.7",
876 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
877 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
878 | "dependencies": {
879 | "forwarded": "0.2.0",
880 | "ipaddr.js": "1.9.1"
881 | },
882 | "engines": {
883 | "node": ">= 0.10"
884 | }
885 | },
886 | "node_modules/pstree.remy": {
887 | "version": "1.1.8",
888 | "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
889 | "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w=="
890 | },
891 | "node_modules/qs": {
892 | "version": "6.14.0",
893 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
894 | "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
895 | "dependencies": {
896 | "side-channel": "^1.1.0"
897 | },
898 | "engines": {
899 | "node": ">=0.6"
900 | },
901 | "funding": {
902 | "url": "https://github.com/sponsors/ljharb"
903 | }
904 | },
905 | "node_modules/range-parser": {
906 | "version": "1.2.1",
907 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
908 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
909 | "engines": {
910 | "node": ">= 0.6"
911 | }
912 | },
913 | "node_modules/raw-body": {
914 | "version": "3.0.0",
915 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
916 | "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
917 | "dependencies": {
918 | "bytes": "3.1.2",
919 | "http-errors": "2.0.0",
920 | "iconv-lite": "0.6.3",
921 | "unpipe": "1.0.0"
922 | },
923 | "engines": {
924 | "node": ">= 0.8"
925 | }
926 | },
927 | "node_modules/readdirp": {
928 | "version": "3.6.0",
929 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
930 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
931 | "dependencies": {
932 | "picomatch": "^2.2.1"
933 | },
934 | "engines": {
935 | "node": ">=8.10.0"
936 | }
937 | },
938 | "node_modules/router": {
939 | "version": "2.2.0",
940 | "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
941 | "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
942 | "dependencies": {
943 | "debug": "^4.4.0",
944 | "depd": "^2.0.0",
945 | "is-promise": "^4.0.0",
946 | "parseurl": "^1.3.3",
947 | "path-to-regexp": "^8.0.0"
948 | },
949 | "engines": {
950 | "node": ">= 18"
951 | }
952 | },
953 | "node_modules/safe-buffer": {
954 | "version": "5.2.1",
955 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
956 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
957 | "funding": [
958 | {
959 | "type": "github",
960 | "url": "https://github.com/sponsors/feross"
961 | },
962 | {
963 | "type": "patreon",
964 | "url": "https://www.patreon.com/feross"
965 | },
966 | {
967 | "type": "consulting",
968 | "url": "https://feross.org/support"
969 | }
970 | ]
971 | },
972 | "node_modules/safer-buffer": {
973 | "version": "2.1.2",
974 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
975 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
976 | },
977 | "node_modules/semver": {
978 | "version": "7.7.1",
979 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
980 | "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
981 | "bin": {
982 | "semver": "bin/semver.js"
983 | },
984 | "engines": {
985 | "node": ">=10"
986 | }
987 | },
988 | "node_modules/send": {
989 | "version": "1.2.0",
990 | "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
991 | "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
992 | "dependencies": {
993 | "debug": "^4.3.5",
994 | "encodeurl": "^2.0.0",
995 | "escape-html": "^1.0.3",
996 | "etag": "^1.8.1",
997 | "fresh": "^2.0.0",
998 | "http-errors": "^2.0.0",
999 | "mime-types": "^3.0.1",
1000 | "ms": "^2.1.3",
1001 | "on-finished": "^2.4.1",
1002 | "range-parser": "^1.2.1",
1003 | "statuses": "^2.0.1"
1004 | },
1005 | "engines": {
1006 | "node": ">= 18"
1007 | }
1008 | },
1009 | "node_modules/serve-static": {
1010 | "version": "2.2.0",
1011 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
1012 | "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
1013 | "dependencies": {
1014 | "encodeurl": "^2.0.0",
1015 | "escape-html": "^1.0.3",
1016 | "parseurl": "^1.3.3",
1017 | "send": "^1.2.0"
1018 | },
1019 | "engines": {
1020 | "node": ">= 18"
1021 | }
1022 | },
1023 | "node_modules/setprototypeof": {
1024 | "version": "1.2.0",
1025 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
1026 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
1027 | },
1028 | "node_modules/side-channel": {
1029 | "version": "1.1.0",
1030 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
1031 | "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
1032 | "dependencies": {
1033 | "es-errors": "^1.3.0",
1034 | "object-inspect": "^1.13.3",
1035 | "side-channel-list": "^1.0.0",
1036 | "side-channel-map": "^1.0.1",
1037 | "side-channel-weakmap": "^1.0.2"
1038 | },
1039 | "engines": {
1040 | "node": ">= 0.4"
1041 | },
1042 | "funding": {
1043 | "url": "https://github.com/sponsors/ljharb"
1044 | }
1045 | },
1046 | "node_modules/side-channel-list": {
1047 | "version": "1.0.0",
1048 | "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
1049 | "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
1050 | "dependencies": {
1051 | "es-errors": "^1.3.0",
1052 | "object-inspect": "^1.13.3"
1053 | },
1054 | "engines": {
1055 | "node": ">= 0.4"
1056 | },
1057 | "funding": {
1058 | "url": "https://github.com/sponsors/ljharb"
1059 | }
1060 | },
1061 | "node_modules/side-channel-map": {
1062 | "version": "1.0.1",
1063 | "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
1064 | "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
1065 | "dependencies": {
1066 | "call-bound": "^1.0.2",
1067 | "es-errors": "^1.3.0",
1068 | "get-intrinsic": "^1.2.5",
1069 | "object-inspect": "^1.13.3"
1070 | },
1071 | "engines": {
1072 | "node": ">= 0.4"
1073 | },
1074 | "funding": {
1075 | "url": "https://github.com/sponsors/ljharb"
1076 | }
1077 | },
1078 | "node_modules/side-channel-weakmap": {
1079 | "version": "1.0.2",
1080 | "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
1081 | "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
1082 | "dependencies": {
1083 | "call-bound": "^1.0.2",
1084 | "es-errors": "^1.3.0",
1085 | "get-intrinsic": "^1.2.5",
1086 | "object-inspect": "^1.13.3",
1087 | "side-channel-map": "^1.0.1"
1088 | },
1089 | "engines": {
1090 | "node": ">= 0.4"
1091 | },
1092 | "funding": {
1093 | "url": "https://github.com/sponsors/ljharb"
1094 | }
1095 | },
1096 | "node_modules/simple-update-notifier": {
1097 | "version": "2.0.0",
1098 | "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz",
1099 | "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==",
1100 | "dependencies": {
1101 | "semver": "^7.5.3"
1102 | },
1103 | "engines": {
1104 | "node": ">=10"
1105 | }
1106 | },
1107 | "node_modules/split2": {
1108 | "version": "4.2.0",
1109 | "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
1110 | "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
1111 | "engines": {
1112 | "node": ">= 10.x"
1113 | }
1114 | },
1115 | "node_modules/statuses": {
1116 | "version": "2.0.1",
1117 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
1118 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
1119 | "engines": {
1120 | "node": ">= 0.8"
1121 | }
1122 | },
1123 | "node_modules/supports-color": {
1124 | "version": "5.5.0",
1125 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
1126 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
1127 | "dependencies": {
1128 | "has-flag": "^3.0.0"
1129 | },
1130 | "engines": {
1131 | "node": ">=4"
1132 | }
1133 | },
1134 | "node_modules/to-regex-range": {
1135 | "version": "5.0.1",
1136 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
1137 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
1138 | "dependencies": {
1139 | "is-number": "^7.0.0"
1140 | },
1141 | "engines": {
1142 | "node": ">=8.0"
1143 | }
1144 | },
1145 | "node_modules/toidentifier": {
1146 | "version": "1.0.1",
1147 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
1148 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
1149 | "engines": {
1150 | "node": ">=0.6"
1151 | }
1152 | },
1153 | "node_modules/touch": {
1154 | "version": "3.1.1",
1155 | "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz",
1156 | "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==",
1157 | "bin": {
1158 | "nodetouch": "bin/nodetouch.js"
1159 | }
1160 | },
1161 | "node_modules/type-is": {
1162 | "version": "2.0.1",
1163 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
1164 | "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
1165 | "dependencies": {
1166 | "content-type": "^1.0.5",
1167 | "media-typer": "^1.1.0",
1168 | "mime-types": "^3.0.0"
1169 | },
1170 | "engines": {
1171 | "node": ">= 0.6"
1172 | }
1173 | },
1174 | "node_modules/undefsafe": {
1175 | "version": "2.0.5",
1176 | "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
1177 | "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA=="
1178 | },
1179 | "node_modules/unpipe": {
1180 | "version": "1.0.0",
1181 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
1182 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
1183 | "engines": {
1184 | "node": ">= 0.8"
1185 | }
1186 | },
1187 | "node_modules/vary": {
1188 | "version": "1.1.2",
1189 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
1190 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
1191 | "engines": {
1192 | "node": ">= 0.8"
1193 | }
1194 | },
1195 | "node_modules/wrappy": {
1196 | "version": "1.0.2",
1197 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1198 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
1199 | },
1200 | "node_modules/xtend": {
1201 | "version": "4.0.2",
1202 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
1203 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
1204 | "engines": {
1205 | "node": ">=0.4"
1206 | }
1207 | }
1208 | }
1209 | }
1210 |
--------------------------------------------------------------------------------
/prueba4-postgreSql/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "plantilla-node-express",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "nodemon src/index.js",
8 | "db" : "node src/db/db.js"
9 |
10 | },
11 | "keywords": [],
12 | "author": "",
13 | "license": "ISC",
14 | "description": "",
15 | "dependencies": {
16 | "cors": "^2.8.5",
17 | "dotenv": "^16.5.0",
18 | "express": "^5.1.0",
19 | "nodemon": "^3.1.9",
20 | "pg": "^8.15.5"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/prueba4-postgreSql/src/controllers/productosController.js:
--------------------------------------------------------------------------------
1 | // src/controllers/productosController.js
2 | import pool from "../db/db.js";
3 |
4 | export const obtenerProductos = async (req, res) => {
5 | try {
6 | const result = await pool.query("SELECT * FROM productos");
7 | if (result.rows.length > 0) {
8 | res.json(result.rows);
9 | } else {
10 | res.status(404).json({ message: "No tienes productos" });
11 | }
12 | } catch (error) {
13 | res.status(500).json({ error: "Error al obtener productos" });
14 | }
15 | };
16 |
17 | export const obtenerProductoPorId = async (req, res) => {
18 | const { id } = req.params;
19 | try {
20 | const result = await pool.query("SELECT * FROM productos WHERE id = $1", [id]);
21 | if (result.rows.length === 0) {
22 | return res.status(404).json({ mensaje: "No encontrado" });
23 | }
24 | res.json(result.rows[0]);
25 | } catch (error) {
26 | res.status(500).json({ error: "Error al buscar producto" });
27 | }
28 | };
29 |
30 | export const crearProducto = async (req, res) => {
31 | const { nombre, precio, categoria } = req.body;
32 | if (!nombre || !precio) {
33 | return res.status(400).json({ mensaje: "Nombre y precio son requeridos" });
34 | }
35 |
36 | try {
37 | const result = await pool.query(
38 | "INSERT INTO productos (nombre, precio, categoria) VALUES ($1, $2, $3) RETURNING *",
39 | [nombre, precio, categoria || ""]
40 | );
41 | res.status(201).json(result.rows[0]);
42 | } catch (error) {
43 | res.status(500).json({ error: "Error al crear producto" });
44 | }
45 | };
46 |
47 | export const actualizarProducto = async (req, res) => {
48 | const { id } = req.params;
49 | const { nombre, precio, categoria } = req.body;
50 |
51 | try {
52 | const result = await pool.query(
53 | "UPDATE productos SET nombre=$1, precio=$2, categoria=$3 WHERE id=$4 RETURNING *",
54 | [nombre, precio, categoria, id]
55 | );
56 |
57 | if (result.rows.length === 0) {
58 | return res.status(404).json({ mensaje: "Producto no encontrado" });
59 | }
60 |
61 | res.json(result.rows[0]);
62 | } catch (error) {
63 | res.status(500).json({ error: "Error al actualizar producto" });
64 | }
65 | };
66 |
67 | export const eliminarProducto = async (req, res) => {
68 | const { id } = req.params;
69 | try {
70 | const result = await pool.query("DELETE FROM productos WHERE id=$1 RETURNING *", [id]);
71 |
72 | if (result.rows.length === 0) {
73 | return res.status(404).json({ mensaje: "Producto no encontrado" });
74 | }
75 |
76 | res.json({ mensaje: "Producto eliminado" });
77 | } catch (error) {
78 | res.status(500).json({ error: "Error al eliminar producto" });
79 | }
80 | };
81 |
--------------------------------------------------------------------------------
/prueba4-postgreSql/src/db/db.js:
--------------------------------------------------------------------------------
1 | // db/index.js
2 | import pkg from 'pg';
3 | import dotenv from 'dotenv';
4 |
5 | dotenv.config();
6 |
7 | const { Pool } = pkg;
8 |
9 | const pool = new Pool({
10 | connectionString: process.env.DATABASE_URL,
11 | });
12 |
13 | pool.on('connect', () => {
14 | console.log('🟢 Conectado a PostgreSQL');
15 | });
16 |
17 |
18 |
19 |
20 | export default pool;
21 |
--------------------------------------------------------------------------------
/prueba4-postgreSql/src/index.js:
--------------------------------------------------------------------------------
1 | import express from "express";
2 | import cors from "cors";
3 | import dotenv from "dotenv";
4 | import productosRoutes from "./routes/productos.js";
5 | import pool from "./db/db.js";
6 |
7 | dotenv.config();
8 |
9 | const app = express();
10 | app.use(cors());
11 | app.use(express.json());
12 |
13 | app.use("/api/productos", productosRoutes);
14 |
15 | app.get("/", (req, res) => {
16 | res.send("API activa");
17 | });
18 |
19 |
20 | const PORT = process.env.PORT || 3000;
21 | app.listen(PORT, () => {
22 | console.log(`Servidor corriendo en http://localhost:${PORT}`);
23 | });
24 |
--------------------------------------------------------------------------------
/prueba4-postgreSql/src/routes/productos.js:
--------------------------------------------------------------------------------
1 | import express from "express";
2 | import {
3 | obtenerProductos,
4 | obtenerProductoPorId,
5 | crearProducto,
6 | actualizarProducto,
7 | eliminarProducto,
8 | } from "../controllers/productosController.js";
9 |
10 | const router = express.Router();
11 |
12 | router.get("/", obtenerProductos);
13 | router.get("/:id", obtenerProductoPorId);
14 | router.post("/", crearProducto);
15 | router.put("/:id", actualizarProducto);
16 | router.delete("/:id", eliminarProducto);
17 |
18 | export default router;
19 |
--------------------------------------------------------------------------------