@aiot-toolkit/aiotpack 2.1.0-prender.7 → 2.1.0-prender.9
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.
|
@@ -13,6 +13,126 @@ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return
|
|
|
13
13
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
14
14
|
// Template.json compilation from parse5 AST
|
|
15
15
|
|
|
16
|
+
// vivo blueos-pack's aggressive camelCase applied to transition-property values.
|
|
17
|
+
// Every letter that follows a non-letter character (separator or digit) is upper-cased,
|
|
18
|
+
// then all non-alphanumeric characters are dropped. This intentionally covers both the
|
|
19
|
+
// simple case (`background-position` → `backgroundPosition`) and the odd shorthand-inside-
|
|
20
|
+
// transition-property form we see in inline styles (`transform-origin 0.2s ease-in-out .5s`
|
|
21
|
+
// → `transformOrigin02SEaseInOut5S`).
|
|
22
|
+
function normalizeTransitionPropertyValue(s) {
|
|
23
|
+
let out = '';
|
|
24
|
+
let capNext = false;
|
|
25
|
+
for (const ch of s) {
|
|
26
|
+
if (/[A-Za-z]/.test(ch)) {
|
|
27
|
+
out += capNext ? ch.toUpperCase() : ch;
|
|
28
|
+
capNext = false;
|
|
29
|
+
} else if (/[0-9]/.test(ch)) {
|
|
30
|
+
out += ch;
|
|
31
|
+
capNext = true;
|
|
32
|
+
} else {
|
|
33
|
+
capNext = true;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return out;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// vivo blueos-pack's inline `animation-timing-function` normalization.
|
|
40
|
+
// Returns:
|
|
41
|
+
// - string → the normalized value to emit
|
|
42
|
+
// - null (drop) → invalid; caller should skip this inline decl so the class-level
|
|
43
|
+
// value (or default) applies
|
|
44
|
+
// Rules (traced empirically from build-vivo/watch-round baseline):
|
|
45
|
+
// - Predefined keywords (`linear`, `ease`, `ease-in`, `ease-out`, `ease-in-out`,
|
|
46
|
+
// `step-start`, `step-end`) → keep as-is
|
|
47
|
+
// - `steps(N)` → normalize to `steps(N, end)` (fill default dir)
|
|
48
|
+
// - `steps(N, start|end)` → keep as-is
|
|
49
|
+
// - `cubic-bezier(a, b, c, d)`
|
|
50
|
+
// * all 4 numeric and x1,x2 ∈ [0,1] → keep (spec-compliant)
|
|
51
|
+
// * otherwise → drop (invalid per vivo validator)
|
|
52
|
+
// - Any other unrecognized function → drop
|
|
53
|
+
function normalizeAnimationTimingFunction(s) {
|
|
54
|
+
const trimmed = s.trim();
|
|
55
|
+
if (['linear', 'ease', 'ease-in', 'ease-out', 'ease-in-out', 'step-start', 'step-end'].includes(trimmed)) return trimmed;
|
|
56
|
+
const stepsMatch = /^steps\s*\(\s*([^,)]+?)\s*(?:,\s*(start|end)\s*)?\)$/.exec(trimmed);
|
|
57
|
+
if (stepsMatch) {
|
|
58
|
+
const n = stepsMatch[1];
|
|
59
|
+
const dir = stepsMatch[2] || 'end';
|
|
60
|
+
return `steps(${n}, ${dir})`;
|
|
61
|
+
}
|
|
62
|
+
const cubicMatch = /^cubic-bezier\s*\(\s*([^)]+)\)$/.exec(trimmed);
|
|
63
|
+
if (cubicMatch) {
|
|
64
|
+
const args = cubicMatch[1].split(',').map(a => a.trim());
|
|
65
|
+
if (args.length !== 4) return null;
|
|
66
|
+
const nums = args.map(a => Number(a));
|
|
67
|
+
if (nums.some(n => !isFinite(n))) return null;
|
|
68
|
+
// spec: x1 and x2 must be in [0, 1]; y1 and y2 unbounded. Reproduce vivo behavior:
|
|
69
|
+
// any component outside [0, 1] is treated as invalid (vivo is stricter than spec).
|
|
70
|
+
if (nums.some(n => n < 0 || n > 1)) return null;
|
|
71
|
+
return `cubic-bezier(${args.join(', ')})`;
|
|
72
|
+
}
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// `transform: translate(40px) scale(0.5) ...` (CSS function-list from inline style="")
|
|
77
|
+
// → `{"translateX":"40px","translateY":"0px","scaleX":0.5,"scaleY":0.5}`.
|
|
78
|
+
// Returns null when input isn't a plain CSS function list (already JSON, dynamic
|
|
79
|
+
// binding, or unknown function), so callers can fall back to the raw string.
|
|
80
|
+
function normalizeCssTransform(input) {
|
|
81
|
+
if (typeof input !== 'string') return null;
|
|
82
|
+
const s = input.trim();
|
|
83
|
+
if (!s || s.startsWith('{') || /\{\{/.test(s)) return null;
|
|
84
|
+
const out = {};
|
|
85
|
+
const funcRe = /(\w+)\s*\(([^)]*)\)/g;
|
|
86
|
+
let matched = false;
|
|
87
|
+
let m;
|
|
88
|
+
const toNum = x => /^-?\d+(?:\.\d+)?$/.test(x) ? Number(x) : x;
|
|
89
|
+
// Add a CSS unit to bare numeric arguments; keep existing unit / percent forms.
|
|
90
|
+
const withUnit = (x, defaultUnit) => {
|
|
91
|
+
if (x === undefined) return '0' + defaultUnit;
|
|
92
|
+
return /^-?\d+(?:\.\d+)?$/.test(x) ? x + defaultUnit : x;
|
|
93
|
+
};
|
|
94
|
+
while ((m = funcRe.exec(s)) !== null) {
|
|
95
|
+
matched = true;
|
|
96
|
+
const fn = m[1];
|
|
97
|
+
const args = m[2].split(',').map(a => a.trim()).filter(Boolean);
|
|
98
|
+
switch (fn) {
|
|
99
|
+
case 'translate':
|
|
100
|
+
out.translateX = withUnit(args[0], 'px');
|
|
101
|
+
out.translateY = withUnit(args[1], 'px');
|
|
102
|
+
break;
|
|
103
|
+
case 'scale':
|
|
104
|
+
{
|
|
105
|
+
const x = args[0] ?? '1';
|
|
106
|
+
out.scaleX = toNum(x);
|
|
107
|
+
out.scaleY = args[1] !== undefined ? toNum(args[1]) : toNum(x);
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
case 'translateX':
|
|
111
|
+
case 'translateY':
|
|
112
|
+
case 'translateZ':
|
|
113
|
+
out[fn] = withUnit(args[0], 'px');
|
|
114
|
+
break;
|
|
115
|
+
case 'scaleX':
|
|
116
|
+
case 'scaleY':
|
|
117
|
+
out[fn] = toNum(args[0] ?? '1');
|
|
118
|
+
break;
|
|
119
|
+
case 'rotate':
|
|
120
|
+
case 'rotateX':
|
|
121
|
+
case 'rotateY':
|
|
122
|
+
case 'rotateZ':
|
|
123
|
+
case 'skew':
|
|
124
|
+
case 'skewX':
|
|
125
|
+
case 'skewY':
|
|
126
|
+
// Only the first arg is meaningful for single-axis rotate/skew; vivo silently
|
|
127
|
+
// discards extras (e.g. `rotate(90deg,120deg)` → `rotate: "90deg"`). We follow suit.
|
|
128
|
+
out[fn] = withUnit(args[0], 'deg');
|
|
129
|
+
break;
|
|
130
|
+
default:
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return matched ? JSON.stringify(out) : null;
|
|
135
|
+
}
|
|
16
136
|
function uxToTemplateJson(templateNode, styleObjectId, styleSheet, importMap, pageDir) {
|
|
17
137
|
const children = templateNode.content?.childNodes || templateNode.childNodes || [];
|
|
18
138
|
const rootEl = children.find(n => n.tagName && n.nodeName !== '#text');
|
|
@@ -485,7 +605,17 @@ function elementToJson(el, styleSheet, importMap, scopeVars, pageDir) {
|
|
|
485
605
|
hasDynamicInlineStyle = true;
|
|
486
606
|
} else {
|
|
487
607
|
// Static value — accumulate to staticInlineStyle for merging into node.style later
|
|
488
|
-
|
|
608
|
+
if (key === 'transform') {
|
|
609
|
+
staticInlineStyle[key] = normalizeCssTransform(propVal) ?? propVal;
|
|
610
|
+
} else if (key === 'transitionProperty') {
|
|
611
|
+
staticInlineStyle[key] = normalizeTransitionPropertyValue(propVal);
|
|
612
|
+
} else if (key === 'animationTimingFunction' || key === 'transitionTimingFunction') {
|
|
613
|
+
const normalized = normalizeAnimationTimingFunction(propVal);
|
|
614
|
+
if (normalized !== null) staticInlineStyle[key] = normalized;
|
|
615
|
+
// else drop — invalid inline value; class-level rule (or default) applies
|
|
616
|
+
} else {
|
|
617
|
+
staticInlineStyle[key] = propVal;
|
|
618
|
+
}
|
|
489
619
|
}
|
|
490
620
|
}
|
|
491
621
|
});
|
|
@@ -581,28 +711,45 @@ function elementToJson(el, styleSheet, importMap, scopeVars, pageDir) {
|
|
|
581
711
|
hasBind = true;
|
|
582
712
|
hasDynClass = true;
|
|
583
713
|
}
|
|
584
|
-
if (
|
|
585
|
-
node.bind = 3;
|
|
586
|
-
node['import'] = importMap[el.tagName];
|
|
587
|
-
} else if (node['$shown'] !== undefined || node['$repeat'] || node['repeat']?.['$exp']) {
|
|
714
|
+
if (node['$shown'] !== undefined || node['$repeat'] !== undefined || node['repeat']?.['$exp']) {
|
|
588
715
|
node.bind = 2;
|
|
716
|
+
} else if (isComponent) {
|
|
717
|
+
node.bind = 3;
|
|
589
718
|
} else if (hasBind) {
|
|
590
719
|
node.bind = 1;
|
|
591
720
|
}
|
|
721
|
+
if (isComponent) {
|
|
722
|
+
node['import'] = importMap[el.tagName];
|
|
723
|
+
}
|
|
592
724
|
if (!hasDynClass && className) {
|
|
593
725
|
node.class = className;
|
|
594
726
|
}
|
|
595
727
|
if (Object.keys(events).length) node.events = events;
|
|
596
|
-
// Inline style from styleSheet (class selector + tag selector) + static portion of style="..."
|
|
597
728
|
// Inline style from styleSheet (class selector + tag selector) + static portion of style="...".
|
|
598
|
-
//
|
|
729
|
+
// - Static class only: merge tag + class rules + staticInlineStyle → node.style
|
|
730
|
+
// - Dynamic class (partly {{}}): vivo emits merged tag + STATIC class rules into
|
|
731
|
+
// node.inlineStyle (alongside per-key $foo bindings),
|
|
732
|
+
// so the runtime still applies them even though the
|
|
733
|
+
// class list is only known at runtime.
|
|
734
|
+
// - Fully dynamic (only {{...}}): no static class tokens → tag rules only, still into
|
|
735
|
+
// inlineStyle.
|
|
736
|
+
// @media rules are applied at runtime by SDK, not inlined here.
|
|
599
737
|
// Class rules apply in stylesheet declaration order (later declarations override earlier),
|
|
600
738
|
// NOT in class-attribute order.
|
|
601
739
|
if (styleSheet) {
|
|
602
740
|
const merged = {};
|
|
603
741
|
if (styleSheet[el.tagName]) Object.assign(merged, styleSheet[el.tagName]);
|
|
604
|
-
|
|
605
|
-
|
|
742
|
+
// Collect class tokens that are LITERAL strings (skip `{{ ... }}` binding parts).
|
|
743
|
+
const staticClassTokens = [];
|
|
744
|
+
if (className) {
|
|
745
|
+
const parts = className.split(/(\{\{[\s\S]*?\}\})/).filter(Boolean);
|
|
746
|
+
for (const p of parts) {
|
|
747
|
+
if (/^\{\{[\s\S]*?\}\}$/.test(p)) continue;
|
|
748
|
+
for (const tok of p.trim().split(/\s+/)) if (tok) staticClassTokens.push(tok);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
if (staticClassTokens.length) {
|
|
752
|
+
const classSet = new Set(staticClassTokens);
|
|
606
753
|
for (const key of Object.keys(styleSheet)) {
|
|
607
754
|
if (key.length > 1 && key.startsWith('.') && classSet.has(key.slice(1))) {
|
|
608
755
|
Object.assign(merged, styleSheet[key]);
|
|
@@ -610,7 +757,22 @@ function elementToJson(el, styleSheet, importMap, scopeVars, pageDir) {
|
|
|
610
757
|
}
|
|
611
758
|
}
|
|
612
759
|
Object.assign(merged, staticInlineStyle);
|
|
613
|
-
if (
|
|
760
|
+
if (merged.animationName && styleSheet['@KEYFRAMES']?.[merged.animationName]) {
|
|
761
|
+
merged.animationKeyframes = {
|
|
762
|
+
[merged.animationName]: styleSheet['@KEYFRAMES'][merged.animationName]
|
|
763
|
+
};
|
|
764
|
+
}
|
|
765
|
+
if (Object.keys(merged).length) {
|
|
766
|
+
if (hasDynClass) {
|
|
767
|
+
const existing = node['inlineStyle'] || {};
|
|
768
|
+
node['inlineStyle'] = {
|
|
769
|
+
...merged,
|
|
770
|
+
...existing
|
|
771
|
+
};
|
|
772
|
+
} else {
|
|
773
|
+
node.style = merged;
|
|
774
|
+
}
|
|
775
|
+
}
|
|
614
776
|
} else if (Object.keys(staticInlineStyle).length) {
|
|
615
777
|
node.style = {
|
|
616
778
|
...staticInlineStyle
|
|
@@ -238,6 +238,30 @@ class ViteCompiler {
|
|
|
238
238
|
}
|
|
239
239
|
},
|
|
240
240
|
plugins: [{
|
|
241
|
+
name: 'image-asset-string',
|
|
242
|
+
enforce: 'pre',
|
|
243
|
+
load(id) {
|
|
244
|
+
// require("./x.png") in .ux <script> must resolve to a path string,
|
|
245
|
+
// matching webpack file-loader / vivo blueos-pack semantics. Without
|
|
246
|
+
// this hook rolldown treats each image as an ES module and emits
|
|
247
|
+
// `(init_x(), __toCommonJS(x_exports))` — the site assigns
|
|
248
|
+
// `{ default: fn }` to src and runtime cannot render.
|
|
249
|
+
const match = id.match(/\.(png|jpe?g|gif|svg|webp|bmp|ico)(\?.*)?$/i);
|
|
250
|
+
if (!match) return null;
|
|
251
|
+
const filePath = id.replace(/\?.*$/, '');
|
|
252
|
+
if (!_fsExtra.default.existsSync(filePath)) return null;
|
|
253
|
+
const relFromSrc = _path.default.relative(srcPath, filePath).split(_path.default.sep).join('/');
|
|
254
|
+
// Assets outside src/ (typically node_modules) fall through to the
|
|
255
|
+
// default asset handler — the caller is responsible for their path
|
|
256
|
+
// resolution. Vivo blueos-pack + webpack file-loader use rpk-root
|
|
257
|
+
// absolute paths (`/common/...`, `/dynamicAssets/name-hash.png`);
|
|
258
|
+
// runtime <image src> resolves against the rpk root, so relative
|
|
259
|
+
// `./common/...` from a nested page directory would misdirect.
|
|
260
|
+
if (relFromSrc.startsWith('..')) return null;
|
|
261
|
+
const runtimePath = '/' + relFromSrc;
|
|
262
|
+
return `module.exports = ${JSON.stringify(runtimePath)};`;
|
|
263
|
+
}
|
|
264
|
+
}, {
|
|
241
265
|
name: "cjs-shim",
|
|
242
266
|
enforce: "pre",
|
|
243
267
|
load(id) {
|
|
@@ -36,8 +36,11 @@ declare class ZipUtil {
|
|
|
36
36
|
* Build the blueos-pack compatible "wrapped release" RPK.
|
|
37
37
|
* Outer RPK (zip) contains:
|
|
38
38
|
* - manifest.json (top-level metadata)
|
|
39
|
-
* -
|
|
39
|
+
* - <icon-basename>.<ext> (icon - kept as png since VUG conversion is out of scope,
|
|
40
|
+
* basename taken from manifest.icon so runtime + IDE previews can locate it)
|
|
40
41
|
* - META-INF/CERT (signature)
|
|
42
|
+
* - META-INF/build.txt (key=value pipeline info; includes `json=true`
|
|
43
|
+
* so downstream can distinguish this from legacy webpack output)
|
|
41
44
|
* - <package>.vru (multi-file VRU containing all build artifacts)
|
|
42
45
|
*/
|
|
43
46
|
private static createWrappedReleaseRpk;
|
|
@@ -88,8 +88,11 @@ class ZipUtil {
|
|
|
88
88
|
* Build the blueos-pack compatible "wrapped release" RPK.
|
|
89
89
|
* Outer RPK (zip) contains:
|
|
90
90
|
* - manifest.json (top-level metadata)
|
|
91
|
-
* -
|
|
91
|
+
* - <icon-basename>.<ext> (icon - kept as png since VUG conversion is out of scope,
|
|
92
|
+
* basename taken from manifest.icon so runtime + IDE previews can locate it)
|
|
92
93
|
* - META-INF/CERT (signature)
|
|
94
|
+
* - META-INF/build.txt (key=value pipeline info; includes `json=true`
|
|
95
|
+
* so downstream can distinguish this from legacy webpack output)
|
|
93
96
|
* - <package>.vru (multi-file VRU containing all build artifacts)
|
|
94
97
|
*/
|
|
95
98
|
static async createWrappedReleaseRpk(param, config, files, signConfig) {
|
|
@@ -146,14 +149,16 @@ class ZipUtil {
|
|
|
146
149
|
});
|
|
147
150
|
}
|
|
148
151
|
|
|
149
|
-
// Add icon (as-is, no VUG conversion)
|
|
152
|
+
// Add icon (as-is, no VUG conversion). Vivo blueos-pack preserves the icon
|
|
153
|
+
// basename from manifest.icon (e.g. `/resources/base/media/icon_small.png`
|
|
154
|
+
// → `icon_small.vug` at rpk root) so runtime + IDE previews can look it up
|
|
155
|
+
// by the manifest-declared name.
|
|
150
156
|
if (config.icon) {
|
|
151
157
|
const iconPath = _path.default.join(buildDir, config.icon.replace(/^\//, ''));
|
|
152
158
|
if (_fsExtra.default.existsSync(iconPath)) {
|
|
153
159
|
const iconBuf = _fsExtra.default.readFileSync(iconPath);
|
|
154
|
-
const iconExt = _path.default.extname(iconPath) || '.png';
|
|
155
160
|
outerPackage.addResource({
|
|
156
|
-
fileBuildPath:
|
|
161
|
+
fileBuildPath: _path.default.basename(iconPath),
|
|
157
162
|
fileContentBuffer: iconBuf,
|
|
158
163
|
fileContentDigest: _sharedUtils.CommonUtil.calcDataDigest(iconBuf)
|
|
159
164
|
});
|
|
@@ -167,6 +172,18 @@ class ZipUtil {
|
|
|
167
172
|
fileContentDigest: _sharedUtils.CommonUtil.calcDataDigest(vruBuffer)
|
|
168
173
|
});
|
|
169
174
|
|
|
175
|
+
// Add META-INF/build.txt — key=value lines matching what UxAfterCompile
|
|
176
|
+
// writes for flat-mode rpks. Historical downstream (IDE preview, cli
|
|
177
|
+
// rebuild) reads this to identify the source toolkit / pipeline.
|
|
178
|
+
const buildInfo = this.createComment(param);
|
|
179
|
+
const buildTxt = Object.keys(buildInfo).map(k => `${k}=${buildInfo[k]}`).join('\n');
|
|
180
|
+
const buildTxtBuf = Buffer.from(buildTxt, 'utf-8');
|
|
181
|
+
outerPackage.addResource({
|
|
182
|
+
fileBuildPath: ZipUtil.BUILD_FILE_PATH,
|
|
183
|
+
fileContentBuffer: buildTxtBuf,
|
|
184
|
+
fileContentDigest: _sharedUtils.CommonUtil.calcDataDigest(buildTxtBuf)
|
|
185
|
+
});
|
|
186
|
+
|
|
170
187
|
// Add CERT if present
|
|
171
188
|
const certAbsPath = _path.default.join(buildDir, ZipUtil.CERT_PATH);
|
|
172
189
|
if (_fsExtra.default.existsSync(certAbsPath)) {
|
|
@@ -367,7 +384,8 @@ class ZipUtil {
|
|
|
367
384
|
node: process.version,
|
|
368
385
|
platform: process.platform,
|
|
369
386
|
arch: process.arch,
|
|
370
|
-
component: true
|
|
387
|
+
component: true,
|
|
388
|
+
json: true
|
|
371
389
|
};
|
|
372
390
|
return obj;
|
|
373
391
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiot-toolkit/aiotpack",
|
|
3
|
-
"version": "2.1.0-prender.
|
|
3
|
+
"version": "2.1.0-prender.9",
|
|
4
4
|
"description": "The process tool for packaging aiot projects.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"aiotpack"
|
|
@@ -19,16 +19,16 @@
|
|
|
19
19
|
"test": "node ./__tests__/aiotpack.test.js"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@aiot-toolkit/generator": "2.1.0-prender.
|
|
23
|
-
"@aiot-toolkit/parser": "2.1.0-prender.
|
|
24
|
-
"@aiot-toolkit/shared-utils": "2.1.0-prender.
|
|
22
|
+
"@aiot-toolkit/generator": "2.1.0-prender.9",
|
|
23
|
+
"@aiot-toolkit/parser": "2.1.0-prender.9",
|
|
24
|
+
"@aiot-toolkit/shared-utils": "2.1.0-prender.9",
|
|
25
25
|
"@hap-toolkit/aaptjs": "^2.0.0",
|
|
26
26
|
"@rspack/core": "^1.3.9",
|
|
27
27
|
"acorn": "^8.16.0",
|
|
28
28
|
"aiot-parse5": "^1.0.2",
|
|
29
29
|
"astring": "^1.9.0",
|
|
30
30
|
"babel-loader": "^9.1.3",
|
|
31
|
-
"file-lane": "2.1.0-prender.
|
|
31
|
+
"file-lane": "2.1.0-prender.9",
|
|
32
32
|
"file-loader": "^6.2.0",
|
|
33
33
|
"fs-extra": "^11.2.0",
|
|
34
34
|
"jsrsasign": "^11.1.0",
|