tally-simple 1.3.1 → 1.8.4

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 (81) hide show
  1. package/README.md +132 -83
  2. package/bin/tally-simple.js +2 -7
  3. package/docs/.nojekyll +1 -0
  4. package/docs/architecture.html +67 -68
  5. package/docs/architecture.md +74 -57
  6. package/docs/execution-pipeline.html +71 -0
  7. package/docs/execution-pipeline.md +158 -0
  8. package/docs/index.html +288 -26
  9. package/docs/queries.html +107 -0
  10. package/docs/queries.md +122 -0
  11. package/docs/route-engine.html +57 -0
  12. package/docs/route-engine.md +141 -0
  13. package/docs/style.css +137 -0
  14. package/docs/usage.html +82 -0
  15. package/docs/usage.md +117 -0
  16. package/package.json +14 -8
  17. package/src/index.js +2 -8
  18. package/src/v5/external-api/api.js +21 -0
  19. package/src/{v3 → v5}/external-api/api.json +1 -1
  20. package/src/v5/index.js +1 -0
  21. package/src/v5/internal-working/execution/buildXmlBody.js +41 -0
  22. package/src/v5/internal-working/execution/getTdl.js +12 -0
  23. package/src/v5/internal-working/execution/index.js +30 -0
  24. package/src/v5/internal-working/execution/postHttp.js +26 -0
  25. package/src/v5/internal-working/execution/validateCompany.js +11 -0
  26. package/src/v5/internal-working/route/attachPath.js +25 -0
  27. package/src/v5/internal-working/route/createLeafHandler.js +17 -0
  28. package/src/v5/internal-working/route/index.js +24 -0
  29. package/src/{v3 → v5}/source.json +1 -11
  30. package/src/v6/external-api/api.js +21 -0
  31. package/src/v6/external-api/api.json +6 -0
  32. package/src/v6/index.js +1 -0
  33. package/src/v6/internal-working/execution/buildXmlBody.js +41 -0
  34. package/src/v6/internal-working/execution/getTdl.js +12 -0
  35. package/src/v6/internal-working/execution/index.js +30 -0
  36. package/src/v6/internal-working/execution/postHttp.js +26 -0
  37. package/src/v6/internal-working/execution/validateCompany.js +11 -0
  38. package/src/v6/internal-working/route/attachPath.js +25 -0
  39. package/src/v6/internal-working/route/createLeafHandler.js +17 -0
  40. package/src/v6/internal-working/route/index.js +24 -0
  41. package/src/{v2 → v6}/source.json +8 -10
  42. package/src/v7/api.json +6 -0
  43. package/src/v7/index.js +14 -0
  44. package/src/v7/internal-working/execution/buildXmlBody.js +41 -0
  45. package/src/v7/internal-working/execution/getTdl.js +12 -0
  46. package/src/v7/internal-working/execution/index.js +30 -0
  47. package/src/v7/internal-working/execution/postHttp.js +26 -0
  48. package/src/v7/internal-working/execution/validateCompany.js +11 -0
  49. package/src/v7/internal-working/route/attachPath.js +25 -0
  50. package/src/v7/internal-working/route/createLeafHandler.js +17 -0
  51. package/src/v7/internal-working/route/index.js +24 -0
  52. package/src/{v1 → v7}/source.json +8 -10
  53. package/src/v8/engine/index.js +19 -0
  54. package/src/v8/engine/parseXml.js +11 -0
  55. package/src/v8/index.js +21 -0
  56. package/docs/api.html +0 -41
  57. package/docs/api.md +0 -20
  58. package/docs/developer.html +0 -57
  59. package/docs/developer.md +0 -41
  60. package/docs/end-user.html +0 -49
  61. package/docs/end-user.md +0 -34
  62. package/docs/repo-developer.html +0 -91
  63. package/docs/repo-developer.md +0 -107
  64. package/src/index.d.ts +0 -54
  65. package/src/v1/external-api/api.js +0 -67
  66. package/src/v1/external-api/api.json +0 -5
  67. package/src/v1/external-api/index.js +0 -1
  68. package/src/v1/index.js +0 -1
  69. package/src/v1/traverse.js +0 -103
  70. package/src/v1/traverseObject/index.js +0 -39
  71. package/src/v2/external-api/api.js +0 -67
  72. package/src/v2/external-api/api.json +0 -5
  73. package/src/v2/external-api/index.js +0 -1
  74. package/src/v2/index.js +0 -1
  75. package/src/v2/traverse.js +0 -103
  76. package/src/v2/traverseObject/index.js +0 -39
  77. package/src/v3/external-api/api.js +0 -67
  78. package/src/v3/external-api/index.js +0 -1
  79. package/src/v3/index.js +0 -1
  80. package/src/v3/traverse.js +0 -103
  81. package/src/v3/traverseObject/index.js +0 -39
