diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 39023d7..0000000 --- a/.gitignore +++ /dev/null @@ -1,50 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.* -.yarn/* -!.yarn/patches -!.yarn/plugins -!.yarn/releases -!.yarn/versions - -# testing -/coverage - -# next.js -/.next/ -/out/* -!/out/.assetsignore -/.open-next -# production -/build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* -.pnpm-debug.log* - -# env files (can opt-in for committing if needed) -.env* - -# vercel -.vercel - -# typescript -*.tsbuildinfo -next-env.d.ts - -.wrangler - -public/robots.txt -public/sitemap-0.xml -public/sitemap.xml -# Sentry Config File -.env.sentry-build-plugin diff --git a/public/.nojekyll b/.nojekyll similarity index 100% rename from public/.nojekyll rename to .nojekyll diff --git a/.well-known/ai-openapi.yaml b/.well-known/ai-openapi.yaml new file mode 100644 index 0000000..66d6194 --- /dev/null +++ b/.well-known/ai-openapi.yaml @@ -0,0 +1,328 @@ +openapi: 3.0.0 +x-optic-url: https://app.useoptic.com/organizations/febf8ac6-ee67-4565-b45a-5c85a469dca7/apis/_0fKWqUvhs9ssYNkq1k-c +x-optic-standard: "@febf8ac6-ee67-4565-b45a-5c85a469dca7/Fz6KU3_wMIO5iJ6_VUZ30" +info: + version: 2.2.0 + title: APIs.guru + description: > + Wikipedia for Web APIs. Repository of API definitions in OpenAPI format. + + **Warning**: If you want to be notified about changes in advance please join our [Slack channel](https://join.slack.com/t/mermade/shared_invite/zt-g78g7xir-MLE_CTCcXCdfJfG3CJe9qA). + + Client sample: [[Demo]](https://apis.guru/simple-ui) [[Repo]](https://github.com/APIs-guru/simple-ui) + contact: + name: APIs.guru + url: https://APIs.guru + email: mike.ralphson@gmail.com + license: + name: CC0 1.0 + url: https://github.com/APIs-guru/openapi-directory#licenses + x-logo: + url: https://apis.guru/branding/logo_vertical.svg +externalDocs: + url: https://github.com/APIs-guru/openapi-directory/blob/master/API.md +servers: + - url: https://api.apis.guru/v2 +security: [] +tags: + - name: APIs + description: Actions relating to APIs in the collection +paths: + /providers.json: + get: + operationId: getProviders + tags: + - APIs + summary: List all providers + description: | + List all the providers in the directory + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + type: string + minLength: 1 + minItems: 1 + "/{provider}.json": + get: + operationId: getProvider + tags: + - APIs + summary: List all APIs for a particular provider + description: | + List all APIs in the directory for a particular providerName + Returns links to the individual API entry for each API. + parameters: + - $ref: "#/components/parameters/provider" + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/APIs" + "/{provider}/services.json": + get: + operationId: getServices + tags: + - APIs + summary: List all serviceNames for a particular provider + description: | + List all serviceNames in the directory for a particular providerName + parameters: + - $ref: "#/components/parameters/provider" + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + type: string + minLength: 0 + minItems: 1 + "/specs/{provider}/{api}.json": + get: + operationId: getAPI + tags: + - APIs + summary: Retrieve one version of a particular API + description: Returns the API entry for one specific version of an API where + there is no serviceName. + parameters: + - $ref: "#/components/parameters/provider" + - $ref: "#/components/parameters/api" + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/API" + "/specs/{provider}/{service}/{api}.json": + get: + operationId: getServiceAPI + tags: + - APIs + summary: Retrieve one version of a particular API with a serviceName. + description: Returns the API entry for one specific version of an API where + there is a serviceName. + parameters: + - $ref: "#/components/parameters/provider" + - name: service + in: path + required: true + schema: + type: string + minLength: 1 + maxLength: 255 + - $ref: "#/components/parameters/api" + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/API" + /list.json: + get: + operationId: listAPIs + tags: + - APIs + summary: List all APIs + description: > + List all APIs in the directory. + + Returns links to the OpenAPI definitions for each API in the directory. + + If API exist in multiple versions `preferred` one is explicitly marked. + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/APIs" + /metrics.json: + get: + operationId: getMetrics + summary: Get basic metrics + description: > + Some basic metrics for the entire directory. + + These counts hold the number of APIs in the directory and other metadata. + tags: + - APIs + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/Metrics" +components: + schemas: + APIs: + description: | + List of API details. + It is a JSON object with API IDs(`[:]`) as keys. + type: object + additionalProperties: + $ref: "#/components/schemas/API" + minProperties: 1 + API: + description: Meta information about API + type: object + required: + - added + - preferred + - versions + properties: + added: + description: Timestamp when the API was first added to the directory + type: string + format: date-time + preferred: + description: Recommended version + type: string + versions: + description: List of supported versions of the API + type: object + additionalProperties: + $ref: "#/components/schemas/ApiVersion" + minProperties: 1 + additionalProperties: false + ApiVersion: + type: object + required: + - added + - updated + - swaggerUrl + - swaggerYamlUrl + - info + - openapiVer + properties: + added: + description: Timestamp when the version was added + type: string + format: date-time + updated: + description: Timestamp when the version was updated + type: string + format: date-time + swaggerUrl: + description: URL to OpenAPI definition in JSON format + type: string + format: url + swaggerYamlUrl: + description: URL to OpenAPI definition in YAML format + type: string + format: url + link: + description: Link to the individual API entry for this API + type: string + format: url + info: + description: Copy of `info` section from OpenAPI definition + type: object + minProperties: 1 + externalDocs: + description: Copy of `externalDocs` section from OpenAPI definition + type: object + minProperties: 1 + openapiVer: + description: The value of the `openapi` or `swagger` property of the source + definition + type: string + additionalProperties: false + Metrics: + description: List of basic metrics + type: object + required: + - numSpecs + - numAPIs + - numEndpoints + properties: + numSpecs: + description: Number of API definitions including different versions of the same + API + type: integer + minimum: 1 + numAPIs: + description: Number of unique APIs + type: integer + minimum: 1 + numEndpoints: + description: Total number of endpoints inside all definitions + type: integer + minimum: 1 + unreachable: + description: Number of unreachable (4XX,5XX status) APIs + type: integer + invalid: + description: Number of newly invalid APIs + type: integer + unofficial: + description: Number of unofficial APIs + type: integer + fixes: + description: Total number of fixes applied across all APIs + type: integer + fixedPct: + description: Percentage of all APIs where auto fixes have been applied + type: integer + datasets: + description: Data used for charting etc + type: array + items: {} + stars: + description: GitHub stars for our main repo + type: integer + issues: + description: Open GitHub issues on our main repo + type: integer + thisWeek: + description: Summary totals for the last 7 days + type: object + properties: + added: + description: APIs added in the last week + type: integer + updated: + description: APIs updated in the last week + type: integer + numDrivers: + description: Number of methods of API retrieval + type: integer + numProviders: + description: Number of API providers in directory + type: integer + additionalProperties: false + parameters: + provider: + name: provider + in: path + required: true + schema: + type: string + minLength: 1 + maxLength: 255 + api: + name: api + in: path + required: true + schema: + type: string + minLength: 1 + maxLength: 255 diff --git a/.well-known/ai-plugin.json b/.well-known/ai-plugin.json new file mode 100644 index 0000000..bd8a10f --- /dev/null +++ b/.well-known/ai-plugin.json @@ -0,0 +1,18 @@ +{ + "schema_version": "v1", + "name_for_human": "APIs.guru Plugin", + "name_for_model": "apis_guru", + "description_for_human": "Plugin for accessing APIs.guru OpenAPI Directory.", + "description_for_model": "Plugin for accessing APIs.guru OpenAPI Directory. Use the /list.json endpoint to find APIs. Use the /metrics.json endpoint to find metadata about APIs such as counts, how many APIs, providers or services there are in the directory, API totals and chart data. Use the /providers.json endpoint to find out about providers, companies, or authors. Use the /{provider}/services.json endpoint to find out about API services for a particular provider. Use the /{provider}/{service}.json endpoint to find a specific API for a given provider and service (which may be blank/empty).", + "auth": { + "type": "none" + }, + "api": { + "type": "openapi", + "url": "https://apis.guru/.well-known/ai-openapi.yaml", + "is_user_authenticated": false + }, + "logo_url": "https://api.apis.guru/logo.svg", + "contact_email": "mike.ralphson@gmail.com", + "legal_info_url": "https://apis.guru/" +} diff --git a/404.html b/404.html new file mode 100644 index 0000000..5e9b37c --- /dev/null +++ b/404.html @@ -0,0 +1,82 @@ + + + + + + + + +APIs.guru + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + logo-sad + + +

404: Page not found

+

Sorry, we've misplaced that URL or it's pointing to something + that doesn't exist. Head back home to try finding it + again.
+ We have moved to the APIs.guru domain recently. Check out + migration guide. +

+
+
+ + + + + + + + + + + + + diff --git a/CLOUDFLARE_WORKERS.md b/CLOUDFLARE_WORKERS.md deleted file mode 100644 index 611abd2..0000000 --- a/CLOUDFLARE_WORKERS.md +++ /dev/null @@ -1,41 +0,0 @@ -# Cloudflare Workers D1 Database Setup - -## Prerequisites - -- Node.js 18+ -- Cloudflare account with Workers access -- Wrangler CLI: `npm install -g wrangler` - -## Database Setup Commands - -```bash -# Create production database -wrangler d1 create apis-guru-data - -# Initialize production schema -wrangler d1 execute apis-guru-data --file=./schema.sql - -# Create development database -wrangler d1 create apis-guru-data-dev - -# Initialize development schema -wrangler d1 execute apis-guru-data-dev --file=./schema.sql -``` - -## Manual Configuration - -1. Copy `database_id` from create commands -2. Update `wrangler.toml` with production and development `database_id` - -## Next Steps - -```bash -# Deploy Workers -wrangler deploy - -# Start development server -wrangler dev - -# Test API endpoint -curl -X POST http://localhost:8788/api/sync-apis -``` diff --git a/CNAME b/CNAME new file mode 100644 index 0000000..b5315e3 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +old.apis.guru \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index f718aaf..0000000 --- a/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# APIs.guru Website - -Visit: [https://apis.guru/](https://apis.guru/) - -## Getting Started (Development) - -Clone the repository and install dependencies: - -```bash -git clone https://github.com/APIs-guru/APIs-guru.github.io.git -cd APIs-guru.github.io -``` - -Run the development server: - -```bash - -npm install -npm run dev -# or: yarn dev / pnpm dev / bun dev -``` - -Open [http://localhost:3000](http://localhost:3000) in your browser. diff --git a/_drafts/2016-10-26-generator-openapi-repo/index.html b/_drafts/2016-10-26-generator-openapi-repo/index.html new file mode 100644 index 0000000..ad7922e --- /dev/null +++ b/_drafts/2016-10-26-generator-openapi-repo/index.html @@ -0,0 +1,235 @@ + + + + + + + + +APIs.guru + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + +
+ +
+ + + +
+ +
+
+ APIs.guru banner + + + +
+ + + + Our blog has migrated to blog.apis.guru + + +
+ +
+

+ +
+ +
+

As you probably know, we are absolutely in love with GitHub. +We host 100% of our projects there and try to promote GitHub among our friends and customers. That's why we are happy that more and more developers choose to publish their API specifications on GitHub. In our quest to catch all pokemons specifications we've discovered that nearly one-third of specifications in our directory were found on GitHub!

+

Many big companies have followed this trend: SendGrid, Dropbox, Spotify. +Even Microsoft has published Azure OpenAPI specificatoins on GitHub. Need we say more?

+

It's very easy to publish your specifications on GitHub and instantly get many benefits from this. +But at some point, every API owner has to write scripts for: bundling, validation, deployment, etc.

+

That's why we got excited when Rebilly inc. contracted us to create GitHub repo for their OpenAPI spec. +This opportunity allowed us to develop Yeoman generator for GitHub repository that has many exciting features for API owners. +And that's how generator-openapi-repo was born.

+

generator-openapi-repo

+ +

With our generator, you need only 20 minutes to generate full featured API repository on GitHub.

+

generator screenshot

+

Instead of describing all the features we encourage you to try it out on your OpenAPI spec.

+

Star the project on GitHub <3:

+
+ +
+ +
+ + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + diff --git a/_posts/2016-07-18-welcome/index.html b/_posts/2016-07-18-welcome/index.html new file mode 100644 index 0000000..fc09241 --- /dev/null +++ b/_posts/2016-07-18-welcome/index.html @@ -0,0 +1,253 @@ + + + + + + + + +APIs.guru + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + +
+ +
+ + + +
+ +
+
+ APIs.guru banner + + + +
+ + + + Our blog has migrated to blog.apis.guru + + +
+ +
+

+ +
+ +
+

APIs.guru banner

+

Hello, readers! +After a couple years we finally break the vow of silence :)

+

As you probably saw on our main page we are building directory of machine-readable API definitions or how we like to call it "Wikipedia for Web APIs".

+

You probably think:

+
+

I understand every individual word like Wikipedia, Web and even API but what the heck your are building and how it can be useful for me?

+
+

And you are not the only one! It's the most frequent question we hear. We improvise a lot so often we don't know the answer ourselves :). That's why we decided to start this blog: to share our vision and ideas.

+ +

What will this blog be about?

+

Beyond primary goal of explaining our vision behind APIs.guru there are couple more topics we plan to write on:

+
    +
  • machine-readable specs and APIs in general;
  • +
  • some statistics: we have a few interesting numbers we'd like to share;
  • +
  • answer questions about APIs.guru, feel free to ask them in comments;
  • +
  • news and updates: there are a few exiting projects we plan to release in the next few months
  • +
+

Something to read right now

+

You can read our guest post at swagger.io and any of a few 3rd-party articles:

+ +

In addition, here is a great article to get a bigger picture: +Tips to Improve the Discoverability of Your API.

+

Also, we have spoken at a couple of events and here are slides from the most recent one:

+ +

Teaser

+

Our next post will be about a tool that we have been developing for last year. This will change the way you document your API. +If you don't want to miss our next blog posts subscribe to our Twitter: as a bonus, you will see notifications for all new APIs added to our directory.

+
+

Do you have any questions? Don't hesitate to ask them in comments.

+ +
+ +
+ + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + diff --git a/_posts/2016-07-29-redoc-release/index.html b/_posts/2016-07-29-redoc-release/index.html new file mode 100644 index 0000000..5578d59 --- /dev/null +++ b/_posts/2016-07-29-redoc-release/index.html @@ -0,0 +1,267 @@ + + + + + + + + +APIs.guru + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + +
+ +
+ + + +
+ +
+
+ APIs.guru banner + + + +
+ + + + Our blog has migrated to blog.apis.guru + + +
+ +
+

+ +
+ +
+

SwaggerUI proves the possibility to use OpenAPI specs as a single source for generating API documentation. Although we love SwaggerUI we should admit an obvious fact: SwaggerUI is rather an API console than an API documentation.

+

A long time ago in a galaxy far, far away....

+

Rebilly adopted Swagger as a definition language for their API, and they were looking for a documentation engine. +But they wanted to go beyond the industry standards and document their API to the fullest. Here’s how they did it:

+
    +
  • every field in JSON payloads;
  • +
  • in their quest, they had to use almost every OpenAPI feature including lots of Mr. discriminator ;)
  • +
  • resulting spec is really huge: 12K+ lines and growing! (one of the biggest we've seen in the wild). And believe us - they use all the possible tricks to reduce duplications.
  • +
+

So, they approached us with this challenging project: to build a brand new documentation engine - ReDoc.

+

redoc

+ +

Check out demo!

+

The best part?

+

Together with Rebilly we realized the full potential of ReDoc since other API owners face exactly same problems. That's why we've decided to open-source it and stick with vanilla OpenAPI. +We'd love to thank Rebilly and personally Adam Altman for sponsoring this open-source project! +After months of work now we feel confident to make 1.0.0 release.

+

Why should I use ReDoc?

+

Let’s take a look!

+

Extremely easy deployment

+

No, it's really easy. Don't believe us? Take a look at the minimal setup:

+ +

That's all folks! We've bundled everything (html, css, javascript) into a single file! Also, we're serving the latest release (and all previous releases) from our CDN.

+

Why else?

+
    +
  • It's free and open-source project under MIT license
  • +
  • The widest OpenAPI features support (yes, it supports even discriminator)
  • +
  • Neat documentation for nested objects
  • +
  • Meaningful request/response samples generated using openapi-sampler
  • +
  • Code samples support (via vendor extension)
  • +
  • Responsive three-panel design with menu/scrolling synchronization
  • +
  • Integrate API introduction into side menu - ReDoc takes advantage of markdown headings from OpenAPI description field. It pulls them into side menu and also supports deep linking.
  • +
+

Roadmap

+

Currently, we have the following global key points on our TO-DO list:

+
    +
  • Docs pre-rendering (performance and SEO)
  • +
  • Built-in API Console
  • +
  • Support for external styling
  • +
+

What's next? It depends on you! Don't hesitate to open issues and feature requests on GitHub. PRs are welcome too :)

+

Moreover, you can hire APIs.guru to do integration or customization of ReDoc for you needs.

+

Stay tuned

+

At the beginning of the next week, we will release a support tool which will help you to easily setup OpenAPI spec repository with lots of appetizing features.

+
+

If you need any help with integration ReDoc feel free to ask! Subscribe to our twitter so as not to miss ReDoc new releases and other news. Will you try ReDoc? Tell us in comments bellow :)

+

Star the project on GitHub <3:

+
+ +
+ +
+ + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + diff --git a/_posts/2016-09-05-repo-rename/index.html b/_posts/2016-09-05-repo-rename/index.html new file mode 100644 index 0000000..f1484b0 --- /dev/null +++ b/_posts/2016-09-05-repo-rename/index.html @@ -0,0 +1,248 @@ + + + + + + + + +APIs.guru + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + +
+ +
+ + + +
+ +
+
+ APIs.guru banner + + + +
+ + + + Our blog has migrated to blog.apis.guru + + +
+ +
+

+ +
+ +
+
+

"There is nothing more permanent than a temporary solution".

+
+

You may ask, why our main repo is called so weird: api-models? +It is easy to explain api part but models is something strange and alien in this context. +If you see api-models in search results you will probably never expect it to be a collection of API specs.

+

But why we made this mistake when we created the repo? +At the beginning we were planning to build website with DB to store our collection and Repo was just a temporary solution. +So we basically used the first thing that came to our mind and didn't think it would have any long-term consequences.

+

But we feel it's time to rip off the bandaid:

+

repo rename

+ +
+# API models VS API directory +What's the difference? +Let's try to google both terms and see the results: +

models vs directory

+

"API directory" appears to be much more relevant.

+
+# Why "directory"? +

The answer is simple. We've just used Google Trends to find what keywords are more popular: +google trends

+
+# And what's about "openapi"? +

Since we use "OpenAPI" as the primary format for our collection we want to be on the first page of GitHub search results by keyword "OpenAPI" (4th page at the moment). +As far as we know GitHub sorts search results by where the match occurs: in the project name, project description or inside README.md. +So placing right keywords in the right places is more important than number of stars, see screenshot:

+

GitHub search

+
+

What do you think about the new name? We'd like to hear your opinion in comments.

+ +
+ +
+ + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + diff --git a/_posts/2016-09-29-restfest/index.html b/_posts/2016-09-29-restfest/index.html new file mode 100644 index 0000000..daf87a6 --- /dev/null +++ b/_posts/2016-09-29-restfest/index.html @@ -0,0 +1,243 @@ + + + + + + + + +APIs.guru + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + +
+ +
+ + + +
+ +
+
+ APIs.guru banner + + + +
+ + + + Our blog has migrated to blog.apis.guru + + +
+ +
+

+ +
+ +
+

We have just returned to Ukraine from our trip to the USA. +The most exiting part was RestFest conference in Greenville, SC.

+

RestFest 2016

+

It was great opportunity to speak with API experts and also to do a few talks.

+ +

JSON Schema MegaWAT

+

Description: I work with JSON Schema almost every day, so I've already accepted all its strange quirks. +But quite often (GitHub, forums, clients) I see the same mistakes and misunderstanding. +I'd like to show all these quirks in the form of funny WAT talk. +As a bonus, I'd like to discuss the alternative format I'm currently working on.

+ + +

From API Directory to Semantic Web

+

Description: When it comes to SemanticWeb we see the forest for the trees by only associating it with academia-developed standards like RDF, OWL, etc. +But today more and more companies are using API specifications(OpenAPI/Swagger, RAML, API Blueprint, ...) as they provide benefits on their own: API consoles, generating Docs & SDKs, testing. +Can we use these API specification to build SemanticWeb? +As the first step, I working on APIs.guru directory of OpenAPI spec and I want to +share my vision how we can use it to build The Next Web.

+ + +

Also we have presented live demo of how to use [generator-openapi-repo](LINK TO GENERATOR) to set up full-featured API portal on GitHub in less that 10 minutes (by @RomanGotsiy)

+

Besides API related things we unknowingly took part in David Gardner social experement:

+ +

Meet us on RestFest next year or maybe other API conferrence this year! +You can always recognize us by APIs.guru T-Shirts and we always have one for you :)

+ +
+ +
+ + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + diff --git a/about/index.html b/about/index.html new file mode 100644 index 0000000..4349639 --- /dev/null +++ b/about/index.html @@ -0,0 +1,508 @@ + + + + + + + + +APIs.guru + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + +
+ +
+ + + +
+
+

APIS.GURU

+

Wikipedia for WEB APIs

+ +
+
+ +
+
+ Our goal is to create a machine-readable Wikipedia for Web APIs in the OpenAPI Specification format, with the following principals: +
+
+ +
Open source, community driven project
+
Only publicly available APIs (free or paid)
+
Anyone can add or change an API, not only API owners
+
All data can be accessed through an HTTP API
+
+
+
+
+ + +
+ 2,232 +
+
+ API descriptions +
+
+
+ + +
+ 75,747 +
+
+ Endpoints +
+
+
+ + +
+ 2,407 +
+
+ Stars on GitHub +
+
+
+
+
+ What does APIs.guru do? +
+ + + + +
+
+ + + +
+ + + + +
Search for public API definitions
+
+
+ + + + + + + + + + + + +
Filter out private and non-reliable APIs
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Update definitions on a weekly basis
+
+
+
+ + + +
+ + + + +
Convert different formats into OpenAPI 3.0
+
+
+ + + + +
Correct mistakes, ~80% of definitions have some
+
+
+ + + + + + + + + + + + + + +
Add additional data, like: logo, categories
+
+
+
+
+
+
+ Contribution process +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + API owner + + + Contributors + + + Pull requests + + + + + + + + + + + + + + + + + API + + + 3rd-party integrations + + + + + + + + + + +
+
+ Browse APIs +
+
+
+ Join the movement +
+ +
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + diff --git a/add-api/index.html b/add-api/index.html new file mode 100644 index 0000000..a890291 --- /dev/null +++ b/add-api/index.html @@ -0,0 +1,441 @@ + + + + + + + + +APIs.guru + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + +
+ +
+ + + +
+ +
+
+ APIs.guru banner + + + +
+ + +
+

This page is help you to submit your API into the APIs.guru + directory. The most important requirement is the presence of a machine-readable + API definition in one of the popular formats, such as: OpenAPI (fka Swagger), + RAML, API Blueprint, etc.

+

Important note: we only aggregate API definitions, not host them. + So please, provide us with a stable URL to the definition. We will use it to keep your definition + up to date: see our + update procedure .

+

Note: If you enter a .well-known/ai-plugin.json URL in the URL field, + the linked OpenAPI definition will be looked up and the name and logo fields automatically populated.

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +

What is the name of the API?

+ +
+ +
+ +

Include the protocol, e.g. “https://”

+ +
+ +
+ +

If not already in the definition. Include the protocol, e.g. “https://”

+ +
+ +
+ +

(Please select the most appropriate)

+ +
+ +
+ +
+
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + diff --git a/api-doc/index.html b/api-doc/index.html new file mode 100644 index 0000000..b43e927 --- /dev/null +++ b/api-doc/index.html @@ -0,0 +1,163 @@ + + + + + + + + +APIs.guru + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + +
+ +
+ + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + diff --git a/apis/quotes.yaml b/apis/quotes.yaml new file mode 100644 index 0000000..9e9515d --- /dev/null +++ b/apis/quotes.yaml @@ -0,0 +1,106 @@ +openapi: 3.0.3 +info: + title: Quotes API + version: "1.0" + description: > + An API for retrieving quotations. + + This OpenAPI definition defines the following endpoints: + + * `/quotes`: This endpoint returns all quotes. + * `/quotes/author`: This endpoint returns quotes by the specified author. + * `/quotes/source`: This endpoint returns quotes from the specified source. + * `/quotes/random`: This endpoint returns a random number of quotes. + + The `Quote` schema defines the properties of a quote. +paths: + /quotes: + get: + tags: + - Quotes + summary: Get all quotes. + responses: + 200: + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/Quote" + description: Returns all quotes. + + /quotes/author: + get: + tags: + - Quotes + summary: Get quotes by author. + parameters: + - name: author + in: path + required: true + type: string + description: The author of the quotes to retrieve. + responses: + 200: + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/Quote" + description: Returns quotes by the specified author. + + /quotes/source: + get: + tags: + - Quotes + summary: Get quotes by source. + parameters: + - name: source + in: path + required: true + type: string + description: The source of the quotes to retrieve. + responses: + 200: + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/Quote" + description: Returns quotes from the specified source. + + /quotes/random: + get: + tags: + - Quotes + summary: Get random quotes. + parameters: + - name: limit + in: query + required: false + type: string + description: The number of quotes to return. + responses: + 200: + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/Quote" + description: Returns a random number of quotes. +components: + schemas: + Quote: + type: object + properties: + id: + type: string + author: + type: string + source: + type: string + quote: + type: string diff --git a/app/(utils)/worker.min.js/route.ts b/app/(utils)/worker.min.js/route.ts deleted file mode 100644 index 61e9b03..0000000 --- a/app/(utils)/worker.min.js/route.ts +++ /dev/null @@ -1,11 +0,0 @@ -export const dynamic = "force-static"; - -export function GET() { - const content = `var t=Uint8Array,n=Uint16Array,r=Int32Array,e=new t([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),i=new t([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),a=new t([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),s=function(t,e){for(var i=new n(31),a=0;a<31;++a)i[a]=e+=1<>1|(21845&c)<<1;v=(61680&(v=(52428&v)>>2|(13107&v)<<2))>>4|(3855&v)<<4,u[c]=((65280&v)>>8|(255&v)<<8)>>1}var d=function(t,r,e){for(var i=t.length,a=0,s=new n(r);a>h]=l}else for(o=new n(i),a=0;a>15-t[a]);return o},g=new t(288);for(c=0;c<144;++c)g[c]=8;for(c=144;c<256;++c)g[c]=9;for(c=256;c<280;++c)g[c]=7;for(c=280;c<288;++c)g[c]=8;var w=new t(32);for(c=0;c<32;++c)w[c]=5;var p=d(g,9,0),y=d(w,5,0),m=function(t){return(t+7)/8|0},b=function(n,r,e){return(null==r||r<0)&&(r=0),(null==e||e>n.length)&&(e=n.length),new t(n.subarray(r,e))},M=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],E=function(t,n,r){var e=new Error(n||M[t]);if(e.code=t,Error.captureStackTrace&&Error.captureStackTrace(e,E),!r)throw e;return e},z=function(t,n,r){r<<=7&n;var e=n/8|0;t[e]|=r,t[e+1]|=r>>8},A=function(t,n,r){r<<=7&n;var e=n/8|0;t[e]|=r,t[e+1]|=r>>8,t[e+2]|=r>>16},_=function(r,e){for(var i=[],a=0;ad&&(d=o[a].s);var g=new n(d+1),w=x(i[c-1],g,0);if(w>e){a=0;var p=0,y=w-e,m=1<e))break;p+=m-(1<>=y;p>0;){var M=o[a].s;g[M]=0&&p;--a){var E=o[a].s;g[E]==e&&(--g[E],++p)}w=e}return{t:new t(g),l:w}},x=function(t,n,r){return-1==t.s?Math.max(x(t.l,n,r+1),x(t.r,n,r+1)):n[t.s]=r},D=function(t){for(var r=t.length;r&&!t[--r];);for(var e=new n(++r),i=0,a=t[0],s=1,o=function(t){e[i++]=t},f=1;f<=r;++f)if(t[f]==a&&f!=r)++s;else{if(!a&&s>2){for(;s>138;s-=138)o(32754);s>2&&(o(s>10?s-11<<5|28690:s-3<<5|12305),s=0)}else if(s>3){for(o(a),--s;s>6;s-=6)o(8304);s>2&&(o(s-3<<5|8208),s=0)}for(;s--;)o(a);s=1,a=t[f]}return{c:e.subarray(0,i),n:r}},T=function(t,n){for(var r=0,e=0;e>8,t[i+2]=255^t[i],t[i+3]=255^t[i+1];for(var a=0;a4&&!H[a[K-1]];--K);var N,P,Q,R,V=v+5<<3,W=T(f,g)+T(h,w)+l,X=T(f,M)+T(h,C)+l+14+3*K+T(q,H)+2*q[16]+3*q[17]+7*q[18];if(c>=0&&V<=W&&V<=X)return k(r,m,t.subarray(c,c+v));if(z(r,m,1+(X15&&(z(r,m,tt[B]>>5&127),m+=tt[B]>>12)}}}else N=p,P=g,Q=y,R=w;for(B=0;B255){A(r,m,N[(nt=rt>>18&31)+257]),m+=P[nt+257],nt>7&&(z(r,m,rt>>23&31),m+=e[nt]);var et=31&rt;A(r,m,Q[et]),m+=R[et],et>3&&(A(r,m,rt>>5&8191),m+=i[et])}else A(r,m,N[rt]),m+=P[rt]}return A(r,m,N[256]),m+P[256]},U=new r([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),F=new t(0),I=function(){for(var t=new Int32Array(256),n=0;n<256;++n){for(var r=n,e=9;--e;)r=(1&r&&-306674912)^r>>>1;t[n]=r}return t}(),S=function(){var t=-1;return{p:function(n){for(var r=t,e=0;e>>8;t=r},d:function(){return~t}}},L=function(){var t=1,n=0;return{p:function(r){for(var e=t,i=n,a=0|r.length,s=0;s!=a;){for(var o=Math.min(s+2655,a);s>16),i=(65535&i)+15*(i>>16)}t=e,n=i},d:function(){return(255&(t%=65521))<<24|(65280&t)<<8|(255&(n%=65521))<<8|n>>8}}},O=function(a,s,o,f,u){if(!u&&(u={l:1},s.dictionary)){var c=s.dictionary.subarray(-32768),v=new t(c.length+a.length);v.set(c),v.set(a,c.length),a=v,u.w=c.length}return function(a,s,o,f,u,c){var v=c.z||a.length,d=new t(f+v+5*(1+Math.ceil(v/7e3))+u),g=d.subarray(f,d.length-u),w=c.l,p=7&(c.r||0);if(s){p&&(g[0]=c.r>>3);for(var y=U[s-1],M=y>>13,E=8191&y,z=(1<7e3||q>24576)&&(N>423||!w)){p=C(a,g,0,F,I,S,O,q,G,j-G,p),q=L=O=0,G=j;for(var P=0;P<286;++P)I[P]=0;for(P=0;P<30;++P)S[P]=0}var Q=2,R=0,V=E,W=J-K&32767;if(N>2&&H==T(j-W))for(var X=Math.min(M,N)-1,Y=Math.min(32767,j),Z=Math.min(258,N);W<=Y&&--V&&J!=K;){if(a[j+Q]==a[j+Q-W]){for(var $=0;$Q){if(Q=$,R=W,$>X)break;var tt=Math.min(W,$-2),nt=0;for(P=0;Pnt&&(nt=et,K=rt)}}}W+=(J=K)-(K=A[J])&32767}if(R){F[q++]=268435456|h[Q]<<18|l[R];var it=31&h[Q],at=31&l[R];O+=e[it]+i[at],++I[257+it],++S[at],B=j+Q,++L}else F[q++]=a[j],++I[a[j]]}}for(j=Math.max(j,B);j=v&&(g[p/8|0]=w,st=v),p=k(g,p+1,a.subarray(j,st))}c.i=v}return b(d,0,f+m(p)+u)}(a,null==s.level?6:s.level,null==s.mem?Math.ceil(1.5*Math.max(8,Math.min(13,Math.log(a.length)))):12+s.mem,o,f,u)},j=function(t,n,r){for(;r;++n)t[n]=r,r>>>=8},q=function(t,n){var r=n.filename;if(t[0]=31,t[1]=139,t[2]=8,t[8]=n.level<2?4:9==n.level?2:0,t[9]=3,0!=n.mtime&&j(t,4,Math.floor(new Date(n.mtime||Date.now())/1e3)),r){t[3]=8;for(var e=0;e<=r.length;++e)t[e+10]=r.charCodeAt(e)}},B=function(t){return 10+(t.filename?t.filename.length+1:0)},G=function(){function n(n,r){if("function"==typeof n&&(r=n,n={}),this.ondata=r,this.o=n||{},this.s={l:0,i:32768,w:32768,z:32768},this.b=new t(98304),this.o.dictionary){var e=this.o.dictionary.subarray(-32768);this.b.set(e,32768-e.length),this.s.i=32768-e.length}}return n.prototype.p=function(t,n){this.ondata(O(t,this.o,0,0,this.s),n)},n.prototype.push=function(n,r){this.ondata||E(5),this.s.l&&E(4);var e=n.length+this.s.z;if(e>this.b.length){if(e>2*this.b.length-32768){var i=new t(-32768&e);i.set(this.b.subarray(0,this.s.z)),this.b=i}var a=this.b.length-this.s.z;a&&(this.b.set(n.subarray(0,a),this.s.z),this.s.z=this.b.length,this.p(this.b,!1)),this.b.set(this.b.subarray(-32768)),this.b.set(n.subarray(a),32768),this.s.z=n.length-a+32768,this.s.i=32766,this.s.w=32768}else this.b.set(n,this.s.z),this.s.z+=n.length;this.s.l=1&r,(this.s.z>this.s.w+8191||r)&&(this.p(this.b,r||!1),this.s.w=this.s.i,this.s.i-=2)},n}();var H=function(){function t(t,n){this.c=L(),this.v=1,G.call(this,t,n)}return t.prototype.push=function(t,n){this.c.p(t),G.prototype.push.call(this,t,n)},t.prototype.p=function(t,n){var r=O(t,this.o,this.v&&(this.o.dictionary?6:2),n&&4,this.s);this.v&&(function(t,n){var r=n.level,e=0==r?0:r<6?1:9==r?3:2;if(t[0]=120,t[1]=e<<6|(n.dictionary&&32),t[1]|=31-(t[0]<<8|t[1])%31,n.dictionary){var i=L();i.p(n.dictionary),j(t,2,i.d())}}(r,this.o),this.v=0),n&&j(r,r.length-4,this.c.d()),this.ondata(r,n)},t}(),J="undefined"!=typeof TextEncoder&&new TextEncoder,K="undefined"!=typeof TextDecoder&&new TextDecoder;try{K.decode(F,{stream:!0})}catch(t){}var N=function(){function t(t){this.ondata=t}return t.prototype.push=function(t,n){this.ondata||E(5),this.d&&E(4),this.ondata(P(t),this.d=n||!1)},t}();function P(n,r){if(r){for(var e=new t(n.length),i=0;i>1)),o=0,f=function(t){s[o++]=t};for(i=0;is.length){var h=new t(o+8+(a-i<<1));h.set(s),s=h}var l=n.charCodeAt(i);l<128||r?f(l):l<2048?(f(192|l>>6),f(128|63&l)):l>55295&&l<57344?(f(240|(l=65536+(1047552&l)|1023&n.charCodeAt(++i))>>18),f(128|l>>12&63),f(128|l>>6&63),f(128|63&l)):(f(224|l>>12),f(128|l>>6&63),f(128|63&l))}return b(s,0,o)}function Q(t){return function(t,n){n||(n={});var r=S(),e=t.length;r.p(t);var i=O(t,n,B(n),8),a=i.length;return q(i,n),j(i,a-8,r.d()),j(i,a-4,e),i}(P(t))}const R=new class{constructor(){this._init()}clear(){this._init()}addEvent(t){if(!t)throw new Error("Adding invalid event");const n=this._hasEvents?",":"";this.stream.push(n+t),this._hasEvents=!0}finish(){this.stream.push("]",!0);const t=function(t){let n=0;for(const r of t)n+=r.length;const r=new Uint8Array(n);for(let n=0,e=0,i=t.length;n{this._deflatedData.push(t)},this.stream=new N(((t,n)=>{this.deflate.push(t,n)})),this.stream.push("[")}},V={clear:()=>{R.clear()},addEvent:t=>R.addEvent(t),finish:()=>R.finish(),compress:t=>Q(t)};addEventListener("message",(function(t){const n=t.data.method,r=t.data.id,e=t.data.arg;if(n in V&&"function"==typeof V[n])try{const t=V[n](e);postMessage({id:r,method:n,success:!0,response:t})}catch(t){postMessage({id:r,method:n,success:!1,response:t.message}),console.error(t)}})),postMessage({id:void 0,method:"init",success:!0,response:void 0});`; - return new Response(content, { - headers: { - "Content-Type": "application/javascript", - "Cache-Control": "public, max-age=31536000", - }, - }); -} diff --git a/app/(with-support)/about/page.tsx b/app/(with-support)/about/page.tsx deleted file mode 100644 index a194865..0000000 --- a/app/(with-support)/about/page.tsx +++ /dev/null @@ -1,274 +0,0 @@ -import React from "react"; -import Image from "next/image"; -import Link from "next/link"; -import { Button } from "@/components/ui/button"; -import { generateSimpleMetadata } from "@/sanity/lib/metadata"; - -export async function generateMetadata() { - return generateSimpleMetadata({ - title: "About APIs.guru", - description: - "Learn more about the APIs.guru project and its contributors. Discover how we maintain the largest repository of machine-readable API specifications.", - slug: "about", - }); -} - -const NumberRomb = () => ( - - - -); - -async function getMetrics() { - try { - const response = await fetch("https://github.com/service/https://api.apis.guru/v2/metrics.json", { - next: { revalidate: 3600 }, - }); - if (!response.ok) throw new Error("Failed to fetch metrics"); - return response.json(); - } catch (error) { - console.error("Error fetching metrics:", error); - return { numAPIs: 2232, numEndpoints: 75747 }; - } -} - -export default async function AboutPage() { - const metrics = await getMetrics(); - - return ( -
-
-
-
- Our goal is to create a machine-readable Wikipedia for Web APIs in - the{" "} - - OpenAPI Specification - {" "} - format, with the following principals: -
-
-
- {" "} - Open source, community driven project{" "} -
-
- {" "} - Only publicly available APIs (free or paid){" "} -
-
- {" "} - Anyone can add or change an API, not only API owners{" "} -
-
- {" "} - All data can be accessed through an HTTP API{" "} -
-
-
- -
-
-
- -
- {metrics.numAPIs.toLocaleString()} -
-
-
API descriptions
-
- -
-
- -
- {metrics.numEndpoints.toLocaleString()} -
-
-
Endpoints
-
- -
-
- -
- 2,407 -
-
-
Stars on GitHub
-
-
- -
-
- What does APIs.guru do? -
-
- Light bulb -
- - {/* Main connecting line from lightbulb */} -
-
- -
-
-
-
-
- Search for public API definitions -
-
-
- Search -
-
- -
-
-
- Filter out private and non-reliable APIs -
-
-
- Filter -
-
- -
-
-
- Update definitions on a weekly basis -
-
-
- Update -
-
-
- -
-
-
- Convert -
-
-
- Convert different formats into OpenAPI 3.0 -
-
-
- -
-
- Fix -
-
-
- Correct mistakes, ~80% of definitions have some -
-
-
- -
-
- Add -
-
-
- Add additional data, like: logo, categories -
-
-
-
-
-
-
- -
-
- Contribution process -
-
- Contribution process -
-
- -
- - - -
- -
-
- Join the movement -
-
-
-
- ); -} diff --git a/app/(with-support)/add-api/page.tsx b/app/(with-support)/add-api/page.tsx deleted file mode 100644 index db6c0be..0000000 --- a/app/(with-support)/add-api/page.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import React from "react"; -import FormAddApi from "@/components/FormAddApi"; -import { generateSimpleMetadata } from "@/sanity/lib/metadata"; - -export async function generateMetadata() { - return generateSimpleMetadata({ - title: "Add API", - description: - "Submit your API to the APIs.guru directory. We aggregate OpenAPI specifications, RAML, API Blueprint and other machine-readable API definitions.", - slug: "add-api", - }); -} - -export default function AddApiPage() { - return ( -
-

- Add API -

- -
-

- This page helps you submit your API into the APIs.guru directory. The - most important requirement is the presence of a machine-readable API - definition in one of the popular formats, such as: OpenAPI (formerly - known as Swagger), RAML, API Blueprint, etc. -

-

- Important note: we only aggregate API definitions, - not host them. So please, provide us with a stable URL to the - definition. We will use it to keep your definition up to date: see our{" "} - - update procedure - - . -

-

- Note: If you enter a{" "} - - .well-known/ai-plugin.json - {" "} - URL in the{" "} - - URL - {" "} - field, the linked OpenAPI definition will be looked up and the name - and logo fields automatically populated. -

-
- - -
- ); -} diff --git a/app/(with-support)/layout.tsx b/app/(with-support)/layout.tsx deleted file mode 100644 index 5c5f87b..0000000 --- a/app/(with-support)/layout.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { Geist, Geist_Mono, Roboto } from "next/font/google"; - -import Support from "@/components/Support"; - -export default function RootLayout({ - children, -}: { - children: React.ReactNode; -}) { - return ( - <> - - {children} - - ); -} diff --git a/app/(with-support)/page.tsx b/app/(with-support)/page.tsx deleted file mode 100644 index 539f814..0000000 --- a/app/(with-support)/page.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import React from "react"; -import SearchClientComponent from "@/components/SearchClientComponent"; -import { generateSimpleMetadata } from "@/sanity/lib/metadata"; - -export const dynamic = "force-dynamic"; - -export async function generateMetadata() { - return generateSimpleMetadata({ - title: "APIs.guru - Wikipedia for Web APIs", - description: - "Wikipedia for Web APIs. Directory of REST API specs in OpenAPI 3.0 format", - slug: "", - }); -} - -export default async function Home() { - return ( -
-
- -
-
- ); -} diff --git a/app/api-doc/ApiDocClient.tsx b/app/api-doc/ApiDocClient.tsx deleted file mode 100644 index 405e5c6..0000000 --- a/app/api-doc/ApiDocClient.tsx +++ /dev/null @@ -1,37 +0,0 @@ -"use client"; - -import { RedocStandalone } from "redoc"; -import { useEffect } from "react"; - -export default function ApiDocClient() { - useEffect(() => { - const robotoFont = document.createElement("link"); - robotoFont.rel = "stylesheet"; - robotoFont.href = "//fonts.googleapis.com/css?family=Roboto:300,400,700"; - document.head.appendChild(robotoFont); - - const montserratFont = document.createElement("link"); - montserratFont.rel = "stylesheet"; - montserratFont.href = - "//fonts.googleapis.com/css?family=Montserrat:400,700"; - document.head.appendChild(montserratFont); - - return () => { - document.head.removeChild(robotoFont); - document.head.removeChild(montserratFont); - }; - }, []); - - return ( -
- -
- ); -} diff --git a/app/api-doc/page.tsx b/app/api-doc/page.tsx deleted file mode 100644 index 49fdae9..0000000 --- a/app/api-doc/page.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { generateSimpleMetadata } from "@/sanity/lib/metadata"; -import ApiDocClient from "./ApiDocClient"; - -export async function generateMetadata() { - return generateSimpleMetadata({ - title: "API Documentation", - description: - "Interactive API documentation for the APIs.guru REST API. Explore endpoints and test API calls.", - slug: "api-doc", - }); -} - -export default function ApiDocPage() { - return ; -} diff --git a/app/api/draft-mode/disable/route.ts b/app/api/draft-mode/disable/route.ts deleted file mode 100644 index dd80c52..0000000 --- a/app/api/draft-mode/disable/route.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { draftMode } from "next/headers"; -import { NextRequest, NextResponse } from "next/server"; - -export async function GET(request: NextRequest) { - (await draftMode()).disable(); - return NextResponse.redirect(new URL("/", request.url)); -} diff --git a/app/api/draft-mode/enable/route.ts b/app/api/draft-mode/enable/route.ts deleted file mode 100644 index 81742d9..0000000 --- a/app/api/draft-mode/enable/route.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { defineEnableDraftMode } from "next-sanity/draft-mode"; -import { client } from "@/sanity/lib/client"; -import { token } from "@/sanity/lib/token"; - -export const { GET } = defineEnableDraftMode({ - client: client.withConfig({ token }), -}); diff --git a/app/api/sentry-tunnel/route.ts b/app/api/sentry-tunnel/route.ts deleted file mode 100644 index 9df0886..0000000 --- a/app/api/sentry-tunnel/route.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { NextRequest, NextResponse } from "next/server"; - -interface SentryResponse { - error?: string; - message?: string; -} - -const corsHeaders = { - "Access-Control-Allow-Origin": "*", - "Access-Control-Allow-Methods": "GET, POST, OPTIONS", - "Access-Control-Allow-Headers": "Content-Type", - "Cache-Control": "public, max-age=300", -}; - -export async function POST(req: NextRequest) { - try { - const sentryDsn = - "https://8296abef723d97e7b8d5a15d1e93be1f@o4509816683823104.ingest.us.sentry.io/4509831375683584"; - - const dsn = new URL(sentryDsn); - const projectId = dsn.pathname.split("/").pop(); - if (!projectId) { - throw new Error("Invalid SENTRY_DSN: missing project ID"); - } - - const sentryIngestUrl = `https://${dsn.host}/api/${projectId}/envelope/`; - - const clientIp = - req.headers.get("x-forwarded-for")?.split(",")[0]?.trim() || ""; - - const newRequest = new Request(sentryIngestUrl, { - method: "POST", - headers: { - "Content-Type": "application/x-sentry-envelope", - "X-Forwarded-For": clientIp, - }, - body: await req.arrayBuffer(), - }); - - const response = await fetch(newRequest); - - return new Response(response.body, { - status: response.status, - headers: { - ...corsHeaders, - "Content-Type": "application/x-sentry-envelope", - }, - }); - } catch (error: unknown) { - console.error("Sentry proxy failed:", error); - const errorMessage = - error instanceof Error ? error.message : "Unknown error"; - return NextResponse.json( - { - error: "Internal server error", - message: `Failed to proxy Sentry request: ${errorMessage}`, - } as SentryResponse, - { - status: 500, - headers: corsHeaders, - }, - ); - } -} - -export async function OPTIONS() { - return new Response(null, { - status: 204, - headers: corsHeaders, - }); -} diff --git a/app/apis/[providerSlug]/[serviceSlug]/page.tsx b/app/apis/[providerSlug]/[serviceSlug]/page.tsx deleted file mode 100644 index f43a3a4..0000000 --- a/app/apis/[providerSlug]/[serviceSlug]/page.tsx +++ /dev/null @@ -1,348 +0,0 @@ -import React from "react"; -import Link from "next/link"; -import Image from "next/image"; -import { marked } from "marked"; -import { Metadata, ResolvingMetadata } from "next"; -import { notFound } from "next/navigation"; -import DescriptionSection from "../../../../components/DescriptionSection"; -import list from "../../../../list.json"; - -import JsonTreeContainer, { JsonTree } from "@/components/JsonTree"; -import ApiButtons from "@/components/ApiButtons"; -import VisitCounter from "@/components/VisitCounter"; -import type { ApiVersion } from "@/types/api"; -import { ExternalLink } from "lucide-react"; - -function stripMarkdown(markdown: string): string { - return markdown - .replace(/(\*\*|__)(.*?)\1/g, "$2") - .replace(/(\*|_)(.*?)\1/g, "$2") - .replace(/#{1,6}\s/g, "") - .replace(/\[([^\]]+)\]\([^\)]+\)/g, "$1") - .replace(/!\[([^\]]*)\]\([^\)]+\)/g, "$1") - .replace(/`{1,3}([^`]+)`{1,3}/g, "$1") - .replace(/(\n\s*){2,}/g, "\n\n") - .replace(/^\s+|\s+$/g, ""); -} -export function getData( - providerSlug: string, - serviceSlug?: string | null -): any | null { - const apiList = list as Record; - - const targetKey = serviceSlug - ? `${providerSlug}:${serviceSlug}` - : providerSlug; - - if (apiList[targetKey]) { - return processApiData(targetKey, apiList[targetKey]); - } - - for (const key in apiList) { - if ( - apiList.hasOwnProperty(key) && - key.toLowerCase() === targetKey.toLowerCase() - ) { - return processApiData(key, apiList[key]); - } - } - - console.warn( - `No API found for provider: ${providerSlug}, service: ${serviceSlug}` - ); - return null; -} - -function processApiData(key: string, api: any) { - try { - const versions = api.versions || {}; - const preferred = api.preferred || Object.keys(versions)[0] || ""; - const preferredVersion = versions[preferred] || {}; - const info = preferredVersion.info || {}; - const externalDocs = preferredVersion.externalDocs || {}; - const contact = info.contact || {}; - - const logo = { - url: info["x-logo"]?.url || "/assets/images/no-logo.svg", - backgroundColor: info["x-logo"]?.backgroundColor || null, - }; - - const externalUrl = - externalDocs.url || - contact.url || - (key.indexOf(".local") < 0 ? `https://${key.split(":")[0]}` : ""); - - let origUrl = ""; - if ( - info["x-origin"] && - Array.isArray(info["x-origin"]) && - info["x-origin"].length > 0 - ) { - origUrl = info["x-origin"][0]?.url || preferredVersion.swaggerUrl || ""; - } else { - origUrl = preferredVersion.swaggerUrl || ""; - } - - const categories = info["x-apisguru-categories"] || []; - const tags = info["x-tags"] || []; - - const versionsArray = Object.entries(versions).map( - ([version, details]: [string, any]) => ({ - version, - swaggerUrl: details?.swaggerUrl || "", - swaggerYamlUrl: details?.swaggerYamlUrl || "", - }) - ); - - const description = info.description || "No description available"; - const cardDescription = marked(description); - const cardDescriptionPlain = stripMarkdown(description); - - return { - name: key, - preferred: api.preferred || "", - info, - api: { - swaggerUrl: preferredVersion.swaggerUrl || "", - swaggerYamlUrl: preferredVersion.swaggerYamlUrl || "", - }, - logo, - externalUrl, - origUrl, - versions: versionsArray, - cardDescription, - cardDescriptionPlain, - categories, - tags, - integrations: api.integrations || [], - updated: preferredVersion.updated || "", - }; - } catch (error) { - console.error(`Error processing API ${key}:`, error); - return null; - } -} - -export async function generateStaticParams() { - const apiList = list as Record; - const params: { providerSlug: string; serviceSlug: string }[] = []; - - for (const key in apiList) { - if (Object.prototype.hasOwnProperty.call(apiList, key)) { - const [provider, service] = key.split(":"); - - if (service) { - const providerSlug = provider.toLowerCase(); - const serviceSlug = service.toLowerCase(); - - params.push({ - providerSlug, - serviceSlug, - }); - } - } - } - - return params; -} - -export async function generateMetadata( - { - params, - }: { params: Promise<{ providerSlug: string; serviceSlug: string }> }, - parent: ResolvingMetadata -): Promise { - const { providerSlug, serviceSlug } = await params; - const api = getData(providerSlug, serviceSlug); - const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || "https://apis.guru/"; - const isProduction = process.env.NEXT_PUBLIC_SITE_ENV === "production"; - - if (!api) { - notFound(); - } - - const title = `${api.info.title} API`; - const description = `Documentation and specification of the ${api.info.title} API. Explore endpoints, methods, and integration options to use ${api.info.title} in your applications.`; - const canonicalUrl = `${siteUrl}/apis/${providerSlug}/${serviceSlug}`; - - return { - title, - description, - keywords: [ - ...(api.categories || []), - ...(api.tags || []), - "API", - "developer tools", - ], - openGraph: { - title, - description, - url: canonicalUrl, - type: "website", - locale: "en_US", - images: [ - { - url: api.logo.url, - width: 1200, - height: 630, - alt: `${api.info.title} API logo`, - }, - ], - }, - twitter: { - card: "summary_large_image", - title, - description, - images: [api.logo.url], - }, - robots: !isProduction ? "noindex, nofollow" : "index, follow", - alternates: { - canonical: canonicalUrl, - }, - }; -} - -export default async function ApiPage({ - params, -}: { - params: Promise<{ providerSlug: string; serviceSlug: string | null }>; -}) { - const { providerSlug, serviceSlug } = await params; - const api = getData(providerSlug, serviceSlug); - - if (!api) { - notFound(); - } - - return ( -
- - -
-
-
- {`${api.info.title} -
-
- -
-
-

- {api.externalUrl ? ( - - {api.info.title} - - ) : ( - api.info.title - )} -

- -

- Last updated:{" "} - {new Date(api.updated).toLocaleString("en-US", { - year: "numeric", - month: "long", - day: "numeric", - })} -

- -
- -
-
- - {api.integrations && api.integrations.length > 0 && ( -
-

- Available Tools -

-
- {api.integrations.map((integration: any, index: any) => ( - - {integration.text} - - - ))} -
-
- )} -
-
- - - -
-

- OpenAPI Specification -

- -
- - {api.versions && api.versions.length > 0 && ( -
-

- All Versions -

-
- {api.versions - .reverse() - .map((version: ApiVersion, index: number) => ( -
-
-

- Version {version.version} -

- -
- -
-

- OpenAPI Specification -

- -
-
- ))} -
-
- )} -
- ); -} diff --git a/app/apis/[providerSlug]/page.tsx b/app/apis/[providerSlug]/page.tsx deleted file mode 100644 index 8d73917..0000000 --- a/app/apis/[providerSlug]/page.tsx +++ /dev/null @@ -1,156 +0,0 @@ -import React from "react"; -import Link from "next/link"; -import { notFound } from "next/navigation"; -import list from "../../../list.json"; -import { generateSimpleMetadata } from "@/sanity/lib/metadata"; - -import ApiPage, { getData } from "./[serviceSlug]/page"; -import SearchClientComponent from "@/components/SearchClientComponent"; - -interface Api { - name: string; - providerName: string; - serviceName?: string; - title: string; - description: string; - logo?: { url: string; backgroundColor?: string }; - preferredVersion: string; -} - -function getProviderApis(providerSlug: string): Api[] { - const apiList = list as Record; - const apis: Api[] = []; - - for (const key in apiList) { - if (Object.prototype.hasOwnProperty.call(apiList, key)) { - const [provider, service] = key.split(":"); - const normalizedProviderSlug = provider.toLowerCase(); - - if (normalizedProviderSlug === providerSlug) { - const api = apiList[key]; - const preferred = - api.preferred || - (api.versions ? Object.keys(api.versions)[0] : "") || - ""; - const preferredVersion = api.versions?.[preferred] || {}; - const info = preferredVersion.info || {}; - - apis.push({ - name: key, - providerName: provider, - serviceName: service, - title: info.title || key, - description: info.description || "No description available", - logo: info["x-logo"] || { url: "/assets/images/no-logo.svg" }, - preferredVersion: preferred, - }); - } - } - } - - return apis; -} - -export function generateStaticParams() { - const apiList = list as Record; - const providerSlugs = new Set(); - - for (const key in apiList) { - if (Object.prototype.hasOwnProperty.call(apiList, key)) { - const [provider] = key.split(":"); - if (!provider) { - console.warn(`Invalid key format: ${key}`); - continue; - } - const providerSlug = provider.toLowerCase(); - - providerSlugs.add(providerSlug); - } - } - - const params = Array.from(providerSlugs).map((providerSlug) => ({ - providerSlug, - })); - return params; -} - -export async function generateMetadata({ - params, -}: { - params: Promise<{ providerSlug: string }>; -}) { - const { providerSlug } = await params; - const apis = getProviderApis(providerSlug); - - const providerName = apis.length > 0 ? apis[0].providerName : providerSlug; - const services = apis.filter((api) => api.serviceName); - - const title = - services.length > 0 - ? `${providerName} APIs` - : `${apis[0]?.title || providerName} API`; - - const description = - services.length > 0 - ? `Explore ${providerName} APIs. Browse ${services.length} API${services.length > 1 ? "s" : ""} from ${providerName}.` - : `Documentation and specification of the ${apis[0]?.title || providerName} API. Explore endpoints, methods, and integration options to use ${apis[0]?.title || providerName} in your applications.`; - - return generateSimpleMetadata({ - title, - description, - slug: `apis/${providerSlug}`, - }); -} -export default async function ProviderPage({ - params, -}: { - params: Promise<{ providerSlug: string }>; -}) { - const { providerSlug } = await params; - const apis = getProviderApis(providerSlug); - - if (apis.length === 0) { - notFound(); - } - - const services = apis.filter((api) => api.serviceName); - if (services.length > 0) { - const providerName = apis[0]?.providerName || providerSlug; - return ( -
-
-
-
-

- {providerName} APIs -

-

- Discover and explore {services.length} API - {services.length > 1 ? "s" : ""} from {providerName}. Access - comprehensive documentation, endpoints, and integration guides - to power your applications. -

-
-
- - {services.length} Service{services.length > 1 ? "s" : ""}{" "} - Available - -
-
-
-
-
- - {/* Main Content */} -
- -
-
- ); - } else { - return ( - - ); - } -} diff --git a/app/apis/layout.tsx b/app/apis/layout.tsx deleted file mode 100644 index b225053..0000000 --- a/app/apis/layout.tsx +++ /dev/null @@ -1,118 +0,0 @@ -"use client"; - -import { usePathname } from "next/navigation"; -import { - Breadcrumb, - BreadcrumbItem, - BreadcrumbLink, - BreadcrumbList, - BreadcrumbPage, - BreadcrumbSeparator, - BreadcrumbEllipsis, -} from "@/components/ui/breadcrumb"; -import { Drawer, DrawerContent, DrawerTrigger } from "@/components/ui/drawer"; -import { SlashIcon } from "lucide-react"; -import Link from "next/link"; -import { ReactNode } from "react"; - -type BreadcrumbItemType = - | { name: string; href: string; isEllipsis?: never } - | { name: string; isEllipsis: boolean; href?: never }; - -export default function RootLayout({ children }: { children: ReactNode }) { - const pathname = usePathname(); - - const generateBreadcrumbs = (): BreadcrumbItemType[] => { - const paths = pathname.split("/").filter((path) => path); - const items: BreadcrumbItemType[] = [ - { name: "Home", href: "/" }, - ...paths - .map((path, index): BreadcrumbItemType | null => { - const href = `/${paths.slice(0, index + 1).join("/")}`; - - if (path.toLowerCase() === "apis") { - return null; - } - return { - name: - path.charAt(0).toUpperCase() + path.slice(1).replace(/-/g, " "), - href, - }; - }) - .filter((item): item is BreadcrumbItemType => item !== null), - ]; - - if (items.length > 4) { - return [ - items[0], - { name: "More", isEllipsis: true }, - items[items.length - 2], - items[items.length - 1], - ]; - } - - return items; - }; - - const breadcrumbItems = generateBreadcrumbs(); - - return ( -
-
- - - {breadcrumbItems.map((item, index) => ( -
- {index > 0 && ( - - - - )} - {"isEllipsis" in item && item.isEllipsis ? ( - - - - - - -
- {generateBreadcrumbs().map((subItem) => ( - - {subItem.name} - - ))} -
-
-
-
- ) : ( - - {index === breadcrumbItems.length - 1 ? ( - - {item.name} - - ) : ( - - - {item.name} - - - )} - - )} -
- ))} -
-
-
-
{children}
-
- ); -} diff --git a/app/blog/[slug]/page.tsx b/app/blog/[slug]/page.tsx deleted file mode 100644 index b98610b..0000000 --- a/app/blog/[slug]/page.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { notFound } from "next/navigation"; - -import PostHero from "@/components/blocks/post-hero"; -import RecentArticles from "@/components/blocks/recent-articles"; - -import PortableTextRenderer from "@/components/portable-text-renderer"; -import { - fetchSanityPostBySlug, - fetchSanityPostsStaticParams, -} from "@/sanity/lib/fetch"; -import { generatePageMetadata } from "@/sanity/lib/metadata"; - -export async function generateStaticParams() { - const posts = await fetchSanityPostsStaticParams(); - - return posts.map((post) => ({ - slug: post.slug?.current, - })); -} - -export async function generateMetadata(props: { - params: Promise<{ slug: string }>; -}) { - const params = await props.params; - const post = await fetchSanityPostBySlug({ slug: params.slug }); - - if (!post) { - notFound(); - } - - return generatePageMetadata({ page: post, slug: `blog/${params.slug}` }); -} - -export default async function PostPage(props: { - params: Promise<{ slug: string }>; -}) { - const params = await props.params; - const post = await fetchSanityPostBySlug(params); - - if (!post) { - notFound(); - } - - return ( -
-
-
- - {post.body && } -
- -
-
- ); -} diff --git a/app/blog/layout.tsx b/app/blog/layout.tsx deleted file mode 100644 index f9976e8..0000000 --- a/app/blog/layout.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { DisableDraftMode } from "@/components/disable-draft-mode"; -import { VisualEditing } from "next-sanity"; -import { draftMode } from "next/headers"; -import { SanityLive } from "@/sanity/lib/live"; - -export default async function MainLayout({ - children, -}: { - children: React.ReactNode; -}) { - return ( - <> -
{children}
- - {(await draftMode()).isEnabled && ( - <> - - - - )} - - ); -} diff --git a/app/blog/page.tsx b/app/blog/page.tsx deleted file mode 100644 index 4287348..0000000 --- a/app/blog/page.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import Blocks from "@/components/blocks"; -import { fetchSanityPageBySlug } from "@/sanity/lib/fetch"; -import { generatePageMetadata } from "@/sanity/lib/metadata"; -import MissingSanityPage from "@/components/ui/missing-sanity-page"; - -export async function generateMetadata() { - const page = await fetchSanityPageBySlug({ slug: "blog" }); - - return generatePageMetadata({ page, slug: "blog" }); -} - -export default async function IndexPage() { - const page = await fetchSanityPageBySlug({ slug: "blog" }); - - if (!page) { - return MissingSanityPage({ document: "page", slug: "blog" }); - } - - return ; -} diff --git a/app/blog/sitemap.ts b/app/blog/sitemap.ts deleted file mode 100644 index 6eea972..0000000 --- a/app/blog/sitemap.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { MetadataRoute } from "next"; -import { groq } from "next-sanity"; -import { client } from "@/sanity/lib/client"; - -const POSTS_PER_SITEMAP = 50000; - -export async function generateSitemaps() { - const countQuery = groq`count(*[_type == "post" && noindex != true])`; - const total = await client.fetch(countQuery); - const sitemapsNeeded = Math.max( - 1, - Math.ceil((total || 0) / POSTS_PER_SITEMAP) - ); - return Array.from({ length: sitemapsNeeded }, (_, index) => ({ id: index })); -} - -export default async function sitemap({ - id, -}: { - id: number; -}): Promise { - const baseUrl = - process.env.SITE_URL || - process.env.NEXT_PUBLIC_SITE_URL || - "https://apis.guru/"; - - const start = id * POSTS_PER_SITEMAP; - const end = start + POSTS_PER_SITEMAP - 1; - - const postsQuery = groq` - *[_type == "post" && noindex != true] | order(_updatedAt desc) [${start}..${end}]{ - "url": $baseUrl + "/blog/" + slug.current, - "lastModified": _updatedAt, - "changeFrequency": "daily", - "priority": 0.7 - } - `; - - const posts = await client.fetch(postsQuery, { - baseUrl, - }); - - return posts ?? []; -} diff --git a/app/favicon.ico b/app/favicon.ico deleted file mode 100644 index 718d6fe..0000000 Binary files a/app/favicon.ico and /dev/null differ diff --git a/app/global-error.tsx b/app/global-error.tsx deleted file mode 100644 index 9388e06..0000000 --- a/app/global-error.tsx +++ /dev/null @@ -1,27 +0,0 @@ -"use client"; - -import * as Sentry from "@sentry/nextjs"; -import NextError from "next/error"; -import { useEffect } from "react"; - -export default function GlobalError({ - error, -}: { - error: Error & { digest?: string }; -}) { - useEffect(() => { - Sentry.captureException(error); - }, [error]); - - return ( - - - {/* `NextError` is the default Next.js error page component. Its type - definition requires a `statusCode` prop. However, since the App Router - does not expose status codes for errors, we simply pass 0 to render a - generic error message. */} - - - - ); -} diff --git a/app/globals.css b/app/globals.css deleted file mode 100644 index 91815a7..0000000 --- a/app/globals.css +++ /dev/null @@ -1,261 +0,0 @@ -@import "https://github.com/tailwindcss"; -@import "https://github.com/tw-animate-css"; -@plugin '@tailwindcss/typography'; - -@custom-variant dark (&:is(.dark *)); - -@font-face { - font-family: "Sansation"; - src: - url("https://github.com/fonts/Sansation-Regular-webfont.woff2") format("woff2"), - url("https://github.com/fonts/Sansation-Regular-webfont.woff") format("woff"); - font-weight: normal; - font-style: normal; -} - -@font-face { - font-family: "Sansation"; - src: - url("https://github.com/fonts/Sansation-Bold-webfont.woff2") format("woff2"), - url("https://github.com/fonts/Sansation-Bold-webfont.woff") format("woff"); - font-weight: bold; - font-style: normal; -} - -@font-face { - font-family: "Sansation"; - src: - url("https://github.com/fonts/Sansation-Light-webfont.woff2") format("woff2"), - url("https://github.com/fonts/Sansation-Light-webfont.woff") format("woff"); - font-weight: 200; - font-style: normal; -} - -@theme inline { - --color-background: var(--background); - --color-foreground: var(--foreground); - --font-sans: "Sansation", Helvetica, Arial, sans-serif; - --font-mono: var(--font-geist-mono); - --small-font-size: 16px; /* 16px * 0.875 from SCSS */ - --base-line-height: 1.5; - --color-sidebar-ring: var(--sidebar-ring); - --color-sidebar-border: var(--sidebar-border); - --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); - --color-sidebar-accent: var(--sidebar-accent); - --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); - --color-sidebar-primary: var(--sidebar-primary); - --color-sidebar-foreground: var(--sidebar-foreground); - --color-sidebar: var(--sidebar); - --color-chart-5: var(--chart-5); - --color-chart-4: var(--chart-4); - --color-chart-3: var(--chart-3); - --color-chart-2: var(--chart-2); - --color-chart-1: var(--chart-1); - --color-ring: var(--ring); - --color-input: var(--input); - --color-border: var(--border); - --color-destructive: var(--destructive); - --color-accent-foreground: var(--accent-foreground); - --color-accent: var(--accent); - --color-muted-foreground: var(--muted-foreground); - --color-muted: var(--muted); - --color-secondary-foreground: var(--secondary-foreground); - --color-secondary: var(--secondary); - --color-primary-foreground: var(--primary-foreground); - --color-primary: var(--primary); - --color-popover-foreground: var(--popover-foreground); - --color-popover: var(--popover); - --color-card-foreground: var(--card-foreground); - --color-card: var(--card); - --radius-sm: calc(var(--radius) - 4px); - --radius-md: calc(var(--radius) - 2px); - --radius-lg: var(--radius); - --radius-xl: calc(var(--radius) + 4px); - --brand-color: var(--brand); - --brand-color-light: var(--brand-light); - --brand-color-dark: var(--brand-dark); - --secondary-color: var(--sec); - --secondary-color-light: var(--sec-light); -} -@utility container { - width: 100%; - margin-left: auto; - margin-right: auto; - padding-left: 1rem; - padding-right: 1rem; - @media (width >= theme(--breakpoint-sm)) { - max-width: 640px; - padding-left: 2rem; - padding-right: 2rem; - } - @media (width >= theme(--breakpoint-md)) { - max-width: 768px; - } - @media (width >= theme(--breakpoint-lg)) { - max-width: 1024px; - } - @media (width >= theme(--breakpoint-xl)) { - max-width: 1280px; - padding-left: 4rem; - padding-right: 4rem; - } -} -:root { - --radius: 0.625rem; - --background: #ffffff; - --foreground: #333333; - --card: #ffffff; - --card-foreground: #333333; - --popover: #ffffff; - --popover-foreground: #333333; - --primary: #f5c01b; - --primary-foreground: #ffffff; - --secondary: #48acbd; - --secondary-foreground: #ffffff; - --muted: #f1f1f1; - --muted-foreground: #666666; - --accent: #f7d16f; - --accent-foreground: #333333; - --destructive: oklch(0.577 0.245 27.325); - --border: #dddddd; - --input: #dddddd; - --ring: #f5c01b; - --chart-1: #f5c01b; - --chart-2: #f7d16f; - --chart-3: #f39925; - --chart-4: #48acbd; - --chart-5: #9dd4e1; - --sidebar: #ffffff; - --sidebar-foreground: #333333; - --sidebar-primary: #f5c01b; - --sidebar-primary-foreground: #ffffff; - --sidebar-accent: #f7d16f; - --sidebar-accent-foreground: #333333; - --sidebar-border: #dddddd; - --sidebar-ring: #f5c01b; - --brand: #f5c01b; - --brand-light: #f7d16f; - --brand-dark: #f39925; - --sec: #48acbd; - --sec-light: #9dd4e1; -} - -.dark { - --background: #1a1a1a; - --foreground: #ffffff; - --card: #222222; - --card-foreground: #ffffff; - --popover: #222222; - --popover-foreground: #ffffff; - --primary: #f7d16f; - --primary-foreground: #333333; - --secondary: #48acbd; - --secondary-foreground: #ffffff; - --muted: #333333; - --muted-foreground: #999999; - --accent: #f5c01b; - --accent-foreground: #ffffff; - --destructive: oklch(0.704 0.191 22.216); - --border: rgba(255, 255, 255, 0.1); - --input: rgba(255, 255, 255, 0.15); - --ring: #f7d16f; - --chart-1: #f7d16f; - --chart-2: #f5c01b; - --chart-3: #f39925; - --chart-4: #48acbd; - --chart-5: #9dd4e1; - --sidebar: #222222; - --sidebar-foreground: #ffffff; - --sidebar-primary: #f7d16f; - --sidebar-primary-foreground: #333333; - --sidebar-accent: #333333; - --sidebar-accent-foreground: #ffffff; - --sidebar-border: rgba(255, 255, 255, 0.1); - --sidebar-ring: #f7d16f; - --brand: #f5c01b; - --brand-light: #f7d16f; - --brand-dark: #f39925; - --sec: #48acbd; - --sec-light: #9dd4e1; -} - -@layer base { - * { - @apply border-border outline-ring/50; - } - body { - @apply bg-background text-foreground font-sans; - font-weight: 200; - font-size: 16px; - line-height: 1.5; - } - body { - @apply bg-background text-foreground font-sans; - font-family: "Sansation", Helvetica, Arial, sans-serif; - font-weight: 200; - font-size: 16px; - line-height: 1.5; - color: #333; - background-color: #fff; - -webkit-text-size-adjust: 100%; - -webkit-font-feature-settings: - "kern" 1, - "liga" off; - font-feature-settings: - "kern" 1, - "liga" off; - font-kerning: normal; - width: 100%; - height: 100%; - } - /* Ensure small text matches SCSS small-font-size */ - .text-sm { - font-size: var(--small-font-size, 14px); - } - - /* Custom markdown table styling */ - .prose table { - width: 100%; - margin: 2rem 0; - font-size: 0.875rem; - } - - .prose table th { - text-align: left; - font-weight: 600; - vertical-align: top; - } - - .prose table td { - vertical-align: top; - } - - .prose table th:nth-child(3), - .prose table td:nth-child(3) { - text-align: center; - width: 100px; - } - - .prose table th:nth-child(4), - .prose table td:nth-child(4) { - text-align: center; - width: 120px; - } - - /* Improve link styling in tables */ - .prose table a { - font-weight: 500; - text-decoration: none; - border-radius: 4px; - padding: 2px 6px; - transition: all 0.2s ease; - } - - /* Emoji support */ - .prose img[alt*="smile"] { - display: inline; - margin: 0; - width: 1em; - height: 1em; - } -} diff --git a/app/graphql-apis/page.tsx b/app/graphql-apis/page.tsx deleted file mode 100644 index 195de27..0000000 --- a/app/graphql-apis/page.tsx +++ /dev/null @@ -1,134 +0,0 @@ -import ReactMarkdown from "react-markdown"; -import remarkGfm from "remark-gfm"; -import rehypeRaw from "rehype-raw"; -import { generateSimpleMetadata } from "@/sanity/lib/metadata"; - -export async function generateMetadata() { - return generateSimpleMetadata({ - title: "Public GraphQL APIs", - description: - "A collective list of public GraphQL APIs. Discover and explore GraphQL endpoints from various providers.", - slug: "graphql-apis", - }); -} - -// Define your markdown content here -const markdownContent = `# Public GraphQL APIs - -*A collective list of public [GraphQL](https://graphql.org/) APIs. PRs are welcome :smile:* -If you are interested in GraphQL in general, check out [awesome-graphql](https://github.com/chentsulin/awesome-graphql). - -## Official APIs - -| API | Description | Graph*i*QL | Docs/Repo -| --- | ----------- | :--------: | :-: | -| AniList | Anime and manga datum, including character, staff, and live airing data. | [Try it!](https://anilist.co/graphiql) | [Docs](https://anilist.gitbook.io/anilist-apiv2-docs/) -| Artsy | free online platform for collecting and discovering art | [Try it!](https://github.com/artsy/metaphysics/tree/2eab34884eed9204acfd3f3507e1f91eaae5d424?tab=readme-ov-file#setting-up-your-local-graphiql) | [Repo](https://github.com/artsy/metaphysics) -| Bitquery | on-chain blockchain analytics | [Try it!](https://graphql.bitquery.io) | [Docs](https://bitquery.io/blog/working-with-blockchain-data) -| Braintree | Payment platform | [Try it!](https://graphql.braintreepayments.com/explorer) | [Docs](https://graphql.braintreepayments.com/) -| Buildkite | Continuous integration and deployments | [Try it!](https://graphql.buildkite.com/) | [Docs](https://building.buildkite.com/tutorial-getting-started-with-graphql-queries-and-mutations-11211dfe5d64#.7uhjusw1q) -| Canopy | The missing GraphQL API for Amazon.com e-commerce | [Try it!](https://graphql.canopyapi.co/) | [Repo](https://github.com/canopy-api/canopy-api)
[Docs](https://docs.canopyapi.co/) | -| Catalysis Hub | Chemical surface reaction energies and structures | [Try it!](http://api.catalysis-hub.org/graphql) | [Repo](https://github.com/SUNCAT-Center/CatalysisHubBackend)
[Docs](http://docs.catalysis-hub.org/en/latest/tutorials/index.html#graphql) -| Changetrip | The Chargetrip API gives you the ability to integrate smart, EV-specific routing into products built for electric car drivers. | [Try it!](https://playground.chargetrip.com/) | [Docs](https://developers.chargetrip.com/API-Reference/API/introduction) -| CommerceTools | e-commerce solutions | [Try it!](https://impex.commercetools.com/graphiql) | [Docs](https://docs.commercetools.com/graphql-api) -| Contentful | "CMS as a Service". Graph*i*QL demo allows to query a simple blog, but the library itself generates a schema automatically for any content model you store in Contentful. | [Try it!](https://graphql.contentful.com/content/v1/spaces/f8bqpb154z8p/explore?access_token=9d5de88248563ebc0d2ad688d0473f56fcd31c600e419d6c8962f6aed0150599&query=%7B%0A%20%20lessonCollection(where%3A%20%7B%20%0A%09%09OR%3A%20%5B%0A%09%09%09%7B%20title_contains%3A%20%22content%22%20%7D%2C%0A%09%09%09%7B%20title_contains%3A%20%22SDK%22%20%7D%0A%09%09%5D%0A%20%20%7D)%20%7B%0A%20%20%20%20items%20%7B%0A%20%20%20%20%20%20title%0A%20%20%20%20%20%20slug%0A%20%20%20%20%20%20modulesCollection(limit%3A%202%2C%20skip%3A%201)%20%7B%0A%20%20%20%20%20%20%20%20total%0A%09%09%09%09limit%0A%09%09%09%09skip%0A%20%20%20%20%20%20%20%20items%20%7B%0A%20%20%20%20%20%20%20%20%20%20...imageUrl%0A%09%09%09%09%09...%20on%20LessonCodeSnippets%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20title%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20...%20on%20LessonCopy%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20sys%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20id%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D%0A%0Afragment%20imageUrl%20on%20LessonImage%20%7B%0A%20%20title%0A%20%20image%20%7B%0A%20%20%20%20url%0A%20%20%7D%0A%7D) | [Docs](https://www.contentful.com/developers/docs/tutorials/general/graphql/) -| Countries | Information about countries, continents, and languages, based on [Countries List](https://annexare.github.io/Countries/) | [Try it!](https://countries.trevorblades.com) | [Repo](https://github.com/trevorblades/countries) -| Deutsche Bahn | Infrastructure Data, like realtime facility status, stations, timetables and more | [Try it!](https://bahnql.herokuapp.com/graphql) | [Repo](https://github.com/dbsystel/1BahnQL) -| Digitransit HSL | Transit routes and realtime schedules from Helsinki Regional Transport Authority, Finland | [Try it!](https://api.digitransit.fi/graphiql/finland) | [Docs](https://digitransit.fi/en/developers/apis/1-routing-api/1-graphiql/) -| EAN-Search | Search barcodes and products | [Try it!](https://api.ean-search.org/graphql) | [Docs](https://www.ean-search.org/blog/graphql-ean-api.html) -| EHRI | Holocaust-related archival materials | [Try it!](https://portal.ehri-project.eu/api/graphql/ui) | [Docs](https://portal.ehri-project.eu/api/graphql) -| EtMDB | Ethiopian Movie Database | [Try it!](https://etmdb.com/graphql?query=%7B%0A%20%20allCinemaDetails(before%3A%20%222017-10-04%22%2C%20after%3A%20%222010-01-01%22)%20%7B%0A%20%20%20%20edges%20%7B%0A%20%20%20%20%20%20node%20%7B%0A%20%20%20%20%20%20%20%20slug%0A%20%20%20%20%20%20%20%20hallName%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D%0A) | [Docs](https://etmdb.com/api/docs/) -| FaunaDB | Serverless GraphQL Database | [Try it!](https://fauna.com/blog/try-faunadbs-graphql-api) | [Docs](https://docs.fauna.com/fauna/current/graphql) -| Gdom | DOM Traversing and Scraping using GraphQL | [Try it!](http://gdom.graphene-python.org/graphql?query=%7B%0A++page%28url%3A%22http%3A%2F%2Fnews.ycombinator.com%22%29+%7B%0A++++items%3A+query%28selector%3A%22tr.athing%22%29+%7B%0A++++++rank%3A+text%28selector%3A%22td+span.rank%22%29%0A++++++title%3A+text%28selector%3A%22td.title+a%22%29%0A++++++sitebit%3A+text%28selector%3A%22span.comhead+a%22%29%0A++++++url%3A+attr%28selector%3A%22td.title+a%22%2C+name%3A%22href%22%29%0A++++++attrs%3A+next+%7B%0A+++++++++score%3A+text%28selector%3A%22span.score%22%29%0A+++++++++user%3A+text%28selector%3A%22a%3Aeq%280%29%22%29%0A+++++++++comments%3A+text%28selector%3A%22a%3Aeq%282%29%22%29%0A++++++%7D%0A++++%7D%0A++%7D%0A%7D) | [Repo](https://github.com/syrusakbary/gdom) -| GitHub | Web-based Git repository hosting service | [Try it!](https://developer.github.com/v4/explorer/) | [Docs](https://docs.github.com/v4/) -| GitLab | Host-your-own Git repository hosting service | [Try it!](https://gitlab.com/-/graphql-explorer) | [Docs](https://docs.gitlab.com/ee/api/graphql/) -| GraphLoc | Find a geolocation of an IP address including latitude, longitude, city, country, time zone and area code. Free to use, SSL supported | [Try it!](https://graphloc.com) | [Docs](https://www.graphloc.com) -| GraphQL Jobs | GraphQL jobs in modern startups | [Try it!](https://api.graphql.jobs) | [Docs](https://graphql.jobs/docs/api)| -| HIVDB | A curated database to represent, store and analyze HIV drug resistance data | [Try it!](https://hivdb.stanford.edu/page/graphiql/) | [Docs](https://hivdb.stanford.edu/page/webservice/) -| Idobata | Dedicated chat for team development. | [Try it!](https://idobata.io/api) | | -| leanIX | Tools for business strategy | | [Docs](https://dev.leanix.net/docs/graphql-api) -| Pipefy | The operations excellence platform. | [Try it!](https://app.pipefy.com/graphiql) | [Docs](https://developers.pipefy.com) | -| Mattermark | Business research and networking | | [Docs](https://developer.mattermark.com/docs/graphql) -| Memair | Quantified self / extended mind platform | [Try it!](https://memair.com/graphiql) | [Docs](https://docs.memair.com) -| melodyRepo | Fast and reliable dependency manager for Go | [Try it!](https://melody.sh/play/) | [Docs](https://melody.sh/docs/api) -| monday.com | Connect to your monday data with the platform API. An expressive API to interact with your workflows, automate processes, power integrations, and more. | [Try it!](https://monday.com/developers/v2/try-it-yourself?ref=graphqlkit) | [Docs](https://developer.monday.com/api-reference?ref=graphqlkit) -| React Finland | React Finland API is built with conferences and meetups in mind | [Try it!](https://api.react-finland.fi/graphql) | [Repo](https://github.com/ReactFinland/graphql-api) -| Saleor | Headless open-source E-commerce API for storefront and admin | [Try it!](https://demo.saleor.io/graphql/) | [Docs](https://docs.saleor.io/docs/3.x/developer/api-reference/) -| Shopify Storefront | The Storefront API gives you full creative control to build customized purchasing experiences for your customers. | [Try it!](https://help.shopify.com/api/storefront-graphiql) | [Docs](https://help.shopify.com/api/storefront-api)
[Examples](https://github.com/Shopify/storefront-api-examples) -| Shopify Admin | The Admin API is the primary way that apps and services interact with Shopify. | [Try it!](https://shopify-graphiql-app.shopifycloud.com/login) | [Docs](https://shopify.dev/docs/admin-api/graphql/reference) -| SWOP | GraphQL and REST foreign exchange rate API. Note: Required registration. | [Try it!](https://swop.cx/) | [Docs](https://swop.cx/documentation) -| Universe | Check what your friends are doing & find unique events near you using our filter. | [Try it!](https://www.universe.com/graphiql) | [Docs](https://developers.universe.com/docs/graphql) -| Yelp | User Reviews and Recommendations of Top Restaurants, Shopping, Nightlife, Entertainment, Services and More | [Try it!](https://docs.developer.yelp.com/graphql) | [Docs](https://docs.developer.yelp.com/docs/graphql-intro) -| TravelgateX | The global marketplace for the travel trade | [Try it!](https://api.travelgatex.com/) | [Docs](https://docs.travelgatex.com/getting-started/) -| TCGdex | A Multilanguage Pokémon TCG Database with Cards Pictures and most of the informations contained on the cards. | [Try it!](https://api.tcgdex.net/v2/graphql) | [Repo](https://github.com/tcgdex/cards-database) - -## Unofficial API proxies - -| API | Description | Graph*i*QL | Docs/Repo -| --- | ----------- | :--------: | :-: | -| Barcelona Urban Mobility API | Information about the different public transport / urban mobility services of Barcelona | [Try it!](https://barcelona-urban-mobility-graphql-api.netlify.app/graphql) | [Repo](https://github.com/aalises/barcelona-urban-mobility-graphql-api) -| Câmara dos deputados Brasil | "GraphQL api to grab the data from the brazilian deputies chamber" | [Try it!](https://graphql-camara-deputados.herokuapp.com/) | [Repo](https://github.com/matheusrocha89/graphql-camara-deputados) -| Ghibliql | "GhibliQL is a GraphQL wrapper to the Studio Ghibli REST API" | [Try it!](https://ghibliql.herokuapp.com/) | [Repo](https://github.com/kisscool-fr/ghibliql) -| Favware's GraphQL Pokémon | Query for all the Pokémon, and their abilities, moves, items, learnsets, and type matchups from generations 1 through 8. This API strives to always stay up-to-date with new Pokémon releases, and has multiple contributors to achieve this. | [Try it!](https://graphqlpokemon.favware.tech) | [Repo](https://github.com/favware/graphql-pokemon)| -| MetaMate | Semantic service bus example for HackerNews | [Try it!](https://metamate.io/blog/most-advanced-hackernews-api/) | [Repo](https://github.com/metamatex/metamate)
[Examples](https://showcase.metamate.io/hackernews-user-activity) -| MusicBrainz | Open music encyclopedia that collects music metadata | [Try it!](https://graphbrainz.herokuapp.com/?query=query%20NirvanaAlbumSingles%20%7B%0A%20%20lookup%20%7B%0A%20%20%20%20artist(mbid%3A%20%225b11f4ce-a62d-471e-81fc-a69a8278c7da%22)%20%7B%0A%20%20%20%20%20%20name%0A%20%20%20%20%20%20releaseGroups(type%3A%20ALBUM)%20%7B%0A%20%20%20%20%20%20%20%20edges%20%7B%0A%20%20%20%20%20%20%20%20%20%20node%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20title%0A%20%20%20%20%20%20%20%20%20%20%20%20firstReleaseDate%0A%20%20%20%20%20%20%20%20%20%20%20%20relationships%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20releaseGroups(type%3A%20%22single%20from%22)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20edges%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20node%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20target%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20...%20on%20ReleaseGroup%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20title%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20firstReleaseDate%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D%0A&operationName=NirvanaAlbumSingles) | [Repo](https://github.com/exogen/graphbrainz) -| PokeAPI | Pokémon Data API | [Try it!](https://pokeapi-graphiql.herokuapp.com/) | [Repo](https://github.com/patrickshaughnessy/PokeAPI-GraphQL) -| Spacex Land | A non official platform for SpaceX's data! | [Try it!](https://api.spacex.land/graphql/) | [Docs](https://spacex.land/) -| Spotify | Spotify gives you instant access to millions of songs - from old favorites to the latest hits. | [Try it!](https://spotify-api-graphql-console.herokuapp.com/) | [Repo](https://github.com/thefrenchhouse/spotify-graphql)
[Examples](https://github.com/thefrenchhouse/spotify-graphql-examples) -| Stratz | Dota 2 Statistics Api | [Try it!](https://api.stratz.com/graphiql/) | [Site](https://stratz.com/welcome) -| SWAPI | Star Wars API | [Try it!](https://graphql.org/swapi-graphql/) | [Repo](https://github.com/graphql/swapi-graphql) -| Star-Wars-Api | A fully fledged Star Wars API. Using mostly the same data source as [swapi.dev](https://swapi.dev), but way faster (no Django overhead) and easier to query nested data. | [Try it!](https://swapi.skyra.pw) | [Repo](https://github.com/skyra-project/star-wars-api) -| TMDB | The Movie Database Wrapper | [Try it!](https://tmdb.apps.quintero.io/) | [Repo](https://github.com/nerdsupremacist/tmdb) - - -## Demonstration-only APIs - -| API | Description | Graph*i*QL | Docs/Repo -| --- | ----------- | :--------: | :-: | -| A-Maze | [Enter the maze](https://maze.andreamazzarella.com), try to get out! | [Try it!](https://maze.andreamazzarella.com/graphiql) | [Repo](https://github.com/andreamazza89/amaze)| -| Demotivational Quotes API | Get Random Demotivational quote and its author | [Try it!](https://demotivation-quotes-api.herokuapp.com/graphql) | [Repo](https://github.com/aravindasiva/demotivational-quotes-api)| -| Lucas Bento's GraphQL Pokémon | Get information of a Pokémon with GraphQL! (**Note**: Only has data on Generation 1, and only has data on Pokémon!) | [Try it!](https://react-relay-pokemon.now.sh/#/) | [Repo](https://github.com/lucasbento/graphql-pokemon)
[ClientRepo](https://github.com/lucasbento/react-relay-pokemon) -| MongoDB Northwind demo | [Demo App](https://nodkz.github.io/relay-northwind/) build on top of [graphql-compose](https://github.com/nodkz/graphql-compose) and [mongoose](https://github.com/Automattic/mongoose) | [Try it!](https://graphql-compose.herokuapp.com/northwind/)
[Try Relay version!](https://nodkz.github.io/relay-northwind/) | [Docs](https://github.com/nodkz/graphql-compose)
[ServerRepo](https://github.com/nodkz/graphql-compose-examples)
[ClientRepo](https://github.com/nodkz/relay-northwind-app) -| MongoDB TODO-List | TODO List using GraphQL and MongoDb | [Try it!](https://todo-mongo-graphql-server.herokuapp.com/) | [Docs](https://www.compose.com/articles/using-graphql-with-mongodb/)
[Repo](https://github.com/igorlima/todo-mongo-graphql-server) -| Planets | Information about planets and exoplanets, including mass, radius, orbit, semimajor axis, and how it was discovered. | [Try it!](https://pristine-gadget-267405.appspot.com/graphql/) | [Repo](https://github.com/ZaneTurner/PlanetsAPI) -| Spotify GraphQL Server | This demonstrates how to build a GraphQL server which fetches data from an external API (Spotify) | [Try it!](https://spotify-graphql-server.herokuapp.com/) | [Repo](https://github.com/lowsky/spotify-graphql-server) -| Three.js demo | Declare a Three.js program with GraphQL | [Try it!](https://jwerle.github.io/three.graphql/) | [Repo](https://github.com/jwerle/three.graphql) -| UFC GraphQL Server | Public UFC API turned into a GraphQL server. It's hosted by [now.sh](https://now.sh/) then, sometimes, it gets freeze. | [Try it!](https://graphql-ufc-api.now.sh/) | [Repo](https://github.com/jgcmarins/graphql-ufc-api) -| Google directions API | GraphQL wrapper for google directions API. | [Try it!](https://directions-graphql.herokuapp.com/graphql) | [Repo](https://github.com/Arjun-sna/directions_graphql/) -| FakeQL | GraphQL API mocking as a service. | [Try it!](https://fakeql.com/) | [Docs](https://www.blowson.com/docs/) -| The Rick and Morty API | All the Rick and Morty information. | [Try it!](https://rickandmortyapi.com/graphql) | [Docs](https://rickandmortyapi.com/documentation/#graphql) -| UN SDG data series API | UN SDG statistical data served via GraphQL as JSON-LD objects mapped to RDF Data Cube Vocabulary | [Try it!](http://linkedsdg.apps.officialstatistics.org/graphql/) | [Code](https://code.officialstatistics.org/cslovell/sdg-docker-ontologies/tree/master/sdgapi)
[Docs](https://github.com/UNStats/LOD4Stats/wiki/SDG-series-as-RDF-Data-Cubes#querying-sdg-statistical-series-data-via-graphql)
[Blog post](https://medium.com/@sklarman/linked-open-statistical-data-served-simply-ead245bf715) -| Weather API | Retrieve the current weather for any given city | [Try it!](https://graphql-weather-api.herokuapp.com/) | [Repo](https://github.com/konstantinmuenster/graphql-weather-api) -| Fake GraphQL API | Mock user and to do data | [Try it!](https://mocki.io/graphql) | [Docs](https://mocki.io/docs) -| Fruits API | Information of fruit trees of the world | [Try it!](https://fruits-api.netlify.app/graphql) | [Docs](https://github.com/Franqsanz/fruits-api/blob/main/readme.md)`; - -export default function GraphQLAPIsPage() { - return ( -
-
-
-
- - {markdownContent} - -
-
-
-
- ); -} diff --git a/app/layout.tsx b/app/layout.tsx deleted file mode 100644 index c2313d0..0000000 --- a/app/layout.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import { Geist, Geist_Mono, Roboto } from "next/font/google"; -import Header from "@/components/Header"; -import Footer from "@/components/Footer"; -import Support from "@/components/Support"; -import Script from "next/script"; -import "./globals.css"; - -const geistSans = Geist({ - variable: "--font-geist-sans", - subsets: ["latin"], -}); - -const geistMono = Geist_Mono({ - variable: "--font-geist-mono", - subsets: ["latin"], -}); - -const roboto = Roboto({ - variable: "--font-roboto", - subsets: ["latin"], - weight: ["300", "400"], - style: ["normal", "italic"], - display: "swap", -}); - -export const metadata = { - title: { - default: "APIs.guru - Wikipedia for Web APIs", - template: "%s | Api Directory", - }, - description: - "Wikipedia for Web APIs. Directory of REST API specs in OpenAPI 3.0 format", - viewport: "width=device-width, initial-scale=1", - icons: { - icon: [ - { - url: "/images/favicons/icon-16x16.png", - sizes: "16x16", - type: "image/png", - }, - { - url: "/images/favicons/icon-32x32.png", - sizes: "32x32", - type: "image/png", - }, - { - url: "/images/favicons/icon-96x96.png", - sizes: "96x96", - type: "image/png", - }, - ], - }, - metadataBase: new URL( - process.env.NEXT_PUBLIC_SITE_URL || "https://apis.guru/" - ), -}; - -export default function RootLayout({ - children, -}: { - children: React.ReactNode; -}) { - return ( - - -
- -
{children}
- -