tally-xml-tdl 1.4.1 → 1.6.2

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 (92) hide show
  1. package/README.md +175 -95
  2. package/index.d.ts +10 -84
  3. package/package.json +9 -26
  4. package/src/index.js +2 -5
  5. package/src/v6/body.json +26 -0
  6. package/src/v6/body.xml +25 -0
  7. package/src/v6/core/buildXml.js +9 -0
  8. package/src/v6/core/cleanTallyResponse.js +57 -0
  9. package/src/{v4 → v6}/core/execute/executeXml.js +3 -2
  10. package/src/v6/core/execute/executeXmlAndClean.js +15 -0
  11. package/src/v6/core/execute/index.js +3 -0
  12. package/src/v6/core/index.js +20 -0
  13. package/src/v6/core/response/index.js +2 -0
  14. package/src/v6/index.d.ts +8 -0
  15. package/src/v6/index.js +44 -0
  16. package/src/v1/client.js +0 -59
  17. package/src/v1/envelope.js +0 -87
  18. package/src/v1/index.d.ts +0 -65
  19. package/src/v1/index.js +0 -12
  20. package/src/v1/jsonToXml.js +0 -20
  21. package/src/v1/xmlToJson.js +0 -19
  22. package/src/v2/client.js +0 -59
  23. package/src/v2/envelope.js +0 -87
  24. package/src/v2/index.d.ts +0 -65
  25. package/src/v2/index.js +0 -12
  26. package/src/v2/jsonToXml.js +0 -20
  27. package/src/v2/xmlToJson.js +0 -19
  28. package/src/v3/client.js +0 -105
  29. package/src/v3/envelope.js +0 -87
  30. package/src/v3/index.d.ts +0 -78
  31. package/src/v3/index.js +0 -14
  32. package/src/v3/jsonToXml.js +0 -20
  33. package/src/v3/xmlToJson.js +0 -19
  34. package/src/v4/company/body.json +0 -7
  35. package/src/v4/company/index.js +0 -12
  36. package/src/v4/core/execute/executeBody.js +0 -48
  37. package/src/v4/core/execute/fetchCollection.js +0 -35
  38. package/src/v4/core/execute/index.js +0 -4
  39. package/src/v4/core/index.js +0 -31
  40. package/src/v4/core/request/envelope.js +0 -86
  41. package/src/v4/core/request/index.js +0 -6
  42. package/src/v4/core/request/jsonToXml.js +0 -19
  43. package/src/v4/core/response/extract.js +0 -17
  44. package/src/v4/core/response/index.js +0 -4
  45. package/src/v4/core/response/validate.js +0 -20
  46. package/src/v4/import/index.js +0 -7
  47. package/src/v4/import/transaction/index.js +0 -10
  48. package/src/v4/import/transaction/last/body.xml +0 -34
  49. package/src/v4/import/transaction/last/index.js +0 -12
  50. package/src/v4/import/transaction/sales/body.xml +0 -50
  51. package/src/v4/import/transaction/sales/index.js +0 -12
  52. package/src/v4/index.d.ts +0 -132
  53. package/src/v4/index.js +0 -15
  54. package/src/v4/masters/accounting/currency/body.json +0 -10
  55. package/src/v4/masters/accounting/currency/index.js +0 -12
  56. package/src/v4/masters/accounting/group/body.json +0 -8
  57. package/src/v4/masters/accounting/group/index.js +0 -12
  58. package/src/v4/masters/accounting/index.js +0 -16
  59. package/src/v4/masters/accounting/ledger/body.json +0 -8
  60. package/src/v4/masters/accounting/ledger/index.js +0 -12
  61. package/src/v4/masters/accounting/voucherTypes/body.json +0 -11
  62. package/src/v4/masters/accounting/voucherTypes/index.js +0 -12
  63. package/src/v4/masters/index.js +0 -10
  64. package/src/v4/masters/inventory/batch/body.json +0 -26
  65. package/src/v4/masters/inventory/batch/index.js +0 -12
  66. package/src/v4/masters/inventory/godown/body.json +0 -8
  67. package/src/v4/masters/inventory/godown/index.js +0 -12
  68. package/src/v4/masters/inventory/index.js +0 -19
  69. package/src/v4/masters/inventory/stockCategory/body.json +0 -8
  70. package/src/v4/masters/inventory/stockCategory/index.js +0 -12
  71. package/src/v4/masters/inventory/stockItems/body copy.json +0 -8
  72. package/src/v4/masters/inventory/stockItems/body.json +0 -26
  73. package/src/v4/masters/inventory/stockItems/index.js +0 -12
  74. package/src/v4/masters/inventory/uom/body.json +0 -13
  75. package/src/v4/masters/inventory/uom/index.js +0 -12
  76. package/src/v4/reports/index.js +0 -7
  77. package/src/v4/reports/inventory/index.js +0 -7
  78. package/src/v4/reports/inventory/stockItems/body copy 2.json +0 -34
  79. package/src/v4/reports/inventory/stockItems/body copy.json +0 -26
  80. package/src/v4/reports/inventory/stockItems/body.json +0 -34
  81. package/src/v4/reports/inventory/stockItems/index.js +0 -12
  82. package/src/v4/transactions/index.js +0 -15
  83. package/src/v4/transactions/purchase/body.json +0 -36
  84. package/src/v4/transactions/purchase/index.js +0 -12
  85. package/src/v4/transactions/sale/body copy.json +0 -36
  86. package/src/v4/transactions/sale/body.json +0 -40
  87. package/src/v4/transactions/sale/index.js +0 -12
  88. package/src/v4/transactions/stockJournal/body.json +0 -40
  89. package/src/v4/transactions/stockJournal/index.js +0 -12
  90. /package/src/{v4 → v6}/core/response/xmlToJson.js +0 -0
  91. /package/src/{v4 → v6}/core/transport/http.js +0 -0
  92. /package/src/{v4 → v6}/core/transport/index.js +0 -0