@@ -0,0 +1,122 @@
1
+ # Available Queries Reference
2
+
3
+ [**View this document as HTML**](./queries.html) · [**Documentation Hub**](./index.html)
4
+
5
+ This document details the queries available in Tally Simple, the underlying TDL requests generated, and the XML data returned.
6
+
7
+ ---
8
+
9
+ ## Master Endpoints Overview
10
+
11
+ | Query Path | Domain Object | TDL Action |
12
+ | :--- | :--- | :--- |
13
+ | `tally.masters.units.fetch` | Unit of Measurement | `fetch` |
14
+ | `tally.masters.stockItems.withBatches` | Inventory Stock Item | `fetch` |
15
+ | `tally.masters.ledgers.withGstDetails` | Accounting Ledger | `fetch` |
16
+ | `tally.masters.stockGroup.withParent` | Stock Classification | `fetch` |
17
+
18
+ ---
19
+
20
+ ## 1. Units (`masters.units.fetch`)
21
+
22
+ Fetches all defined units of measurement in the specified company along with their aliases and names.
23
+
24
+ ### TDL Definition:
25
+ ```xml
26
+ <TYPE>Unit</TYPE>
27
+ <FETCH>$$Alias:Name</FETCH>
28
+ ```
29
+
30
+ ### Usage:
31
+ ```javascript
32
+ const xml = await tally.masters.units.fetch("Mani9");
33
+ ```
34
+
35
+ ---
36
+
37
+ ## 2. Stock Items with Batches (`masters.stockItems.withBatches`)
38
+
39
+ Fetches stock items including their base unit of measure and batch allocation details.
40
+
41
+ ### TDL Definition:
42
+ ```xml
43
+ <TYPE>StockItem</TYPE>
44
+ <FETCH>$$Alias:Name</FETCH>
45
+ <FETCH>BaseUnits</FETCH>
46
+ <FETCH>BatchAllocations.*</FETCH>
47
+ ```
48
+
49
+ ### Usage:
50
+ ```javascript
51
+ const xml = await tally.masters.stockItems.withBatches("Mani9");
52
+ ```
53
+
54
+ ---
55
+
56
+ ## 3. Ledgers with GST Details (`masters.ledgers.withGstDetails`)
57
+
58
+ Fetches accounting ledgers including their GST registration details list.
59
+
60
+ ### TDL Definition:
61
+ ```xml
62
+ <TYPE>Ledger</TYPE>
63
+ <FETCH>$$Alias:Name</FETCH>
64
+ <FETCH>LEDGSTREGDETAILS.LIST</FETCH>
65
+ ```
66
+
67
+ ### Usage:
68
+ ```javascript
69
+ const xml = await tally.masters.ledgers.withGstDetails("Mani9");
70
+ ```
71
+
72
+ ---
73
+
74
+ ## 4. Stock Groups with Parent (`masters.stockGroup.withParent`)
75
+
76
+ Fetches stock groups and their parent group hierarchy.
77
+
78
+ ### TDL Definition:
79
+ ```xml
80
+ <TYPE>StockGroup</TYPE>
81
+ <FETCH>$$Alias:Name</FETCH>
82
+ <FETCH>Parent</FETCH>
83
+ ```
84
+
85
+ ### Usage:
86
+ ```javascript
87
+ const xml = await tally.masters.stockGroup.withParent("Mani9");
88
+ ```
89
+
90
+ ---
91
+
92
+ ## The Request Envelope
93
+
94
+ Every query is wrapped inside Tally's standard Export Collection XML envelope:
95
+
96
+ ```xml
97
+ <ENVELOPE>
98
+ <HEADER>
99
+ <VERSION>1</VERSION>
100
+ <TALLYREQUEST>Export</TALLYREQUEST>
101
+ <TYPE>Collection</TYPE>
102
+ <ID>TDLID</ID>
103
+ </HEADER>
104
+ <BODY>
105
+ <DESC>
106
+ <STATICVARIABLES>
107
+ <SVEXPORTFORMAT>$$SysName:XML</SVEXPORTFORMAT>
108
+ <SVCURRENTCOMPANY>{company}</SVCURRENTCOMPANY>
109
+ </STATICVARIABLES>
110
+ <TDL>
111
+ <TDLMESSAGE>
112
+ <COLLECTION NAME="TDLID">
113
+ {collectionBody}
114
+ </COLLECTION>
115
+ </TDLMESSAGE>
116
+ </TDL>
117
+ </DESC>
118
+ </BODY>
119
+ </ENVELOPE>
120
+ ```
121
+
122
+ Tally Simple dynamically substitutes `{company}` (XML-escaped) and `{collectionBody}` (the TDL collection query) at runtime.
@@ -0,0 +1,57 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Route Assembly Engine — Tally Simple</title>
7
+ <link rel="stylesheet" href="style.css">
8
+ </head>
9
+ <body>
10
+ <div class="container">
11
+ <nav class="doc-nav">
12
+ <a href="index.html">&larr; Documentation Hub</a>
13
+ <a href="route-engine.md">View Markdown</a>
14
+ </nav>
15
+
16
+ <h1>Route Assembly Engine</h1>
17
+ <p>The route engine transforms a flat allowlist of string paths (from <code>api.json</code>) into an intuitive, nested, callable JavaScript object tree at initialization.</p>
18
+
19
+ <h2>Why Route Assembly?</h2>
20
+ <p>Consumers expect to call:</p>
21
+ <pre><code>await tally.masters.units.fetch("Mani9");</code></pre>
22
+ <p>The route engine builds this tree dynamically from <code>api.json</code> without hardcoding methods.</p>
23
+
24
+ <h2>The Three Narrative Modules</h2>
25
+ <p>Inside <code>internal-working/route/</code>, the responsibility is divided into three small, story-driven files:</p>
26
+ <pre><code>internal-working/route/
27
+ ├── index.js &lt;-- Coordinator: iterates paths &amp; returns root
28
+ ├── attachPath.js &lt;-- Walks tree branches &amp; mounts leaf
29
+ └── createLeafHandler.js &lt;-- Factory creating the callable endpoint</code></pre>
30
+
31
+ <h2>1. The Leaf Factory (<code>createLeafHandler.js</code>)</h2>
32
+ <p>A leaf is the terminal callable function at the end of a route. When the user executes <code>fetch("Mani9")</code>, the leaf handler captures the bound route path and delegates execution to the executor.</p>
33
+
34
+ <h2>2. Path Attacher (<code>attachPath.js</code>)</h2>
35
+ <p>To attach a path like <code>"tally.masters.units.fetch"</code>:</p>
36
+ <ol>
37
+ <li>Split the path into branch segments (<code>["tally", "masters", "units"]</code>) and a leaf name (<code>"fetch"</code>).</li>
38
+ <li>Walk through the branch segments, creating intermediate objects if they don't yet exist.</li>
39
+ <li>Attach the callable leaf handler at the target position.</li>
40
+ </ol>
41
+
42
+ <h2>3. Route Coordinator (<code>index.js</code>)</h2>
43
+ <p>The entry coordinator iterates each path in <code>inApiPaths</code>, mounts it into the tree using <code>attachPath</code>, and returns the root namespace.</p>
44
+
45
+ <h2>Benefits of this Design</h2>
46
+ <ul>
47
+ <li><strong>Predictable:</strong> Built once at module load time. Zero runtime overhead during queries.</li>
48
+ <li><strong>Narrative-Driven:</strong> Every file is under 40 lines and has a single, obvious purpose.</li>
49
+ <li><strong>Strictly One Export:</strong> Every file uses <code>export default startFunc;</code>.</li>
50
+ </ul>
51
+
52
+ <footer>
53
+ <p>&copy; KeshavSoft. Distributed under the MIT License.</p>
54
+ </footer>
55
+ </div>
56
+ </body>
57
+ </html>
@@ -0,0 +1,141 @@
1
+ # Route Assembly Engine
2
+
3
+ [**View this document as HTML**](./route-engine.html) · [**Documentation Hub**](./index.html)
4
+
5
+ The route engine transforms a flat allowlist of string paths (from `api.json`) into an intuitive, nested, callable JavaScript object tree at initialization.
6
+
7
+ ---
8
+
9
+ ## Why Route Assembly?
10
+
11
+ Consumers expect to call:
12
+
13
+ ```javascript
14
+ await tally.masters.units.fetch("Mani9");
15
+ ```
16
+
17
+ Rather than manual string dispatch:
18
+
19
+ ```javascript
20
+ // Not this:
21
+ await execute("tally.masters.units.fetch", "Mani9");
22
+ ```
23
+
24
+ The route engine builds this tree dynamically from `api.json` without hardcoding methods.
25
+
26
+ ---
27
+
28
+ ## The Three Narrative Modules
29
+
30
+ Inside `internal-working/route/`, the responsibility is divided into three small, story-driven files:
31
+
32
+ ```text
33
+ internal-working/route/
34
+ ├── index.js <-- Coordinator: iterates paths & returns root
35
+ ├── attachPath.js <-- Walks tree branches & mounts leaf
36
+ └── createLeafHandler.js <-- Factory creating the callable endpoint
37
+ ```
38
+
39
+ ---
40
+
41
+ ### 1. The Leaf Factory (`createLeafHandler.js`)
42
+
43
+ A leaf is the terminal callable function at the end of a route. When the user executes `fetch("Mani9")`, the leaf handler captures the bound route path and delegates execution to the executor:
44
+
45
+ ```javascript
46
+ const startFunc = ({ inPath, inSource, inExecutor }) => {
47
+ const localPath = inPath;
48
+ const localSource = inSource;
49
+ const localExecutor = inExecutor;
50
+
51
+ return async (inCompany) => {
52
+ const localCompany = inCompany;
53
+
54
+ return await localExecutor({
55
+ inRoutePath: localPath,
56
+ inCompany: localCompany,
57
+ inSource: localSource
58
+ });
59
+ };
60
+ };
61
+
62
+ export default startFunc;
63
+ ```
64
+
65
+ ---
66
+
67
+ ### 2. Path Attacher (`attachPath.js`)
68
+
69
+ To attach a path like `"tally.masters.units.fetch"`:
70
+ 1. Split the path into branch segments (`["tally", "masters", "units"]`) and a leaf name (`"fetch"`).
71
+ 2. Walk through the branch segments, creating intermediate objects if they don't yet exist.
72
+ 3. Attach the callable leaf handler at the target position.
73
+
74
+ ```javascript
75
+ import createLeafHandler from "./createLeafHandler.js";
76
+
77
+ const startFunc = ({ inTree, inPath, inSource, inExecutor }) => {
78
+ const localTree = inTree;
79
+ const localPath = inPath;
80
+ const localSource = inSource;
81
+ const localExecutor = inExecutor;
82
+
83
+ const parts = localPath.split(".");
84
+ const leafName = parts.pop();
85
+
86
+ let branch = localTree;
87
+ for (const segment of parts) {
88
+ branch[segment] ??= {};
89
+ branch = branch[segment];
90
+ }
91
+
92
+ branch[leafName] = createLeafHandler({
93
+ inPath: localPath,
94
+ inSource: localSource,
95
+ inExecutor: localExecutor
96
+ });
97
+ };
98
+
99
+ export default startFunc;
100
+ ```
101
+
102
+ ---
103
+
104
+ ### 3. Route Coordinator (`index.js`)
105
+
106
+ The entry coordinator iterates each path in `inApiPaths`, mounts it into the tree using `attachPath`, and returns the root namespace:
107
+
108
+ ```javascript
109
+ import attachPath from "./attachPath.js";
110
+
111
+ const startFunc = ({ inApiPaths, inSource, inExecutor }) => {
112
+ const localApiPaths = inApiPaths;
113
+ const localSource = inSource;
114
+ const localExecutor = inExecutor;
115
+
116
+ const tree = {};
117
+
118
+ for (const path of localApiPaths) {
119
+ attachPath({
120
+ inTree: tree,
121
+ inPath: path,
122
+ inSource: localSource,
123
+ inExecutor: localExecutor
124
+ });
125
+ }
126
+
127
+ const rootNamespace = localApiPaths[0]?.split(".")[0];
128
+
129
+ return rootNamespace ? tree[rootNamespace] : tree;
130
+ };
131
+
132
+ export default startFunc;
133
+ ```
134
+
135
+ ---
136
+
137
+ ## Benefits of this Design
138
+
139
+ - **Predictable:** Built once at module load time. Zero runtime overhead during queries.
140
+ - **Narrative-Driven:** Every file is under 40 lines and has a single, obvious purpose.
141
+ - **Strictly One Export:** Every file uses `export default startFunc;`.
package/docs/style.css ADDED
@@ -0,0 +1,137 @@
1
+ :root {
2
+ --bg: #0f172a;
3
+ --panel-bg: #1e293b;
4
+ --border: #334155;
5
+ --text-main: #f8fafc;
6
+ --text-muted: #94a3b8;
7
+ --accent: #38bdf8;
8
+ --code-bg: #0b1120;
9
+ --inline-code-bg: #334155;
10
+ }
11
+
12
+ * { box-sizing: border-box; margin: 0; padding: 0; }
13
+
14
+ body {
15
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
16
+ background-color: var(--bg);
17
+ color: var(--text-main);
18
+ line-height: 1.65;
19
+ padding: 2.5rem 1.5rem;
20
+ }
21
+
22
+ .container {
23
+ max-width: 820px;
24
+ margin: 0 auto;
25
+ }
26
+
27
+ nav.doc-nav {
28
+ display: flex;
29
+ justify-content: space-between;
30
+ align-items: center;
31
+ border-bottom: 1px solid var(--border);
32
+ padding-bottom: 1rem;
33
+ margin-bottom: 2.5rem;
34
+ font-size: 0.9rem;
35
+ }
36
+
37
+ nav.doc-nav a {
38
+ color: var(--accent);
39
+ text-decoration: none;
40
+ font-weight: 500;
41
+ }
42
+
43
+ nav.doc-nav a:hover {
44
+ text-decoration: underline;
45
+ }
46
+
47
+ h1 {
48
+ font-size: 2.2rem;
49
+ color: var(--text-main);
50
+ margin-bottom: 1rem;
51
+ line-height: 1.25;
52
+ }
53
+
54
+ h2 {
55
+ font-size: 1.5rem;
56
+ color: var(--accent);
57
+ margin-top: 2rem;
58
+ margin-bottom: 0.75rem;
59
+ border-bottom: 1px solid var(--border);
60
+ padding-bottom: 0.35rem;
61
+ }
62
+
63
+ h3 {
64
+ font-size: 1.2rem;
65
+ color: #cbd5e1;
66
+ margin-top: 1.5rem;
67
+ margin-bottom: 0.5rem;
68
+ }
69
+
70
+ p, ul, ol {
71
+ margin-bottom: 1.2rem;
72
+ color: #e2e8f0;
73
+ }
74
+
75
+ ul, ol {
76
+ padding-left: 1.75rem;
77
+ }
78
+
79
+ li {
80
+ margin-bottom: 0.4rem;
81
+ }
82
+
83
+ code {
84
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
85
+ font-size: 0.88em;
86
+ background-color: var(--inline-code-bg);
87
+ color: #f1f5f9;
88
+ padding: 0.15rem 0.35rem;
89
+ border-radius: 4px;
90
+ }
91
+
92
+ pre {
93
+ background-color: var(--code-bg);
94
+ border: 1px solid var(--border);
95
+ border-radius: 6px;
96
+ padding: 1.2rem;
97
+ overflow-x: auto;
98
+ margin-bottom: 1.5rem;
99
+ }
100
+
101
+ pre code {
102
+ background: transparent;
103
+ padding: 0;
104
+ font-size: 0.92rem;
105
+ color: #f8fafc;
106
+ }
107
+
108
+ table {
109
+ width: 100%;
110
+ border-collapse: collapse;
111
+ margin-bottom: 1.5rem;
112
+ }
113
+
114
+ th, td {
115
+ padding: 0.75rem 1rem;
116
+ text-align: left;
117
+ border: 1px solid var(--border);
118
+ }
119
+
120
+ th {
121
+ background-color: var(--panel-bg);
122
+ color: var(--accent);
123
+ font-weight: 600;
124
+ }
125
+
126
+ tr:nth-child(even) {
127
+ background-color: rgba(30, 41, 59, 0.5);
128
+ }
129
+
130
+ footer {
131
+ margin-top: 3rem;
132
+ border-top: 1px solid var(--border);
133
+ padding-top: 1.5rem;
134
+ color: var(--text-muted);
135
+ font-size: 0.85rem;
136
+ text-align: center;
137
+ }
@@ -0,0 +1,82 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Usage Guide — Tally Simple</title>
7
+ <link rel="stylesheet" href="style.css">
8
+ </head>
9
+ <body>
10
+ <div class="container">
11
+ <nav class="doc-nav">
12
+ <a href="index.html">&larr; Documentation Hub</a>
13
+ <a href="usage.md">View Markdown</a>
14
+ </nav>
15
+
16
+ <h1>Usage Guide</h1>
17
+ <p>This guide explains how to consume Tally Simple in JavaScript/TypeScript applications and from the command line.</p>
18
+
19
+ <h2>Requirements</h2>
20
+ <ul>
21
+ <li><strong>Node.js</strong>: Version 20.10 or newer.</li>
22
+ <li><strong>Tally</strong>: A running Tally Prime / ERP instance with the ODBC/XML server enabled on <code>http://localhost:9000</code>.</li>
23
+ </ul>
24
+
25
+ <h2>Installation</h2>
26
+ <pre><code>npm install tally-simple</code></pre>
27
+ <p>The package contains zero runtime dependencies and ships as an ECMAScript Module (ESM).</p>
28
+
29
+ <h2>Using in JavaScript (ESM)</h2>
30
+ <p>Import the default <code>tally</code> client and call any supported query path with a company name:</p>
31
+ <pre><code>import tally from "tally-simple";
32
+
33
+ const unitsXml = await tally.masters.units.fetch("Mani9");
34
+ console.log(unitsXml);</code></pre>
35
+
36
+ <h3>Supported Query Paths</h3>
37
+ <p>The client mirrors the hierarchy exposed in the public API:</p>
38
+ <pre><code>// Units
39
+ const units = await tally.masters.units.fetch("Mani9");
40
+
41
+ // Stock items with batch details
42
+ const items = await tally.masters.stockItems.withBatches("Mani9");
43
+
44
+ // Ledgers with GST registration
45
+ const ledgers = await tally.masters.ledgers.withGstDetails("Mani9");
46
+
47
+ // Stock groups with parent hierarchy
48
+ const groups = await tally.masters.stockGroup.withParent("Mani9");</code></pre>
49
+
50
+ <h2>TypeScript Support</h2>
51
+ <p>Tally Simple automatically generates TypeScript declarations (<code>src/index.d.ts</code>) directly from the domain specification.</p>
52
+ <p>You receive full autocomplete and inline documentation in editors like VS Code:</p>
53
+ <pre><code>import tally from "tally-simple";
54
+
55
+ // Editor automatically autocompletes:
56
+ // tally.masters.units.fetch
57
+ // tally.masters.stockItems.withBatches
58
+ // tally.masters.ledgers.withGstDetails
59
+ // tally.masters.stockGroup.withParent
60
+
61
+ const xml: string = await tally.masters.units.fetch("Mani9");</code></pre>
62
+
63
+ <h2>Command Line Interface (CLI)</h2>
64
+ <p>You can run any query path directly from the shell using <code>npx</code>:</p>
65
+ <pre><code>npx tally-simple masters.units.fetch --company Mani9</code></pre>
66
+
67
+ <h3>Saving &amp; Piping Output</h3>
68
+ <p>The CLI writes Tally's raw XML response directly to <code>stdout</code>, making it easy to pipe to a file or another command:</p>
69
+ <pre><code>npx tally-simple masters.units.fetch --company Mani9 > units.xml</code></pre>
70
+
71
+ <h2>Error Handling</h2>
72
+ <ul>
73
+ <li><strong>Company Name Validation:</strong> Passing an empty or non-string company name throws a <code>TypeError</code> before sending a request.</li>
74
+ <li><strong>HTTP Failures:</strong> If the Tally endpoint returns an HTTP error, an exception is thrown containing the status code and response body.</li>
75
+ </ul>
76
+
77
+ <footer>
78
+ <p>&copy; KeshavSoft. Distributed under the MIT License.</p>
79
+ </footer>
80
+ </div>
81
+ </body>
82
+ </html>
package/docs/usage.md ADDED
@@ -0,0 +1,117 @@
1
+ # Usage Guide
2
+
3
+ [**View this document as HTML**](./usage.html) · [**Documentation Hub**](./index.html)
4
+
5
+ This guide explains how to consume Tally Simple in JavaScript/TypeScript applications and from the command line.
6
+
7
+ ---
8
+
9
+ ## Requirements
10
+
11
+ - **Node.js**: Version 20.10 or newer.
12
+ - **Tally**: A running Tally Prime / ERP instance with the ODBC/XML server enabled on `http://localhost:9000`.
13
+
14
+ ---
15
+
16
+ ## Installation
17
+
18
+ Add Tally Simple to your project:
19
+
20
+ ```bash
21
+ npm install tally-simple
22
+ ```
23
+
24
+ The package contains zero runtime dependencies and ships as an ECMAScript Module (ESM).
25
+
26
+ ---
27
+
28
+ ## Using in JavaScript (ESM)
29
+
30
+ Import the default `tally` client and call any supported query path with a company name:
31
+
32
+ ```javascript
33
+ import tally from "tally-simple";
34
+
35
+ const unitsXml = await tally.masters.units.fetch("Mani9");
36
+ console.log(unitsXml);
37
+ ```
38
+
39
+ ### Supported Query Paths
40
+
41
+ The client mirrors the hierarchy exposed in the public API:
42
+
43
+ ```javascript
44
+ // Units
45
+ const units = await tally.masters.units.fetch("Mani9");
46
+
47
+ // Stock items with batch details
48
+ const items = await tally.masters.stockItems.withBatches("Mani9");
49
+
50
+ // Ledgers with GST registration
51
+ const ledgers = await tally.masters.ledgers.withGstDetails("Mani9");
52
+
53
+ // Stock groups with parent hierarchy
54
+ const groups = await tally.masters.stockGroup.withParent("Mani9");
55
+ ```
56
+
57
+ ---
58
+
59
+ ## TypeScript Support
60
+
61
+ Tally Simple automatically generates TypeScript declarations (`src/index.d.ts`) directly from the domain specification.
62
+
63
+ You receive full autocomplete and inline documentation in editors like VS Code:
64
+
65
+ ```typescript
66
+ import tally from "tally-simple";
67
+
68
+ // Editor automatically autocompletes:
69
+ // tally.masters.units.fetch
70
+ // tally.masters.stockItems.withBatches
71
+ // tally.masters.ledgers.withGstDetails
72
+ // tally.masters.stockGroup.withParent
73
+
74
+ const xml: string = await tally.masters.units.fetch("Mani9");
75
+ ```
76
+
77
+ ---
78
+
79
+ ## Command Line Interface (CLI)
80
+
81
+ You can run any query path directly from the shell using `npx`:
82
+
83
+ ```bash
84
+ npx tally-simple masters.units.fetch --company Mani9
85
+ ```
86
+
87
+ ### Saving & Piping Output
88
+
89
+ The CLI writes Tally's raw XML response directly to `stdout`, making it easy to pipe to a file or another command:
90
+
91
+ ```bash
92
+ npx tally-simple masters.units.fetch --company Mani9 > units.xml
93
+ ```
94
+
95
+ Pipe directly into `xmllint` or formatting utilities:
96
+
97
+ ```bash
98
+ npx tally-simple masters.units.fetch --company Mani9 | xmllint --format -
99
+ ```
100
+
101
+ ---
102
+
103
+ ## Error Handling
104
+
105
+ Tally Simple provides clear, predictable errors:
106
+
107
+ 1. **Company Name Validation:**
108
+ Passing an empty string or non-string argument throws a `TypeError` before any request is sent:
109
+ ```javascript
110
+ await tally.masters.units.fetch(" "); // Throws: TypeError: Company name is required.
111
+ ```
112
+
113
+ 2. **HTTP Failures:**
114
+ If the Tally server returns an error status (e.g. 500), an error is thrown containing the HTTP status and response body:
115
+ ```text
116
+ Error: Tally request failed with HTTP 500: Tally is unavailable
117
+ ```
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "tally-simple",
3
- "version": "1.3.1",
3
+ "version": "1.8.4",
4
4
  "description": "A small, typed JavaScript client and CLI for querying Tally through TDL definitions.",
