diff --git a/README.md b/README.md
index 51528c8..3591d99 100644
--- a/README.md
+++ b/README.md
@@ -90,7 +90,7 @@ I also tried to make it as **generic** and **reusable** as possible to cover mos
- Support for a range of foundational and embedding models (DeepSeek, Llama, Mistral, Sentence Transformers, etc.) via LangChain, Together.AI, and Hugging Face
- **API Examples**
- **Backoffice:** Lob (USPS Mail), Paypal, Quickbooks, Stripe, Twilio (text messaging)
- - **Data, Media & Entertainment:** Alpha Vantage (stocks and finance info) with ChartJS, Github, Foursquare, Last.fm, New York Times, PubChem (chemical information), Trakt.tv (movies/TV), Twitch, Tumblr (OAuth 1.0a example), Web Scraping
+ - **Data, Media & Entertainment:** Alpha Vantage (stocks and finance info) with ChartJS, Github, Foursquare, Last.fm, New York Times, PubChem (chemical information), Trakt.tv (movies/TV), Twitch, Tumblr (OAuth 1.0a example), Web Scraping, Wikipedia
- **Maps and Location:** Google Maps, HERE Maps
- **Productivity:** Google Drive, Google Sheets
@@ -459,6 +459,19 @@ The OpenAI moderation API for checking harmful inputs is free to use as long as
+
+
+**Wikipedia API** uses the public REST API which doesn't require any API keys or authentication. The Wikipedia API provides access to Wikipedia content and metadata.
+
+- **No setup required** - The Wikipedia REST API is completely free and open
+- **API Documentation**: Visit Wikipedia REST API for full documentation
+- **Rate Limits**: Please be respectful of Wikipedia's servers and don't make excessive requests
+- **Example endpoints used**:
+ - Search: `https://en.wikipedia.org/api/rest_v1/page/search/{query}`
+ - Page summary: `https://en.wikipedia.org/api/rest_v1/page/summary/{title}`
+
+
+
## Web Analytics
This project supports integrating web analytics tools such as Google Analytics 4 and Facebook Pixel, along with Open Graph metadata for social sharing. Below are instructions to help you set up these features in your application.
diff --git a/app.js b/app.js
index 97150d8..3f3b501 100644
--- a/app.js
+++ b/app.js
@@ -232,6 +232,7 @@ app.get('/api/chart', apiController.getChart);
app.get('/api/google/sheets', passportConfig.isAuthenticated, passportConfig.isAuthorized, apiController.getGoogleSheets);
app.get('/api/quickbooks', passportConfig.isAuthenticated, passportConfig.isAuthorized, apiController.getQuickbooks);
app.get('/api/trakt', apiController.getTrakt);
+app.get('/api/wikipedia', apiController.getWikipedia);
app.get('/api/pubchem', apiController.getPubChem);
/**
diff --git a/controllers/ai.js b/controllers/ai.js
index b2e02e0..d936486 100644
--- a/controllers/ai.js
+++ b/controllers/ai.js
@@ -11,8 +11,14 @@ const { ChatTogetherAI } = require('@langchain/community/chat_models/togetherai'
const { HumanMessage } = require('@langchain/core/messages');
const { CacheBackedEmbeddings } = require('langchain/embeddings/cache_backed');
const { MongoClient } = require('mongodb');
-// eslint-disable-next-line import/extensions
-const pdfjsLib = require('pdfjs-dist/legacy/build/pdf.mjs');
+// Using dynamic import for pdfjs-dist due to ESM compatibility
+let pdfjsLib;
+const getPdfjsLib = async () => {
+ if (!pdfjsLib) {
+ pdfjsLib = await import('pdfjs-dist/legacy/build/pdf.mjs');
+ }
+ return pdfjsLib;
+};
/**
* GET /ai
@@ -243,8 +249,9 @@ exports.postRagIngest = async (req, res) => {
// Process the PDF file
try {
+ const pdfjs = await getPdfjsLib();
const loader = new PDFLoader(filePath, {
- pdfjs: () => Promise.resolve(pdfjsLib),
+ pdfjs: () => Promise.resolve(pdfjs),
});
const docs = await loader.load();
// Split the document into chunks
diff --git a/controllers/api.js b/controllers/api.js
index 02c6f46..520ec69 100644
--- a/controllers/api.js
+++ b/controllers/api.js
@@ -4,11 +4,16 @@ const cheerio = require('cheerio');
const { LastFmNode } = require('lastfm');
const multer = require('multer');
const { OAuth } = require('oauth');
-// Disable eslint rule for @octakit/rest until the following github issue is resolved
-// github npm package bug: https://github.com/octokit/rest.js/issues/446
-// eslint-disable-next-line import/no-unresolved
-const { Octokit } = require('@octokit/rest');
-const stripe = require('stripe')(process.env.STRIPE_SKEY);
+// Using dynamic import for @octokit/rest due to ESM compatibility
+let OctokitClass;
+const getOctokit = async () => {
+ if (!OctokitClass) {
+ const { Octokit } = await import('@octokit/rest');
+ OctokitClass = Octokit;
+ }
+ return OctokitClass;
+};
+const stripe = process.env.STRIPE_SKEY ? require('stripe')(process.env.STRIPE_SKEY) : null;
const twilioClient = require('twilio')(process.env.TWILIO_SID, process.env.TWILIO_TOKEN);
const googledrive = require('@googleapis/drive');
const googlesheets = require('@googleapis/sheets');
@@ -168,6 +173,7 @@ exports.getGithub = async (req, res, next) => {
let userInfo;
let userRepos;
let userEvents;
+ const Octokit = await getOctokit();
if (githubToken) {
github = new Octokit({
auth: req.user.tokens.find((token) => token.kind === 'github').accessToken,
@@ -481,6 +487,10 @@ exports.getStripe = (req, res) => {
* Make a payment.
*/
exports.postStripe = (req, res) => {
+ if (!stripe) {
+ req.flash('errors', { msg: 'Stripe API key not configured.' });
+ return res.redirect('/api/stripe');
+ }
const { stripeToken, stripeEmail } = req.body;
stripe.charges.create(
{
@@ -1444,6 +1454,40 @@ exports.getTrakt = async (req, res, next) => {
}
};
+/**
+ * GET /api/wikipedia
+ * Wikipedia API example.
+ */
+exports.getWikipedia = async (req, res, next) => {
+ const searchTerm = req.query.search || 'Node.js';
+
+ try {
+ // Search for articles
+ const searchResponse = await fetch(`https://en.wikipedia.org/api/rest_v1/page/search/${encodeURIComponent(searchTerm)}?limit=5`);
+ if (!searchResponse.ok) throw new Error('Wikipedia search failed');
+ const searchResults = await searchResponse.json();
+
+ // Get summary for the first result if available
+ let summary = null;
+ if (searchResults.pages && searchResults.pages.length > 0) {
+ const firstResult = searchResults.pages[0];
+ const summaryResponse = await fetch(`https://en.wikipedia.org/api/rest_v1/page/summary/${encodeURIComponent(firstResult.key)}`);
+ if (summaryResponse.ok) {
+ summary = await summaryResponse.json();
+ }
+ }
+
+ res.render('api/wikipedia', {
+ title: 'Wikipedia API',
+ searchTerm,
+ searchResults: searchResults.pages || [],
+ summary
+ });
+ } catch (error) {
+ next(error);
+ }
+};
+
/**
* GET /api/pubchem
* PubChem API example - Chemical information for Aspirin.
diff --git a/package-lock.json b/package-lock.json
index 1e77b4d..3b6b313 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -95,6 +95,7 @@
"resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.27.3.tgz",
"integrity": "sha512-IjLt0gd3L4jlOfilxVXTifn42FnVffMgDC04RJK1KDZpmkBWLv0XC92MVVmkxrFZNS/7l3xWgP/I3nqtX1sQHw==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@types/node": "^18.11.18",
"@types/node-fetch": "^2.6.4",
@@ -166,6 +167,7 @@
"resolved": "https://registry.npmjs.org/@browserbasehq/sdk/-/sdk-2.6.0.tgz",
"integrity": "sha512-83iXP5D7xMm8Wyn66TUaUrgoByCmAJuoMoZQI3sGg3JAiMlTfnCIMqyVBoNSaItaPIkaCnrsj6LiusmXV2X9YA==",
"license": "Apache-2.0",
+ "peer": true,
"dependencies": {
"@types/node": "^18.11.18",
"@types/node-fetch": "^2.6.4",
@@ -489,7 +491,6 @@
"resolved": "https://registry.npmjs.org/@huggingface/inference/-/inference-4.11.0.tgz",
"integrity": "sha512-pgtNIYt0jkDBq+sbOX8un3W3NulRrRBkSJEo6Rvze9rjvXT5k71XeSm7QsG2bz6jOcJ1KOqoNDPPSSXT4dw34Q==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@huggingface/jinja": "^0.5.1",
"@huggingface/tasks": "^0.19.49"
@@ -1179,7 +1180,6 @@
"resolved": "https://registry.npmjs.org/@langchain/core/-/core-0.3.78.tgz",
"integrity": "sha512-Nn0x9erQlK3zgtRU1Z8NUjLuyW0gzdclMsvLQ6wwLeDqV91pE+YKl6uQb+L2NUDs4F0N7c2Zncgz46HxrvPzuA==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@cfworker/json-schema": "^4.0.2",
"ansi-styles": "^5.0.0",
@@ -1845,7 +1845,6 @@
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.5.tgz",
"integrity": "sha512-t54CUOsFMappY1Jbzb7fetWeO0n6K0k/4+/ZpkS+3Joz8I4VcvY9OiEBFRYISqaI2fq5sCiPtAjRDOzVYG8m+Q==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@octokit/auth-token": "^6.0.0",
"@octokit/graphql": "^9.0.2",
@@ -2336,7 +2335,6 @@
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.56.0.tgz",
"integrity": "sha512-Tzh95Twig7hUwwNe381/K3PggZBZblKUe2wv25oIpzWLr6Z0m4KgV1ZVIjnR6GM9ANEqjZD7XsZEa6JL/7YEgg==",
"license": "Apache-2.0",
- "peer": true,
"dependencies": {
"playwright": "1.56.0"
},
@@ -2352,7 +2350,6 @@
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
"integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
"license": "MIT",
- "peer": true,
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/popperjs"
@@ -2501,7 +2498,8 @@
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
"integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/@tybys/wasm-util": {
"version": "0.10.1",
@@ -2518,6 +2516,7 @@
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
"integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@types/ms": "*"
}
@@ -2554,7 +2553,8 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
"integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/@types/node": {
"version": "18.19.129",
@@ -2570,6 +2570,7 @@
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.13.tgz",
"integrity": "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@types/node": "*",
"form-data": "^4.0.4"
@@ -2585,7 +2586,8 @@
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz",
"integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/@types/uuid": {
"version": "10.0.0",
@@ -2628,6 +2630,7 @@
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"event-target-shim": "^5.0.0"
},
@@ -2668,7 +2671,6 @@
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"license": "MIT",
- "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -2700,6 +2702,7 @@
"resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz",
"integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"humanize-ms": "^1.2.1"
},
@@ -2954,7 +2957,6 @@
"resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz",
"integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==",
"license": "MIT",
- "peer": true,
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.4",
@@ -3196,6 +3198,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.2.1"
@@ -3413,7 +3416,6 @@
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.1.2.tgz",
"integrity": "sha512-IkxPpb5rS/d1IiLbHMgfPuS0FgiWTtFIm/Nj+2woXDLTZ7fOT2eqzgYbdMlLweqlHbsZjxEChoVK+7iph7jyQg==",
"license": "MIT",
- "peer": true,
"dependencies": {
"cheerio-select": "^2.1.0",
"dom-serializer": "^2.0.0",
@@ -4114,7 +4116,6 @@
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz",
"integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==",
"license": "BSD-2-Clause",
- "peer": true,
"engines": {
"node": ">=12"
},
@@ -4391,7 +4392,6 @@
"integrity": "sha512-XyLmROnACWqSxiGYArdef1fItQd47weqB7iwtfr9JHwRrqIXZdcFMvvEcL9xHCmL0SNsOvF0c42lWyM1U5dgig==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
@@ -4688,6 +4688,7 @@
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=6"
}
@@ -4703,6 +4704,7 @@
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=0.8.x"
}
@@ -4799,7 +4801,6 @@
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.2.tgz",
"integrity": "sha512-SZjssGQC7TzTs9rpPDuUrR23GNZ9+2+IkA/+IJWmvQilTr5OSliEHGF+D9scbIpdC6yGtTI0/VhaHoVes2AN/A==",
"license": "MIT",
- "peer": true,
"dependencies": {
"cookie": "0.7.2",
"cookie-signature": "1.0.7",
@@ -4989,6 +4990,7 @@
"resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz",
"integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"readable-web-to-node-stream": "^3.0.0",
"strtok3": "^6.2.4",
@@ -5205,13 +5207,15 @@
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz",
"integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/formdata-node": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-6.0.3.tgz",
"integrity": "sha512-8e1++BCiTzUno9v5IZ2J6bv4RU+3UKDmqWUQD0MIMVCd9AdhWkO1gw57oo1mNEX1dMq2EGI+FbWz4B92pscSQg==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">= 18"
}
@@ -5370,6 +5374,7 @@
"integrity": "sha512-FNTkdNEnBdlqF2oatizolQqNANMrcqJt6AAYt99B3y1aLLC8Hc5IOBb+ZnnzllodEEf6xMBp6wRcBbc16fa65w==",
"license": "Apache-2.0",
"optional": true,
+ "peer": true,
"dependencies": {
"gaxios": "^5.0.0",
"json-bigint": "^1.0.0"
@@ -5384,6 +5389,7 @@
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"license": "MIT",
"optional": true,
+ "peer": true,
"dependencies": {
"debug": "4"
},
@@ -5397,6 +5403,7 @@
"integrity": "sha512-95hVgBRgEIRQQQHIbnxBXeHbW4TqFk4ZDJW7wmVtvYar72FdhRIo1UGOLS2eRAKCPEdPBWu+M7+A33D9CdX9rA==",
"license": "Apache-2.0",
"optional": true,
+ "peer": true,
"dependencies": {
"extend": "^3.0.2",
"https-proxy-agent": "^5.0.0",
@@ -5413,6 +5420,7 @@
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
"license": "MIT",
"optional": true,
+ "peer": true,
"dependencies": {
"agent-base": "6",
"debug": "4"
@@ -5665,7 +5673,6 @@
"resolved": "https://registry.npmjs.org/graphql/-/graphql-16.11.0.tgz",
"integrity": "sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==",
"license": "MIT",
- "peer": true,
"engines": {
"node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0"
}
@@ -5876,6 +5883,7 @@
"resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
"integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"ms": "^2.0.0"
}
@@ -5953,7 +5961,8 @@
"url": "https://feross.org/support"
}
],
- "license": "BSD-3-Clause"
+ "license": "BSD-3-Clause",
+ "peer": true
},
"node_modules/ignore": {
"version": "5.3.2",
@@ -5961,7 +5970,6 @@
"integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
"devOptional": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">= 4"
}
@@ -6406,6 +6414,7 @@
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
"license": "MIT",
"optional": true,
+ "peer": true,
"engines": {
"node": ">=8"
},
@@ -6551,7 +6560,8 @@
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
"integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/istanbul-lib-coverage": {
"version": "3.2.2",
@@ -7403,7 +7413,6 @@
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.20.0.tgz",
"integrity": "sha512-Tl6MEIU3K4Rq3TSHd+sZQqRBoGlFsOgNrH5ltAcFBV62Re3Fd+FcaVf8uSEQFOJ51SDowDVttBTONMfoYWrWlQ==",
"license": "Apache-2.0",
- "peer": true,
"dependencies": {
"@mongodb-js/saslprep": "^1.3.0",
"bson": "^6.10.4",
@@ -8449,6 +8458,7 @@
"resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz",
"integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=8"
},
@@ -8576,7 +8586,6 @@
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.56.0.tgz",
"integrity": "sha512-X5Q1b8lOdWIE4KAoHpW3SE8HvUB+ZZsUoN64ZhjnN8dOb1UpujxBtENGiZFE+9F/yhzJwYa+ca3u43FeLbboHA==",
"license": "Apache-2.0",
- "peer": true,
"dependencies": {
"playwright-core": "1.56.0"
},
@@ -8628,7 +8637,6 @@
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"bin": {
"prettier": "bin/prettier.cjs"
},
@@ -8644,6 +8652,7 @@
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">= 0.6.0"
}
@@ -8705,6 +8714,7 @@
"resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz",
"integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"punycode": "^2.3.1"
},
@@ -8864,7 +8874,8 @@
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/queue-microtask": {
"version": "1.2.3",
@@ -8964,6 +8975,7 @@
"resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.4.tgz",
"integrity": "sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"readable-stream": "^4.7.0"
},
@@ -8980,6 +8992,7 @@
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
"integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"abort-controller": "^3.0.0",
"buffer": "^6.0.3",
@@ -9061,7 +9074,8 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/resolve": {
"version": "1.22.10",
@@ -9107,6 +9121,7 @@
"resolved": "https://registry.npmjs.org/retry-axios/-/retry-axios-2.6.0.tgz",
"integrity": "sha512-pOLi+Gdll3JekwuFjXO3fTq+L9lzMQGcSq7M5gIjExcl3Gu1hd4XXuf5o3+LuSBsaULQH7DiNbsqPd1chVpQGQ==",
"license": "Apache-2.0",
+ "peer": true,
"engines": {
"node": ">=10.7.0"
},
@@ -9827,6 +9842,7 @@
"resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz",
"integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@tokenizer/token": "^0.3.0",
"peek-readable": "^4.1.0"
@@ -10002,6 +10018,7 @@
"resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz",
"integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@tokenizer/token": "^0.3.0",
"ieee754": "^1.2.1"
@@ -10019,6 +10036,7 @@
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz",
"integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==",
"license": "BSD-3-Clause",
+ "peer": true,
"dependencies": {
"psl": "^1.1.33",
"punycode": "^2.1.1",
@@ -10034,6 +10052,7 @@
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
"integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">= 4.0.0"
}
@@ -10375,6 +10394,7 @@
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"querystringify": "^2.1.1",
"requires-port": "^1.0.0"
@@ -10789,6 +10809,7 @@
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
"integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=10.0.0"
},
@@ -10973,7 +10994,6 @@
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
"license": "MIT",
- "peer": true,
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
diff --git a/views/api/index.pug b/views/api/index.pug
index fcaa666..8fb42fc 100644
--- a/views/api/index.pug
+++ b/views/api/index.pug
@@ -131,6 +131,12 @@ block content
.card-body
img(src='https://i.imgur.com/Adtl9qg.png', height=40, style='padding: 0px 10px 0px 0px')
| trakt.tv
+ .col-md-4
+ a(href='/api/wikipedia', style='color: #000')
+ .card.mb-3(style='background-color: #f8f9fa')
+ .card-body
+ img(src='https://upload.wikimedia.org/wikipedia/commons/8/80/Wikipedia-logo-v2.svg', height=40, style='padding: 0px 10px 0px 0px')
+ | Wikipedia
.col-md-4
a(href='/api/pubchem', style='color: #fff')
.card.text-white.mb-3(style='background-color: rgba(128, 200, 255, 1)')
diff --git a/views/api/wikipedia.pug b/views/api/wikipedia.pug
new file mode 100644
index 0000000..5414311
--- /dev/null
+++ b/views/api/wikipedia.pug
@@ -0,0 +1,47 @@
+extends ../layout
+
+block content
+ .pb-2.mt-2.mb-4.border-bottom
+ h3 Wikipedia API
+ p.lead Search and retrieve information from Wikipedia
+
+ .row
+ .col-md-12
+ form(method='GET', action='/api/wikipedia')
+ .input-group.mb-3
+ input.form-control(type='text', name='search', placeholder='Search Wikipedia...', value=searchTerm)
+ button.btn.btn-primary(type='submit') Search
+
+ if summary
+ .row
+ .col-md-12
+ .card.mb-4
+ .card-header
+ h4= summary.title
+ .card-body
+ .row
+ if summary.thumbnail
+ .col-md-3
+ img.img-fluid.rounded(src=summary.thumbnail.source, alt=summary.title)
+ .col-md-9
+ p= summary.extract
+ if summary.content_urls && summary.content_urls.desktop
+ a.btn.btn-outline-primary(href=summary.content_urls.desktop.page, target='_blank') Read Full Article
+
+ if searchResults && searchResults.length > 0
+ .row
+ .col-md-12
+ h4 Search Results
+ .list-group
+ each result in searchResults
+ .list-group-item
+ .d-flex.w-100.justify-content-between
+ h5.mb-1= result.title
+ small= result.key
+ p.mb-1= result.excerpt
+ if result.thumbnail
+ img.img-thumbnail(src=result.thumbnail.url, alt=result.title, style='max-width: 100px; height: auto;')
+ else if searchTerm
+ .row
+ .col-md-12
+ .alert.alert-info No results found for "#{searchTerm}"
\ No newline at end of file