@cocreate/lazy-loader 1.23.3 → 1.23.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/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## [1.23.4](https://github.com/CoCreate-app/CoCreate-lazy-loader/compare/v1.23.3...v1.23.4) (2025-04-30)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * added css-loader ([b0dd656](https://github.com/CoCreate-app/CoCreate-lazy-loader/commit/b0dd65637000ca8f910b72b278a3b1d4da011c24))
7
+ * observer name creation to define for addedNodes and attributes ([b66cfb3](https://github.com/CoCreate-app/CoCreate-lazy-loader/commit/b66cfb3d2a2aacb26c732a2caffcecacd8e5c1ee))
8
+ * testing executeEndpoint ([f1e208f](https://github.com/CoCreate-app/CoCreate-lazy-loader/commit/f1e208ff61493f0cfca796df1a8a5fefdd11ebf7))
9
+ * update query attributes ([3059ea9](https://github.com/CoCreate-app/CoCreate-lazy-loader/commit/3059ea935d4be4d47b0f37d7f3496303c9426698))
10
+ * updated cocreate modules versions ([d307fd9](https://github.com/CoCreate-app/CoCreate-lazy-loader/commit/d307fd9f9f5bdf6d8d35359de7e0b37a413b9e92))
11
+ * webpack.config and devdependencies ([0e34c13](https://github.com/CoCreate-app/CoCreate-lazy-loader/commit/0e34c136ccd639362094af97c333bd0f8a715484))
12
+
1
13
  ## [1.23.3](https://github.com/CoCreate-app/CoCreate-lazy-loader/compare/v1.23.2...v1.23.3) (2025-04-11)
2
14
 
3
15
 
package/docs/index.html CHANGED
@@ -1,230 +1,230 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en">
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta http-equiv="X-UA-Compatible" content="IE=edge" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1" />
7
- <title>CoCreate-lazy-loader Documentation | CoCreateJS</title>
8
- <link
9
- rel="icon"
10
- type="image/png"
11
- sizes="32x32"
12
- href="https://cocreate.app/images/favicon.ico" />
13
- <meta
14
- name="description"
15
- content="A simple HTML5 and pure javascript component. Easy configuration using data-attributes and highly styleable." />
16
- <meta
17
- name="keywords"
18
- content="helper classes, utility classes, css framework, css library, inline style classes" />
19
- <meta name="robots" content="index,follow" />
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
7
+ <title>CoCreate-lazy-loader Documentation | CoCreateJS</title>
8
+ <link
9
+ rel="icon"
10
+ type="image/png"
11
+ sizes="32x32"
12
+ href="https://cocreate.app/images/favicon.ico" />
13
+ <meta
14
+ name="description"
15
+ content="A simple HTML5 and pure javascript component. Easy configuration using data-attributes and highly styleable." />
16
+ <meta
17
+ name="keywords"
18
+ content="helper classes, utility classes, css framework, css library, inline style classes" />
19
+ <meta name="robots" content="index,follow" />
20
20
 
21
- <!-- CoCreate CSS CDN -->
21
+ <!-- CoCreate CSS CDN -->
22
22
 
23
- <link rel="manifest" href="/manifest.webmanifest" />
24
- </head>
23
+ <link rel="manifest" href="/manifest.webmanifest" />
24
+ </head>
25
25
 
26
- <body>
27
- <div array="" object="" key="" id="cocreate-lazy-loader">
28
- <div
29
- class="display:flex flex-wrap:wrap justify-content:space-between margin:10px">
30
- <div class="display:flex align-items:center">
31
- <h2>CoCreate-lazy-loader</h2>
32
- </div>
33
- <div
34
- class="display:flex align-items:center font-size:20px"
35
- share-height="600"
36
- share-width="500"
37
- share-media="https://via.placeholder.com/300/09f/fff.png">
38
- <a
39
- href="https://github.com/CoCreate-app/CoCreate-lazy-loader"
40
- target="_blank"
41
- class="margin-right:15px"
42
- ><i src="/assets/svg/github.svg"></i
43
- ></a>
44
- <a
45
- class="margin-right:15px share"
46
- share-network="twitter"
47
- title="Share on twitter"
48
- ><i src="/assets/svg/twitter.svg"></i
49
- ></a>
50
- <a
51
- class="margin-right:15px share"
52
- share-network="facebook"
53
- title="Share on Facebook"
54
- ><i src="/assets/svg/facebook.svg"></i
55
- ></a>
56
- <a
57
- class="margin-right:15px share"
58
- share-network="instagram"
59
- title="Share on instagram"
60
- ><i src="/assets/svg/instagram.svg"></i
61
- ></a>
62
- <a
63
- class="margin-right:15px share"
64
- share-network="share"
65
- title="Share on share"
66
- ><i src="/assets/svg/share-alt.svg"></i
67
- ></a>
68
- </div>
69
- </div>
70
- <h1 class="max-width:500px margin:20px_10px">
71
- A simple HTML5, CSS and pure javascript component. Easy
72
- configuration using data-attributes and highly styleable.
73
- </h1>
74
- <div id="lazy-loader-section" class="display:flex flex-wrap:wrap">
75
- <div class="flex-grow:1 width:300px padding:20px_10px">
76
- <h2
77
- class="border-bottom:1px_solid_lightgrey padding:5px_0px">
78
- Install
79
- </h2>
80
- <pre
81
- class="margin-top:15px"><code class="language-javascript">npm install cocreate-lazy-loader</code></pre>
82
- <p class="padding:10px_0px">Or you can use cdn link:</p>
83
- <pre><code class="language-javascript">https://cdn.cocreate.app/js/CoCreate-lazy-loader.min.js</code></pre>
26
+ <body>
27
+ <div array="" object="" key="" id="cocreate-lazy-loader">
28
+ <div
29
+ class="display:flex flex-wrap:wrap justify-content:space-between margin:10px">
30
+ <div class="display:flex align-items:center">
31
+ <h2>CoCreate-lazy-loader</h2>
32
+ </div>
33
+ <div
34
+ class="display:flex align-items:center font-size:20px"
35
+ share-height="600"
36
+ share-width="500"
37
+ share-media="https://via.placeholder.com/300/09f/fff.png">
38
+ <a
39
+ href="https://github.com/CoCreate-app/CoCreate-lazy-loader"
40
+ target="_blank"
41
+ class="margin-right:15px"
42
+ ><i src="/assets/svg/github.svg"></i
43
+ ></a>
44
+ <a
45
+ class="margin-right:15px share"
46
+ share-network="twitter"
47
+ title="Share on twitter"
48
+ ><i src="/assets/svg/twitter.svg"></i
49
+ ></a>
50
+ <a
51
+ class="margin-right:15px share"
52
+ share-network="facebook"
53
+ title="Share on Facebook"
54
+ ><i src="/assets/svg/facebook.svg"></i
55
+ ></a>
56
+ <a
57
+ class="margin-right:15px share"
58
+ share-network="instagram"
59
+ title="Share on instagram"
60
+ ><i src="/assets/svg/instagram.svg"></i
61
+ ></a>
62
+ <a
63
+ class="margin-right:15px share"
64
+ share-network="share"
65
+ title="Share on share"
66
+ ><i src="/assets/svg/share-alt.svg"></i
67
+ ></a>
68
+ </div>
69
+ </div>
70
+ <h1 class="max-width:500px margin:20px_10px">
71
+ A simple HTML5, CSS and pure javascript component. Easy
72
+ configuration using data-attributes and highly styleable.
73
+ </h1>
74
+ <div id="lazy-loader-section" class="display:flex flex-wrap:wrap">
75
+ <div class="flex-grow:1 width:300px padding:20px_10px">
76
+ <h2
77
+ class="border-bottom:1px_solid_lightgrey padding:5px_0px">
78
+ Install
79
+ </h2>
80
+ <pre
81
+ class="margin-top:15px"><code class="language-javascript">npm install cocreate-lazy-loader</code></pre>
82
+ <p class="padding:10px_0px">Or you can use cdn link:</p>
83
+ <pre><code class="language-javascript">https://cdn.cocreate.app/js/CoCreate-lazy-loader.min.js</code></pre>
84
84
 
85
- <h2
86
- class="border-bottom:1px_solid_lightgrey margin-top:20px padding:5px_0px">
87
- Usage
88
- </h2>
89
- <p class="padding:10px_0px">lazy-loader usage content</p>
90
- <pre><code class="language-html">&lt;div&gt;&lt;/div&gt;</code></pre>
85
+ <h2
86
+ class="border-bottom:1px_solid_lightgrey margin-top:20px padding:5px_0px">
87
+ Usage
88
+ </h2>
89
+ <p class="padding:10px_0px">lazy-loader usage content</p>
90
+ <pre><code class="language-html">&lt;div&gt;&lt;/div&gt;</code></pre>
91
91
 
92
- <h2
93
- class="border-bottom:1px_solid_lightgrey margin-top:20px padding:5px_0px">
94
- Reference
95
- </h2>
96
- <p class="padding:10px_0px">
97
- This is lazy-loader reference content
98
- </p>
99
- <pre><code class="language-javascript">&lt;div&gt;&lt;/div&gt;</code></pre>
100
- <p class="padding:10px_0px">
101
- This is lazy-loader reference content
102
- </p>
92
+ <h2
93
+ class="border-bottom:1px_solid_lightgrey margin-top:20px padding:5px_0px">
94
+ Reference
95
+ </h2>
96
+ <p class="padding:10px_0px">
97
+ This is lazy-loader reference content
98
+ </p>
99
+ <pre><code class="language-javascript">&lt;div&gt;&lt;/div&gt;</code></pre>
100
+ <p class="padding:10px_0px">
101
+ This is lazy-loader reference content
102
+ </p>
103
103
 
104
- <h2
105
- class="border-bottom:1px_solid_lightgrey margin-top:20px padding:5px_0px">
106
- Attributes
107
- </h2>
108
- <ul class="list-style-type:none">
109
- <li
110
- class="padding:15px_0px border-bottom:1px_solid_lightgrey">
111
- <h4>
112
- <span>lazy-loader</span>
113
- <span class="cocreate-badge success"
114
- >string</span
115
- >
116
- <span class="cocreate-badge warning"
117
- >optional</span
118
- >
119
- </h4>
120
- <p>lazy-loader-attribute</p>
121
- </li>
122
- <li
123
- class="padding:15px_0px border-bottom:1px_solid_lightgrey">
124
- <h4>
125
- <span>lazy-loader</span>
126
- <span class="cocreate-badge success"
127
- >string</span
128
- >
129
- <span class="cocreate-badge warning"
130
- >optional</span
131
- >
132
- </h4>
133
- <p>lazy-loader-attribute</p>
134
- </li>
135
- </ul>
136
- </div>
104
+ <h2
105
+ class="border-bottom:1px_solid_lightgrey margin-top:20px padding:5px_0px">
106
+ Attributes
107
+ </h2>
108
+ <ul class="list-style-type:none">
109
+ <li
110
+ class="padding:15px_0px border-bottom:1px_solid_lightgrey">
111
+ <h4>
112
+ <span>lazy-loader</span>
113
+ <span class="cocreate-badge success"
114
+ >string</span
115
+ >
116
+ <span class="cocreate-badge warning"
117
+ >optional</span
118
+ >
119
+ </h4>
120
+ <p>lazy-loader-attribute</p>
121
+ </li>
122
+ <li
123
+ class="padding:15px_0px border-bottom:1px_solid_lightgrey">
124
+ <h4>
125
+ <span>lazy-loader</span>
126
+ <span class="cocreate-badge success"
127
+ >string</span
128
+ >
129
+ <span class="cocreate-badge warning"
130
+ >optional</span
131
+ >
132
+ </h4>
133
+ <p>lazy-loader-attribute</p>
134
+ </li>
135
+ </ul>
136
+ </div>
137
137
 
138
- <div
139
- class="flex-grow:1 width:300px padding:0px_10px margin:20px_0px border-bottom:1px_solid_lightgrey">
140
- <!-- SandBox -->
141
- <h2
142
- class="border-bottom:1px_solid_lightgrey padding:5px_0px">
143
- Demo
144
- </h2>
145
- <div
146
- class="position:sticky top:0 padding:10px_0px height:100vh">
147
- <!-- SandBox -->
148
- <div
149
- class="display:flex flex-direction:column position:relative overflow:hidden card border-radius:2px width:auto height:600px margin-top:20px"
150
- id="playground">
151
- <div
152
- id="demo-code"
153
- resizable
154
- class="position:relative height:50%">
155
- <textarea
156
- type="code"
157
- lang="html"
158
- array="demos"
159
- object=""
160
- key="demo"
161
- save="false"
162
- id="demo"
163
- class="height:100% width:100% outline:none border:none resize:none padding:5px"></textarea>
164
- <div
165
- resize="bottom"
166
- class="background:lightgrey"></div>
167
- </div>
138
+ <div
139
+ class="flex-grow:1 width:300px padding:0px_10px margin:20px_0px border-bottom:1px_solid_lightgrey">
140
+ <!-- SandBox -->
141
+ <h2
142
+ class="border-bottom:1px_solid_lightgrey padding:5px_0px">
143
+ Demo
144
+ </h2>
145
+ <div
146
+ class="position:sticky top:0 padding:10px_0px height:100vh">
147
+ <!-- SandBox -->
148
+ <div
149
+ class="display:flex flex-direction:column position:relative overflow:hidden card border-radius:2px width:auto height:600px margin-top:20px"
150
+ id="playground">
151
+ <div
152
+ id="demo-code"
153
+ resizable
154
+ class="position:relative height:50%">
155
+ <textarea
156
+ type="code"
157
+ lang="html"
158
+ array="demos"
159
+ object=""
160
+ key="demo"
161
+ save="false"
162
+ id="demo"
163
+ class="height:100% width:100% outline:none border:none resize:none padding:5px"></textarea>
164
+ <div
165
+ resize="bottom"
166
+ class="background:lightgrey"></div>
167
+ </div>
168
168
 
169
- <div
170
- id="demo-preview"
171
- class="position:relative overflow:auto background-color:white">
172
- <div class="demopreview padding:20px"></div>
173
- </div>
169
+ <div
170
+ id="demo-preview"
171
+ class="position:relative overflow:auto background-color:white">
172
+ <div class="demopreview padding:20px"></div>
173
+ </div>
174
174
 
175
- <div
176
- class="font-size:20px position:absolute top:10px right:10px opacity:0.6">
177
- <a
178
- class="margin-right:10px"
179
- id="eye"
180
- show="#eye-slash"
181
- hide="#eye, #demo-preview"
182
- toggle="code-height"
183
- toggle-selector="#demo-code"
184
- ><i
185
- class="height:18px"
186
- src="/assets/svg/eye.svg"></i
187
- ></a>
188
- <a
189
- class="margin-right:10px"
190
- hidden
191
- id="eye-slash"
192
- show="#eye, #demo-preview"
193
- hide="#eye-slash"
194
- toggle="code-height"
195
- toggle-selector="#demo-code"
196
- ><i src="/assets/svg/eye-slash.svg"></i
197
- ></a>
198
- <a
199
- class="margin-right:10px"
200
- id="code"
201
- show="#code-slash"
202
- hide="#code, #demo-code"
203
- ><i src="/assets/svg/code.svg"></i
204
- ></a>
205
- <a
206
- class="margin-right:10px"
207
- hidden
208
- id="code-slash"
209
- show="#code, #demo-code"
210
- hide="#code-slash"
211
- ><i
212
- class="height:18px"
213
- src="/assets/svg/code.svg"></i
214
- ></a>
215
- <a
216
- class="margin-right:5px"
217
- fullscreen
218
- fullscreen-selector="#playground"></a>
219
- </div>
220
- </div>
221
- <!-- End SandBox -->
222
- </div>
223
- </div>
224
- </div>
225
- </div>
175
+ <div
176
+ class="font-size:20px position:absolute top:10px right:10px opacity:0.6">
177
+ <a
178
+ class="margin-right:10px"
179
+ id="eye"
180
+ show="#eye-slash"
181
+ hide="#eye, #demo-preview"
182
+ toggle="code-height"
183
+ toggle-query="#demo-code"
184
+ ><i
185
+ class="height:18px"
186
+ src="/assets/svg/eye.svg"></i
187
+ ></a>
188
+ <a
189
+ class="margin-right:10px"
190
+ hidden
191
+ id="eye-slash"
192
+ show="#eye, #demo-preview"
193
+ hide="#eye-slash"
194
+ toggle="code-height"
195
+ toggle-query="#demo-code"
196
+ ><i src="/assets/svg/eye-slash.svg"></i
197
+ ></a>
198
+ <a
199
+ class="margin-right:10px"
200
+ id="code"
201
+ show="#code-slash"
202
+ hide="#code, #demo-code"
203
+ ><i src="/assets/svg/code.svg"></i
204
+ ></a>
205
+ <a
206
+ class="margin-right:10px"
207
+ hidden
208
+ id="code-slash"
209
+ show="#code, #demo-code"
210
+ hide="#code-slash"
211
+ ><i
212
+ class="height:18px"
213
+ src="/assets/svg/code.svg"></i
214
+ ></a>
215
+ <a
216
+ class="margin-right:5px"
217
+ fullscreen
218
+ fullscreen-query="#playground"></a>
219
+ </div>
220
+ </div>
221
+ <!-- End SandBox -->
222
+ </div>
223
+ </div>
224
+ </div>
225
+ </div>
226
226
 
227
- <!--CoCreateJS-->
228
- <script src="https://CoCreate.app/dist/CoCreate.js"></script>
229
- </body>
227
+ <!--CoCreateJS-->
228
+ <script src="https://CoCreate.app/dist/CoCreate.js"></script>
229
+ </body>
230
230
  </html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocreate/lazy-loader",
3
- "version": "1.23.3",
3
+ "version": "1.23.4",
4
4
  "description": "A simple lazy-loader component in vanilla javascript. Easily configured using HTML5 data-attributes and/or JavaScript API.",
5
5
  "keywords": [
6
6
  "lazy-loader",
@@ -45,20 +45,16 @@
45
45
  },
46
46
  "main": "./src/index.js",
47
47
  "devDependencies": {
48
- "@babel/core": "^7.9.6",
49
- "@babel/preset-env": "^7.9.6",
50
- "babel-loader": "^8.1.0",
51
- "clean-webpack-plugin": "^3.0.0",
52
- "file-loader": "^6.2.0",
48
+ "css-loader": "^5.1.3",
49
+ "esbuild": "^0.25.2",
50
+ "esbuild-loader": "^4.3.0",
53
51
  "mini-css-extract-plugin": "^1.5.0",
54
- "style-loader": "^3.3.1",
55
- "terser-webpack-plugin": "^5.1.1",
56
52
  "webpack": "^5.24.4",
57
53
  "webpack-cli": "^4.5.0",
58
54
  "webpack-log": "^3.0.1"
59
55
  },
60
56
  "dependencies": {
61
- "@cocreate/config": "^1.12.5",
62
- "@cocreate/observer": "^1.16.3"
57
+ "@cocreate/config": "^1.13.0",
58
+ "@cocreate/observer": "^1.18.0"
63
59
  }
64
60
  }
package/src/client.js CHANGED
@@ -1,9 +1,11 @@
1
1
  import observer from "@cocreate/observer";
2
2
 
3
3
  function listen(name, callback, selector) {
4
- const observerName = name + "LazyloadAddedNodesObserver";
4
+ const addedNodesObserverName = name + "LazyloadAddedNodesObserver";
5
+ const attributesObserverName = name + "LazyloadAttributesObserver";
5
6
  async function observerCallback(mutation) {
6
- observer.uninit(observerName);
7
+ observer.uninit(addedNodesObserverName);
8
+ observer.uninit(attributesObserverName);
7
9
 
8
10
  if (!window.CoCreate) window.CoCreate = {};
9
11
 
@@ -19,7 +21,7 @@ function listen(name, callback, selector) {
19
21
  }
20
22
 
21
23
  observer.init({
22
- name: observerName,
24
+ name: addedNodesObserverName,
23
25
  types: ["addedNodes"],
24
26
  selector,
25
27
  callback: observerCallback
@@ -42,7 +44,7 @@ function listen(name, callback, selector) {
42
44
  }
43
45
  if (selectorAttributes.length > 0)
44
46
  observer.init({
45
- name: observerName,
47
+ name: attributesObserverName,
46
48
  types: ["attributes"],
47
49
  attributeFilter: selectorAttributes,
48
50
  selector,
@@ -51,9 +53,11 @@ function listen(name, callback, selector) {
51
53
  }
52
54
 
53
55
  export async function lazyLoad(name, selector, callback) {
54
- if (document.querySelector(selector))
56
+ if (document.querySelector(selector)) {
55
57
  await dependency(name, await callback());
56
- else listen(name, callback, selector);
58
+ } else {
59
+ listen(name, callback, selector);
60
+ }
57
61
  }
58
62
 
59
63
  export async function dependency(name, promise) {
package/src/server.js CHANGED
@@ -3,7 +3,7 @@ const path = require("path");
3
3
  const { URL } = require("url");
4
4
  const vm = require("vm");
5
5
  const Config = require("@cocreate/config");
6
- const { getValueFromObject } = require("@cocreate/utils");
6
+ const { getValueFromObject, objectToSearchParams } = require("@cocreate/utils");
7
7
 
8
8
  class CoCreateLazyLoader {
9
9
  constructor(server, crud, files) {
@@ -26,12 +26,16 @@ class CoCreateLazyLoader {
26
26
  throw error; // Halt execution if directory creation fails
27
27
  }
28
28
 
29
+ this.wsManager.on("endpoint", (data) => {
30
+ this.executeEndpoint(data);
31
+ });
32
+
29
33
  this.modules = await Config("modules", false, false);
30
34
  if (!this.modules) return;
31
35
  else this.modules = this.modules.modules;
32
36
 
33
37
  for (let name of Object.keys(this.modules)) {
34
- this.wsManager.on(this.modules[name].event, async (data) => {
38
+ this.wsManager.on(this.modules[name].event, (data) => {
35
39
  this.executeScriptWithTimeout(name, data);
36
40
  });
37
41
  }
@@ -86,15 +90,242 @@ class CoCreateLazyLoader {
86
90
  }
87
91
  }
88
92
 
93
+ async executeEndpoint(data) {
94
+ try {
95
+ if (!data.method || !data.endpoint) {
96
+ throw new Error("Request missing 'method' or 'endpoint'.");
97
+ }
98
+
99
+ let name = data.method.split(".")[0];
100
+ let method = data.endpoint.split(" ")[0].toUpperCase();
101
+
102
+ // data = await this.processOperators(data, "", name);
103
+
104
+ let apiConfig = await this.getApiConfig(data, name);
105
+ // --- Refined Validation ---
106
+ if (!apiConfig) {
107
+ throw new Error(`Configuration missing for API: '${name}'.`);
108
+ }
109
+ if (!apiConfig.url) {
110
+ throw new Error(
111
+ `Configuration error: Missing base url for API '${name}'.`
112
+ );
113
+ }
114
+ // apiConfig = await this.processOperators(data, getApiConfig, "");
115
+
116
+ let override = apiConfig.endpoint?.[data.endpoint] || {};
117
+
118
+ let url = apiConfig.url; // Base URL
119
+ url = url.endsWith("/") ? url.slice(0, -1) : url;
120
+
121
+ let path = override.path || data.endpoint.split(" ")[1];
122
+ url += path.startsWith("/") ? path : `/${path}`;
123
+
124
+ url += objectToSearchParams(data[name].$searchParams);
125
+
126
+ // User's proposed simplification:
127
+ let headers = apiConfig.headers; // Default headers
128
+ if (override.headers) {
129
+ headers = { ...headers, ...override.headers }; // Correct idea for merging
130
+ }
131
+
132
+ let body = formatRequestBody(data[name]);
133
+
134
+ let options = { method, headers, body, timeout };
135
+
136
+ const response = await makeHttpRequest(url, options);
137
+ data[name] = parseResponse(response);
138
+
139
+ this.wsManager.send(data);
140
+ } catch (error) {
141
+ data.error = error.message;
142
+ if (data.req) {
143
+ data.res.writeHead(400, {
144
+ "Content-Type": "text/plain"
145
+ });
146
+ data.res.end(`Lazyload Error: ${error.message}`);
147
+ }
148
+ if (data.socket) {
149
+ this.wsManager.send(data);
150
+ }
151
+ }
152
+ }
153
+
154
+ /**
155
+ * Formats the request body payload based on the specified format type.
156
+ *
157
+ * @param {object | string} payload The data intended for the request body.
158
+ * @param {string} [formatType='json'] The desired format ('json', 'form-urlencoded', 'text', 'multipart', 'xml'). Defaults to 'json'.
159
+ * @returns {{ body: string | Buffer | FormData | null, contentTypeHeader: string | null }}
160
+ * An object containing the formatted body and the corresponding Content-Type header.
161
+ * Returns null body/header on error or for unsupported types.
162
+ */
163
+ formatRequestBody(payload, formatType = "json") {
164
+ let body = null;
165
+ let contentTypeHeader = null;
166
+
167
+ try {
168
+ switch (formatType.toLowerCase()) {
169
+ case "json":
170
+ body = JSON.stringify(payload);
171
+ contentTypeHeader = "application/json; charset=utf-8";
172
+ break;
173
+
174
+ case "form-urlencoded":
175
+ // In Node.js using querystring:
176
+ // const querystring = require('node:querystring');
177
+ // body = querystring.stringify(payload);
178
+ // Or using URLSearchParams (Node/Browser):
179
+ body = new URLSearchParams(payload).toString();
180
+ contentTypeHeader =
181
+ "application/x-www-form-urlencoded; charset=utf-8";
182
+ break;
183
+
184
+ case "text":
185
+ if (typeof payload === "string") {
186
+ body = payload;
187
+ } else if (
188
+ payload &&
189
+ typeof payload.toString === "function"
190
+ ) {
191
+ // Attempt conversion for simple objects/values, might need refinement
192
+ body = payload.toString();
193
+ } else {
194
+ throw new Error(
195
+ "Payload must be a string or convertible to string for 'text' format."
196
+ );
197
+ }
198
+ contentTypeHeader = "text/plain; charset=utf-8";
199
+ break;
200
+
201
+ case "multipart":
202
+ // COMPLEX: Requires FormData (browser) or form-data library (Node)
203
+ // Needs specific logic to handle payload structure (identifying files vs fields)
204
+ // const formData = buildFormData(payload); // Placeholder for complex logic
205
+ // body = formData; // The FormData object itself or its stream
206
+ // contentTypeHeader = formData.getHeaders ? formData.getHeaders()['content-type'] : 'multipart/form-data; boundary=...'; // Header includes boundary
207
+ console.warn(
208
+ "Multipart formatting requires specific implementation."
209
+ );
210
+ // For now, return null or throw error
211
+ throw new Error(
212
+ "Multipart formatting not implemented in this basic function."
213
+ );
214
+ break; // Example: Not fully implemented here
215
+
216
+ case "xml":
217
+ // COMPLEX: Requires an XML serialization library
218
+ // const xmlString = convertObjectToXml(payload); // Placeholder
219
+ // body = xmlString;
220
+ console.warn(
221
+ "XML formatting requires an external library."
222
+ );
223
+ throw new Error(
224
+ "XML formatting not implemented in this basic function."
225
+ );
226
+ break; // Example: Not fully implemented here
227
+
228
+ default:
229
+ console.error(
230
+ `Unsupported requestBodyFormat: ${formatType}`
231
+ );
232
+ // Fallback or throw error
233
+ body = JSON.stringify(payload); // Default to JSON on unknown? Or error?
234
+ contentTypeHeader = "application/json; charset=utf-8";
235
+ }
236
+ } catch (error) {
237
+ console.error(
238
+ `Error formatting request body as ${formatType}:`,
239
+ error
240
+ );
241
+ return { body: null, contentTypeHeader: null }; // Return nulls on error
242
+ }
243
+
244
+ return { body, contentTypeHeader };
245
+ }
246
+
247
+ /**
248
+ * Makes an HTTP request using node-fetch.
249
+ * @param {string} url - The complete URL to request.
250
+ * @param {string} method - The HTTP method (GET, POST, etc.).
251
+ * @param {object} headers - The request headers object.
252
+ * @param {string|Buffer|null|undefined} body - The formatted request body.
253
+ * @param {number} timeout - Request timeout in milliseconds.
254
+ * @returns {Promise<{status: number, data: any}>} - Resolves with status and parsed response data.
255
+ * @throws {Error} If the request fails or returns a non-ok status.
256
+ */
257
+ async makeHttpRequest(url, options) {
258
+ if (!this.server.AbortController) {
259
+ console.log("makeHttpRequest test");
260
+ return {};
261
+ }
262
+ const controller = new this.server.AbortController();
263
+ const timeoutId = setTimeout(() => controller.abort(), options.timeout);
264
+ options.signal = controller.signal;
265
+
266
+ // Remove Content-Type header if there's no body (relevant for GET, DELETE etc.)
267
+ if (
268
+ options.body === undefined &&
269
+ options.headers &&
270
+ options.headers["Content-Type"]
271
+ ) {
272
+ delete options.headers["Content-Type"];
273
+ }
274
+
275
+ try {
276
+ const response = await this.server.fetch(url, options);
277
+ clearTimeout(timeoutId); // Request finished, clear timeout
278
+
279
+ if (!response.ok) {
280
+ // status >= 200 && status < 300
281
+ const error = new Error(
282
+ `HTTP error! Status: ${response.status} ${response.statusText}`
283
+ );
284
+ // Attach structured response info to the error
285
+ error.response = {
286
+ status: response.status,
287
+ statusText: response.statusText,
288
+ headers: Object.fromEntries(response.headers.entries()),
289
+ data: parseResponse(response) // Include parsed error body
290
+ };
291
+ throw error;
292
+ }
293
+ return response;
294
+ } catch (error) {
295
+ clearTimeout(timeoutId);
296
+ if (error.name === "AbortError") {
297
+ console.error(
298
+ `Request timed out after ${options.timeout}ms: ${options.method} ${url}`
299
+ );
300
+ throw new Error(
301
+ `Request Timeout: API call exceeded ${options.timeout}ms`
302
+ );
303
+ }
304
+
305
+ // If it already has response info (from !response.ok), rethrow it
306
+ if (error.response) {
307
+ throw error;
308
+ }
309
+ // Otherwise, wrap other errors (network, DNS, etc.)
310
+ console.error(
311
+ `Network/Request Error: ${options.method} ${url}`,
312
+ error
313
+ );
314
+ throw new Error(`Network/Request Error: ${error.message}`);
315
+ }
316
+ }
317
+
89
318
  async executeScriptWithTimeout(name, data) {
90
319
  try {
91
320
  if (
92
321
  this.modules[name].initialize ||
93
322
  this.modules[name].initialize === ""
94
323
  ) {
95
- if (data.req)
324
+ if (data.req) {
96
325
  data = await this.webhooks(this.modules[name], data, name);
97
- else data = await this.api(this.modules[name], data);
326
+ } else {
327
+ data = await this.api(this.modules[name], data);
328
+ }
98
329
  } else {
99
330
  if (!this.modules[name].content) {
100
331
  if (this.modules[name].path)
@@ -124,7 +355,7 @@ class CoCreateLazyLoader {
124
355
  }
125
356
 
126
357
  if (this.modules[name].content) {
127
- data.apis = await this.getApiKey(data, name);
358
+ data.apis = await this.getApiConfig(data, name);
128
359
  data.crud = this.crud;
129
360
  data = await this.modules[name].content.send(data);
130
361
  delete data.apis;
@@ -218,7 +449,7 @@ class CoCreateLazyLoader {
218
449
  const methodPath = data.method.split(".");
219
450
  const name = methodPath.shift();
220
451
 
221
- const apis = await this.getApiKey(data, name);
452
+ const apis = await this.getApiConfig(data, name);
222
453
 
223
454
  const key = apis.key;
224
455
  if (!key)
@@ -320,7 +551,7 @@ class CoCreateLazyLoader {
320
551
 
321
552
  async webhooks(config, data, name) {
322
553
  try {
323
- const apis = await this.getApiKey(data, name);
554
+ const apis = await this.getApiConfig(data, name);
324
555
 
325
556
  const key = apis.key;
326
557
  if (!key)
@@ -568,7 +799,7 @@ class CoCreateLazyLoader {
568
799
  return operator;
569
800
  }
570
801
 
571
- async getApiKey(data, name) {
802
+ async getApiConfig(data, name) {
572
803
  let organization = await this.crud.getOrganization(data);
573
804
  if (organization.error) throw new Error(organization.error);
574
805
  if (!organization.apis)
package/webpack.config.js CHANGED
@@ -1,90 +1,65 @@
1
- const path = require("path")
2
- const TerserPlugin = require("terser-webpack-plugin")
3
- const MiniCssExtractPlugin = require("mini-css-extract-plugin")
4
- const { CleanWebpackPlugin } = require("clean-webpack-plugin")
5
-
6
- module.exports = (env, argv) => {
7
- let isProduction = false
8
- if (argv.mode === 'production')
9
- isProduction = true
10
-
11
- const config = {
12
- entry: {
13
- "CoCreate-lazy-loader": "./src/index.js",
14
- },
15
- output: {
16
- path: path.resolve(__dirname, "dist"),
17
- filename: isProduction ? "[name].min.js" : "[name].js",
18
- libraryTarget: "umd",
19
- libraryExport: "default",
20
- library: ["CoCreate", "lazy-loader"],
21
- globalObject: "this",
22
- },
23
-
24
- plugins: [
25
- new CleanWebpackPlugin(),
26
- new MiniCssExtractPlugin({
27
- filename: "[name].css",
28
- }),
29
- ],
30
- // Default mode for Webpack is production.
31
- // Depending on mode Webpack will apply different things
32
- // on final bundle. For now we don't need production's JavaScript
33
- // minifying and other thing so let's set mode to development
34
- mode: isProduction ? "production" : "development",
35
- module: {
36
- rules: [
37
- {
38
- test: /.js$/,
39
- exclude: /(node_modules)/,
40
- use: {
41
- loader: "babel-loader",
42
- options: {
43
- plugins: ["@babel/plugin-transform-modules-commonjs"],
44
- },
45
- },
46
- },
47
- {
48
- test: /.css$/i,
49
- use: [
50
- { loader: "style-loader", options: { injectType: "linkTag" } },
51
- "file-loader",
52
- ],
53
- },
54
- ],
55
- },
56
-
57
- // add source map
58
- ...(isProduction ? {} : { devtool: "eval-source-map" }),
59
-
60
- optimization: {
61
- minimize: true,
62
- minimizer: [
63
- new TerserPlugin({
64
- extractComments: true,
65
- // cache: true,
66
- parallel: true,
67
- // sourceMap: true, // Must be set to true if using source-maps in production
68
- terserOptions: {
69
- // https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions
70
- // extractComments: 'all',
71
- compress: {
72
- drop_console: true,
73
- },
74
- },
75
- }),
76
- ],
77
- splitChunks: {
78
- chunks: "all",
79
- minSize: 200,
80
- // maxSize: 99999,
81
- //minChunks: 1,
82
-
83
- cacheGroups: {
84
- defaultVendors: false,
85
- },
86
- },
87
- },
88
- }
89
- return config
90
- }
1
+ const path = require("path");
2
+ const MiniCssExtractPlugin = require("mini-css-extract-plugin");
3
+ const { EsbuildPlugin } = require("esbuild-loader");
4
+ const { FileUploader } = require("@cocreate/webpack");
5
+
6
+ module.exports = async (env, argv) => {
7
+ const isProduction = argv && argv.mode === "production";
8
+ const config = {
9
+ entry: {
10
+ "CoCreate-lazy-loader": "./src/index.js"
11
+ },
12
+ output: {
13
+ path: path.resolve(__dirname, "dist"),
14
+ filename: isProduction ? "[name].min.js" : "[name].js",
15
+ libraryExport: "default",
16
+ library: ["CoCreate", "lazyLoader"],
17
+ clean: true
18
+ },
19
+ plugins: [
20
+ new MiniCssExtractPlugin({
21
+ filename: isProduction ? "[name].min.css" : "[name].css"
22
+ }),
23
+ new FileUploader(env, argv)
24
+ ],
25
+ mode: isProduction ? "production" : "development",
26
+ devtool: isProduction ? "source-map" : "eval-source-map",
27
+ module: {
28
+ rules: [
29
+ {
30
+ test: /.js$/,
31
+ exclude: /node_modules/,
32
+ use: {
33
+ loader: "esbuild-loader",
34
+ options: {
35
+ loader: "js",
36
+ target: "es2017"
37
+ }
38
+ }
39
+ },
40
+ {
41
+ test: /.css$/i,
42
+ use: [MiniCssExtractPlugin.loader, "css-loader"]
43
+ }
44
+ ]
45
+ },
46
+ optimization: {
47
+ minimize: isProduction,
48
+ minimizer: [
49
+ new EsbuildPlugin({
50
+ target: "es2017",
51
+ css: true
52
+ })
53
+ ],
54
+ splitChunks: {
55
+ cacheGroups: {
56
+ defaultVendors: false
57
+ }
58
+ }
59
+ },
60
+ performance: {
61
+ hints: isProduction ? "warning" : false
62
+ }
63
+ };
64
+ return config;
65
+ };