5
- "homepage": "https://github.com/keshavsoft/tally-simple#readme",
5
+ "homepage": "https://keshavsoft.github.io/tally-simple/",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/keshavsoft/tally-simple.git"
@@ -33,11 +33,8 @@
33
33
  "LICENSE"
34
34
  ],
35
35
  "scripts": {
36
- "generate:dts": "node generate-dts.js",
37
- "test": "node --test test/test.js test/units.js",
38
- "verify": "npm run generate:dts && npm test",
39
- "prepack": "npm run verify",
40
- "prepublishOnly": "npm run verify"
36
+ "generate:dts": "create-intellisense",
37
+ "test": "node --test test/test.js test/units.js"
41
38
  },
42
39
  "keywords": [
43
40
  "tally",
@@ -51,5 +48,14 @@
51
48
  },
52
49
  "publishConfig": {
53
50
  "access": "public"
51
+ },
52
+ "devDependencies": {
53
+ "create-intellisense": "^1.2.1"
54
+ },
55
+ "dependencies": {
56
+ "@keshavsoft/api-tree": "^11.1.1",
57
+ "@keshavsoft/json-transformer": "^1.9.2",
58
+ "tally-simple-json": "^1.16.6",
59
+ "tally-spec": "^1.2.3"
54
60
  }
55
- }
61
+ }