qorstack-report-sdk 0.0.1 → 0.1.1

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.
Files changed (2) hide show
  1. package/README.md +499 -370
  2. package/package.json +3 -3
package/README.md CHANGED
@@ -1,370 +1,499 @@
1
- # Qorstack Report SDK
2
-
3
- The official SDK for Qorstack Report, a powerful API for generating PDF reports from Microsoft Word (DOCX) templates.
4
- This SDK simplifies the integration of Qorstack Report into your **Node.js** and **.NET** applications.
5
-
6
- ## Features
7
-
8
- - **Template-Based Rendering**: Generate PDFs from templates stored in your Qorstack Report account.
9
- - **Dynamic File Rendering**: Generate PDFs directly from a base64-encoded DOCX file.
10
- - **Comprehensive Data Binding**:
11
- - Text replacement
12
- - Dynamic tables (with merge and collapse support)
13
- - Images (from URL or Base64)
14
- - QR Codes and Barcodes
15
- - Conditional logic (hide/show sections)
16
- - **Cross-Platform Support**: Fully typed libraries for TypeScript/Node.js and C#/.NET 8.0+.
17
-
18
- ---
19
-
20
- ## Installation
21
-
22
- ### Node.js (TypeScript/JavaScript)
23
-
24
- ```bash
25
- npm install qorstack-report-sdk
26
- # or
27
- yarn add qorstack-report-sdk
28
- ```
29
-
30
- ### .NET (C#)
31
-
32
- ```bash
33
- dotnet add package Qorstack.Report.Sdk
34
- ```
35
-
36
- ---
37
-
38
- ## Authentication
39
-
40
- To use the SDK, you need an **API Key** from the Qorstack Portal.
41
-
42
- 1. Log in to the Qorstack Portal.
43
- 2. Navigate to **Settings > API Keys**.
44
- 3. Create a new API Key.
45
-
46
- ---
47
-
48
- ## Getting Started
49
-
50
- ### Node.js Setup
51
-
52
- ```typescript
53
- import { QorstackApi } from "qorstack-report-sdk";
54
-
55
- // 1. Initialize the client with API Key
56
- const qorstackApi = new QorstackApi({
57
- securityData: {
58
- headers: {
59
- "X-API-KEY": "YOUR_API_KEY_HERE",
60
- },
61
- },
62
- });
63
-
64
- // OR: Initialize with custom Base URL and API Key
65
- const qorstackApiCustom = new QorstackApi({
66
- baseUrl: "https://your-custom-url.com",
67
- securityData: {
68
- headers: {
69
- "X-API-KEY": "YOUR_API_KEY_HERE",
70
- },
71
- },
72
- });
73
- ```
74
-
75
- ### .NET Setup
76
-
77
- ```csharp
78
- using Qorstack.Report.Sdk;
79
- using System.Net.Http;
80
-
81
- // 1. Initialize the Client with API Key
82
- var qorstackApi = new QorstackApi(apiKey: "YOUR_API_KEY_HERE");
83
-
84
- // OR: Initialize with custom Base URL and API Key
85
- var qorstackApiCustom = new QorstackApi("https://your-custom-url.com", "YOUR_API_KEY_HERE");
86
- ```
87
-
88
- ---
89
-
90
- ## Usage Examples
91
-
92
- This section demonstrates how to construct request objects for various scenarios.
93
-
94
- ### 1. Generate PDF from Template (`PdfFromTemplateRequest`)
95
-
96
- This is the most common use case. You reference a `templateKey` stored in the system.
97
-
98
- #### Full Feature Example (Text, Table, Image, QR, Barcode)
99
-
100
- **Node.js (TypeScript)**
101
-
102
- ```typescript
103
- // Prepare table rows
104
- const tableRows = data.map((item, index) => ({
105
- no: index + 1,
106
- category: item.category,
107
- description: item.description,
108
- qty: item.quantity,
109
- unit_price: item.price,
110
- amount: item.total,
111
- }));
112
-
113
- const response = await qorstackApi.render.postRenderTemplatePdf({
114
- templateKey: "RENDOX-7326-758-974-2067",
115
- fileName: "Full_Report_Example",
116
- replace: {
117
- customer_name: "Example Company Ltd.",
118
- document_date: new Date().toLocaleDateString("en-GB"), // dd/MM/yyyy
119
- total_amount: "1,500.00",
120
- },
121
- table: [
122
- {
123
- rows: tableRows,
124
- verticalMerge: ["category"],
125
- collapse: ["description"],
126
- },
127
- ],
128
- image: {
129
- header_logo: {
130
- src: "https://example.com/logo.png",
131
- width: 200,
132
- fit: "contain",
133
- },
134
- },
135
- qrcode: {
136
- payment_qr: {
137
- text: "https://payment.link/123456",
138
- size: 150,
139
- },
140
- },
141
- barcode: {
142
- product_barcode: {
143
- text: "PROD-123456789",
144
- format: "Code128",
145
- width: 300,
146
- height: 80,
147
- },
148
- },
149
- });
150
-
151
- console.log("Download URL:", response.data.downloadUrl);
152
- ```
153
-
154
- **C# (.NET)**
155
-
156
- ```csharp
157
- var data = await _exampleService.GetDataAsync(id);
158
-
159
- var tableRows = data.Select((item, index) => new Dictionary<string, object>
160
- {
161
- { "no", index + 1 },
162
- { "category", item.Category },
163
- { "description", item.Description },
164
- { "qty", item.Quantity },
165
- { "unit_price", item.Price },
166
- { "amount", item.Total }
167
- }).ToList();
168
-
169
- var request = new PdfFromTemplateRequest
170
- {
171
- TemplateKey = "RENDOX-7326-758-974-2067",
172
- FileName = "Full_Report_Example",
173
- Replace = new()
174
- {
175
- { "customer_name", "Example Company Ltd." },
176
- { "document_date", DateTime.Now.ToString("dd/MM/yyyy") },
177
- { "total_amount", "1,500.00" }
178
- },
179
- Table = new()
180
- {
181
- new()
182
- {
183
- Rows = tableRows,
184
- VerticalMerge = new() { "category" },
185
- Collapse = new() { "description" }
186
- }
187
- },
188
- Image = new()
189
- {
190
- {
191
- "header_logo",
192
- new() { Src = "https://example.com/logo.png", Width = 200, Fit = "contain" }
193
- }
194
- },
195
- QrCode = new()
196
- {
197
- {
198
- "payment_qr",
199
- new() { Text = "https://payment.link/123456", Size = 150 }
200
- }
201
- },
202
- Barcode = new()
203
- {
204
- {
205
- "product_barcode",
206
- new() { Text = "PROD-123456789", Format = "Code128", Width = 300, Height = 80 }
207
- }
208
- }
209
- };
210
-
211
- var response = await qorstackApi.PostRenderTemplatePdfAsync(request);
212
- ```
213
-
214
- ---
215
-
216
- ### 2. Generate PDF from File (`PdfFromFileRequest`)
217
-
218
- Use this when you want to send the DOCX template file directly with the request.
219
-
220
- **Node.js (TypeScript)**
221
-
222
- ```typescript
223
- import * as fs from "fs";
224
-
225
- // Read local file as Base64
226
- const fileBuffer = fs.readFileSync("template.docx");
227
- const base64File = fileBuffer.toString("base64");
228
-
229
- const response = await qorstackApi.render.postRenderDocxPdf({
230
- fileBase64: base64File,
231
- fileName: "OnDemand_Report",
232
- replace: {
233
- title: "Report Title",
234
- },
235
- table: [
236
- {
237
- rows: [
238
- { item: "Item A", price: 100 },
239
- { item: "Item B", price: 200 },
240
- ],
241
- },
242
- ],
243
- });
244
- ```
245
-
246
- **C# (.NET)**
247
-
248
- ```csharp
249
- byte[] fileBytes = await File.ReadAllBytesAsync("template.docx");
250
-
251
- var request = new PdfFromFileRequest
252
- {
253
- FileBase64 = Convert.ToBase64String(fileBytes),
254
- FileName = "OnDemand_Report",
255
- Replace = new()
256
- {
257
- { "title", "Report Title" }
258
- },
259
- Table = new()
260
- {
261
- new()
262
- {
263
- Rows = new()
264
- {
265
- new Dictionary<string, object> { { "item", "Item A" }, { "price", 100 } },
266
- new Dictionary<string, object> { { "item", "Item B" }, { "price", 200 } }
267
- }
268
- }
269
- }
270
- };
271
-
272
- var response = await qorstackApi.PostRenderDocxPdfAsync(request);
273
- ```
274
-
275
- ---
276
-
277
- ## Data Binding Reference
278
-
279
- The Qorstack Report engine supports various data types. Here is how to structure your request object.
280
-
281
- ### Text Replacement (`replace`)
282
-
283
- Simple key-value pairs to replace text placeholders like `{{customerName}}`.
284
-
285
- ```json
286
- "replace": {
287
- "customerName": "Acme Corp",
288
- "totalAmount": "$1,050.00"
289
- }
290
- ```
291
-
292
- ### Tables (`table`)
293
-
294
- Populates rows in a table. The `rows` array contains objects where keys match the columns in your Word table.
295
-
296
- ```json
297
- "table": [
298
- {
299
- "rows": [
300
- { "name": "Value A", "last_name": "Value B" },
301
- { "name": "Value C", "last_name": "Value D" }
302
- ],
303
- "verticalMerge": ["category"],
304
- "collapse": ["description"]
305
- }
306
- ]
307
- ```
308
-
309
- ### Images (`image`)
310
-
311
- Replaces placeholders like `{{image:logo}}`. Supports URLs or Base64.
312
-
313
- - `src`: Image URL or Base64 string.
314
- - `width`, `height`: Optional dimensions in pixels.
315
- - `fit`: Optional ("contain", "cover", "fill").
316
-
317
- ```json
318
- "image": {
319
- "logo": {
320
- "src": "https://example.com/logo.png",
321
- "width": 150,
322
- "height": 50
323
- }
324
- }
325
- ```
326
-
327
- ### QR Codes (`qrcode`)
328
-
329
- Generates QR codes for placeholders like `{{qr:website}}`.
330
-
331
- ```json
332
- "qrcode": {
333
- "website": {
334
- "text": "https://qorstack.dev",
335
- "size": 200,
336
- "color": "#000000"
337
- }
338
- }
339
- ```
340
-
341
- ### Barcodes (`barcode`)
342
-
343
- Generates barcodes for placeholders like `{{barcode:productId}}`.
344
-
345
- - `format`: Default is "Code128".
346
-
347
- ```json
348
- "barcode": {
349
- "productId": {
350
- "text": "1234567890",
351
- "format": "Code128",
352
- "includeText": true
353
- }
354
- }
355
- ```
356
-
357
- ---
358
-
359
- ## Error Handling
360
-
361
- The SDK throws exceptions when the API returns an error (e.g., 400 Bad Request, 401 Unauthorized).
362
-
363
- - **Node.js**: The promise will reject with the error response.
364
- - **.NET**: `ApiException` or `ApiException<ProblemDetails>` will be thrown. You can access `ex.Result` to get detailed error messages from the server.
365
-
366
- ---
367
-
368
- ## License
369
-
370
- MIT License. See [LICENSE](LICENSE) for details.
1
+ # Qorstack Report SDK
2
+
3
+ The official SDK for **Qorstack Report** — a REST API for generating **PDF**, **DOCX**, and **XLSX** reports from Microsoft Word and Excel templates.
4
+ This SDK simplifies integration into your **Node.js** and **.NET** applications.
5
+
6
+ ## Features
7
+
8
+ - **Word template rendering** — generate PDF or DOCX from a stored DOCX template.
9
+ - **Excel template rendering** — generate XLSX (or PDF) from a stored XLSX template, with auto-filter, freeze header, table styles, and conditional formatting.
10
+ - **Sandbox rendering** — render a template using its configured sample payload (great for previews).
11
+ - **Render job history** — list and inspect past render jobs.
12
+ - **Rich data binding:**
13
+ - Text replacement
14
+ - Dynamic tables (with vertical merge / column collapse on Word; auto-filter / freeze / split-to-sheets on Excel)
15
+ - Images (URL or Base64)
16
+ - QR codes and barcodes
17
+ - **Pro features** *(requires Pro license on self-hosted, included on cloud Pro plans)*:
18
+ - PDF password protection
19
+ - PDF watermarking
20
+ - **Zip output** — bundle multiple output files into a `.zip`.
21
+ - **Cross-platform** — fully typed clients for TypeScript/Node.js and C#/.NET 8.0+.
22
+
23
+ ---
24
+
25
+ ## Installation
26
+
27
+ ### Node.js (TypeScript/JavaScript)
28
+
29
+ ```bash
30
+ npm install qorstack-report-sdk
31
+ # or
32
+ yarn add qorstack-report-sdk
33
+ ```
34
+
35
+ ### .NET (C#)
36
+
37
+ ```bash
38
+ dotnet add package Qorstack.Report.Sdk
39
+ ```
40
+
41
+ ---
42
+
43
+ ## Authentication
44
+
45
+ You need an **API Key** from the Qorstack Portal.
46
+
47
+ 1. Log in to the Qorstack Portal.
48
+ 2. Navigate to **Settings → API Keys**.
49
+ 3. Create a new API Key (scoped per project).
50
+
51
+ ---
52
+
53
+ ## Getting Started
54
+
55
+ ### Node.js Setup
56
+
57
+ ```typescript
58
+ import { QorstackApi } from "qorstack-report-sdk";
59
+
60
+ // Initialize the client with API Key
61
+ const qorstackApi = new QorstackApi({
62
+ securityData: {
63
+ headers: {
64
+ "X-API-KEY": "YOUR_API_KEY_HERE",
65
+ },
66
+ },
67
+ });
68
+
69
+ // OR: with custom Base URL (e.g. self-hosted instance)
70
+ const qorstackApiCustom = new QorstackApi({
71
+ baseUrl: "https://your-custom-url.com",
72
+ securityData: {
73
+ headers: {
74
+ "X-API-KEY": "YOUR_API_KEY_HERE",
75
+ },
76
+ },
77
+ });
78
+ ```
79
+
80
+ ### .NET Setup
81
+
82
+ ```csharp
83
+ using Qorstack.Report.Sdk;
84
+
85
+ // Initialize with API Key
86
+ var qorstackApi = new QorstackApi(apiKey: "YOUR_API_KEY_HERE");
87
+
88
+ // OR: with custom Base URL
89
+ var qorstackApiCustom = new QorstackApi("https://your-custom-url.com", "YOUR_API_KEY_HERE");
90
+ ```
91
+
92
+ ---
93
+
94
+ ## Usage Examples
95
+
96
+ ### 1. Render Word/PDF from template (`PdfFromTemplateRequest`)
97
+
98
+ Endpoint: `POST /render/word/template`
99
+ Method: `render.postRenderWordTemplate` (Node) / `PostRenderWordTemplateAsync` (.NET)
100
+
101
+ Use `fileType: "pdf"` (default) to get a PDF, or `"docx"` to get the rendered Word document.
102
+
103
+ #### Full feature example (text, table, image, QR, barcode)
104
+
105
+ ```typescript
106
+ // Node.js (TypeScript)
107
+ const tableRows = data.map((item, index) => ({
108
+ no: index + 1,
109
+ category: item.category,
110
+ description: item.description,
111
+ qty: item.quantity,
112
+ unit_price: item.price,
113
+ amount: item.total,
114
+ }));
115
+
116
+ const response = await qorstackApi.render.postRenderWordTemplate({
117
+ templateKey: "RENDOX-7326-758-974-2067",
118
+ fileName: "Full_Report_Example",
119
+ fileType: "pdf", // "pdf" | "docx"
120
+ replace: {
121
+ customer_name: "Example Company Ltd.",
122
+ document_date: new Date().toLocaleDateString("en-GB"),
123
+ total_amount: "1,500.00",
124
+ },
125
+ table: [
126
+ {
127
+ rows: tableRows,
128
+ verticalMerge: ["category"],
129
+ collapse: ["description"],
130
+ },
131
+ ],
132
+ image: {
133
+ header_logo: {
134
+ src: "https://example.com/logo.png",
135
+ width: 200,
136
+ fit: "contain",
137
+ },
138
+ },
139
+ qrcode: {
140
+ payment_qr: {
141
+ text: "https://payment.link/123456",
142
+ size: 150,
143
+ },
144
+ },
145
+ barcode: {
146
+ product_barcode: {
147
+ text: "PROD-123456789",
148
+ format: "Code128",
149
+ width: 300,
150
+ height: 80,
151
+ },
152
+ },
153
+ });
154
+
155
+ console.log("Download URL:", response.data.downloadUrl);
156
+ ```
157
+
158
+ ```csharp
159
+ // C# (.NET)
160
+ var data = await _exampleService.GetDataAsync(id);
161
+
162
+ var tableRows = data.Select((item, index) => new Dictionary<string, object>
163
+ {
164
+ { "no", index + 1 },
165
+ { "category", item.Category },
166
+ { "description", item.Description },
167
+ { "qty", item.Quantity },
168
+ { "unit_price", item.Price },
169
+ { "amount", item.Total }
170
+ }).ToList();
171
+
172
+ var request = new PdfFromTemplateRequest
173
+ {
174
+ TemplateKey = "RENDOX-7326-758-974-2067",
175
+ FileName = "Full_Report_Example",
176
+ FileType = "pdf",
177
+ Replace = new()
178
+ {
179
+ { "customer_name", "Example Company Ltd." },
180
+ { "document_date", DateTime.Now.ToString("dd/MM/yyyy") },
181
+ { "total_amount", "1,500.00" }
182
+ },
183
+ Table = new()
184
+ {
185
+ new()
186
+ {
187
+ Rows = tableRows,
188
+ VerticalMerge = new() { "category" },
189
+ Collapse = new() { "description" }
190
+ }
191
+ },
192
+ Image = new()
193
+ {
194
+ { "header_logo", new() { Src = "https://example.com/logo.png", Width = 200, Fit = "contain" } }
195
+ },
196
+ QrCode = new()
197
+ {
198
+ { "payment_qr", new() { Text = "https://payment.link/123456", Size = 150 } }
199
+ },
200
+ Barcode = new()
201
+ {
202
+ { "product_barcode", new() { Text = "PROD-123456789", Format = "Code128", Width = 300, Height = 80 } }
203
+ }
204
+ };
205
+
206
+ var response = await qorstackApi.PostRenderWordTemplateAsync(request);
207
+ Console.WriteLine($"Download URL: {response.DownloadUrl}");
208
+ ```
209
+
210
+ ---
211
+
212
+ ### 2. Render Excel from template (`ExcelFromTemplateRequest`)
213
+
214
+ Endpoint: `POST /render/excel/template`
215
+ Method: `render.postRenderExcelTemplate` (Node) / `PostRenderExcelTemplateAsync` (.NET)
216
+
217
+ ```typescript
218
+ // Node.js (TypeScript)
219
+ const response = await qorstackApi.render.postRenderExcelTemplate({
220
+ templateKey: "XLSX-1234-5678",
221
+ fileName: "Sales_Report_Q1",
222
+ replace: {
223
+ report_period: "Q1 2026",
224
+ generated_by: "Sales Team",
225
+ },
226
+ table: [
227
+ {
228
+ rows: [
229
+ { region: "North", product: "A", qty: 10, total: 1000 },
230
+ { region: "North", product: "B", qty: 5, total: 500 },
231
+ { region: "South", product: "A", qty: 8, total: 800 },
232
+ ],
233
+ autoFilter: true,
234
+ freezeHeader: true,
235
+ autoFitColumns: true,
236
+ asExcelTable: true,
237
+ excelTableStyle: "TableStyleMedium2",
238
+ generateTotals: { total: "sum", qty: "sum" },
239
+ numberFormat: { total: "#,##0.00" },
240
+ },
241
+ ],
242
+ });
243
+
244
+ console.log("Download URL:", response.data.downloadUrl);
245
+ ```
246
+
247
+ ```csharp
248
+ // C# (.NET)
249
+ var request = new ExcelFromTemplateRequest
250
+ {
251
+ TemplateKey = "XLSX-1234-5678",
252
+ FileName = "Sales_Report_Q1",
253
+ Replace = new()
254
+ {
255
+ { "report_period", "Q1 2026" },
256
+ { "generated_by", "Sales Team" }
257
+ },
258
+ Table = new()
259
+ {
260
+ new()
261
+ {
262
+ Rows = new()
263
+ {
264
+ new Dictionary<string, object> { { "region", "North" }, { "product", "A" }, { "qty", 10 }, { "total", 1000 } },
265
+ new Dictionary<string, object> { { "region", "North" }, { "product", "B" }, { "qty", 5 }, { "total", 500 } },
266
+ new Dictionary<string, object> { { "region", "South" }, { "product", "A" }, { "qty", 8 }, { "total", 800 } }
267
+ },
268
+ AutoFilter = true,
269
+ FreezeHeader = true,
270
+ AutoFitColumns = true,
271
+ AsExcelTable = true,
272
+ ExcelTableStyle = "TableStyleMedium2",
273
+ GenerateTotals = new() { { "total", "sum" }, { "qty", "sum" } },
274
+ NumberFormat = new() { { "total", "#,##0.00" } }
275
+ }
276
+ }
277
+ };
278
+
279
+ var response = await qorstackApi.PostRenderExcelTemplateAsync(request);
280
+ ```
281
+
282
+ ---
283
+
284
+ ### 3. PDF password protection *(Pro)*
285
+
286
+ ```typescript
287
+ const response = await qorstackApi.render.postRenderWordTemplate({
288
+ templateKey: "RENDOX-7326-758-974-2067",
289
+ fileName: "Confidential_Report",
290
+ fileType: "pdf",
291
+ pdfPassword: {
292
+ userPassword: "open-me",
293
+ ownerPassword: "owner-secret",
294
+ restrictPrinting: true,
295
+ restrictCopying: true,
296
+ restrictModifying: true,
297
+ },
298
+ });
299
+ ```
300
+
301
+ ---
302
+
303
+ ### 4. PDF watermark *(Pro)*
304
+
305
+ ```typescript
306
+ const response = await qorstackApi.render.postRenderWordTemplate({
307
+ templateKey: "RENDOX-7326-758-974-2067",
308
+ fileName: "Draft_Report",
309
+ fileType: "pdf",
310
+ watermark: {
311
+ text: "DRAFT",
312
+ fontSize: 72,
313
+ fontFamily: "Arial",
314
+ },
315
+ });
316
+ ```
317
+
318
+ ---
319
+
320
+ ### 5. Sandbox render (preview using template's sample payload)
321
+
322
+ Endpoint: `POST /render/word/template-sandbox/{templateKey}`
323
+ Useful for previewing a template without supplying real data.
324
+
325
+ ```typescript
326
+ const response = await qorstackApi.render.postRenderWordTemplateSandbox(
327
+ "RENDOX-7326-758-974-2067",
328
+ { fileName: "Preview" },
329
+ /* body */ null, // or a JSON object to override the sandbox payload
330
+ );
331
+ ```
332
+
333
+ ---
334
+
335
+ ### 6. Inspect render jobs
336
+
337
+ ```typescript
338
+ // List jobs
339
+ const jobs = await qorstackApi.render.getRenderJobs({
340
+ page: 1,
341
+ pageSize: 20,
342
+ // templateKey: "...", status: "Success" | "Failed" | "Pending"
343
+ });
344
+
345
+ // Get one
346
+ const job = await qorstackApi.render.getRenderJobById("job-id-here");
347
+ ```
348
+
349
+ ---
350
+
351
+ ## Data Binding Reference
352
+
353
+ ### Text replacement (`replace`)
354
+
355
+ Replaces `{{variable}}` placeholders with strings.
356
+
357
+ ```json
358
+ "replace": {
359
+ "customerName": "Acme Corp",
360
+ "totalAmount": "$1,050.00"
361
+ }
362
+ ```
363
+
364
+ ### Word table (`table` — `WordTableDataRequest[]`)
365
+
366
+ ```json
367
+ "table": [
368
+ {
369
+ "rows": [
370
+ { "name": "Value A", "last_name": "Value B" },
371
+ { "name": "Value C", "last_name": "Value D" }
372
+ ],
373
+ "verticalMerge": ["category"],
374
+ "collapse": ["description"]
375
+ }
376
+ ]
377
+ ```
378
+
379
+ | Field | Description |
380
+ | --- | --- |
381
+ | `rows` | Array of row objects. Keys match column placeholders. |
382
+ | `verticalMerge` | Columns whose adjacent identical values are merged vertically. |
383
+ | `collapse` | Columns whose empty/duplicate values collapse to keep layout tidy. |
384
+
385
+ ### Excel table (`table` — `ExcelTableDataRequest[]`)
386
+
387
+ ```json
388
+ "table": [
389
+ {
390
+ "rows": [{ "region": "North", "qty": 10 }],
391
+ "autoFilter": true,
392
+ "freezeHeader": true,
393
+ "autoFitColumns": true,
394
+ "asExcelTable": true,
395
+ "excelTableStyle": "TableStyleMedium2",
396
+ "generateTotals": { "qty": "sum" },
397
+ "numberFormat": { "qty": "#,##0" }
398
+ }
399
+ ]
400
+ ```
401
+
402
+ | Field | Description |
403
+ | --- | --- |
404
+ | `autoFilter` | Enable Excel auto-filter on the header row. |
405
+ | `freezeHeader` | Freeze the header row. |
406
+ | `autoFitColumns` | Auto-fit column widths to content. |
407
+ | `asExcelTable` / `excelTableStyle` | Render as native Excel table with style. |
408
+ | `generateTotals` | Per-column aggregation (`sum`, `avg`, `count`, `min`, `max`). |
409
+ | `numberFormat` | Excel number format string per column. |
410
+ | `conditionalFormat` | Conditional formatting rules. |
411
+ | `splitToSheets` | Split rows into multiple sheets by a column value. |
412
+ | `sort` | Sort rows before render. |
413
+
414
+ ### Images (`image`)
415
+
416
+ Replaces `{{image:logo}}`. Accepts URL or Base64.
417
+
418
+ ```json
419
+ "image": {
420
+ "logo": {
421
+ "src": "https://example.com/logo.png",
422
+ "width": 150,
423
+ "height": 50,
424
+ "fit": "contain"
425
+ }
426
+ }
427
+ ```
428
+
429
+ ### QR codes (`qrcode`)
430
+
431
+ Replaces `{{qr:website}}`.
432
+
433
+ ```json
434
+ "qrcode": {
435
+ "website": {
436
+ "text": "https://qorstack.dev",
437
+ "size": 200,
438
+ "color": "#000000"
439
+ }
440
+ }
441
+ ```
442
+
443
+ ### Barcodes (`barcode`)
444
+
445
+ Replaces `{{barcode:productId}}`. Default format: `Code128`.
446
+
447
+ ```json
448
+ "barcode": {
449
+ "productId": {
450
+ "text": "1234567890",
451
+ "format": "Code128",
452
+ "includeText": true,
453
+ "width": 300,
454
+ "height": 80
455
+ }
456
+ }
457
+ ```
458
+
459
+ ### Output options
460
+
461
+ | Field | Type | Description |
462
+ | --- | --- | --- |
463
+ | `fileName` | string | Output file name (without extension). |
464
+ | `fileType` | string | Word only: `"pdf"` (default) or `"docx"`. |
465
+ | `zipOutput` | boolean | If `true`, bundle the output into a `.zip` archive. |
466
+ | `pdfPassword` | object | *(Pro)* Encrypt the PDF and set permissions. |
467
+ | `watermark` | object | *(Pro)* Apply a text watermark to the PDF. |
468
+
469
+ ---
470
+
471
+ ## Response shape
472
+
473
+ All render endpoints return a download URL plus metadata:
474
+
475
+ ```jsonc
476
+ {
477
+ "downloadUrl": "https://.../output.pdf",
478
+ "fileName": "Full_Report_Example.pdf",
479
+ "fileSize": 102400,
480
+ "fileType": "pdf",
481
+ "status": "Success",
482
+ "isZipped": false
483
+ }
484
+ ```
485
+
486
+ ---
487
+
488
+ ## Error Handling
489
+
490
+ The SDK throws when the API returns 4xx/5xx (`ProblemDetails` payload).
491
+
492
+ - **Node.js** — the promise rejects; `error.error` contains the `ProblemDetails` body.
493
+ - **.NET** — `ApiException<ProblemDetails>` is thrown; access `ex.Result` for the body.
494
+
495
+ ---
496
+
497
+ ## License
498
+
499
+ MIT License. See [LICENSE](LICENSE) for details.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qorstack-report-sdk",
3
- "version": "0.0.1",
3
+ "version": "0.1.1",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [
@@ -11,8 +11,8 @@
11
11
  "prebuild": "yarn sync-config",
12
12
  "build": "tsc",
13
13
  "test": "echo \"Error: no test specified\" && exit 1",
14
- "gen:nodejs": "swagger-typescript-api generate -p ./src/qorstack-swagger.json -o ./src/nodejs --name QorstackApi.ts",
15
- "gen:dotnet": "nswag openapi2csclient /input:src/qorstack-swagger.json /output:src/dotnet/QorstackApi.cs /namespace:Qorstack.Report.Sdk /ClassName:QorstackApi",
14
+ "gen:nodejs": "swagger-typescript-api generate -p ../backend/swagger-sdk.json -o ./src/nodejs --name QorstackApi.ts",
15
+ "gen:dotnet": "nswag openapi2csclient /input:../backend/swagger-sdk.json /output:src/dotnet/QorstackApi.cs /namespace:Qorstack.Report.Sdk /ClassName:QorstackApi",
16
16
  "gen:all": "yarn gen:nodejs && yarn gen:dotnet"
17
17
  },
18
18
  "keywords": [