svelteesp32 1.4.2 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,6 +12,8 @@ In order to be able to easily update OTA, it is important - from the users' poin
12
12
 
13
13
  This npm package provides a solution for **inserting any JS client application into the ESP web server** (PsychicHttp and also ESPAsyncWebServer available, PsychicHttp is the default). For this, JS, html, css, font, assets, etc. files must be converted to binary byte array. Npm mode is easy to use and easy to **integrate into your CI/CD pipeline**.
14
14
 
15
+ > Starting with version v1.5.0, PsychicHttp v2 is also supported.
16
+
15
17
  > Version v1.4.0 has a breaking change! --no-gzip changed to --gzip. Starting with this version c++ compiler directives are available to setup operation in project level.
16
18
 
17
19
  > Starting with version v1.3.0, c++ defines can be used.
@@ -34,6 +36,9 @@ After a successful Svelte build (rollup/webpack/vite) **create an includeable c+
34
36
  // for PsychicHttpServer
35
37
  npx svelteesp32 -e psychic -s ../svelteapp/dist -o ../esp32project/svelteesp32.h --etag=true
36
38
 
39
+ // for PsychicHttpServer V2
40
+ npx svelteesp32 -e psychic2 -s ../svelteapp/dist -o ../esp32project/svelteesp32.h --etag=true
41
+
37
42
  // for ESPAsyncWebServer
38
43
  npx svelteesp32 -e async -s ../svelteapp/dist -o ../esp32project/svelteesp32.h --etag=true
