@funbrew/pdf 1.0.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/README.ja.md +59 -0
- package/README.md +106 -0
- package/package.json +12 -0
- package/src/index.d.ts +54 -0
- package/src/index.js +124 -0
package/README.ja.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# @funbrew/pdf
|
|
2
|
+
|
|
3
|
+
FUNBREW PDF APIのNode.jsクライアントライブラリです。TypeScript型定義付き。
|
|
4
|
+
|
|
5
|
+
## インストール
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @funbrew/pdf
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 使い方
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
const { FunbrewPdf } = require('@funbrew/pdf');
|
|
15
|
+
|
|
16
|
+
const pdf = new FunbrewPdf('sk-your-api-key');
|
|
17
|
+
|
|
18
|
+
// HTML → PDF
|
|
19
|
+
const result = await pdf.fromHtml('<h1>Hello World</h1>');
|
|
20
|
+
console.log(result.data.download_url);
|
|
21
|
+
|
|
22
|
+
// URL → PDF
|
|
23
|
+
const result = await pdf.fromUrl('https://example.com');
|
|
24
|
+
|
|
25
|
+
// テンプレート → PDF
|
|
26
|
+
const result = await pdf.fromTemplate('invoice', {
|
|
27
|
+
company_name: 'FUNBREW Inc.',
|
|
28
|
+
amount: '100,000',
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// PDF生成 + メール送信
|
|
32
|
+
const result = await pdf.fromHtmlWithEmail(
|
|
33
|
+
'<h1>請求書</h1>',
|
|
34
|
+
'customer@example.com',
|
|
35
|
+
'請求書をお送りします',
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
// テストモード
|
|
39
|
+
const result = await pdf.test('<h1>Test</h1>');
|
|
40
|
+
|
|
41
|
+
// ダウンロード
|
|
42
|
+
const buffer = await pdf.download('uuid.pdf');
|
|
43
|
+
require('fs').writeFileSync('output.pdf', buffer);
|
|
44
|
+
|
|
45
|
+
// 利用状況
|
|
46
|
+
const usage = await pdf.usage();
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## オプション
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
const result = await pdf.fromHtml('<h1>Hello</h1>', {
|
|
53
|
+
options: { 'page-size': 'A3' },
|
|
54
|
+
expiration_hours: 168,
|
|
55
|
+
max_downloads: 5,
|
|
56
|
+
password: 'secret',
|
|
57
|
+
watermark: 'CONFIDENTIAL',
|
|
58
|
+
});
|
|
59
|
+
```
|
package/README.md
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# @funbrew/pdf
|
|
2
|
+
|
|
3
|
+
Official Node.js client library for the [FUNBREW PDF API](https://pdf.funbrew.cloud). Includes TypeScript type definitions.
|
|
4
|
+
|
|
5
|
+
[日本語ドキュメント](README.ja.md)
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @funbrew/pdf
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```js
|
|
16
|
+
const { FunbrewPdf } = require('@funbrew/pdf');
|
|
17
|
+
|
|
18
|
+
const pdf = new FunbrewPdf('sk-your-api-key');
|
|
19
|
+
|
|
20
|
+
// HTML to PDF
|
|
21
|
+
const result = await pdf.fromHtml('<h1>Hello World</h1>');
|
|
22
|
+
console.log(result.data.download_url);
|
|
23
|
+
|
|
24
|
+
// URL to PDF
|
|
25
|
+
const result = await pdf.fromUrl('https://example.com');
|
|
26
|
+
|
|
27
|
+
// Template to PDF
|
|
28
|
+
const result = await pdf.fromTemplate('invoice', {
|
|
29
|
+
company_name: 'Acme Inc.',
|
|
30
|
+
amount: '1,000',
|
|
31
|
+
});
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Features
|
|
35
|
+
|
|
36
|
+
```js
|
|
37
|
+
// Generate PDF and send via email
|
|
38
|
+
const result = await pdf.fromHtmlWithEmail(
|
|
39
|
+
'<h1>Invoice</h1>',
|
|
40
|
+
'customer@example.com',
|
|
41
|
+
'Your invoice is ready',
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
// Test mode (no count, TEST watermark)
|
|
45
|
+
const result = await pdf.test('<h1>Test</h1>');
|
|
46
|
+
|
|
47
|
+
// File operations
|
|
48
|
+
const info = await pdf.info('uuid.pdf');
|
|
49
|
+
const buffer = await pdf.download('uuid.pdf');
|
|
50
|
+
require('fs').writeFileSync('output.pdf', buffer);
|
|
51
|
+
await pdf.delete('uuid.pdf');
|
|
52
|
+
|
|
53
|
+
// Batch generate
|
|
54
|
+
const batch = await pdf.batch([
|
|
55
|
+
{ type: 'html', html: '<h1>Doc 1</h1>' },
|
|
56
|
+
{ type: 'html', html: '<h1>Doc 2</h1>' },
|
|
57
|
+
]);
|
|
58
|
+
|
|
59
|
+
// Merge PDFs
|
|
60
|
+
const merged = await pdf.merge(['file1.pdf', 'file2.pdf']);
|
|
61
|
+
|
|
62
|
+
// Usage stats
|
|
63
|
+
const usage = await pdf.usage();
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Options
|
|
67
|
+
|
|
68
|
+
```js
|
|
69
|
+
const result = await pdf.fromHtml('<h1>Hello</h1>', {
|
|
70
|
+
options: { 'page-size': 'A3', engine: 'quality' },
|
|
71
|
+
expiration_hours: 168,
|
|
72
|
+
max_downloads: 5,
|
|
73
|
+
password: 'secret',
|
|
74
|
+
watermark: 'CONFIDENTIAL',
|
|
75
|
+
});
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## TypeScript
|
|
79
|
+
|
|
80
|
+
Full type definitions are included. No need for `@types` packages.
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
import { FunbrewPdf, PdfResult } from '@funbrew/pdf';
|
|
84
|
+
|
|
85
|
+
const pdf = new FunbrewPdf('sk-your-api-key');
|
|
86
|
+
const result: PdfResult = await pdf.fromHtml('<h1>Hello</h1>');
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Error Handling
|
|
90
|
+
|
|
91
|
+
```js
|
|
92
|
+
const { FunbrewPdf, FunbrewError } = require('@funbrew/pdf');
|
|
93
|
+
|
|
94
|
+
try {
|
|
95
|
+
const result = await pdf.fromHtml('<h1>Hello</h1>');
|
|
96
|
+
} catch (e) {
|
|
97
|
+
if (e instanceof FunbrewError) {
|
|
98
|
+
console.error(e.message); // Error message
|
|
99
|
+
console.error(e.statusCode); // HTTP status code
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## License
|
|
105
|
+
|
|
106
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@funbrew/pdf",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "FUNBREW PDF API client for Node.js",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"types": "src/index.d.ts",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": ">=18"
|
|
10
|
+
},
|
|
11
|
+
"keywords": ["pdf", "api", "html-to-pdf", "funbrew"]
|
|
12
|
+
}
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export interface PdfResult {
|
|
2
|
+
success: boolean;
|
|
3
|
+
data: {
|
|
4
|
+
filename: string;
|
|
5
|
+
download_url: string;
|
|
6
|
+
public_url: string | null;
|
|
7
|
+
file_size: number;
|
|
8
|
+
expires_at: string;
|
|
9
|
+
max_downloads: number;
|
|
10
|
+
remaining_downloads: number;
|
|
11
|
+
s3_url?: string;
|
|
12
|
+
test_mode?: boolean;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface PdfOptions {
|
|
17
|
+
options?: { 'page-size'?: 'A3' | 'A4' | 'A5' | 'Letter' | 'Legal'; engine?: 'fast' | 'quality' };
|
|
18
|
+
expiration_hours?: number;
|
|
19
|
+
max_downloads?: number;
|
|
20
|
+
password?: string;
|
|
21
|
+
watermark?: string;
|
|
22
|
+
filename?: string;
|
|
23
|
+
test?: boolean;
|
|
24
|
+
email?: { to: string; subject?: string; body?: string };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface UsageResult {
|
|
28
|
+
success: boolean;
|
|
29
|
+
data: {
|
|
30
|
+
plan: { name: string; slug: string; monthly_limit: number };
|
|
31
|
+
usage: { current_month: string; generated: number; remaining: number | null; is_unlimited: boolean };
|
|
32
|
+
features: Record<string, boolean | { enabled: boolean; limit: number }>;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export class FunbrewPdf {
|
|
37
|
+
constructor(apiKey: string, options?: { baseUrl?: string });
|
|
38
|
+
fromHtml(html: string, options?: PdfOptions): Promise<PdfResult>;
|
|
39
|
+
fromUrl(url: string, options?: PdfOptions): Promise<PdfResult>;
|
|
40
|
+
fromTemplate(slug: string, variables?: Record<string, string>, options?: PdfOptions): Promise<PdfResult>;
|
|
41
|
+
fromHtmlWithEmail(html: string, to: string, subject?: string, body?: string, options?: PdfOptions): Promise<PdfResult>;
|
|
42
|
+
batch(items: Array<Record<string, any>>): Promise<any>;
|
|
43
|
+
batchStatus(batchUuid: string): Promise<any>;
|
|
44
|
+
merge(filenames: string[], options?: Record<string, any>): Promise<PdfResult>;
|
|
45
|
+
info(filename: string): Promise<any>;
|
|
46
|
+
download(filename: string): Promise<Buffer>;
|
|
47
|
+
delete(filename: string): Promise<any>;
|
|
48
|
+
usage(): Promise<UsageResult>;
|
|
49
|
+
test(html: string, options?: PdfOptions): Promise<PdfResult>;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export class FunbrewError extends Error {
|
|
53
|
+
statusCode: number;
|
|
54
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
class FunbrewPdf {
|
|
2
|
+
/**
|
|
3
|
+
* @param {string} apiKey
|
|
4
|
+
* @param {object} [options]
|
|
5
|
+
* @param {string} [options.baseUrl]
|
|
6
|
+
*/
|
|
7
|
+
constructor(apiKey, { baseUrl = 'https://pdf.funbrew.cloud' } = {}) {
|
|
8
|
+
this.apiKey = apiKey;
|
|
9
|
+
this.baseUrl = baseUrl.replace(/\/$/, '');
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** Generate PDF from HTML */
|
|
13
|
+
async fromHtml(html, options = {}) {
|
|
14
|
+
return this._post('/api/pdf/generate-from-html', { html, ...options });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Generate PDF from URL */
|
|
18
|
+
async fromUrl(url, options = {}) {
|
|
19
|
+
return this._post('/api/pdf/generate-from-url', { url, ...options });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Generate PDF from template */
|
|
23
|
+
async fromTemplate(slug, variables = {}, options = {}) {
|
|
24
|
+
return this._post('/api/pdf/generate-from-template', {
|
|
25
|
+
template: slug,
|
|
26
|
+
variables,
|
|
27
|
+
...options,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Generate PDF and send via email */
|
|
32
|
+
async fromHtmlWithEmail(html, to, subject = '', body = '', options = {}) {
|
|
33
|
+
const email = { to };
|
|
34
|
+
if (subject) email.subject = subject;
|
|
35
|
+
if (body) email.body = body;
|
|
36
|
+
return this.fromHtml(html, { ...options, email });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Get PDF file info */
|
|
40
|
+
async info(filename) {
|
|
41
|
+
return this._get(`/api/pdf/info/${filename}`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Download PDF file as Buffer */
|
|
45
|
+
async download(filename) {
|
|
46
|
+
const res = await fetch(`${this.baseUrl}/api/pdf/download/${filename}`, {
|
|
47
|
+
headers: { Authorization: `Bearer ${this.apiKey}` },
|
|
48
|
+
});
|
|
49
|
+
if (!res.ok) throw new FunbrewError('Download failed', res.status);
|
|
50
|
+
return Buffer.from(await res.arrayBuffer());
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Delete PDF file */
|
|
54
|
+
async delete(filename) {
|
|
55
|
+
return this._request('DELETE', `/api/pdf/delete/${filename}`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Batch generate multiple PDFs */
|
|
59
|
+
async batch(items) {
|
|
60
|
+
return this._post('/api/pdf/batch', { items });
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Get batch status */
|
|
64
|
+
async batchStatus(batchUuid) {
|
|
65
|
+
return this._get(`/api/pdf/batch/${batchUuid}`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Merge multiple PDFs into one */
|
|
69
|
+
async merge(filenames, options = {}) {
|
|
70
|
+
return this._post('/api/pdf/merge', { filenames, ...options });
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Get usage information */
|
|
74
|
+
async usage() {
|
|
75
|
+
return this._get('/api/usage');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** Generate PDF in test mode */
|
|
79
|
+
async test(html, options = {}) {
|
|
80
|
+
return this.fromHtml(html, { ...options, test: true });
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async _get(path) {
|
|
84
|
+
return this._request('GET', path);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async _post(path, data) {
|
|
88
|
+
return this._request('POST', path, data);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async _request(method, path, data) {
|
|
92
|
+
const options = {
|
|
93
|
+
method,
|
|
94
|
+
headers: {
|
|
95
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
96
|
+
'Content-Type': 'application/json',
|
|
97
|
+
Accept: 'application/json',
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
if (data && method !== 'GET') {
|
|
102
|
+
options.body = JSON.stringify(data);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const res = await fetch(`${this.baseUrl}${path}`, options);
|
|
106
|
+
const json = await res.json();
|
|
107
|
+
|
|
108
|
+
if (!res.ok) {
|
|
109
|
+
throw new FunbrewError(json.message || 'API request failed', res.status);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return json;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
class FunbrewError extends Error {
|
|
117
|
+
constructor(message, statusCode) {
|
|
118
|
+
super(message);
|
|
119
|
+
this.name = 'FunbrewError';
|
|
120
|
+
this.statusCode = statusCode;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
module.exports = { FunbrewPdf, FunbrewError };
|