json-to-spec 19.1.0

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 (217) hide show
  1. package/README.md +118 -0
  2. package/docs/demo.html +426 -0
  3. package/docs/dist/min.js +164 -0
  4. package/docs/dist/v1/min.js +124 -0
  5. package/docs/dist/v17/min.js +355 -0
  6. package/docs/dist/v18/min.js +160 -0
  7. package/docs/dist/v19/min.js +164 -0
  8. package/docs/dist/v2/min.js +129 -0
  9. package/docs/dist/v3/min.js +201 -0
  10. package/docs/index.html +248 -0
  11. package/docs/pages/architecture.html +115 -0
  12. package/docs/pages/how-it-works.html +125 -0
  13. package/docs/pages/what-not.html +100 -0
  14. package/docs/pages/what.html +105 -0
  15. package/docs/pages/why.html +88 -0
  16. package/docs/samples/form.html +265 -0
  17. package/docs/samples/index.html +112 -0
  18. package/docs/samples/table.html +306 -0
  19. package/index.js +2 -0
  20. package/package.json +50 -0
  21. package/samples/dataList/index.html +31 -0
  22. package/samples/dataList/index.js +62 -0
  23. package/samples/dataList/input/data.json +5043 -0
  24. package/samples/dataList/input/structure.json +38 -0
  25. package/samples/dataList copy/index.html +30 -0
  26. package/samples/dataList copy/index.js +61 -0
  27. package/samples/dataList copy/input/data.json +35307 -0
  28. package/samples/dataList copy/input/structure.json +18 -0
  29. package/samples/form/index.html +29 -0
  30. package/samples/form/index.js +64 -0
  31. package/samples/form/input/data.json +9 -0
  32. package/samples/form/input/structure.json +192 -0
  33. package/samples/form-/data.json +42 -0
  34. package/samples/form-/structure.json +110 -0
  35. package/samples/select/index.html +31 -0
  36. package/samples/select/index.js +61 -0
  37. package/samples/select/input/data.json +35287 -0
  38. package/samples/select/input/select.json +18 -0
  39. package/samples/select/input/structure.json +47 -0
  40. package/samples/table/index.html +29 -0
  41. package/samples/table/index.js +61 -0
  42. package/samples/table/input/data.json +35287 -0
  43. package/samples/table/input/structure copy.json +47 -0
  44. package/samples/table/input/structure.json +86 -0
  45. package/samples/table/input/table.json +135 -0
  46. package/samples/table-/data.json +68 -0
  47. package/samples/table-/structure.json +235 -0
  48. package/src/index.js +2 -0
  49. package/src/v10/index.js +96 -0
  50. package/src/v10/instructionEngine/compile/compileTree.js +191 -0
  51. package/src/v10/instructionEngine/compileTree.js +1 -0
  52. package/src/v10/instructionEngine/expandIteration.js +1 -0
  53. package/src/v10/instructionEngine/index.js +29 -0
  54. package/src/v10/instructionEngine/interpolate.js +2 -0
  55. package/src/v10/instructionEngine/iteration/expandIteration.js +95 -0
  56. package/src/v10/instructionEngine/operation/operation.js +237 -0
  57. package/src/v10/instructionEngine/other/other.js +150 -0
  58. package/src/v10/instructionEngine/pipeline/pipeline.js +47 -0
  59. package/src/v10/instructionEngine/replace/replace.js +173 -0
  60. package/src/v10/instructionEngine/resolve/resolvePath.js +18 -0
  61. package/src/v10/instructionEngine/resolve/resolveTokenValue.js +22 -0
  62. package/src/v10/instructionEngine/resolvePath.js +1 -0
  63. package/src/v10/instructionEngine/resolveTokenValue.js +1 -0
  64. package/src/v10/instructionEngine/story/storyInjector.js +50 -0
  65. package/src/v10/instructionEngine/storyInjector.js +1 -0
  66. package/src/v10/instructionEngine/value/interpolate.js +38 -0
  67. package/src/v11/index.js +116 -0
  68. package/src/v11/iterate.js +270 -0
  69. package/src/v11/replace.js +169 -0
  70. package/src/v11/resolvePath.js +29 -0
  71. package/src/v12/index.js +122 -0
  72. package/src/v12/iterate/bindFormValues.js +74 -0
  73. package/src/v12/iterate/expandIteration.js +181 -0
  74. package/src/v12/iterate/index.js +10 -0
  75. package/src/v12/iterate/iterate.js +56 -0
  76. package/src/v12/iterate/iterateNode.js +86 -0
  77. package/src/v12/iterate/resolveCollection.js +37 -0
  78. package/src/v12/iterate.js +270 -0
  79. package/src/v12/replace.js +169 -0
  80. package/src/v12/resolvePath.js +29 -0
  81. package/src/v13/index.js +110 -0
  82. package/src/v13/iterate/bindFormValues.js +74 -0
  83. package/src/v13/iterate/expandIteration.js +188 -0
  84. package/src/v13/iterate/index.js +9 -0
  85. package/src/v13/iterate/iterate.js +32 -0
  86. package/src/v13/iterate/iterateNode.js +86 -0
  87. package/src/v13/iterate/resolveCollection.js +37 -0
  88. package/src/v13/iterate/walk.js +90 -0
  89. package/src/v13/iterate.js +270 -0
  90. package/src/v13/replace.js +169 -0
  91. package/src/v13/resolvePath.js +29 -0
  92. package/src/v14/index.js +112 -0
  93. package/src/v14/iterate/bindFormValues.js +74 -0
  94. package/src/v14/iterate/expandIteration.js +188 -0
  95. package/src/v14/iterate/index.js +9 -0
  96. package/src/v14/iterate/iterate.js +32 -0
  97. package/src/v14/iterate/resolveCollection.js +37 -0
  98. package/src/v14/iterate/walk/walk copy 2.js +114 -0
  99. package/src/v14/iterate/walk/walk copy.js +90 -0
  100. package/src/v14/iterate/walk/walk.js +98 -0
  101. package/src/v14/iterate.js +270 -0
  102. package/src/v14/replace/index.js +16 -0
  103. package/src/v14/replace/walk.js +90 -0
  104. package/src/v14/replace.js +153 -0
  105. package/src/v14/resolvePath.js +29 -0
  106. package/src/v15/index.js +123 -0
  107. package/src/v15/iterate/bindFormValues.js +74 -0
  108. package/src/v15/iterate/expandIteration.js +188 -0
  109. package/src/v15/iterate/index.js +9 -0
  110. package/src/v15/iterate/iterate.js +32 -0
  111. package/src/v15/iterate/resolveCollection.js +37 -0
  112. package/src/v15/iterate/walk/walk copy 2.js +114 -0
  113. package/src/v15/iterate/walk/walk copy.js +90 -0
  114. package/src/v15/iterate/walk/walk.js +195 -0
  115. package/src/v15/iterate.js +270 -0
  116. package/src/v15/replace/index.js +16 -0
  117. package/src/v15/replace/walk.js +90 -0
  118. package/src/v15/replace.js +155 -0
  119. package/src/v15/resolvePath.js +29 -0
  120. package/src/v16/index.js +129 -0
  121. package/src/v16/iterate/bindFormValues.js +74 -0
  122. package/src/v16/iterate/expandIteration.js +188 -0
  123. package/src/v16/iterate/index.js +9 -0
  124. package/src/v16/iterate/iterate.js +32 -0
  125. package/src/v16/iterate/resolveCollection.js +37 -0
  126. package/src/v16/iterate/walk/walk copy 2.js +114 -0
  127. package/src/v16/iterate/walk/walk copy.js +90 -0
  128. package/src/v16/iterate/walk/walk.js +196 -0
  129. package/src/v16/iterate.js +270 -0
  130. package/src/v16/replace/index.js +16 -0
  131. package/src/v16/replace/walk.js +90 -0
  132. package/src/v16/replace.js +155 -0
  133. package/src/v16/resolvePath.js +29 -0
  134. package/src/v17/index.js +119 -0
  135. package/src/v17/iterate/bindFormValues.js +74 -0
  136. package/src/v17/iterate/expandIteration.js +188 -0
  137. package/src/v17/iterate/index.js +9 -0
  138. package/src/v17/iterate/iterate.js +32 -0
  139. package/src/v17/iterate/resolveCollection.js +37 -0
  140. package/src/v17/iterate/walk/iterateDo.js +42 -0
  141. package/src/v17/iterate/walk/replaceWithData.js +60 -0
  142. package/src/v17/iterate/walk/walk.js +94 -0
  143. package/src/v17/iterate.js +270 -0
  144. package/src/v17/replace/index.js +16 -0
  145. package/src/v17/replace/walk.js +90 -0
  146. package/src/v17/replace.js +160 -0
  147. package/src/v17/resolvePath.js +29 -0
  148. package/src/v18/index.js +66 -0
  149. package/src/v18/meta.js +7 -0
  150. package/src/v18/registerGlobal.js +17 -0
  151. package/src/v18/replace.js +18 -0
  152. package/src/v18/resolvePath.js +29 -0
  153. package/src/v18/walk/iterate/v1/index.js +42 -0
  154. package/src/v18/walk/iterate/v2/index.js +32 -0
  155. package/src/v18/walk/iterate/v3/index.js +46 -0
  156. package/src/v18/walk/iterate/v4/createChildren.js +24 -0
  157. package/src/v18/walk/iterate/v4/index.js +25 -0
  158. package/src/v18/walk/replaceWithData/v1/index.js +42 -0
  159. package/src/v18/walk/replaceWithData/v1/replaceCommon.js +21 -0
  160. package/src/v18/walk/replaceWithData/v2/index.js +105 -0
  161. package/src/v18/walk/replaceWithData/v2/replaceCommon.js +21 -0
  162. package/src/v18/walk/replaceWithData/v3/index.js +15 -0
  163. package/src/v18/walk/replaceWithData/v3/replaceAttributes.js +29 -0
  164. package/src/v18/walk/replaceWithData/v3/replaceCommon.js +23 -0
  165. package/src/v18/walk/replaceWithData/v3/replaceNodeValue.js +27 -0
  166. package/src/v18/walk/walk.js +94 -0
  167. package/src/v19/index.js +55 -0
  168. package/src/v19/meta.js +7 -0
  169. package/src/v19/registerGlobal.js +17 -0
  170. package/src/v19/replace.js +18 -0
  171. package/src/v19/resolvePath.js +29 -0
  172. package/src/v19/walk/iterate/v1/index.js +42 -0
  173. package/src/v19/walk/iterate/v2/index.js +32 -0
  174. package/src/v19/walk/iterate/v3/index.js +46 -0
  175. package/src/v19/walk/iterate/v4/createChildren.js +27 -0
  176. package/src/v19/walk/iterate/v4/index.js +25 -0
  177. package/src/v19/walk/replaceWithData/v1/index.js +42 -0
  178. package/src/v19/walk/replaceWithData/v1/replaceCommon.js +21 -0
  179. package/src/v19/walk/replaceWithData/v2/index.js +105 -0
  180. package/src/v19/walk/replaceWithData/v2/replaceCommon.js +21 -0
  181. package/src/v19/walk/replaceWithData/v3/index.js +15 -0
  182. package/src/v19/walk/replaceWithData/v3/replaceAttributes.js +29 -0
  183. package/src/v19/walk/replaceWithData/v3/replaceCommon.js +23 -0
  184. package/src/v19/walk/replaceWithData/v3/replaceNodeValue.js +27 -0
  185. package/src/v19/walk/walk.js +97 -0
  186. package/src/v8/index.js +69 -0
  187. package/src/v8/instructionEngine/compile/compileTree.js +191 -0
  188. package/src/v8/instructionEngine/compileTree.js +1 -0
  189. package/src/v8/instructionEngine/expandIteration.js +1 -0
  190. package/src/v8/instructionEngine/index.js +16 -0
  191. package/src/v8/instructionEngine/interpolate.js +2 -0
  192. package/src/v8/instructionEngine/iteration/expandIteration.js +95 -0
  193. package/src/v8/instructionEngine/resolve/resolvePath.js +18 -0
  194. package/src/v8/instructionEngine/resolve/resolveTokenValue.js +22 -0
  195. package/src/v8/instructionEngine/resolvePath.js +1 -0
  196. package/src/v8/instructionEngine/resolveTokenValue.js +1 -0
  197. package/src/v8/instructionEngine/story/storyInjector.js +50 -0
  198. package/src/v8/instructionEngine/storyInjector.js +1 -0
  199. package/src/v8/instructionEngine/value/interpolate.js +38 -0
  200. package/src/v9/index.js +96 -0
  201. package/src/v9/instructionEngine/compile/compileTree.js +191 -0
  202. package/src/v9/instructionEngine/compileTree.js +1 -0
  203. package/src/v9/instructionEngine/expandIteration.js +1 -0
  204. package/src/v9/instructionEngine/index.js +29 -0
  205. package/src/v9/instructionEngine/interpolate.js +2 -0
  206. package/src/v9/instructionEngine/iteration/expandIteration.js +95 -0
  207. package/src/v9/instructionEngine/operation/operation.js +237 -0
  208. package/src/v9/instructionEngine/other/other.js +150 -0
  209. package/src/v9/instructionEngine/pipeline/pipeline.js +47 -0
  210. package/src/v9/instructionEngine/replace/replace.js +173 -0
  211. package/src/v9/instructionEngine/resolve/resolvePath.js +18 -0
  212. package/src/v9/instructionEngine/resolve/resolveTokenValue.js +22 -0
  213. package/src/v9/instructionEngine/resolvePath.js +1 -0
  214. package/src/v9/instructionEngine/resolveTokenValue.js +1 -0
  215. package/src/v9/instructionEngine/story/storyInjector.js +50 -0
  216. package/src/v9/instructionEngine/storyInjector.js +1 -0
  217. package/src/v9/instructionEngine/value/interpolate.js +38 -0
