public-api-finder 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/package.json +1 -1
- package/skills/public-api-finder/SKILL.md +5 -5
- package/src/cli.js +123 -10
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Find free/public APIs for agents, prototypes, demos, and integrations.
|
|
4
4
|
|
|
5
|
-
Powered by multiple sources:
|
|
5
|
+
Powered by multiple sources plus a curated best-known API layer:
|
|
6
6
|
|
|
7
7
|
- [`public-api-lists/public-api-lists`](https://github.com/public-api-lists/public-api-lists) for fast curated JSON discovery
|
|
8
8
|
- [`public-apis/public-apis`](https://github.com/public-apis/public-apis) for the larger canonical README list
|
|
@@ -11,10 +11,10 @@ Powered by multiple sources:
|
|
|
11
11
|
## Quick start
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
npx --package
|
|
15
|
-
npx --package
|
|
16
|
-
npx --package
|
|
17
|
-
npx --package
|
|
14
|
+
npx --yes --package=public-api-finder -- public-api-finder "weather forecast" --no-auth --https
|
|
15
|
+
npx --yes --package=public-api-finder -- public-api-finder "crypto prices" --category Cryptocurrency --limit 5
|
|
16
|
+
npx --yes --package=public-api-finder -- public-api-finder "jobs" --json
|
|
17
|
+
npx --yes --package=public-api-finder -- public-api-finder "payments" --openapi
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
## Why
|
|
@@ -35,7 +35,7 @@ The skill tells agents to prefer the CLI first, then live-check docs/endpoints b
|
|
|
35
35
|
|
|
36
36
|
```text
|
|
37
37
|
--category <name> Filter by category substring
|
|
38
|
-
--source <name> Filter by source: public-api-lists, public-apis, apis-guru
|
|
38
|
+
--source <name> Filter by source: public-api-lists, public-apis, apis-guru, curated
|
|
39
39
|
--no-auth Only APIs with Auth = No
|
|
40
40
|
--https Only HTTPS APIs
|
|
41
41
|
--cors <value> Filter by CORS: Yes, No, Unknown
|
package/package.json
CHANGED
|
@@ -5,15 +5,15 @@ description: Find and evaluate free/public APIs for projects, demos, agents, pro
|
|
|
5
5
|
|
|
6
6
|
# Public API Finder
|
|
7
7
|
|
|
8
|
-
Use this skill when a task needs a public API candidate. The CLI searches multiple sources: public-api-lists, public-apis,
|
|
8
|
+
Use this skill when a task needs a public API candidate. The CLI searches multiple sources: public-api-lists, public-apis, APIs.guru OpenAPI directory, and a curated best-known API layer for common domains like crypto, stocks, weather, maps, jobs, sports, media, news, government, and commerce. Use the CLI first, then live-check docs/endpoints before coding.
|
|
9
9
|
|
|
10
10
|
## Quick command
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
|
-
npx --package
|
|
14
|
-
npx --package
|
|
15
|
-
npx --package
|
|
16
|
-
npx --package
|
|
13
|
+
npx --yes --package=public-api-finder -- public-api-finder "weather forecast" --no-auth --https
|
|
14
|
+
npx --yes --package=public-api-finder -- public-api-finder "crypto prices" --category Cryptocurrency --limit 5
|
|
15
|
+
npx --yes --package=public-api-finder -- public-api-finder "jobs" --json
|
|
16
|
+
npx --yes --package=public-api-finder -- public-api-finder "payments" --openapi
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
If npm is unavailable, use the bundled fallback script:
|
package/src/cli.js
CHANGED
|
@@ -13,21 +13,116 @@ const CACHE_TTL_MS = 24 * 60 * 60 * 1000;
|
|
|
13
13
|
|
|
14
14
|
const DOMAIN_PROFILES = {
|
|
15
15
|
crypto: {
|
|
16
|
-
triggers: ['crypto', 'cryptocurrency', 'cryptocurrencies', 'bitcoin', 'ethereum', 'blockchain', 'defi', 'token', 'tokens', 'coin', 'coins', 'wallet'],
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
boostTerms: ['crypto', 'cryptocurrency', 'bitcoin', 'ethereum', 'blockchain', 'defi', 'token', 'coin', 'exchange', 'price', 'market'],
|
|
16
|
+
triggers: ['crypto', 'cryptocurrency', 'cryptocurrencies', 'bitcoin', 'ethereum', 'solana', 'blockchain', 'defi', 'token', 'tokens', 'coin', 'coins', 'wallet'],
|
|
17
|
+
categoryWeights: { cryptocurrency: 18, 'currency exchange': 5, finance: 3, financial: 3 },
|
|
18
|
+
boostTerms: ['crypto', 'cryptocurrency', 'bitcoin', 'ethereum', 'solana', 'blockchain', 'defi', 'token', 'coin', 'exchange', 'price', 'market', 'wallet'],
|
|
20
19
|
weakTerms: ['price', 'prices'],
|
|
21
20
|
},
|
|
22
21
|
finance: {
|
|
23
|
-
triggers: ['stock', 'stocks', 'equity', 'equities', 'market', 'trading', 'ticker', 'tickers', 'quote', 'quotes', 'etf', 'forex', 'portfolio'],
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
boostTerms: ['stock', 'stocks', 'equity', 'market', 'trading', 'ticker', 'quote', 'quotes', 'forex', 'portfolio'],
|
|
22
|
+
triggers: ['stock', 'stocks', 'equity', 'equities', 'market', 'trading', 'ticker', 'tickers', 'quote', 'quotes', 'etf', 'forex', 'portfolio', 'options'],
|
|
23
|
+
categoryWeights: { finance: 16, financial: 16, 'currency exchange': 5 },
|
|
24
|
+
boostTerms: ['stock', 'stocks', 'equity', 'market', 'trading', 'ticker', 'quote', 'quotes', 'forex', 'portfolio', 'options', 'historical'],
|
|
27
25
|
weakTerms: ['quote', 'quotes', 'price', 'prices', 'market'],
|
|
28
26
|
},
|
|
27
|
+
weather: {
|
|
28
|
+
triggers: ['weather', 'forecast', 'radar', 'temperature', 'climate', 'alerts', 'precipitation', 'hourly', 'daily'],
|
|
29
|
+
categoryWeights: { weather: 18, location: 4 },
|
|
30
|
+
boostTerms: ['weather', 'forecast', 'radar', 'temperature', 'climate', 'alerts', 'precipitation', 'meteorological'],
|
|
31
|
+
weakTerms: ['daily', 'hourly'],
|
|
32
|
+
},
|
|
33
|
+
maps: {
|
|
34
|
+
triggers: ['maps', 'map', 'geocoding', 'reverse', 'address', 'coordinates', 'places', 'routing', 'distance', 'timezone', 'location', 'navigation'],
|
|
35
|
+
categoryWeights: { geocoding: 18, location: 12, 'open data': 3 },
|
|
36
|
+
boostTerms: ['map', 'maps', 'geocoding', 'geocoder', 'reverse', 'address', 'coordinates', 'routing', 'places', 'location', 'navigation', 'timezone'],
|
|
37
|
+
weakTerms: ['location'],
|
|
38
|
+
},
|
|
39
|
+
jobs: {
|
|
40
|
+
triggers: ['jobs', 'careers', 'employment', 'hiring', 'salary', 'resume', 'remote', 'companies', 'internships', 'recruitment'],
|
|
41
|
+
categoryWeights: { jobs: 20 },
|
|
42
|
+
boostTerms: ['jobs', 'careers', 'employment', 'hiring', 'salary', 'resume', 'remote', 'recruitment'],
|
|
43
|
+
weakTerms: ['remote'],
|
|
44
|
+
},
|
|
45
|
+
sports: {
|
|
46
|
+
triggers: ['sports', 'scores', 'teams', 'leagues', 'fixtures', 'odds', 'football', 'basketball', 'baseball', 'soccer', 'standings', 'stats'],
|
|
47
|
+
categoryWeights: { 'sports & fitness': 18, entertainment: 4 },
|
|
48
|
+
boostTerms: ['sports', 'scores', 'teams', 'leagues', 'fixtures', 'odds', 'football', 'basketball', 'baseball', 'soccer', 'standings', 'stats'],
|
|
49
|
+
weakTerms: ['scores', 'stats'],
|
|
50
|
+
},
|
|
51
|
+
media: {
|
|
52
|
+
triggers: ['movies', 'movie', 'tv', 'shows', 'streaming', 'actors', 'ratings', 'posters', 'trailers', 'anime', 'imdb', 'films', 'episodes'],
|
|
53
|
+
categoryWeights: { entertainment: 16, anime: 14, media: 12, video: 8 },
|
|
54
|
+
boostTerms: ['movie', 'movies', 'tv', 'show', 'shows', 'streaming', 'actors', 'ratings', 'posters', 'trailers', 'anime', 'imdb', 'film', 'films', 'episodes'],
|
|
55
|
+
weakTerms: ['media'],
|
|
56
|
+
},
|
|
57
|
+
news: {
|
|
58
|
+
triggers: ['news', 'headlines', 'articles', 'breaking', 'media', 'newspapers', 'topics', 'politics', 'world', 'latest'],
|
|
59
|
+
categoryWeights: { news: 20, media: 6 },
|
|
60
|
+
boostTerms: ['news', 'headlines', 'articles', 'breaking', 'newspapers', 'topics', 'politics', 'world', 'latest'],
|
|
61
|
+
weakTerms: ['media', 'search'],
|
|
62
|
+
},
|
|
63
|
+
government: {
|
|
64
|
+
triggers: ['government', 'census', 'legislation', 'representatives', 'elections', 'bills', 'federal', 'agencies', 'public', 'civic'],
|
|
65
|
+
categoryWeights: { government: 18, 'open data': 10 },
|
|
66
|
+
boostTerms: ['government', 'census', 'legislation', 'representatives', 'elections', 'bills', 'federal', 'agencies', 'public data', 'civic'],
|
|
67
|
+
weakTerms: ['public', 'data'],
|
|
68
|
+
},
|
|
69
|
+
commerce: {
|
|
70
|
+
triggers: ['commerce', 'products', 'product', 'prices', 'deals', 'coupons', 'barcode', 'ecommerce', 'shopping', 'reviews', 'inventory', 'catalog', 'store'],
|
|
71
|
+
categoryWeights: { ecommerce: 18, shopping: 16, 'test data': 14, food: 10, 'food & drink': 10, 'open data': 3 },
|
|
72
|
+
boostTerms: ['commerce', 'products', 'product', 'prices', 'deals', 'coupons', 'barcode', 'ecommerce', 'shopping', 'reviews', 'inventory', 'catalog', 'store'],
|
|
73
|
+
weakTerms: ['price', 'prices'],
|
|
74
|
+
},
|
|
29
75
|
};
|
|
30
76
|
|
|
77
|
+
const CURATED_APIS = [
|
|
78
|
+
{ name: 'CoinMarketCap', url: 'https://coinmarketcap.com/api/', description: 'Popular cryptocurrency market data, rankings, quotes, metadata, and exchange data.', auth: 'apiKey', https: true, cors: 'Unknown', category: 'Cryptocurrency', source: 'curated', sourceWeight: 5 },
|
|
79
|
+
{ name: 'CoinGecko', url: 'https://www.coingecko.com/en/api', description: 'Popular cryptocurrency prices, market data, tokens, exchanges, and DeFi data.', auth: 'apiKey', https: true, cors: 'Yes', category: 'Cryptocurrency', source: 'curated', sourceWeight: 5 },
|
|
80
|
+
|
|
81
|
+
{ name: 'Coinpaprika', url: 'https://api.coinpaprika.com/', description: 'Cryptocurrency prices, coins, market data, exchanges, and historical data.', auth: 'No', https: true, cors: 'Yes', category: 'Cryptocurrency', source: 'curated', sourceWeight: 5 },
|
|
82
|
+
{ name: 'CoinCap', url: 'https://docs.coincap.io/', description: 'Real-time cryptocurrency prices, assets, rates, exchanges, and markets.', auth: 'No', https: true, cors: 'Unknown', category: 'Cryptocurrency', source: 'curated', sourceWeight: 5 },
|
|
83
|
+
{ name: 'Coinbase', url: 'https://docs.cloud.coinbase.com/', description: 'Coinbase crypto exchange, wallet, price, account, and trading APIs.', auth: 'apiKey', https: true, cors: 'Unknown', category: 'Cryptocurrency', source: 'curated', sourceWeight: 5 },
|
|
84
|
+
{ name: 'Alpha Vantage', url: 'https://www.alphavantage.co/documentation/', description: 'Stock, ETF, forex, crypto, technical indicators, and market data API.', auth: 'apiKey', https: true, cors: 'Unknown', category: 'Finance', source: 'curated', sourceWeight: 5 },
|
|
85
|
+
{ name: 'Polygon', url: 'https://polygon.io/docs/', description: 'Stock market, options, forex, crypto, tickers, trades, aggregates, and historical market data.', auth: 'apiKey', https: true, cors: 'Unknown', category: 'Finance', source: 'curated', sourceWeight: 5 },
|
|
86
|
+
{ name: 'Twelve Data', url: 'https://twelvedata.com/docs', description: 'Stock, forex, ETF, index, and crypto market data with real-time and historical prices.', auth: 'apiKey', https: true, cors: 'Unknown', category: 'Finance', source: 'curated', sourceWeight: 5 },
|
|
87
|
+
{ name: 'Tradier', url: 'https://developer.tradier.com/', description: 'US equity, options, quotes, market data, trading, and brokerage API.', auth: 'OAuth', https: true, cors: 'Yes', category: 'Finance', source: 'curated', sourceWeight: 5 },
|
|
88
|
+
{ name: 'Finnhub', url: 'https://finnhub.io/docs/api', description: 'Real-time stock, forex, crypto, company fundamentals, news, and alternative market data.', auth: 'apiKey', https: true, cors: 'Unknown', category: 'Finance', source: 'curated', sourceWeight: 5 },
|
|
89
|
+
{ name: 'Open-Meteo', url: 'https://open-meteo.com/en/docs', description: 'Free weather forecast, historical weather, climate, geocoding, and marine weather APIs.', auth: 'No', https: true, cors: 'Yes', category: 'Weather', source: 'curated', sourceWeight: 5 },
|
|
90
|
+
{ name: 'National Weather Service API', url: 'https://www.weather.gov/documentation/services-web-api', description: 'US weather alerts, forecasts, observations, radar stations, and gridpoint weather data.', auth: 'No', https: true, cors: 'Yes', category: 'Weather', source: 'curated', sourceWeight: 5 },
|
|
91
|
+
{ name: 'Pirate Weather', url: 'https://pirateweather.net/en/latest/', description: 'Weather forecast API compatible with Dark Sky-style forecast data.', auth: 'No', https: true, cors: 'Yes', category: 'Weather', source: 'curated', sourceWeight: 5 },
|
|
92
|
+
{ name: 'Geocod.io', url: 'https://www.geocod.io/docs/', description: 'Forward and reverse geocoding, address parsing, coordinates, and census data.', auth: 'apiKey', https: true, cors: 'Unknown', category: 'Geocoding', source: 'curated', sourceWeight: 5 },
|
|
93
|
+
{ name: 'GraphHopper', url: 'https://docs.graphhopper.com/', description: 'Routing, navigation, route optimization, matrix, geocoding, and map matching APIs.', auth: 'apiKey', https: true, cors: 'Unknown', category: 'Geocoding', source: 'curated', sourceWeight: 5 },
|
|
94
|
+
{ name: 'GraphQL Jobs', url: 'https://graphql.jobs/docs/api/', description: 'GraphQL job listings and employment search API.', auth: 'No', https: true, cors: 'Yes', category: 'Jobs', source: 'curated', sourceWeight: 5 },
|
|
95
|
+
{ name: 'Search.gov Jobs', url: 'https://search.gov/developer/jobs.html', description: 'US government job openings and federal jobs search API.', auth: 'No', https: true, cors: 'Unknown', category: 'Jobs', source: 'curated', sourceWeight: 5 },
|
|
96
|
+
{ name: 'API-FOOTBALL', url: 'https://www.api-football.com/documentation-v3', description: 'Football/soccer fixtures, standings, teams, players, odds, predictions, and stats.', auth: 'apiKey', https: true, cors: 'Unknown', category: 'Sports & Fitness', source: 'curated', sourceWeight: 5 },
|
|
97
|
+
{ name: 'Football-Data', url: 'https://www.football-data.org/documentation/quickstart', description: 'Football competitions, teams, fixtures, matches, standings, and scores.', auth: 'apiKey', https: true, cors: 'Unknown', category: 'Sports & Fitness', source: 'curated', sourceWeight: 5 },
|
|
98
|
+
{ name: 'TVMaze', url: 'https://www.tvmaze.com/api', description: 'TV shows, episodes, schedules, cast, search, and show metadata API.', auth: 'No', https: true, cors: 'Yes', category: 'Entertainment', source: 'curated', sourceWeight: 5 },
|
|
99
|
+
{ name: 'Jikan', url: 'https://docs.api.jikan.moe/', description: 'Unofficial MyAnimeList anime, manga, characters, rankings, and search API.', auth: 'No', https: true, cors: 'Yes', category: 'Anime', source: 'curated', sourceWeight: 5 },
|
|
100
|
+
{ name: 'AniList', url: 'https://docs.anilist.co/', description: 'Anime and manga GraphQL API for titles, characters, studios, staff, and lists.', auth: 'OAuth', https: true, cors: 'Yes', category: 'Anime', source: 'curated', sourceWeight: 5 },
|
|
101
|
+
{ name: 'GNews', url: 'https://gnews.io/docs/', description: 'News headlines, article search, topics, countries, and languages API.', auth: 'apiKey', https: true, cors: 'Unknown', category: 'News', source: 'curated', sourceWeight: 5 },
|
|
102
|
+
{ name: 'Currents', url: 'https://currentsapi.services/en/docs/', description: 'Latest news, headlines, search, topics, regions, and languages API.', auth: 'apiKey', https: true, cors: 'Unknown', category: 'News', source: 'curated', sourceWeight: 5 },
|
|
103
|
+
{ name: 'Data.gov', url: 'https://api.data.gov/docs/', description: 'US government API catalog and API key access for federal public data APIs.', auth: 'apiKey', https: true, cors: 'Unknown', category: 'Government', source: 'curated', sourceWeight: 5 },
|
|
104
|
+
{ name: 'Open Food Facts', url: 'https://world.openfoodfacts.org/data', description: 'Food product database with barcodes, ingredients, nutrition, labels, and product metadata.', auth: 'No', https: true, cors: 'Yes', category: 'Food & Drink', source: 'curated', sourceWeight: 5 },
|
|
105
|
+
{ name: 'Barcode Lookup', url: 'https://www.barcodelookup.com/api', description: 'Barcode, UPC, EAN, product lookup, catalog, pricing, images, and store product data.', auth: 'apiKey', https: true, cors: 'Unknown', category: 'Shopping', source: 'curated', sourceWeight: 5 },
|
|
106
|
+
{ name: 'OpenWeather', url: 'https://openweathermap.org/api', description: 'Weather forecasts, current weather, historical weather, alerts, geocoding, and maps.', auth: 'apiKey', https: true, cors: 'Unknown', category: 'Weather', source: 'curated', sourceWeight: 5 },
|
|
107
|
+
{ name: 'News API', url: 'https://newsapi.org/', description: 'News headlines and article search across publishers and topics.', auth: 'apiKey', https: true, cors: 'Unknown', category: 'News', source: 'curated', sourceWeight: 5 },
|
|
108
|
+
{ name: 'The Guardian Open Platform', url: 'https://open-platform.theguardian.com/', description: 'Guardian articles, sections, tags, search, and content API.', auth: 'apiKey', https: true, cors: 'Unknown', category: 'News', source: 'curated', sourceWeight: 5 },
|
|
109
|
+
{ name: 'TMDb', url: 'https://developer.themoviedb.org/docs', description: 'Movie and TV metadata, ratings, posters, images, actors, and discovery.', auth: 'apiKey', https: true, cors: 'Unknown', category: 'Entertainment', source: 'curated', sourceWeight: 5 },
|
|
110
|
+
{ name: 'OMDb', url: 'https://www.omdbapi.com/', description: 'Movie and TV metadata by IMDb ID or title.', auth: 'apiKey', https: true, cors: 'Unknown', category: 'Entertainment', source: 'curated', sourceWeight: 5 },
|
|
111
|
+
{ name: 'OpenStreetMap Nominatim', url: 'https://nominatim.org/release-docs/latest/api/Overview/', description: 'OpenStreetMap geocoding and reverse geocoding API.', auth: 'No', https: true, cors: 'Yes', category: 'Geocoding', source: 'curated', sourceWeight: 5 },
|
|
112
|
+
{ name: 'Mapbox', url: 'https://docs.mapbox.com/api/', description: 'Maps, geocoding, routing, navigation, tiles, and location APIs.', auth: 'apiKey', https: true, cors: 'Yes', category: 'Geocoding', source: 'curated', sourceWeight: 5 },
|
|
113
|
+
{ name: 'USAJOBS', url: 'https://developer.usajobs.gov/', description: 'US federal government job listings and hiring data.', auth: 'apiKey', https: true, cors: 'Unknown', category: 'Jobs', source: 'curated', sourceWeight: 5 },
|
|
114
|
+
{ name: 'Adzuna', url: 'https://developer.adzuna.com/', description: 'Job search, salary, vacancies, and employment market data.', auth: 'apiKey', https: true, cors: 'Unknown', category: 'Jobs', source: 'curated', sourceWeight: 5 },
|
|
115
|
+
{ name: 'TheSportsDB', url: 'https://www.thesportsdb.com/api.php', description: 'Sports teams, leagues, events, scores, players, and media.', auth: 'apiKey', https: true, cors: 'Yes', category: 'Sports & Fitness', source: 'curated', sourceWeight: 5 },
|
|
116
|
+
{ name: 'balldontlie', url: 'https://www.balldontlie.io/', description: 'Basketball/NBA teams, players, games, stats, and seasons.', auth: 'No', https: true, cors: 'Yes', category: 'Sports & Fitness', source: 'curated', sourceWeight: 5 },
|
|
117
|
+
{ name: 'Census Data API', url: 'https://www.census.gov/data/developers/data-sets.html', description: 'US Census datasets, demographics, geography, ACS, and economic data.', auth: 'No', https: true, cors: 'Yes', category: 'Government', source: 'curated', sourceWeight: 5 },
|
|
118
|
+
{ name: 'OpenFEC', url: 'https://api.open.fec.gov/developers/', description: 'US campaign finance, candidates, committees, filings, and election data.', auth: 'apiKey', https: true, cors: 'Unknown', category: 'Government', source: 'curated', sourceWeight: 5 },
|
|
119
|
+
{ name: 'Fake Store API', url: 'https://fakestoreapi.com/', description: 'Fake ecommerce products, carts, users, and categories for demos and prototypes.', auth: 'No', https: true, cors: 'Yes', category: 'Shopping', source: 'curated', sourceWeight: 5 },
|
|
120
|
+
{ name: 'Open Food Facts', url: 'https://world.openfoodfacts.org/data', description: 'Food product database with barcodes, ingredients, nutrition, and labels.', auth: 'No', https: true, cors: 'Yes', category: 'Food', source: 'curated', sourceWeight: 5 },
|
|
121
|
+
];
|
|
122
|
+
|
|
123
|
+
function compactName(value) { return String(value || '').toLowerCase().replace(/[^a-z0-9]+/g, ''); }
|
|
124
|
+
const KNOWN_BEST_NAMES = new Map(CURATED_APIS.map(api => [compactName(api.name), 8]));
|
|
125
|
+
|
|
31
126
|
function detectDomains(queryTokens) {
|
|
32
127
|
return Object.entries(DOMAIN_PROFILES)
|
|
33
128
|
.filter(([, profile]) => profile.triggers.some(t => queryTokens.has(t)))
|
|
@@ -67,7 +162,7 @@ Usage:
|
|
|
67
162
|
|
|
68
163
|
Options:
|
|
69
164
|
--category <name> Filter by category substring
|
|
70
|
-
--source <name> Filter by source: public-api-lists, public-apis, apis-guru
|
|
165
|
+
--source <name> Filter by source: public-api-lists, public-apis, apis-guru, curated
|
|
71
166
|
--no-auth Only APIs with Auth = No
|
|
72
167
|
--https Only HTTPS APIs
|
|
73
168
|
--cors <value> Filter by CORS: Yes, No, Unknown
|
|
@@ -126,12 +221,26 @@ function textScore(entry, queryTokens) {
|
|
|
126
221
|
+ intersectionCount(queryTokens, all);
|
|
127
222
|
}
|
|
128
223
|
|
|
224
|
+
function asciiRatio(value) {
|
|
225
|
+
const s = String(value || '');
|
|
226
|
+
if (!s.length) return 1;
|
|
227
|
+
let ascii = 0;
|
|
228
|
+
for (const ch of s) if (ch.charCodeAt(0) <= 127) ascii++;
|
|
229
|
+
return ascii / s.length;
|
|
230
|
+
}
|
|
231
|
+
|
|
129
232
|
function score(entry, queryTokens) {
|
|
130
233
|
let base = textScore(entry, queryTokens);
|
|
131
234
|
if (entry.openapiUrl) base += 2;
|
|
132
235
|
if (entry.sources?.length > 1) base += 2;
|
|
133
236
|
if (entry.auth === 'No') base += 1;
|
|
134
237
|
if (entry.https) base += 1;
|
|
238
|
+
if (asciiRatio(entry.name) < 0.7) base -= 28;
|
|
239
|
+
else if (asciiRatio(`${entry.name || ''} ${entry.description || ''}`) < 0.65) base -= 18;
|
|
240
|
+
const compactEntryName = compactName(entry.name);
|
|
241
|
+
for (const [name, weight] of KNOWN_BEST_NAMES) {
|
|
242
|
+
if (compactEntryName.includes(name) || name.includes(compactEntryName)) base += weight;
|
|
243
|
+
}
|
|
135
244
|
return base + domainAdjustment(entry, queryTokens);
|
|
136
245
|
}
|
|
137
246
|
|
|
@@ -252,12 +361,16 @@ async function buildData() {
|
|
|
252
361
|
sourceStatus['apis-guru'] = rows.length;
|
|
253
362
|
entries.push(...rows);
|
|
254
363
|
} else sourceStatus['apis-guru'] = `error: ${guru.reason.message}`;
|
|
364
|
+
sourceStatus.curated = CURATED_APIS.length;
|
|
365
|
+
entries.push(...CURATED_APIS);
|
|
255
366
|
return { generatedAt: new Date().toISOString(), sourceStatus, entries: dedupe(entries) };
|
|
256
367
|
}
|
|
257
368
|
|
|
258
369
|
function keyFor(entry) {
|
|
370
|
+
const compact = compactName(entry.name);
|
|
371
|
+
if (KNOWN_BEST_NAMES.has(compact)) return `known:${compact}`;
|
|
259
372
|
const host = String(entry.url || '').toLowerCase().replace(/^https?:\/\//, '').replace(/^www\./, '').split('/')[0];
|
|
260
|
-
return `${
|
|
373
|
+
return `${compact}|${host}`;
|
|
261
374
|
}
|
|
262
375
|
|
|
263
376
|
function mergeEntry(a, b) {
|