svelteesp32 3.0.1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -42
- package/dist/commandLine.d.ts +1 -0
- package/dist/commandLine.js +14 -11
- package/dist/cppCode.d.ts +49 -0
- package/dist/cppCode.js +107 -985
- package/dist/cppCodeAsync.d.ts +2 -0
- package/dist/cppCodeAsync.js +101 -0
- package/dist/cppCodeEspIdf.d.ts +2 -1
- package/dist/cppCodeEspIdf.js +172 -266
- package/dist/cppCodePsychic.d.ts +2 -0
- package/dist/cppCodePsychic.js +105 -0
- package/dist/cppCodeWebserver.d.ts +2 -0
- package/dist/cppCodeWebserver.js +118 -0
- package/dist/index.js +2 -0
- package/dist/pipeline.js +2 -0
- package/dist/vitePlugin.d.ts +1 -2
- package/dist/vitePlugin.js +67 -30
- package/package.json +7 -7
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.genAsyncCpp = void 0;
|
|
4
|
+
const cppCode_1 = require("./cppCode");
|
|
5
|
+
const genAsyncHandlerBody = (d, source, path) => {
|
|
6
|
+
const lines = [];
|
|
7
|
+
const etagCheck = (0, cppCode_1.sw)(d.etag, {
|
|
8
|
+
always: [
|
|
9
|
+
` const AsyncWebHeader* h = request->getHeader("If-None-Match");`,
|
|
10
|
+
` if (h && h->value().equals(etag_${source.dataname})) {`,
|
|
11
|
+
` ${d.definePrefix}_onFileServed("${path}", 304);`,
|
|
12
|
+
` request->send(304);`,
|
|
13
|
+
` return;`,
|
|
14
|
+
` }`
|
|
15
|
+
].join('\n'),
|
|
16
|
+
compiler: [
|
|
17
|
+
` #ifdef ${d.definePrefix}_ENABLE_ETAG`,
|
|
18
|
+
` const AsyncWebHeader* h = request->getHeader("If-None-Match");`,
|
|
19
|
+
` if (h && h->value().equals(etag_${source.dataname})) {`,
|
|
20
|
+
` ${d.definePrefix}_onFileServed("${path}", 304);`,
|
|
21
|
+
` request->send(304);`,
|
|
22
|
+
` return;`,
|
|
23
|
+
` }`,
|
|
24
|
+
` #endif`
|
|
25
|
+
].join('\n')
|
|
26
|
+
});
|
|
27
|
+
if (etagCheck)
|
|
28
|
+
lines.push(etagCheck);
|
|
29
|
+
lines.push((0, cppCode_1.sw)(d.gzip, {
|
|
30
|
+
always: [
|
|
31
|
+
` AsyncWebServerResponse *response = request->beginResponse(200, "${source.mime}", datagzip_${source.dataname}, ${source.lengthGzip});`,
|
|
32
|
+
...(source.isGzip ? [` response->addHeader("Content-Encoding", "gzip");`] : [])
|
|
33
|
+
].join('\n'),
|
|
34
|
+
never: ` AsyncWebServerResponse *response = request->beginResponse(200, "${source.mime}", data_${source.dataname}, ${source.length});`,
|
|
35
|
+
compiler: [
|
|
36
|
+
` #ifdef ${d.definePrefix}_ENABLE_GZIP`,
|
|
37
|
+
` AsyncWebServerResponse *response = request->beginResponse(200, "${source.mime}", datagzip_${source.dataname}, ${source.lengthGzip});`,
|
|
38
|
+
...(source.isGzip ? [` response->addHeader("Content-Encoding", "gzip");`] : []),
|
|
39
|
+
` #else`,
|
|
40
|
+
` AsyncWebServerResponse *response = request->beginResponse(200, "${source.mime}", data_${source.dataname}, ${source.length});`,
|
|
41
|
+
` #endif`
|
|
42
|
+
].join('\n')
|
|
43
|
+
}));
|
|
44
|
+
const cacheHeaders = (0, cppCode_1.sw)(d.etag, {
|
|
45
|
+
always: [
|
|
46
|
+
` response->addHeader("Cache-Control", "${(0, cppCode_1.cacheCtrl)(source)}");`,
|
|
47
|
+
` response->addHeader("ETag", etag_${source.dataname});`
|
|
48
|
+
].join('\n'),
|
|
49
|
+
compiler: [
|
|
50
|
+
` #ifdef ${d.definePrefix}_ENABLE_ETAG`,
|
|
51
|
+
` response->addHeader("Cache-Control", "${(0, cppCode_1.cacheCtrl)(source)}");`,
|
|
52
|
+
` response->addHeader("ETag", etag_${source.dataname});`,
|
|
53
|
+
` #endif`
|
|
54
|
+
].join('\n')
|
|
55
|
+
});
|
|
56
|
+
if (cacheHeaders)
|
|
57
|
+
lines.push(cacheHeaders);
|
|
58
|
+
lines.push(` ${d.definePrefix}_onFileServed("${path}", 200);`, ` request->send(response);`);
|
|
59
|
+
return lines.join('\n');
|
|
60
|
+
};
|
|
61
|
+
const genAsyncCpp = (d) => {
|
|
62
|
+
const lines = [
|
|
63
|
+
`//engine: ESPAsyncWebServer`,
|
|
64
|
+
`//config: ${d.config}`,
|
|
65
|
+
...(d.created ? [`//created: ${d.now}`] : []),
|
|
66
|
+
'//',
|
|
67
|
+
(0, cppCode_1.genCommonHeader)(d),
|
|
68
|
+
'//',
|
|
69
|
+
'#include <Arduino.h>',
|
|
70
|
+
'#include <ESPAsyncWebServer.h>',
|
|
71
|
+
'//',
|
|
72
|
+
(0, cppCode_1.genDataArrays)(d, true),
|
|
73
|
+
'//',
|
|
74
|
+
(0, cppCode_1.genEtagArrays)(d),
|
|
75
|
+
'//',
|
|
76
|
+
(0, cppCode_1.genManifest)(d),
|
|
77
|
+
'//',
|
|
78
|
+
(0, cppCode_1.genHook)(d),
|
|
79
|
+
'//',
|
|
80
|
+
'// Http Handlers',
|
|
81
|
+
`void ${d.methodName}(AsyncWebServer * server) {`
|
|
82
|
+
];
|
|
83
|
+
for (const source of d.sources) {
|
|
84
|
+
const path = `${d.basePath}/${source.filename}`;
|
|
85
|
+
const defaultPath = d.basePath || '/';
|
|
86
|
+
lines.push('//', `// ${source.filename}`, ` server->on("${path}", HTTP_GET, [](AsyncWebServerRequest * request) {`, genAsyncHandlerBody(d, source, path), ` });`);
|
|
87
|
+
if (source.isDefault)
|
|
88
|
+
lines.push(` server->on("${defaultPath}", HTTP_GET, [](AsyncWebServerRequest * request) {`, genAsyncHandlerBody(d, source, defaultPath), ` });`);
|
|
89
|
+
}
|
|
90
|
+
if (d.spa && d.spaSource) {
|
|
91
|
+
const source = d.spaSource;
|
|
92
|
+
const path = `${d.basePath}/${source.filename}`;
|
|
93
|
+
lines.push('//', `// SPA catch-all: unmatched routes serve ${source.filename}`, ` server->onNotFound([](AsyncWebServerRequest * request) {`, ` if (request->method() != HTTP_GET) { request->send(404); return; }`);
|
|
94
|
+
if (d.basePath)
|
|
95
|
+
lines.push(` if (!request->url().startsWith("${d.basePath}/") && request->url() != "${d.basePath}") { request->send(404); return; }`);
|
|
96
|
+
lines.push(genAsyncHandlerBody(d, source, path), ` });`);
|
|
97
|
+
}
|
|
98
|
+
lines.push('}');
|
|
99
|
+
return lines.join('\n');
|
|
100
|
+
};
|
|
101
|
+
exports.genAsyncCpp = genAsyncCpp;
|
package/dist/cppCodeEspIdf.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import type { TemplateData } from './cppCode';
|
|
2
|
+
export declare const genEspIdfCpp: (d: TemplateData) => string;
|
package/dist/cppCodeEspIdf.js
CHANGED
|
@@ -1,272 +1,178 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
{
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
{
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
{{
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
#ifdef {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
{
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
{{
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
#
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
{
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
#
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
{
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
{
|
|
68
|
-
{
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
{{
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
{{
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
{
|
|
94
|
-
|
|
95
|
-
{{
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
static const char etag_{{this.dataname}}[] = "{{this.sha256}}";
|
|
100
|
-
{{/each}}
|
|
101
|
-
#endif
|
|
102
|
-
{{/case}}
|
|
103
|
-
{{/switch}}
|
|
104
|
-
|
|
105
|
-
// File manifest struct (C-compatible typedef)
|
|
106
|
-
typedef struct {
|
|
107
|
-
const char* path;
|
|
108
|
-
uint32_t size;
|
|
109
|
-
uint32_t gzipSize;
|
|
110
|
-
const char* etag;
|
|
111
|
-
const char* contentType;
|
|
112
|
-
} {{definePrefix}}_FileInfo;
|
|
113
|
-
|
|
114
|
-
// File manifest array
|
|
115
|
-
static const {{definePrefix}}_FileInfo {{definePrefix}}_FILES[] = {
|
|
116
|
-
{{#each sources}}
|
|
117
|
-
{ "{{../basePath}}/{{this.filename}}", {{this.length}}, {{this.gzipSizeForManifest}}, {{this.etagForManifest}}, "{{this.mime}}" },
|
|
118
|
-
{{/each}}
|
|
3
|
+
exports.genEspIdfCpp = void 0;
|
|
4
|
+
const cppCode_1 = require("./cppCode");
|
|
5
|
+
const genEspIdfFileHandler = (d, source) => {
|
|
6
|
+
const path = `${d.basePath}/${source.filename}`;
|
|
7
|
+
const lines = [`static esp_err_t file_handler_${source.datanameUpperCase} (httpd_req_t *req)`, '{'];
|
|
8
|
+
const etagCheck = (0, cppCode_1.sw)(d.etag, {
|
|
9
|
+
always: [
|
|
10
|
+
` size_t hdr_len = httpd_req_get_hdr_value_len(req, "If-None-Match");`,
|
|
11
|
+
` if (hdr_len > 0) {`,
|
|
12
|
+
` char* hdr_value = malloc(hdr_len + 1);`,
|
|
13
|
+
` if (hdr_value == NULL) { httpd_resp_send_500(req); return ESP_FAIL; }`,
|
|
14
|
+
` if (httpd_req_get_hdr_value_str(req, "If-None-Match", hdr_value, hdr_len + 1) == ESP_OK) {`,
|
|
15
|
+
` if (strcmp(hdr_value, etag_${source.dataname}) == 0) {`,
|
|
16
|
+
` free(hdr_value);`,
|
|
17
|
+
` httpd_resp_set_status(req, "304 Not Modified");`,
|
|
18
|
+
` ${d.definePrefix}_onFileServed("${path}", 304);`,
|
|
19
|
+
` httpd_resp_send(req, NULL, 0);`,
|
|
20
|
+
` return ESP_OK;`,
|
|
21
|
+
` }`,
|
|
22
|
+
` }`,
|
|
23
|
+
` free(hdr_value);`,
|
|
24
|
+
` }`
|
|
25
|
+
].join('\n'),
|
|
26
|
+
compiler: [
|
|
27
|
+
` #ifdef ${d.definePrefix}_ENABLE_ETAG`,
|
|
28
|
+
` size_t hdr_len = httpd_req_get_hdr_value_len(req, "If-None-Match");`,
|
|
29
|
+
` if (hdr_len > 0) {`,
|
|
30
|
+
` char* hdr_value = malloc(hdr_len + 1);`,
|
|
31
|
+
` if (hdr_value == NULL) { httpd_resp_send_500(req); return ESP_FAIL; }`,
|
|
32
|
+
` if (httpd_req_get_hdr_value_str(req, "If-None-Match", hdr_value, hdr_len + 1) == ESP_OK) {`,
|
|
33
|
+
` if (strcmp(hdr_value, etag_${source.dataname}) == 0) {`,
|
|
34
|
+
` free(hdr_value);`,
|
|
35
|
+
` httpd_resp_set_status(req, "304 Not Modified");`,
|
|
36
|
+
` ${d.definePrefix}_onFileServed("${path}", 304);`,
|
|
37
|
+
` httpd_resp_send(req, NULL, 0);`,
|
|
38
|
+
` return ESP_OK;`,
|
|
39
|
+
` }`,
|
|
40
|
+
` }`,
|
|
41
|
+
` free(hdr_value);`,
|
|
42
|
+
` }`,
|
|
43
|
+
` #endif`
|
|
44
|
+
].join('\n')
|
|
45
|
+
});
|
|
46
|
+
if (etagCheck)
|
|
47
|
+
lines.push(etagCheck);
|
|
48
|
+
lines.push(` httpd_resp_set_type(req, "${source.mime}");`);
|
|
49
|
+
const gzipEncoding = (0, cppCode_1.sw)(d.gzip, {
|
|
50
|
+
always: source.isGzip ? ` httpd_resp_set_hdr(req, "Content-Encoding", "gzip");` : '',
|
|
51
|
+
compiler: source.isGzip
|
|
52
|
+
? [
|
|
53
|
+
` #ifdef ${d.definePrefix}_ENABLE_GZIP`,
|
|
54
|
+
` httpd_resp_set_hdr(req, "Content-Encoding", "gzip");`,
|
|
55
|
+
` #endif`
|
|
56
|
+
].join('\n')
|
|
57
|
+
: ''
|
|
58
|
+
});
|
|
59
|
+
if (gzipEncoding)
|
|
60
|
+
lines.push(gzipEncoding);
|
|
61
|
+
const cacheHeaders = (0, cppCode_1.sw)(d.etag, {
|
|
62
|
+
always: [
|
|
63
|
+
` httpd_resp_set_hdr(req, "Cache-Control", "${(0, cppCode_1.cacheCtrl)(source)}");`,
|
|
64
|
+
` httpd_resp_set_hdr(req, "ETag", etag_${source.dataname});`
|
|
65
|
+
].join('\n'),
|
|
66
|
+
compiler: [
|
|
67
|
+
` #ifdef ${d.definePrefix}_ENABLE_ETAG`,
|
|
68
|
+
` httpd_resp_set_hdr(req, "Cache-Control", "${(0, cppCode_1.cacheCtrl)(source)}");`,
|
|
69
|
+
` httpd_resp_set_hdr(req, "ETag", etag_${source.dataname});`,
|
|
70
|
+
` #endif`
|
|
71
|
+
].join('\n')
|
|
72
|
+
});
|
|
73
|
+
if (cacheHeaders)
|
|
74
|
+
lines.push(cacheHeaders);
|
|
75
|
+
lines.push((0, cppCode_1.sw)(d.gzip, {
|
|
76
|
+
always: [
|
|
77
|
+
` ${d.definePrefix}_onFileServed("${path}", 200);`,
|
|
78
|
+
` httpd_resp_send(req, (const char *)datagzip_${source.dataname}, ${source.lengthGzip});`
|
|
79
|
+
].join('\n'),
|
|
80
|
+
never: [
|
|
81
|
+
` ${d.definePrefix}_onFileServed("${path}", 200);`,
|
|
82
|
+
` httpd_resp_send(req, (const char *)data_${source.dataname}, ${source.length});`
|
|
83
|
+
].join('\n'),
|
|
84
|
+
compiler: [
|
|
85
|
+
` ${d.definePrefix}_onFileServed("${path}", 200);`,
|
|
86
|
+
` #ifdef ${d.definePrefix}_ENABLE_GZIP`,
|
|
87
|
+
` httpd_resp_send(req, (const char *)datagzip_${source.dataname}, ${source.lengthGzip});`,
|
|
88
|
+
` #else`,
|
|
89
|
+
` httpd_resp_send(req, (const char *)data_${source.dataname}, ${source.length});`,
|
|
90
|
+
` #endif`
|
|
91
|
+
].join('\n')
|
|
92
|
+
}), ` return ESP_OK;`, `}`);
|
|
93
|
+
if (source.isDefault) {
|
|
94
|
+
const defaultUri = d.basePath || '/';
|
|
95
|
+
lines.push(`static const httpd_uri_t route_def_${source.datanameUpperCase} = {`, ` .uri = "${defaultUri}",`, ` .method = HTTP_GET,`, ` .handler = file_handler_${source.datanameUpperCase},`, `};`);
|
|
96
|
+
}
|
|
97
|
+
lines.push(`static const httpd_uri_t route_${source.datanameUpperCase} = {`, ` .uri = "${path}",`, ` .method = HTTP_GET,`, ` .handler = file_handler_${source.datanameUpperCase},`, `};`);
|
|
98
|
+
return lines.join('\n');
|
|
119
99
|
};
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
{
|
|
130
|
-
{
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
100
|
+
const genEspIdfCpp = (d) => {
|
|
101
|
+
const lines = [
|
|
102
|
+
`//engine: espidf`,
|
|
103
|
+
`//config: ${d.config}`,
|
|
104
|
+
...(d.created ? [`//created: ${d.now}`] : []),
|
|
105
|
+
'//'
|
|
106
|
+
];
|
|
107
|
+
const etagWarn = (0, cppCode_1.sw)(d.etag, {
|
|
108
|
+
always: [
|
|
109
|
+
`#ifdef ${d.definePrefix}_ENABLE_ETAG`,
|
|
110
|
+
`#warning ${d.definePrefix}_ENABLE_ETAG has no effect because it is permanently switched ON`,
|
|
111
|
+
`#endif`
|
|
112
|
+
].join('\n'),
|
|
113
|
+
never: [
|
|
114
|
+
`#ifdef ${d.definePrefix}_ENABLE_ETAG`,
|
|
115
|
+
`#warning ${d.definePrefix}_ENABLE_ETAG has no effect because it is permanently switched OFF`,
|
|
116
|
+
`#endif`
|
|
117
|
+
].join('\n')
|
|
118
|
+
});
|
|
119
|
+
if (etagWarn)
|
|
120
|
+
lines.push(etagWarn);
|
|
121
|
+
const gzipWarn = (0, cppCode_1.sw)(d.gzip, {
|
|
122
|
+
always: [
|
|
123
|
+
`#ifdef ${d.definePrefix}_ENABLE_GZIP`,
|
|
124
|
+
`#warning ${d.definePrefix}_ENABLE_GZIP has no effect because it is permanently switched ON`,
|
|
125
|
+
`#endif`
|
|
126
|
+
].join('\n'),
|
|
127
|
+
never: [
|
|
128
|
+
`#ifdef ${d.definePrefix}_ENABLE_GZIP`,
|
|
129
|
+
`#warning ${d.definePrefix}_ENABLE_GZIP has no effect because it is permanently switched OFF`,
|
|
130
|
+
`#endif`
|
|
131
|
+
].join('\n')
|
|
132
|
+
});
|
|
133
|
+
if (gzipWarn)
|
|
134
|
+
lines.push(gzipWarn);
|
|
135
|
+
lines.push('//');
|
|
136
|
+
if (d.version)
|
|
137
|
+
lines.push(`#define ${d.definePrefix}_VERSION "${d.version}"`);
|
|
138
|
+
lines.push(`#define ${d.definePrefix}_COUNT ${d.fileCount}`, `#define ${d.definePrefix}_SIZE ${d.fileSize}`, `#define ${d.definePrefix}_SIZE_GZIP ${d.fileGzipSize}`, '//', ...d.sources.map((s) => `#define ${d.definePrefix}_FILE_${s.datanameUpperCase}`), '//', ...d.filesByExtension.map((g) => `#define ${d.definePrefix}_${g.extension}_FILES ${g.count}`), '#include <stdint.h>', '#include <string.h>', '#include <stdlib.h>', '#include <esp_err.h>', '#include <esp_http_server.h>', '//');
|
|
139
|
+
const gzipArrays = d.sources
|
|
140
|
+
.map((s) => `static const unsigned char datagzip_${s.dataname}[${s.lengthGzip}] = { ${s.bytesGzip} };`)
|
|
141
|
+
.join('\n');
|
|
142
|
+
const plainArrays = d.sources
|
|
143
|
+
.map((s) => `static const unsigned char data_${s.dataname}[${s.length}] = { ${s.bytes} };`)
|
|
144
|
+
.join('\n');
|
|
145
|
+
lines.push((0, cppCode_1.sw)(d.gzip, {
|
|
146
|
+
always: gzipArrays,
|
|
147
|
+
never: plainArrays,
|
|
148
|
+
compiler: [`#ifdef ${d.definePrefix}_ENABLE_GZIP`, gzipArrays, '#else', plainArrays, '#endif'].join('\n')
|
|
149
|
+
}), '//');
|
|
150
|
+
const etagItems = d.sources.map((s) => `static const char etag_${s.dataname}[] = "${s.sha256}";`).join('\n');
|
|
151
|
+
const etagBlock = (0, cppCode_1.sw)(d.etag, {
|
|
152
|
+
always: etagItems,
|
|
153
|
+
compiler: [`#ifdef ${d.definePrefix}_ENABLE_ETAG`, etagItems, '#endif'].join('\n')
|
|
154
|
+
});
|
|
155
|
+
if (etagBlock)
|
|
156
|
+
lines.push(etagBlock);
|
|
157
|
+
lines.push(`// File manifest struct (C-compatible typedef)`, `typedef struct {`, ` const char* path;`, ` uint32_t size;`, ` uint32_t gzipSize;`, ` const char* etag;`, ` const char* contentType;`, `} ${d.definePrefix}_FileInfo;`, `// File manifest array`, `static const ${d.definePrefix}_FileInfo ${d.definePrefix}_FILES[] = {`, ...d.sources.map((s) => ` { "${d.basePath}/${s.filename}", ${s.length}, ${s.gzipSizeForManifest}, ${s.etagForManifest}, "${s.mime}" },`), `};`, `static const size_t ${d.definePrefix}_FILE_COUNT = sizeof(${d.definePrefix}_FILES) / sizeof(${d.definePrefix}_FILES[0]);`, `// File served hook - override with your own implementation`, `__attribute__((weak)) void ${d.definePrefix}_onFileServed(const char* path, int statusCode) {}`);
|
|
158
|
+
for (const source of d.sources)
|
|
159
|
+
lines.push(genEspIdfFileHandler(d, source));
|
|
160
|
+
if (d.spa && d.spaSource) {
|
|
161
|
+
const source = d.spaSource;
|
|
162
|
+
lines.push(`static esp_err_t spa_handler_${source.datanameUpperCase}(httpd_req_t *req, httpd_err_code_t err) {`);
|
|
163
|
+
if (d.basePath)
|
|
164
|
+
lines.push(` const char* prefix = "${d.basePath}/";`, ` if (strncmp(req->uri, prefix, strlen(prefix)) != 0 && strcmp(req->uri, "${d.basePath}") != 0) {`, ` httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "Not found");`, ` return ESP_FAIL;`, ` }`);
|
|
165
|
+
lines.push(` return file_handler_${source.datanameUpperCase}(req);`, `}`);
|
|
145
166
|
}
|
|
146
|
-
{{
|
|
147
|
-
{
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
char* hdr_value = malloc(hdr_len + 1);
|
|
152
|
-
if (hdr_value == NULL) { httpd_resp_send_500(req); return ESP_FAIL; }
|
|
153
|
-
if (httpd_req_get_hdr_value_str(req, "If-None-Match", hdr_value, hdr_len + 1) == ESP_OK) {
|
|
154
|
-
if (strcmp(hdr_value, etag_{{this.dataname}}) == 0) {
|
|
155
|
-
free(hdr_value);
|
|
156
|
-
httpd_resp_set_status(req, "304 Not Modified");
|
|
157
|
-
{{../definePrefix}}_onFileServed("{{../basePath}}/{{this.filename}}", 304);
|
|
158
|
-
httpd_resp_send(req, NULL, 0);
|
|
159
|
-
return ESP_OK;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
free(hdr_value);
|
|
167
|
+
lines.push(`static inline void ${d.methodName}(httpd_handle_t server) {`);
|
|
168
|
+
for (const source of d.sources) {
|
|
169
|
+
if (source.isDefault)
|
|
170
|
+
lines.push(` httpd_register_uri_handler(server, &route_def_${source.datanameUpperCase});`);
|
|
171
|
+
lines.push(` httpd_register_uri_handler(server, &route_${source.datanameUpperCase});`);
|
|
163
172
|
}
|
|
164
|
-
|
|
165
|
-
{
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
{{#switch ../gzip}}
|
|
169
|
-
{{#case "always"}}
|
|
170
|
-
{{#if this.isGzip}}
|
|
171
|
-
httpd_resp_set_hdr(req, "Content-Encoding", "gzip");
|
|
172
|
-
{{/if}}
|
|
173
|
-
{{/case}}
|
|
174
|
-
{{#case "compiler"}}
|
|
175
|
-
{{#if this.isGzip}}
|
|
176
|
-
#ifdef {{../definePrefix}}_ENABLE_GZIP
|
|
177
|
-
httpd_resp_set_hdr(req, "Content-Encoding", "gzip");
|
|
178
|
-
#endif
|
|
179
|
-
{{/if}}
|
|
180
|
-
{{/case}}
|
|
181
|
-
{{/switch}}
|
|
182
|
-
|
|
183
|
-
{{#switch ../etag}}
|
|
184
|
-
{{#case "always"}}
|
|
185
|
-
{{#this.cacheTime}}
|
|
186
|
-
httpd_resp_set_hdr(req, "Cache-Control", "max-age={{value}}");
|
|
187
|
-
{{/this.cacheTime}}
|
|
188
|
-
{{^this.cacheTime}}
|
|
189
|
-
httpd_resp_set_hdr(req, "Cache-Control", "no-cache");
|
|
190
|
-
{{/this.cacheTime}}
|
|
191
|
-
httpd_resp_set_hdr(req, "ETag", etag_{{this.dataname}});
|
|
192
|
-
{{/case}}
|
|
193
|
-
{{#case "compiler"}}
|
|
194
|
-
#ifdef {{../definePrefix}}_ENABLE_ETAG
|
|
195
|
-
{{#this.cacheTime}}
|
|
196
|
-
httpd_resp_set_hdr(req, "Cache-Control", "max-age={{value}}");
|
|
197
|
-
{{/this.cacheTime}}
|
|
198
|
-
{{^this.cacheTime}}
|
|
199
|
-
httpd_resp_set_hdr(req, "Cache-Control", "no-cache");
|
|
200
|
-
{{/this.cacheTime}}
|
|
201
|
-
httpd_resp_set_hdr(req, "ETag", etag_{{this.dataname}});
|
|
202
|
-
#endif
|
|
203
|
-
{{/case}}
|
|
204
|
-
{{/switch}}
|
|
205
|
-
|
|
206
|
-
{{#switch ../gzip}}
|
|
207
|
-
{{#case "always"}}
|
|
208
|
-
{{../definePrefix}}_onFileServed("{{../basePath}}/{{this.filename}}", 200);
|
|
209
|
-
httpd_resp_send(req, (const char *)datagzip_{{this.dataname}}, {{this.lengthGzip}});
|
|
210
|
-
{{/case}}
|
|
211
|
-
{{#case "never"}}
|
|
212
|
-
{{../definePrefix}}_onFileServed("{{../basePath}}/{{this.filename}}", 200);
|
|
213
|
-
httpd_resp_send(req, (const char *)data_{{this.dataname}}, {{this.length}});
|
|
214
|
-
{{/case}}
|
|
215
|
-
{{#case "compiler"}}
|
|
216
|
-
{{../definePrefix}}_onFileServed("{{../basePath}}/{{this.filename}}", 200);
|
|
217
|
-
#ifdef {{../definePrefix}}_ENABLE_GZIP
|
|
218
|
-
httpd_resp_send(req, (const char *)datagzip_{{this.dataname}}, {{this.lengthGzip}});
|
|
219
|
-
#else
|
|
220
|
-
httpd_resp_send(req, (const char *)data_{{this.dataname}}, {{this.length}});
|
|
221
|
-
#endif
|
|
222
|
-
{{/case}}
|
|
223
|
-
{{/switch}}
|
|
224
|
-
return ESP_OK;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
{{#if this.isDefault}}
|
|
228
|
-
static const httpd_uri_t route_def_{{this.datanameUpperCase}} = {
|
|
229
|
-
.uri = "{{#if ../basePath}}{{../basePath}}{{else}}/{{/if}}",
|
|
230
|
-
.method = HTTP_GET,
|
|
231
|
-
.handler = file_handler_{{this.datanameUpperCase}},
|
|
232
|
-
};
|
|
233
|
-
{{/if}}
|
|
234
|
-
|
|
235
|
-
static const httpd_uri_t route_{{this.datanameUpperCase}} = {
|
|
236
|
-
.uri = "{{../basePath}}/{{this.filename}}",
|
|
237
|
-
.method = HTTP_GET,
|
|
238
|
-
.handler = file_handler_{{this.datanameUpperCase}},
|
|
173
|
+
if (d.spa && d.spaSource)
|
|
174
|
+
lines.push(` httpd_register_err_handler(server, HTTPD_404_NOT_FOUND, spa_handler_${d.spaSource.datanameUpperCase});`);
|
|
175
|
+
lines.push('}');
|
|
176
|
+
return lines.join('\n');
|
|
239
177
|
};
|
|
240
|
-
|
|
241
|
-
{{/each}}
|
|
242
|
-
|
|
243
|
-
{{#if spa}}
|
|
244
|
-
{{#with spaSource}}
|
|
245
|
-
static esp_err_t spa_handler_{{this.datanameUpperCase}}(httpd_req_t *req, httpd_err_code_t err) {
|
|
246
|
-
{{#if ../basePath}}
|
|
247
|
-
const char* prefix = "{{../basePath}}/";
|
|
248
|
-
if (strncmp(req->uri, prefix, strlen(prefix)) != 0 && strcmp(req->uri, "{{../basePath}}") != 0) {
|
|
249
|
-
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "Not found");
|
|
250
|
-
return ESP_FAIL;
|
|
251
|
-
}
|
|
252
|
-
{{/if}}
|
|
253
|
-
return file_handler_{{this.datanameUpperCase}}(req);
|
|
254
|
-
}
|
|
255
|
-
{{/with}}
|
|
256
|
-
{{/if}}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
static inline void {{methodName}}(httpd_handle_t server) {
|
|
260
|
-
{{#each sources}}
|
|
261
|
-
{{#if this.isDefault}}
|
|
262
|
-
httpd_register_uri_handler(server, &route_def_{{this.datanameUpperCase}});
|
|
263
|
-
{{/if}}
|
|
264
|
-
httpd_register_uri_handler(server, &route_{{this.datanameUpperCase}});
|
|
265
|
-
{{/each}}
|
|
266
|
-
{{#if spa}}
|
|
267
|
-
{{#with spaSource}}
|
|
268
|
-
httpd_register_err_handler(server, HTTPD_404_NOT_FOUND, spa_handler_{{this.datanameUpperCase}});
|
|
269
|
-
{{/with}}
|
|
270
|
-
{{/if}}
|
|
271
|
-
|
|
272
|
-
}`;
|
|
178
|
+
exports.genEspIdfCpp = genEspIdfCpp;
|