@blokjs/react 0.2.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.
- package/CHANGELOG.md +149 -0
- package/README.md +1 -0
- package/app/index.jsx +74 -0
- package/babel.config.json +12 -0
- package/config.json +56 -0
- package/dist/app/index.d.ts +3 -0
- package/dist/app/index.js +52 -0
- package/dist/app/index.js.map +1 -0
- package/dist/app/index.merged.min.js +2 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.html +23 -0
- package/dist/index.js +76 -0
- package/dist/index.js.map +1 -0
- package/dist/inputSchema.d.ts +29 -0
- package/dist/inputSchema.js +30 -0
- package/dist/inputSchema.js.map +1 -0
- package/index.html +23 -0
- package/index.ts +92 -0
- package/index.ts.backup +103 -0
- package/inputSchema.ts +29 -0
- package/package.json +43 -0
- package/test/helper.ts +57 -0
- package/test/index.mockup.html +27 -0
- package/test/index.test.ts +32 -0
- package/tsconfig.json +20 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# @blokjs/react
|
|
2
|
+
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Initial public release of Blok packages.
|
|
8
|
+
|
|
9
|
+
This release includes:
|
|
10
|
+
|
|
11
|
+
- Core packages: @blokjs/shared, @blokjs/helper, @blokjs/runner
|
|
12
|
+
- Node packages: @blokjs/api-call, @blokjs/if-else, @blokjs/react
|
|
13
|
+
- Trigger packages: pubsub, queue, webhook, websocket, worker, cron, grpc
|
|
14
|
+
- CLI tool: blokctl
|
|
15
|
+
- Editor support: @blokjs/lsp-server, @blokjs/syntax
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- Updated dependencies
|
|
20
|
+
- @blokjs/shared@0.2.0
|
|
21
|
+
- @blokjs/helper@0.2.0
|
|
22
|
+
- @blokjs/runner@0.2.0
|
|
23
|
+
|
|
24
|
+
## 0.0.17
|
|
25
|
+
|
|
26
|
+
### Patch Changes
|
|
27
|
+
|
|
28
|
+
- Updated dependencies
|
|
29
|
+
- @blokjs/runner@0.1.26
|
|
30
|
+
|
|
31
|
+
## 0.0.16
|
|
32
|
+
|
|
33
|
+
### Patch Changes
|
|
34
|
+
|
|
35
|
+
- Updated dependencies
|
|
36
|
+
- @blokjs/runner@0.1.25
|
|
37
|
+
|
|
38
|
+
## 0.0.15
|
|
39
|
+
|
|
40
|
+
### Patch Changes
|
|
41
|
+
|
|
42
|
+
- Updated dependencies
|
|
43
|
+
- @blokjs/runner@0.1.24
|
|
44
|
+
|
|
45
|
+
## 0.0.14
|
|
46
|
+
|
|
47
|
+
### Patch Changes
|
|
48
|
+
|
|
49
|
+
- Updated dependencies
|
|
50
|
+
- @blokjs/runner@0.1.23
|
|
51
|
+
|
|
52
|
+
## 0.0.13
|
|
53
|
+
|
|
54
|
+
### Patch Changes
|
|
55
|
+
|
|
56
|
+
- Updated dependencies
|
|
57
|
+
- @blokjs/runner@0.1.22
|
|
58
|
+
|
|
59
|
+
## 0.0.12
|
|
60
|
+
|
|
61
|
+
### Patch Changes
|
|
62
|
+
|
|
63
|
+
- Updated dependencies
|
|
64
|
+
- @blokjs/runner@0.1.21
|
|
65
|
+
|
|
66
|
+
## 0.0.11
|
|
67
|
+
|
|
68
|
+
### Patch Changes
|
|
69
|
+
|
|
70
|
+
- Updated dependencies
|
|
71
|
+
- @blokjs/helper@0.1.5
|
|
72
|
+
- @blokjs/runner@0.1.20
|
|
73
|
+
|
|
74
|
+
## 0.0.10
|
|
75
|
+
|
|
76
|
+
### Patch Changes
|
|
77
|
+
|
|
78
|
+
- Updated dependencies
|
|
79
|
+
- @blokjs/runner@0.1.19
|
|
80
|
+
- @blokjs/shared@0.0.9
|
|
81
|
+
|
|
82
|
+
## 0.0.9
|
|
83
|
+
|
|
84
|
+
### Patch Changes
|
|
85
|
+
|
|
86
|
+
- Added examples and create project' command to include examples and 'create node' command with options for type ('module' or 'class') and template ('class' or 'ui')
|
|
87
|
+
- Updated dependencies
|
|
88
|
+
- @blokjs/runner@0.1.18
|
|
89
|
+
- @blokjs/shared@0.0.8
|
|
90
|
+
|
|
91
|
+
## 0.0.8
|
|
92
|
+
|
|
93
|
+
### Patch Changes
|
|
94
|
+
|
|
95
|
+
- Updated dependencies
|
|
96
|
+
- @blokjs/runner@0.1.17
|
|
97
|
+
|
|
98
|
+
## 0.0.7
|
|
99
|
+
|
|
100
|
+
### Patch Changes
|
|
101
|
+
|
|
102
|
+
- Added support for YAML, XML and TOML in the workflow file. Upgraded package version recommended by Dependabot.
|
|
103
|
+
- Updated dependencies
|
|
104
|
+
- @blokjs/helper@0.1.4
|
|
105
|
+
- @blokjs/runner@0.1.16
|
|
106
|
+
- @blokjs/shared@0.0.7
|
|
107
|
+
|
|
108
|
+
## 0.0.6
|
|
109
|
+
|
|
110
|
+
### Patch Changes
|
|
111
|
+
|
|
112
|
+
- Improved the BlokService base class to accept a InputType. This force developer to always create a type to define the Node handle input. Added unit test for pending projects like if-else and api-call.
|
|
113
|
+
- Updated dependencies
|
|
114
|
+
- @blokjs/runner@0.1.15
|
|
115
|
+
|
|
116
|
+
## 0.0.5
|
|
117
|
+
|
|
118
|
+
### Patch Changes
|
|
119
|
+
|
|
120
|
+
- Added configuration options
|
|
121
|
+
|
|
122
|
+
## 0.0.4
|
|
123
|
+
|
|
124
|
+
### Patch Changes
|
|
125
|
+
|
|
126
|
+
- Updated dependencies
|
|
127
|
+
- @blokjs/shared@0.0.6
|
|
128
|
+
- @blokjs/runner@0.1.14
|
|
129
|
+
|
|
130
|
+
## 0.0.3
|
|
131
|
+
|
|
132
|
+
### Patch Changes
|
|
133
|
+
|
|
134
|
+
- Add index.html in the package
|
|
135
|
+
|
|
136
|
+
## 0.0.2
|
|
137
|
+
|
|
138
|
+
### Patch Changes
|
|
139
|
+
|
|
140
|
+
- fixed package.json and dependabot error
|
|
141
|
+
|
|
142
|
+
## 0.0.1
|
|
143
|
+
|
|
144
|
+
### Patch Changes
|
|
145
|
+
|
|
146
|
+
- Implemented a react node and the chatbot demo page
|
|
147
|
+
- Updated dependencies
|
|
148
|
+
- @blokjs/runner@0.1.13
|
|
149
|
+
- @blokjs/shared@0.0.5
|
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Node Documentation
|
package/app/index.jsx
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// public/app.js
|
|
2
|
+
const { useState, useEffect } = React;
|
|
3
|
+
|
|
4
|
+
function ChatBot() {
|
|
5
|
+
const [messages, setMessages] = useState([]);
|
|
6
|
+
const [input, setInput] = useState("");
|
|
7
|
+
const ctx = JSON.parse(atob(ctx_base64));
|
|
8
|
+
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
setMessages((prevMessages) => [
|
|
11
|
+
...prevMessages,
|
|
12
|
+
{ text: "Hello! Let share a fact about cats. Ok?", sender: "bot", id: Math.floor(Math.random() * 100) },
|
|
13
|
+
]);
|
|
14
|
+
setMessages((prevMessages) => [
|
|
15
|
+
...prevMessages,
|
|
16
|
+
{ text: ctx.response.data.fact, sender: "bot", id: Math.floor(Math.random() * 100) },
|
|
17
|
+
]);
|
|
18
|
+
}, []);
|
|
19
|
+
|
|
20
|
+
const handleSubmit = (e) => {
|
|
21
|
+
e.preventDefault();
|
|
22
|
+
if (input.trim()) {
|
|
23
|
+
setMessages([...messages, { text: input, sender: "user", id: Math.floor(Math.random() * 100) }]);
|
|
24
|
+
setInput("");
|
|
25
|
+
|
|
26
|
+
// Simulate bot response
|
|
27
|
+
setTimeout(() => {
|
|
28
|
+
setMessages((prevMessages) => [
|
|
29
|
+
...prevMessages,
|
|
30
|
+
{ text: `You said: ${input}`, sender: "bot", id: Math.floor(Math.random() * 100) },
|
|
31
|
+
]);
|
|
32
|
+
}, 500);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<div className="bg-white rounded-lg shadow-md w-96 overflow-hidden">
|
|
38
|
+
<h1 className="bg-blue-500 text-white text-center py-4 text-xl font-bold">
|
|
39
|
+
Simple {ctx.request.params.workflow}
|
|
40
|
+
</h1>
|
|
41
|
+
<div className="h-96 overflow-y-auto p-4 space-y-4">
|
|
42
|
+
{messages.map((message, index) => (
|
|
43
|
+
<div
|
|
44
|
+
key={message.id}
|
|
45
|
+
className={`p-2 rounded-lg ${
|
|
46
|
+
message.sender === "user" ? "bg-blue-500 text-white ml-auto" : "bg-gray-200 text-gray-800"
|
|
47
|
+
} max-w-[80%] ${message.sender === "user" ? "text-right" : "text-left"}`}
|
|
48
|
+
>
|
|
49
|
+
{message.text}
|
|
50
|
+
</div>
|
|
51
|
+
))}
|
|
52
|
+
</div>
|
|
53
|
+
<form onSubmit={handleSubmit} className="p-4 border-t border-gray-200">
|
|
54
|
+
<div className="flex">
|
|
55
|
+
<input
|
|
56
|
+
type="text"
|
|
57
|
+
value={input}
|
|
58
|
+
onChange={(e) => setInput(e.target.value)}
|
|
59
|
+
placeholder="Type your message..."
|
|
60
|
+
className="flex-grow px-3 py-2 border rounded-l-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
61
|
+
/>
|
|
62
|
+
<button
|
|
63
|
+
type="submit"
|
|
64
|
+
className="bg-blue-500 text-white px-4 py-2 rounded-r-md hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
65
|
+
>
|
|
66
|
+
Send
|
|
67
|
+
</button>
|
|
68
|
+
</div>
|
|
69
|
+
</form>
|
|
70
|
+
</div>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
ReactDOM.render(<ChatBot />, document.getElementById("root"));
|
package/config.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "node-name",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"group": "API",
|
|
6
|
+
"config": {
|
|
7
|
+
"type": "object",
|
|
8
|
+
"properties": {
|
|
9
|
+
"inputs": {
|
|
10
|
+
"type": "object",
|
|
11
|
+
"properties": {},
|
|
12
|
+
"required": []
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"required": ["inputs"],
|
|
16
|
+
"example": {
|
|
17
|
+
"inputs": {
|
|
18
|
+
"properties": {
|
|
19
|
+
"url": "https://countriesnow.space/api/v0.1/countries/capital",
|
|
20
|
+
"method": "POST",
|
|
21
|
+
"headers": {
|
|
22
|
+
"Content-Type": "application/json"
|
|
23
|
+
},
|
|
24
|
+
"body": {
|
|
25
|
+
"data": "Hello World"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"input": {
|
|
32
|
+
"anyOf": [
|
|
33
|
+
{
|
|
34
|
+
"type": "object"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"type": "array"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"type": "string"
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
"description": "This node accepts an object as input from the previous node or request body"
|
|
44
|
+
},
|
|
45
|
+
"output": {
|
|
46
|
+
"type": "object",
|
|
47
|
+
"description": "The response from the API call"
|
|
48
|
+
},
|
|
49
|
+
"steps": {
|
|
50
|
+
"type": "boolean",
|
|
51
|
+
"default": false
|
|
52
|
+
},
|
|
53
|
+
"functions": {
|
|
54
|
+
"type": "array"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// public/app.js
|
|
3
|
+
const { useState, useEffect } = React;
|
|
4
|
+
function ChatBot() {
|
|
5
|
+
const [messages, setMessages] = useState([]);
|
|
6
|
+
const [input, setInput] = useState("");
|
|
7
|
+
const ctx = JSON.parse(atob(ctx_base64));
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
setMessages((prevMessages) => [
|
|
10
|
+
...prevMessages,
|
|
11
|
+
{ text: "Hello! Let share a fact about cats. Ok?", sender: "bot", id: Math.floor(Math.random() * 100) },
|
|
12
|
+
]);
|
|
13
|
+
setMessages((prevMessages) => [
|
|
14
|
+
...prevMessages,
|
|
15
|
+
{ text: ctx.response.data.fact, sender: "bot", id: Math.floor(Math.random() * 100) },
|
|
16
|
+
]);
|
|
17
|
+
}, []);
|
|
18
|
+
const handleSubmit = (e) => {
|
|
19
|
+
e.preventDefault();
|
|
20
|
+
if (input.trim()) {
|
|
21
|
+
setMessages([...messages, { text: input, sender: "user", id: Math.floor(Math.random() * 100) }]);
|
|
22
|
+
setInput("");
|
|
23
|
+
// Simulate bot response
|
|
24
|
+
setTimeout(() => {
|
|
25
|
+
setMessages((prevMessages) => [
|
|
26
|
+
...prevMessages,
|
|
27
|
+
{ text: `You said: ${input}`, sender: "bot", id: Math.floor(Math.random() * 100) },
|
|
28
|
+
]);
|
|
29
|
+
}, 500);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
return (<div className="bg-white rounded-lg shadow-md w-96 overflow-hidden">
|
|
33
|
+
<h1 className="bg-blue-500 text-white text-center py-4 text-xl font-bold">
|
|
34
|
+
Simple {ctx.request.params.workflow}
|
|
35
|
+
</h1>
|
|
36
|
+
<div className="h-96 overflow-y-auto p-4 space-y-4">
|
|
37
|
+
{messages.map((message, index) => (<div key={message.id} className={`p-2 rounded-lg ${message.sender === "user" ? "bg-blue-500 text-white ml-auto" : "bg-gray-200 text-gray-800"} max-w-[80%] ${message.sender === "user" ? "text-right" : "text-left"}`}>
|
|
38
|
+
{message.text}
|
|
39
|
+
</div>))}
|
|
40
|
+
</div>
|
|
41
|
+
<form onSubmit={handleSubmit} className="p-4 border-t border-gray-200">
|
|
42
|
+
<div className="flex">
|
|
43
|
+
<input type="text" value={input} onChange={(e) => setInput(e.target.value)} placeholder="Type your message..." className="flex-grow px-3 py-2 border rounded-l-md focus:outline-none focus:ring-2 focus:ring-blue-500"/>
|
|
44
|
+
<button type="submit" className="bg-blue-500 text-white px-4 py-2 rounded-r-md hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500">
|
|
45
|
+
Send
|
|
46
|
+
</button>
|
|
47
|
+
</div>
|
|
48
|
+
</form>
|
|
49
|
+
</div>);
|
|
50
|
+
}
|
|
51
|
+
ReactDOM.render(<ChatBot />, document.getElementById("root"));
|
|
52
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../app/index.jsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";// public/app.js
|
|
2
|
+
function _toConsumableArray(a){return _arrayWithoutHoles(a)||_iterableToArray(a)||_unsupportedIterableToArray(a)||_nonIterableSpread()}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _iterableToArray(a){if("undefined"!=typeof Symbol&&null!=a[Symbol.iterator]||null!=a["@@iterator"])return Array.from(a)}function _arrayWithoutHoles(a){if(Array.isArray(a))return _arrayLikeToArray(a)}function _slicedToArray(a,b){return _arrayWithHoles(a)||_iterableToArrayLimit(a,b)||_unsupportedIterableToArray(a,b)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(b,c){if(b){if("string"==typeof b)return _arrayLikeToArray(b,c);var a={}.toString.call(b).slice(8,-1);return"Object"===a&&b.constructor&&(a=b.constructor.name),"Map"===a||"Set"===a?Array.from(b):"Arguments"===a||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(a)?_arrayLikeToArray(b,c):void 0}}function _arrayLikeToArray(b,c){(null==c||c>b.length)&&(c=b.length);for(var d=0,f=Array(c);d<c;d++)f[d]=b[d];return f}function _iterableToArrayLimit(b,c){var d=null==b?null:"undefined"!=typeof Symbol&&b[Symbol.iterator]||b["@@iterator"];if(null!=d){var g,h,j,k,l=[],a=!0,m=!1;try{if(j=(d=d.call(b)).next,0===c){if(Object(d)!==d)return;a=!1}else for(;!(a=(g=j.call(d)).done)&&(l.push(g.value),l.length!==c);a=!0);}catch(a){m=!0,h=a}finally{try{if(!a&&null!=d["return"]&&(k=d["return"](),Object(k)!==k))return}finally{if(m)throw h}}return l}}function _arrayWithHoles(a){if(Array.isArray(a))return a}var _React=React,useState=_React.useState,useEffect=_React.useEffect;function ChatBot(){var a=Math.floor,b=useState([]),c=_slicedToArray(b,2),d=c[0],f=c[1],g=useState(""),h=_slicedToArray(g,2),i=h[0],j=h[1],k=JSON.parse(atob(ctx_base64));useEffect(function(){f(function(b){return[].concat(_toConsumableArray(b),[{text:"Hello! Let share a fact about cats. Ok?",sender:"bot",id:a(100*Math.random())}])}),f(function(b){return[].concat(_toConsumableArray(b),[{text:k.response.data.fact,sender:"bot",id:a(100*Math.random())}])})},[]);return/*#__PURE__*/React.createElement("div",{className:"bg-white rounded-lg shadow-md w-96 overflow-hidden"},/*#__PURE__*/React.createElement("h1",{className:"bg-blue-500 text-white text-center py-4 text-xl font-bold"},"Simple ",k.request.params.workflow),/*#__PURE__*/React.createElement("div",{className:"h-96 overflow-y-auto p-4 space-y-4"},d.map(function(a){return/*#__PURE__*/React.createElement("div",{key:a.id,className:"p-2 rounded-lg ".concat("user"===a.sender?"bg-blue-500 text-white ml-auto":"bg-gray-200 text-gray-800"," max-w-[80%] ").concat("user"===a.sender?"text-right":"text-left")},a.text)})),/*#__PURE__*/React.createElement("form",{onSubmit:function(b){b.preventDefault(),i.trim()&&(f([].concat(_toConsumableArray(d),[{text:i,sender:"user",id:a(100*Math.random())}])),j(""),setTimeout(function(){f(function(b){return[].concat(_toConsumableArray(b),[{text:"You said: ".concat(i),sender:"bot",id:a(100*Math.random())}])})},500))},className:"p-4 border-t border-gray-200"},/*#__PURE__*/React.createElement("div",{className:"flex"},/*#__PURE__*/React.createElement("input",{type:"text",value:i,onChange:function(a){return j(a.target.value)},placeholder:"Type your message...",className:"flex-grow px-3 py-2 border rounded-l-md focus:outline-none focus:ring-2 focus:ring-blue-500"}),/*#__PURE__*/React.createElement("button",{type:"submit",className:"bg-blue-500 text-white px-4 py-2 rounded-r-md hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500"},"Send"))))}ReactDOM.render(/*#__PURE__*/React.createElement(ChatBot,null),document.getElementById("root"));
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Node - Function-First Implementation
|
|
3
|
+
*
|
|
4
|
+
* Renders React applications by loading a compiled React bundle and rendering it in an HTML template.
|
|
5
|
+
* Migrated from class-based to function-first pattern using defineNode.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
declare const inputSchema: z.ZodObject<{
|
|
9
|
+
react_app: z.ZodString;
|
|
10
|
+
title: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
11
|
+
scripts: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
12
|
+
metas: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
13
|
+
index_html: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
14
|
+
styles: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
15
|
+
root_element: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
16
|
+
}, "strip", z.ZodTypeAny, {
|
|
17
|
+
react_app: string;
|
|
18
|
+
title: string;
|
|
19
|
+
scripts: string;
|
|
20
|
+
metas: string;
|
|
21
|
+
index_html: string;
|
|
22
|
+
styles: string;
|
|
23
|
+
root_element: string;
|
|
24
|
+
}, {
|
|
25
|
+
react_app: string;
|
|
26
|
+
title?: string | undefined;
|
|
27
|
+
scripts?: string | undefined;
|
|
28
|
+
metas?: string | undefined;
|
|
29
|
+
index_html?: string | undefined;
|
|
30
|
+
styles?: string | undefined;
|
|
31
|
+
root_element?: string | undefined;
|
|
32
|
+
}>;
|
|
33
|
+
declare const outputSchema: z.ZodString;
|
|
34
|
+
declare const _default: import("@blokjs/runner").FunctionNode<z.ZodObject<{
|
|
35
|
+
react_app: z.ZodString;
|
|
36
|
+
title: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
37
|
+
scripts: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
38
|
+
metas: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
39
|
+
index_html: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
40
|
+
styles: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
41
|
+
root_element: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
42
|
+
}, "strip", z.ZodTypeAny, {
|
|
43
|
+
react_app: string;
|
|
44
|
+
title: string;
|
|
45
|
+
scripts: string;
|
|
46
|
+
metas: string;
|
|
47
|
+
index_html: string;
|
|
48
|
+
styles: string;
|
|
49
|
+
root_element: string;
|
|
50
|
+
}, {
|
|
51
|
+
react_app: string;
|
|
52
|
+
title?: string | undefined;
|
|
53
|
+
scripts?: string | undefined;
|
|
54
|
+
metas?: string | undefined;
|
|
55
|
+
index_html?: string | undefined;
|
|
56
|
+
styles?: string | undefined;
|
|
57
|
+
root_element?: string | undefined;
|
|
58
|
+
}>, z.ZodString>;
|
|
59
|
+
export default _default;
|
|
60
|
+
export type InputType = z.infer<typeof inputSchema>;
|
|
61
|
+
export type OutputType = z.infer<typeof outputSchema>;
|
package/dist/index.html
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<!-- views/index.ejs -->
|
|
2
|
+
<!DOCTYPE html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<%-metas%>
|
|
8
|
+
<title><%=title%></title>
|
|
9
|
+
<%-styles%>
|
|
10
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
11
|
+
<script type="text/javascript">
|
|
12
|
+
var ctx_base64 = '<%=ctx%>';
|
|
13
|
+
</script>
|
|
14
|
+
</head>
|
|
15
|
+
<body class="bg-gray-100 flex items-center justify-center min-h-screen">
|
|
16
|
+
<div id="<%=root_element%>"></div>
|
|
17
|
+
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
|
|
18
|
+
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
|
|
19
|
+
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
|
|
20
|
+
<%-scripts%>
|
|
21
|
+
<%-react_app%>
|
|
22
|
+
</body>
|
|
23
|
+
</html>
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Node - Function-First Implementation
|
|
3
|
+
*
|
|
4
|
+
* Renders React applications by loading a compiled React bundle and rendering it in an HTML template.
|
|
5
|
+
* Migrated from class-based to function-first pattern using defineNode.
|
|
6
|
+
*/
|
|
7
|
+
import fs from "node:fs";
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
import { defineNode } from "@blokjs/runner";
|
|
10
|
+
import ejs from "ejs";
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
// Input schema using Zod (migrated from JSON Schema)
|
|
13
|
+
const inputSchema = z.object({
|
|
14
|
+
react_app: z.string({
|
|
15
|
+
description: "Path to the compiled React application bundle (e.g., './app/index.merged.min.js')",
|
|
16
|
+
}),
|
|
17
|
+
title: z.string().optional().default("React App"),
|
|
18
|
+
scripts: z.string().optional().default(""),
|
|
19
|
+
metas: z.string().optional().default(""),
|
|
20
|
+
index_html: z.string().optional().default("index.html"),
|
|
21
|
+
styles: z.string().optional().default(""),
|
|
22
|
+
root_element: z.string().optional().default("root"),
|
|
23
|
+
});
|
|
24
|
+
// Output is HTML string
|
|
25
|
+
const outputSchema = z.string();
|
|
26
|
+
// Helper: Resolve path relative to node directory
|
|
27
|
+
const rootDir = path.resolve(__dirname, ".");
|
|
28
|
+
function root(relPath) {
|
|
29
|
+
return path.resolve(rootDir, relPath);
|
|
30
|
+
}
|
|
31
|
+
export default defineNode({
|
|
32
|
+
name: "react",
|
|
33
|
+
description: "Renders React applications by loading a compiled bundle and rendering it in an HTML template",
|
|
34
|
+
contentType: "text/html",
|
|
35
|
+
input: inputSchema,
|
|
36
|
+
output: outputSchema,
|
|
37
|
+
async execute(ctx, inputs) {
|
|
38
|
+
// Resolve React app bundle path
|
|
39
|
+
const file_path = inputs.react_app || "./app/index.merged.min.js";
|
|
40
|
+
const react_script_template = '<script type="text/babel">REACT_SCRIPT</script>';
|
|
41
|
+
// Load React script from the node module location
|
|
42
|
+
const min_file = root(file_path);
|
|
43
|
+
let react_app = fs.readFileSync(min_file, "utf8");
|
|
44
|
+
react_app = react_script_template.replace("REACT_SCRIPT", `\n${react_app}\n`);
|
|
45
|
+
// Read index.html template from the node module location
|
|
46
|
+
const content = fs.readFileSync(root(inputs.index_html), "utf8");
|
|
47
|
+
const render = ejs.compile(content, { client: false });
|
|
48
|
+
// Clone context for template (removing sensitive data)
|
|
49
|
+
const ctxCloned = {
|
|
50
|
+
config: ctx.config,
|
|
51
|
+
inputs: inputs,
|
|
52
|
+
response: ctx.response,
|
|
53
|
+
request: {
|
|
54
|
+
body: ctx.request.body,
|
|
55
|
+
headers: ctx.request.headers,
|
|
56
|
+
url: ctx.request.url,
|
|
57
|
+
originalUrl: ctx.request.originalUrl,
|
|
58
|
+
query: ctx.request.query,
|
|
59
|
+
params: ctx.request.params,
|
|
60
|
+
cookies: ctx.request.cookies,
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
// Render HTML with EJS
|
|
64
|
+
const html = render({
|
|
65
|
+
title: inputs.title,
|
|
66
|
+
metas: inputs.metas,
|
|
67
|
+
styles: inputs.styles,
|
|
68
|
+
scripts: inputs.scripts,
|
|
69
|
+
root_element: inputs.root_element,
|
|
70
|
+
react_app,
|
|
71
|
+
ctx: btoa(JSON.stringify(ctxCloned)),
|
|
72
|
+
});
|
|
73
|
+
return html;
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export declare const inputSchema: {
|
|
2
|
+
$schema: string;
|
|
3
|
+
title: string;
|
|
4
|
+
type: string;
|
|
5
|
+
properties: {
|
|
6
|
+
title: {
|
|
7
|
+
type: string;
|
|
8
|
+
};
|
|
9
|
+
index_html: {
|
|
10
|
+
type: string;
|
|
11
|
+
};
|
|
12
|
+
scripts: {
|
|
13
|
+
type: string;
|
|
14
|
+
};
|
|
15
|
+
react_app: {
|
|
16
|
+
type: string;
|
|
17
|
+
};
|
|
18
|
+
styles: {
|
|
19
|
+
type: string;
|
|
20
|
+
};
|
|
21
|
+
root_element: {
|
|
22
|
+
type: string;
|
|
23
|
+
};
|
|
24
|
+
metas: {
|
|
25
|
+
type: string;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
required: string[];
|
|
29
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export const inputSchema = {
|
|
2
|
+
$schema: "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
title: "Generated schema for Root",
|
|
4
|
+
type: "object",
|
|
5
|
+
properties: {
|
|
6
|
+
title: {
|
|
7
|
+
type: "string",
|
|
8
|
+
},
|
|
9
|
+
index_html: {
|
|
10
|
+
type: "string",
|
|
11
|
+
},
|
|
12
|
+
scripts: {
|
|
13
|
+
type: "string",
|
|
14
|
+
},
|
|
15
|
+
react_app: {
|
|
16
|
+
type: "string",
|
|
17
|
+
},
|
|
18
|
+
styles: {
|
|
19
|
+
type: "string",
|
|
20
|
+
},
|
|
21
|
+
root_element: {
|
|
22
|
+
type: "string",
|
|
23
|
+
},
|
|
24
|
+
metas: {
|
|
25
|
+
type: "string",
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
required: ["react_app"],
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=inputSchema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inputSchema.js","sourceRoot":"","sources":["../inputSchema.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,WAAW,GAAG;IAC1B,OAAO,EAAE,yCAAyC;IAClD,KAAK,EAAE,2BAA2B;IAClC,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACX,KAAK,EAAE;YACN,IAAI,EAAE,QAAQ;SACd;QACD,UAAU,EAAE;YACX,IAAI,EAAE,QAAQ;SACd;QACD,OAAO,EAAE;YACR,IAAI,EAAE,QAAQ;SACd;QACD,SAAS,EAAE;YACV,IAAI,EAAE,QAAQ;SACd;QACD,MAAM,EAAE;YACP,IAAI,EAAE,QAAQ;SACd;QACD,YAAY,EAAE;YACb,IAAI,EAAE,QAAQ;SACd;QACD,KAAK,EAAE;YACN,IAAI,EAAE,QAAQ;SACd;KACD;IACD,QAAQ,EAAE,CAAC,WAAW,CAAC;CACvB,CAAC"}
|
package/index.html
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<!-- views/index.ejs -->
|
|
2
|
+
<!DOCTYPE html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<%-metas%>
|
|
8
|
+
<title><%=title%></title>
|
|
9
|
+
<%-styles%>
|
|
10
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
11
|
+
<script type="text/javascript">
|
|
12
|
+
var ctx_base64 = '<%=ctx%>';
|
|
13
|
+
</script>
|
|
14
|
+
</head>
|
|
15
|
+
<body class="bg-gray-100 flex items-center justify-center min-h-screen">
|
|
16
|
+
<div id="<%=root_element%>"></div>
|
|
17
|
+
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
|
|
18
|
+
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
|
|
19
|
+
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
|
|
20
|
+
<%-scripts%>
|
|
21
|
+
<%-react_app%>
|
|
22
|
+
</body>
|
|
23
|
+
</html>
|
package/index.ts
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Node - Function-First Implementation
|
|
3
|
+
*
|
|
4
|
+
* Renders React applications by loading a compiled React bundle and rendering it in an HTML template.
|
|
5
|
+
* Migrated from class-based to function-first pattern using defineNode.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import fs from "node:fs";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import { defineNode } from "@blokjs/runner";
|
|
11
|
+
import type { Context } from "@blokjs/shared";
|
|
12
|
+
import ejs from "ejs";
|
|
13
|
+
import { z } from "zod";
|
|
14
|
+
|
|
15
|
+
// Input schema using Zod (migrated from JSON Schema)
|
|
16
|
+
const inputSchema = z.object({
|
|
17
|
+
react_app: z.string({
|
|
18
|
+
description: "Path to the compiled React application bundle (e.g., './app/index.merged.min.js')",
|
|
19
|
+
}),
|
|
20
|
+
title: z.string().optional().default("React App"),
|
|
21
|
+
scripts: z.string().optional().default(""),
|
|
22
|
+
metas: z.string().optional().default(""),
|
|
23
|
+
index_html: z.string().optional().default("index.html"),
|
|
24
|
+
styles: z.string().optional().default(""),
|
|
25
|
+
root_element: z.string().optional().default("root"),
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// Output is HTML string
|
|
29
|
+
const outputSchema = z.string();
|
|
30
|
+
|
|
31
|
+
// Helper: Resolve path relative to node directory
|
|
32
|
+
const rootDir = path.resolve(__dirname, ".");
|
|
33
|
+
function root(relPath: string): string {
|
|
34
|
+
return path.resolve(rootDir, relPath);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export default defineNode({
|
|
38
|
+
name: "react",
|
|
39
|
+
description: "Renders React applications by loading a compiled bundle and rendering it in an HTML template",
|
|
40
|
+
contentType: "text/html",
|
|
41
|
+
|
|
42
|
+
input: inputSchema,
|
|
43
|
+
output: outputSchema,
|
|
44
|
+
|
|
45
|
+
async execute(ctx: Context, inputs) {
|
|
46
|
+
// Resolve React app bundle path
|
|
47
|
+
const file_path = inputs.react_app || "./app/index.merged.min.js";
|
|
48
|
+
const react_script_template = '<script type="text/babel">REACT_SCRIPT</script>';
|
|
49
|
+
|
|
50
|
+
// Load React script from the node module location
|
|
51
|
+
const min_file = root(file_path);
|
|
52
|
+
let react_app = fs.readFileSync(min_file, "utf8");
|
|
53
|
+
react_app = react_script_template.replace("REACT_SCRIPT", `\n${react_app}\n`);
|
|
54
|
+
|
|
55
|
+
// Read index.html template from the node module location
|
|
56
|
+
const content = fs.readFileSync(root(inputs.index_html), "utf8");
|
|
57
|
+
const render = ejs.compile(content, { client: false });
|
|
58
|
+
|
|
59
|
+
// Clone context for template (removing sensitive data)
|
|
60
|
+
const ctxCloned = {
|
|
61
|
+
config: ctx.config,
|
|
62
|
+
inputs: inputs,
|
|
63
|
+
response: ctx.response,
|
|
64
|
+
request: {
|
|
65
|
+
body: ctx.request.body,
|
|
66
|
+
headers: ctx.request.headers,
|
|
67
|
+
url: ctx.request.url,
|
|
68
|
+
originalUrl: ctx.request.originalUrl,
|
|
69
|
+
query: ctx.request.query,
|
|
70
|
+
params: ctx.request.params,
|
|
71
|
+
cookies: ctx.request.cookies,
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
// Render HTML with EJS
|
|
76
|
+
const html = render({
|
|
77
|
+
title: inputs.title,
|
|
78
|
+
metas: inputs.metas,
|
|
79
|
+
styles: inputs.styles,
|
|
80
|
+
scripts: inputs.scripts,
|
|
81
|
+
root_element: inputs.root_element,
|
|
82
|
+
react_app,
|
|
83
|
+
ctx: btoa(JSON.stringify(ctxCloned)),
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
return html;
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// Export types for backward compatibility
|
|
91
|
+
export type InputType = z.infer<typeof inputSchema>;
|
|
92
|
+
export type OutputType = z.infer<typeof outputSchema>;
|
package/index.ts.backup
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { type INanoServiceResponse, NanoService, NanoServiceResponse } from "@blok/runner";
|
|
4
|
+
import { type Context, GlobalError } from "@blok/shared";
|
|
5
|
+
import ejs from "ejs";
|
|
6
|
+
import { inputSchema } from "./inputSchema";
|
|
7
|
+
|
|
8
|
+
type InputType = {
|
|
9
|
+
react_app: string;
|
|
10
|
+
title?: string;
|
|
11
|
+
scripts?: string;
|
|
12
|
+
metas?: string;
|
|
13
|
+
index_html?: string;
|
|
14
|
+
styles?: string;
|
|
15
|
+
root_element?: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const rootDir = path.resolve(__dirname, ".");
|
|
19
|
+
|
|
20
|
+
export default class React extends NanoService<InputType> {
|
|
21
|
+
constructor() {
|
|
22
|
+
super();
|
|
23
|
+
|
|
24
|
+
// Set the input "JSON Schema Format" here for automated validation
|
|
25
|
+
// Learn JSON Schema: https://json-schema.org/learn/getting-started-step-by-step
|
|
26
|
+
this.inputSchema = inputSchema;
|
|
27
|
+
|
|
28
|
+
// Set the output "JSON Schema Format" here for automated validation
|
|
29
|
+
// Learn JSON Schema: https://json-schema.org/learn/getting-started-step-by-step
|
|
30
|
+
this.outputSchema = {};
|
|
31
|
+
|
|
32
|
+
// Set html content type
|
|
33
|
+
this.contentType = "text/html";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Relative path to root
|
|
38
|
+
*/
|
|
39
|
+
root(relPath: string): string {
|
|
40
|
+
return path.resolve(rootDir, relPath);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async handle(ctx: Context, inputs: InputType): Promise<INanoServiceResponse> {
|
|
44
|
+
// Create a new instance of the response
|
|
45
|
+
const response = new NanoServiceResponse();
|
|
46
|
+
let file_path = inputs.react_app;
|
|
47
|
+
if (file_path === undefined || file_path === "") file_path = "./app/index.merged.min.js";
|
|
48
|
+
const react_script_template = '<script type="text/babel">REACT_SCRIPT</script>';
|
|
49
|
+
|
|
50
|
+
const title = inputs.title || "React App";
|
|
51
|
+
const scripts = inputs.scripts || "";
|
|
52
|
+
const metas = inputs.metas || "";
|
|
53
|
+
const index_html = inputs.index_html || "index.html";
|
|
54
|
+
const styles = inputs.styles || "";
|
|
55
|
+
const root_element = inputs.root_element || "root";
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
// Load React script from the current module location
|
|
59
|
+
const min_file = this.root(file_path);
|
|
60
|
+
let react_app = fs.readFileSync(min_file, "utf8");
|
|
61
|
+
react_app = react_script_template.replace("REACT_SCRIPT", `\n${react_app}\n`);
|
|
62
|
+
|
|
63
|
+
// Read index.html file from the current module location
|
|
64
|
+
const content = fs.readFileSync(this.root(index_html), "utf8");
|
|
65
|
+
const render = ejs.compile(content, { client: false });
|
|
66
|
+
const ctxCloned = {
|
|
67
|
+
config: ctx.config,
|
|
68
|
+
inputs: inputs,
|
|
69
|
+
response: ctx.response,
|
|
70
|
+
request: {
|
|
71
|
+
body: ctx.request.body,
|
|
72
|
+
headers: ctx.request.headers,
|
|
73
|
+
url: ctx.request.url,
|
|
74
|
+
originalUrl: ctx.request.originalUrl,
|
|
75
|
+
query: ctx.request.query,
|
|
76
|
+
params: ctx.request.params,
|
|
77
|
+
cookies: ctx.request.cookies,
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const html = render({
|
|
82
|
+
title,
|
|
83
|
+
metas,
|
|
84
|
+
styles,
|
|
85
|
+
scripts,
|
|
86
|
+
root_element,
|
|
87
|
+
react_app,
|
|
88
|
+
ctx: btoa(JSON.stringify(ctxCloned)),
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// Your code here
|
|
92
|
+
response.setSuccess(html); // Set the success
|
|
93
|
+
} catch (error: unknown) {
|
|
94
|
+
const nodeError: GlobalError = new GlobalError((error as Error).message);
|
|
95
|
+
nodeError.setCode(500);
|
|
96
|
+
nodeError.setStack((error as Error).stack);
|
|
97
|
+
nodeError.setName(this.name);
|
|
98
|
+
response.setError(nodeError); // Set the error
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return response;
|
|
102
|
+
}
|
|
103
|
+
}
|
package/inputSchema.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export const inputSchema = {
|
|
2
|
+
$schema: "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
title: "Generated schema for Root",
|
|
4
|
+
type: "object",
|
|
5
|
+
properties: {
|
|
6
|
+
title: {
|
|
7
|
+
type: "string",
|
|
8
|
+
},
|
|
9
|
+
index_html: {
|
|
10
|
+
type: "string",
|
|
11
|
+
},
|
|
12
|
+
scripts: {
|
|
13
|
+
type: "string",
|
|
14
|
+
},
|
|
15
|
+
react_app: {
|
|
16
|
+
type: "string",
|
|
17
|
+
},
|
|
18
|
+
styles: {
|
|
19
|
+
type: "string",
|
|
20
|
+
},
|
|
21
|
+
root_element: {
|
|
22
|
+
type: "string",
|
|
23
|
+
},
|
|
24
|
+
metas: {
|
|
25
|
+
type: "string",
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
required: ["react_app"],
|
|
29
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@blokjs/react",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=18.0.0"
|
|
8
|
+
},
|
|
9
|
+
"author": "Deskree Technologies Inc.",
|
|
10
|
+
"license": "Apache-2.0",
|
|
11
|
+
"main": "dist/index.js",
|
|
12
|
+
"types": "dist/index.d.ts",
|
|
13
|
+
"scripts": {
|
|
14
|
+
"test:dev": "vitest",
|
|
15
|
+
"test": "vitest run",
|
|
16
|
+
"build:ts": "rm -rf dist && tsc",
|
|
17
|
+
"build:dev": "tsc --watch",
|
|
18
|
+
"build:babel": "rm -rf dist/app/index.merged.min.js && babel dist/app --out-file dist/app/index.merged.min.js",
|
|
19
|
+
"build": "npm run build:ts && npm run build:babel && cp index.html dist/index.html"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@types/node": "^22.15.21",
|
|
23
|
+
"@types/ejs": "^3.1.5",
|
|
24
|
+
"typescript": "^5.8.3",
|
|
25
|
+
"vitest": "^4.0.18",
|
|
26
|
+
"@babel/cli": "^7.28.6",
|
|
27
|
+
"@babel/core": "^7.28.6",
|
|
28
|
+
"@babel/preset-env": "^7.28.6",
|
|
29
|
+
"@babel/preset-react": "^7.28.5",
|
|
30
|
+
"babel-minify": "^0.5.2"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@blokjs/shared": "workspace:*",
|
|
34
|
+
"@blokjs/runner": "workspace:*",
|
|
35
|
+
"@blokjs/helper": "workspace:*",
|
|
36
|
+
"ejs": "^3.1.10",
|
|
37
|
+
"zod": "^3.24.2"
|
|
38
|
+
},
|
|
39
|
+
"private": false,
|
|
40
|
+
"publishConfig": {
|
|
41
|
+
"access": "public"
|
|
42
|
+
}
|
|
43
|
+
}
|
package/test/helper.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { ParamsDictionary } from "@blokjs/runner";
|
|
2
|
+
import type { Context } from "@blokjs/shared";
|
|
3
|
+
|
|
4
|
+
export default function ctx(): Context {
|
|
5
|
+
const ctx: Context = {
|
|
6
|
+
response: {
|
|
7
|
+
data: {
|
|
8
|
+
title: "Chat bot",
|
|
9
|
+
},
|
|
10
|
+
error: null,
|
|
11
|
+
},
|
|
12
|
+
request: {
|
|
13
|
+
body: {},
|
|
14
|
+
},
|
|
15
|
+
config: {},
|
|
16
|
+
id: "",
|
|
17
|
+
error: {
|
|
18
|
+
message: "",
|
|
19
|
+
code: undefined,
|
|
20
|
+
json: undefined,
|
|
21
|
+
stack: undefined,
|
|
22
|
+
name: undefined,
|
|
23
|
+
},
|
|
24
|
+
logger: {
|
|
25
|
+
log: (message: string): void => {
|
|
26
|
+
throw new Error("Function not implemented.");
|
|
27
|
+
},
|
|
28
|
+
getLogs: (): string[] => {
|
|
29
|
+
throw new Error("Function not implemented.");
|
|
30
|
+
},
|
|
31
|
+
getLogsAsText: (): string => {
|
|
32
|
+
throw new Error("Function not implemented.");
|
|
33
|
+
},
|
|
34
|
+
getLogsAsBase64: (): string => {
|
|
35
|
+
throw new Error("Function not implemented.");
|
|
36
|
+
},
|
|
37
|
+
logLevel: (level: string, message: string): void => {
|
|
38
|
+
throw new Error("Function not implemented.");
|
|
39
|
+
},
|
|
40
|
+
error: (message: string, stack: string): void => {
|
|
41
|
+
throw new Error("Function not implemented.");
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
eventLogger: undefined,
|
|
45
|
+
_PRIVATE_: undefined,
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
ctx.config = {
|
|
49
|
+
react: {
|
|
50
|
+
inputs: {
|
|
51
|
+
react_app: "./dist/app/index.merged.min.js",
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
} as unknown as ParamsDictionary;
|
|
55
|
+
|
|
56
|
+
return ctx;
|
|
57
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<!-- views/index.ejs -->
|
|
2
|
+
<!DOCTYPE html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
|
|
8
|
+
<title>React App</title>
|
|
9
|
+
|
|
10
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
11
|
+
<script type="text/javascript">
|
|
12
|
+
var ctx_base64 = 'eyJjb25maWciOnsicmVhY3QiOnsiaW5wdXRzIjp7InJlYWN0X2FwcCI6Ii4vZGlzdC9hcHAvaW5kZXgubWVyZ2VkLm1pbi5qcyJ9fX0sImlucHV0cyI6eyJyZWFjdF9hcHAiOiIuL2Rpc3QvYXBwL2luZGV4Lm1lcmdlZC5taW4uanMiLCJ0aXRsZSI6IlJlYWN0IEFwcCIsInNjcmlwdHMiOiIiLCJtZXRhcyI6IiIsImluZGV4X2h0bWwiOiJpbmRleC5odG1sIiwic3R5bGVzIjoiIiwicm9vdF9lbGVtZW50Ijoicm9vdCJ9LCJyZXNwb25zZSI6eyJkYXRhIjp7InRpdGxlIjoiQ2hhdCBib3QifSwiZXJyb3IiOm51bGx9LCJyZXF1ZXN0Ijp7ImJvZHkiOnt9fX0=';
|
|
13
|
+
</script>
|
|
14
|
+
</head>
|
|
15
|
+
<body class="bg-gray-100 flex items-center justify-center min-h-screen">
|
|
16
|
+
<div id="root"></div>
|
|
17
|
+
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
|
|
18
|
+
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
|
|
19
|
+
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
|
|
20
|
+
|
|
21
|
+
<script type="text/babel">
|
|
22
|
+
"use strict";// public/app.js
|
|
23
|
+
function _toConsumableArray(a){return _arrayWithoutHoles(a)||_iterableToArray(a)||_unsupportedIterableToArray(a)||_nonIterableSpread()}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _iterableToArray(a){if("undefined"!=typeof Symbol&&null!=a[Symbol.iterator]||null!=a["@@iterator"])return Array.from(a)}function _arrayWithoutHoles(a){if(Array.isArray(a))return _arrayLikeToArray(a)}function _slicedToArray(a,b){return _arrayWithHoles(a)||_iterableToArrayLimit(a,b)||_unsupportedIterableToArray(a,b)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(b,c){if(b){if("string"==typeof b)return _arrayLikeToArray(b,c);var a={}.toString.call(b).slice(8,-1);return"Object"===a&&b.constructor&&(a=b.constructor.name),"Map"===a||"Set"===a?Array.from(b):"Arguments"===a||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(a)?_arrayLikeToArray(b,c):void 0}}function _arrayLikeToArray(b,c){(null==c||c>b.length)&&(c=b.length);for(var d=0,f=Array(c);d<c;d++)f[d]=b[d];return f}function _iterableToArrayLimit(b,c){var d=null==b?null:"undefined"!=typeof Symbol&&b[Symbol.iterator]||b["@@iterator"];if(null!=d){var g,h,j,k,l=[],a=!0,m=!1;try{if(j=(d=d.call(b)).next,0===c){if(Object(d)!==d)return;a=!1}else for(;!(a=(g=j.call(d)).done)&&(l.push(g.value),l.length!==c);a=!0);}catch(a){m=!0,h=a}finally{try{if(!a&&null!=d["return"]&&(k=d["return"](),Object(k)!==k))return}finally{if(m)throw h}}return l}}function _arrayWithHoles(a){if(Array.isArray(a))return a}var _React=React,useState=_React.useState,useEffect=_React.useEffect;function ChatBot(){var a=Math.floor,b=useState([]),c=_slicedToArray(b,2),d=c[0],f=c[1],g=useState(""),h=_slicedToArray(g,2),i=h[0],j=h[1],k=JSON.parse(atob(ctx_base64));useEffect(function(){f(function(b){return[].concat(_toConsumableArray(b),[{text:"Hello! Let share a fact about cats. Ok?",sender:"bot",id:a(100*Math.random())}])}),f(function(b){return[].concat(_toConsumableArray(b),[{text:k.response.data.fact,sender:"bot",id:a(100*Math.random())}])})},[]);return/*#__PURE__*/React.createElement("div",{className:"bg-white rounded-lg shadow-md w-96 overflow-hidden"},/*#__PURE__*/React.createElement("h1",{className:"bg-blue-500 text-white text-center py-4 text-xl font-bold"},"Simple ",k.request.params.workflow),/*#__PURE__*/React.createElement("div",{className:"h-96 overflow-y-auto p-4 space-y-4"},d.map(function(a){return/*#__PURE__*/React.createElement("div",{key:a.id,className:"p-2 rounded-lg ".concat("user"===a.sender?"bg-blue-500 text-white ml-auto":"bg-gray-200 text-gray-800"," max-w-[80%] ").concat("user"===a.sender?"text-right":"text-left")},a.text)})),/*#__PURE__*/React.createElement("form",{onSubmit:function(b){b.preventDefault(),i.trim()&&(f([].concat(_toConsumableArray(d),[{text:i,sender:"user",id:a(100*Math.random())}])),j(""),setTimeout(function(){f(function(b){return[].concat(_toConsumableArray(b),[{text:"You said: ".concat(i),sender:"bot",id:a(100*Math.random())}])})},500))},className:"p-4 border-t border-gray-200"},/*#__PURE__*/React.createElement("div",{className:"flex"},/*#__PURE__*/React.createElement("input",{type:"text",value:i,onChange:function(a){return j(a.target.value)},placeholder:"Type your message...",className:"flex-grow px-3 py-2 border rounded-l-md focus:outline-none focus:ring-2 focus:ring-blue-500"}),/*#__PURE__*/React.createElement("button",{type:"submit",className:"bg-blue-500 text-white px-4 py-2 rounded-r-md hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500"},"Send"))))}ReactDOM.render(/*#__PURE__*/React.createElement(ChatBot,null),document.getElementById("root"));
|
|
24
|
+
|
|
25
|
+
</script>
|
|
26
|
+
</body>
|
|
27
|
+
</html>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Node Tests - Updated for Function-First Implementation
|
|
3
|
+
*
|
|
4
|
+
* Tests migrated from class-based to function-first pattern.
|
|
5
|
+
* All existing behavior is preserved.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import fs from "node:fs";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import type { IBlokResponse } from "@blokjs/runner";
|
|
11
|
+
import { beforeAll, expect, test } from "vitest";
|
|
12
|
+
import ReactNode from "../index";
|
|
13
|
+
import ctx from "./helper";
|
|
14
|
+
|
|
15
|
+
let rootDir: string;
|
|
16
|
+
|
|
17
|
+
beforeAll(() => {
|
|
18
|
+
rootDir = path.resolve(__dirname, ".");
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// Validate React rendering from Node
|
|
22
|
+
test("Render index.html page", async () => {
|
|
23
|
+
const context = ctx();
|
|
24
|
+
const inputs = { react_app: "./dist/app/index.merged.min.js" };
|
|
25
|
+
|
|
26
|
+
const response = (await ReactNode.handle(context, inputs)) as IBlokResponse;
|
|
27
|
+
const mockup_file = path.resolve(rootDir, "index.mockup.html");
|
|
28
|
+
const message: string = fs.readFileSync(mockup_file, "utf8");
|
|
29
|
+
|
|
30
|
+
expect(response.success).toEqual(true);
|
|
31
|
+
expect(response.data).toEqual(message);
|
|
32
|
+
});
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "es2022",
|
|
4
|
+
"allowJs": true,
|
|
5
|
+
"module": "es2022",
|
|
6
|
+
"moduleResolution": "bundler",
|
|
7
|
+
"declaration": true,
|
|
8
|
+
"sourceMap": true,
|
|
9
|
+
"outDir": "./dist",
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"strict": true,
|
|
13
|
+
"noUnusedLocals": true,
|
|
14
|
+
"noImplicitReturns": true,
|
|
15
|
+
"skipLibCheck": true
|
|
16
|
+
},
|
|
17
|
+
"include": ["./*", "app/**/*", "index.html"],
|
|
18
|
+
"exclude": ["node_modules", "dist"],
|
|
19
|
+
"compileOnSave": true
|
|
20
|
+
}
|