package/README.md CHANGED
@@ -1,95 +1,175 @@
1
- # KeshavSoft
2
-
3
- Simple tools. Clean architecture. Fast development.
4
-
5
- ---
6
-
7
- ## @keshavsoft/kschema
8
-
9
- A lightweight schema-driven JSON database for Node.js.
10
-
11
- ---
12
-
13
- ## Install
14
-
15
- npm i @keshavsoft/kschema
16
-
17
- ---
18
-
19
- ## Usage
20
-
21
- import { kschema } from "@keshavsoft/kschema";
22
-
23
- kschema.loadConfig({ dataPath: "./data" });
24
-
25
- const users = kschema.table("users");
26
-
27
- users.insert({ name: "keshav" });
28
-
29
- const data = users.get();
30
-
31
- console.log(data);
32
-
33
- ---
34
-
35
- ## API
36
-
37
- Create
38
-
39
- users.insert(record);
40
- users.insertStrict(record);
41
-
42
- Read
43
-
44
- users.get();
45
- users.findByPk(id);
46
-
47
- Filter
48
-
49
- users.filterByPk(id);
50
- users.filterByColumns({ name: "keshav" });
51
-
52
- Update
53
-
54
- users.update(record);
55
-
56
- Delete
57
-
58
- users.delete(id);
59
- users.deleteByColumns({ name: "keshav" });
60
-
61
- ---
62
-
63
- ## Features
64
-
65
- * File-based JSON storage
66
- * Schema-driven design
67
- * Auto primary key
68
- * Simple CRUD API
69
- * Zero dependencies
70
-
71
- ---
72
-
73
- ## Links
74
-
75
- GitHub: https://github.com/keshavsoft/kschema
76
- NPM: https://www.npmjs.com/package/@keshavsoft/kschema
77
- Website: https://keshavsoft.com
78
-
79
- ---
80
-
81
- ## Contact
82
-
83
- Email: founder@keshavsoft.com
84
-
85
- ---
86
-
87
- ## About
88
-
89
- KeshavSoft builds simple and practical developer tools focused on clarity, speed, and real-world usage.
90
-
91
- ---
92
-
93
- ## License
94
-
95
- MIT License — see LICENSE file
1
+ # tally-xml-tdl
2
+
3
+ > Simple, clean TDL and XML extraction and manipulation tools for Tally.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/tally-xml-tdl.svg)](https://www.npmjs.com/package/tally-xml-tdl)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ Extract data directly from **Tally Prime / Tally.ERP 9** using TDL XML requests over HTTP, and get back **clean, developer-friendly JSON** ready for modern web apps, APIs, dashboards, and databases.
9
+
10
+ ---
11
+
12
+ ## 📖 The Story
13
+
14
+ Interfacing with Tally usually means dealing with complex, deeply nested XML envelopes, verbose TDL message syntax, and responses filled with XML parser artifacts (`@_RESERVEDNAME`, `#text`, `@_TYPE`, etc.):
15
+
16
+ ```json
17
+ // Traditional Tally XML-to-JSON response (cluttered & nested):
18
+ {
19
+ "ENVELOPE": {
20
+ "BODY": {
21
+ "DATA": {
22
+ "COLLECTION": {
23
+ "UNIT": [
24
+ {
25
+ "@_NAME": "Kgs",
26
+ "@_RESERVEDNAME": "",
27
+ "NAME": { "#text": "Kgs", "@_TYPE": "String" }
28
+ }
29
+ ]
30
+ }
31
+ }
32
+ }
33
+ }
34
+ }
35
+ ```
36
+
37
+ **`tally-xml-tdl` changes that.** With version **`v6`**, it introduces a streamlined template-driven engine and two simple functions:
38
+
39
+ - **`clean()`**: Strips all XML noise, flattens text nodes, removes reserved attributes, and returns plain JavaScript objects or arrays.
40
+ - **`get()`**: Returns the full XML-to-JSON parsed object when you need raw envelope fidelity.
41
+
42
+ ```json
43
+ // With tally-xml-tdl clean():
44
+ [
45
+ "Kgs"
46
+ ]
47
+ ```
48
+
49
+ ---
50
+
51
+ ## 🚀 Features
52
+
53
+ - 🧹 **Clean Data Out-of-the-Box**: Automatically strips Tally metadata attributes and flattens nested values.
54
+ - ⚡ **Two Extraction Modes**: Choose `clean()` for clean data arrays, or `get()` for the full parsed envelope.
55
+ - 📋 **Pre-configured Queries**: Built-in TDL queries for UOM, Stock Items, Stock Items with Base Units, and Ledgers.
56
+ - 🏎️ **Fast & Lightweight**: Built on top of `fast-xml-parser` with minimal overhead.
57
+ - 📦 **Zero-Config HTTP Transport**: Communicates directly with Tally's built-in HTTP server (`http://localhost:9000`).
58
+ - 🔷 **First-Class TypeScript Support**: Full type declarations included (`.d.ts`).
59
+ - 🌐 **Modern ESM**: Native ES modules with subpath exports (`tally-xml-tdl` and `tally-xml-tdl/v6`).
60
+
61
+ ---
62
+
63
+ ## 📦 Installation
64
+
65
+ ```bash
66
+ npm install tally-xml-tdl
67
+ ```
68
+
69
+ ### Prerequisites
70
+ Make sure Tally is running and its HTTP server is enabled:
71
+ - **Tally Prime / Tally.ERP 9**: Press `F12` (Configure) -> **Advanced Configuration** -> Set **Tally is acting as** to `Both` or `Server`, and note the port (default is `9000`).
72
+
73
+ ---
74
+
75
+ ## 💡 Quick Start
76
+
77
+ ```javascript
78
+ import { clean, get } from "tally-xml-tdl";
79
+
80
+ // 1. Fetch clean, simplified data
81
+ const items = await clean({
82
+ company: "My Company Name",
83
+ jsonId: "stockItemsWithBaseUnits"
84
+ });
85
+
86
+ console.log(items);
87
+ // Output:
88
+ // [
89
+ // { NAME: "Item A", BASEUNITS: "Nos" },
90
+ // { NAME: "Item B", BASEUNITS: "Kgs" }
91
+ // ]
92
+
93
+ // 2. Fetch raw parsed JSON (full fidelity)
94
+ const raw = await get({
95
+ company: "My Company Name",
96
+ jsonId: "uom"
97
+ });
98
+
99
+ console.log(raw);
100
+ ```
101
+
102
+ ---
103
+
104
+ ## 📚 API Reference
105
+
106
+ ### `clean(options)`
107
+ Sends the TDL query to Tally, parses the XML response, and cleans the resulting collection data.
108
+
109
+ ```typescript
110
+ clean<T = any>(options: V6Options): Promise<T>
111
+ ```
112
+
113
+ #### Options:
114
+ | Option | Type | Required | Default | Description |
115
+ | :--- | :--- | :---: | :--- | :--- |
116
+ | `company` | `string` | **Yes** | — | Name of the active company in Tally. |
117
+ | `jsonId` | `string` | **Yes** | — | ID of the pre-configured TDL query. |
118
+ | `url` | `string` | No | `"http://localhost:9000"` | Tally HTTP endpoint URL. |
119
+
120
+ ---
121
+
122
+ ### `get(options)`
123
+ Sends the TDL query to Tally and returns the complete XML response converted to a JavaScript object without stripping any metadata.
124
+
125
+ ```typescript
126
+ get<T = any>(options: V6Options): Promise<T>
127
+ ```
128
+
129
+ ---
130
+
131
+ ## 🗂️ Built-in Query Catalog (`jsonId`)
132
+
133
+ | `jsonId` | Target Entity | Description | Fields Fetched |
134
+ | :--- | :--- | :--- | :--- |
135
+ | `"uom"` | Units of Measure | List of units of measurement | `$$Alias:Name` |
136
+ | `"stockItems"` | Stock Items | List of inventory stock items | `$$Alias:Name` |
137
+ | `"stockItemsWithBaseUnits"` | Stock Items | Inventory stock items with their base units | `$$Alias:Name`, `BaseUnits` |
138
+ | `"ledgerNames"` | Ledgers | List of accounting ledgers | `$$Alias:Name` |
139
+
140
+ ---
141
+
142
+ ## 🎯 Advanced Usage
143
+
144
+ ### Connecting to a Remote or Custom Port
145
+ If Tally is hosted on another machine or running on a non-default port:
146
+
147
+ ```javascript
148
+ import { clean } from "tally-xml-tdl";
149
+
150
+ const data = await clean({
151
+ company: "Acme Corp",
152
+ jsonId: "ledgerNames",
153
+ url: "http://192.168.1.100:9005"
154
+ });
155
+ ```
156
+
157
+ ### Subpath Import
158
+ You can also explicitly import from the `v6` subpath:
159
+
160
+ ```javascript
161
+ import { clean, get } from "tally-xml-tdl/v6";
162
+ ```
163
+
164
+ ### Using Namespaces
165
+ ```javascript
166
+ import { v6 } from "tally-xml-tdl";
167
+
168
+ const data = await v6.clean({ company: "Acme Corp", jsonId: "uom" });
169
+ ```
170
+
171
+ ---
172
+
173
+ ## 📄 License
174
+
175
+ [MIT](LICENSE) © [KeshavSoft](https://keshavsoft.com)
package/index.d.ts CHANGED
@@ -1,84 +1,10 @@
1
- /**
2
- * Converts an XML string into a JavaScript object.
3
- * Attributes are prefixed with '@_'.
4
- */
5
- export function xmlToJson<T = any>(xml: string, options?: Record<string, any>): T;
6
-
7
- /**
8
- * Converts a JavaScript object into a formatted XML string.
9
- */
10
- export function jsonToXml(jsonObj: Record<string, any>, options?: Record<string, any>): string;
11
-
12
- export interface CreateEnvelopeOptions {
13
- id?: string;
14
- type?: string;
15
- staticVariables?: Record<string, any>;
16
- tdlMessage?: Record<string, any>;
17
- }
18
-
19
- /**
20
- * Creates a base Tally XML Envelope JavaScript Object.
21
- */
22
- export function createEnvelope(options?: CreateEnvelopeOptions): Record<string, any>;
23
-
24
- export interface CreateCollectionEnvelopeOptions {
25
- name: string;
26
- type: string;
27
- fields?: string | string[];
28
- filters?: Record<string, any>;
29
- staticVariables?: Record<string, any>;
30
- }
31
-
32
- /**
33
- * Creates a Tally Collection Request Envelope object.
34
- */
35
- export function createCollectionEnvelope(options: CreateCollectionEnvelopeOptions): Record<string, any>;
36
-
37
- /**
38
- * Directly builds a Tally XML string for a collection request.
39
- */
40
- export function buildCollectionXml(options: CreateCollectionEnvelopeOptions): string;
41
-
42
- export interface SendToTallyOptions {
43
- xml: string;
44
- url?: string;
45
- }
46
-
47
- /**
48
- * Sends an XML payload to Tally via HTTP POST and returns parsed JSON response.
49
- */
50
- export function sendToTally<T = any>(options: SendToTallyOptions): Promise<T>;
51
-
52
- export interface FetchCollectionOptions {
53
- name: string;
54
- type: string;
55
- fields?: string | string[];
56
- filters?: Record<string, any>;
57
- staticVariables?: Record<string, any>;
58
- url?: string;
59
- }
60
-
61
- /**
62
- * High-level helper to fetch any Tally collection directly.
63
- */
64
- export function fetchCollection<T = any>(options: FetchCollectionOptions): Promise<T>;
65
-
66
- export interface ExecuteBodyOptions {
67
- full?: boolean;
68
- url?: string;
69
- }
70
-
71
- /**
72
- * Executes a Tally request from a JSON body (either envelope or collection definition).
73
- * If options.full is false (default), returns only the children of DATA.COLLECTION on success.
74
- * If options.full is true, returns the raw full ENVELOPE JSON response.
75
- */
76
- export function executeBody<T = any>(body: Record<string, any>, options?: ExecuteBodyOptions): Promise<T>;
77
-
78
- export * as v1 from "./src/v1/index.js";
79
- export * as v2 from "./src/v2/index.js";
80
- export * as v3 from "./src/v3/index.js";
81
- export * as v4 from "./src/v4/index.js";
82
-
83
-
84
-
1
+ export interface V6Options {
2
+ company: string;
3
+ jsonId: string;
4
+ url?: string;
5
+ }
6
+
7
+ export function get<T = any>(options?: V6Options): Promise<T>;
8
+ export function clean<T = any>(options?: V6Options): Promise<T>;
9
+
10
+ export * as v6 from "./src/v6/index.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tally-xml-tdl",
3
- "version": "1.4.1",
3
+ "version": "1.6.2",
4
4
  "description": "Simple, clean TDL and XML extraction and manipulation tools for Tally",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -12,30 +12,15 @@
12
12
  "import": "./index.js",
13
13
  "default": "./index.js"
14
14
  },
15
- "./v1": {
16
- "types": "./src/v1/index.d.ts",
17
- "import": "./src/v1/index.js",
18
- "default": "./src/v1/index.js"
19
- },
20
- "./v2": {
21
- "types": "./src/v2/index.d.ts",
22
- "import": "./src/v2/index.js",
23
- "default": "./src/v2/index.js"
24
- },
25
- "./v3": {
26
- "types": "./src/v3/index.d.ts",
27
- "import": "./src/v3/index.js",
28
- "default": "./src/v3/index.js"
29
- },
30
- "./v4": {
31
- "types": "./src/v4/index.d.ts",
32
- "import": "./src/v4/index.js",
33
- "default": "./src/v4/index.js"
34
- },
35
- "./*": "./src/*.js"
15
+ "./v6": {
16
+ "types": "./src/v6/index.d.ts",
17
+ "import": "./src/v6/index.js",
18
+ "default": "./src/v6/index.js"
19
+ }
36
20
  },
