docfast/scripts/generate-openapi.mjs
DocFast Bot 792e2d9142
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Has been cancelled
v0.4.1: Code-driven OpenAPI docs via swagger-jsdoc
- Add swagger-jsdoc dependency for auto-generating OpenAPI spec from JSDoc
- Add JSDoc @openapi annotations to all route handlers
- Create scripts/generate-openapi.mjs build step
- OpenAPI spec now auto-generated from code — no manual JSON editing
- All 13 endpoints documented with full parameters
- New demo endpoints documented, signup marked as deprecated
- Updated info description: demo-first, no free tier references
- Dockerfile updated to run openapi generation during build
- Build script updated: npm run build generates spec before compile
2026-02-20 07:54:37 +00:00

123 lines
4.1 KiB
JavaScript

#!/usr/bin/env node
/**
* Generates openapi.json from JSDoc annotations in route files.
* Run: node scripts/generate-openapi.mjs
* Output: public/openapi.json
*/
import swaggerJsdoc from 'swagger-jsdoc';
import { writeFileSync } from 'fs';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
const __dirname = dirname(fileURLToPath(import.meta.url));
const options = {
definition: {
openapi: '3.0.3',
info: {
title: 'DocFast API',
version: '1.0.0',
description: `Convert HTML, Markdown, and URLs to pixel-perfect PDFs. Built-in invoice & receipt templates.
## Authentication
All conversion and template endpoints require an API key via \`Authorization: Bearer <key>\` or \`X-API-Key: <key>\` header.
## Demo Endpoints
Try the API without signing up! Demo endpoints are public (no API key needed) but rate-limited to 5 requests/hour per IP and produce watermarked PDFs.
## Rate Limits
- Demo: 5 PDFs/hour per IP (watermarked)
- Pro tier: 5,000 PDFs/month, 30 req/min
## Getting Started
1. Try the demo at \`POST /v1/demo/html\` — no signup needed
2. Subscribe to Pro at [docfast.dev](https://docfast.dev/#pricing) for clean PDFs
3. Use your API key to convert documents`,
contact: {
name: 'DocFast',
url: 'https://docfast.dev',
email: 'support@docfast.dev'
}
},
servers: [
{ url: 'https://docfast.dev', description: 'Production' }
],
tags: [
{ name: 'Demo', description: 'Try the API without signing up — watermarked PDFs, rate-limited' },
{ name: 'Conversion', description: 'Convert HTML, Markdown, or URLs to PDF (requires API key)' },
{ name: 'Templates', description: 'Built-in document templates' },
{ name: 'Account', description: 'Key recovery and email management' },
{ name: 'Billing', description: 'Stripe-powered subscription management' },
{ name: 'System', description: 'Health checks and usage stats' }
],
components: {
securitySchemes: {
BearerAuth: {
type: 'http',
scheme: 'bearer',
description: 'API key as Bearer token'
},
ApiKeyHeader: {
type: 'apiKey',
in: 'header',
name: 'X-API-Key',
description: 'API key via X-API-Key header'
}
},
schemas: {
PdfOptions: {
type: 'object',
properties: {
format: {
type: 'string',
enum: ['A4', 'Letter', 'Legal', 'A3', 'A5', 'Tabloid'],
default: 'A4',
description: 'Page size'
},
landscape: {
type: 'boolean',
default: false,
description: 'Landscape orientation'
},
margin: {
type: 'object',
properties: {
top: { type: 'string', description: 'Top margin (e.g. "10mm", "1in")', default: '0' },
right: { type: 'string', description: 'Right margin', default: '0' },
bottom: { type: 'string', description: 'Bottom margin', default: '0' },
left: { type: 'string', description: 'Left margin', default: '0' }
},
description: 'Page margins'
},
printBackground: {
type: 'boolean',
default: true,
description: 'Print background colors and images'
},
filename: {
type: 'string',
description: 'Custom filename for Content-Disposition header',
default: 'document.pdf'
}
}
},
Error: {
type: 'object',
properties: {
error: { type: 'string', description: 'Error message' }
},
required: ['error']
}
}
}
},
apis: [
join(__dirname, '../src/routes/*.ts'),
join(__dirname, '../src/openapi-extra.yaml')
]
};
const spec = swaggerJsdoc(options);
const outPath = join(__dirname, '../public/openapi.json');
writeFileSync(outPath, JSON.stringify(spec, null, 2));
console.log(`✅ Generated ${outPath} (${Object.keys(spec.paths || {}).length} paths)`);