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/src/index.js
CHANGED
|
@@ -1,8 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const createTallyClient = (options = {}) => createApi(options);
|
|
4
|
-
|
|
5
|
-
const tally = createTallyClient();
|
|
6
|
-
|
|
7
|
-
export { createTallyClient, tally };
|
|
8
|
-
export default tally;
|
|
1
|
+
export { default } from "./v8/index.js";
|
|
2
|
+
export * from "./v8/index.js";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* tally-simple (v5)
|
|
3
|
+
*
|
|
4
|
+
* Public Entry Point:
|
|
5
|
+
* Connects the public allowlist (api.json) and domain specification (source.json)
|
|
6
|
+
* through the internal-working route and execution engines.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import source from "../source.json" with { type: "json" };
|
|
10
|
+
import apiPaths from "./api.json" with { type: "json" };
|
|
11
|
+
|
|
12
|
+
import createRoute from "../internal-working/route/index.js";
|
|
13
|
+
import execute from "../internal-working/execution/index.js";
|
|
14
|
+
|
|
15
|
+
const tally = createRoute({
|
|
16
|
+
inApiPaths: apiPaths,
|
|
17
|
+
inSource: source,
|
|
18
|
+
inExecutor: execute
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
export default tally;
|
package/src/v5/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./external-api/api.js";
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const escapeXml = (value) => value.replace(/[&<>"']/g, (character) => ({
|
|
2
|
+
"&": "&",
|
|
3
|
+
"<": "<",
|
|
4
|
+
">": ">",
|
|
5
|
+
'"': """,
|
|
6
|
+
"'": "'"
|
|
7
|
+
}[character]));
|
|
8
|
+
|
|
9
|
+
const xmlEnvelopeTemplate = `<ENVELOPE>
|
|
10
|
+
<HEADER>
|
|
11
|
+
<VERSION>1</VERSION>
|
|
12
|
+
<TALLYREQUEST>Export</TALLYREQUEST>
|
|
13
|
+
<TYPE>Collection</TYPE>
|
|
14
|
+
<ID>TDLID</ID>
|
|
15
|
+
</HEADER>
|
|
16
|
+
<BODY>
|
|
17
|
+
<DESC>
|
|
18
|
+
<STATICVARIABLES>
|
|
19
|
+
<SVEXPORTFORMAT>$$SysName:XML</SVEXPORTFORMAT>
|
|
20
|
+
<SVCURRENTCOMPANY>{company}</SVCURRENTCOMPANY>
|
|
21
|
+
</STATICVARIABLES>
|
|
22
|
+
<TDL>
|
|
23
|
+
<TDLMESSAGE>
|
|
24
|
+
<COLLECTION NAME="TDLID">
|
|
25
|
+
{collectionBody}</COLLECTION>
|
|
26
|
+
</TDLMESSAGE>
|
|
27
|
+
</TDL>
|
|
28
|
+
</DESC>
|
|
29
|
+
</BODY>
|
|
30
|
+
</ENVELOPE>`;
|
|
31
|
+
|
|
32
|
+
const startFunc = ({ inCompany, inTdl }) => {
|
|
33
|
+
const localCompany = inCompany;
|
|
34
|
+
const localTdl = inTdl;
|
|
35
|
+
|
|
36
|
+
return xmlEnvelopeTemplate
|
|
37
|
+
.replace("{company}", escapeXml(localCompany))
|
|
38
|
+
.replace("{collectionBody}", localTdl?.collection ?? "");
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export default startFunc;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const startFunc = ({ inSource, inRoutePath }) => {
|
|
2
|
+
const localSource = inSource;
|
|
3
|
+
const localRoutePath = inRoutePath;
|
|
4
|
+
|
|
5
|
+
const endpoint = localRoutePath
|
|
6
|
+
.split(".")
|
|
7
|
+
.reduce((current, key) => current?.[key], localSource);
|
|
8
|
+
|
|
9
|
+
return endpoint?.tdl;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export default startFunc;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import validateCompany from "./validateCompany.js";
|
|
2
|
+
import getTdl from "./getTdl.js";
|
|
3
|
+
import buildXmlBody from "./buildXmlBody.js";
|
|
4
|
+
import postHttp from "./postHttp.js";
|
|
5
|
+
|
|
6
|
+
const startFunc = async ({ inRoutePath, inCompany, inSource }) => {
|
|
7
|
+
const localRoutePath = inRoutePath;
|
|
8
|
+
const localCompany = inCompany;
|
|
9
|
+
const localSource = inSource;
|
|
10
|
+
|
|
11
|
+
const companyName = validateCompany({
|
|
12
|
+
inCompany: localCompany
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const tdl = getTdl({
|
|
16
|
+
inSource: localSource,
|
|
17
|
+
inRoutePath: localRoutePath
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const xmlBody = buildXmlBody({
|
|
21
|
+
inCompany: companyName,
|
|
22
|
+
inTdl: tdl
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
return await postHttp({
|
|
26
|
+
inXmlBody: xmlBody
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export default startFunc;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const url = "http://localhost:9000";
|
|
2
|
+
const headers = {
|
|
3
|
+
"Content-Type": "text/xml"
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
const startFunc = async ({ inXmlBody }) => {
|
|
7
|
+
const localXmlBody = inXmlBody;
|
|
8
|
+
|
|
9
|
+
const response = await fetch(url, {
|
|
10
|
+
method: "POST",
|
|
11
|
+
headers: headers,
|
|
12
|
+
body: localXmlBody
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const responseText = await response.text();
|
|
16
|
+
|
|
17
|
+
if (!response.ok) {
|
|
18
|
+
throw new Error(
|
|
19
|
+
`Tally request failed with HTTP ${response.status}: ${responseText}`
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return responseText;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default startFunc;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const startFunc = ({ inCompany }) => {
|
|
2
|
+
const localCompany = inCompany;
|
|
3
|
+
|
|
4
|
+
if (typeof localCompany !== "string" || !localCompany.trim()) {
|
|
5
|
+
throw new TypeError("Company name is required.");
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
return localCompany.trim();
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default startFunc;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import createLeafHandler from "./createLeafHandler.js";
|
|
2
|
+
|
|
3
|
+
const startFunc = ({ inTree, inPath, inSource, inExecutor }) => {
|
|
4
|
+
const localTree = inTree;
|
|
5
|
+
const localPath = inPath;
|
|
6
|
+
const localSource = inSource;
|
|
7
|
+
const localExecutor = inExecutor;
|
|
8
|
+
|
|
9
|
+
const parts = localPath.split(".");
|
|
10
|
+
const leafName = parts.pop();
|
|
11
|
+
|
|
12
|
+
let branch = localTree;
|
|
13
|
+
for (const segment of parts) {
|
|
14
|
+
branch[segment] ??= {};
|
|
15
|
+
branch = branch[segment];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
branch[leafName] = createLeafHandler({
|
|
19
|
+
inPath: localPath,
|
|
20
|
+
inSource: localSource,
|
|
21
|
+
inExecutor: localExecutor
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default startFunc;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const startFunc = ({ inPath, inSource, inExecutor }) => {
|
|
2
|
+
const localPath = inPath;
|
|
3
|
+
const localSource = inSource;
|
|
4
|
+
const localExecutor = inExecutor;
|
|
5
|
+
|
|
6
|
+
return async (inCompany) => {
|
|
7
|
+
const localCompany = inCompany;
|
|
8
|
+
|
|
9
|
+
return await localExecutor({
|
|
10
|
+
inRoutePath: localPath,
|
|
11
|
+
inCompany: localCompany,
|
|
12
|
+
inSource: localSource
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export default startFunc;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import attachPath from "./attachPath.js";
|
|
2
|
+
|
|
3
|
+
const startFunc = ({ inApiPaths, inSource, inExecutor }) => {
|
|
4
|
+
const localApiPaths = inApiPaths;
|
|
5
|
+
const localSource = inSource;
|
|
6
|
+
const localExecutor = inExecutor;
|
|
7
|
+
|
|
8
|
+
const tree = {};
|
|
9
|
+
|
|
10
|
+
for (const path of localApiPaths) {
|
|
11
|
+
attachPath({
|
|
12
|
+
inTree: tree,
|
|
13
|
+
inPath: path,
|
|
14
|
+
inSource: localSource,
|
|
15
|
+
inExecutor: localExecutor
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const rootNamespace = localApiPaths[0]?.split(".")[0];
|
|
20
|
+
|
|
21
|
+
return rootNamespace ? tree[rootNamespace] : tree;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default startFunc;
|
|
@@ -1,15 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"tally": {
|
|
3
|
-
"connection": {
|
|
4
|
-
"url": "http://localhost:9000",
|
|
5
|
-
"method": "POST",
|
|
6
|
-
"headers": {
|
|
7
|
-
"Content-Type": "text/xml"
|
|
8
|
-
}
|
|
9
|
-
},
|
|
10
|
-
"request": {
|
|
11
|
-
"body": "<ENVELOPE>\n<HEADER>\n<VERSION>1</VERSION>\n<TALLYREQUEST>Export</TALLYREQUEST>\n<TYPE>Collection</TYPE>\n<ID>TDLID</ID>\n</HEADER>\n<BODY>\n<DESC>\n<STATICVARIABLES>\n<SVEXPORTFORMAT>$$SysName:XML</SVEXPORTFORMAT>\n<SVCURRENTCOMPANY>{company}</SVCURRENTCOMPANY>\n</STATICVARIABLES>\n<TDL>\n<TDLMESSAGE>\n<COLLECTION NAME=\"TDLID\">\n{collectionBody}</COLLECTION>\n</TDLMESSAGE>\n</TDL>\n</DESC>\n</BODY>\n</ENVELOPE>"
|
|
12
|
-
},
|
|
13
3
|
"masters": {
|
|
14
4
|
"units": {
|
|
15
5
|
"fetch": {
|
|
@@ -45,4 +35,4 @@
|
|
|
45
35
|
}
|
|
46
36
|
}
|
|
47
37
|
}
|
|
48
|
-
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* tally-simple (v5)
|
|
3
|
+
*
|
|
4
|
+
* Public Entry Point:
|
|
5
|
+
* Connects the public allowlist (api.json) and domain specification (source.json)
|
|
6
|
+
* through the internal-working route and execution engines.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import source from "../source.json" with { type: "json" };
|
|
10
|
+
import apiPaths from "./api.json" with { type: "json" };
|
|
11
|
+
|
|
12
|
+
import createRoute from "../internal-working/route/index.js";
|
|
13
|
+
import execute from "../internal-working/execution/index.js";
|
|
14
|
+
|
|
15
|
+
const tally = createRoute({
|
|
16
|
+
inApiPaths: apiPaths,
|
|
17
|
+
inSource: source,
|
|
18
|
+
inExecutor: execute
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
export default tally;
|
package/src/v6/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./external-api/api.js";
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const escapeXml = (value) => value.replace(/[&<>"']/g, (character) => ({
|
|
2
|
+
"&": "&",
|
|
3
|
+
"<": "<",
|
|
4
|
+
">": ">",
|
|
5
|
+
'"': """,
|
|
6
|
+
"'": "'"
|
|
7
|
+
}[character]));
|
|
8
|
+
|
|
9
|
+
const xmlEnvelopeTemplate = `<ENVELOPE>
|
|
10
|
+
<HEADER>
|
|
11
|
+
<VERSION>1</VERSION>
|
|
12
|
+
<TALLYREQUEST>Export</TALLYREQUEST>
|
|
13
|
+
<TYPE>Collection</TYPE>
|
|
14
|
+
<ID>TDLID</ID>
|
|
15
|
+
</HEADER>
|
|
16
|
+
<BODY>
|
|
17
|
+
<DESC>
|
|
18
|
+
<STATICVARIABLES>
|
|
19
|
+
<SVEXPORTFORMAT>$$SysName:XML</SVEXPORTFORMAT>
|
|
20
|
+
<SVCURRENTCOMPANY>{company}</SVCURRENTCOMPANY>
|
|
21
|
+
</STATICVARIABLES>
|
|
22
|
+
<TDL>
|
|
23
|
+
<TDLMESSAGE>
|
|
24
|
+
<COLLECTION NAME="TDLID">
|
|
25
|
+
{collectionBody}</COLLECTION>
|
|
26
|
+
</TDLMESSAGE>
|
|
27
|
+
</TDL>
|
|
28
|
+
</DESC>
|
|
29
|
+
</BODY>
|
|
30
|
+
</ENVELOPE>`;
|
|
31
|
+
|
|
32
|
+
const startFunc = ({ inCompany, inTdl }) => {
|
|
33
|
+
const localCompany = inCompany;
|
|
34
|
+
const localTdl = inTdl;
|
|
35
|
+
|
|
36
|
+
return xmlEnvelopeTemplate
|
|
37
|
+
.replace("{company}", escapeXml(localCompany))
|
|
38
|
+
.replace("{collectionBody}", localTdl?.collection ?? "");
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export default startFunc;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const startFunc = ({ inSource, inRoutePath }) => {
|
|
2
|
+
const localSource = inSource;
|
|
3
|
+
const localRoutePath = inRoutePath;
|
|
4
|
+
|
|
5
|
+
const endpoint = localRoutePath
|
|
6
|
+
.split(".")
|
|
7
|
+
.reduce((current, key) => current?.[key], localSource);
|
|
8
|
+
|
|
9
|
+
return endpoint?.tdl;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export default startFunc;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import validateCompany from "./validateCompany.js";
|
|
2
|
+
import getTdl from "./getTdl.js";
|
|
3
|
+
import buildXmlBody from "./buildXmlBody.js";
|
|
4
|
+
import postHttp from "./postHttp.js";
|
|
5
|
+
|
|
6
|
+
const startFunc = async ({ inRoutePath, inCompany, inSource }) => {
|
|
7
|
+
const localRoutePath = inRoutePath;
|
|
8
|
+
const localCompany = inCompany;
|
|
9
|
+
const localSource = inSource;
|
|
10
|
+
|
|
11
|
+
const companyName = validateCompany({
|
|
12
|
+
inCompany: localCompany
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const tdl = getTdl({
|
|
16
|
+
inSource: localSource,
|
|
17
|
+
inRoutePath: localRoutePath
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const xmlBody = buildXmlBody({
|
|
21
|
+
inCompany: companyName,
|
|
22
|
+
inTdl: tdl
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
return await postHttp({
|
|
26
|
+
inXmlBody: xmlBody
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export default startFunc;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const url = "http://localhost:9000";
|
|
2
|
+
const headers = {
|
|
3
|
+
"Content-Type": "text/xml"
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
const startFunc = async ({ inXmlBody }) => {
|
|
7
|
+
const localXmlBody = inXmlBody;
|
|
8
|
+
|
|
9
|
+
const response = await fetch(url, {
|
|
10
|
+
method: "POST",
|
|
11
|
+
headers: headers,
|
|
12
|
+
body: localXmlBody
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const responseText = await response.text();
|
|
16
|
+
|
|
17
|
+
if (!response.ok) {
|
|
18
|
+
throw new Error(
|
|
19
|
+
`Tally request failed with HTTP ${response.status}: ${responseText}`
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return responseText;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default startFunc;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const startFunc = ({ inCompany }) => {
|
|
2
|
+
const localCompany = inCompany;
|
|
3
|
+
|
|
4
|
+
if (typeof localCompany !== "string" || !localCompany.trim()) {
|
|
5
|
+
throw new TypeError("Company name is required.");
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
return localCompany.trim();
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default startFunc;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import createLeafHandler from "./createLeafHandler.js";
|
|
2
|
+
|
|
3
|
+
const startFunc = ({ inTree, inPath, inSource, inExecutor }) => {
|
|
4
|
+
const localTree = inTree;
|
|
5
|
+
const localPath = inPath;
|
|
6
|
+
const localSource = inSource;
|
|
7
|
+
const localExecutor = inExecutor;
|
|
8
|
+
|
|
9
|
+
const parts = localPath.split(".");
|
|
10
|
+
const leafName = parts.pop();
|
|
11
|
+
|
|
12
|
+
let branch = localTree;
|
|
13
|
+
for (const segment of parts) {
|
|
14
|
+
branch[segment] ??= {};
|
|
15
|
+
branch = branch[segment];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
branch[leafName] = createLeafHandler({
|
|
19
|
+
inPath: localPath,
|
|
20
|
+
inSource: localSource,
|
|
21
|
+
inExecutor: localExecutor
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default startFunc;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const startFunc = ({ inPath, inSource, inExecutor }) => {
|
|
2
|
+
const localPath = inPath;
|
|
3
|
+
const localSource = inSource;
|
|
4
|
+
const localExecutor = inExecutor;
|
|
5
|
+
|
|
6
|
+
return async (inCompany) => {
|
|
7
|
+
const localCompany = inCompany;
|
|
8
|
+
|
|
9
|
+
return await localExecutor({
|
|
10
|
+
inRoutePath: localPath,
|
|
11
|
+
inCompany: localCompany,
|
|
12
|
+
inSource: localSource
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export default startFunc;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import attachPath from "./attachPath.js";
|
|
2
|
+
|
|
3
|
+
const startFunc = ({ inApiPaths, inSource, inExecutor }) => {
|
|
4
|
+
const localApiPaths = inApiPaths;
|
|
5
|
+
const localSource = inSource;
|
|
6
|
+
const localExecutor = inExecutor;
|
|
7
|
+
|
|
8
|
+
const tree = {};
|
|
9
|
+
|
|
10
|
+
for (const path of localApiPaths) {
|
|
11
|
+
attachPath({
|
|
12
|
+
inTree: tree,
|
|
13
|
+
inPath: path,
|
|
14
|
+
inSource: localSource,
|
|
15
|
+
inExecutor: localExecutor
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const rootNamespace = localApiPaths[0]?.split(".")[0];
|
|
20
|
+
|
|
21
|
+
return rootNamespace ? tree[rootNamespace] : tree;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default startFunc;
|
|
@@ -1,15 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"tally": {
|
|
3
|
-
"connection": {
|
|
4
|
-
"url": "http://localhost:9000",
|
|
5
|
-
"method": "POST",
|
|
6
|
-
"headers": {
|
|
7
|
-
"Content-Type": "text/xml"
|
|
8
|
-
}
|
|
9
|
-
},
|
|
10
|
-
"request": {
|
|
11
|
-
"body": "<ENVELOPE>\n<HEADER>\n<VERSION>1</VERSION>\n<TALLYREQUEST>Export</TALLYREQUEST>\n<TYPE>Collection</TYPE>\n<ID>TDLID</ID>\n</HEADER>\n<BODY>\n<DESC>\n<STATICVARIABLES>\n<SVEXPORTFORMAT>$$SysName:XML</SVEXPORTFORMAT>\n<SVCURRENTCOMPANY>{company}</SVCURRENTCOMPANY>\n</STATICVARIABLES>\n<TDL>\n<TDLMESSAGE>\n<COLLECTION NAME=\"TDLID\">\n{collectionBody}</COLLECTION>\n</TDLMESSAGE>\n</TDL>\n</DESC>\n</BODY>\n</ENVELOPE>"
|
|
12
|
-
},
|
|
13
3
|
"masters": {
|
|
14
4
|
"units": {
|
|
15
5
|
"fetch": {
|
|
@@ -34,6 +24,14 @@
|
|
|
34
24
|
},
|
|
35
25
|
"action": "fetch"
|
|
36
26
|
}
|
|
27
|
+
},
|
|
28
|
+
"stockGroup": {
|
|
29
|
+
"withParent": {
|
|
30
|
+
"tdl": {
|
|
31
|
+
"collection": "<TYPE>StockGroup</TYPE><FETCH>$$Alias:Name</FETCH><FETCH>Parent</FETCH>"
|
|
32
|
+
},
|
|
33
|
+
"action": "fetch"
|
|
34
|
+
}
|
|
37
35
|
}
|
|
38
36
|
}
|
|
39
37
|
}
|
package/src/v7/api.json
ADDED
package/src/v7/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import source from "./source.json" with { type: "json" };
|
|
2
|
+
import apiPaths from "./api.json" with { type: "json" };
|
|
3
|
+
|
|
4
|
+
import createRoute from "./internal-working/route/index.js";
|
|
5
|
+
import execute from "./internal-working/execution/index.js";
|
|
6
|
+
|
|
7
|
+
const tally = createRoute({
|
|
8
|
+
inApiPaths: apiPaths,
|
|
9
|
+
inSource: source,
|
|
10
|
+
inExecutor: execute
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
export default tally;
|
|
14
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const escapeXml = (value) => value.replace(/[&<>"']/g, (character) => ({
|
|
2
|
+
"&": "&",
|
|
3
|
+
"<": "<",
|
|
4
|
+
">": ">",
|
|
5
|
+
'"': """,
|
|
6
|
+
"'": "'"
|
|
7
|
+
}[character]));
|
|
8
|
+
|
|
9
|
+
const xmlEnvelopeTemplate = `<ENVELOPE>
|
|
10
|
+
<HEADER>
|
|
11
|
+
<VERSION>1</VERSION>
|
|
12
|
+
<TALLYREQUEST>Export</TALLYREQUEST>
|
|
13
|
+
<TYPE>Collection</TYPE>
|
|
14
|
+
<ID>TDLID</ID>
|
|
15
|
+
</HEADER>
|
|
16
|
+
<BODY>
|
|
17
|
+
<DESC>
|
|
18
|
+
<STATICVARIABLES>
|
|
19
|
+
<SVEXPORTFORMAT>$$SysName:XML</SVEXPORTFORMAT>
|
|
20
|
+
<SVCURRENTCOMPANY>{company}</SVCURRENTCOMPANY>
|
|
21
|
+
</STATICVARIABLES>
|
|
22
|
+
<TDL>
|
|
23
|
+
<TDLMESSAGE>
|
|
24
|
+
<COLLECTION NAME="TDLID">
|
|
25
|
+
{collectionBody}</COLLECTION>
|
|
26
|
+
</TDLMESSAGE>
|
|
27
|
+
</TDL>
|
|
28
|
+
</DESC>
|
|
29
|
+
</BODY>
|
|
30
|
+
</ENVELOPE>`;
|
|
31
|
+
|
|
32
|
+
const startFunc = ({ inCompany, inTdl }) => {
|
|
33
|
+
const localCompany = inCompany;
|
|
34
|
+
const localTdl = inTdl;
|
|
35
|
+
|
|
36
|
+
return xmlEnvelopeTemplate
|
|
37
|
+
.replace("{company}", escapeXml(localCompany))
|
|
38
|
+
.replace("{collectionBody}", localTdl?.collection ?? "");
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export default startFunc;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const startFunc = ({ inSource, inRoutePath }) => {
|
|
2
|
+
const localSource = inSource;
|
|
3
|
+
const localRoutePath = inRoutePath;
|
|
4
|
+
|
|
5
|
+
const endpoint = localRoutePath
|
|
6
|
+
.split(".")
|
|
7
|
+
.reduce((current, key) => current?.[key], localSource);
|
|
8
|
+
|
|
9
|
+
return endpoint?.tdl;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export default startFunc;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import validateCompany from "./validateCompany.js";
|
|
2
|
+
import getTdl from "./getTdl.js";
|
|
3
|
+
import buildXmlBody from "./buildXmlBody.js";
|
|
4
|
+
import postHttp from "./postHttp.js";
|
|
5
|
+
|
|
6
|
+
const startFunc = async ({ inRoutePath, inCompany, inSource }) => {
|
|
7
|
+
const localRoutePath = inRoutePath;
|
|
8
|
+
const localCompany = inCompany;
|
|
9
|
+
const localSource = inSource;
|
|
10
|
+
|
|
11
|
+
const companyName = validateCompany({
|
|
12
|
+
inCompany: localCompany
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const tdl = getTdl({
|
|
16
|
+
inSource: localSource,
|
|
17
|
+
inRoutePath: localRoutePath
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const xmlBody = buildXmlBody({
|
|
21
|
+
inCompany: companyName,
|
|
22
|
+
inTdl: tdl
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
return await postHttp({
|
|
26
|
+
inXmlBody: xmlBody
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export default startFunc;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const url = "http://localhost:9000";
|
|
2
|
+
const headers = {
|
|
3
|
+
"Content-Type": "text/xml"
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
const startFunc = async ({ inXmlBody }) => {
|
|
7
|
+
const localXmlBody = inXmlBody;
|
|
8
|
+
|
|
9
|
+
const response = await fetch(url, {
|
|
10
|
+
method: "POST",
|
|
11
|
+
headers: headers,
|
|
12
|
+
body: localXmlBody
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const responseText = await response.text();
|
|
16
|
+
|
|
17
|
+
if (!response.ok) {
|
|
18
|
+
throw new Error(
|
|
19
|
+
`Tally request failed with HTTP ${response.status}: ${responseText}`
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return responseText;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default startFunc;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const startFunc = ({ inCompany }) => {
|
|
2
|
+
const localCompany = inCompany;
|
|
3
|
+
|
|
4
|
+
if (typeof localCompany !== "string" || !localCompany.trim()) {
|
|
5
|
+
throw new TypeError("Company name is required.");
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
return localCompany.trim();
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default startFunc;
|