feat: add official Node.js and Python SDKs
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Has been cancelled
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Has been cancelled
- Node.js SDK (sdk/nodejs/): TypeScript, zero deps, native fetch, Node 18+ - Python SDK (sdk/python/): sync + async clients via httpx, Python 3.8+ - Both wrap all conversion endpoints (html, markdown, url, templates) - Proper error handling with DocFastError - Full README documentation for each
This commit is contained in:
parent
45b5be248c
commit
2e29d564ab
9 changed files with 547 additions and 0 deletions
95
sdk/nodejs/README.md
Normal file
95
sdk/nodejs/README.md
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
# DocFast Node.js SDK
|
||||
|
||||
Official Node.js client for the [DocFast](https://docfast.dev) HTML-to-PDF API.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npm install docfast
|
||||
```
|
||||
|
||||
Requires Node.js 18+ (uses native `fetch`). Zero runtime dependencies.
|
||||
|
||||
## Quick Start
|
||||
|
||||
```typescript
|
||||
import DocFast from 'docfast';
|
||||
|
||||
const client = new DocFast('df_pro_your_api_key');
|
||||
|
||||
// HTML to PDF
|
||||
const pdf = await client.html('<h1>Hello World</h1>');
|
||||
fs.writeFileSync('output.pdf', pdf);
|
||||
|
||||
// Markdown to PDF
|
||||
const pdf2 = await client.markdown('# Hello\n\nThis is **bold**.');
|
||||
fs.writeFileSync('doc.pdf', pdf2);
|
||||
|
||||
// URL to PDF
|
||||
const pdf3 = await client.url('https://example.com');
|
||||
fs.writeFileSync('page.pdf', pdf3);
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### `new DocFast(apiKey, options?)`
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `apiKey` | `string` | Your DocFast API key |
|
||||
| `options.baseUrl` | `string` | API base URL (default: `https://docfast.dev`) |
|
||||
|
||||
### `client.html(html, options?)`
|
||||
|
||||
Convert an HTML string to PDF. Returns `Promise<Buffer>`.
|
||||
|
||||
### `client.markdown(markdown, options?)`
|
||||
|
||||
Convert a Markdown string to PDF. Returns `Promise<Buffer>`.
|
||||
|
||||
### `client.url(url, options?)`
|
||||
|
||||
Convert a webpage URL to PDF. Returns `Promise<Buffer>`.
|
||||
|
||||
### `client.templates()`
|
||||
|
||||
List available templates. Returns `Promise<Template[]>`.
|
||||
|
||||
### `client.renderTemplate(id, data, options?)`
|
||||
|
||||
Render a template with data. Returns `Promise<Buffer>`.
|
||||
|
||||
### PDF Options
|
||||
|
||||
All conversion methods accept an optional `options` object:
|
||||
|
||||
```typescript
|
||||
{
|
||||
format: 'A4' | 'Letter' | 'Legal' | 'A3' | 'A5' | 'Tabloid',
|
||||
landscape: boolean,
|
||||
margin: { top: '20mm', bottom: '20mm', left: '15mm', right: '15mm' },
|
||||
header: { content: '<div>Header HTML</div>', height: '30mm' },
|
||||
footer: { content: '<div>Footer HTML</div>', height: '20mm' },
|
||||
scale: 1.0,
|
||||
printBackground: true,
|
||||
}
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
```typescript
|
||||
import DocFast, { DocFastError } from 'docfast';
|
||||
|
||||
try {
|
||||
const pdf = await client.html('<h1>Test</h1>');
|
||||
} catch (err) {
|
||||
if (err instanceof DocFastError) {
|
||||
console.error(err.message); // "Invalid API key"
|
||||
console.error(err.status); // 403
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
24
sdk/nodejs/package.json
Normal file
24
sdk/nodejs/package.json
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"name": "docfast",
|
||||
"version": "0.1.0",
|
||||
"description": "Official Node.js client for the DocFast HTML-to-PDF API",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"files": ["dist"],
|
||||
"engines": { "node": ">=18.0.0" },
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"prepublishOnly": "npm run build"
|
||||
},
|
||||
"keywords": ["pdf", "html-to-pdf", "markdown-to-pdf", "docfast", "api", "document"],
|
||||
"author": "DocFast <support@docfast.dev>",
|
||||
"license": "MIT",
|
||||
"homepage": "https://docfast.dev",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.cloonar.com/openclawd/docfast"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.0.0"
|
||||
}
|
||||
}
|
||||
129
sdk/nodejs/src/index.ts
Normal file
129
sdk/nodejs/src/index.ts
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
/**
|
||||
* DocFast — Official Node.js SDK
|
||||
* https://docfast.dev
|
||||
*/
|
||||
|
||||
export interface PdfMargin {
|
||||
top?: string;
|
||||
bottom?: string;
|
||||
left?: string;
|
||||
right?: string;
|
||||
}
|
||||
|
||||
export interface HeaderFooter {
|
||||
content?: string;
|
||||
height?: string;
|
||||
}
|
||||
|
||||
export interface PdfOptions {
|
||||
format?: 'A4' | 'Letter' | 'Legal' | 'A3' | 'A5' | 'Tabloid';
|
||||
landscape?: boolean;
|
||||
margin?: PdfMargin;
|
||||
header?: HeaderFooter;
|
||||
footer?: HeaderFooter;
|
||||
scale?: number;
|
||||
printBackground?: boolean;
|
||||
}
|
||||
|
||||
export interface Template {
|
||||
id: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export interface DocFastOptions {
|
||||
baseUrl?: string;
|
||||
}
|
||||
|
||||
export class DocFastError extends Error {
|
||||
readonly status: number;
|
||||
readonly code?: string;
|
||||
|
||||
constructor(message: string, status: number, code?: string) {
|
||||
super(message);
|
||||
this.name = 'DocFastError';
|
||||
this.status = status;
|
||||
this.code = code;
|
||||
}
|
||||
}
|
||||
|
||||
export class DocFast {
|
||||
private readonly apiKey: string;
|
||||
private readonly baseUrl: string;
|
||||
|
||||
constructor(apiKey: string, options?: DocFastOptions) {
|
||||
if (!apiKey) throw new Error('API key is required');
|
||||
this.apiKey = apiKey;
|
||||
this.baseUrl = options?.baseUrl?.replace(/\/+$/, '') ?? 'https://docfast.dev';
|
||||
}
|
||||
|
||||
private async request(path: string, body: Record<string, unknown>): Promise<Buffer> {
|
||||
const res = await fetch(`${this.baseUrl}${path}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${this.apiKey}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
let message = `HTTP ${res.status}`;
|
||||
let code: string | undefined;
|
||||
try {
|
||||
const err = await res.json() as { error?: string; code?: string };
|
||||
if (err.error) message = err.error;
|
||||
code = err.code;
|
||||
} catch {}
|
||||
throw new DocFastError(message, res.status, code);
|
||||
}
|
||||
|
||||
const arrayBuffer = await res.arrayBuffer();
|
||||
return Buffer.from(arrayBuffer);
|
||||
}
|
||||
|
||||
private async requestJson<T>(method: string, path: string): Promise<T> {
|
||||
const res = await fetch(`${this.baseUrl}${path}`, {
|
||||
method,
|
||||
headers: { 'Authorization': `Bearer ${this.apiKey}` },
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
let message = `HTTP ${res.status}`;
|
||||
try {
|
||||
const err = await res.json() as { error?: string };
|
||||
if (err.error) message = err.error;
|
||||
} catch {}
|
||||
throw new DocFastError(message, res.status);
|
||||
}
|
||||
|
||||
return res.json() as Promise<T>;
|
||||
}
|
||||
|
||||
/** Convert HTML to PDF */
|
||||
async html(html: string, options?: PdfOptions): Promise<Buffer> {
|
||||
return this.request('/v1/convert/html', { html, options });
|
||||
}
|
||||
|
||||
/** Convert Markdown to PDF */
|
||||
async markdown(markdown: string, options?: PdfOptions): Promise<Buffer> {
|
||||
return this.request('/v1/convert/markdown', { markdown, options });
|
||||
}
|
||||
|
||||
/** Convert a URL to PDF */
|
||||
async url(url: string, options?: PdfOptions): Promise<Buffer> {
|
||||
return this.request('/v1/convert/url', { url, options });
|
||||
}
|
||||
|
||||
/** List available templates */
|
||||
async templates(): Promise<Template[]> {
|
||||
return this.requestJson<Template[]>('GET', '/v1/templates');
|
||||
}
|
||||
|
||||
/** Render a template to PDF */
|
||||
async renderTemplate(id: string, data: Record<string, unknown>, options?: PdfOptions): Promise<Buffer> {
|
||||
return this.request(`/v1/templates/${encodeURIComponent(id)}/render`, { data, options });
|
||||
}
|
||||
}
|
||||
|
||||
export default DocFast;
|
||||
16
sdk/nodejs/tsconfig.json
Normal file
16
sdk/nodejs/tsconfig.json
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "Node16",
|
||||
"moduleResolution": "Node16",
|
||||
"lib": ["ES2022"],
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"declaration": true,
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue