svelteesp32 2.4.0 → 3.0.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 +89 -27
- package/bin/index.js +10 -1
- package/dist/commandLine.d.ts +12 -11
- package/dist/commandLine.js +41 -18
- package/dist/consoleColor.d.ts +1 -0
- package/dist/cppCode.d.ts +1 -0
- package/dist/cppCode.js +48 -48
- package/dist/cppCodeEspIdf.d.ts +2 -1
- package/dist/cppCodeEspIdf.js +13 -13
- package/dist/errorMessages.d.ts +1 -0
- package/dist/errorMessages.js +1 -1
- package/dist/file.d.ts +3 -1
- package/dist/file.js +8 -11
- package/dist/index.d.ts +2 -16
- package/dist/index.js +22 -227
- package/dist/initCommand.d.ts +2 -0
- package/dist/initCommand.js +55 -0
- package/dist/pipeline.d.ts +29 -0
- package/dist/pipeline.js +278 -0
- package/dist/vitePlugin.d.ts +34 -0
- package/dist/vitePlugin.js +56 -0
- package/package.json +31 -14
package/dist/index.js
CHANGED
|
@@ -1,235 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.updateExtensionGroup = exports.shouldUseGzip = exports.formatSizePrecise = exports.formatSize = exports.formatDryRunRoutes = exports.formatCompressionLog = exports.formatAnalyzeTable = exports.createSourceEntry = exports.calculateCompressionRatio = void 0;
|
|
3
|
+
exports.updateExtensionGroup = exports.shouldUseGzip = exports.formatSizePrecise = exports.formatSize = exports.formatDryRunRoutes = exports.formatCompressionLog = exports.formatChangeSummary = exports.formatAnalyzeTable = exports.createSourceEntry = exports.calculateCompressionRatio = void 0;
|
|
7
4
|
exports.main = main;
|
|
8
|
-
const node_fs_1 = require("node:fs");
|
|
9
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
-
const node_zlib_1 = require("node:zlib");
|
|
11
|
-
const mime_types_1 = require("mime-types");
|
|
12
5
|
const commandLine_1 = require("./commandLine");
|
|
13
|
-
const
|
|
14
|
-
const cppCode_1 = require("./cppCode");
|
|
15
|
-
const errorMessages_1 = require("./errorMessages");
|
|
16
|
-
const file_1 = require("./file");
|
|
17
|
-
const GZIP_MIN_SIZE = 1024;
|
|
18
|
-
const GZIP_MIN_REDUCTION_RATIO = 0.85;
|
|
19
|
-
const shouldUseGzip = (originalSize, compressedSize) => originalSize > GZIP_MIN_SIZE && compressedSize < originalSize * GZIP_MIN_REDUCTION_RATIO;
|
|
20
|
-
exports.shouldUseGzip = shouldUseGzip;
|
|
21
|
-
const calculateCompressionRatio = (originalSize, compressedSize) => Math.round((compressedSize / originalSize) * 100);
|
|
22
|
-
exports.calculateCompressionRatio = calculateCompressionRatio;
|
|
23
|
-
const formatCompressionLog = (filename, padding, originalSize, compressedSize, useGzip) => {
|
|
24
|
-
const ratio = calculateCompressionRatio(originalSize, compressedSize);
|
|
25
|
-
const sizeInfo = `(${originalSize} -> ${compressedSize} = ${ratio}%)`;
|
|
26
|
-
if (useGzip)
|
|
27
|
-
return (0, consoleColor_1.greenLog)(` [${filename}] ${padding} ✓ gzip used ${sizeInfo}`);
|
|
28
|
-
const tooSmall = originalSize <= GZIP_MIN_SIZE ? '(too small) ' : '';
|
|
29
|
-
return (0, consoleColor_1.yellowLog)(` [${filename}] ${padding} x gzip unused ${tooSmall}${sizeInfo}`);
|
|
30
|
-
};
|
|
31
|
-
exports.formatCompressionLog = formatCompressionLog;
|
|
32
|
-
const formatSize = (bytes) => {
|
|
33
|
-
if (bytes < 1024)
|
|
34
|
-
return `${bytes}B`;
|
|
35
|
-
return `${Math.round(bytes / 1024)}kB`;
|
|
36
|
-
};
|
|
37
|
-
exports.formatSize = formatSize;
|
|
38
|
-
const formatSizePrecise = (bytes) => {
|
|
39
|
-
if (bytes < 1024)
|
|
40
|
-
return `${bytes}B`;
|
|
41
|
-
return `${(bytes / 1024).toFixed(1)}kB`;
|
|
42
|
-
};
|
|
43
|
-
exports.formatSizePrecise = formatSizePrecise;
|
|
44
|
-
const createSourceEntry = (filename, dataname, content, contentGzip, mimeType, sha256, isGzip) => ({
|
|
45
|
-
filename,
|
|
46
|
-
dataname,
|
|
47
|
-
datanameUpperCase: dataname.toUpperCase(),
|
|
48
|
-
content,
|
|
49
|
-
contentGzip: isGzip ? contentGzip : content,
|
|
50
|
-
isGzip,
|
|
51
|
-
mime: mimeType,
|
|
52
|
-
sha256
|
|
53
|
-
});
|
|
54
|
-
exports.createSourceEntry = createSourceEntry;
|
|
55
|
-
const updateExtensionGroup = (filesByExtension, extension) => {
|
|
56
|
-
const group = filesByExtension.find((fe) => fe.extension === extension);
|
|
57
|
-
if (group)
|
|
58
|
-
group.count += 1;
|
|
59
|
-
else
|
|
60
|
-
filesByExtension.push({ extension, count: 1 });
|
|
61
|
-
};
|
|
62
|
-
exports.updateExtensionGroup = updateExtensionGroup;
|
|
63
|
-
const sizeCellFor = (s) => {
|
|
64
|
-
const orig = formatSize(s.content.length);
|
|
65
|
-
if (s.isGzip)
|
|
66
|
-
return `${orig} → ${formatSize(s.contentGzip.length)}`;
|
|
67
|
-
return orig;
|
|
68
|
-
};
|
|
69
|
-
const formatDryRunRoutes = (sources, engine, basePath, spa) => {
|
|
70
|
-
if (sources.length === 0)
|
|
71
|
-
return ' (no files)';
|
|
72
|
-
const defaultSource = sources.find((s) => s.filename === 'index.html' || s.filename === 'index.htm');
|
|
73
|
-
const rows = [];
|
|
74
|
-
if (defaultSource)
|
|
75
|
-
rows.push({
|
|
76
|
-
url: basePath || '/',
|
|
77
|
-
mime: defaultSource.mime,
|
|
78
|
-
sizeCell: sizeCellFor(defaultSource),
|
|
79
|
-
tag: '[default]'
|
|
80
|
-
});
|
|
81
|
-
for (const source of sources)
|
|
82
|
-
rows.push({
|
|
83
|
-
url: `${basePath}/${source.filename}`,
|
|
84
|
-
mime: source.mime,
|
|
85
|
-
sizeCell: sizeCellFor(source),
|
|
86
|
-
tag: source.isGzip ? '' : '[no gzip]'
|
|
87
|
-
});
|
|
88
|
-
if (spa && defaultSource) {
|
|
89
|
-
const spaUrl = engine === 'psychic' && basePath ? `${basePath}/*` : '(SPA catch-all)';
|
|
90
|
-
rows.push({ url: spaUrl, mime: defaultSource.mime, sizeCell: '', tag: '[SPA catch-all → index.html]' });
|
|
91
|
-
}
|
|
92
|
-
const urlWidth = Math.max(...rows.map((r) => r.url.length));
|
|
93
|
-
const mimeWidth = Math.max(...rows.map((r) => r.mime.length));
|
|
94
|
-
const sizeWidth = Math.max(...rows.map((r) => r.sizeCell.length));
|
|
95
|
-
return rows
|
|
96
|
-
.map((r) => {
|
|
97
|
-
const tagPart = r.tag ? ` ${r.tag}` : '';
|
|
98
|
-
return ` GET ${r.url.padEnd(urlWidth)} ${r.mime.padEnd(mimeWidth)} ${r.sizeCell.padEnd(sizeWidth)}${tagPart}`.trimEnd();
|
|
99
|
-
})
|
|
100
|
-
.join('\n');
|
|
101
|
-
};
|
|
102
|
-
exports.formatDryRunRoutes = formatDryRunRoutes;
|
|
103
|
-
const formatAnalyzeTable = (sources, summary, maxSize, maxGzipSize) => {
|
|
104
|
-
const rows = sources.map((s) => ({
|
|
105
|
-
file: s.filename,
|
|
106
|
-
orig: formatSizePrecise(s.content.length),
|
|
107
|
-
gzip: formatSizePrecise(s.isGzip ? s.contentGzip.length : s.content.length),
|
|
108
|
-
tag: s.isGzip ? '' : '[no gzip]'
|
|
109
|
-
}));
|
|
110
|
-
const fileWidth = Math.max(4, ...rows.map((r) => r.file.length), 'Total'.length);
|
|
111
|
-
const origWidth = Math.max(8, ...rows.map((r) => r.orig.length), formatSizePrecise(summary.size).length);
|
|
112
|
-
const gzipWidth = Math.max(8, ...rows.map((r) => r.gzip.length), formatSizePrecise(summary.gzipsize).length);
|
|
113
|
-
const separator = `${'─'.repeat(fileWidth)} ${'─'.repeat(origWidth)} ${'─'.repeat(gzipWidth)}`;
|
|
114
|
-
const header = `${'File'.padEnd(fileWidth)} ${'Original'.padEnd(origWidth)} ${'Gzip'.padEnd(gzipWidth)}`;
|
|
115
|
-
const dataRows = rows.map((r) => {
|
|
116
|
-
const tagPart = r.tag ? ` ${r.tag}` : '';
|
|
117
|
-
return `${r.file.padEnd(fileWidth)} ${r.orig.padEnd(origWidth)} ${r.gzip.padEnd(gzipWidth)}${tagPart}`.trimEnd();
|
|
118
|
-
});
|
|
119
|
-
const totalOrig = formatSizePrecise(summary.size);
|
|
120
|
-
const totalGzip = formatSizePrecise(summary.gzipsize);
|
|
121
|
-
const totalRow = `${'Total'.padEnd(fileWidth)} ${totalOrig.padEnd(origWidth)} ${totalGzip.padEnd(gzipWidth)}`;
|
|
122
|
-
const lines = [header, separator, ...dataRows, separator, totalRow];
|
|
123
|
-
if (maxSize !== undefined) {
|
|
124
|
-
const pass = summary.size <= maxSize;
|
|
125
|
-
const budgetRow = `${'Budget (maxsize)'.padEnd(fileWidth)} ${formatSizePrecise(maxSize).padEnd(origWidth)} ${'-'.padEnd(gzipWidth)} ${pass ? '✓ PASS' : '✗ FAIL'}`;
|
|
126
|
-
lines.push(budgetRow);
|
|
127
|
-
}
|
|
128
|
-
if (maxGzipSize !== undefined) {
|
|
129
|
-
const pass = summary.gzipsize <= maxGzipSize;
|
|
130
|
-
const budgetRow = `${'Budget (maxgzipsize)'.padEnd(fileWidth)} ${'-'.padEnd(origWidth)} ${formatSizePrecise(maxGzipSize).padEnd(gzipWidth)} ${pass ? '✓ PASS' : '✗ FAIL'}`;
|
|
131
|
-
lines.push(budgetRow);
|
|
132
|
-
}
|
|
133
|
-
return lines.join('\n');
|
|
134
|
-
};
|
|
135
|
-
exports.formatAnalyzeTable = formatAnalyzeTable;
|
|
6
|
+
const pipeline_1 = require("./pipeline");
|
|
136
7
|
function main() {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
if (files.size === 0) {
|
|
147
|
-
console.error(`Directory ${commandLine_1.cmdLine.sourcepath} is empty`);
|
|
8
|
+
try {
|
|
9
|
+
(0, pipeline_1.runPipeline)(commandLine_1.cmdLine);
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
if (!(error instanceof pipeline_1.OverBudgetError)) {
|
|
13
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
14
|
+
if (message)
|
|
15
|
+
console.error(message);
|
|
16
|
+
}
|
|
148
17
|
process.exit(1);
|
|
149
18
|
}
|
|
150
|
-
if (commandLine_1.cmdLine.spa && ![...files.keys()].some((f) => f === 'index.html' || f === 'index.htm'))
|
|
151
|
-
console.warn((0, consoleColor_1.yellowLog)('[SvelteESP32] Warning: --spa is set but no index.html/index.htm found; catch-all will not be generated.'));
|
|
152
|
-
console.log();
|
|
153
|
-
console.log('Translation to header file');
|
|
154
|
-
const longestFilename = [...files.keys()].reduce((p, c) => Math.max(c.length, p), 0);
|
|
155
|
-
for (const [originalFilename, fileData] of files) {
|
|
156
|
-
const { content, hash: sha256 } = fileData;
|
|
157
|
-
const rawMime = (0, mime_types_1.lookup)(originalFilename);
|
|
158
|
-
if (!rawMime)
|
|
159
|
-
console.log((0, consoleColor_1.yellowLog)(` [${originalFilename}] unknown MIME type for extension '${node_path_1.default.extname(originalFilename)}', using text/plain`));
|
|
160
|
-
const mimeType = rawMime || 'text/plain';
|
|
161
|
-
summary.filecount++;
|
|
162
|
-
const filename = originalFilename.replace(/\\/g, '/');
|
|
163
|
-
let dataname = filename.replace(/\W/g, '_');
|
|
164
|
-
if (/^\d/.test(dataname))
|
|
165
|
-
dataname = '_' + dataname;
|
|
166
|
-
let extension = node_path_1.default.extname(filename).toUpperCase();
|
|
167
|
-
if (extension.startsWith('.'))
|
|
168
|
-
extension = extension.slice(1);
|
|
169
|
-
updateExtensionGroup(filesByExtension, extension);
|
|
170
|
-
summary.size += content.length;
|
|
171
|
-
const zipContent = (0, node_zlib_1.gzipSync)(content, { level: 9 });
|
|
172
|
-
const useGzip = shouldUseGzip(content.length, zipContent.length);
|
|
173
|
-
summary.gzipsize += useGzip ? zipContent.length : content.length;
|
|
174
|
-
sources.push(createSourceEntry(filename, dataname, content, zipContent, mimeType, sha256, useGzip));
|
|
175
|
-
const padding = ' '.repeat(longestFilename - originalFilename.length);
|
|
176
|
-
console.log(formatCompressionLog(originalFilename, padding, content.length, zipContent.length, useGzip));
|
|
177
|
-
}
|
|
178
|
-
console.log('');
|
|
179
|
-
filesByExtension.sort((left, right) => left.extension.localeCompare(right.extension));
|
|
180
|
-
if (commandLine_1.cmdLine.analyze) {
|
|
181
|
-
console.log(formatAnalyzeTable(sources, summary, commandLine_1.cmdLine.maxSize, commandLine_1.cmdLine.maxGzipSize));
|
|
182
|
-
const overBudget = (commandLine_1.cmdLine.maxSize !== undefined && summary.size > commandLine_1.cmdLine.maxSize) ||
|
|
183
|
-
(commandLine_1.cmdLine.maxGzipSize !== undefined && summary.gzipsize > commandLine_1.cmdLine.maxGzipSize);
|
|
184
|
-
if (overBudget)
|
|
185
|
-
process.exit(1);
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
if (commandLine_1.cmdLine.maxSize !== undefined && summary.size > commandLine_1.cmdLine.maxSize) {
|
|
189
|
-
console.error((0, errorMessages_1.getSizeBudgetExceededError)('size', commandLine_1.cmdLine.maxSize, summary.size));
|
|
190
|
-
process.exit(1);
|
|
191
|
-
}
|
|
192
|
-
if (commandLine_1.cmdLine.maxGzipSize !== undefined && summary.gzipsize > commandLine_1.cmdLine.maxGzipSize) {
|
|
193
|
-
console.error((0, errorMessages_1.getSizeBudgetExceededError)('gzipSize', commandLine_1.cmdLine.maxGzipSize, summary.gzipsize));
|
|
194
|
-
process.exit(1);
|
|
195
|
-
}
|
|
196
|
-
if (commandLine_1.cmdLine.dryRun) {
|
|
197
|
-
const baseLabel = commandLine_1.cmdLine.basePath || '(none)';
|
|
198
|
-
const spaLabel = commandLine_1.cmdLine.spa ? 'yes' : 'no';
|
|
199
|
-
console.log(`[DRY RUN] Engine: ${commandLine_1.cmdLine.engine} | ETag: ${commandLine_1.cmdLine.etag} | Gzip: ${commandLine_1.cmdLine.gzip} | Base: ${baseLabel} | SPA: ${spaLabel}`);
|
|
200
|
-
console.log(`[DRY RUN] ${summary.filecount} files, ${formatSize(summary.size)} → ${formatSize(summary.gzipsize)} gzip | would write to ${commandLine_1.cmdLine.outputfile}`);
|
|
201
|
-
console.log('');
|
|
202
|
-
console.log('[DRY RUN] Routes:');
|
|
203
|
-
console.log(formatDryRunRoutes(sources, commandLine_1.cmdLine.engine, commandLine_1.cmdLine.basePath, commandLine_1.cmdLine.spa ?? false));
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
const cppFile = (0, cppCode_1.getCppCode)(sources, filesByExtension);
|
|
207
|
-
(0, node_fs_1.mkdirSync)(node_path_1.default.normalize(node_path_1.default.dirname(commandLine_1.cmdLine.outputfile)), { recursive: true });
|
|
208
|
-
(0, node_fs_1.writeFileSync)(commandLine_1.cmdLine.outputfile, cppFile, { flush: true, encoding: 'utf8' });
|
|
209
|
-
console.log(`${summary.filecount} files, ${formatSize(summary.size)} original size, ${formatSize(summary.gzipsize)} gzip size`);
|
|
210
|
-
console.log(`${commandLine_1.cmdLine.outputfile} ${formatSize(cppFile.length)} size`);
|
|
211
|
-
if (commandLine_1.cmdLine.manifest) {
|
|
212
|
-
const manifestPath = node_path_1.default.join(node_path_1.default.dirname(commandLine_1.cmdLine.outputfile), node_path_1.default.basename(commandLine_1.cmdLine.outputfile, node_path_1.default.extname(commandLine_1.cmdLine.outputfile)) + '.manifest.json');
|
|
213
|
-
const manifest = {
|
|
214
|
-
generated: new Date().toISOString(),
|
|
215
|
-
engine: commandLine_1.cmdLine.engine,
|
|
216
|
-
etag: commandLine_1.cmdLine.etag,
|
|
217
|
-
gzip: commandLine_1.cmdLine.gzip,
|
|
218
|
-
filecount: summary.filecount,
|
|
219
|
-
size: summary.size,
|
|
220
|
-
gzipSize: summary.gzipsize,
|
|
221
|
-
files: sources.map((s) => ({
|
|
222
|
-
path: s.filename,
|
|
223
|
-
mime: s.mime,
|
|
224
|
-
size: s.content.length,
|
|
225
|
-
gzipSize: s.isGzip ? s.contentGzip.length : s.content.length,
|
|
226
|
-
isGzip: s.isGzip
|
|
227
|
-
}))
|
|
228
|
-
};
|
|
229
|
-
(0, node_fs_1.writeFileSync)(manifestPath, JSON.stringify(manifest, undefined, 2), { encoding: 'utf8' });
|
|
230
|
-
console.log(`${manifestPath} manifest written`);
|
|
231
|
-
}
|
|
232
|
-
if (commandLine_1.cmdLine.engine === 'psychic' || commandLine_1.cmdLine.engine === 'espidf')
|
|
233
|
-
console.log('\n' + (0, errorMessages_1.getMaxUriHandlersHint)(commandLine_1.cmdLine.engine, sources.length, commandLine_1.cmdLine.espmethod));
|
|
234
19
|
}
|
|
235
|
-
|
|
20
|
+
var pipeline_2 = require("./pipeline");
|
|
21
|
+
Object.defineProperty(exports, "calculateCompressionRatio", { enumerable: true, get: function () { return pipeline_2.calculateCompressionRatio; } });
|
|
22
|
+
Object.defineProperty(exports, "createSourceEntry", { enumerable: true, get: function () { return pipeline_2.createSourceEntry; } });
|
|
23
|
+
Object.defineProperty(exports, "formatAnalyzeTable", { enumerable: true, get: function () { return pipeline_2.formatAnalyzeTable; } });
|
|
24
|
+
Object.defineProperty(exports, "formatChangeSummary", { enumerable: true, get: function () { return pipeline_2.formatChangeSummary; } });
|
|
25
|
+
Object.defineProperty(exports, "formatCompressionLog", { enumerable: true, get: function () { return pipeline_2.formatCompressionLog; } });
|
|
26
|
+
Object.defineProperty(exports, "formatDryRunRoutes", { enumerable: true, get: function () { return pipeline_2.formatDryRunRoutes; } });
|
|
27
|
+
Object.defineProperty(exports, "formatSize", { enumerable: true, get: function () { return pipeline_2.formatSize; } });
|
|
28
|
+
Object.defineProperty(exports, "formatSizePrecise", { enumerable: true, get: function () { return pipeline_2.formatSizePrecise; } });
|
|
29
|
+
Object.defineProperty(exports, "shouldUseGzip", { enumerable: true, get: function () { return pipeline_2.shouldUseGzip; } });
|
|
30
|
+
Object.defineProperty(exports, "updateExtensionGroup", { enumerable: true, get: function () { return pipeline_2.updateExtensionGroup; } });
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.runInit = runInit;
|
|
7
|
+
const node_child_process_1 = require("node:child_process");
|
|
8
|
+
const node_fs_1 = require("node:fs");
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
+
const promises_1 = require("node:readline/promises");
|
|
11
|
+
const RC_FILENAME = '.svelteesp32rc.json';
|
|
12
|
+
const ENGINES = ['psychic', 'async', 'espidf', 'webserver'];
|
|
13
|
+
const TRISTATES = ['always', 'never', 'compiler'];
|
|
14
|
+
function isEngine(value) {
|
|
15
|
+
return ENGINES.includes(value);
|
|
16
|
+
}
|
|
17
|
+
function isTriState(value) {
|
|
18
|
+
return TRISTATES.includes(value);
|
|
19
|
+
}
|
|
20
|
+
async function runInit() {
|
|
21
|
+
const rl = (0, promises_1.createInterface)({ input: process.stdin, output: process.stdout });
|
|
22
|
+
try {
|
|
23
|
+
console.log('svelteesp32 init - Create a configuration file\n');
|
|
24
|
+
const rcPath = node_path_1.default.join(process.cwd(), RC_FILENAME);
|
|
25
|
+
if ((0, node_fs_1.existsSync)(rcPath)) {
|
|
26
|
+
const overwriteAnswerRaw = await rl.question(`${RC_FILENAME} already exists. Overwrite? (y/N): `);
|
|
27
|
+
if (overwriteAnswerRaw.trim().toLowerCase() !== 'y') {
|
|
28
|
+
console.log('Aborted.');
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const engineAnswerRaw = await rl.question(`Engine (${ENGINES.join('|')}) [psychic]: `);
|
|
33
|
+
const engineAnswer = engineAnswerRaw.trim();
|
|
34
|
+
const engine = isEngine(engineAnswer) ? engineAnswer : 'psychic';
|
|
35
|
+
const sourcepathAnswerRaw = await rl.question('Source path (compiled web app dist folder) [./dist]: ');
|
|
36
|
+
const sourcepath = sourcepathAnswerRaw.trim() || './dist';
|
|
37
|
+
const outputfileAnswerRaw = await rl.question('Output file (C++ header path) [./svelteesp32.h]: ');
|
|
38
|
+
const outputfile = outputfileAnswerRaw.trim() || './svelteesp32.h';
|
|
39
|
+
const etagAnswerRaw = await rl.question(`ETag (${TRISTATES.join('|')}) [always]: `);
|
|
40
|
+
const etagAnswer = etagAnswerRaw.trim();
|
|
41
|
+
const etag = isTriState(etagAnswer) ? etagAnswer : 'always';
|
|
42
|
+
const config = { engine, sourcepath, outputfile, etag, gzip: 'always' };
|
|
43
|
+
(0, node_fs_1.writeFileSync)(rcPath, JSON.stringify(config, undefined, 2) + '\n', 'utf8');
|
|
44
|
+
console.log(`\nCreated ${RC_FILENAME}`);
|
|
45
|
+
const runAnswerRaw = await rl.question('\nWould you like to run svelteesp32 now? (Y/n): ');
|
|
46
|
+
if (runAnswerRaw.trim().toLowerCase() !== 'n') {
|
|
47
|
+
const binaryPath = process.argv[1];
|
|
48
|
+
if (binaryPath)
|
|
49
|
+
(0, node_child_process_1.spawnSync)('node', [binaryPath], { stdio: 'inherit' });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
finally {
|
|
53
|
+
rl.close();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ICopyFilesArguments } from './commandLine';
|
|
2
|
+
import { type CppCodeSource, type CppCodeSources, type ExtensionGroups } from './cppCode';
|
|
3
|
+
type ProcessingSummary = {
|
|
4
|
+
filecount: number;
|
|
5
|
+
size: number;
|
|
6
|
+
gzipsize: number;
|
|
7
|
+
};
|
|
8
|
+
declare const shouldUseGzip: (originalSize: number, compressedSize: number) => boolean;
|
|
9
|
+
declare const calculateCompressionRatio: (originalSize: number, compressedSize: number) => number;
|
|
10
|
+
declare const formatCompressionLog: (filename: string, padding: string, originalSize: number, compressedSize: number, useGzip: boolean) => string;
|
|
11
|
+
declare const formatSize: (bytes: number) => string;
|
|
12
|
+
declare const formatSizePrecise: (bytes: number) => string;
|
|
13
|
+
declare const createSourceEntry: (filename: string, dataname: string, content: Buffer, contentGzip: Buffer, mimeType: string, sha256: string, isGzip: boolean) => CppCodeSource;
|
|
14
|
+
declare const updateExtensionGroup: (filesByExtension: ExtensionGroups, extension: string) => void;
|
|
15
|
+
declare const formatDryRunRoutes: (sources: CppCodeSources, engine: "psychic" | "async" | "espidf" | "webserver", basePath: string, spa: boolean) => string;
|
|
16
|
+
declare const formatAnalyzeTable: (sources: CppCodeSources, summary: ProcessingSummary, maxSize: number | undefined, maxGzipSize: number | undefined) => string;
|
|
17
|
+
export type PreviousManifestFile = {
|
|
18
|
+
path: string;
|
|
19
|
+
size: number;
|
|
20
|
+
sha256?: string;
|
|
21
|
+
};
|
|
22
|
+
export declare class OverBudgetError extends Error {
|
|
23
|
+
readonly name = "OverBudgetError";
|
|
24
|
+
constructor();
|
|
25
|
+
}
|
|
26
|
+
declare const formatChangeSummary: (sources: CppCodeSources, previousFiles: PreviousManifestFile[]) => string;
|
|
27
|
+
export declare function runPipeline(options: ICopyFilesArguments): void;
|
|
28
|
+
export { calculateCompressionRatio, createSourceEntry, formatAnalyzeTable, formatChangeSummary, formatCompressionLog, formatDryRunRoutes, formatSize, formatSizePrecise, shouldUseGzip, updateExtensionGroup };
|
|
29
|
+
//# sourceMappingURL=pipeline.d.ts.map
|
package/dist/pipeline.js
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.updateExtensionGroup = exports.shouldUseGzip = exports.formatSizePrecise = exports.formatSize = exports.formatDryRunRoutes = exports.formatCompressionLog = exports.formatChangeSummary = exports.formatAnalyzeTable = exports.createSourceEntry = exports.calculateCompressionRatio = exports.OverBudgetError = void 0;
|
|
7
|
+
exports.runPipeline = runPipeline;
|
|
8
|
+
const node_fs_1 = require("node:fs");
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
+
const node_zlib_1 = require("node:zlib");
|
|
11
|
+
const mime_types_1 = require("mime-types");
|
|
12
|
+
const consoleColor_1 = require("./consoleColor");
|
|
13
|
+
const cppCode_1 = require("./cppCode");
|
|
14
|
+
const errorMessages_1 = require("./errorMessages");
|
|
15
|
+
const file_1 = require("./file");
|
|
16
|
+
const GZIP_MIN_SIZE = 1024;
|
|
17
|
+
const GZIP_MIN_REDUCTION_RATIO = 0.85;
|
|
18
|
+
const shouldUseGzip = (originalSize, compressedSize) => originalSize > GZIP_MIN_SIZE && compressedSize < originalSize * GZIP_MIN_REDUCTION_RATIO;
|
|
19
|
+
exports.shouldUseGzip = shouldUseGzip;
|
|
20
|
+
const calculateCompressionRatio = (originalSize, compressedSize) => Math.round((compressedSize / originalSize) * 100);
|
|
21
|
+
exports.calculateCompressionRatio = calculateCompressionRatio;
|
|
22
|
+
const formatCompressionLog = (filename, padding, originalSize, compressedSize, useGzip) => {
|
|
23
|
+
const ratio = calculateCompressionRatio(originalSize, compressedSize);
|
|
24
|
+
const sizeInfo = `(${originalSize} -> ${compressedSize} = ${ratio}%)`;
|
|
25
|
+
if (useGzip)
|
|
26
|
+
return (0, consoleColor_1.greenLog)(` [${filename}] ${padding} ✓ gzip used ${sizeInfo}`);
|
|
27
|
+
const tooSmall = originalSize <= GZIP_MIN_SIZE ? '(too small) ' : '';
|
|
28
|
+
return (0, consoleColor_1.yellowLog)(` [${filename}] ${padding} x gzip unused ${tooSmall}${sizeInfo}`);
|
|
29
|
+
};
|
|
30
|
+
exports.formatCompressionLog = formatCompressionLog;
|
|
31
|
+
const formatSize = (bytes) => {
|
|
32
|
+
if (bytes < 1024)
|
|
33
|
+
return `${bytes}B`;
|
|
34
|
+
return `${Math.round(bytes / 1024)}kB`;
|
|
35
|
+
};
|
|
36
|
+
exports.formatSize = formatSize;
|
|
37
|
+
const formatSizePrecise = (bytes) => {
|
|
38
|
+
if (bytes < 1024)
|
|
39
|
+
return `${bytes}B`;
|
|
40
|
+
return `${(bytes / 1024).toFixed(1)}kB`;
|
|
41
|
+
};
|
|
42
|
+
exports.formatSizePrecise = formatSizePrecise;
|
|
43
|
+
const createSourceEntry = (filename, dataname, content, contentGzip, mimeType, sha256, isGzip) => ({
|
|
44
|
+
filename,
|
|
45
|
+
dataname,
|
|
46
|
+
datanameUpperCase: dataname.toUpperCase(),
|
|
47
|
+
content,
|
|
48
|
+
contentGzip: isGzip ? contentGzip : content,
|
|
49
|
+
isGzip,
|
|
50
|
+
mime: mimeType,
|
|
51
|
+
sha256
|
|
52
|
+
});
|
|
53
|
+
exports.createSourceEntry = createSourceEntry;
|
|
54
|
+
const updateExtensionGroup = (filesByExtension, extension) => {
|
|
55
|
+
const group = filesByExtension.find((fe) => fe.extension === extension);
|
|
56
|
+
if (group)
|
|
57
|
+
group.count += 1;
|
|
58
|
+
else
|
|
59
|
+
filesByExtension.push({ extension, count: 1 });
|
|
60
|
+
};
|
|
61
|
+
exports.updateExtensionGroup = updateExtensionGroup;
|
|
62
|
+
const sizeCellFor = (s) => {
|
|
63
|
+
const orig = formatSize(s.content.length);
|
|
64
|
+
if (s.isGzip)
|
|
65
|
+
return `${orig} → ${formatSize(s.contentGzip.length)}`;
|
|
66
|
+
return orig;
|
|
67
|
+
};
|
|
68
|
+
const formatDryRunRoutes = (sources, engine, basePath, spa) => {
|
|
69
|
+
if (sources.length === 0)
|
|
70
|
+
return ' (no files)';
|
|
71
|
+
const defaultSource = sources.find((s) => s.filename === 'index.html' || s.filename === 'index.htm');
|
|
72
|
+
const rows = [];
|
|
73
|
+
if (defaultSource)
|
|
74
|
+
rows.push({
|
|
75
|
+
url: basePath || '/',
|
|
76
|
+
mime: defaultSource.mime,
|
|
77
|
+
sizeCell: sizeCellFor(defaultSource),
|
|
78
|
+
tag: '[default]'
|
|
79
|
+
});
|
|
80
|
+
for (const source of sources)
|
|
81
|
+
rows.push({
|
|
82
|
+
url: `${basePath}/${source.filename}`,
|
|
83
|
+
mime: source.mime,
|
|
84
|
+
sizeCell: sizeCellFor(source),
|
|
85
|
+
tag: source.isGzip ? '' : '[no gzip]'
|
|
86
|
+
});
|
|
87
|
+
if (spa && defaultSource) {
|
|
88
|
+
const spaUrl = engine === 'psychic' && basePath ? `${basePath}/*` : '(SPA catch-all)';
|
|
89
|
+
rows.push({ url: spaUrl, mime: defaultSource.mime, sizeCell: '', tag: '[SPA catch-all → index.html]' });
|
|
90
|
+
}
|
|
91
|
+
const urlWidth = Math.max(...rows.map((r) => r.url.length));
|
|
92
|
+
const mimeWidth = Math.max(...rows.map((r) => r.mime.length));
|
|
93
|
+
const sizeWidth = Math.max(...rows.map((r) => r.sizeCell.length));
|
|
94
|
+
return rows
|
|
95
|
+
.map((r) => {
|
|
96
|
+
const tagPart = r.tag ? ` ${r.tag}` : '';
|
|
97
|
+
return ` GET ${r.url.padEnd(urlWidth)} ${r.mime.padEnd(mimeWidth)} ${r.sizeCell.padEnd(sizeWidth)}${tagPart}`.trimEnd();
|
|
98
|
+
})
|
|
99
|
+
.join('\n');
|
|
100
|
+
};
|
|
101
|
+
exports.formatDryRunRoutes = formatDryRunRoutes;
|
|
102
|
+
const formatAnalyzeTable = (sources, summary, maxSize, maxGzipSize) => {
|
|
103
|
+
const rows = sources.map((s) => ({
|
|
104
|
+
file: s.filename,
|
|
105
|
+
orig: formatSizePrecise(s.content.length),
|
|
106
|
+
gzip: formatSizePrecise(s.isGzip ? s.contentGzip.length : s.content.length),
|
|
107
|
+
tag: s.isGzip ? '' : '[no gzip]'
|
|
108
|
+
}));
|
|
109
|
+
const fileWidth = Math.max(4, ...rows.map((r) => r.file.length), 'Total'.length);
|
|
110
|
+
const origWidth = Math.max(8, ...rows.map((r) => r.orig.length), formatSizePrecise(summary.size).length);
|
|
111
|
+
const gzipWidth = Math.max(8, ...rows.map((r) => r.gzip.length), formatSizePrecise(summary.gzipsize).length);
|
|
112
|
+
const separator = `${'─'.repeat(fileWidth)} ${'─'.repeat(origWidth)} ${'─'.repeat(gzipWidth)}`;
|
|
113
|
+
const header = `${'File'.padEnd(fileWidth)} ${'Original'.padEnd(origWidth)} ${'Gzip'.padEnd(gzipWidth)}`;
|
|
114
|
+
const dataRows = rows.map((r) => {
|
|
115
|
+
const tagPart = r.tag ? ` ${r.tag}` : '';
|
|
116
|
+
return `${r.file.padEnd(fileWidth)} ${r.orig.padEnd(origWidth)} ${r.gzip.padEnd(gzipWidth)}${tagPart}`.trimEnd();
|
|
117
|
+
});
|
|
118
|
+
const totalOrig = formatSizePrecise(summary.size);
|
|
119
|
+
const totalGzip = formatSizePrecise(summary.gzipsize);
|
|
120
|
+
const totalRow = `${'Total'.padEnd(fileWidth)} ${totalOrig.padEnd(origWidth)} ${totalGzip.padEnd(gzipWidth)}`;
|
|
121
|
+
const lines = [header, separator, ...dataRows, separator, totalRow];
|
|
122
|
+
if (maxSize !== undefined) {
|
|
123
|
+
const pass = summary.size <= maxSize;
|
|
124
|
+
const budgetRow = `${'Budget (maxsize)'.padEnd(fileWidth)} ${formatSizePrecise(maxSize).padEnd(origWidth)} ${'-'.padEnd(gzipWidth)} ${pass ? '✓ PASS' : '✗ FAIL'}`;
|
|
125
|
+
lines.push(budgetRow);
|
|
126
|
+
}
|
|
127
|
+
if (maxGzipSize !== undefined) {
|
|
128
|
+
const pass = summary.gzipsize <= maxGzipSize;
|
|
129
|
+
const budgetRow = `${'Budget (maxgzipsize)'.padEnd(fileWidth)} ${'-'.padEnd(origWidth)} ${formatSizePrecise(maxGzipSize).padEnd(gzipWidth)} ${pass ? '✓ PASS' : '✗ FAIL'}`;
|
|
130
|
+
lines.push(budgetRow);
|
|
131
|
+
}
|
|
132
|
+
return lines.join('\n');
|
|
133
|
+
};
|
|
134
|
+
exports.formatAnalyzeTable = formatAnalyzeTable;
|
|
135
|
+
class OverBudgetError extends Error {
|
|
136
|
+
name = 'OverBudgetError';
|
|
137
|
+
constructor() {
|
|
138
|
+
super('Over budget in analyze mode');
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
exports.OverBudgetError = OverBudgetError;
|
|
142
|
+
const formatChangeSummary = (sources, previousFiles) => {
|
|
143
|
+
const previousMap = new Map(previousFiles.map((f) => [f.path, f]));
|
|
144
|
+
const currentMap = new Map(sources.map((s) => [s.filename, s]));
|
|
145
|
+
const added = [];
|
|
146
|
+
const removed = [];
|
|
147
|
+
const modified = [];
|
|
148
|
+
for (const source of sources) {
|
|
149
|
+
const previous = previousMap.get(source.filename);
|
|
150
|
+
if (!previous)
|
|
151
|
+
added.push(source);
|
|
152
|
+
else if (previous.sha256 ? previous.sha256 !== source.sha256 : previous.size !== source.content.length)
|
|
153
|
+
modified.push({ source, previousSize: previous.size });
|
|
154
|
+
}
|
|
155
|
+
for (const previous of previousFiles)
|
|
156
|
+
if (!currentMap.has(previous.path))
|
|
157
|
+
removed.push(previous);
|
|
158
|
+
if (added.length === 0 && removed.length === 0 && modified.length === 0)
|
|
159
|
+
return 'Change summary: (no changes)';
|
|
160
|
+
const allNames = [
|
|
161
|
+
...added.map((s) => s.filename),
|
|
162
|
+
...removed.map((f) => f.path),
|
|
163
|
+
...modified.map((m) => m.source.filename)
|
|
164
|
+
];
|
|
165
|
+
const nameWidth = Math.max(...allNames.map((n) => n.length));
|
|
166
|
+
const lines = ['Change summary:'];
|
|
167
|
+
for (const source of added)
|
|
168
|
+
lines.push((0, consoleColor_1.greenLog)(` + ${source.filename.padEnd(nameWidth)} ${formatSizePrecise(source.content.length)}`));
|
|
169
|
+
for (const { source, previousSize } of modified)
|
|
170
|
+
lines.push((0, consoleColor_1.yellowLog)(` ~ ${source.filename.padEnd(nameWidth)} ${formatSizePrecise(previousSize)} → ${formatSizePrecise(source.content.length)}`));
|
|
171
|
+
for (const previous of removed)
|
|
172
|
+
lines.push((0, consoleColor_1.redLog)(` - ${previous.path}`));
|
|
173
|
+
return lines.join('\n');
|
|
174
|
+
};
|
|
175
|
+
exports.formatChangeSummary = formatChangeSummary;
|
|
176
|
+
function runPipeline(options) {
|
|
177
|
+
const summary = {
|
|
178
|
+
filecount: 0,
|
|
179
|
+
size: 0,
|
|
180
|
+
gzipsize: 0
|
|
181
|
+
};
|
|
182
|
+
const sources = [];
|
|
183
|
+
const filesByExtension = [];
|
|
184
|
+
console.log('Collecting source files');
|
|
185
|
+
const files = (0, file_1.getFiles)(options);
|
|
186
|
+
if (files.size === 0)
|
|
187
|
+
throw new Error(`Directory ${options.sourcepath} is empty`);
|
|
188
|
+
if (options.spa && ![...files.keys()].some((f) => f === 'index.html' || f === 'index.htm'))
|
|
189
|
+
console.warn((0, consoleColor_1.yellowLog)('[SvelteESP32] Warning: --spa is set but no index.html/index.htm found; catch-all will not be generated.'));
|
|
190
|
+
console.log();
|
|
191
|
+
console.log('Translation to header file');
|
|
192
|
+
const longestFilename = [...files.keys()].reduce((p, c) => Math.max(c.length, p), 0);
|
|
193
|
+
for (const [originalFilename, fileData] of files) {
|
|
194
|
+
const { content, hash: sha256 } = fileData;
|
|
195
|
+
const rawMime = (0, mime_types_1.lookup)(originalFilename);
|
|
196
|
+
if (!rawMime)
|
|
197
|
+
console.log((0, consoleColor_1.yellowLog)(` [${originalFilename}] unknown MIME type for extension '${node_path_1.default.extname(originalFilename)}', using text/plain`));
|
|
198
|
+
const mimeType = rawMime || 'text/plain';
|
|
199
|
+
summary.filecount++;
|
|
200
|
+
const filename = originalFilename.replace(/\\/g, '/');
|
|
201
|
+
let dataname = filename.replace(/\W/g, '_');
|
|
202
|
+
if (/^\d/.test(dataname))
|
|
203
|
+
dataname = '_' + dataname;
|
|
204
|
+
let extension = node_path_1.default.extname(filename).toUpperCase();
|
|
205
|
+
if (extension.startsWith('.'))
|
|
206
|
+
extension = extension.slice(1);
|
|
207
|
+
updateExtensionGroup(filesByExtension, extension);
|
|
208
|
+
summary.size += content.length;
|
|
209
|
+
const zipContent = (0, node_zlib_1.gzipSync)(content, { level: 9 });
|
|
210
|
+
const useGzip = shouldUseGzip(content.length, zipContent.length);
|
|
211
|
+
summary.gzipsize += useGzip ? zipContent.length : content.length;
|
|
212
|
+
sources.push(createSourceEntry(filename, dataname, content, zipContent, mimeType, sha256, useGzip));
|
|
213
|
+
const padding = ' '.repeat(longestFilename - originalFilename.length);
|
|
214
|
+
console.log(formatCompressionLog(originalFilename, padding, content.length, zipContent.length, useGzip));
|
|
215
|
+
}
|
|
216
|
+
console.log('');
|
|
217
|
+
filesByExtension.sort((left, right) => left.extension.localeCompare(right.extension));
|
|
218
|
+
if (options.analyze) {
|
|
219
|
+
console.log(formatAnalyzeTable(sources, summary, options.maxSize, options.maxGzipSize));
|
|
220
|
+
const overBudget = (options.maxSize !== undefined && summary.size > options.maxSize) ||
|
|
221
|
+
(options.maxGzipSize !== undefined && summary.gzipsize > options.maxGzipSize);
|
|
222
|
+
if (overBudget)
|
|
223
|
+
throw new OverBudgetError();
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
if (options.maxSize !== undefined && summary.size > options.maxSize)
|
|
227
|
+
throw new Error((0, errorMessages_1.getSizeBudgetExceededError)('size', options.maxSize, summary.size));
|
|
228
|
+
if (options.maxGzipSize !== undefined && summary.gzipsize > options.maxGzipSize)
|
|
229
|
+
throw new Error((0, errorMessages_1.getSizeBudgetExceededError)('gzipSize', options.maxGzipSize, summary.gzipsize));
|
|
230
|
+
if (options.dryRun) {
|
|
231
|
+
const baseLabel = options.basePath || '(none)';
|
|
232
|
+
const spaLabel = options.spa ? 'yes' : 'no';
|
|
233
|
+
console.log(`[DRY RUN] Engine: ${options.engine} | ETag: ${options.etag} | Gzip: ${options.gzip} | Base: ${baseLabel} | SPA: ${spaLabel}`);
|
|
234
|
+
console.log(`[DRY RUN] ${summary.filecount} files, ${formatSize(summary.size)} → ${formatSize(summary.gzipsize)} gzip | would write to ${options.outputfile}`);
|
|
235
|
+
console.log('');
|
|
236
|
+
console.log('[DRY RUN] Routes:');
|
|
237
|
+
console.log(formatDryRunRoutes(sources, options.engine, options.basePath, options.spa ?? false));
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
const cppFile = (0, cppCode_1.getCppCode)(sources, filesByExtension);
|
|
241
|
+
(0, node_fs_1.mkdirSync)(node_path_1.default.normalize(node_path_1.default.dirname(options.outputfile)), { recursive: true });
|
|
242
|
+
(0, node_fs_1.writeFileSync)(options.outputfile, cppFile, { flush: true, encoding: 'utf8' });
|
|
243
|
+
console.log(`${summary.filecount} files, ${formatSize(summary.size)} original size, ${formatSize(summary.gzipsize)} gzip size`);
|
|
244
|
+
console.log(`${options.outputfile} ${formatSize(cppFile.length)} size`);
|
|
245
|
+
if (options.manifest) {
|
|
246
|
+
const manifestPath = node_path_1.default.join(node_path_1.default.dirname(options.outputfile), node_path_1.default.basename(options.outputfile, node_path_1.default.extname(options.outputfile)) + '.manifest.json');
|
|
247
|
+
let previousManifest;
|
|
248
|
+
if ((0, node_fs_1.existsSync)(manifestPath))
|
|
249
|
+
try {
|
|
250
|
+
previousManifest = JSON.parse((0, node_fs_1.readFileSync)(manifestPath, 'utf8'));
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
}
|
|
254
|
+
const manifest = {
|
|
255
|
+
generated: new Date().toISOString(),
|
|
256
|
+
engine: options.engine,
|
|
257
|
+
etag: options.etag,
|
|
258
|
+
gzip: options.gzip,
|
|
259
|
+
filecount: summary.filecount,
|
|
260
|
+
size: summary.size,
|
|
261
|
+
gzipSize: summary.gzipsize,
|
|
262
|
+
files: sources.map((s) => ({
|
|
263
|
+
path: s.filename,
|
|
264
|
+
mime: s.mime,
|
|
265
|
+
size: s.content.length,
|
|
266
|
+
gzipSize: s.isGzip ? s.contentGzip.length : s.content.length,
|
|
267
|
+
isGzip: s.isGzip,
|
|
268
|
+
sha256: s.sha256
|
|
269
|
+
}))
|
|
270
|
+
};
|
|
271
|
+
(0, node_fs_1.writeFileSync)(manifestPath, JSON.stringify(manifest, undefined, 2), { encoding: 'utf8' });
|
|
272
|
+
console.log(`${manifestPath} manifest written`);
|
|
273
|
+
if (previousManifest)
|
|
274
|
+
console.log(formatChangeSummary(sources, previousManifest.files));
|
|
275
|
+
}
|
|
276
|
+
if (options.engine === 'psychic' || options.engine === 'espidf')
|
|
277
|
+
console.log('\n' + (0, errorMessages_1.getMaxUriHandlersHint)(options.engine, sources.length, options.espmethod));
|
|
278
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
interface ResolvedViteConfig {
|
|
2
|
+
build: {
|
|
3
|
+
outDir: string;
|
|
4
|
+
};
|
|
5
|
+
}
|
|
6
|
+
interface VitePlugin {
|
|
7
|
+
name: string;
|
|
8
|
+
configResolved: (config: ResolvedViteConfig) => void;
|
|
9
|
+
closeBundle: () => void;
|
|
10
|
+
}
|
|
11
|
+
export interface SvelteESP32PluginOptions {
|
|
12
|
+
output: string;
|
|
13
|
+
sourcepath?: string;
|
|
14
|
+
engine?: 'psychic' | 'async' | 'espidf' | 'webserver';
|
|
15
|
+
etag?: 'always' | 'never' | 'compiler';
|
|
16
|
+
gzip?: 'always' | 'never' | 'compiler';
|
|
17
|
+
cachetime?: number;
|
|
18
|
+
cachetimeHtml?: number;
|
|
19
|
+
cachetimeAssets?: number;
|
|
20
|
+
exclude?: string[];
|
|
21
|
+
basepath?: string;
|
|
22
|
+
espmethod?: string;
|
|
23
|
+
define?: string;
|
|
24
|
+
version?: string;
|
|
25
|
+
created?: boolean;
|
|
26
|
+
spa?: boolean;
|
|
27
|
+
manifest?: boolean;
|
|
28
|
+
noIndexCheck?: boolean;
|
|
29
|
+
maxSize?: number;
|
|
30
|
+
maxGzipSize?: number;
|
|
31
|
+
}
|
|
32
|
+
export declare function svelteESP32(options: SvelteESP32PluginOptions): VitePlugin;
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=vitePlugin.d.ts.map
|