svelteesp32 3.0.0 → 3.0.2
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 +25 -11
- package/dist/commandLine.d.ts +5 -3
- package/dist/commandLine.js +17 -14
- package/dist/consoleColor.d.ts +0 -1
- package/dist/cppCode.d.ts +2 -2
- package/dist/cppCode.js +16 -16
- package/dist/cppCodeEspIdf.d.ts +0 -1
- package/dist/errorMessages.d.ts +0 -1
- package/dist/file.d.ts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +13 -1
- package/dist/initCommand.d.ts +0 -1
- package/dist/pipeline.d.ts +0 -1
- package/dist/pipeline.js +3 -1
- package/dist/vitePlugin.d.ts +7 -8
- package/dist/vitePlugin.js +72 -36
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -88,7 +88,7 @@ void setup() {
|
|
|
88
88
|
|
|
89
89
|
## What's New
|
|
90
90
|
|
|
91
|
-
- **v3.0.0** — **Vite plugin** (`import { svelteESP32 } from 'svelteesp32/vite'`) generates the header automatically after every build; `npx svelteesp32 init` interactive RC file wizard; Node.js >= 22 required
|
|
91
|
+
- **v3.0.0** — **Vite plugin** (`import { svelteESP32 } from 'svelteesp32/vite'`) generates the header automatically after every build — call with no argument for RC file mode or pass an options object for plugin-options mode; `npx svelteesp32 init` interactive RC file wizard; Node.js >= 22 required
|
|
92
92
|
- **v2.4.0** — `--analyze` for CI size budget checks (per-file table, exits 1 on over-budget); `--manifest` to write a companion JSON manifest alongside the header
|
|
93
93
|
- **v2.3.0** — `--cachetime-html` and `--cachetime-assets` for per-type cache control (e.g. `no-cache` for HTML, 1-year for content-hashed JS/CSS)
|
|
94
94
|
- **v2.2.0** — SPA routing catch-all (`--spa`) for client-side routers on all four engines
|
|
@@ -132,13 +132,27 @@ It asks for engine, source path, output path, and ETag preference, writes the RC
|
|
|
132
132
|
|
|
133
133
|
For Vite-based projects (SvelteKit, React, Vue, Vanilla) you can skip the manual CLI step entirely — the plugin hooks into the build pipeline and regenerates the C++ header automatically after every `vite build`.
|
|
134
134
|
|
|
135
|
-
|
|
135
|
+
The plugin has two exclusive modes — pick one:
|
|
136
|
+
|
|
137
|
+
**RC file mode** — call with no argument (or a string path to a custom RC file). All settings come from `.svelteesp32rc.json`; `outputfile` in the RC file is required.
|
|
136
138
|
|
|
137
139
|
```ts
|
|
138
140
|
import { svelteKit } from '@sveltejs/kit/vite';
|
|
139
141
|
import { svelteESP32 } from 'svelteesp32/vite';
|
|
140
142
|
import { defineConfig } from 'vite';
|
|
141
143
|
|
|
144
|
+
export default defineConfig({
|
|
145
|
+
plugins: [
|
|
146
|
+
svelteKit(),
|
|
147
|
+
svelteESP32() // auto-discover .svelteesp32rc.json
|
|
148
|
+
// svelteESP32('/path/to/custom.rc.json') // or specify path explicitly
|
|
149
|
+
]
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Plugin options mode** — call with an options object. The RC file is completely ignored; `output` is required.
|
|
154
|
+
|
|
155
|
+
```ts
|
|
142
156
|
export default defineConfig({
|
|
143
157
|
plugins: [
|
|
144
158
|
svelteKit(),
|
|
@@ -147,27 +161,27 @@ export default defineConfig({
|
|
|
147
161
|
engine: 'psychic',
|
|
148
162
|
etag: 'always',
|
|
149
163
|
gzip: 'always',
|
|
150
|
-
|
|
151
|
-
|
|
164
|
+
cachetimehtml: 0,
|
|
165
|
+
cachetimeassets: 31536000
|
|
152
166
|
})
|
|
153
167
|
]
|
|
154
168
|
});
|
|
155
169
|
```
|
|
156
170
|
|
|
157
|
-
|
|
171
|
+
`sourcepath` defaults to Vite's `build.outDir` in both modes.
|
|
158
172
|
|
|
159
173
|
**Plugin options**
|
|
160
174
|
|
|
161
175
|
| Option | Type | Default | Description |
|
|
162
176
|
| ----------------- | ------------------------------------------- | ------------------------- | -------------------------------------------------- |
|
|
163
|
-
| `output` | `string` |
|
|
177
|
+
| `output` | `string` | RC `outputfile` | Output `.h` file path |
|
|
164
178
|
| `sourcepath` | `string` | Vite's `build.outDir` | Source directory (compiled web files) |
|
|
165
179
|
| `engine` | `'psychic'\|'async'\|'espidf'\|'webserver'` | `'psychic'` | Target web server engine |
|
|
166
180
|
| `etag` | `'always'\|'never'\|'compiler'` | `'never'` | ETag generation mode |
|
|
167
181
|
| `gzip` | `'always'\|'never'\|'compiler'` | `'always'` | Gzip compression mode |
|
|
168
182
|
| `cachetime` | `number` | `0` | `Cache-Control: max-age` in seconds (all files) |
|
|
169
|
-
| `
|
|
170
|
-
| `
|
|
183
|
+
| `cachetimehtml` | `number` | (unset) | max-age for HTML files (overrides `cachetime`) |
|
|
184
|
+
| `cachetimeassets` | `number` | (unset) | max-age for non-HTML files (overrides `cachetime`) |
|
|
171
185
|
| `exclude` | `string[]` | `[]` | Glob patterns to exclude |
|
|
172
186
|
| `basepath` | `string` | (none) | URL prefix for all routes |
|
|
173
187
|
| `espmethod` | `string` | `'initSvelteStaticFiles'` | Generated init function name |
|
|
@@ -176,9 +190,9 @@ The `output` path is required; all other options mirror the CLI flags and have t
|
|
|
176
190
|
| `created` | `boolean` | `false` | Include creation timestamp |
|
|
177
191
|
| `spa` | `boolean` | `false` | Serve `index.html` for unmatched routes |
|
|
178
192
|
| `manifest` | `boolean` | `false` | Write companion `.manifest.json` |
|
|
179
|
-
| `
|
|
180
|
-
| `
|
|
181
|
-
| `
|
|
193
|
+
| `noindexcheck` | `boolean` | `false` | Skip `index.html` validation |
|
|
194
|
+
| `maxsize` | `number` | (none) | Max total uncompressed size in bytes |
|
|
195
|
+
| `maxgzipsize` | `number` | (none) | Max total gzip size in bytes |
|
|
182
196
|
|
|
183
197
|
### Generate Header File (CLI)
|
|
184
198
|
|
package/dist/commandLine.d.ts
CHANGED
|
@@ -21,8 +21,9 @@ export interface ICopyFilesArguments {
|
|
|
21
21
|
spa?: boolean;
|
|
22
22
|
manifest?: boolean;
|
|
23
23
|
help?: boolean;
|
|
24
|
+
configSource: 'cli' | 'rcfile' | 'vite';
|
|
24
25
|
}
|
|
25
|
-
interface IRcFileConfig {
|
|
26
|
+
export interface IRcFileConfig {
|
|
26
27
|
engine?: 'psychic' | 'async' | 'espidf' | 'webserver';
|
|
27
28
|
sourcepath?: string;
|
|
28
29
|
outputfile?: string;
|
|
@@ -46,11 +47,12 @@ interface IRcFileConfig {
|
|
|
46
47
|
manifest?: boolean | 'true' | 'false';
|
|
47
48
|
}
|
|
48
49
|
declare function validateCppIdentifier(value: string, name: string): string;
|
|
50
|
+
export declare function validateBasePath(value: string): string;
|
|
49
51
|
declare function parseSize(value: string, name: string): number;
|
|
50
52
|
declare function getNpmPackageVariable(packageJson: Record<string, unknown>, variableName: string): string | undefined;
|
|
51
53
|
declare function hasNpmVariables(config: IRcFileConfig): boolean;
|
|
52
54
|
declare function interpolateNpmVariables(config: IRcFileConfig, rcFilePath: string): IRcFileConfig;
|
|
55
|
+
export declare function loadRcFileConfig(configPath?: string): Partial<IRcFileConfig>;
|
|
56
|
+
export declare function parseArguments(): ICopyFilesArguments;
|
|
53
57
|
export { getNpmPackageVariable, hasNpmVariables, interpolateNpmVariables, parseSize, validateCppIdentifier };
|
|
54
58
|
export declare function formatConfiguration(cmdLine: ICopyFilesArguments): string;
|
|
55
|
-
export declare const cmdLine: ICopyFilesArguments;
|
|
56
|
-
//# sourceMappingURL=commandLine.d.ts.map
|
package/dist/commandLine.js
CHANGED
|
@@ -3,7 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.validateBasePath = validateBasePath;
|
|
7
|
+
exports.loadRcFileConfig = loadRcFileConfig;
|
|
8
|
+
exports.parseArguments = parseArguments;
|
|
7
9
|
exports.getNpmPackageVariable = getNpmPackageVariable;
|
|
8
10
|
exports.hasNpmVariables = hasNpmVariables;
|
|
9
11
|
exports.interpolateNpmVariables = interpolateNpmVariables;
|
|
@@ -255,6 +257,12 @@ function loadRcFile(rcPath) {
|
|
|
255
257
|
throw error;
|
|
256
258
|
}
|
|
257
259
|
}
|
|
260
|
+
function loadRcFileConfig(configPath) {
|
|
261
|
+
const rcPath = findRcFile(configPath);
|
|
262
|
+
if (!rcPath)
|
|
263
|
+
return {};
|
|
264
|
+
return loadRcFile(rcPath);
|
|
265
|
+
}
|
|
258
266
|
function validateSizeOption(configObject, key) {
|
|
259
267
|
const value = configObject[key];
|
|
260
268
|
if (value === undefined)
|
|
@@ -404,7 +412,8 @@ function parseArguments() {
|
|
|
404
412
|
define: 'SVELTEESP32',
|
|
405
413
|
cachetime: 0,
|
|
406
414
|
exclude: [],
|
|
407
|
-
basePath: ''
|
|
415
|
+
basePath: '',
|
|
416
|
+
configSource: 'cli'
|
|
408
417
|
};
|
|
409
418
|
if (rcConfig.engine)
|
|
410
419
|
result.engine = rcConfig.engine;
|
|
@@ -525,8 +534,10 @@ function parseArguments() {
|
|
|
525
534
|
const argument = arguments_[index];
|
|
526
535
|
if (!argument)
|
|
527
536
|
continue;
|
|
528
|
-
if (argument === '--help' || argument === '-h')
|
|
537
|
+
if (argument === '--help' || argument === '-h') {
|
|
529
538
|
showHelp();
|
|
539
|
+
return result;
|
|
540
|
+
}
|
|
530
541
|
if (argument.startsWith('--') && argument.includes('=')) {
|
|
531
542
|
const parts = argument.split('=');
|
|
532
543
|
const flag = parts[0];
|
|
@@ -605,10 +616,12 @@ function parseArguments() {
|
|
|
605
616
|
return result;
|
|
606
617
|
}
|
|
607
618
|
function formatConfiguration(cmdLine) {
|
|
619
|
+
const relativeOutput = node_path_1.default.relative(process.cwd(), cmdLine.outputfile);
|
|
608
620
|
const parts = [
|
|
621
|
+
`source=${cmdLine.configSource}`,
|
|
609
622
|
`engine=${cmdLine.engine}`,
|
|
610
623
|
`sourcepath=${cmdLine.sourcepath}`,
|
|
611
|
-
`outputfile=${
|
|
624
|
+
`outputfile=${relativeOutput}`,
|
|
612
625
|
`etag=${cmdLine.etag}`,
|
|
613
626
|
`gzip=${cmdLine.gzip}`,
|
|
614
627
|
`cachetime=${cmdLine.cachetime}`
|
|
@@ -639,13 +652,3 @@ function formatConfiguration(cmdLine) {
|
|
|
639
652
|
parts.push(`exclude=[${cmdLine.exclude.join(', ')}]`);
|
|
640
653
|
return parts.join(' ').replace(/[\n\r]/g, ' ');
|
|
641
654
|
}
|
|
642
|
-
exports.cmdLine = parseArguments();
|
|
643
|
-
if (!(0, node_fs_1.existsSync)(exports.cmdLine.sourcepath)) {
|
|
644
|
-
console.error((0, errorMessages_1.getSourcepathNotFoundError)(exports.cmdLine.sourcepath, 'not_found'));
|
|
645
|
-
process.exit(1);
|
|
646
|
-
}
|
|
647
|
-
if (!(0, node_fs_1.statSync)(exports.cmdLine.sourcepath).isDirectory()) {
|
|
648
|
-
console.error((0, errorMessages_1.getSourcepathNotFoundError)(exports.cmdLine.sourcepath, 'not_directory'));
|
|
649
|
-
process.exit(1);
|
|
650
|
-
}
|
|
651
|
-
console.log(`[SvelteESP32] Generate code for ${exports.cmdLine.engine} engine`);
|
package/dist/consoleColor.d.ts
CHANGED
package/dist/cppCode.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ICopyFilesArguments } from './commandLine';
|
|
1
2
|
export type CppCodeSource = {
|
|
2
3
|
filename: string;
|
|
3
4
|
dataname: string;
|
|
@@ -14,5 +15,4 @@ export type ExtensionGroup = {
|
|
|
14
15
|
count: number;
|
|
15
16
|
};
|
|
16
17
|
export type ExtensionGroups = ExtensionGroup[];
|
|
17
|
-
export declare const getCppCode: (sources: CppCodeSources, filesByExtension: ExtensionGroups) => string;
|
|
18
|
-
//# sourceMappingURL=cppCode.d.ts.map
|
|
18
|
+
export declare const getCppCode: (sources: CppCodeSources, filesByExtension: ExtensionGroups, options: ICopyFilesArguments) => string;
|
package/dist/cppCode.js
CHANGED
|
@@ -1010,17 +1010,17 @@ const createHandlebarsHelpers = () => {
|
|
|
1010
1010
|
}
|
|
1011
1011
|
};
|
|
1012
1012
|
};
|
|
1013
|
-
const getCppCode = (sources, filesByExtension) => {
|
|
1014
|
-
const template = (0, handlebars_1.compile)(getTemplate(
|
|
1013
|
+
const getCppCode = (sources, filesByExtension, options) => {
|
|
1014
|
+
const template = (0, handlebars_1.compile)(getTemplate(options.engine));
|
|
1015
1015
|
const transformedSources = sources.map((s) => {
|
|
1016
1016
|
const effectiveCacheTime = s.mime === 'text/html'
|
|
1017
|
-
? (
|
|
1018
|
-
: (
|
|
1019
|
-
return transformSourceToTemplateData(s,
|
|
1017
|
+
? (options.cachetimeHtml ?? options.cachetime)
|
|
1018
|
+
: (options.cachetimeAssets ?? options.cachetime);
|
|
1019
|
+
return transformSourceToTemplateData(s, options.etag, effectiveCacheTime);
|
|
1020
1020
|
});
|
|
1021
|
-
const spaSource =
|
|
1021
|
+
const spaSource = options.spa ? transformedSources.find((s) => s.isDefault) : undefined;
|
|
1022
1022
|
const templateData = {
|
|
1023
|
-
config: (0, commandLine_1.formatConfiguration)(
|
|
1023
|
+
config: (0, commandLine_1.formatConfiguration)(options),
|
|
1024
1024
|
now: (() => {
|
|
1025
1025
|
const d = new Date();
|
|
1026
1026
|
return `${d.toLocaleDateString()} ${d.toLocaleTimeString()}`;
|
|
@@ -1030,16 +1030,16 @@ const getCppCode = (sources, filesByExtension) => {
|
|
|
1030
1030
|
fileGzipSize: sources.reduce((previous, current) => previous + current.contentGzip.length, 0).toString(),
|
|
1031
1031
|
sources: transformedSources,
|
|
1032
1032
|
filesByExtension,
|
|
1033
|
-
etag:
|
|
1034
|
-
gzip:
|
|
1035
|
-
created:
|
|
1036
|
-
version:
|
|
1037
|
-
methodName:
|
|
1038
|
-
definePrefix:
|
|
1039
|
-
basePath:
|
|
1040
|
-
spa: !!
|
|
1033
|
+
etag: options.etag,
|
|
1034
|
+
gzip: options.gzip,
|
|
1035
|
+
created: options.created,
|
|
1036
|
+
version: options.version,
|
|
1037
|
+
methodName: options.espmethod,
|
|
1038
|
+
definePrefix: options.define,
|
|
1039
|
+
basePath: options.basePath,
|
|
1040
|
+
spa: !!options.spa,
|
|
1041
1041
|
spaSource,
|
|
1042
|
-
isPsychic:
|
|
1042
|
+
isPsychic: options.engine === 'psychic',
|
|
1043
1043
|
maxUriHandlers: (sources.length + 5).toString()
|
|
1044
1044
|
};
|
|
1045
1045
|
const rawCode = template(templateData, { helpers: createHandlebarsHelpers() });
|
package/dist/cppCodeEspIdf.d.ts
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
1
|
export declare const espidfTemplate = "\n//engine: espidf\n//config: {{{config}}}\n{{#if created }}\n//created: {{now}}\n{{/if}}\n//\n\n{{#switch etag}}\n{{#case \"always\"}}\n#ifdef {{definePrefix}}_ENABLE_ETAG\n#warning {{definePrefix}}_ENABLE_ETAG has no effect because it is permanently switched ON\n#endif\n{{/case}}\n{{#case \"never\"}}\n#ifdef {{definePrefix}}_ENABLE_ETAG\n#warning {{definePrefix}}_ENABLE_ETAG has no effect because it is permanently switched OFF\n#endif\n{{/case}}\n{{/switch}}\n\n{{#switch gzip}}\n{{#case \"always\"}}\n#ifdef {{definePrefix}}_ENABLE_GZIP\n#warning {{definePrefix}}_ENABLE_GZIP has no effect because it is permanently switched ON\n#endif\n{{/case}}\n{{#case \"never\"}}\n#ifdef {{definePrefix}}_ENABLE_GZIP\n#warning {{definePrefix}}_ENABLE_GZIP has no effect because it is permanently switched OFF\n#endif\n{{/case}}\n{{/switch}}\n\n//\n{{#if version }}\n#define {{definePrefix}}_VERSION \"{{version}}\"\n{{/if}}\n#define {{definePrefix}}_COUNT {{fileCount}}\n#define {{definePrefix}}_SIZE {{fileSize}}\n#define {{definePrefix}}_SIZE_GZIP {{fileGzipSize}}\n\n//\n{{#each sources}}\n#define {{../definePrefix}}_FILE_{{this.datanameUpperCase}}\n{{/each}}\n\n//\n{{#each filesByExtension}}\n#define {{../definePrefix}}_{{this.extension}}_FILES {{this.count}}\n{{/each}}\n\n#include <stdint.h>\n#include <string.h>\n#include <stdlib.h>\n#include <esp_err.h>\n#include <esp_http_server.h>\n\n//\n{{#switch gzip}}\n{{#case \"always\"}}\n {{#each sources}}\nstatic const unsigned char datagzip_{{this.dataname}}[{{this.lengthGzip}}] = { {{this.bytesGzip}} };\n {{/each}}\n{{/case}}\n{{#case \"never\"}}\n {{#each sources}}\nstatic const unsigned char data_{{this.dataname}}[{{this.length}}] = { {{this.bytes}} };\n {{/each}}\n{{/case}}\n{{#case \"compiler\"}}\n#ifdef {{definePrefix}}_ENABLE_GZIP\n {{#each sources}}\nstatic const unsigned char datagzip_{{this.dataname}}[{{this.lengthGzip}}] = { {{this.bytesGzip}} };\n {{/each}}\n#else\n {{#each sources}}\nstatic const unsigned char data_{{this.dataname}}[{{this.length}}] = { {{this.bytes}} };\n {{/each}}\n#endif \n{{/case}}\n{{/switch}}\n\n//\n{{#switch etag}}\n{{#case \"always\"}}\n {{#each sources}}\nstatic const char etag_{{this.dataname}}[] = \"{{this.sha256}}\";\n {{/each}}\n{{/case}}\n{{#case \"never\"}}\n{{/case}}\n{{#case \"compiler\"}}\n#ifdef {{definePrefix}}_ENABLE_ETAG\n {{#each sources}}\nstatic const char etag_{{this.dataname}}[] = \"{{this.sha256}}\";\n {{/each}}\n#endif\n{{/case}}\n{{/switch}}\n\n// File manifest struct (C-compatible typedef)\ntypedef struct {\n const char* path;\n uint32_t size;\n uint32_t gzipSize;\n const char* etag;\n const char* contentType;\n} {{definePrefix}}_FileInfo;\n\n// File manifest array\nstatic const {{definePrefix}}_FileInfo {{definePrefix}}_FILES[] = {\n{{#each sources}}\n { \"{{../basePath}}/{{this.filename}}\", {{this.length}}, {{this.gzipSizeForManifest}}, {{this.etagForManifest}}, \"{{this.mime}}\" },\n{{/each}}\n};\nstatic const size_t {{definePrefix}}_FILE_COUNT = sizeof({{definePrefix}}_FILES) / sizeof({{definePrefix}}_FILES[0]);\n\n// File served hook - override with your own implementation\n__attribute__((weak)) void {{definePrefix}}_onFileServed(const char* path, int statusCode) {}\n\n{{#each sources}}\n\nstatic esp_err_t file_handler_{{this.datanameUpperCase}} (httpd_req_t *req)\n{\n{{#switch ../etag}}\n{{#case \"always\"}}\n size_t hdr_len = httpd_req_get_hdr_value_len(req, \"If-None-Match\");\n if (hdr_len > 0) {\n char* hdr_value = malloc(hdr_len + 1);\n if (hdr_value == NULL) { httpd_resp_send_500(req); return ESP_FAIL; }\n if (httpd_req_get_hdr_value_str(req, \"If-None-Match\", hdr_value, hdr_len + 1) == ESP_OK) {\n if (strcmp(hdr_value, etag_{{this.dataname}}) == 0) {\n free(hdr_value);\n httpd_resp_set_status(req, \"304 Not Modified\");\n {{../definePrefix}}_onFileServed(\"{{../basePath}}/{{this.filename}}\", 304);\n httpd_resp_send(req, NULL, 0);\n return ESP_OK;\n }\n }\n free(hdr_value);\n }\n{{/case}}\n{{#case \"compiler\"}}\n #ifdef {{../definePrefix}}_ENABLE_ETAG\n size_t hdr_len = httpd_req_get_hdr_value_len(req, \"If-None-Match\");\n if (hdr_len > 0) {\n char* hdr_value = malloc(hdr_len + 1);\n if (hdr_value == NULL) { httpd_resp_send_500(req); return ESP_FAIL; }\n if (httpd_req_get_hdr_value_str(req, \"If-None-Match\", hdr_value, hdr_len + 1) == ESP_OK) {\n if (strcmp(hdr_value, etag_{{this.dataname}}) == 0) {\n free(hdr_value);\n httpd_resp_set_status(req, \"304 Not Modified\");\n {{../definePrefix}}_onFileServed(\"{{../basePath}}/{{this.filename}}\", 304);\n httpd_resp_send(req, NULL, 0);\n return ESP_OK;\n }\n }\n free(hdr_value);\n }\n #endif\n{{/case}}\n{{/switch}}\n httpd_resp_set_type(req, \"{{this.mime}}\");\n{{#switch ../gzip}}\n{{#case \"always\"}}\n{{#if this.isGzip}}\n httpd_resp_set_hdr(req, \"Content-Encoding\", \"gzip\");\n{{/if}}\n{{/case}}\n{{#case \"compiler\"}}\n {{#if this.isGzip}}\n #ifdef {{../definePrefix}}_ENABLE_GZIP\n httpd_resp_set_hdr(req, \"Content-Encoding\", \"gzip\");\n #endif \n {{/if}}\n{{/case}}\n{{/switch}}\n\n{{#switch ../etag}}\n{{#case \"always\"}}\n{{#this.cacheTime}}\n httpd_resp_set_hdr(req, \"Cache-Control\", \"max-age={{value}}\");\n{{/this.cacheTime}}\n{{^this.cacheTime}}\n httpd_resp_set_hdr(req, \"Cache-Control\", \"no-cache\");\n{{/this.cacheTime}}\n httpd_resp_set_hdr(req, \"ETag\", etag_{{this.dataname}});\n{{/case}}\n{{#case \"compiler\"}}\n #ifdef {{../definePrefix}}_ENABLE_ETAG\n{{#this.cacheTime}}\n httpd_resp_set_hdr(req, \"Cache-Control\", \"max-age={{value}}\");\n{{/this.cacheTime}}\n{{^this.cacheTime}}\n httpd_resp_set_hdr(req, \"Cache-Control\", \"no-cache\");\n{{/this.cacheTime}}\n httpd_resp_set_hdr(req, \"ETag\", etag_{{this.dataname}});\n #endif \n{{/case}}\n{{/switch}}\n\n{{#switch ../gzip}}\n{{#case \"always\"}}\n {{../definePrefix}}_onFileServed(\"{{../basePath}}/{{this.filename}}\", 200);\n httpd_resp_send(req, (const char *)datagzip_{{this.dataname}}, {{this.lengthGzip}});\n{{/case}}\n{{#case \"never\"}}\n {{../definePrefix}}_onFileServed(\"{{../basePath}}/{{this.filename}}\", 200);\n httpd_resp_send(req, (const char *)data_{{this.dataname}}, {{this.length}});\n{{/case}}\n{{#case \"compiler\"}}\n {{../definePrefix}}_onFileServed(\"{{../basePath}}/{{this.filename}}\", 200);\n #ifdef {{../definePrefix}}_ENABLE_GZIP\n httpd_resp_send(req, (const char *)datagzip_{{this.dataname}}, {{this.lengthGzip}});\n #else\n httpd_resp_send(req, (const char *)data_{{this.dataname}}, {{this.length}});\n #endif\n{{/case}}\n{{/switch}}\n return ESP_OK;\n}\n\n{{#if this.isDefault}}\nstatic const httpd_uri_t route_def_{{this.datanameUpperCase}} = {\n .uri = \"{{#if ../basePath}}{{../basePath}}{{else}}/{{/if}}\",\n .method = HTTP_GET,\n .handler = file_handler_{{this.datanameUpperCase}},\n};\n{{/if}}\n\nstatic const httpd_uri_t route_{{this.datanameUpperCase}} = {\n .uri = \"{{../basePath}}/{{this.filename}}\",\n .method = HTTP_GET,\n .handler = file_handler_{{this.datanameUpperCase}},\n};\n\n{{/each}}\n\n{{#if spa}}\n{{#with spaSource}}\nstatic esp_err_t spa_handler_{{this.datanameUpperCase}}(httpd_req_t *req, httpd_err_code_t err) {\n{{#if ../basePath}}\n const char* prefix = \"{{../basePath}}/\";\n if (strncmp(req->uri, prefix, strlen(prefix)) != 0 && strcmp(req->uri, \"{{../basePath}}\") != 0) {\n httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, \"Not found\");\n return ESP_FAIL;\n }\n{{/if}}\n return file_handler_{{this.datanameUpperCase}}(req);\n}\n{{/with}}\n{{/if}}\n\n\nstatic inline void {{methodName}}(httpd_handle_t server) {\n{{#each sources}}\n{{#if this.isDefault}}\n httpd_register_uri_handler(server, &route_def_{{this.datanameUpperCase}});\n{{/if}}\n httpd_register_uri_handler(server, &route_{{this.datanameUpperCase}});\n{{/each}}\n{{#if spa}}\n{{#with spaSource}}\n httpd_register_err_handler(server, HTTPD_404_NOT_FOUND, spa_handler_{{this.datanameUpperCase}});\n{{/with}}\n{{/if}}\n\n}";
|
|
2
|
-
//# sourceMappingURL=cppCodeEspIdf.d.ts.map
|
package/dist/errorMessages.d.ts
CHANGED
|
@@ -3,4 +3,3 @@ export declare function getInvalidEngineError(attempted: string): string;
|
|
|
3
3
|
export declare function getSourcepathNotFoundError(sourcepath: string, reason: 'not_found' | 'not_directory'): string;
|
|
4
4
|
export declare function getSizeBudgetExceededError(type: 'size' | 'gzipSize', limit: number, actual: number): string;
|
|
5
5
|
export declare function getMaxUriHandlersHint(engine: string, routeCount: number, espmethod?: string): string;
|
|
6
|
-
//# sourceMappingURL=errorMessages.d.ts.map
|
package/dist/file.d.ts
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
1
|
export declare function main(): void;
|
|
2
2
|
export { calculateCompressionRatio, createSourceEntry, formatAnalyzeTable, formatChangeSummary, formatCompressionLog, formatDryRunRoutes, formatSize, formatSizePrecise, type PreviousManifestFile, shouldUseGzip, updateExtensionGroup } from './pipeline';
|
|
3
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -2,11 +2,23 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.updateExtensionGroup = exports.shouldUseGzip = exports.formatSizePrecise = exports.formatSize = exports.formatDryRunRoutes = exports.formatCompressionLog = exports.formatChangeSummary = exports.formatAnalyzeTable = exports.createSourceEntry = exports.calculateCompressionRatio = void 0;
|
|
4
4
|
exports.main = main;
|
|
5
|
+
const node_fs_1 = require("node:fs");
|
|
5
6
|
const commandLine_1 = require("./commandLine");
|
|
7
|
+
const errorMessages_1 = require("./errorMessages");
|
|
6
8
|
const pipeline_1 = require("./pipeline");
|
|
7
9
|
function main() {
|
|
10
|
+
const cmdLine = (0, commandLine_1.parseArguments)();
|
|
11
|
+
if (!(0, node_fs_1.existsSync)(cmdLine.sourcepath)) {
|
|
12
|
+
console.error((0, errorMessages_1.getSourcepathNotFoundError)(cmdLine.sourcepath, 'not_found'));
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
if (!(0, node_fs_1.statSync)(cmdLine.sourcepath).isDirectory()) {
|
|
16
|
+
console.error((0, errorMessages_1.getSourcepathNotFoundError)(cmdLine.sourcepath, 'not_directory'));
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
console.log(`[SvelteESP32] Generate code for ${cmdLine.engine} engine`);
|
|
8
20
|
try {
|
|
9
|
-
(0, pipeline_1.runPipeline)(
|
|
21
|
+
(0, pipeline_1.runPipeline)(cmdLine);
|
|
10
22
|
}
|
|
11
23
|
catch (error) {
|
|
12
24
|
if (!(error instanceof pipeline_1.OverBudgetError)) {
|
package/dist/initCommand.d.ts
CHANGED
package/dist/pipeline.d.ts
CHANGED
|
@@ -26,4 +26,3 @@ export declare class OverBudgetError extends Error {
|
|
|
26
26
|
declare const formatChangeSummary: (sources: CppCodeSources, previousFiles: PreviousManifestFile[]) => string;
|
|
27
27
|
export declare function runPipeline(options: ICopyFilesArguments): void;
|
|
28
28
|
export { calculateCompressionRatio, createSourceEntry, formatAnalyzeTable, formatChangeSummary, formatCompressionLog, formatDryRunRoutes, formatSize, formatSizePrecise, shouldUseGzip, updateExtensionGroup };
|
|
29
|
-
//# sourceMappingURL=pipeline.d.ts.map
|
package/dist/pipeline.js
CHANGED
|
@@ -181,6 +181,8 @@ function runPipeline(options) {
|
|
|
181
181
|
};
|
|
182
182
|
const sources = [];
|
|
183
183
|
const filesByExtension = [];
|
|
184
|
+
const sourceLabels = { cli: 'command line', rcfile: 'RC file', vite: 'vite plugin' };
|
|
185
|
+
console.log(`Config source: ${sourceLabels[options.configSource]}`);
|
|
184
186
|
console.log('Collecting source files');
|
|
185
187
|
const files = (0, file_1.getFiles)(options);
|
|
186
188
|
if (files.size === 0)
|
|
@@ -237,7 +239,7 @@ function runPipeline(options) {
|
|
|
237
239
|
console.log(formatDryRunRoutes(sources, options.engine, options.basePath, options.spa ?? false));
|
|
238
240
|
return;
|
|
239
241
|
}
|
|
240
|
-
const cppFile = (0, cppCode_1.getCppCode)(sources, filesByExtension);
|
|
242
|
+
const cppFile = (0, cppCode_1.getCppCode)(sources, filesByExtension, options);
|
|
241
243
|
(0, node_fs_1.mkdirSync)(node_path_1.default.normalize(node_path_1.default.dirname(options.outputfile)), { recursive: true });
|
|
242
244
|
(0, node_fs_1.writeFileSync)(options.outputfile, cppFile, { flush: true, encoding: 'utf8' });
|
|
243
245
|
console.log(`${summary.filecount} files, ${formatSize(summary.size)} original size, ${formatSize(summary.gzipsize)} gzip size`);
|
package/dist/vitePlugin.d.ts
CHANGED
|
@@ -9,14 +9,14 @@ interface VitePlugin {
|
|
|
9
9
|
closeBundle: () => void;
|
|
10
10
|
}
|
|
11
11
|
export interface SvelteESP32PluginOptions {
|
|
12
|
-
output
|
|
12
|
+
output?: string;
|
|
13
13
|
sourcepath?: string;
|
|
14
14
|
engine?: 'psychic' | 'async' | 'espidf' | 'webserver';
|
|
15
15
|
etag?: 'always' | 'never' | 'compiler';
|
|
16
16
|
gzip?: 'always' | 'never' | 'compiler';
|
|
17
17
|
cachetime?: number;
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
cachetimehtml?: number;
|
|
19
|
+
cachetimeassets?: number;
|
|
20
20
|
exclude?: string[];
|
|
21
21
|
basepath?: string;
|
|
22
22
|
espmethod?: string;
|
|
@@ -25,10 +25,9 @@ export interface SvelteESP32PluginOptions {
|
|
|
25
25
|
created?: boolean;
|
|
26
26
|
spa?: boolean;
|
|
27
27
|
manifest?: boolean;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
noindexcheck?: boolean;
|
|
29
|
+
maxsize?: number;
|
|
30
|
+
maxgzipsize?: number;
|
|
31
31
|
}
|
|
32
|
-
export declare function svelteESP32(
|
|
32
|
+
export declare function svelteESP32(optionsOrRcPath?: SvelteESP32PluginOptions | string): VitePlugin;
|
|
33
33
|
export {};
|
|
34
|
-
//# sourceMappingURL=vitePlugin.d.ts.map
|
package/dist/vitePlugin.js
CHANGED
|
@@ -5,8 +5,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.svelteESP32 = svelteESP32;
|
|
7
7
|
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
+
const commandLine_1 = require("./commandLine");
|
|
8
9
|
const pipeline_1 = require("./pipeline");
|
|
9
|
-
function
|
|
10
|
+
function coerceBool(value) {
|
|
11
|
+
if (value === undefined)
|
|
12
|
+
return undefined;
|
|
13
|
+
return value === true || value === 'true';
|
|
14
|
+
}
|
|
15
|
+
function svelteESP32(optionsOrRcPath) {
|
|
10
16
|
let outDirectory = 'dist';
|
|
11
17
|
return {
|
|
12
18
|
name: 'svelteesp32',
|
|
@@ -14,42 +20,72 @@ function svelteESP32(options) {
|
|
|
14
20
|
outDirectory = config.build.outDir;
|
|
15
21
|
},
|
|
16
22
|
closeBundle() {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
let options_;
|
|
24
|
+
if (optionsOrRcPath === undefined || typeof optionsOrRcPath === 'string') {
|
|
25
|
+
const rcPath = optionsOrRcPath;
|
|
26
|
+
const rcConfig = (0, commandLine_1.loadRcFileConfig)(rcPath);
|
|
27
|
+
const rawOutput = rcConfig.outputfile;
|
|
28
|
+
if (!rawOutput)
|
|
29
|
+
throw new Error('output is required — specify outputfile in the RC file (.svelteesp32rc.json)');
|
|
30
|
+
const outputfile = node_path_1.default.resolve(rawOutput);
|
|
31
|
+
const sourcepath = rcConfig.sourcepath ?? outDirectory;
|
|
32
|
+
const rawBasepath = rcConfig.basepath ?? '';
|
|
33
|
+
const basePath = (0, commandLine_1.validateBasePath)(rawBasepath);
|
|
34
|
+
options_ = {
|
|
35
|
+
configSource: 'rcfile',
|
|
36
|
+
engine: rcConfig.engine ?? 'psychic',
|
|
37
|
+
sourcepath,
|
|
38
|
+
outputfile,
|
|
39
|
+
etag: rcConfig.etag ?? 'never',
|
|
40
|
+
gzip: rcConfig.gzip ?? 'always',
|
|
41
|
+
cachetime: rcConfig.cachetime ?? 0,
|
|
42
|
+
cachetimeHtml: rcConfig.cachetimehtml,
|
|
43
|
+
cachetimeAssets: rcConfig.cachetimeassets,
|
|
44
|
+
created: coerceBool(rcConfig.created) ?? false,
|
|
45
|
+
version: rcConfig.version ?? '',
|
|
46
|
+
espmethod: rcConfig.espmethod ?? 'initSvelteStaticFiles',
|
|
47
|
+
define: rcConfig.define ?? 'SVELTEESP32',
|
|
48
|
+
exclude: rcConfig.exclude ?? [],
|
|
49
|
+
basePath,
|
|
50
|
+
noIndexCheck: coerceBool(rcConfig.noindexcheck),
|
|
51
|
+
spa: coerceBool(rcConfig.spa),
|
|
52
|
+
manifest: coerceBool(rcConfig.manifest),
|
|
53
|
+
maxSize: rcConfig.maxsize,
|
|
54
|
+
maxGzipSize: rcConfig.maxgzipsize
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
const options = optionsOrRcPath;
|
|
59
|
+
const rawOutput = options.output;
|
|
60
|
+
if (!rawOutput)
|
|
61
|
+
throw new Error('output is required — specify it as a plugin option or use svelteESP32() for RC file mode');
|
|
62
|
+
const outputfile = node_path_1.default.resolve(rawOutput);
|
|
63
|
+
const sourcepath = options.sourcepath ?? outDirectory;
|
|
64
|
+
const rawBasepath = options.basepath ?? '';
|
|
65
|
+
const basePath = (0, commandLine_1.validateBasePath)(rawBasepath);
|
|
66
|
+
options_ = {
|
|
67
|
+
configSource: 'vite',
|
|
68
|
+
engine: options.engine ?? 'psychic',
|
|
69
|
+
sourcepath,
|
|
70
|
+
outputfile,
|
|
71
|
+
etag: options.etag ?? 'never',
|
|
72
|
+
gzip: options.gzip ?? 'always',
|
|
73
|
+
cachetime: options.cachetime ?? 0,
|
|
74
|
+
cachetimeHtml: options.cachetimehtml,
|
|
75
|
+
cachetimeAssets: options.cachetimeassets,
|
|
76
|
+
created: options.created ?? false,
|
|
77
|
+
version: options.version ?? '',
|
|
78
|
+
espmethod: options.espmethod ?? 'initSvelteStaticFiles',
|
|
79
|
+
define: options.define ?? 'SVELTEESP32',
|
|
80
|
+
exclude: options.exclude ?? [],
|
|
81
|
+
basePath,
|
|
82
|
+
noIndexCheck: options.noindexcheck,
|
|
83
|
+
spa: options.spa,
|
|
84
|
+
manifest: options.manifest,
|
|
85
|
+
maxSize: options.maxsize,
|
|
86
|
+
maxGzipSize: options.maxgzipsize
|
|
87
|
+
};
|
|
31
88
|
}
|
|
32
|
-
const options_ = {
|
|
33
|
-
engine: options.engine ?? 'psychic',
|
|
34
|
-
sourcepath,
|
|
35
|
-
outputfile,
|
|
36
|
-
etag: options.etag ?? 'never',
|
|
37
|
-
gzip: options.gzip ?? 'always',
|
|
38
|
-
cachetime: options.cachetime ?? 0,
|
|
39
|
-
cachetimeHtml: options.cachetimeHtml,
|
|
40
|
-
cachetimeAssets: options.cachetimeAssets,
|
|
41
|
-
created: options.created ?? false,
|
|
42
|
-
version: options.version ?? '',
|
|
43
|
-
espmethod: options.espmethod ?? 'initSvelteStaticFiles',
|
|
44
|
-
define: options.define ?? 'SVELTEESP32',
|
|
45
|
-
exclude: options.exclude ?? [],
|
|
46
|
-
basePath: options.basepath ?? '',
|
|
47
|
-
noIndexCheck: options.noIndexCheck,
|
|
48
|
-
spa: options.spa,
|
|
49
|
-
manifest: options.manifest,
|
|
50
|
-
maxSize: options.maxSize,
|
|
51
|
-
maxGzipSize: options.maxGzipSize
|
|
52
|
-
};
|
|
53
89
|
(0, pipeline_1.runPipeline)(options_);
|
|
54
90
|
}
|
|
55
91
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelteesp32",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.2",
|
|
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",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
},
|
|
12
12
|
"./vite": {
|
|
13
13
|
"types": "./dist/vitePlugin.d.ts",
|
|
14
|
+
"require": "./dist/vitePlugin.js",
|
|
14
15
|
"default": "./dist/vitePlugin.js"
|
|
15
16
|
}
|
|
16
17
|
},
|
|
@@ -73,8 +74,8 @@
|
|
|
73
74
|
"@types/mime-types": "^3.0.1",
|
|
74
75
|
"@types/node": "^25.6.0",
|
|
75
76
|
"@types/picomatch": "^4.0.3",
|
|
76
|
-
"@typescript-eslint/eslint-plugin": "^8.59.
|
|
77
|
-
"@typescript-eslint/parser": "^8.59.
|
|
77
|
+
"@typescript-eslint/eslint-plugin": "^8.59.2",
|
|
78
|
+
"@typescript-eslint/parser": "^8.59.2",
|
|
78
79
|
"@vitest/coverage-v8": "^4.1.5",
|
|
79
80
|
"eslint": "^10.3.0",
|
|
80
81
|
"eslint-config-prettier": "^10.1.8",
|