39
44
  ```
@@ -217,18 +222,18 @@ You can use the following c++ directives at the project level if you want to con
217
222
 
218
223
  ### Command line options
219
224
 
220
- | Option | Description | default |
221
- | ------------- | ---------------------------------------------------------------- | ----------------------- |
222
- | `-s` | **Source dist folder contains compiled web files** | |
223
- | `-e` | The engine for which the include file is created (psychic/async) | psychic |
224
- | `-o` | Generated output file with path | `svelteesp32.h` |
225
- | `--etag` | Use ETag header for cache (true/false/compiler) | false |
226
- | `--gzip` | Compress content with gzip (true/false/compiler) | true |
227
- | `--created` | Include creation time | false |
228
- | `--version` | Include a version string, `--version=v$npm_package_version` | '' |
229
- | `--espmethod` | Name of generated method | `initSvelteStaticFiles` |
230
- | `--define` | Prefix of c++ defines | `SVELTEESP32` |
231
- | `-h` | Show help | |
225
+ | Option | Description | default |
226
+ | ------------- | ------------------------------------------------------------------------- | ----------------------- |
227
+ | `-s` | **Source dist folder contains compiled web files** | |
228
+ | `-e` | The engine for which the include file is created (psychic/psychic2/async) | psychic |
229
+ | `-o` | Generated output file with path | `svelteesp32.h` |
230
+ | `--etag` | Use ETag header for cache (true/false/compiler) | false |
231
+ | `--gzip` | Compress content with gzip (true/false/compiler) | true |
232
+ | `--created` | Include creation time | false |
233
+ | `--version` | Include a version string, `--version=v$npm_package_version` | '' |
234
+ | `--espmethod` | Name of generated method | `initSvelteStaticFiles` |
235
+ | `--define` | Prefix of c++ defines | `SVELTEESP32` |
236
+ | `-h` | Show help | |
232
237
 
233
238
  ### Q&A
234
239
 
@@ -1,5 +1,5 @@
1
1
  interface ICopyFilesArguments {
2
- engine: 'psychic' | 'async';
2
+ engine: 'psychic' | 'psychic2' | 'async';
3
3
  sourcepath: string;
4
4
  outputfile: string;
5
5
  espmethod: string;
@@ -8,12 +8,14 @@ exports.cmdLine = (0, ts_command_line_args_1.parse)({
8
8
  type: (value) => {
9
9
  if (value === 'psychic')
10
10
  return 'psychic';
11
+ if (value === 'psychic2')
12
+ return 'psychic2';
11
13
  if (value === 'async')
12
14
  return 'async';
13
15
  throw new Error(`Invalid engine: ${value}`);
14
16
  },
15
17
  alias: 'e',
16
- description: 'The engine for which the include file is created (psychic|async)',
18
+ description: 'The engine for which the include file is created (psychic|psychic2|async)',
17
19
  defaultValue: 'psychic'
18
20
  },
19
21
  sourcepath: {
package/dist/cppCode.js CHANGED
@@ -180,6 +180,182 @@ void {{methodName}}(PsychicHttpServer * server) {
180
180
  return response.send();
181
181
  });
182
182
 
183
+ {{/each}}
184
+ }`;
185
+ const psychic2Template = `
186
+ //engine: PsychicHttpServerV2
187
+ //cmdline: {{{commandLine}}}
188
+ {{#if created }}
189
+ //created: {{now}}
190
+ {{/if}}
191
+ //
192
+
193
+ {{#switch etag}}
194
+ {{#case "true"}}
195
+ #ifdef {{definePrefix}}_ENABLE_ETAG
196
+ #warning {{definePrefix}}_ENABLE_ETAG has no effect because it is permanently switched ON
197
+ #endif
198
+ {{/case}}
199
+ {{#case "false"}}
200
+ #ifdef {{definePrefix}}_ENABLE_ETAG
201
+ #warning {{definePrefix}}_ENABLE_ETAG has no effect because it is permanently switched OFF
202
+ #endif
203
+ {{/case}}
204
+ {{/switch}}
205
+
206
+ {{#switch gzip}}
207
+ {{#case "true"}}
208
+ #ifdef {{definePrefix}}_ENABLE_GZIP
209
+ #warning {{definePrefix}}_ENABLE_GZIP has no effect because it is permanently switched ON
210
+ #endif
211
+ {{/case}}
212
+ {{#case "false"}}
213
+ #ifdef {{definePrefix}}_ENABLE_GZIP
214
+ #warning {{definePrefix}}_ENABLE_GZIP has no effect because it is permanently switched OFF
215
+ #endif
216
+ {{/case}}
217
+ {{/switch}}
218
+
219
+ //
220
+ {{#if version }}
221
+ #define {{definePrefix}}_VERSION "{{version}}"
222
+ {{/if}}
223
+ #define {{definePrefix}}_COUNT {{fileCount}}
224
+ #define {{definePrefix}}_SIZE {{fileSize}}
225
+ #define {{definePrefix}}_SIZE_GZIP {{fileGzipSize}}
226
+
227
+ //
228
+ {{#each sources}}
229
+ #define {{../definePrefix}}_FILE_{{this.datanameUpperCase}}
230
+ {{/each}}
231
+
232
+ //
233
+ {{#each filesByExtension}}
234
+ #define {{../definePrefix}}_{{this.extension}}_FILES {{this.count}}
235
+ {{/each}}
236
+
237
+ //
238
+ #include <Arduino.h>
239
+ #include <PsychicHttp.h>
240
+ #include <PsychicHttpsServer.h>
241
+
242
+ //
243
+ {{#switch gzip}}
244
+ {{#case "true"}}
245
+ {{#each sources}}
246
+ const uint8_t datagzip_{{this.dataname}}[{{this.lengthGzip}}] = { {{this.bytesGzip}} };
247
+ {{/each}}
248
+ {{/case}}
249
+ {{#case "false"}}
250
+ {{#each sources}}
251
+ const uint8_t data_{{this.dataname}}[{{this.length}}] = { {{this.bytes}} };
252
+ {{/each}}
253
+ {{/case}}
254
+ {{#case "compiler"}}
255
+ #ifdef {{definePrefix}}_ENABLE_GZIP
256
+ {{#each sources}}
257
+ const uint8_t datagzip_{{this.dataname}}[{{this.lengthGzip}}] = { {{this.bytesGzip}} };
258
+ {{/each}}
259
+ #else
260
+ {{#each sources}}
261
+ const uint8_t data_{{this.dataname}}[{{this.length}}] = { {{this.bytes}} };
262
+ {{/each}}
263
+ #endif
264
+ {{/case}}
265
+ {{/switch}}
266
+
267
+ //
268
+ {{#switch etag}}
269
+ {{#case "true"}}
270
+ {{#each sources}}
271
+ const char * etag_{{this.dataname}} = "{{this.md5}}";
272
+ {{/each}}
273
+ {{/case}}
274
+ {{#case "false"}}
275
+ {{/case}}
276
+ {{#case "compiler"}}
277
+ #ifdef {{definePrefix}}_ENABLE_ETAG
278
+ {{#each sources}}
279
+ const char * etag_{{this.dataname}} = "{{this.md5}}";
280
+ {{/each}}
281
+ #endif
282
+ {{/case}}
283
+ {{/switch}}
284
+
285
+ //
286
+ // Http Handlers
287
+ void {{methodName}}(PsychicHttpServer * server) {
288
+ {{#each sources}}
289
+ //
290
+ // {{this.filename}}
291
+ {{#if this.isDefault}}server->defaultEndpoint = {{/if}}server->on("/{{this.filename}}", HTTP_GET, [](PsychicRequest * request, PsychicResponse * response) {
292
+
293
+ {{#switch ../etag}}
294
+ {{#case "true"}}
295
+ if (request->hasHeader("If-None-Match") && request->header("If-None-Match") == String(etag_{{this.dataname}})) {
296
+ response->setCode(304);
297
+ return response->send();
298
+ }
299
+ {{/case}}
300
+ {{#case "compiler"}}
301
+ #ifdef {{../definePrefix}}_ENABLE_ETAG
302
+ if (request->hasHeader("If-None-Match") && request->header("If-None-Match") == String(etag_{{this.dataname}})) {
303
+ response->setCode(304);
304
+ return response->send();
305
+ }
306
+ #endif
307
+ {{/case}}
308
+ {{/switch}}
309
+
310
+ response->setContentType("{{this.mime}}");
311
+
312
+ {{#switch ../gzip}}
313
+ {{#case "true"}}
314
+ {{#if this.isGzip}}
315
+ response->addHeader("Content-Encoding", "gzip");
316
+ {{/if}}
317
+ {{/case}}
318
+ {{#case "compiler"}}
319
+ {{#if this.isGzip}}
320
+ #ifdef {{../definePrefix}}_ENABLE_GZIP
321
+ response->addHeader("Content-Encoding", "gzip");
322
+ #endif
323
+ {{/if}}
324
+ {{/case}}
325
+ {{/switch}}
326
+
327
+ {{#switch ../etag}}
328
+ {{#case "true"}}
329
+ response->addHeader("cache-control", "no-cache");
330
+ response->addHeader("ETag", etag_{{this.dataname}});
331
+ {{/case}}
332
+ {{#case "compiler"}}
333
+ #ifdef {{../definePrefix}}_ENABLE_ETAG
334
+ response->addHeader("cache-control", "no-cache");
335
+ response->addHeader("ETag", etag_{{this.dataname}});
336
+ #endif
337
+ {{/case}}
338
+ {{/switch}}
339
+
340
+ {{#switch ../gzip}}
341
+ {{#case "true"}}
342
+ response->setContent(datagzip_{{this.dataname}}, {{this.lengthGzip}});
343
+ {{/case}}
344
+ {{#case "false"}}
345
+ response->setContent(data_{{this.dataname}}, {{this.length}});
346
+ {{/case}}
347
+ {{#case "compiler"}}
348
+ #ifdef {{../definePrefix}}_ENABLE_GZIP
349
+ response->setContent(datagzip_{{this.dataname}}, {{this.lengthGzip}});
350
+ #else
351
+ response->setContent(data_{{this.dataname}}, {{this.length}});
352
+ #endif
353
+ {{/case}}
354
+ {{/switch}}
355
+
356
+ return response->send();
357
+ });
358
+
183
359
  {{/each}}
184
360
  }`;
