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
@@ -1,67 +0,0 @@
1
- import source from "../source.json" with { type: "json" };
2
- import traverse from "../traverse.js";
3
- import apiPaths from "./api.json" with { type: "json" };
4
-
5
- const createApi = (options = {}) => {
6
- const connection = {
7
- ...source.tally.connection,
8
- ...options.connection,
9
- ...(options.url ? { url: options.url } : {}),
10
- ...(options.method ? { method: options.method } : {}),
11
- headers: {
12
- ...source.tally.connection.headers,
13
- ...options.connection?.headers,
14
- ...options.headers
15
- }
16
- };
17
- const request = options.request ?? source.tally.request;
18
- const fetchImpl = options.fetch ?? globalThis.fetch;
19
- const clientSource = {
20
- ...source,
21
- tally: {
22
- ...source.tally,
23
- connection,
24
- request
25
- }
26
- };
27
-
28
- const createFunction = (path) => async (company) => {
29
- if (typeof company !== "string" || !company.trim()) {
30
- throw new TypeError("Company name is required.");
31
- }
32
-
33
- return await traverse(clientSource, "", path, {
34
- company: company.trim(),
35
- connection,
36
- request,
37
- fetch: fetchImpl,
38
- timeout: options.timeout
39
- });
40
- };
41
-
42
- const root = {};
43
-
44
- for (const path of apiPaths) {
45
- const parts = path.split(".");
46
- let current = root;
47
-
48
- parts.forEach((part, index) => {
49
- const isLast = index === parts.length - 1;
50
-
51
- if (isLast) {
52
- current[part] = createFunction(path);
53
- return;
54
- }
55
-
56
- current[part] ??= {};
57
- current = current[part];
58
- });
59
- }
60
-
61
- const rootName = apiPaths[0]?.split(".")[0];
62
-
63
- return rootName ? root[rootName] : root;
64
- };
65
-
66
- export { createApi };
67
- export default createApi();
@@ -1,5 +0,0 @@
1
- [
2
- "tally.masters.units.fetch",
3
- "tally.masters.stockItems.withBatches",
4
- "tally.masters.ledgers.withGstDetails"
5
- ]
@@ -1 +0,0 @@
1
- export { createApi, default } from "./api.js";
package/src/v1/index.js DELETED
@@ -1 +0,0 @@
1
- export { createApi, default } from "./external-api/api.js";
@@ -1,103 +0,0 @@
1
- import traverseObject from "./traverseObject/index.js";
2
-
3
- const escapeXml = (value) => value.replace(/[&<>"']/g, (character) => ({
4
- "&": "&amp;",
5
- "<": "&lt;",
6
- ">": "&gt;",
7
- '"': "&quot;",
8
- "'": "&apos;"
9
- }[character]));
10
-
11
- const buildRequestBody = (requestBody, { company, collection }) => {
12
- return requestBody
13
- .replace("{company}", escapeXml(company))
14
- .replace("{collectionBody}", collection);
15
- };
16
-
17
- const execute = async (connection, xml, fetchImpl, timeout) => {
18
- if (typeof fetchImpl !== "function") {
19
- throw new Error(
20
- "No fetch implementation is available. Use Node.js 20+ or provide fetch to createTallyClient()."
21
- );
22
- }
23
-
24
- const controller = typeof AbortController === "function"
25
- ? new AbortController()
26
- : undefined;
27
- const timeoutId = Number.isFinite(timeout) && timeout > 0
28
- ? setTimeout(() => controller?.abort(), timeout)
29
- : undefined;
30
-
31
- let response;
32
-
33
- try {
34
- response = await fetchImpl(connection.url, {
35
- method: connection.method,
36
- headers: connection.headers,
37
- body: xml,
38
- ...(controller ? { signal: controller.signal } : {})
39
- });
40
- } catch (error) {
41
- if (controller?.signal.aborted) {
42
- throw new Error(`Tally request timed out after ${timeout} ms.`, {
43
- cause: error
44
- });
45
- }
46
-
47
- throw error;
48
- } finally {
49
- if (timeoutId) clearTimeout(timeoutId);
50
- }
51
-
52
- const responseText = await response.text();
53
-
54
- if (!response.ok) {
55
- throw new Error(
56
- `Tally request failed with HTTP ${response.status}: ${responseText}`
57
- );
58
- }
59
-
60
- return responseText;
61
- };
62
-
63
- const traverse = async (
64
- raka,
65
- relativePath,
66
- pathToFind,
67
- context = {}
68
- ) => {
69
- if (relativePath === pathToFind) {
70
- if (raka?.action === "fetch") {
71
- const body = buildRequestBody(
72
- context.request.body,
73
- {
74
- company: context.company,
75
- collection: raka.tdl.collection
76
- }
77
- );
78
-
79
- return await execute(
80
- context.connection,
81
- body,
82
- context.fetch,
83
- context.timeout
84
- );
85
- }
86
-
87
- return raka;
88
- }
89
-
90
- if (typeof raka === "object" && raka !== null) {
91
- return await traverseObject(
92
- raka,
93
- relativePath,
94
- pathToFind,
95
- context
96
- );
97
- }
98
-
99
- return undefined;
100
- };
101
-
102
- export { traverse };
103
- export default traverse;
@@ -1,39 +0,0 @@
1
- import { traverse } from "../traverse.js";
2
-
3
- const traverseObject = async (
4
- specJson,
5
- relativePath,
6
- pathToFind,
7
- context = {}
8
- ) => {
9
- const nextContext = {
10
- ...context,
11
- connection: specJson.connection ?? context.connection,
12
- request: specJson.request ?? context.request
13
- };
14
-
15
- for (const [key, value] of Object.entries(specJson)) {
16
- if (key === "connection" || key === "request") continue;
17
-
18
- if (typeof value === "object" && value !== null) {
19
- const nextPath = relativePath
20
- ? `${relativePath}.${key}`
21
- : key;
22
-
23
- const result = await traverse(
24
- value,
25
- nextPath,
26
- pathToFind,
27
- nextContext
28
- );
29
-
30
- if (result !== undefined) {
31
- return result;
32
- }
33
- }
34
- }
35
-
36
- return undefined;
37
- };
38
-
39
- export default traverseObject;
@@ -1,67 +0,0 @@
1
- import source from "../source.json" with { type: "json" };
2
- import traverse from "../traverse.js";
3
- import apiPaths from "./api.json" with { type: "json" };
4
-
5
- const createApi = (options = {}) => {
6
- const connection = {
7
- ...source.tally.connection,
8
- ...options.connection,
9
- ...(options.url ? { url: options.url } : {}),
10
- ...(options.method ? { method: options.method } : {}),
11
- headers: {
12
- ...source.tally.connection.headers,
13
- ...options.connection?.headers,
14
- ...options.headers
15
- }
16
- };
17
- const request = options.request ?? source.tally.request;
18
- const fetchImpl = options.fetch ?? globalThis.fetch;
19
- const clientSource = {
20
- ...source,
21
- tally: {
22
- ...source.tally,
23
- connection,
24
- request
25
- }
26
- };
27
-
28
- const createFunction = (path) => async (company) => {
29
- if (typeof company !== "string" || !company.trim()) {
30
- throw new TypeError("Company name is required.");
31
- }
32
-
33
- return await traverse(clientSource, "", path, {
34
- company: company.trim(),
35
- connection,
36
- request,
37
- fetch: fetchImpl,
38
- timeout: options.timeout
39
- });
40
- };
41
-
42
- const root = {};
43
-
44
- for (const path of apiPaths) {
45
- const parts = path.split(".");
46
- let current = root;
47
-
48
- parts.forEach((part, index) => {
49
- const isLast = index === parts.length - 1;
50
-
51
- if (isLast) {
52
- current[part] = createFunction(path);
53
- return;
54
- }
55
-
56
- current[part] ??= {};
57
- current = current[part];
58
- });
59
- }
60
-
61
- const rootName = apiPaths[0]?.split(".")[0];
62
-
63
- return rootName ? root[rootName] : root;
64
- };
65
-
66
- export { createApi };
67
- export default createApi();
@@ -1,5 +0,0 @@
1
- [
2
- "tally.masters.units.fetch",
3
- "tally.masters.stockItems.withBatches",
4
- "tally.masters.ledgers.withGstDetails"
5
- ]
@@ -1 +0,0 @@
1
- export { createApi, default } from "./api.js";
package/src/v2/index.js DELETED
@@ -1 +0,0 @@
1
- export { createApi, default } from "./external-api/api.js";
@@ -1,103 +0,0 @@
1
- import traverseObject from "./traverseObject/index.js";
2
-
3
- const escapeXml = (value) => value.replace(/[&<>"']/g, (character) => ({
4
- "&": "&amp;",
5
- "<": "&lt;",
6
- ">": "&gt;",
7
- '"': "&quot;",
8
- "'": "&apos;"
9
- }[character]));
10
-
11
- const buildRequestBody = (requestBody, { company, collection }) => {
12
- return requestBody
13
- .replace("{company}", escapeXml(company))
14
- .replace("{collectionBody}", collection);
15
- };
16
-
17
- const execute = async (connection, xml, fetchImpl, timeout) => {
18
- if (typeof fetchImpl !== "function") {
19
- throw new Error(
20
- "No fetch implementation is available. Use Node.js 20+ or provide fetch to createTallyClient()."
21
- );
22
- }
23
-
24
- const controller = typeof AbortController === "function"
25
- ? new AbortController()
26
- : undefined;
27
- const timeoutId = Number.isFinite(timeout) && timeout > 0
28
- ? setTimeout(() => controller?.abort(), timeout)
29
- : undefined;
30
-
31
- let response;
32
-
33
- try {
34
- response = await fetchImpl(connection.url, {
35
- method: connection.method,
36
- headers: connection.headers,
37
- body: xml,
38
- ...(controller ? { signal: controller.signal } : {})
39
- });
40
- } catch (error) {
41
- if (controller?.signal.aborted) {
42
- throw new Error(`Tally request timed out after ${timeout} ms.`, {
43
- cause: error
44
- });
45
- }
46
-
47
- throw error;
48
- } finally {
49
- if (timeoutId) clearTimeout(timeoutId);
50
- }
51
-
52
- const responseText = await response.text();
53
-
54
- if (!response.ok) {
55
- throw new Error(
56
- `Tally request failed with HTTP ${response.status}: ${responseText}`
57
- );
58
- }
59
-
60
- return responseText;
61
- };
62
-
63
- const traverse = async (
64
- raka,
65
- relativePath,
66
- pathToFind,
67
- context = {}
68
- ) => {
69
- if (relativePath === pathToFind) {
70
- if (raka?.action === "fetch") {
71
- const body = buildRequestBody(
72
- context.request.body,
73
- {
74
- company: context.company,
75
- collection: raka.tdl.collection
76
- }
77
- );
78
-
79
- return await execute(
80
- context.connection,
81
- body,
82
- context.fetch,
83
- context.timeout
84
- );
85
- }
86
-
87
- return raka;
88
- }
89
-
90
- if (typeof raka === "object" && raka !== null) {
91
- return await traverseObject(
92
- raka,
93
- relativePath,
94
- pathToFind,
95
- context
96
- );
97
- }
98
-
99
- return undefined;
100
- };
101
-
102
- export { traverse };
103
- export default traverse;
@@ -1,39 +0,0 @@
1
- import { traverse } from "../traverse.js";
2
-
3
- const traverseObject = async (
4
- specJson,
5
- relativePath,
6
- pathToFind,
7
- context = {}
8
- ) => {
9
- const nextContext = {
10
- ...context,
11
- connection: specJson.connection ?? context.connection,
12
- request: specJson.request ?? context.request
13
- };
14
-
15
- for (const [key, value] of Object.entries(specJson)) {
16
- if (key === "connection" || key === "request") continue;
17
-
18
- if (typeof value === "object" && value !== null) {
19
- const nextPath = relativePath
20
- ? `${relativePath}.${key}`
21
- : key;
22
-
23
- const result = await traverse(
24
- value,
25
- nextPath,
26
- pathToFind,
27
- nextContext
28
- );
29
-
30
- if (result !== undefined) {
31
- return result;
32
- }
33
- }
34
- }
35
-
36
- return undefined;
37
- };
38
-
39
- export default traverseObject;
@@ -1,67 +0,0 @@
1
- import source from "../source.json" with { type: "json" };
2
- import traverse from "../traverse.js";
3
- import apiPaths from "./api.json" with { type: "json" };
4
-
5
- const createApi = (options = {}) => {
6
- const connection = {
7
- ...source.tally.connection,
8
- ...options.connection,
9
- ...(options.url ? { url: options.url } : {}),
10
- ...(options.method ? { method: options.method } : {}),
11
- headers: {
12
- ...source.tally.connection.headers,
13
- ...options.connection?.headers,
14
- ...options.headers
15
- }
16
- };
17
- const request = options.request ?? source.tally.request;
18
- const fetchImpl = options.fetch ?? globalThis.fetch;
19
- const clientSource = {
20
- ...source,
21
- tally: {
22
- ...source.tally,
23
- connection,
24
- request
25
- }
26
- };
27
-
28
- const createFunction = (path) => async (company) => {
29
- if (typeof company !== "string" || !company.trim()) {
30
- throw new TypeError("Company name is required.");
31
- }
32
-
33
- return await traverse(clientSource, "", path, {
34
- company: company.trim(),
35
- connection,
36
- request,
37
- fetch: fetchImpl,
38
- timeout: options.timeout
39
- });
40
- };
41
-
42
- const root = {};
43
-
44
- for (const path of apiPaths) {
45
- const parts = path.split(".");
46
- let current = root;
47
-
48
- parts.forEach((part, index) => {
49
- const isLast = index === parts.length - 1;
50
-
51
- if (isLast) {
52
- current[part] = createFunction(path);
53
- return;
54
- }
55
-
56
- current[part] ??= {};
57
- current = current[part];
58
- });
59
- }
60
-
61
- const rootName = apiPaths[0]?.split(".")[0];
62
-
63
- return rootName ? root[rootName] : root;
64
- };
65
-
66
- export { createApi };
67
- export default createApi();
@@ -1 +0,0 @@
1
- export { createApi, default } from "./api.js";
package/src/v3/index.js DELETED
@@ -1 +0,0 @@
1
- export { createApi, default } from "./external-api/api.js";
@@ -1,103 +0,0 @@
1
- import traverseObject from "./traverseObject/index.js";
2
-
3
- const escapeXml = (value) => value.replace(/[&<>"']/g, (character) => ({
4
- "&": "&amp;",
5
- "<": "&lt;",
6
- ">": "&gt;",
7
- '"': "&quot;",
8
- "'": "&apos;"
9
- }[character]));
10
-
11
- const buildRequestBody = (requestBody, { company, collection }) => {
12
- return requestBody
13
- .replace("{company}", escapeXml(company))
14
- .replace("{collectionBody}", collection);
15
- };
16
-
17
- const execute = async (connection, xml, fetchImpl, timeout) => {
18
- if (typeof fetchImpl !== "function") {
19
- throw new Error(
20
- "No fetch implementation is available. Use Node.js 20+ or provide fetch to createTallyClient()."
21
- );
22
- }
23
-
24
- const controller = typeof AbortController === "function"
25
- ? new AbortController()
26
- : undefined;
27
- const timeoutId = Number.isFinite(timeout) && timeout > 0
28
- ? setTimeout(() => controller?.abort(), timeout)
29
- : undefined;
30
-
31
- let response;
32
-
33
- try {
34
- response = await fetchImpl(connection.url, {
35
- method: connection.method,
36
- headers: connection.headers,
37
- body: xml,
38
- ...(controller ? { signal: controller.signal } : {})
39
- });
40
- } catch (error) {
41
- if (controller?.signal.aborted) {
42
- throw new Error(`Tally request timed out after ${timeout} ms.`, {
43
- cause: error
44
- });
45
- }
46
-
47
- throw error;
48
- } finally {
49
- if (timeoutId) clearTimeout(timeoutId);
50
- }
51
-
52
- const responseText = await response.text();
53
-
54
- if (!response.ok) {
55
- throw new Error(
56
- `Tally request failed with HTTP ${response.status}: ${responseText}`
57
- );
58
- }
59
-
60
- return responseText;
61
- };
62
-
63
- const traverse = async (
64
- raka,
65
- relativePath,
66
- pathToFind,
67
- context = {}
68
- ) => {
69
- if (relativePath === pathToFind) {
70
- if (raka?.action === "fetch") {
71
- const body = buildRequestBody(
72
- context.request.body,
73
- {
74
- company: context.company,
75
- collection: raka.tdl.collection
76
- }
77
- );
78
-
79
- return await execute(
80
- context.connection,
81
- body,
82
- context.fetch,
83
- context.timeout
84
- );
85
- }
86
-
87
- return raka;
88
- }
89
-
90
- if (typeof raka === "object" && raka !== null) {
91
- return await traverseObject(
92
- raka,
93
- relativePath,
94
- pathToFind,
95
- context
96
- );
97
- }
98
-
99
- return undefined;
100
- };
101
-
102
- export { traverse };
103
- export default traverse;
@@ -1,39 +0,0 @@
1
- import { traverse } from "../traverse.js";
2
-
3
- const traverseObject = async (
4
- specJson,
5
- relativePath,
6
- pathToFind,
7
- context = {}
8
- ) => {
9
- const nextContext = {
10
- ...context,
11
- connection: specJson.connection ?? context.connection,
12
- request: specJson.request ?? context.request
13
- };
14
-
15
- for (const [key, value] of Object.entries(specJson)) {
16
- if (key === "connection" || key === "request") continue;
17
-
18
- if (typeof value === "object" && value !== null) {
19
- const nextPath = relativePath
20
- ? `${relativePath}.${key}`
21
- : key;
22
-
23
- const result = await traverse(
24
- value,
25
- nextPath,
26
- pathToFind,
27
- nextContext
28
- );
29
-
30
- if (result !== undefined) {
31
- return result;
32
- }
33
- }
34
- }
35
-
36
- return undefined;
37
- };
38
-
39
- export default traverseObject;