schemantic 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +92 -0
- package/LICENSE +21 -0
- package/README.md +827 -0
- package/dist/__tests__/setup.d.ts +6 -0
- package/dist/__tests__/setup.d.ts.map +1 -0
- package/dist/__tests__/setup.js +30 -0
- package/dist/__tests__/setup.js.map +1 -0
- package/dist/__tests__/test-config.d.ts +36 -0
- package/dist/__tests__/test-config.d.ts.map +1 -0
- package/dist/__tests__/test-config.js +563 -0
- package/dist/__tests__/test-config.js.map +1 -0
- package/dist/cli/index.d.ts +118 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +657 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +21 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/schemantic.d.ts +95 -0
- package/dist/core/schemantic.d.ts.map +1 -0
- package/dist/core/schemantic.js +543 -0
- package/dist/core/schemantic.js.map +1 -0
- package/dist/generators/api-client-generator.d.ts +145 -0
- package/dist/generators/api-client-generator.d.ts.map +1 -0
- package/dist/generators/api-client-generator.js +856 -0
- package/dist/generators/api-client-generator.js.map +1 -0
- package/dist/generators/base.d.ts +117 -0
- package/dist/generators/base.d.ts.map +1 -0
- package/dist/generators/base.js +232 -0
- package/dist/generators/base.js.map +1 -0
- package/dist/generators/enum-generator.d.ts +52 -0
- package/dist/generators/enum-generator.d.ts.map +1 -0
- package/dist/generators/enum-generator.js +178 -0
- package/dist/generators/enum-generator.js.map +1 -0
- package/dist/generators/factory.d.ts +59 -0
- package/dist/generators/factory.d.ts.map +1 -0
- package/dist/generators/factory.js +127 -0
- package/dist/generators/factory.js.map +1 -0
- package/dist/generators/hook-generator.d.ts +36 -0
- package/dist/generators/hook-generator.d.ts.map +1 -0
- package/dist/generators/hook-generator.js +495 -0
- package/dist/generators/hook-generator.js.map +1 -0
- package/dist/generators/index.d.ts +10 -0
- package/dist/generators/index.d.ts.map +1 -0
- package/dist/generators/index.js +26 -0
- package/dist/generators/index.js.map +1 -0
- package/dist/generators/object-generator.d.ts +48 -0
- package/dist/generators/object-generator.d.ts.map +1 -0
- package/dist/generators/object-generator.js +280 -0
- package/dist/generators/object-generator.js.map +1 -0
- package/dist/generators/primitive-generator.d.ts +40 -0
- package/dist/generators/primitive-generator.d.ts.map +1 -0
- package/dist/generators/primitive-generator.js +150 -0
- package/dist/generators/primitive-generator.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/parsers/base.d.ts +101 -0
- package/dist/parsers/base.d.ts.map +1 -0
- package/dist/parsers/base.js +77 -0
- package/dist/parsers/base.js.map +1 -0
- package/dist/parsers/factory.d.ts +64 -0
- package/dist/parsers/factory.d.ts.map +1 -0
- package/dist/parsers/factory.js +116 -0
- package/dist/parsers/factory.js.map +1 -0
- package/dist/parsers/index.d.ts +7 -0
- package/dist/parsers/index.d.ts.map +1 -0
- package/dist/parsers/index.js +23 -0
- package/dist/parsers/index.js.map +1 -0
- package/dist/parsers/openapi.d.ts +52 -0
- package/dist/parsers/openapi.d.ts.map +1 -0
- package/dist/parsers/openapi.js +396 -0
- package/dist/parsers/openapi.js.map +1 -0
- package/dist/plugins/branded-types.d.ts +28 -0
- package/dist/plugins/branded-types.d.ts.map +1 -0
- package/dist/plugins/branded-types.js +568 -0
- package/dist/plugins/branded-types.js.map +1 -0
- package/dist/plugins/builtin.d.ts +38 -0
- package/dist/plugins/builtin.d.ts.map +1 -0
- package/dist/plugins/builtin.js +283 -0
- package/dist/plugins/builtin.js.map +1 -0
- package/dist/plugins/index.d.ts +7 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +23 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/loader.d.ts +92 -0
- package/dist/plugins/loader.d.ts.map +1 -0
- package/dist/plugins/loader.js +245 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/plugins/manager.d.ts +99 -0
- package/dist/plugins/manager.d.ts.map +1 -0
- package/dist/plugins/manager.js +233 -0
- package/dist/plugins/manager.js.map +1 -0
- package/dist/plugins/performance-monitoring.d.ts +98 -0
- package/dist/plugins/performance-monitoring.d.ts.map +1 -0
- package/dist/plugins/performance-monitoring.js +596 -0
- package/dist/plugins/performance-monitoring.js.map +1 -0
- package/dist/plugins/request-deduplication.d.ts +27 -0
- package/dist/plugins/request-deduplication.d.ts.map +1 -0
- package/dist/plugins/request-deduplication.js +650 -0
- package/dist/plugins/request-deduplication.js.map +1 -0
- package/dist/plugins/zod-validation.d.ts +63 -0
- package/dist/plugins/zod-validation.d.ts.map +1 -0
- package/dist/plugins/zod-validation.js +743 -0
- package/dist/plugins/zod-validation.js.map +1 -0
- package/dist/types/core.d.ts +203 -0
- package/dist/types/core.d.ts.map +1 -0
- package/dist/types/core.js +24 -0
- package/dist/types/core.js.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +23 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/openapi.d.ts +250 -0
- package/dist/types/openapi.d.ts.map +1 -0
- package/dist/types/openapi.js +8 -0
- package/dist/types/openapi.js.map +1 -0
- package/dist/types/schema.d.ts +68 -0
- package/dist/types/schema.d.ts.map +1 -0
- package/dist/types/schema.js +22 -0
- package/dist/types/schema.js.map +1 -0
- package/docs/ADVANCED_PLUGINS_IMPLEMENTATION.md +355 -0
- package/docs/ADVANCED_PLUGIN_DEVELOPMENT.md +309 -0
- package/docs/API.md +600 -0
- package/docs/CONFIGURATION.md +722 -0
- package/docs/FASTAPI_TUTORIAL.md +1497 -0
- package/docs/PLUGINS.md +683 -0
- package/docs/PLUGIN_DEVELOPMENT.md +720 -0
- package/package.json +90 -0
package/README.md
ADDED
|
@@ -0,0 +1,827 @@
|
|
|
1
|
+
# Schemantic
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/js/@cstannahill%2Fschemantic)
|
|
4
|
+
[](https://github.com/cstannahill/schemantic/actions/workflows/ci-cd.yml)
|
|
5
|
+
[](https://codecov.io/gh/cstannahill/schemantic)
|
|
6
|
+
[](https://www.npmjs.com/package/@cstannahill/schemantic)
|
|
7
|
+
[](https://opensource.org/licenses/MIT)
|
|
8
|
+
[](https://www.typescriptlang.org/)
|
|
9
|
+
[](https://nodejs.org/)
|
|
10
|
+
[](https://swagger.io/specification/)
|
|
11
|
+
|
|
12
|
+
A fully typed, extensible, modular TypeScript type generator for OpenAPI schemas (great with FastAPI). Generate TypeScript types, API clients, and optional hooks with sensible defaults.
|
|
13
|
+
|
|
14
|
+
> **Status**: Production Ready ๐ | **Maintenance**: Actively Maintained โ
| **Support**: Community & Issues ๐ฌ | **Version**: v0.1.0
|
|
15
|
+
|
|
16
|
+
## Features
|
|
17
|
+
|
|
18
|
+
- ๐ง **Zero Configuration** - Works out of the box with FastAPI applications
|
|
19
|
+
- ๐ฏ **Fully Typed** - Generates comprehensive TypeScript types with no `any` types
|
|
20
|
+
- ๐งฉ **Modular Architecture** - Extensible plugin system for custom generators
|
|
21
|
+
- ๐ **Fast & Efficient** - Optimized for large schemas and complex APIs
|
|
22
|
+
- ๐ฆ **Multiple Outputs** - Types, API clients, React hooks, and more
|
|
23
|
+
- ๐ **Schema Validation** - Built-in OpenAPI schema validation
|
|
24
|
+
- ๐จ **Customizable** - Flexible naming conventions and type mappings
|
|
25
|
+
- ๐ **Well Documented** - Comprehensive documentation and examples
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install schemantic
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
### CLI Usage
|
|
36
|
+
|
|
37
|
+
Generate types and API client from your OpenAPI schema:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# From URL (recommended)
|
|
41
|
+
npx schemantic generate --url http://localhost:8000/openapi.json --output ./src/generated
|
|
42
|
+
|
|
43
|
+
# From file (local snapshot)
|
|
44
|
+
npx schemantic generate --file ./schema.json --output ./src/generated
|
|
45
|
+
|
|
46
|
+
# With React hooks
|
|
47
|
+
npx schemantic generate --url http://localhost:8000/openapi.json --output ./src/generated --hooks
|
|
48
|
+
|
|
49
|
+
# With custom options
|
|
50
|
+
npx schemantic generate \
|
|
51
|
+
--url http://localhost:8000/openapi.json \
|
|
52
|
+
--output ./src/generated \
|
|
53
|
+
--naming camelCase \
|
|
54
|
+
--prefix API \
|
|
55
|
+
--suffix Type
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Where to get your OpenAPI schema
|
|
59
|
+
|
|
60
|
+
You can point Schemantic at any reachable OpenAPI 3.x JSON. Common frameworks expose it at predictable URLs:
|
|
61
|
+
|
|
62
|
+
- FastAPI (default): http://localhost:8000/openapi.json
|
|
63
|
+
- ASP.NET Core (.NET): https://localhost:5001/swagger/v1/swagger.json
|
|
64
|
+
|
|
65
|
+
Grab a local snapshot if you prefer generating from a file:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# FastAPI
|
|
69
|
+
curl -s http://localhost:8000/openapi.json -o ./openapi-schema.json
|
|
70
|
+
|
|
71
|
+
# ASP.NET Core (.NET)
|
|
72
|
+
curl -k -s https://localhost:5001/swagger/v1/swagger.json -o ./openapi-schema.json
|
|
73
|
+
|
|
74
|
+
# Generate from the snapshot
|
|
75
|
+
npx schemantic generate --file ./openapi-schema.json --output ./src/generated --client --types
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Notes:
|
|
79
|
+
|
|
80
|
+
- On .NET dev certs (HTTPS), use `-k` with curl to skip certificate verification locally.
|
|
81
|
+
- In ASP.NET Core, ensure Swagger is enabled in Development (AddSwaggerGen/UseSwagger) and the Swagger endpoint exposes `/swagger/v1/swagger.json`.
|
|
82
|
+
|
|
83
|
+
### Programmatic Usage
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
import { Schemantic, SchemanticConfig } from "schemantic";
|
|
87
|
+
|
|
88
|
+
const config: SchemanticConfig = {
|
|
89
|
+
schemaUrl: "http://localhost:8000/openapi.json",
|
|
90
|
+
outputDir: "./src/generated",
|
|
91
|
+
generateTypes: true,
|
|
92
|
+
generateApiClient: true,
|
|
93
|
+
useStrictTypes: true,
|
|
94
|
+
namingConvention: "camelCase",
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const Schemantic = new Schemantic(config);
|
|
98
|
+
const result = await Schemantic.generate();
|
|
99
|
+
|
|
100
|
+
if (result.success) {
|
|
101
|
+
console.log(`Generated ${result.generatedFiles.length} files`);
|
|
102
|
+
console.log(`Types: ${result.statistics.totalTypes}`);
|
|
103
|
+
console.log(`Endpoints: ${result.statistics.totalEndpoints}`);
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Configuration
|
|
108
|
+
|
|
109
|
+
### Basic Configuration
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
const config: SchemanticConfig = {
|
|
113
|
+
// Input sources (choose one)
|
|
114
|
+
schemaUrl: "http://localhost:8000/openapi.json",
|
|
115
|
+
schemaFile: "./schema.json",
|
|
116
|
+
schemaData: {
|
|
117
|
+
/* OpenAPI schema object */
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
// Output configuration
|
|
121
|
+
outputDir: "./src/generated",
|
|
122
|
+
outputFileName: "api-client.ts",
|
|
123
|
+
|
|
124
|
+
// Generation options
|
|
125
|
+
generateTypes: true,
|
|
126
|
+
generateApiClient: true,
|
|
127
|
+
generateHooks: false, // Enable React hooks generation
|
|
128
|
+
|
|
129
|
+
// TypeScript configuration
|
|
130
|
+
useStrictTypes: true,
|
|
131
|
+
useOptionalChaining: true,
|
|
132
|
+
useNullishCoalescing: true,
|
|
133
|
+
|
|
134
|
+
// Naming conventions
|
|
135
|
+
namingConvention: "camelCase", // 'camelCase' | 'snake_case' | 'PascalCase'
|
|
136
|
+
// By default, Schemantic prefixes type names with "API". Customize if desired:
|
|
137
|
+
typePrefix: "API",
|
|
138
|
+
typeSuffix: "Type",
|
|
139
|
+
|
|
140
|
+
// Customization
|
|
141
|
+
customTypeMappings: {
|
|
142
|
+
uuid: "string",
|
|
143
|
+
datetime: "Date",
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
// Filtering
|
|
147
|
+
excludePaths: ["/health", "/docs"],
|
|
148
|
+
includePaths: ["/api/v1/*"],
|
|
149
|
+
excludeSchemas: ["Error"],
|
|
150
|
+
includeSchemas: ["User", "Product"],
|
|
151
|
+
|
|
152
|
+
// Plugin configuration
|
|
153
|
+
plugins: [
|
|
154
|
+
{ name: "jsdoc", enabled: true },
|
|
155
|
+
{ name: "validation", enabled: true },
|
|
156
|
+
],
|
|
157
|
+
};
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### CLI Reference
|
|
161
|
+
|
|
162
|
+
#### Commands
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
# Generate types and API client
|
|
166
|
+
npx schemantic generate [source] [options]
|
|
167
|
+
npx schemantic gen [source] [options]
|
|
168
|
+
|
|
169
|
+
# Validate OpenAPI schema
|
|
170
|
+
npx schemantic validate [source] [options]
|
|
171
|
+
npx schemantic check [source] [options]
|
|
172
|
+
|
|
173
|
+
# Manage plugins
|
|
174
|
+
npx schemantic plugin list
|
|
175
|
+
npx schemantic plugin load <path>
|
|
176
|
+
|
|
177
|
+
# Initialize configuration
|
|
178
|
+
npx schemantic init [directory] [options]
|
|
179
|
+
|
|
180
|
+
# Get help
|
|
181
|
+
npx schemantic --help
|
|
182
|
+
npx schemantic generate --help
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
#### Generate Command Options
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
# Input options
|
|
189
|
+
--url, -u <url> OpenAPI schema URL
|
|
190
|
+
--file, -f <file> OpenAPI schema file path
|
|
191
|
+
|
|
192
|
+
# Output options
|
|
193
|
+
--output, -o <dir> Output directory (default: ./src/generated)
|
|
194
|
+
|
|
195
|
+
# Generation options
|
|
196
|
+
--types Generate types only
|
|
197
|
+
--client Generate API client only
|
|
198
|
+
--hooks Generate React hooks factory
|
|
199
|
+
--watch Watch for changes and regenerate
|
|
200
|
+
|
|
201
|
+
# TypeScript options
|
|
202
|
+
--strict Use strict TypeScript types (default: true)
|
|
203
|
+
--naming <convention> Naming convention (camelCase|snake_case|PascalCase)
|
|
204
|
+
|
|
205
|
+
# Customization
|
|
206
|
+
--prefix <prefix> Type name prefix (default: API)
|
|
207
|
+
--suffix <suffix> Type name suffix
|
|
208
|
+
--exclude-paths <paths> Exclude paths (comma-separated)
|
|
209
|
+
--include-paths <paths> Include paths (comma-separated)
|
|
210
|
+
--exclude-schemas <schemas> Exclude schemas (comma-separated)
|
|
211
|
+
--include-schemas <schemas> Include schemas (comma-separated)
|
|
212
|
+
|
|
213
|
+
# Plugin options
|
|
214
|
+
--plugins <plugins> Enable plugins (comma-separated)
|
|
215
|
+
--config, -c <file> Configuration file path
|
|
216
|
+
|
|
217
|
+
# Global options
|
|
218
|
+
--interactive, -i Run in interactive mode
|
|
219
|
+
--verbose, -v Verbose output
|
|
220
|
+
--quiet, -q Quiet output
|
|
221
|
+
--no-color Disable colored output
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
#### Validate Command Options
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
--url, -u <url> OpenAPI schema URL
|
|
228
|
+
--file, -f <file> OpenAPI schema file path
|
|
229
|
+
--fix Attempt to fix common issues
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
#### Init Command Options
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
--template, -t <template> Configuration template (default)
|
|
236
|
+
--yes Skip interactive prompts
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### CLI Examples
|
|
240
|
+
|
|
241
|
+
#### Basic Usage
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
# Generate from live FastAPI server
|
|
245
|
+
npx schemantic generate --url http://localhost:8000/openapi.json
|
|
246
|
+
|
|
247
|
+
# Generate from local schema file
|
|
248
|
+
npx schemantic generate --file ./openapi-schema.json
|
|
249
|
+
|
|
250
|
+
# Custom output directory
|
|
251
|
+
npx schemantic generate --url http://localhost:8000/openapi.json --output ./src/api
|
|
252
|
+
|
|
253
|
+
# Generate with React hooks
|
|
254
|
+
npx schemantic generate --url http://localhost:8000/openapi.json --hooks
|
|
255
|
+
|
|
256
|
+
# Interactive mode (guided setup)
|
|
257
|
+
npx schemantic generate --interactive
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
#### Advanced Usage
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
# Custom naming and prefixes
|
|
264
|
+
npx schemantic generate \
|
|
265
|
+
--url http://localhost:8000/openapi.json \
|
|
266
|
+
--naming PascalCase \
|
|
267
|
+
--prefix "MyAPI" \
|
|
268
|
+
--suffix "DTO"
|
|
269
|
+
|
|
270
|
+
# Filter paths and schemas
|
|
271
|
+
npx schemantic generate \
|
|
272
|
+
--url http://localhost:8000/openapi.json \
|
|
273
|
+
--include-paths "/api/v1/*,/auth/*" \
|
|
274
|
+
--exclude-paths "/health,/docs" \
|
|
275
|
+
--exclude-schemas "Error,ValidationError"
|
|
276
|
+
|
|
277
|
+
# Enable plugins
|
|
278
|
+
npx schemantic generate \
|
|
279
|
+
--url http://localhost:8000/openapi.json \
|
|
280
|
+
--plugins jsdoc,validation,react-hooks
|
|
281
|
+
|
|
282
|
+
# Use configuration file
|
|
283
|
+
npx schemantic generate --config ./Schemantic.config.json
|
|
284
|
+
|
|
285
|
+
# Watch mode for development
|
|
286
|
+
npx schemantic generate --url http://localhost:8000/openapi.json --watch
|
|
287
|
+
|
|
288
|
+
# Generate specific outputs
|
|
289
|
+
npx schemantic generate --url http://localhost:8000/openapi.json --types --client
|
|
290
|
+
npx schemantic generate --url http://localhost:8000/openapi.json --hooks
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
#### Validation
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
# Validate schema
|
|
297
|
+
npx schemantic validate --url http://localhost:8000/openapi.json
|
|
298
|
+
|
|
299
|
+
# Validate local file
|
|
300
|
+
npx schemantic validate --file ./openapi-schema.json
|
|
301
|
+
|
|
302
|
+
# Validate with auto-fix attempts
|
|
303
|
+
npx schemantic validate --file ./openapi-schema.json --fix
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
#### Configuration Management
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
# Initialize new project configuration
|
|
310
|
+
npx schemantic init
|
|
311
|
+
|
|
312
|
+
# Initialize with default settings
|
|
313
|
+
npx schemantic init --yes
|
|
314
|
+
|
|
315
|
+
# Initialize in specific directory
|
|
316
|
+
npx schemantic init ./my-project
|
|
317
|
+
|
|
318
|
+
# Initialize with template
|
|
319
|
+
npx schemantic init --template react
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
#### Plugin Management
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
# List available plugins
|
|
326
|
+
npx schemantic plugin list
|
|
327
|
+
|
|
328
|
+
# Load custom plugin
|
|
329
|
+
npx schemantic plugin load ./my-custom-plugin.js
|
|
330
|
+
npx schemantic plugin load @my-org/Schemantic-plugin
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
## Generated Output
|
|
334
|
+
|
|
335
|
+
### Types
|
|
336
|
+
|
|
337
|
+
```typescript
|
|
338
|
+
// Generated from OpenAPI schema
|
|
339
|
+
export interface APIUser {
|
|
340
|
+
id: string;
|
|
341
|
+
email: string;
|
|
342
|
+
firstName: string;
|
|
343
|
+
lastName: string;
|
|
344
|
+
createdAt: string;
|
|
345
|
+
updatedAt: string;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
export interface APICreateUserRequest {
|
|
349
|
+
email: string;
|
|
350
|
+
firstName: string;
|
|
351
|
+
lastName: string;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
export interface APIUpdateUserRequest {
|
|
355
|
+
email?: string;
|
|
356
|
+
firstName?: string;
|
|
357
|
+
lastName?: string;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
export enum APIUserRole {
|
|
361
|
+
ADMIN = "admin",
|
|
362
|
+
USER = "user",
|
|
363
|
+
MODERATOR = "moderator",
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
### API Client
|
|
368
|
+
|
|
369
|
+
### React Hooks (optional)
|
|
370
|
+
|
|
371
|
+
Enable hook generation with `--hooks` (CLI) or `generateHooks: true` (config). A `hooks.ts` file will export `createApiHooks(client)` which returns per-endpoint hooks.
|
|
372
|
+
|
|
373
|
+
Example:
|
|
374
|
+
|
|
375
|
+
```typescript
|
|
376
|
+
import { ECommerceApiClient, createApiHooks } from "./src/generated";
|
|
377
|
+
|
|
378
|
+
const client = new ECommerceApiClient({ baseUrl: "http://localhost:8000" });
|
|
379
|
+
const { useGetProductsProductsGetQuery, useCreateOrderOrdersPostMutation } =
|
|
380
|
+
createApiHooks(client);
|
|
381
|
+
|
|
382
|
+
function ProductsList() {
|
|
383
|
+
const { data, loading, error, refetch } = useGetProductsProductsGetQuery({
|
|
384
|
+
query: { page: 1, size: 20 },
|
|
385
|
+
});
|
|
386
|
+
// ... render
|
|
387
|
+
}
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Notes:
|
|
391
|
+
|
|
392
|
+
- Hooks mirror the client method signatures: path params, query params, optional body (for mutations), then `RequestInit` as the last arg.
|
|
393
|
+
- The generated `index.ts` re-exports `createApiHooks` when hooks are enabled.
|
|
394
|
+
|
|
395
|
+
```typescript
|
|
396
|
+
// Actual name is derived from your API title; example below shows a generic name.
|
|
397
|
+
export class MyApiApiClient {
|
|
398
|
+
private baseUrl: string;
|
|
399
|
+
private config: ApiClientConfig;
|
|
400
|
+
|
|
401
|
+
constructor(config: ApiClientConfig) {
|
|
402
|
+
this.baseUrl = config.baseUrl.replace(/\/$/, "");
|
|
403
|
+
this.config = {
|
|
404
|
+
timeout: 30000,
|
|
405
|
+
retries: 3,
|
|
406
|
+
retryDelay: 1000,
|
|
407
|
+
...config,
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
async getUsers(): Promise<APIUser[]> {
|
|
412
|
+
const url = new URL(`${this.baseUrl}/users`);
|
|
413
|
+
const response = await fetch(url.toString(), {
|
|
414
|
+
method: "GET",
|
|
415
|
+
headers: {
|
|
416
|
+
...this.config.headers,
|
|
417
|
+
},
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
if (!response.ok) {
|
|
421
|
+
throw new ApiClientError(
|
|
422
|
+
`Request failed: ${response.status} ${response.statusText}`,
|
|
423
|
+
response.status,
|
|
424
|
+
response
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
return response.json();
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
async createUser(body: APICreateUserRequest): Promise<APIUser> {
|
|
432
|
+
const url = new URL(`${this.baseUrl}/users`);
|
|
433
|
+
const response = await fetch(url.toString(), {
|
|
434
|
+
method: "POST",
|
|
435
|
+
headers: {
|
|
436
|
+
...this.config.headers,
|
|
437
|
+
"Content-Type": "application/json",
|
|
438
|
+
},
|
|
439
|
+
body: JSON.stringify(body),
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
if (!response.ok) {
|
|
443
|
+
throw new ApiClientError(
|
|
444
|
+
`Request failed: ${response.status} ${response.statusText}`,
|
|
445
|
+
response.status,
|
|
446
|
+
response
|
|
447
|
+
);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
return response.json();
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
## Plugin System
|
|
456
|
+
|
|
457
|
+
Schemantic includes a powerful plugin system for extending functionality:
|
|
458
|
+
|
|
459
|
+
### Built-in Plugins
|
|
460
|
+
|
|
461
|
+
- **jsdoc** - Adds JSDoc comments to generated types
|
|
462
|
+
- **validation** - Adds validation decorators for class-validator
|
|
463
|
+
- **react-hooks** - Generates React hooks for API endpoints
|
|
464
|
+
- **strict-mode** - Adds TypeScript strict mode enhancements
|
|
465
|
+
|
|
466
|
+
### Using Plugins
|
|
467
|
+
|
|
468
|
+
```typescript
|
|
469
|
+
// Enable plugins via configuration
|
|
470
|
+
const config: SchemanticConfig = {
|
|
471
|
+
// ... other config
|
|
472
|
+
plugins: [
|
|
473
|
+
{ name: 'jsdoc', enabled: true },
|
|
474
|
+
{ name: 'validation', enabled: true },
|
|
475
|
+
{ name: 'react-hooks', enabled: true },
|
|
476
|
+
],
|
|
477
|
+
};
|
|
478
|
+
|
|
479
|
+
// Or via CLI
|
|
480
|
+
npx schemantic generate --plugins jsdoc,validation,react-hooks
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
### Creating Custom Plugins
|
|
484
|
+
|
|
485
|
+
```typescript
|
|
486
|
+
import { SchemanticPlugin, GenerationContext, GeneratedType } from "schemantic";
|
|
487
|
+
|
|
488
|
+
const customPlugin: SchemanticPlugin = {
|
|
489
|
+
name: "custom-plugin",
|
|
490
|
+
version: "1.0.0",
|
|
491
|
+
description: "Custom plugin for special transformations",
|
|
492
|
+
|
|
493
|
+
beforeTypeGeneration: async (
|
|
494
|
+
typeName: string,
|
|
495
|
+
schema: any,
|
|
496
|
+
context: GenerationContext
|
|
497
|
+
) => {
|
|
498
|
+
// Transform schema before generation
|
|
499
|
+
console.log(`Generating type: ${typeName}`);
|
|
500
|
+
},
|
|
501
|
+
|
|
502
|
+
afterTypeGeneration: async (
|
|
503
|
+
typeName: string,
|
|
504
|
+
generatedType: GeneratedType,
|
|
505
|
+
context: GenerationContext
|
|
506
|
+
) => {
|
|
507
|
+
// Modify generated type
|
|
508
|
+
generatedType.content = `// Custom comment\n${generatedType.content}`;
|
|
509
|
+
},
|
|
510
|
+
|
|
511
|
+
transformSchema: (schema: any, context: GenerationContext) => {
|
|
512
|
+
// Transform schema
|
|
513
|
+
return schema;
|
|
514
|
+
},
|
|
515
|
+
|
|
516
|
+
customTypeGenerators: {
|
|
517
|
+
"custom-type": (schema: any, context: GenerationContext) => {
|
|
518
|
+
// Custom type generator
|
|
519
|
+
return {
|
|
520
|
+
name: "CustomType",
|
|
521
|
+
content: "export type CustomType = string;",
|
|
522
|
+
dependencies: [],
|
|
523
|
+
exports: ["CustomType"],
|
|
524
|
+
isInterface: false,
|
|
525
|
+
isEnum: false,
|
|
526
|
+
isUnion: false,
|
|
527
|
+
sourceSchema: schema,
|
|
528
|
+
};
|
|
529
|
+
},
|
|
530
|
+
},
|
|
531
|
+
};
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
๐ **[Complete Plugin Development Guide](./docs/PLUGIN_DEVELOPMENT.md)** - Learn how to create custom plugins
|
|
535
|
+
|
|
536
|
+
๐ **[Plugin API Reference](./docs/PLUGINS.md)** - Built-in plugins and usage examples
|
|
537
|
+
|
|
538
|
+
## FastAPI Integration
|
|
539
|
+
|
|
540
|
+
### Basic FastAPI Setup
|
|
541
|
+
|
|
542
|
+
```python
|
|
543
|
+
from fastapi import FastAPI
|
|
544
|
+
from pydantic import BaseModel
|
|
545
|
+
from typing import List, Optional
|
|
546
|
+
|
|
547
|
+
app = FastAPI(
|
|
548
|
+
title="My API",
|
|
549
|
+
description="API description",
|
|
550
|
+
version="1.0.0",
|
|
551
|
+
)
|
|
552
|
+
|
|
553
|
+
class User(BaseModel):
|
|
554
|
+
id: str
|
|
555
|
+
email: str
|
|
556
|
+
first_name: str
|
|
557
|
+
last_name: str
|
|
558
|
+
created_at: str
|
|
559
|
+
updated_at: str
|
|
560
|
+
|
|
561
|
+
class CreateUserRequest(BaseModel):
|
|
562
|
+
email: str
|
|
563
|
+
first_name: str
|
|
564
|
+
last_name: str
|
|
565
|
+
|
|
566
|
+
@app.get("/users", response_model=List[User])
|
|
567
|
+
async def get_users():
|
|
568
|
+
# Your implementation
|
|
569
|
+
pass
|
|
570
|
+
|
|
571
|
+
@app.post("/users", response_model=User)
|
|
572
|
+
async def create_user(user: CreateUserRequest):
|
|
573
|
+
# Your implementation
|
|
574
|
+
pass
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
### Generate Types
|
|
578
|
+
|
|
579
|
+
```bash
|
|
580
|
+
# Start your FastAPI server
|
|
581
|
+
uvicorn main:app --reload
|
|
582
|
+
|
|
583
|
+
# Generate types
|
|
584
|
+
npx schemantic generate --url http://localhost:8000/openapi.json --output ./src/generated
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
## Advanced Usage
|
|
588
|
+
|
|
589
|
+
### Custom Type Mappings
|
|
590
|
+
|
|
591
|
+
```typescript
|
|
592
|
+
const config: SchemanticConfig = {
|
|
593
|
+
// ... other config
|
|
594
|
+
customTypeMappings: {
|
|
595
|
+
uuid: "string",
|
|
596
|
+
datetime: "Date",
|
|
597
|
+
decimal: "number",
|
|
598
|
+
email: "string",
|
|
599
|
+
},
|
|
600
|
+
};
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
### Path and Schema Filtering
|
|
604
|
+
|
|
605
|
+
```typescript
|
|
606
|
+
const config: SchemanticConfig = {
|
|
607
|
+
// ... other config
|
|
608
|
+
excludePaths: ["/health", "/docs", "/redoc"],
|
|
609
|
+
includePaths: ["/api/v1/*"],
|
|
610
|
+
excludeSchemas: ["Error", "ValidationError"],
|
|
611
|
+
includeSchemas: ["User", "Product", "Order"],
|
|
612
|
+
};
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
### Configuration Files
|
|
616
|
+
|
|
617
|
+
Create a `schemantic.config.json` file:
|
|
618
|
+
|
|
619
|
+
```json
|
|
620
|
+
{
|
|
621
|
+
"schemaUrl": "http://localhost:8000/openapi.json",
|
|
622
|
+
"outputDir": "./generated",
|
|
623
|
+
"generateTypes": true,
|
|
624
|
+
"generateApiClient": true,
|
|
625
|
+
"useStrictTypes": true,
|
|
626
|
+
"namingConvention": "camelCase",
|
|
627
|
+
"plugins": [
|
|
628
|
+
{ "name": "jsdoc", "enabled": true },
|
|
629
|
+
{ "name": "validation", "enabled": true }
|
|
630
|
+
]
|
|
631
|
+
}
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
Use with CLI:
|
|
635
|
+
|
|
636
|
+
```bash
|
|
637
|
+
npx schemantic generate --config schemantic.config.json
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
## Validation
|
|
641
|
+
|
|
642
|
+
Validate your OpenAPI schema before generation:
|
|
643
|
+
|
|
644
|
+
```bash
|
|
645
|
+
# Validate schema
|
|
646
|
+
npx schemantic validate --url http://localhost:8000/openapi.json
|
|
647
|
+
|
|
648
|
+
# Validate with verbose output
|
|
649
|
+
npx schemantic validate --file schema.json --verbose
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
## Examples
|
|
653
|
+
|
|
654
|
+
### React Application
|
|
655
|
+
|
|
656
|
+
```typescript
|
|
657
|
+
// Import from the generated index barrel
|
|
658
|
+
import { MyApiApiClient } from "./generated";
|
|
659
|
+
import type { APIUser } from "./generated";
|
|
660
|
+
|
|
661
|
+
const apiClient = new MyApiApiClient({
|
|
662
|
+
baseUrl: "http://localhost:8000",
|
|
663
|
+
headers: {
|
|
664
|
+
Authorization: `Bearer ${token}`,
|
|
665
|
+
},
|
|
666
|
+
});
|
|
667
|
+
|
|
668
|
+
// Use in React component
|
|
669
|
+
const UsersPage = () => {
|
|
670
|
+
const [users, setUsers] = useState<APIUser[]>([]);
|
|
671
|
+
|
|
672
|
+
useEffect(() => {
|
|
673
|
+
const fetchUsers = async () => {
|
|
674
|
+
try {
|
|
675
|
+
const usersData = await apiClient.getUsers();
|
|
676
|
+
setUsers(usersData);
|
|
677
|
+
} catch (error) {
|
|
678
|
+
console.error("Failed to fetch users:", error);
|
|
679
|
+
}
|
|
680
|
+
};
|
|
681
|
+
|
|
682
|
+
fetchUsers();
|
|
683
|
+
}, []);
|
|
684
|
+
|
|
685
|
+
return (
|
|
686
|
+
<div>
|
|
687
|
+
{users.map((user) => (
|
|
688
|
+
<div key={user.id}>
|
|
689
|
+
{user.firstName} {user.lastName} - {user.email}
|
|
690
|
+
</div>
|
|
691
|
+
))}
|
|
692
|
+
</div>
|
|
693
|
+
);
|
|
694
|
+
};
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
### Node.js Application
|
|
698
|
+
|
|
699
|
+
```typescript
|
|
700
|
+
import { MyApiApiClient } from "./generated";
|
|
701
|
+
|
|
702
|
+
const apiClient = new MyApiApiClient({
|
|
703
|
+
baseUrl: "http://localhost:8000",
|
|
704
|
+
});
|
|
705
|
+
|
|
706
|
+
// Use in Node.js application
|
|
707
|
+
const main = async () => {
|
|
708
|
+
try {
|
|
709
|
+
const users = await apiClient.getUsers();
|
|
710
|
+
console.log("Users:", users);
|
|
711
|
+
|
|
712
|
+
const newUser = await apiClient.createUser({
|
|
713
|
+
email: "user@example.com",
|
|
714
|
+
firstName: "John",
|
|
715
|
+
lastName: "Doe",
|
|
716
|
+
});
|
|
717
|
+
console.log("Created user:", newUser);
|
|
718
|
+
} catch (error) {
|
|
719
|
+
console.error("API error:", error);
|
|
720
|
+
}
|
|
721
|
+
};
|
|
722
|
+
|
|
723
|
+
main();
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
## Tutorials
|
|
727
|
+
|
|
728
|
+
๐ **[Complete FastAPI Tutorial](./docs/FASTAPI_TUTORIAL.md)** - Build a full-stack e-commerce app with FastAPI, Schemantic, and React. Includes authentication, database models, type-safe API client, and React hooks.
|
|
729
|
+
|
|
730
|
+
## Contributing
|
|
731
|
+
|
|
732
|
+
We welcome contributions! Here's how you can help:
|
|
733
|
+
|
|
734
|
+
### ๐ Bug Reports
|
|
735
|
+
|
|
736
|
+
Found a bug? Please [open an issue](https://github.com/Cstannahill/schemantic/issues/new) with:
|
|
737
|
+
|
|
738
|
+
- Clear description of the problem
|
|
739
|
+
- Steps to reproduce
|
|
740
|
+
- Expected vs actual behavior
|
|
741
|
+
- Your environment (Node.js version, OS, etc.)
|
|
742
|
+
|
|
743
|
+
### ๐ก Feature Requests
|
|
744
|
+
|
|
745
|
+
Have an idea? [Start a discussion](https://github.com/Cstannahill/schemantic/discussions) or [open an issue](https://github.com/Cstannahill/schemantic/issues/new)!
|
|
746
|
+
|
|
747
|
+
### ๐ง Development Setup
|
|
748
|
+
|
|
749
|
+
```bash
|
|
750
|
+
# Clone the repository
|
|
751
|
+
git clone https://github.com/Cstannahill/schemantic.git
|
|
752
|
+
|
|
753
|
+
cd schemantic
|
|
754
|
+
|
|
755
|
+
# Install dependencies
|
|
756
|
+
npm install
|
|
757
|
+
|
|
758
|
+
# Build the project
|
|
759
|
+
npm run build
|
|
760
|
+
|
|
761
|
+
# Run tests
|
|
762
|
+
npm test
|
|
763
|
+
|
|
764
|
+
# Run tests in watch mode
|
|
765
|
+
npm run test:watch
|
|
766
|
+
|
|
767
|
+
# Run linting
|
|
768
|
+
npm run lint
|
|
769
|
+
|
|
770
|
+
# Fix linting issues automatically
|
|
771
|
+
npm run lint:fix
|
|
772
|
+
```
|
|
773
|
+
|
|
774
|
+
### ๐งช Testing
|
|
775
|
+
|
|
776
|
+
- Write tests for new features
|
|
777
|
+
- Ensure all tests pass: `npm test`
|
|
778
|
+
- Check test coverage: `npm run test:coverage`
|
|
779
|
+
- Test with real FastAPI applications in `local-test/`
|
|
780
|
+
|
|
781
|
+
### ๐ Documentation
|
|
782
|
+
|
|
783
|
+
- Update README.md for new features
|
|
784
|
+
- Add examples to documentation
|
|
785
|
+
- Update API documentation in `docs/`
|
|
786
|
+
|
|
787
|
+
### ๐ Pull Requests
|
|
788
|
+
|
|
789
|
+
1. Fork the repository
|
|
790
|
+
2. Create a feature branch: `git checkout -b feature/amazing-feature`
|
|
791
|
+
3. Make your changes
|
|
792
|
+
4. Add tests and documentation
|
|
793
|
+
5. Ensure all checks pass
|
|
794
|
+
6. Commit with clear messages
|
|
795
|
+
7. Push and create a Pull Request
|
|
796
|
+
|
|
797
|
+
## Support & Community
|
|
798
|
+
|
|
799
|
+
- ๐ **[Documentation](./docs/)** - Comprehensive guides and API reference
|
|
800
|
+
- ๐ **[Issue Tracker](https://github.com/Cstannahill/schemantic/issues)** - Bug reports and feature requests
|
|
801
|
+
- ๐ฌ **[Discussions](https://github.com/Cstannahill/schemantic/discussions)** - Community help and ideas
|
|
802
|
+
- ๏ฟฝ **[Plugin Development](./docs/PLUGIN_DEVELOPMENT.md)** - Create custom generators
|
|
803
|
+
- ๐ **[FastAPI Tutorial](./docs/FASTAPI_TUTORIAL.md)** - Complete integration guide
|
|
804
|
+
|
|
805
|
+
### Getting Help
|
|
806
|
+
|
|
807
|
+
1. Check the [documentation](./docs/) first
|
|
808
|
+
2. Search [existing issues](https://github.com/Cstannahill/schemantic/issues)
|
|
809
|
+
3. Ask in [discussions](https://github.com/Cstannahill/schemantic/discussions)
|
|
810
|
+
4. Create a new issue with detailed information
|
|
811
|
+
|
|
812
|
+
## Roadmap
|
|
813
|
+
|
|
814
|
+
- [ ] Support for OpenAPI 3.1 features
|
|
815
|
+
- [ ] GraphQL schema support
|
|
816
|
+
- [ ] Additional framework integrations (Express, NestJS)
|
|
817
|
+
- [ ] VS Code extension
|
|
818
|
+
- [ ] Enhanced React Query integration
|
|
819
|
+
- [ ] Performance optimizations for large schemas
|
|
820
|
+
|
|
821
|
+
## License
|
|
822
|
+
|
|
823
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
824
|
+
|
|
825
|
+
## Changelog
|
|
826
|
+
|
|
827
|
+
See [CHANGELOG.md](CHANGELOG.md) for a list of changes and version history.
|