185
361
  const asyncTemplate = `
@@ -351,7 +527,7 @@ void {{methodName}}(AsyncWebServer * server) {
351
527
  {{/each}}
352
528
  }`;
353
529
  let switchValue;
354
- const getCppCode = (sources, filesByExtension) => (0, handlebars_1.compile)(commandLine_1.cmdLine.engine === 'psychic' ? psychicTemplate : asyncTemplate)({
530
+ const getCppCode = (sources, filesByExtension) => (0, handlebars_1.compile)(commandLine_1.cmdLine.engine === 'psychic' ? psychicTemplate : commandLine_1.cmdLine.engine === 'psychic2' ? psychic2Template : asyncTemplate)({
355
531
  commandLine: process.argv.slice(2).join(' '),
356
532
  now: `${new Date().toLocaleDateString()} ${new Date().toLocaleTimeString()}`,
357
533
  fileCount: sources.length.toString(),
package/dist/index.js CHANGED
@@ -32,7 +32,7 @@ for (const [originalFilename, content] of files) {
32
32
  const mime = (0, mime_types_1.lookup)(originalFilename) || 'text/plain';
33
33
  summary.filecount++;
34
34
  const filename = originalFilename.replace(/\\/g, '/');
35
- const dataname = filename.replace(/[./-]/g, '_');
35
+ const dataname = filename.replace(/[!&()+./@{}~-]/g, '_');
36
36
  let extension = node_path_1.default.extname(filename).toUpperCase();
37
37
  if (extension.startsWith('.'))
38
38
  extension = extension.slice(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelteesp32",
3
- "version": "1.4.2",
3
+ "version": "1.5.1",
4
4
  "description": "Convert Svelte (or any frontend) JS application to serve it from ESP32 webserver (PsychicHttp)",
5
5
  "author": "BCsabaEngine",
6
6
  "license": "ISC",
@@ -30,6 +30,7 @@
30
30
  "scripts": {
31
31
  "dev:async": "nodemon src/index.ts -- -e async -s ./demo/svelte/dist -o ./demo/esp32/include/svelteesp32.h --etag=true --gzip=true --version=v$npm_package_version",
32
32
  "dev:psychic": "nodemon src/index.ts -- -e psychic -s ./demo/svelte/dist -o ./demo/esp32/include/svelteesp32.h --etag=false --gzip=false --version=v$npm_package_version",
33
+ "dev:psychic2": "nodemon src/index.ts -- -e psychic2 -s ./demo/svelte/dist -o ./demo/esp32/include/svelteesp32.h --etag=false --gzip=false --version=v$npm_package_version",
33
34
  "test:all": "./package.script && ~/.platformio/penv/bin/pio run -d ./demo/esp32",
34
35
  "clean": "tsc --build --clean",
35
36
  "build": "tsc --build --clean && tsc --build --force",
@@ -49,21 +50,22 @@
49
50
  "esp8266",
50
51
  "webserver",
51
52
  "psychichttpserver",
53
+ "psychichttpserverV2",
52
54
  "espasyncwebserver"
53
55
  ],
54
56
  "devDependencies": {
55
57
  "@types/mime-types": "^2.1.4",
56
- "@types/node": "^22.4.2",
57
- "@typescript-eslint/eslint-plugin": "^8.2.0",
58
- "@typescript-eslint/parser": "^8.2.0",
59
- "eslint": "^9.9.0",
58
+ "@types/node": "^22.5.4",
59
+ "@typescript-eslint/eslint-plugin": "^8.4.0",
60
+ "@typescript-eslint/parser": "^8.4.0",
61
+ "eslint": "^9.10.0",
60
62
  "eslint-config-prettier": "^9.1.0",
61
63
  "eslint-plugin-simple-import-sort": "^12.1.1",
62
64
  "eslint-plugin-unicorn": "^55.0.0",
63
65
  "nodemon": "^3.1.4",
64
66
  "prettier": "^3.3.3",
65
67
  "ts-node": "^10.9.2",
66
- "tsx": "^4.17.0",
68
+ "tsx": "^4.19.0",
67
69
  "typescript": "^5.5.4"
68
70
  },
69
71
  "dependencies": {