docstron 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.md ADDED
@@ -0,0 +1,789 @@
1
+ # Docstron SDK for Node.js
2
+
3
+ [![npm version](https://img.shields.io/npm/v/docstron.svg)](https://www.npmjs.com/package/docstron)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ The official Node.js library for the [Docstron](https://docstron.com) PDF Generation API.
7
+
8
+ > **Current Version: v0.1.0 - Template Management**
9
+ > This is an early release focused on template operations. Document generation coming in v0.2.0!
10
+
11
+ ## 📋 What's Included in v0.1.0
12
+
13
+ ✅ **Template Management**
14
+
15
+ - Create templates with HTML content
16
+ - Get template details
17
+ - Update existing templates
18
+ - Delete templates
19
+ - List all templates
20
+
21
+ 🚧 **Coming Soon**
22
+
23
+ - v0.2.0: Document generation (PDF creation from templates)
24
+ - v0.3.0: Application management
25
+ - v1.0.0: Full feature set with comprehensive testing
26
+
27
+ ## Installation
28
+
29
+ ```bash
30
+ npm install docstron
31
+ ```
32
+
33
+ ## Quick Start
34
+
35
+ ```javascript
36
+ const Docstron = require("docstron");
37
+
38
+ // Initialize the client
39
+ const client = new Docstron("your-api-key-here");
40
+
41
+ // Create a template
42
+ const template = await client.templates.create({
43
+ application_id: "app-xxx",
44
+ name: "Invoice Template",
45
+ content: "<h1>Invoice #{{invoice_number}}</h1><p>Total: {{total}}</p>",
46
+ is_active: true,
47
+ });
48
+
49
+ console.log("Template created:", template.template_id);
50
+ ```
51
+
52
+ ## Authentication
53
+
54
+ Get your API key from your [Docstron Dashboard](https://docstron.com/dashboard).
55
+
56
+ ```javascript
57
+ const client = new Docstron("your-api-key-here");
58
+
59
+ // With custom options
60
+ const client = new Docstron("your-api-key-here", {
61
+ baseURL: "https://custom-api.docstron.com",
62
+ });
63
+ ```
64
+
65
+ ## API Reference
66
+
67
+ ### Templates
68
+
69
+ #### `templates.create(params)`
70
+
71
+ Create a new PDF template.
72
+
73
+ **Parameters:**
74
+
75
+ - `application_id` (string, required) - Your application ID
76
+ - `name` (string, required) - Template name
77
+ - `content` (string, required) - HTML content with `{{placeholders}}`
78
+ - `is_active` (boolean, optional) - Active status (default: `true`)
79
+ - `extra_css` (string, optional) - Additional CSS rules for PDF styling
80
+
81
+ **Returns:** Promise<Template>
82
+
83
+ **Example:**
84
+
85
+ ```javascript
86
+ const template = await client.templates.create({
87
+ application_id: "app-7b4d78fb-820c-4ca9-84cc-46953f211234",
88
+ name: "Invoice Template",
89
+ content: `
90
+ <html>
91
+ <body>
92
+ <h1>Invoice</h1>
93
+ <p>Customer: {{customer_name}}</p>
94
+ <p>Total: {{total_amount}}</p>
95
+ </body>
96
+ </html>
97
+ `,
98
+ is_active: true,
99
+ extra_css: "@page { margin: 2cm; }",
100
+ });
101
+ ```
102
+
103
+ #### `templates.get(templateId)`
104
+
105
+ Retrieve a specific template by ID.
106
+
107
+ **Parameters:**
108
+
109
+ - `templateId` (string, required) - The template ID
110
+
111
+ **Returns:** Promise<Template>
112
+
113
+ **Example:**
114
+
115
+ ```javascript
116
+ const template = await client.templates.get("template-xxx");
117
+ console.log(template.name);
118
+ ```
119
+
120
+ #### `templates.update(templateId, params)`
121
+
122
+ Update an existing template.
123
+
124
+ **Parameters:**
125
+
126
+ - `templateId` (string, required) - The template ID
127
+ - `params` (object, required) - Fields to update
128
+
129
+ **Returns:** Promise<Template>
130
+
131
+ **Example:**
132
+
133
+ ```javascript
134
+ const updated = await client.templates.update("template-xxx", {
135
+ name: "Updated Invoice Template",
136
+ is_active: false,
137
+ });
138
+ ```
139
+
140
+ #### `templates.delete(templateId)`
141
+
142
+ Delete a template.
143
+
144
+ **Parameters:**
145
+
146
+ - `templateId` (string, required) - The template ID
147
+
148
+ **Returns:** Promise<Object>
149
+
150
+ **Example:**
151
+
152
+ ```javascript
153
+ await client.templates.delete("template-xxx");
154
+ console.log("Template deleted");
155
+ ```
156
+
157
+ #### `templates.list(applicationId)`
158
+
159
+ List all templates for an application.
160
+
161
+ **Parameters:**
162
+
163
+ - `applicationId` (string, required) - The application ID
164
+
165
+ **Returns:** Promise<Array<Template>>
166
+
167
+ **Example:**
168
+
169
+ ```javascript
170
+ const templates = await client.templates.list("app-xxx");
171
+ console.log(`Found ${templates.length} templates`);
172
+ ```
173
+
174
+ ### Documents (v0.2.0+)
175
+
176
+ #### `documents.generate(templateId, options)`
177
+
178
+ Generate a PDF from a template.
179
+
180
+ **Parameters:**
181
+
182
+ - `templateId` (string, required) - Template ID
183
+ - `options.data` (object, required) - Data for placeholders
184
+ - `options.response_type` (string, optional) - `'pdf'`, `'json_with_base64'`, or `'document_id'` (default)
185
+ - `options.password` (string, optional) - Password protect the PDF
186
+
187
+ **Returns:** Document object or PDF buffer
188
+
189
+ **Example:**
190
+
191
+ ```javascript
192
+ const doc = await client.documents.generate(templateId, {
193
+ data: {
194
+ customer_name: "John Doe",
195
+ invoice_number: "INV-001",
196
+ total: "$299.00",
197
+ },
198
+ response_type: "document_id",
199
+ });
200
+
201
+ console.log("Download URL:", doc.download_url);
202
+ ```
203
+
204
+ #### `documents.quickGenerate(options)`
205
+
206
+ Generate a PDF without creating a template first.
207
+
208
+ **Parameters:**
209
+
210
+ - `options.html` (string, required) - HTML content
211
+ - `options.data` (object, required) - Data for placeholders
212
+ - `options.response_type` (string, optional) - Response format
213
+ - `options.extra_css` (string, optional) - Additional CSS
214
+ - `options.save_template` (boolean, optional) - Save as reusable template
215
+ - `options.application_id` (string, conditional) - Required if save_template is true
216
+ - `options.password` (string, optional) - Password protect the PDF
217
+
218
+ **Example:**
219
+
220
+ ```javascript
221
+ const doc = await client.documents.quickGenerate({
222
+ html: "<h1>Hello {{name}}</h1>",
223
+ data: { name: "World" },
224
+ response_type: "document_id",
225
+ });
226
+ ```
227
+
228
+ #### `documents.get(documentId)`
229
+
230
+ Get document details.
231
+
232
+ **Example:**
233
+
234
+ ```javascript
235
+ const doc = await client.documents.get("document-xxx");
236
+ console.log(doc.template_id, doc.created_at);
237
+ ```
238
+
239
+ #### `documents.list()`
240
+
241
+ List all documents.
242
+
243
+ **Example:**
244
+
245
+ ```javascript
246
+ const docs = await client.documents.list();
247
+ console.log(`Total documents: ${docs.length}`);
248
+ ```
249
+
250
+ #### `documents.download(documentId, filepath)`
251
+
252
+ Download a PDF document.
253
+
254
+ **Parameters:**
255
+
256
+ - `documentId` (string, required) - Document ID
257
+ - `filepath` (string, optional) - Local path to save the PDF
258
+
259
+ **Example:**
260
+
261
+ ```javascript
262
+ // Save to file
263
+ await client.documents.download("document-xxx", "./invoice.pdf");
264
+
265
+ // Get as buffer
266
+ const buffer = await client.documents.download("document-xxx");
267
+ ```
268
+
269
+ #### `documents.update(documentId, data)`
270
+
271
+ Update document data.
272
+
273
+ #### `documents.delete(documentId)`
274
+
275
+ Delete a document.
276
+
277
+ ### Applications (v0.3.0+)
278
+
279
+ #### `applications.create(params)`
280
+
281
+ Create a new application to organize your templates and documents.
282
+
283
+ **Parameters:**
284
+
285
+ - `params.name` (string, required) - Application name
286
+ - `params.description` (string, optional) - Application description
287
+ - `params.is_active` (boolean, optional) - Active status (default: `true`)
288
+
289
+ **Returns:** Promise<Application>
290
+
291
+ **Example:**
292
+
293
+ ```javascript
294
+ const app = await client.applications.create({
295
+ name: "Invoice System",
296
+ description: "Manages all customer invoices",
297
+ is_active: true,
298
+ });
299
+
300
+ console.log("App ID:", app.app_id);
301
+ ```
302
+
303
+ #### `applications.get(appId)`
304
+
305
+ Get details of a specific application.
306
+
307
+ **Example:**
308
+
309
+ ```javascript
310
+ const app = await client.applications.get("app-xxx");
311
+ console.log(app.name, app.is_active);
312
+ ```
313
+
314
+ #### `applications.list()`
315
+
316
+ List all applications in your account.
317
+
318
+ **Example:**
319
+
320
+ ```javascript
321
+ const apps = await client.applications.list();
322
+ console.log(`Total applications: ${apps.length}`);
323
+
324
+ apps.forEach((app) => {
325
+ console.log(`- ${app.name} (${app.is_active ? "Active" : "Inactive"})`);
326
+ });
327
+ ```
328
+
329
+ #### `applications.update(appId, params)`
330
+
331
+ Update an existing application.
332
+
333
+ **Parameters:**
334
+
335
+ - `appId` (string, required) - Application ID
336
+ - `params.name` (string, optional) - New name
337
+ - `params.description` (string, optional) - New description
338
+ - `params.is_active` (boolean, optional) - New active status
339
+
340
+ **Example:**
341
+
342
+ ```javascript
343
+ const updated = await client.applications.update("app-xxx", {
344
+ name: "Updated Invoice System",
345
+ is_active: false,
346
+ });
347
+ ```
348
+
349
+ #### `applications.delete(appId)`
350
+
351
+ Delete an application.
352
+
353
+ **Example:**
354
+
355
+ ```javascript
356
+ await client.applications.delete("app-xxx");
357
+ console.log("Application deleted");
358
+ ```
359
+
360
+ #### `applications.listActive()`
361
+
362
+ Get only active applications.
363
+
364
+ **Example:**
365
+
366
+ ```javascript
367
+ const activeApps = await client.applications.listActive();
368
+ console.log(`Active: ${activeApps.length}`);
369
+ ```
370
+
371
+ #### `applications.listInactive()`
372
+
373
+ Get only inactive applications.
374
+
375
+ **Example:**
376
+
377
+ ```javascript
378
+ const inactiveApps = await client.applications.listInactive();
379
+ console.log(`Inactive: ${inactiveApps.length}`);
380
+ ```
381
+
382
+ ## Response Types
383
+
384
+ When generating documents, you can choose the response format:
385
+
386
+ ### `document_id` (default)
387
+
388
+ Returns document ID and download URL - best for most use cases.
389
+
390
+ ```javascript
391
+ {
392
+ document_id: "document-xxx",
393
+ template_id: "template-xxx",
394
+ download_url: "https://api.docstron.com/v1/documents/download/document-xxx",
395
+ size_bytes: 5370
396
+ }
397
+ ```
398
+
399
+ ### `json_with_base64`
400
+
401
+ Returns base64-encoded PDF content - useful for immediate processing.
402
+
403
+ ```javascript
404
+ {
405
+ document_id: "document-xxx",
406
+ pdf_content: "JVBERi0xLjcK...",
407
+ filename: "document.pdf",
408
+ size_bytes: 5370
409
+ }
410
+ ```
411
+
412
+ ### `pdf`
413
+
414
+ Returns raw PDF binary data - useful for direct download endpoints.
415
+
416
+ ## Template Placeholders
417
+
418
+ Use double curly braces to create dynamic placeholders:
419
+
420
+ ```html
421
+ <h1>Hello {{customer_name}}!</h1>
422
+ <p>Order #{{order_number}} - Total: {{total_amount}}</p>
423
+ <p>Date: {{order_date}}</p>
424
+ ```
425
+
426
+ When generating PDFs (coming in v0.2.0), you'll pass data to fill these placeholders:
427
+
428
+ ```javascript
429
+ // Coming in v0.2.0
430
+ {
431
+ customer_name: "John Doe",
432
+ order_number: "12345",
433
+ total_amount: "$299.00",
434
+ order_date: "2025-11-08"
435
+ }
436
+ ```
437
+
438
+ ## Error Handling
439
+
440
+ The SDK provides specific error types for better error handling:
441
+
442
+ ```javascript
443
+ const {
444
+ DocstronError,
445
+ ValidationError,
446
+ AuthenticationError,
447
+ NotFoundError
448
+ } = require('docstron');
449
+
450
+ try {
451
+ await client.templates.create({...});
452
+ } catch (error) {
453
+ if (error instanceof ValidationError) {
454
+ console.error('Validation failed:');
455
+ error.errors.forEach(err => {
456
+ console.error(`- ${err.field}: ${err.message}`);
457
+ });
458
+ } else if (error instanceof AuthenticationError) {
459
+ console.error('Invalid API key');
460
+ } else if (error instanceof NotFoundError) {
461
+ console.error('Template or application not found');
462
+ } else if (error instanceof DocstronError) {
463
+ console.error('API error:', error.message);
464
+ } else {
465
+ console.error('Unexpected error:', error);
466
+ }
467
+ }
468
+ ```
469
+
470
+ ## Examples
471
+
472
+ ### Complete Workflow
473
+
474
+ ```javascript
475
+ const Docstron = require("docstron");
476
+ const client = new Docstron("your-api-key");
477
+
478
+ // 1. Create template
479
+ const template = await client.templates.create({
480
+ application_id: "app-xxx",
481
+ name: "Invoice",
482
+ content: "<h1>Invoice #{{invoice_no}}</h1>",
483
+ });
484
+
485
+ // 2. Generate PDF
486
+ const pdf = await client.documents.generate(template.template_id, {
487
+ data: { invoice_no: "12345" },
488
+ response_type: "document_id",
489
+ });
490
+
491
+ // 3. Download PDF
492
+ await client.documents.download(pdf.document_id, "./invoice.pdf");
493
+
494
+ console.log("PDF saved to invoice.pdf");
495
+ ```
496
+
497
+ ### Quick Generation
498
+
499
+ ```javascript
500
+ // Generate without creating a template
501
+ const doc = await client.documents.quickGenerate({
502
+ html: "<h1>Receipt</h1><p>Total: {{total}}</p>",
503
+ data: { total: "$99.00" },
504
+ response_type: "document_id",
505
+ });
506
+
507
+ console.log("PDF URL:", doc.download_url);
508
+ ```
509
+
510
+ ### Password Protection
511
+
512
+ ```javascript
513
+ const doc = await client.documents.generate(templateId, {
514
+ data: {
515
+ /* your data */
516
+ },
517
+ password: "SecurePass123!",
518
+ response_type: "document_id",
519
+ });
520
+ ```
521
+
522
+ ### Basic Usage
523
+
524
+ ```bash
525
+ DOCSTRON_API_KEY=your-key npm run example
526
+ ```
527
+
528
+ ### Create Invoice Template
529
+
530
+ ```bash
531
+ DOCSTRON_API_KEY=your-key npm run example:invoice
532
+ ```
533
+
534
+ ## Development
535
+
536
+ ```bash
537
+ # Install dependencies
538
+ npm install
539
+
540
+ # Run tests (basic validation tests)
541
+ npm test
542
+
543
+ # Run examples
544
+ npm run example
545
+ npm run example:invoice
546
+ ```
547
+
548
+ ## Requirements
549
+
550
+ - Node.js >= 14.0.0
551
+ - A Docstron account and API key
552
+
553
+ ## Roadmap
554
+
555
+ ### v0.2.0 (Coming Soon)
556
+
557
+ - 📄 Document generation from templates
558
+ - 🔄 Asynchronous PDF processing
559
+ - 📥 Multiple output formats (URL, base64, binary)
560
+
561
+ ### v0.3.0 (Planned)
562
+
563
+ - 🏢 Application management
564
+ - 📊 Usage statistics
565
+ - 🔐 Advanced authentication options
566
+
567
+ ### v1.0.0 (Future)
568
+
569
+ - 🎯 Full API coverage
570
+ - ✅ Comprehensive test suite
571
+ - 📚 Extended documentation
572
+ - 🔌 Webhook support
573
+
574
+ ## Support
575
+
576
+ - 📧 Email: support@docstron.com
577
+ - 📚 Documentation: https://docs.docstron.com
578
+ - 🐛 Issues: https://github.com/yourusername/docstron-sdk/issues
579
+ - 💬 Discussions: https://github.com/yourusername/docstron-sdk/discussions
580
+
581
+ ## Contributing
582
+
583
+ Contributions are welcome! This is an early-stage project, and we'd love your help making it better.
584
+
585
+ 1. Fork the repository
586
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
587
+ 3. Commit your changes (`git commit -m 'Add amazing feature'`)
588
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
589
+ 5. Open a Pull Request
590
+
591
+ ## License
592
+
593
+ MIT © [Your Name]
594
+
595
+ ## Changelog
596
+
597
+ ### [0.3.0] - 2025-11-17
598
+
599
+ ### Added
600
+
601
+ - Application management (create, get, list, update, delete)
602
+ - Filter active/inactive applications with `listActive()` and `listInactive()`
603
+ - Complete workflow example (Application → Template → Document)
604
+ - Application organization best practices
605
+
606
+ ### Examples
607
+
608
+ - `manage-applications.js` - Full application CRUD examples
609
+ - `complete-workflow-with-apps.js` - End-to-end workflow demonstration
610
+
611
+ ### Improvements
612
+
613
+ - Updated all documentation with application examples
614
+ - Added application organization patterns
615
+ - Complete SDK feature set (Templates, Documents, Applications)
616
+
617
+ ### [0.2.0] - 2025-11-17
618
+
619
+ ### Added
620
+
621
+ - Document generation from templates
622
+ - Quick PDF generation without templates
623
+ - Document management (get, list, update, delete)
624
+ - PDF download functionality
625
+ - Password protection for PDFs
626
+ - Multiple response type support
627
+
628
+ ### [0.1.0] - 2025-11-17
629
+
630
+ ### Added
631
+
632
+ - Initial release
633
+ - Template management (CRUD operations)
634
+ - Basic error handling
635
+
636
+ # Dependencies
637
+
638
+ node_modules/
639
+
640
+ # Environment
641
+
642
+ .env
643
+ .env.local
644
+ .env.\*.local
645
+
646
+ # Logs
647
+
648
+ _.log
649
+ npm-debug.log_
650
+ yarn-debug.log*
651
+ yarn-error.log*
652
+
653
+ # Editor directories
654
+
655
+ .vscode/
656
+ .idea/
657
+ _.swp
658
+ _.swo
659
+ \*~
660
+
661
+ # OS
662
+
663
+ .DS_Store
664
+ Thumbs.db
665
+
666
+ # Testing
667
+
668
+ coverage/
669
+ .nyc_output/
670
+
671
+ # Build
672
+
673
+ dist/
674
+ build/
675
+
676
+ # Optional npm cache
677
+
678
+ .npm
679
+
680
+ # Optional eslint cache
681
+
682
+ .eslintcache
683
+
684
+ ```
685
+
686
+ ### 4. .npmignore
687
+ ```
688
+
689
+ # Development files
690
+
691
+ test/
692
+ examples/
693
+ .vscode/
694
+ .idea/
695
+
696
+ # Git files
697
+
698
+ .git/
699
+ .gitignore
700
+ .gitattributes
701
+
702
+ # CI/CD
703
+
704
+ .github/
705
+ .travis.yml
706
+ .gitlab-ci.yml
707
+
708
+ # Documentation source
709
+
710
+ docs/
711
+
712
+ ## Complete Workflow Example
713
+
714
+ Here's a complete example showing all features working together:
715
+
716
+ ```javascript
717
+ const Docstron = require("docstron-sdk");
718
+ const client = new Docstron("your-api-key");
719
+
720
+ // 1. Create application
721
+ const app = await client.applications.create({
722
+ name: "My Invoice App",
723
+ description: "Customer invoicing system",
724
+ });
725
+
726
+ // 2. Create template in the application
727
+ const template = await client.templates.create({
728
+ application_id: app.app_id,
729
+ name: "Standard Invoice",
730
+ content: "<h1>Invoice #{{number}}</h1><p>Total: {{total}}</p>",
731
+ });
732
+
733
+ // 3. Generate PDF from template
734
+ const doc = await client.documents.generate(template.template_id, {
735
+ data: {
736
+ number: "12345",
737
+ total: "$999.00",
738
+ },
739
+ });
740
+
741
+ // 4. Download the PDF
742
+ await client.documents.download(doc.document_id, "./invoice.pdf");
743
+
744
+ console.log("✅ Complete workflow finished!");
745
+ ```
746
+
747
+ ## Application Organization Best Practices
748
+
749
+ # Environment
750
+
751
+ .env
752
+ .env.\*
753
+
754
+ # Logs
755
+
756
+ \*.log
757
+
758
+ # Editor files
759
+
760
+ _.swp
761
+ _.swo
762
+ \*~
763
+
764
+ ```
765
+
766
+ ### 5. LICENSE (MIT)
767
+ ```
768
+
769
+ MIT License
770
+
771
+ Copyright (c) 2025 [Your Name]
772
+
773
+ Permission is hereby granted, free of charge, to any person obtaining a copy
774
+ of this software and associated documentation files (the "Software"), to deal
775
+ in the Software without restriction, including without limitation the rights
776
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
777
+ copies of the Software, and to permit persons to whom the Software is
778
+ furnished to do so, subject to the following conditions:
779
+
780
+ The above copyright notice and this permission notice shall be included in all
781
+ copies or substantial portions of the Software.
782
+
783
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
784
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
785
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
786
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
787
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
788
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
789
+ SOFTWARE.