37
21
  "files": [
38
- "src",
22
+ "src/v6",
23
+ "src/index.js",
39
24
  "index.js",
40
25
  "index.d.ts",
41
26
  "README.md",
@@ -50,8 +35,6 @@
50
35
  "url": "https://github.com/keshavsoft/tally-xml-tdl/issues"
51
36
  },
52
37
  "dependencies": {
53
- "fast-xml-parser": "^5.11.1",
54
- "stream-chain": "^4.2.5",
55
- "stream-json": "^3.6.0"
38
+ "fast-xml-parser": "^5.11.1"
56
39
  }
57
40
  }
package/src/index.js CHANGED
@@ -1,5 +1,2 @@
1
- export * from "./v4/index.js";
2
- export * as v1 from "./v1/index.js";
3
- export * as v2 from "./v2/index.js";
4
- export * as v3 from "./v3/index.js";
5
- export * as v4 from "./v4/index.js";
1
+ export * from "./v6/index.js";
2
+ export * as v6 from "./v6/index.js";
@@ -0,0 +1,26 @@
1
+ {
2
+ "uom": {
3
+ "staticVariables": "<SVEXPORTFORMAT>$$SysName:XML</SVEXPORTFORMAT>",
4
+ "tdlMessage": "<TYPE>Unit</TYPE><FETCH>$$Alias:Name</FETCH>"
5
+ },
6
+ "stockItems": {
7
+ "staticVariables": "<SVEXPORTFORMAT>$$SysName:XML</SVEXPORTFORMAT>",
8
+ "tdlMessage": "<TYPE>StockItem</TYPE><FETCH>$$Alias:Name</FETCH>"
9
+ },
10
+ "stockItemsWithBaseUnits": {
11
+ "staticVariables": "<SVEXPORTFORMAT>$$SysName:XML</SVEXPORTFORMAT>",
12
+ "tdlMessage": "<TYPE>StockItem</TYPE><FETCH>$$Alias:Name</FETCH><FETCH>BaseUnits</FETCH>"
13
+ },
14
+ "ledgerNames": {
15
+ "staticVariables": "<SVEXPORTFORMAT>$$SysName:XML</SVEXPORTFORMAT>",
16
+ "tdlMessage": "<TYPE>Ledger</TYPE><FETCH>$$Alias:Name</FETCH>"
17
+ },
18
+ "stockGroups": {
19
+ "staticVariables": "<SVEXPORTFORMAT>$$SysName:XML</SVEXPORTFORMAT>",
20
+ "tdlMessage": "<TYPE>StockGroup</TYPE><FETCH>$$Alias:Name</FETCH>"
21
+ },
22
+ "stockGroupsAndParent": {
23
+ "staticVariables": "<SVEXPORTFORMAT>$$SysName:XML</SVEXPORTFORMAT>",
24
+ "tdlMessage": "<TYPE>StockGroup</TYPE><FETCH>$$Alias:Name</FETCH><FETCH>Parent</FETCH>"
25
+ }
26
+ }
@@ -0,0 +1,25 @@
1
+ <ENVELOPE>
2
+ <HEADER>
3
+ <VERSION>1</VERSION>
4
+ <TALLYREQUEST>Export</TALLYREQUEST>
5
+ <TYPE>Collection</TYPE>
6
+ <ID>TDLID</ID>
7
+ </HEADER>
8
+
9
+ <BODY>
10
+ <DESC>
11
+ <STATICVARIABLES>
12
+ <SVEXPORTFORMAT>$$SysName:XML</SVEXPORTFORMAT>
13
+ {{STATICVARIABLES}}
14
+ </STATICVARIABLES>
15
+
16
+ <TDL>
17
+ <TDLMESSAGE>
18
+ <COLLECTION NAME="TDLID">
19
+ {{TDLMESSAGE}}
20
+ </COLLECTION>
21
+ </TDLMESSAGE>
22
+ </TDL>
23
+ </DESC>
24
+ </BODY>
25
+ </ENVELOPE>
@@ -0,0 +1,9 @@
1
+ export const buildXml = (body, {
2
+ staticVariables,
3
+ tdlMessage
4
+ }) => {
5
+
6
+ return body
7
+ .replace("{{STATICVARIABLES}}", staticVariables)
8
+ .replace("{{TDLMESSAGE}}", tdlMessage);
9
+ };
@@ -0,0 +1,57 @@
1
+ export const cleanTallyResponse = (json) => {
2
+
3
+ const collection = json?.ENVELOPE?.BODY?.DATA?.COLLECTION;
4
+
5
+ if (!collection) {
6
+ return [];
7
+ }
8
+
9
+ const key = Object.keys(collection).find(
10
+ key => Array.isArray(collection[key])
11
+ );
12
+
13
+ if (!key) {
14
+ return [];
15
+ }
16
+
17
+ const rows = collection[key];
18
+
19
+ return rows.map(row => {
20
+
21
+ const result = {};
22
+
23
+ for (const [key, value] of Object.entries(row)) {
24
+
25
+ // Remove Tally/XML metadata
26
+ if (key === "@_RESERVEDNAME") {
27
+ continue;
28
+ }
29
+
30
+ // Keep NAME simple
31
+ if (key === "@_NAME") {
32
+ result.NAME = value;
33
+ continue;
34
+ }
35
+
36
+ // Handle XML parser objects like:
37
+ // { "#text": "kgs", "@_TYPE": "String" }
38
+ if (
39
+ value &&
40
+ typeof value === "object" &&
41
+ "#text" in value
42
+ ) {
43
+ result[key] = value["#text"];
44
+ continue;
45
+ }
46
+
47
+ result[key] = value;
48
+ }
49
+
50
+ // If only NAME exists, return the NAME itself
51
+ if (Object.keys(result).length === 1 && result.NAME !== undefined) {
52
+ return result.NAME;
53
+ }
54
+
55
+ return result;
56
+ });
57
+ };
@@ -1,5 +1,4 @@
1
1
  // src/v4/core/execute/executeXml.js
