@codexsploitx/schemaapi 1.1.12 → 1.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codexsploitx/schemaapi",
3
- "version": "1.1.12",
3
+ "version": "1.1.13",
4
4
  "description": "Type-safe API contracts (HTTP/WebSocket) with adapters, client and docs generator.",
5
5
  "main": "dist/schemaapi.cjs.js",
6
6
  "module": "dist/schemaapi.esm.js",
package/readme.md CHANGED
@@ -1,291 +1,179 @@
1
1
  <div align="center">
2
2
 
3
- # SchemaApi
3
+ # SchemaApi
4
4
 
5
- **The Zod of APIs**
6
- *Type-safe contracts. Runtime validation. Auto-generated docs.*
5
+ ### **The Contract-First API Standard for TypeScript**
7
6
 
8
- [![npm version](https://img.shields.io/npm/v/%40codexsploitx%2Fschemaapi?style=flat-square&color=blue)](https://www.npmjs.com/package/@codexsploitx/schemaapi)
9
- [![License](https://img.shields.io/npm/l/%40codexsploitx%2Fschemaapi?style=flat-square&color=green)](LICENSE)
10
- [![Tests](https://img.shields.io/github/actions/workflow/status/CodexSploitx/SchemaApi/test.yml?label=tests&style=flat-square)](https://github.com/CodexSploitx/SchemaApi/actions)
11
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue?style=flat-square&logo=typescript)](https://www.typescriptlang.org/)
7
+ <p align="center">
8
+ <a href="https://codexsploitx.github.io/SchemaApi/">Website</a> •
9
+ <a href="#-quick-start">Quick Start</a> •
10
+ <a href="#-adapters">Adapters</a> •
11
+ <a href="#-documentation">Docs</a>
12
+ </p>
12
13
 
13
- [Features](#-features) • [Installation](#-installation) • [Usage](#-usage) • [Adapters](#-adapters) • [Documentation](#-documentation)
14
+ [![npm version](https://img.shields.io/npm/v/@codexsploitx/schemaapi?style=for-the-badge&color=7b2cbf)](https://www.npmjs.com/package/@codexsploitx/schemaapi)
15
+ [![Downloads](https://img.shields.io/npm/dm/@codexsploitx/schemaapi?style=for-the-badge&color=00f5d4)](https://www.npmjs.com/package/@codexsploitx/schemaapi)
16
+ [![License](https://img.shields.io/npm/l/@codexsploitx/schemaapi?style=for-the-badge&color=f72585)](LICENSE)
17
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Strict-blue?style=for-the-badge&logo=typescript)](https://www.typescriptlang.org/)
14
18
 
15
- </div>
19
+ <br>
16
20
 
17
- ---
21
+ **Build type-safe APIs at the speed of thought.**
22
+ Define your contract once. Generate Backend Controllers, Frontend SDKs, and Documentation instantly.
18
23
 
19
- ## 🚀 Why SchemaApi?
24
+ </div>
20
25
 
21
- **Your API is a contract.** But in most codebases, that contract is broken into pieces:
22
- - Validation logic in controllers.
23
- - Types in a `types.ts` file.
24
- - Documentation in a stale Swagger file.
25
- - Client SDKs handwritten (and buggy).
26
+ ---
26
27
 
27
- **SchemaApi** unifies everything into a **Single Source of Truth**. Define your contract once, and get everything else for free.
28
+ ## 🔮 The Future of API Development
28
29
 
29
- > "It doesn't replace your framework. It makes it invincible."
30
+ **SchemaApi** isn't just a validation library. It's an **Architecture**.
30
31
 
31
- ---
32
+ By defining a **Single Source of Truth** (Contract), you eliminate the disconnect between your Backend and Frontend.
32
33
 
33
- ## Features
34
+ ### 🆚 The Old Way vs. The SchemaApi Way
34
35
 
35
- | Feature | Description |
36
+ | Traditional | SchemaApi |
36
37
  | :--- | :--- |
37
- | **🛡️ End-to-End Type Safety** | Types flow from your server contract directly to your client SDK. No code generation required. |
38
- | **⚡ Runtime Validation** | Powered by **[Zod](https://zod.dev)**. Automatically validates params, query, body, and headers. |
39
- | **🔐 Built-in Security** | Define `roles` and `scopes` directly in your contract. RBAC made simple. |
40
- | **📚 Auto Documentation** | Generate beautiful, interactive HTML documentation that never drifts from code. |
41
- | **🔌 Framework Agnostic** | Works with Express, Next.js, Fastify, Remix, NestJS, and more. |
42
- | **📦 Zero-Config SDK** | Export a fully typed client that handles methods, paths, and errors for you. |
38
+ | Write Controllers manually | **Auto-generated strict controllers** |
39
+ | Write `types.ts` manually | **Types inferred from schema** |
40
+ | Write Frontend Fetch calls | **Auto-generated Typed SDK** |
41
+ | Update Swagger manually | **Auto-generated Documentation** |
42
+ | "It works on my machine" | **"It adheres to the contract"** |
43
43
 
44
44
  ---
45
45
 
46
- ## 📦 Installation
46
+ ## Superpowers
47
47
 
48
- ### Core package
49
-
50
- ```bash
51
- # npm
52
- npm install @codexsploitx/schemaapi zod
53
-
54
- # pnpm
55
- pnpm add @codexsploitx/schemaapi zod
56
-
57
- # yarn
58
- yarn add @codexsploitx/schemaapi zod
59
- ```
48
+ <div align="center">
60
49
 
61
- ### Per-adapter setup
50
+ | 🛡️ **End-to-End Type Safety** | ⚡ **Runtime Validation** | 🔌 **Adapter Agnostic** |
51
+ | :--- | :--- | :--- |
52
+ | Your Backend types **ARE** your Frontend types. Zero duplication. | Powered by **Zod**. If the data is wrong, the request never hits your logic. | Works with Express, Next.js, Fastify, NestJS, Remix, and more. |
62
53
 
63
- Below are the recommended commands for **new projects** and for **existing projects**.
54
+ | 📦 **Zero-Config SDK** | 🚀 **Instant Mocking** | 📚 **Live Documentation** |
55
+ | :--- | :--- | :--- |
56
+ | Frontend devs get a fully typed client. `client.users.get({ id })` | Start frontend work before the backend is even written. | Beautiful HTML docs generated from your contracts. |
64
57
 
65
- #### CLI quick reference
58
+ </div>
66
59
 
67
- | Adapter | Init command |
68
- |---------|----------------------------------------------------|
69
- | Express | `npx @codexsploitx/schemaapi init express` |
70
- | Next.js | `npx @codexsploitx/schemaapi init next` |
71
- | Fastify | `npx @codexsploitx/schemaapi init fastify` |
72
- | Remix | `npx @codexsploitx/schemaapi init remix` |
73
- | NestJS | `npx @codexsploitx/schemaapi init nest` |
74
- | Deno | `npx @codexsploitx/schemaapi init deno` |
60
+ ---
75
61
 
76
- #### Express
62
+ ## 🚀 Quick Start
77
63
 
78
- - 🆕 **New project**
64
+ Go from **Zero** to **Production-Ready API** in 30 seconds.
79
65
 
66
+ ### 1. Initialize
80
67
  ```bash
81
- mkdir my-express-api && cd my-express-api
82
- npm init -y
83
- npm install express @codexsploitx/schemaapi zod
84
68
  npx @codexsploitx/schemaapi init express
85
69
  ```
86
70
 
87
- - ♻️ **Existing Express project**
88
-
89
- ```bash
90
- npm install @codexsploitx/schemaapi zod
91
- npx @codexsploitx/schemaapi init express
92
- ```
93
-
94
- #### Next.js
95
-
96
- - 🆕 **New project**
97
-
98
- ```bash
99
- npx create-next-app@latest my-next-api --ts
100
- cd my-next-api
101
- npm install @codexsploitx/schemaapi zod
102
- npx @codexsploitx/schemaapi init next
103
- ```
104
-
105
- - ♻️ **Existing Next.js project**
106
-
71
+ ### 2. Generate Resource
107
72
  ```bash
108
- npm install @codexsploitx/schemaapi zod
109
- npx @codexsploitx/schemaapi init next
73
+ npx @codexsploitx/schemaapi generate resource users
110
74
  ```
111
75
 
112
- El comando `schemaapi init next` creará automáticamente:
113
-
114
- - Carpeta `contracts/` con un contrato de ejemplo `usersContract.ts`.
115
- - `contracts/index.ts` exportando los contratos.
116
- - `schemaapi.config.json` apuntando a `contracts/`.
117
- - Un handler de ejemplo compatible con **App Router** en `app/api/users/route.ts`.
118
-
119
- #### Fastify
120
-
121
- - 🆕 **New project**
122
-
76
+ ### 3. Generate SDK
123
77
  ```bash
124
- mkdir my-fastify-api && cd my-fastify-api
125
- npm init -y
126
- npm install fastify @codexsploitx/schemaapi zod
127
- npx @codexsploitx/schemaapi init fastify
78
+ npx @codexsploitx/schemaapi generate sdk users
128
79
  ```
129
80
 
130
- - ♻️ **Existing Fastify project**
81
+ **That's it.** You now have:
82
+ - `contracts/usersContract.ts`: The definition.
83
+ - `src/routes/users.ts`: The backend implementation.
84
+ - `src/sdk/usersClient.ts`: The frontend client.
131
85
 
132
- ```bash
133
- npm install @codexsploitx/schemaapi zod
134
- npx @codexsploitx/schemaapi init fastify
135
- ```
136
-
137
- #### Remix
138
-
139
- - 🆕 **New project**
140
-
141
- ```bash
142
- npx create-remix@latest
143
- npm install @codexsploitx/schemaapi zod
144
- npx @codexsploitx/schemaapi init remix
145
- ```
146
-
147
- - ♻️ **Existing Remix project**
148
-
149
- ```bash
150
- npm install @codexsploitx/schemaapi zod
151
- npx @codexsploitx/schemaapi init remix
152
-
153
- #### NestJS
154
-
155
- - 🆕 **New project**
156
-
157
- ```bash
158
- npm i -g @nestjs/cli
159
- nest new my-nest-api
160
- cd my-nest-api
161
- npm install @codexsploitx/schemaapi zod
162
- npx @codexsploitx/schemaapi init nest
163
- ```
164
-
165
- - ♻️ **Existing NestJS project**
166
-
167
- ```bash
168
- npm install @codexsploitx/schemaapi zod
169
- npx @codexsploitx/schemaapi init nest
170
- ```
171
-
172
- #### Deno
86
+ ---
173
87
 
174
- - 🆕 / ♻️ **Deno projects**
88
+ ## 🧩 The Ecosystem (Adapters)
175
89
 
176
- En Deno no se usa npm para el runtime, pero puedes usar SchemaApi en tu
177
- tooling o en proyectos que usen `deno2node`. Para Node+Deno híbrido:
90
+ SchemaApi plays nice with everyone. Use the CLI to drop into any stack.
178
91
 
179
- ```bash
180
- npm install @codexsploitx/schemaapi zod
181
- npx @codexsploitx/schemaapi init deno
182
- ```
92
+ | Stack | Status | CLI Command |
93
+ | :--- | :---: | :--- |
94
+ | <img src="https://simpleicons.org/icons/express.svg" width="18"/> **Express** | 🟢 Stable | `npx ... init express` |
95
+ | <img src="https://simpleicons.org/icons/nextdotjs.svg" width="18"/> **Next.js** | 🟢 Stable | `npx ... init next` |
96
+ | <img src="https://simpleicons.org/icons/fastify.svg" width="18"/> **Fastify** | 🟢 Stable | `npx ... init fastify` |
97
+ | <img src="https://simpleicons.org/icons/remix.svg" width="18"/> **Remix** | 🟢 Stable | `npx ... init remix` |
98
+ | <img src="https://simpleicons.org/icons/nestjs.svg" width="18"/> **NestJS** | 🟢 Stable | `npx ... init nest` |
99
+ | <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/84/Deno.svg/1200px-Deno.svg.png" width="18"/> **Deno** | 🟢 Stable | `npx ... init deno` |
100
+ | <img src="https://simpleicons.org/icons/nodedotjs.svg" width="18"/> **Koa/Hapi**| 🟡 Beta | `npx ... init koa` |
183
101
 
184
102
  ---
185
103
 
186
- ## 🛠 Usage
187
-
188
- ### 1️⃣ Define the Contract
104
+ ## 🛠️ Usage Example
189
105
 
190
- Create a shared file (e.g., `contract.ts`). This is your API's law.
106
+ ### 1️⃣ The Contract (`contracts/post.ts`)
107
+ This is the **Law**.
191
108
 
192
109
  ```typescript
193
110
  import { createContract } from "@codexsploitx/schemaapi";
194
111
  import { z } from "zod";
195
112
 
196
- export const contract = createContract({
197
- "/users/:id": {
198
- GET: {
113
+ export const postContract = createContract({
114
+ name: "posts",
115
+ routes: {
116
+ "GET /posts/:id": {
199
117
  params: z.object({ id: z.string().uuid() }),
200
- response: z.object({
201
- id: z.string(),
202
- name: z.string(),
203
- email: z.string().email(),
204
- }),
205
- errors: {
206
- 404: "USER_NOT_FOUND",
207
- },
208
- },
209
- },
118
+ responses: {
119
+ 200: z.object({ id: z.string(), title: z.string() }),
120
+ 404: z.object({ error: z.string() })
121
+ }
122
+ }
123
+ }
210
124
  });
211
125
  ```
212
126
 
213
- ### 2️⃣ Implement the Server
214
-
215
- Use the `handle` method to implement the logic. SchemaApi ensures you return exactly what the contract promises.
127
+ ### 2️⃣ The Backend (`src/routes/post.ts`)
128
+ Implement the logic. Types are **enforced**.
216
129
 
217
130
  ```typescript
218
- import express from "express";
219
- import { contract } from "./contract";
220
-
221
- const app = express();
222
-
223
- app.get(
224
- "/users/:id",
225
- contract.handle("GET /users/:id", async ({ params }) => {
226
- // `params.id` is strictly typed as a UUID string
227
- const user = await db.users.find(params.id);
228
-
229
- if (!user) {
230
- throw { status: 404, message: "User not found" };
231
- }
232
-
233
- // TypeScript ensures this return value matches the contract
234
- return user;
235
- })
236
- );
131
+ // Express Adapter Example
132
+ router.get("/posts/:id", async (req, res) => {
133
+ // `req.params.id` is strictly typed as string (UUID)
134
+ const post = await db.find(req.params.id);
135
+
136
+ if (!post) return res.status(404).json({ error: "Not found" });
137
+
138
+ // Return type is checked against contract
139
+ return res.json(post);
140
+ });
237
141
  ```
238
142
 
239
- ### 3️⃣ Consume with Client SDK
240
-
241
- No more manual fetch calls. No more `any`.
143
+ ### 3️⃣ The Frontend (`src/app.ts`)
144
+ Consume with the generated SDK.
242
145
 
243
146
  ```typescript
244
- import { createClient } from "@codexsploitx/schemaapi";
245
- import { contract } from "./shared/contract";
147
+ import { PostClient } from "./sdk/postClient";
246
148
 
247
- const client = createClient(contract, {
248
- baseUrl: "https://api.example.com"
249
- });
250
-
251
- // Full autocomplete & type checking
252
- const user = await client.users.get({
253
- id: "550e8400-e29b-41d4-a716-446655440000"
254
- });
149
+ const client = new PostClient("https://api.myapp.com");
255
150
 
256
- console.log(user.email); // Typed!
151
+ // Autocomplete heaven
152
+ const post = await client.getPost({ id: "123-abc" });
153
+ console.log(post.title);
257
154
  ```
258
155
 
259
156
  ---
260
157
 
261
- ## 🔌 Adapters Ecosystem
158
+ ## 💻 CLI Commands
262
159
 
263
- SchemaApi is designed to drop into any stack.
160
+ Your swiss-army knife for API development.
264
161
 
265
- | Adapter | Status | Package Support |
266
- | :--- | :---: | :--- |
267
- | <img src="https://raw.githubusercontent.com/expressjs/expressjs.com/gh-pages/images/favicon.png" width="20" /> **Express** | Stable | Native support |
268
- | <img src="https://assets.vercel.com/image/upload/v1662130559/nextjs/Icon_dark_background.png" width="20" /> **Next.js** | Stable | API Routes & App Router |
269
- | <img src="https://raw.githubusercontent.com/fastify/graphics/master/fastify-icon.png" width="20" /> **Fastify** | Stable | High performance |
270
- | <img src="https://github.com/remix-run/branding/raw/main/remix-r.png" width="20" /> **Remix** | Stable | Loaders & Actions |
271
- | <img src="https://nestjs.com/img/logo-small.svg" width="20" /> **NestJS** | ✅ Stable | Decorators |
272
- | <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/84/Deno.svg/1200px-Deno.svg.png" width="20" /> **Deno** | ✅ Stable | Native HTTP |
273
- | ⚡ **WebSocket** | 🚧 Beta | Real-time contracts |
162
+ - `npx @codexsploitx/schemaapi init <stack>` -> Setup project
163
+ - `npx @codexsploitx/schemaapi generate resource <name>` -> Create API route
164
+ - `npx @codexsploitx/schemaapi generate sdk <name>` -> Create Typed Client
165
+ - `npx @codexsploitx/schemaapi generate tests <name>` -> Create Integration Tests
166
+ - `npx @codexsploitx/schemaapi generate docs` -> Build HTML Documentation website
167
+ - `npx @codexsploitx/schemaapi audit` -> Check for security & best practices
274
168
 
275
169
  ---
276
170
 
277
- ## 📚 Documentation Generator
278
-
279
- Stop writing Swagger files manually. Generate a stunning static documentation site with one command.
280
-
281
- ```bash
282
- npx schemaapi generate docs --out ./docs
283
- ```
284
-
285
- It creates a fully responsive, dark-mode ready HTML dashboard showing all your routes, schemas, and types.
171
+ <div align="center">
286
172
 
287
- ---
173
+ ### Ready to build the future?
288
174
 
289
- ## 📄 License
175
+ [Get Started](https://codexsploitx.github.io/SchemaApi/)
290
176
 
291
177
  MIT © [CodexSploitx](https://github.com/CodexSploitx)
178
+
179
+ </div>
@@ -0,0 +1,183 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Documentation | SchemaApi</title>
7
+ <link rel="stylesheet" href="styles.css">
8
+ </head>
9
+ <body>
10
+
11
+ <!-- Navigation -->
12
+ <nav class="container">
13
+ <a href="index.html" class="logo">
14
+ <span>⚡</span> SchemaApi
15
+ </a>
16
+ <div class="nav-links">
17
+ <a href="index.html">Home</a>
18
+ <a href="docs.html" class="active">Documentation</a>
19
+ <a href="https://github.com/codexsploitx/schemaapi">GitHub</a>
20
+ </div>
21
+ </nav>
22
+
23
+ <div class="container docs-layout">
24
+ <!-- Sidebar -->
25
+ <aside class="sidebar">
26
+ <ul>
27
+ <li><a href="#introduction" class="active">Introduction</a></li>
28
+ <li><a href="#installation">Installation</a></li>
29
+ <li><a href="#quick-start">Quick Start</a></li>
30
+ <li><a href="#cli-commands">CLI Commands</a></li>
31
+ <li><a href="#contracts">Contracts</a></li>
32
+ <li><a href="#sdk">Frontend SDK</a></li>
33
+ <li><a href="#testing">Testing</a></li>
34
+ <li><a href="#adapters">Adapters</a></li>
35
+ </ul>
36
+ </aside>
37
+
38
+ <!-- Content -->
39
+ <main class="docs-content">
40
+ <section id="introduction">
41
+ <h1>Documentation</h1>
42
+ <p>Welcome to SchemaApi. This guide will help you automate your backend and frontend development workflow using our contract-first approach.</p>
43
+ </section>
44
+
45
+ <section id="installation">
46
+ <h2>Installation</h2>
47
+ <p>You don't need to install SchemaApi globally. You can use it directly via <code>npx</code>, which ensures you're always using the latest version.</p>
48
+ <div class="code-block">
49
+ npx @codexsploitx/schemaapi init
50
+ </div>
51
+ <p>Or install it as a dev dependency in your project:</p>
52
+ <div class="code-block">
53
+ npm install -D @codexsploitx/schemaapi
54
+ </div>
55
+ </section>
56
+
57
+ <section id="quick-start">
58
+ <h2>Quick Start</h2>
59
+ <p>Get a full API up and running in less than a minute.</p>
60
+
61
+ <p>1. Initialize your project:</p>
62
+ <div class="code-block">
63
+ <span class="cmd-text">npx</span> @codexsploitx/schemaapi init <span class="highlight">express</span>
64
+ </div>
65
+
66
+ <p>2. Generate a resource (e.g., users):</p>
67
+ <div class="code-block">
68
+ <span class="cmd-text">npx</span> @codexsploitx/schemaapi generate resource <span class="highlight">users</span>
69
+ </div>
70
+ <p>This creates:</p>
71
+ <ul>
72
+ <li><code>contracts/usersContract.ts</code> (The definition)</li>
73
+ <li><code>src/routes/users.ts</code> (The implementation)</li>
74
+ </ul>
75
+
76
+ <p>3. Generate the Client SDK:</p>
77
+ <div class="code-block">
78
+ <span class="cmd-text">npx</span> @codexsploitx/schemaapi generate sdk <span class="highlight">users</span>
79
+ </div>
80
+ </section>
81
+
82
+ <section id="cli-commands">
83
+ <h2>CLI Commands</h2>
84
+ <p>Here is the full list of available commands:</p>
85
+
86
+ <h3>Init</h3>
87
+ <div class="code-block">npx @codexsploitx/schemaapi init &lt;framework&gt;</div>
88
+ <p>Supported frameworks: <code>express</code>, <code>fastify</code>, <code>next</code>, <code>nest</code>, <code>koa</code>, <code>hapi</code>, <code>remix</code>, <code>deno</code>.</p>
89
+
90
+ <h3>Generate Resource (Backend)</h3>
91
+ <div class="code-block">npx @codexsploitx/schemaapi generate resource &lt;name&gt;</div>
92
+
93
+ <h3>Generate SDK (Frontend)</h3>
94
+ <div class="code-block">npx @codexsploitx/schemaapi generate sdk &lt;name&gt;</div>
95
+
96
+ <h3>Generate Tests</h3>
97
+ <div class="code-block">npx @codexsploitx/schemaapi generate tests &lt;name&gt;</div>
98
+
99
+ <h3>Generate Docs</h3>
100
+ <div class="code-block">npx @codexsploitx/schemaapi generate docs</div>
101
+ </section>
102
+
103
+ <section id="contracts">
104
+ <h2>Contracts</h2>
105
+ <p>Contracts are the heart of SchemaApi. They define the shape of your API. They are standard TypeScript files.</p>
106
+ <div class="code-block">
107
+ <pre><span class="highlight">export</span> <span class="cmd-text">const</span> usersContract = {
108
+ name: "users",
109
+ routes: {
110
+ create: {
111
+ method: "POST",
112
+ path: "/users",
113
+ body: { name: "string", email: "string" },
114
+ responses: {
115
+ 201: { id: "string", name: "string" }
116
+ }
117
+ }
118
+ }
119
+ };</pre>
120
+ </div>
121
+ </section>
122
+
123
+ <section id="sdk">
124
+ <h2>Frontend SDK</h2>
125
+ <p>The generated SDK is a typed class that handles all HTTP communication.</p>
126
+ <div class="code-block">
127
+ <pre><span class="highlight">import</span> { UsersClient } from "./sdk/usersClient";
128
+
129
+ <span class="cmd-text">const</span> client = <span class="highlight">new</span> UsersClient("http://localhost:3000");
130
+
131
+ <span class="comment">// Fully typed!</span>
132
+ <span class="cmd-text">const</span> user = <span class="highlight">await</span> client.create({
133
+ name: "Alice",
134
+ email: "alice@example.com"
135
+ });</pre>
136
+ </div>
137
+ </section>
138
+
139
+ </main>
140
+ </div>
141
+
142
+ <footer>
143
+ <div class="container">
144
+ <p>© 2026 SchemaApi. Documentation.</p>
145
+ </div>
146
+ </footer>
147
+
148
+ <script>
149
+ // Smooth scroll for anchor links is handled by CSS (scroll-behavior: smooth)
150
+
151
+ // Active link highlighting on scroll (ScrollSpy)
152
+ const observerOptions = {
153
+ root: null,
154
+ rootMargin: '-20% 0px -70% 0px', // Trigger when section is near top
155
+ threshold: 0
156
+ };
157
+
158
+ const observer = new IntersectionObserver((entries) => {
159
+ entries.forEach(entry => {
160
+ if (entry.isIntersecting) {
161
+ // Remove active class from all links
162
+ document.querySelectorAll('.sidebar a').forEach(link => {
163
+ link.classList.remove('active');
164
+ });
165
+
166
+ // Add active class to corresponding link
167
+ const id = entry.target.getAttribute('id');
168
+ const activeLink = document.querySelector(`.sidebar a[href="#${id}"]`);
169
+ if (activeLink) {
170
+ activeLink.classList.add('active');
171
+ }
172
+ }
173
+ });
174
+ }, observerOptions);
175
+
176
+ // Observe all sections
177
+ document.querySelectorAll('section[id]').forEach(section => {
178
+ observer.observe(section);
179
+ });
180
+ </script>
181
+
182
+ </body>
183
+ </html>