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.
- package/README.md +132 -83
- package/bin/tally-simple.js +2 -7
- package/docs/.nojekyll +1 -0
- package/docs/architecture.html +67 -68
- package/docs/architecture.md +74 -57
- package/docs/execution-pipeline.html +71 -0
- package/docs/execution-pipeline.md +158 -0
- package/docs/index.html +288 -26
- package/docs/queries.html +107 -0
- package/docs/queries.md +122 -0
- package/docs/route-engine.html +57 -0
- package/docs/route-engine.md +141 -0
- package/docs/style.css +137 -0
- package/docs/usage.html +82 -0
- package/docs/usage.md +117 -0
- package/package.json +14 -8
- package/src/index.js +2 -8
- package/src/v5/external-api/api.js +21 -0
- package/src/{v3 → v5}/external-api/api.json +1 -1
- package/src/v5/index.js +1 -0
- package/src/v5/internal-working/execution/buildXmlBody.js +41 -0
- package/src/v5/internal-working/execution/getTdl.js +12 -0
- package/src/v5/internal-working/execution/index.js +30 -0
- package/src/v5/internal-working/execution/postHttp.js +26 -0
- package/src/v5/internal-working/execution/validateCompany.js +11 -0
- package/src/v5/internal-working/route/attachPath.js +25 -0
- package/src/v5/internal-working/route/createLeafHandler.js +17 -0
- package/src/v5/internal-working/route/index.js +24 -0
- package/src/{v3 → v5}/source.json +1 -11
- package/src/v6/external-api/api.js +21 -0
- package/src/v6/external-api/api.json +6 -0
- package/src/v6/index.js +1 -0
- package/src/v6/internal-working/execution/buildXmlBody.js +41 -0
- package/src/v6/internal-working/execution/getTdl.js +12 -0
- package/src/v6/internal-working/execution/index.js +30 -0
- package/src/v6/internal-working/execution/postHttp.js +26 -0
- package/src/v6/internal-working/execution/validateCompany.js +11 -0
- package/src/v6/internal-working/route/attachPath.js +25 -0
- package/src/v6/internal-working/route/createLeafHandler.js +17 -0
- package/src/v6/internal-working/route/index.js +24 -0
- package/src/{v2 → v6}/source.json +8 -10
- package/src/v7/api.json +6 -0
- package/src/v7/index.js +14 -0
- package/src/v7/internal-working/execution/buildXmlBody.js +41 -0
- package/src/v7/internal-working/execution/getTdl.js +12 -0
- package/src/v7/internal-working/execution/index.js +30 -0
- package/src/v7/internal-working/execution/postHttp.js +26 -0
- package/src/v7/internal-working/execution/validateCompany.js +11 -0
- package/src/v7/internal-working/route/attachPath.js +25 -0
- package/src/v7/internal-working/route/createLeafHandler.js +17 -0
- package/src/v7/internal-working/route/index.js +24 -0
- package/src/{v1 → v7}/source.json +8 -10
- package/src/v8/engine/index.js +19 -0
- package/src/v8/engine/parseXml.js +11 -0
- package/src/v8/index.js +21 -0
- package/docs/api.html +0 -41
- package/docs/api.md +0 -20
- package/docs/developer.html +0 -57
- package/docs/developer.md +0 -41
- package/docs/end-user.html +0 -49
- package/docs/end-user.md +0 -34
- package/docs/repo-developer.html +0 -91
- package/docs/repo-developer.md +0 -107
- package/src/index.d.ts +0 -54
- package/src/v1/external-api/api.js +0 -67
- package/src/v1/external-api/api.json +0 -5
- package/src/v1/external-api/index.js +0 -1
- package/src/v1/index.js +0 -1
- package/src/v1/traverse.js +0 -103
- package/src/v1/traverseObject/index.js +0 -39
- package/src/v2/external-api/api.js +0 -67
- package/src/v2/external-api/api.json +0 -5
- package/src/v2/external-api/index.js +0 -1
- package/src/v2/index.js +0 -1
- package/src/v2/traverse.js +0 -103
- package/src/v2/traverseObject/index.js +0 -39
- package/src/v3/external-api/api.js +0 -67
- package/src/v3/external-api/index.js +0 -1
- package/src/v3/index.js +0 -1
- package/src/v3/traverse.js +0 -103
- package/src/v3/traverseObject/index.js +0 -39
package/docs/queries.md
ADDED
|
@@ -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">← 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 <-- Coordinator: iterates paths & returns root
|
|
28
|
+
├── attachPath.js <-- Walks tree branches & mounts leaf
|
|
29
|
+
└── createLeafHandler.js <-- 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>© 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
|
+
}
|
package/docs/usage.html
ADDED
|
@@ -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">← 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 & 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>© 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
|
+
"version": "1.8.4",
|
|
4
4
|
"description": "A small, typed JavaScript client and CLI for querying Tally through TDL definitions.",
|
|
5
|
-
"homepage": "https://github.
|
|
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": "
|
|
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
|
+
}
|