2
-
3
2
  import { sendXml } from "../transport/http.js";
4
3
  import { xmlToJson } from "../response/xmlToJson.js";
5
4
 
@@ -9,5 +8,7 @@ export const executeXml = async (
9
8
  ) => {
10
9
  const rawXml = await sendXml({ xml, url });
11
10
 
12
- return xmlToJson(rawXml);
11
+ const json = xmlToJson(rawXml);
12
+
13
+ return json;
13
14
  };
@@ -0,0 +1,15 @@
1
+ // src/v4/core/execute/executeXml.js
2
+ import { cleanTallyResponse } from "../cleanTallyResponse.js";
3
+ import { sendXml } from "../transport/http.js";
4
+ import { xmlToJson } from "../response/xmlToJson.js";
5
+
6
+ export const executeXmlAndClean = async (
7
+ xml,
8
+ { url = "http://localhost:9000" } = {}
9
+ ) => {
10
+ const rawXml = await sendXml({ xml, url });
11
+
12
+ const json = xmlToJson(rawXml);
13
+
14
+ return cleanTallyResponse(json);
15
+ };
@@ -0,0 +1,3 @@
1
+ export { executeXml } from "./executeXml.js";
2
+ export { executeXmlAndClean } from "./executeXmlAndClean.js";
3
+
@@ -0,0 +1,20 @@
1
+ // Sub-modules
2
+ export * as transport from "./transport/index.js";
3
+ export * as response from "./response/index.js";
4
+ export * as execute from "./execute/index.js";
5
+
6
+ // Direct Core Exports
7
+ export {
8
+ sendXml,
9
+ sendToTally
10
+ } from "./transport/index.js";
11
+
12
+ export {
13
+ xmlToJson
14
+ } from "./response/index.js";
15
+
16
+ export {
17
+ executeXml,
18
+ executeXmlAndClean
19
+ } from "./execute/index.js";
20
+
@@ -0,0 +1,2 @@
1
+ export { xmlToJson } from "./xmlToJson.js";
2
+
@@ -0,0 +1,8 @@
1
+ export interface V6Options {
2
+ company: string;
3
+ jsonId: string;
4
+ url?: string;
5
+ }
6
+
7
+ export function get<T = any>(options?: V6Options): Promise<T>;
8
+ export function clean<T = any>(options?: V6Options): Promise<T>;
@@ -0,0 +1,44 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { fileURLToPath } from "url";
4
+
5
+ import { executeXml, executeXmlAndClean } from "./core/index.js";
6
+ import { buildXml } from "./core/buildXml.js";
7
+ import bodyJson from "./body.json" with {type: "json"};
8
+
9
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
10
+ const body = fs.readFileSync(path.join(__dirname, "body.xml"), "utf8");
11
+
12
+ const get = (options = {}) => {
13
+ const company = options.company;
14
+ const jsonId = options.jsonId;
15
+
16
+ const { tdlMessage } = bodyJson[jsonId];
17
+
18
+ const staticVariables = `<SVCURRENTCOMPANY>${company}</SVCURRENTCOMPANY>`;
19
+
20
+ const xml = buildXml(body, {
21
+ staticVariables,
22
+ tdlMessage
23
+ });
24
+
25
+ return executeXml(xml, options);
26
+ };
27
+
28
+ const clean = (options = {}) => {
29
+ const company = options.company;
30
+ const jsonId = options.jsonId;
31
+
32
+ const { tdlMessage } = bodyJson[jsonId];
33
+
34
+ const staticVariables = `<SVCURRENTCOMPANY>${company}</SVCURRENTCOMPANY>`;
35
+
36
+ const xml = buildXml(body, {
37
+ staticVariables,
38
+ tdlMessage
39
+ });
40
+
41
+ return executeXmlAndClean(xml, options);
42
+ };
43
+
44
+ export { get, clean };