svelteesp32 1.12.1 → 1.13.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 +85 -0
- package/dist/commandLine.d.ts +17 -1
- package/dist/commandLine.js +93 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,6 +12,8 @@ In order to be able to easily update OTA, it is important - from the users' poin
|
|
|
12
12
|
|
|
13
13
|
This npm package provides a solution for **inserting any JS client application into the ESP web server** (PsychicHttp and also ESPAsyncWebServer (https://github.com/ESP32Async/ESPAsyncWebServer) and ESP-IDF available, PsychicHttp is the default). For this, JS, html, css, font, assets, etc. files must be converted to binary byte array. Npm mode is easy to use and easy to **integrate into your CI/CD pipeline**.
|
|
14
14
|
|
|
15
|
+
> Starting with version v1.13.0, RC files support npm package variable interpolation
|
|
16
|
+
|
|
15
17
|
> Starting with version v1.12.0, you can use RC file for configuration
|
|
16
18
|
|
|
17
19
|
> Starting with version v1.11.0, you can exclude files by pattern
|
|
@@ -540,6 +542,89 @@ To keep defaults, explicitly list them in your RC file:
|
|
|
540
542
|
}
|
|
541
543
|
```
|
|
542
544
|
|
|
545
|
+
#### NPM Package Variable Interpolation
|
|
546
|
+
|
|
547
|
+
RC files support automatic variable interpolation from your `package.json`. This allows you to reference package.json fields in your RC configuration using npm-style variable syntax.
|
|
548
|
+
|
|
549
|
+
**Syntax:** `$npm_package_<field_name>`
|
|
550
|
+
|
|
551
|
+
**Supported in:** All string fields (`version`, `define`, `sourcepath`, `outputfile`, `espmethod`, `exclude` patterns)
|
|
552
|
+
|
|
553
|
+
**Example:**
|
|
554
|
+
|
|
555
|
+
```json
|
|
556
|
+
// .svelteesp32rc.json
|
|
557
|
+
{
|
|
558
|
+
"engine": "psychic",
|
|
559
|
+
"version": "v$npm_package_version",
|
|
560
|
+
"define": "$npm_package_name",
|
|
561
|
+
"sourcepath": "./dist",
|
|
562
|
+
"outputfile": "./output.h"
|
|
563
|
+
}
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
With `package.json` containing:
|
|
567
|
+
|
|
568
|
+
```json
|
|
569
|
+
{
|
|
570
|
+
"name": "my-esp32-app",
|
|
571
|
+
"version": "2.1.0"
|
|
572
|
+
}
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
The variables are automatically interpolated to:
|
|
576
|
+
|
|
577
|
+
```json
|
|
578
|
+
{
|
|
579
|
+
"version": "v2.1.0",
|
|
580
|
+
"define": "my_esp32_app"
|
|
581
|
+
}
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
**Nested Fields:**
|
|
585
|
+
|
|
586
|
+
You can access nested package.json fields using underscores:
|
|
587
|
+
|
|
588
|
+
```json
|
|
589
|
+
// package.json
|
|
590
|
+
{
|
|
591
|
+
"name": "myapp",
|
|
592
|
+
"repository": {
|
|
593
|
+
"type": "git",
|
|
594
|
+
"url": "https://github.com/user/repo.git"
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
// .svelteesp32rc.json
|
|
599
|
+
{
|
|
600
|
+
"version": "$npm_package_repository_type"
|
|
601
|
+
}
|
|
602
|
+
// Results in: "version": "git"
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
**Multiple Variables:**
|
|
606
|
+
|
|
607
|
+
Combine multiple variables in a single field:
|
|
608
|
+
|
|
609
|
+
```json
|
|
610
|
+
{
|
|
611
|
+
"version": "$npm_package_name-v$npm_package_version-release"
|
|
612
|
+
}
|
|
613
|
+
// Results in: "my-esp32-app-v2.1.0-release"
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
**Requirements:**
|
|
617
|
+
|
|
618
|
+
- `package.json` must exist in the same directory as the RC file
|
|
619
|
+
- If variables are used but `package.json` is not found, an error is thrown with details about which fields contain variables
|
|
620
|
+
- Unknown variables are left unchanged (e.g., `$npm_package_nonexistent` stays as-is)
|
|
621
|
+
|
|
622
|
+
**Use Cases:**
|
|
623
|
+
|
|
624
|
+
- **Version Synchronization:** Keep header version in sync with npm package version
|
|
625
|
+
- **Dynamic Naming:** Use package name for C++ defines automatically
|
|
626
|
+
- **CI/CD Integration:** Reusable RC files across projects with different package names
|
|
627
|
+
|
|
543
628
|
### Q&A
|
|
544
629
|
|
|
545
630
|
- **How big a frontend application can be placed?** If you compress the content with gzip, even a 3-4Mb assets directory can be placed. This is a serious enough amount to serve a complete application.
|
package/dist/commandLine.d.ts
CHANGED
|
@@ -12,6 +12,22 @@ interface ICopyFilesArguments {
|
|
|
12
12
|
exclude: string[];
|
|
13
13
|
help?: boolean;
|
|
14
14
|
}
|
|
15
|
+
interface IRcFileConfig {
|
|
16
|
+
engine?: 'psychic' | 'psychic2' | 'async' | 'espidf';
|
|
17
|
+
sourcepath?: string;
|
|
18
|
+
outputfile?: string;
|
|
19
|
+
espmethod?: string;
|
|
20
|
+
define?: string;
|
|
21
|
+
gzip?: 'true' | 'false' | 'compiler';
|
|
22
|
+
etag?: 'true' | 'false' | 'compiler';
|
|
23
|
+
cachetime?: number;
|
|
24
|
+
created?: boolean;
|
|
25
|
+
version?: string;
|
|
26
|
+
exclude?: string[];
|
|
27
|
+
}
|
|
28
|
+
declare function getNpmPackageVariable(packageJson: Record<string, unknown>, variableName: string): string | undefined;
|
|
29
|
+
declare function hasNpmVariables(config: IRcFileConfig): boolean;
|
|
30
|
+
declare function interpolateNpmVariables(config: IRcFileConfig, rcFilePath: string): IRcFileConfig;
|
|
31
|
+
export { getNpmPackageVariable, hasNpmVariables, interpolateNpmVariables };
|
|
15
32
|
export declare function formatConfiguration(cmdLine: ICopyFilesArguments): string;
|
|
16
33
|
export declare const cmdLine: ICopyFilesArguments;
|
|
17
|
-
export {};
|
package/dist/commandLine.js
CHANGED
|
@@ -4,6 +4,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.cmdLine = void 0;
|
|
7
|
+
exports.getNpmPackageVariable = getNpmPackageVariable;
|
|
8
|
+
exports.hasNpmVariables = hasNpmVariables;
|
|
9
|
+
exports.interpolateNpmVariables = interpolateNpmVariables;
|
|
7
10
|
exports.formatConfiguration = formatConfiguration;
|
|
8
11
|
const node_fs_1 = require("node:fs");
|
|
9
12
|
const node_os_1 = require("node:os");
|
|
@@ -90,11 +93,100 @@ function findRcFile(customConfigPath) {
|
|
|
90
93
|
}
|
|
91
94
|
return undefined;
|
|
92
95
|
}
|
|
96
|
+
function findPackageJson(rcFilePath) {
|
|
97
|
+
const rcDirectory = node_path_1.default.dirname(rcFilePath);
|
|
98
|
+
const packageJsonPath = node_path_1.default.join(rcDirectory, 'package.json');
|
|
99
|
+
return (0, node_fs_1.existsSync)(packageJsonPath) ? packageJsonPath : undefined;
|
|
100
|
+
}
|
|
101
|
+
function parsePackageJson(packageJsonPath) {
|
|
102
|
+
try {
|
|
103
|
+
const content = (0, node_fs_1.readFileSync)(packageJsonPath, 'utf8');
|
|
104
|
+
return JSON.parse(content);
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
throw new Error(`Failed to parse package.json at ${packageJsonPath}: ${error.message}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function getNpmPackageVariable(packageJson, variableName) {
|
|
111
|
+
const prefix = '$npm_package_';
|
|
112
|
+
if (!variableName.startsWith(prefix))
|
|
113
|
+
return undefined;
|
|
114
|
+
const pathString = variableName.slice(prefix.length);
|
|
115
|
+
const pathSegments = pathString.split('_');
|
|
116
|
+
let current = packageJson;
|
|
117
|
+
for (const segment of pathSegments) {
|
|
118
|
+
if (current === null || current === undefined)
|
|
119
|
+
return undefined;
|
|
120
|
+
if (typeof current !== 'object')
|
|
121
|
+
return undefined;
|
|
122
|
+
current = current[segment];
|
|
123
|
+
}
|
|
124
|
+
if (current === null || current === undefined)
|
|
125
|
+
return undefined;
|
|
126
|
+
return String(current);
|
|
127
|
+
}
|
|
128
|
+
function checkStringForNpmVariable(value) {
|
|
129
|
+
return value?.includes('$npm_package_') ?? false;
|
|
130
|
+
}
|
|
131
|
+
function hasNpmVariables(config) {
|
|
132
|
+
return (checkStringForNpmVariable(config.sourcepath) ||
|
|
133
|
+
checkStringForNpmVariable(config.outputfile) ||
|
|
134
|
+
checkStringForNpmVariable(config.espmethod) ||
|
|
135
|
+
checkStringForNpmVariable(config.define) ||
|
|
136
|
+
checkStringForNpmVariable(config.version) ||
|
|
137
|
+
(Array.isArray(config.exclude) && config.exclude.some((pattern) => checkStringForNpmVariable(pattern))) ||
|
|
138
|
+
false);
|
|
139
|
+
}
|
|
140
|
+
function interpolateNpmVariables(config, rcFilePath) {
|
|
141
|
+
if (!hasNpmVariables(config))
|
|
142
|
+
return config;
|
|
143
|
+
const packageJsonPath = findPackageJson(rcFilePath);
|
|
144
|
+
if (!packageJsonPath) {
|
|
145
|
+
const affectedFields = [];
|
|
146
|
+
if (config.sourcepath?.includes('$npm_package_'))
|
|
147
|
+
affectedFields.push('sourcepath');
|
|
148
|
+
if (config.outputfile?.includes('$npm_package_'))
|
|
149
|
+
affectedFields.push('outputfile');
|
|
150
|
+
if (config.version?.includes('$npm_package_'))
|
|
151
|
+
affectedFields.push('version');
|
|
152
|
+
if (config.espmethod?.includes('$npm_package_'))
|
|
153
|
+
affectedFields.push('espmethod');
|
|
154
|
+
if (config.define?.includes('$npm_package_'))
|
|
155
|
+
affectedFields.push('define');
|
|
156
|
+
if (config.exclude)
|
|
157
|
+
for (const [index, pattern] of config.exclude.entries())
|
|
158
|
+
if (pattern.includes('$npm_package_'))
|
|
159
|
+
affectedFields.push(`exclude[${index}]`);
|
|
160
|
+
throw new Error(`RC file uses npm package variables but package.json not found in ${node_path_1.default.dirname(rcFilePath)}\n` +
|
|
161
|
+
`Variables found in fields: ${affectedFields.join(', ')}\n` +
|
|
162
|
+
`Please ensure package.json exists in the same directory as your RC file.`);
|
|
163
|
+
}
|
|
164
|
+
const packageJson = parsePackageJson(packageJsonPath);
|
|
165
|
+
const interpolateString = (value) => {
|
|
166
|
+
const regex = /\$npm_package_[\dA-Za-z]+(?:_[a-z][\dA-Za-z]*)*/g;
|
|
167
|
+
return value.replace(regex, (match) => getNpmPackageVariable(packageJson, match) ?? match);
|
|
168
|
+
};
|
|
169
|
+
const result = { ...config };
|
|
170
|
+
if (result.sourcepath)
|
|
171
|
+
result.sourcepath = interpolateString(result.sourcepath);
|
|
172
|
+
if (result.outputfile)
|
|
173
|
+
result.outputfile = interpolateString(result.outputfile);
|
|
174
|
+
if (result.espmethod)
|
|
175
|
+
result.espmethod = interpolateString(result.espmethod);
|
|
176
|
+
if (result.define)
|
|
177
|
+
result.define = interpolateString(result.define);
|
|
178
|
+
if (result.version)
|
|
179
|
+
result.version = interpolateString(result.version);
|
|
180
|
+
if (result.exclude)
|
|
181
|
+
result.exclude = result.exclude.map((pattern) => interpolateString(pattern));
|
|
182
|
+
return result;
|
|
183
|
+
}
|
|
93
184
|
function loadRcFile(rcPath) {
|
|
94
185
|
try {
|
|
95
186
|
const content = (0, node_fs_1.readFileSync)(rcPath, 'utf8');
|
|
96
187
|
const config = JSON.parse(content);
|
|
97
|
-
|
|
188
|
+
const interpolatedConfig = interpolateNpmVariables(config, rcPath);
|
|
189
|
+
return validateRcConfig(interpolatedConfig, rcPath);
|
|
98
190
|
}
|
|
99
191
|
catch (error) {
|
|
100
192
|
if (error instanceof SyntaxError)
|