@@ -0,0 +1,114 @@
1
+
2
+ /**
3
+ * Applies the supplied operation to the current node.
4
+ */
5
+ const applyOperation = ({
6
+ inNode,
7
+ inContext = {},
8
+ inData = {},
9
+ inOperation
10
+ } = {}) => {
11
+ if (typeof inOperation !== "function") {
12
+ return inNode;
13
+ }
14
+
15
+ const operatedNode = inOperation({
16
+ inNode,
17
+ inContext,
18
+ inData
19
+ });
20
+
21
+ return operatedNode === undefined
22
+ ? inNode
23
+ : operatedNode;
24
+ };
25
+
26
+ /**
27
+ * Recursively walks a JSON structure.
28
+ *
29
+ * The walker knows only how to traverse.
30
+ * The supplied operation decides what to do with each node.
31
+ */
32
+ const walk = ({
33
+ inNode,
34
+ inContext = {},
35
+ inData = {},
36
+ inOperation
37
+ } = {}) => {
38
+ const localNode = inNode;
39
+ const localContext = inContext;
40
+ const localData = inData;
41
+
42
+ if (localNode === null || localNode === undefined) {
43
+ return localNode;
44
+ }
45
+
46
+ if (Array.isArray(localNode)) {
47
+ const results = [];
48
+
49
+ for (const child of localNode) {
50
+ const result = walk({
51
+ inNode: child,
52
+ inContext: localContext,
53
+ inData: localData,
54
+ inOperation
55
+ });
56
+
57
+ if (Array.isArray(result)) {
58
+ results.push(...result);
59
+ } else if (result !== null && result !== undefined) {
60
+ results.push(result);
61
+ }
62
+ }
63
+
64
+ return results;
65
+ }
66
+
67
+ if (typeof localNode !== "object") {
68
+ return localNode;
69
+ }
70
+
71
+ const localOperatedNode = applyOperation({
72
+ inNode: localNode,
73
+ inContext: localContext,
74
+ inData: localData,
75
+ inOperation
76
+ });
77
+
78
+ if (localOperatedNode === null) {
79
+ return null;
80
+ }
81
+
82
+ if (Array.isArray(localOperatedNode)) {
83
+ return walk({
84
+ inNode: localOperatedNode,
85
+ inContext: localContext,
86
+ inData: localData,
87
+ inOperation
88
+ });
89
+ }
90
+
91
+ if (typeof localOperatedNode !== "object") {
92
+ return localOperatedNode;
93
+ }
94
+
95
+ const clone = { ...localOperatedNode };
96
+
97
+ if (Array.isArray(clone.children)) {
98
+ clone.children = walk({
99
+ inNode: clone.children,
100
+ inContext: localContext,
101
+ inData: localData,
102
+ inOperation
103
+ });
104
+ }
105
+
106
+ return clone;
107
+ };
108
+
109
+ export {
110
+ walk,
111
+ applyOperation
112
+ };
113
+
114
+ export default walk;
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Recursively walks a JSON structure.
3
+ *
4
+ * The walker knows only how to traverse.
5
+ * The supplied operation decides what to do with each node.
6
+ */
7
+ const walk = ({
8
+ inNode,
9
+ inContext = {},
10
+ inData = {},
11
+ inOperation
12
+ } = {}) => {
13
+ const localNode = inNode;
14
+ const localContext = inContext;
15
+ const localData = inData;
16
+
17
+ if (localNode === null || localNode === undefined) {
18
+ return localNode;
19
+ }
20
+
21
+ if (Array.isArray(localNode)) {
22
+ const results = [];
23
+
24
+ for (const child of localNode) {
25
+ const result = walk({
26
+ inNode: child,
27
+ inContext: localContext,
28
+ inData: localData,
29
+ inOperation
30
+ });
31
+
32
+ if (Array.isArray(result)) {
33
+ results.push(...result);
34
+ } else if (result !== null && result !== undefined) {
35
+ results.push(result);
36
+ }
37
+ }
38
+
39
+ return results;
40
+ }
41
+
42
+ if (typeof localNode !== "object") {
43
+ return localNode;
44
+ }
45
+
46
+ const operatedNode = typeof inOperation === "function"
47
+ ? inOperation({
48
+ inNode: localNode,
49
+ inContext: localContext,
50
+ inData: localData
51
+ })
52
+ : localNode;
53
+
54
+ const localOperatedNode =
55
+ operatedNode === undefined
56
+ ? localNode
57
+ : operatedNode;
58
+
59
+ if (localOperatedNode === null) {
60
+ return null;
61
+ }
62
+
63
+ if (Array.isArray(localOperatedNode)) {
64
+ return walk({
65
+ inNode: localOperatedNode,
66
+ inContext: localContext,
67
+ inData: localData,
68
+ inOperation
69
+ });
70
+ }
71
+
72
+ if (typeof localOperatedNode !== "object") {
73
+ return localOperatedNode;
74
+ }
75
+
76
+ const clone = { ...localOperatedNode };
77
+
78
+ if (Array.isArray(clone.children)) {
79
+ clone.children = walk({
80
+ inNode: clone.children,
81
+ inContext: localContext,
82
+ inData: localData,
83
+ inOperation
84
+ });
85
+ }
86
+
87
+ return clone;
88
+ };
89
+
90
+ export default walk;
@@ -0,0 +1,196 @@
1
+ const replaceCommonFunc = ({ inData, inDataKey }) => {
2
+ const dataKey = inDataKey;
3
+ console.log("dataKey : ", dataKey, inData);
4
+
5
+ let valueToReturn = inData[dataKey];
6
+
7
+ if (dataKey.includes(".")) {
8
+ const keysOfArray = dataKey.split(".");
9
+
10
+ const value = keysOfArray.reduce(
11
+ (current, key) => current?.[key],
12
+ inData
13
+ );
14
+
15
+ valueToReturn = value;
16
+ };
17
+
18
+ return valueToReturn;
19
+ };
20
+
21
+ const replaceWithData = ({
22
+ inNode,
23
+ inData,
24
+ } = {}) => {
25
+ const localNode = inNode;
26
+ const localData = inData;
27
+
28
+ if ("textContent" in inNode) {
29
+ if (inNode.textContent.includes("${")) {
30
+ const dataKey = inNode.textContent
31
+ .replace(/^\$\{/, "")
32
+ .replace(/\}$/, "");
33
+
34
+ inNode.textContent = replaceCommonFunc({ inData, inDataKey: dataKey });
35
+
36
+ };
37
+ };
38
+
39
+ if ("attributes" in inNode) {
40
+ const attributes = Object.fromEntries(
41
+ Object.entries(inNode.attributes || {}).map(([key, value]) => [
42
+ key,
43
+ typeof value === "string" && value.includes("${")
44
+ ? replaceCommonFunc({
45
+ inData,
46
+ inDataKey: value
47
+ .replace(/^\$\{/, "")
48
+ .replace(/\}$/, "")
49
+ })
50
+ : value
51
+ ])
52
+ );
53
+
54
+ // console.log("attributes----- : ", inNode, attributes);
55
+
56
+ inNode.attributes = { ...attributes };
57
+ };
58
+ };
59
+
60
+ const iterateDo = ({
61
+ inNode,
62
+ inData,
63
+ } = {}) => {
64
+ const localNode = inNode;
65
+ const localData = inData;
66
+
67
+ if ("jsonToSpec" in localNode) {
68
+
69
+ if ("operation" in localNode?.jsonToSpec) {
70
+ if (localNode?.jsonToSpec?.operation === "iterate") {
71
+
72
+ if ("source" in localNode?.jsonToSpec) {
73
+ if (localNode?.jsonToSpec?.source === "columns") {
74
+ const columns = inData[localNode?.jsonToSpec?.source];
75
+
76
+ const newChildren = columns.map(loopColumn => {
77
+ const clone = structuredClone(localNode?.jsonToSpec?.template);
78
+
79
+ const k1 = walk({
80
+ inNode: clone,
81
+ inData: loopColumn,
82
+ inOperation: "replace"
83
+ });
84
+
85
+ return k1
86
+ });
87
+
88
+ localNode.children = newChildren;
89
+
90
+ // console.log("newChildren : ", newChildren);
91
+ };
92
+ };
93
+
94
+ };
95
+ };
96
+ };
97
+
98
+ console.log("localNode : ", localNode);
99
+
100
+ };
101
+
102
+ const forArray = ({ inNode, inData, inOperation }) => {
103
+ const localNode = inNode;
104
+ const localData = inData;
105
+ const localOperation = inOperation;
106
+
107
+ console.log("forArray : ", inNode, inOperation);
108
+
109
+ if (Array.isArray(localNode)) {
110
+ const results = [];
111
+
112
+ for (const child of localNode) {
113
+ const result = walk({
114
+ inNode: child,
115
+ inData, inOperation: localOperation
116
+ });
117
+
118
+ if (Array.isArray(result)) {
119
+ results.push(...result);
120
+ } else if (result !== null && result !== undefined) {
121
+ results.push(result);
122
+ };
123
+ };
124
+
125
+ return results;
126
+ };
127
+ };
128
+
129
+ /**
130
+ * Recursively walks a JSON structure.
131
+ *
132
+ * The walker knows only how to traverse.
133
+ * The supplied operation decides what to do with each node.
134
+ */
135
+ const walk = ({
136
+ inNode,
137
+ inData = {},
138
+ inOperation
139
+ } = {}) => {
140
+ const localNode = inNode;
141
+ const localData = inData;
142
+ const localOperation = inOperation;
143
+ // debugger
144
+ if (localNode === null || localNode === undefined) {
145
+ return localNode;
146
+ }
147
+
148
+ if (Array.isArray(localNode)) {
149
+ return forArray({
150
+ inNode: localNode, inData,
151
+ inOperation: localOperation
152
+ });
153
+ };
154
+
155
+ if ("children" in localNode) {
156
+ if (Array.isArray(localNode?.children)) {
157
+ localNode.children = forArray({
158
+ inNode: localNode?.children,
159
+ inData, inOperation: localOperation
160
+ });
161
+ };
162
+ };
163
+
164
+ if (typeof localNode !== "object") {
165
+ return localNode;
166
+ };
167
+
168
+ // console.log("localOperation :", localOperation);
169
+
170
+ switch (localOperation) {
171
+ case "replace":
172
+ if (typeof localNode === "object") {
173
+ console.log("yyyyyyyyyy :", typeof localNode === "object");
174
+ replaceWithData({
175
+ inNode: localNode,
176
+ inData
177
+ });
178
+ };
179
+ break;
180
+ case "iterateDo":
181
+ iterateDo({
182
+ inNode: localNode,
183
+ inData
184
+ });
185
+ default:
186
+ break;
187
+ };
188
+
189
+ return localNode;
190
+ };
191
+
192
+ export {
193
+ walk
194
+ };
195
+
196
+ export default walk;
@@ -0,0 +1,270 @@
1
+ import resolvePath from "./resolvePath.js";
2
+ import { replaceNode } from "./replace.js";
3
+
4
+ /**
5
+ * Resolves the collection array targeted by an iteration instruction.
6
+ */
7
+ const resolveCollection = ({ inNode, inContext, inData }) => {
8
+ const localNode = inNode;
9
+ const localContext = inContext;
10
+ const localData = inData;
11
+
12
+ const instruction = localNode && (localNode.jsonToSpec || (localNode.operation ? localNode : null));
13
+ if (!instruction) return undefined;
14
+
15
+ const sourceKey = instruction.source || instruction.iterateOn || instruction.$iterate;
16
+ if (!sourceKey) return undefined;
17
+
18
+ return resolvePath({ inData: localData, inPath: sourceKey })
19
+ || (localData && localData[sourceKey])
20
+ || resolvePath({ inData: localContext, inPath: sourceKey })
21
+ || (localContext && localContext[sourceKey]);
22
+ };
23
+
24
+ /**
25
+ * Recursively binds form field values into input, textarea, select, option nodes.
26
+ */
27
+ const bindFormValues = ({ inNode, inItem, inData }) => {
28
+ const localNode = inNode;
29
+ const localItem = inItem;
30
+ const localData = inData;
31
+
32
+ if (!localNode || typeof localNode !== "object") return localNode;
33
+
34
+ if (localNode.attributes) {
35
+ const isFormField = ["input", "textarea", "select", "option"].includes(localNode.tagName?.toLowerCase());
36
+ if (isFormField) {
37
+ const fieldName = localItem.field || localItem.columnName || localItem.name;
38
+ if (localItem.value !== undefined && localItem.value !== null) {
39
+ localNode.attributes.value = String(localItem.value);
40
+ if (localNode.tagName === "textarea" && !localNode.textContent) {
41
+ localNode.textContent = String(localItem.value);
42
+ }
43
+ } else if (fieldName && localData[fieldName] !== undefined && localData[fieldName] !== null) {
44
+ localNode.attributes.value = String(localData[fieldName]);
45
+ if (localNode.tagName === "textarea" && !localNode.textContent) {
46
+ localNode.textContent = String(localData[fieldName]);
47
+ }
48
+ }
49
+ }
50
+ }
51
+
52
+ if (Array.isArray(localNode.children)) {
53
+ localNode.children.forEach(child => bindFormValues({ inNode: child, inItem: localItem, inData: localData }));
54
+ }
55
+
56
+ return localNode;
57
+ };
58
+
59
+ /**
60
+ * Expands a single iteration directive into an array of DOM element nodes.
61
+ */
62
+ const expandIteration = ({ inNode, inContext, inData }) => {
63
+ const localNode = inNode;
64
+ const localContext = inContext;
65
+ const localData = inData;
66
+
67
+ const instruction = localNode && (localNode.jsonToSpec || (localNode.operation ? localNode : null));
68
+ if (!instruction) return undefined;
69
+
70
+ const operationType = instruction.operation;
71
+ if (operationType !== "iterate" && !instruction.source && !instruction.$iterate) {
72
+ return undefined;
73
+ }
74
+
75
+ const sourceKey = instruction.source || instruction.iterateOn || instruction.$iterate;
76
+ const collection = resolveCollection({
77
+ inNode: localNode,
78
+ inContext: localContext,
79
+ inData: localData
80
+ }) || [];
81
+
82
+ if (!Array.isArray(collection)) {
83
+ if (localNode && localNode.tagName) {
84
+ const cloned = { ...localNode };
85
+ delete cloned.jsonToSpec;
86
+ cloned.children = [];
87
+ return cloned;
88
+ }
89
+ return [];
90
+ }
91
+
92
+ const template = instruction.template || instruction.item || {};
93
+ const filter = instruction.filter;
94
+
95
+ const filtered = collection.filter(item => {
96
+ if (!item || typeof item !== "object") return true;
97
+ if (filter && typeof filter === "object") {
98
+ for (const [key, value] of Object.entries(filter)) {
99
+ if (item[key] !== value) return false;
100
+ }
101
+ }
102
+ if (item.isVisible === false) return false;
103
+ return true;
104
+ });
105
+
106
+ const expandedChildren = [];
107
+ filtered.forEach((item, index) => {
108
+ const itemContext = {
109
+ ...localContext,
110
+ item,
111
+ ...(typeof item === "object" && item !== null ? item : {}),
112
+ $index: index,
113
+ $number: index + 1
114
+ };
115
+
116
+ if (sourceKey === "rows" || sourceKey.endsWith(".rows") || sourceKey === "items" || sourceKey.endsWith("Rows")) {
117
+ itemContext.row = item;
118
+ }
119
+
120
+ if (localContext.row && (item.field || item.columnName || item.name)) {
121
+ const fieldKey = item.field || item.columnName || item.name;
122
+ const cellValue = localContext.row[fieldKey];
123
+ if (cellValue !== undefined) {
124
+ itemContext.cellValue = cellValue;
125
+ itemContext.value = cellValue;
126
+ if (typeof item === "object" && item !== null && item.value === undefined) {
127
+ item.value = cellValue;
128
+ }
129
+ }
130
+ }
131
+
132
+ // 1. Clone the template
133
+ const rawTemplate = typeof template === "object" && template !== null
134
+ ? JSON.parse(JSON.stringify(template))
135
+ : { tagName: "span", textContent: template };
136
+
137
+ // 2. Expand any nested iterations within the template
138
+ const iteratedTemplate = iterateNode({
139
+ inNode: rawTemplate,
140
+ inContext: itemContext,
141
+ inData: localData
142
+ });
143
+
144
+ // 3. Replace item-level tokens in the template
145
+ const replacedTemplate = replaceNode({
146
+ inNode: iteratedTemplate,
147
+ inContext: itemContext,
148
+ inData: localData
149
+ });
150
+
151
+ bindFormValues({
152
+ inNode: replacedTemplate,
153
+ inItem: item,
154
+ inData: localData
155
+ });
156
+
157
+ if (Array.isArray(replacedTemplate)) {
158
+ expandedChildren.push(...replacedTemplate);
159
+ } else if (replacedTemplate !== null && replacedTemplate !== undefined) {
160
+ expandedChildren.push(replacedTemplate);
161
+ }
162
+ });
163
+
164
+ // If jsonToSpec was a sibling on a container node (e.g. <div class="row" jsonToSpec="...">)
165
+ if (localNode && localNode.tagName) {
166
+ const cloned = { ...localNode };
167
+ delete cloned.jsonToSpec;
168
+ cloned.children = expandedChildren;
169
+ return cloned;
170
+ }
171
+
172
+ return expandedChildren;
173
+ };
174
+
175
+ /**
176
+ * Recursively walks a JSON tree and resolves all jsonToSpec iteration directives.
177
+ */
178
+ export const iterateNode = ({ inNode, inContext = {}, inData = {} } = {}) => {
179
+ const localNode = inNode;
180
+ const localContext = inContext;
181
+ const localData = inData;
182
+
183
+ if (localNode === null || localNode === undefined) return localNode;
184
+
185
+ if (Array.isArray(localNode)) {
186
+ const flattened = [];
187
+ for (const child of localNode) {
188
+ const processed = iterateNode({
189
+ inNode: child,
190
+ inContext: localContext,
191
+ inData: localData
192
+ });
193
+
194
+ if (Array.isArray(processed)) {
195
+ flattened.push(...processed);
196
+ } else if (processed !== null && processed !== undefined) {
197
+ flattened.push(processed);
198
+ }
199
+ }
200
+ return flattened;
201
+ }
202
+
203
+ if (typeof localNode !== "object") {
204
+ return localNode;
205
+ }
206
+
207
+ // Check if current node is or has an iteration directive
208
+ const iterationResult = expandIteration({
209
+ inNode: localNode,
210
+ inContext: localContext,
211
+ inData: localData
212
+ });
213
+
214
+ if (iterationResult !== undefined) {
215
+ return iterationResult;
216
+ }
217
+
218
+ // Standard node: recursively process children
219
+ const clone = { ...localNode };
220
+
221
+ if (Array.isArray(clone.children)) {
222
+ const processedChildren = [];
223
+ for (const child of clone.children) {
224
+ const processed = iterateNode({
225
+ inNode: child,
226
+ inContext: localContext,
227
+ inData: localData
228
+ });
229
+
230
+ if (Array.isArray(processed)) {
231
+ processedChildren.push(...processed);
232
+ } else if (processed !== null && processed !== undefined) {
233
+ processedChildren.push(processed);
234
+ }
235
+ }
236
+ clone.children = processedChildren;
237
+ }
238
+
239
+ return clone;
240
+ };
241
+
242
+ /**
243
+ * Main iterate/operation function: (structure, data) -> expanded JSON specification
244
+ */
245
+ export const iterate = (inStructureOrOptions, inData = {}) => {
246
+ let localStructure = inStructureOrOptions;
247
+ let localData = inData;
248
+ let localContext = {};
249
+
250
+ if (inStructureOrOptions && typeof inStructureOrOptions === "object" && !Array.isArray(inStructureOrOptions)) {
251
+ if ("inStructure" in inStructureOrOptions || "inTree" in inStructureOrOptions || "inNode" in inStructureOrOptions) {
252
+ localStructure = inStructureOrOptions.inStructure || inStructureOrOptions.inTree || inStructureOrOptions.inNode;
253
+ localData = inStructureOrOptions.inData || localData;
254
+ localContext = inStructureOrOptions.inContext || localContext;
255
+ } else if ("structure" in inStructureOrOptions) {
256
+ localStructure = inStructureOrOptions.structure;
257
+ localData = inStructureOrOptions.data || localData;
258
+ localContext = inStructureOrOptions.context || localContext;
259
+ }
260
+ }
261
+
262
+ return iterateNode({
263
+ inNode: localStructure,
264
+ inContext: localContext,
265
+ inData: localData
266
+ });
267
+ };
268
+
269
+ export const operation = iterate;
270
+ export default iterate;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * replace/index.js
3
+ *
4
+ * Responsibility:
5
+ * - Provide the public replace API for the v14 replace phase.
6
+ * - For now this is a thin wrapper that re-exports the existing
7
+ * implementation in `../replace.js` so no public imports break.
8
+ * - Later the implementation can be moved into this folder and
9
+ * the wrapper updated accordingly.
10
+ */
11
+
12
+ import replaceDefault, { replace, replaceNode } from "../replace.js";
13
+
14
+ export { replace, replaceNode };
15
+
16
+ export default replaceDefault;