@kurot/cli 1.0.2 → 1.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/CHANGELOG.md +53 -1
- package/README.md +41 -11
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +49 -10
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +19 -5
- package/dist/commands/dev.js.map +1 -1
- package/dist/core/dev-server.d.ts +9 -0
- package/dist/core/dev-server.d.ts.map +1 -1
- package/dist/core/dev-server.js +40 -16
- package/dist/core/dev-server.js.map +1 -1
- package/dist/core/diagnostics/codes.d.ts +21 -0
- package/dist/core/diagnostics/codes.d.ts.map +1 -0
- package/dist/core/diagnostics/codes.js +25 -0
- package/dist/core/diagnostics/codes.js.map +1 -0
- package/dist/core/diagnostics/collector.d.ts +28 -0
- package/dist/core/diagnostics/collector.d.ts.map +1 -0
- package/dist/core/diagnostics/collector.js +78 -0
- package/dist/core/diagnostics/collector.js.map +1 -0
- package/dist/core/diagnostics/index.d.ts +7 -0
- package/dist/core/diagnostics/index.d.ts.map +1 -0
- package/dist/core/diagnostics/index.js +4 -0
- package/dist/core/diagnostics/index.js.map +1 -0
- package/dist/core/diagnostics/output.d.ts +30 -0
- package/dist/core/diagnostics/output.d.ts.map +1 -0
- package/dist/core/diagnostics/output.js +15 -0
- package/dist/core/diagnostics/output.js.map +1 -0
- package/dist/core/diagnostics/types.d.ts +30 -0
- package/dist/core/diagnostics/types.d.ts.map +1 -0
- package/dist/core/diagnostics/types.js +2 -0
- package/dist/core/diagnostics/types.js.map +1 -0
- package/dist/core/exml/ast.d.ts +9 -1
- package/dist/core/exml/ast.d.ts.map +1 -1
- package/dist/core/exml/exml-diagnostics.d.ts +7 -0
- package/dist/core/exml/exml-diagnostics.d.ts.map +1 -0
- package/dist/core/exml/exml-diagnostics.js +26 -0
- package/dist/core/exml/exml-diagnostics.js.map +1 -0
- package/dist/core/exml/exml-parser.d.ts.map +1 -1
- package/dist/core/exml/exml-parser.js +1 -1
- package/dist/core/exml/exml-parser.js.map +1 -1
- package/dist/core/exml/index.d.ts +5 -3
- package/dist/core/exml/index.d.ts.map +1 -1
- package/dist/core/exml/index.js +2 -1
- package/dist/core/exml/index.js.map +1 -1
- package/dist/core/exml/registry.d.ts +7 -0
- package/dist/core/exml/registry.d.ts.map +1 -1
- package/dist/core/exml/registry.js +41 -0
- package/dist/core/exml/registry.js.map +1 -1
- package/dist/core/exml/skin-module-builder.d.ts +21 -0
- package/dist/core/exml/skin-module-builder.d.ts.map +1 -0
- package/dist/core/exml/skin-module-builder.js +103 -0
- package/dist/core/exml/skin-module-builder.js.map +1 -0
- package/dist/core/exml/source-location.d.ts +25 -0
- package/dist/core/exml/source-location.d.ts.map +1 -0
- package/dist/core/exml/source-location.js +52 -0
- package/dist/core/exml/source-location.js.map +1 -0
- package/dist/core/exml/xml-parser.d.ts +15 -0
- package/dist/core/exml/xml-parser.d.ts.map +1 -1
- package/dist/core/exml/xml-parser.js +13 -7
- package/dist/core/exml/xml-parser.js.map +1 -1
- package/dist/core/pipeline.d.ts +11 -1
- package/dist/core/pipeline.d.ts.map +1 -1
- package/dist/core/pipeline.js +9 -0
- package/dist/core/pipeline.js.map +1 -1
- package/dist/core/plugins/compile-exml.d.ts.map +1 -1
- package/dist/core/plugins/compile-exml.js +101 -88
- package/dist/core/plugins/compile-exml.js.map +1 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/utils/logger.d.ts +1 -0
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +14 -5
- package/dist/utils/logger.js.map +1 -1
- package/package.json +1 -1
- package/templates/game/template/web/logo.png +0 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One-based source coordinates for a UTF-16 offset.
|
|
3
|
+
*/
|
|
4
|
+
export interface SourcePosition {
|
|
5
|
+
readonly line: number;
|
|
6
|
+
readonly column: number;
|
|
7
|
+
readonly offset: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Maps source offsets to one-based lines and UTF-16 code-unit columns.
|
|
11
|
+
*/
|
|
12
|
+
export declare class SourceLocator {
|
|
13
|
+
private readonly _lineStarts;
|
|
14
|
+
private readonly _sourceLength;
|
|
15
|
+
constructor(source: string);
|
|
16
|
+
/**
|
|
17
|
+
* Returns the one-based line and column for a source offset.
|
|
18
|
+
*/
|
|
19
|
+
locate(offset: number): SourcePosition;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Creates a reusable locator for a source string.
|
|
23
|
+
*/
|
|
24
|
+
export declare function createSourceLocator(source: string): SourceLocator;
|
|
25
|
+
//# sourceMappingURL=source-location.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-location.d.ts","sourceRoot":"","sources":["../../../src/core/exml/source-location.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,qBAAa,aAAa;IAGzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoB;IAChD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;gBAIpB,MAAM,EAAE,MAAM;IAajC;;OAEG;IACI,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc;CAuB7C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAEjE"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maps source offsets to one-based lines and UTF-16 code-unit columns.
|
|
3
|
+
*/
|
|
4
|
+
export class SourceLocator {
|
|
5
|
+
// ── Instance fields ───────────────────────────────────────────────
|
|
6
|
+
_lineStarts;
|
|
7
|
+
_sourceLength;
|
|
8
|
+
// ── Constructor ───────────────────────────────────────────────────
|
|
9
|
+
constructor(source) {
|
|
10
|
+
this._sourceLength = source.length;
|
|
11
|
+
const lineStarts = [0];
|
|
12
|
+
for (let i = 0; i < source.length; i++) {
|
|
13
|
+
if (source.charCodeAt(i) === 10) {
|
|
14
|
+
lineStarts.push(i + 1);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
this._lineStarts = lineStarts;
|
|
18
|
+
}
|
|
19
|
+
// ── Public methods ────────────────────────────────────────────────
|
|
20
|
+
/**
|
|
21
|
+
* Returns the one-based line and column for a source offset.
|
|
22
|
+
*/
|
|
23
|
+
locate(offset) {
|
|
24
|
+
if (!Number.isInteger(offset) || offset < 0 || offset > this._sourceLength) {
|
|
25
|
+
throw new RangeError(`Source offset must be an integer from 0 to ${this._sourceLength}, got ${offset}`);
|
|
26
|
+
}
|
|
27
|
+
let low = 0;
|
|
28
|
+
let high = this._lineStarts.length - 1;
|
|
29
|
+
while (low <= high) {
|
|
30
|
+
const middle = Math.floor((low + high) / 2);
|
|
31
|
+
if (this._lineStarts[middle] <= offset) {
|
|
32
|
+
low = middle + 1;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
high = middle - 1;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const lineIndex = Math.max(0, high);
|
|
39
|
+
return {
|
|
40
|
+
line: lineIndex + 1,
|
|
41
|
+
column: offset - this._lineStarts[lineIndex] + 1,
|
|
42
|
+
offset,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Creates a reusable locator for a source string.
|
|
48
|
+
*/
|
|
49
|
+
export function createSourceLocator(source) {
|
|
50
|
+
return new SourceLocator(source);
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=source-location.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-location.js","sourceRoot":"","sources":["../../../src/core/exml/source-location.ts"],"names":[],"mappings":"AASA;;GAEG;AACH,MAAM,OAAO,aAAa;IACzB,qEAAqE;IAEpD,WAAW,CAAoB;IAC/B,aAAa,CAAS;IAEvC,qEAAqE;IAErE,YAAmB,MAAc;QAChC,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC;QACnC,MAAM,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC;QACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACxC,IAAI,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;gBACjC,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACxB,CAAC;QACF,CAAC;QACD,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED,qEAAqE;IAErE;;OAEG;IACI,MAAM,CAAC,MAAc;QAC3B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;YAC5E,MAAM,IAAI,UAAU,CAAC,8CAA8C,IAAI,CAAC,aAAa,SAAS,MAAM,EAAE,CAAC,CAAC;QACzG,CAAC;QAED,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,IAAI,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;QACvC,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC;YACpB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAC5C,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;gBACxC,GAAG,GAAG,MAAM,GAAG,CAAC,CAAC;YAClB,CAAC;iBAAM,CAAC;gBACP,IAAI,GAAG,MAAM,GAAG,CAAC,CAAC;YACnB,CAAC;QACF,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QACpC,OAAO;YACN,IAAI,EAAE,SAAS,GAAG,CAAC;YACnB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC;YAChD,MAAM;SACN,CAAC;IACH,CAAC;CACD;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAc;IACjD,OAAO,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -13,11 +13,22 @@
|
|
|
13
13
|
* - DTD / ENTITY declarations
|
|
14
14
|
* - Namespaced attribute prefixes (we only care about the local name)
|
|
15
15
|
*/
|
|
16
|
+
/**
|
|
17
|
+
* Half-open offsets covering a parsed XML node or attribute.
|
|
18
|
+
*/
|
|
19
|
+
export interface SourceRange {
|
|
20
|
+
readonly start: number;
|
|
21
|
+
readonly end: number;
|
|
22
|
+
}
|
|
16
23
|
export interface XNode {
|
|
17
24
|
/**
|
|
18
25
|
* Node type.
|
|
19
26
|
*/
|
|
20
27
|
readonly type: 'element' | 'text';
|
|
28
|
+
/**
|
|
29
|
+
* Half-open source range containing the complete node syntax.
|
|
30
|
+
*/
|
|
31
|
+
readonly range: SourceRange;
|
|
21
32
|
}
|
|
22
33
|
export interface XText extends XNode {
|
|
23
34
|
readonly type: 'text';
|
|
@@ -35,6 +46,10 @@ export interface XAttribute {
|
|
|
35
46
|
* Attribute value (unescaped).
|
|
36
47
|
*/
|
|
37
48
|
readonly value: string;
|
|
49
|
+
/**
|
|
50
|
+
* Half-open source range containing the complete attribute assignment.
|
|
51
|
+
*/
|
|
52
|
+
readonly range: SourceRange;
|
|
38
53
|
}
|
|
39
54
|
export interface XElement extends XNode {
|
|
40
55
|
readonly type: 'element';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xml-parser.d.ts","sourceRoot":"","sources":["../../../src/core/exml/xml-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,MAAM,WAAW,KAAK;IACrB;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"xml-parser.d.ts","sourceRoot":"","sources":["../../../src/core/exml/xml-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,KAAK;IACrB;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC;IAClC;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;CAC5B;AAED,MAAM,WAAW,KAAM,SAAQ,KAAK;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IAC1B;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;CAC5B;AAED,MAAM,WAAW,QAAS,SAAQ,KAAK;IACtC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,QAAQ,CAAC,UAAU,EAAE,UAAU,EAAE,CAAC;IAClC;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC;CAC3B;AAQD,wBAAgB,cAAc,CAAC,QAAQ,EAAE,SAAS,KAAK,EAAE,GAAG,QAAQ,EAAE,CAErE;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,SAAS,KAAK,EAAE,GAAG,MAAM,CAKjE;AAID;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAQjD"}
|
|
@@ -73,7 +73,7 @@ class _Parser {
|
|
|
73
73
|
}
|
|
74
74
|
// CDATA
|
|
75
75
|
if (this.src.startsWith('<![CDATA[', this.pos)) {
|
|
76
|
-
nodes.push(
|
|
76
|
+
nodes.push(this.readCDATA());
|
|
77
77
|
continue;
|
|
78
78
|
}
|
|
79
79
|
// Processing instruction <?...?>
|
|
@@ -115,7 +115,7 @@ class _Parser {
|
|
|
115
115
|
// Self-closing />
|
|
116
116
|
if (this.src.startsWith('/>', this.pos)) {
|
|
117
117
|
this.pos += 2;
|
|
118
|
-
return { type: 'element', name: tagName, attributes: attrs, children: [] };
|
|
118
|
+
return { type: 'element', name: tagName, attributes: attrs, children: [], range: { start, end: this.pos } };
|
|
119
119
|
}
|
|
120
120
|
// Open tag end >
|
|
121
121
|
if (this.src[this.pos] === '>') {
|
|
@@ -125,8 +125,13 @@ class _Parser {
|
|
|
125
125
|
// Attribute
|
|
126
126
|
const am = this.src.slice(this.pos).match(RX_ATTR);
|
|
127
127
|
if (am) {
|
|
128
|
-
|
|
128
|
+
const attributeStart = this.pos;
|
|
129
129
|
this.pos += am[0].length;
|
|
130
|
+
attrs.push({
|
|
131
|
+
name: am[1],
|
|
132
|
+
value: am[2] ?? am[3],
|
|
133
|
+
range: { start: attributeStart, end: this.pos },
|
|
134
|
+
});
|
|
130
135
|
}
|
|
131
136
|
else {
|
|
132
137
|
// Unexpected character — skip
|
|
@@ -146,15 +151,16 @@ class _Parser {
|
|
|
146
151
|
else {
|
|
147
152
|
throw new Error(`EXML: missing closing tag </${tagName}>`);
|
|
148
153
|
}
|
|
149
|
-
return { type: 'element', name: tagName, attributes: attrs, children };
|
|
154
|
+
return { type: 'element', name: tagName, attributes: attrs, children, range: { start, end: this.pos } };
|
|
150
155
|
}
|
|
151
156
|
// ── Text ──────────────────────────────────────────────────────────
|
|
152
157
|
readText() {
|
|
158
|
+
const start = this.pos;
|
|
153
159
|
let text = '';
|
|
154
160
|
while (this.pos < this.src.length && this.src[this.pos] !== '<') {
|
|
155
161
|
text += this.src[this.pos++];
|
|
156
162
|
}
|
|
157
|
-
return { type: 'text', text: unescapeXML(text) };
|
|
163
|
+
return { type: 'text', text: unescapeXML(text), range: { start, end: this.pos } };
|
|
158
164
|
}
|
|
159
165
|
// ── CDATA ─────────────────────────────────────────────────────────
|
|
160
166
|
readCDATA() {
|
|
@@ -163,11 +169,11 @@ class _Parser {
|
|
|
163
169
|
const end = this.src.indexOf(']]>', this.pos);
|
|
164
170
|
if (end === -1) {
|
|
165
171
|
this.pos = this.src.length;
|
|
166
|
-
return this.src.slice(start);
|
|
172
|
+
return { type: 'text', text: this.src.slice(start), range: { start, end: this.pos } };
|
|
167
173
|
}
|
|
168
174
|
const content = this.src.slice(this.pos, end);
|
|
169
175
|
this.pos = end + 3;
|
|
170
|
-
return content;
|
|
176
|
+
return { type: 'text', text: content, range: { start, end: this.pos } };
|
|
171
177
|
}
|
|
172
178
|
// ── Skip helpers ──────────────────────────────────────────────────
|
|
173
179
|
skipComment() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xml-parser.js","sourceRoot":"","sources":["../../../src/core/exml/xml-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;
|
|
1
|
+
{"version":3,"file":"xml-parser.js","sourceRoot":"","sources":["../../../src/core/exml/xml-parser.ts"],"names":[],"mappings":"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"}
|
package/dist/core/pipeline.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DiagnosticCollector } from './diagnostics/index.js';
|
|
1
2
|
import type { Project } from './project.js';
|
|
2
3
|
/**
|
|
3
4
|
* Shared state threaded through every build plugin.
|
|
@@ -11,6 +12,14 @@ export interface BuildContext {
|
|
|
11
12
|
readonly sourcemap: boolean;
|
|
12
13
|
readonly analyze: boolean;
|
|
13
14
|
readonly watch: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Whether strict policy promotes selected warnings to errors.
|
|
17
|
+
*/
|
|
18
|
+
readonly strict: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Diagnostics reported by build plugins.
|
|
21
|
+
*/
|
|
22
|
+
readonly diagnostics: DiagnosticCollector;
|
|
14
23
|
/**
|
|
15
24
|
* Artifacts produced during the build, populated incrementally by plugins.
|
|
16
25
|
*/
|
|
@@ -63,11 +72,12 @@ export declare function createContext(project: Project, options?: {
|
|
|
63
72
|
sourcemap?: boolean;
|
|
64
73
|
analyze?: boolean;
|
|
65
74
|
watch?: boolean;
|
|
75
|
+
strict?: boolean;
|
|
66
76
|
}): BuildContext;
|
|
67
77
|
/**
|
|
68
78
|
* Runs plugins in order, logging each step.
|
|
69
79
|
*/
|
|
70
|
-
export declare function runPipeline(ctx: BuildContext, plugins: BuildPlugin[]): Promise<void>;
|
|
80
|
+
export declare function runPipeline(ctx: BuildContext, plugins: readonly BuildPlugin[]): Promise<void>;
|
|
71
81
|
/**
|
|
72
82
|
* Invokes every registered disposer, ignoring individual failures.
|
|
73
83
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/core/pipeline.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE;QACjB;;WAEG;QACH,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB;;WAEG;QACH,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB;;WAEG;QACH,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/B;;;;;;;;;;;;;;WAcG;QACH,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACtC,CAAC;IACF;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;CACtD;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC5B,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/core/pipeline.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAE7D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,mBAAmB,CAAC;IAC1C;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE;QACjB;;WAEG;QACH,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB;;WAEG;QACH,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB;;WAEG;QACH,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/B;;;;;;;;;;;;;;WAcG;QACH,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACtC,CAAC;IACF;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;CACtD;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC5B,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACzF,YAAY,CAYd;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,SAAS,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CASnG;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAErE"}
|
package/dist/core/pipeline.js
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import { logger } from '../utils/logger.js';
|
|
2
|
+
import { DiagnosticCollector } from './diagnostics/index.js';
|
|
3
|
+
import { BuildError } from './errors.js';
|
|
2
4
|
/**
|
|
3
5
|
* Creates a fresh build context for a project.
|
|
4
6
|
*/
|
|
5
7
|
export function createContext(project, options = {}) {
|
|
8
|
+
const strict = options.strict ?? project.mode === 'release';
|
|
6
9
|
return {
|
|
7
10
|
project,
|
|
8
11
|
sourcemap: options.sourcemap ?? false,
|
|
9
12
|
analyze: options.analyze ?? false,
|
|
10
13
|
watch: options.watch ?? false,
|
|
14
|
+
strict,
|
|
15
|
+
diagnostics: new DiagnosticCollector({ strict }),
|
|
11
16
|
outputs: { engine: {}, namespaceModules: new Map() },
|
|
12
17
|
disposers: [],
|
|
13
18
|
};
|
|
@@ -19,6 +24,10 @@ export async function runPipeline(ctx, plugins) {
|
|
|
19
24
|
for (const plugin of plugins) {
|
|
20
25
|
logger.step(plugin.name);
|
|
21
26
|
await plugin.apply(ctx);
|
|
27
|
+
if (ctx.diagnostics.hasErrors()) {
|
|
28
|
+
const count = ctx.diagnostics.all().filter(diagnostic => diagnostic.severity === 'error').length;
|
|
29
|
+
throw new BuildError(`Build stopped after '${plugin.name}' with ${count} error diagnostic(s).`);
|
|
30
|
+
}
|
|
22
31
|
}
|
|
23
32
|
}
|
|
24
33
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/core/pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/core/pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAsEzC;;GAEG;AACH,MAAM,UAAU,aAAa,CAC5B,OAAgB,EAChB,UAAyF,EAAE;IAE3F,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC;IAC5D,OAAO;QACN,OAAO;QACP,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,KAAK;QACrC,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,KAAK;QACjC,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,KAAK;QAC7B,MAAM;QACN,WAAW,EAAE,IAAI,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;QAChD,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,gBAAgB,EAAE,IAAI,GAAG,EAAE,EAAE;QACpD,SAAS,EAAE,EAAE;KACb,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAiB,EAAE,OAA+B;IACnF,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACzB,MAAM,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxB,IAAI,GAAG,CAAC,WAAW,CAAC,SAAS,EAAE,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,MAAM,CAAC;YACjG,MAAM,IAAI,UAAU,CAAC,wBAAwB,MAAM,CAAC,IAAI,UAAU,KAAK,uBAAuB,CAAC,CAAC;QACjG,CAAC;IACF,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAiB;IACrD,MAAM,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AACnE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile-exml.d.ts","sourceRoot":"","sources":["../../../src/core/plugins/compile-exml.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"compile-exml.d.ts","sourceRoot":"","sources":["../../../src/core/plugins/compile-exml.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAgB,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAgBhE;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,IAAI,WAAW,CA2CzC"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import * as esbuild from 'esbuild';
|
|
2
|
-
import * as os from 'node:os';
|
|
3
1
|
import * as fs from 'node:fs/promises';
|
|
4
2
|
import * as path from 'node:path';
|
|
5
|
-
import {
|
|
3
|
+
import { writeFile } from '../../utils/fs.js';
|
|
6
4
|
import { logger } from '../../utils/logger.js';
|
|
7
|
-
import {
|
|
5
|
+
import { DIAGNOSTIC_CODES } from '../diagnostics/index.js';
|
|
6
|
+
import { buildSkinsModule } from '../exml/skin-module-builder.js';
|
|
7
|
+
import { BuildError } from '../errors.js';
|
|
8
8
|
/**
|
|
9
9
|
* Compiles `.exml` skin files into a single ESM module and rewrites the theme.
|
|
10
10
|
*
|
|
@@ -23,13 +23,27 @@ export function compileExml() {
|
|
|
23
23
|
const { project } = ctx;
|
|
24
24
|
if (!project.config.exml || !project.themeFile)
|
|
25
25
|
return;
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
ctx.diagnostics.removeByCodes([
|
|
27
|
+
DIAGNOSTIC_CODES.EXML_UNKNOWN_TAG,
|
|
28
|
+
DIAGNOSTIC_CODES.EXML_COMPILE_FAILED,
|
|
29
|
+
DIAGNOSTIC_CODES.EXML_DECLARED_FILE_NOT_FOUND,
|
|
30
|
+
DIAGNOSTIC_CODES.THEME_FILE_NOT_FOUND,
|
|
31
|
+
DIAGNOSTIC_CODES.THEME_INVALID_JSON,
|
|
32
|
+
DIAGNOSTIC_CODES.THEME_SKIN_NOT_FOUND,
|
|
33
|
+
]);
|
|
34
|
+
const theme = await loadTheme(ctx);
|
|
35
|
+
if (!theme) {
|
|
36
|
+
throwIfInputInvalid(ctx);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const { files, missingDeclaredPaths } = await resolveExmlFiles(ctx, theme);
|
|
40
|
+
const skins = files.map(file => ({ file, className: extractClassName(file) }));
|
|
41
|
+
reportMissingThemeSkins(ctx, theme, skins, missingDeclaredPaths);
|
|
42
|
+
throwIfInputInvalid(ctx);
|
|
28
43
|
if (files.length === 0) {
|
|
29
44
|
logger.step('no .exml files found, skipping');
|
|
30
45
|
return;
|
|
31
46
|
}
|
|
32
|
-
const skins = files.map(file => ({ file, className: extractClassName(file) }));
|
|
33
47
|
const skinsFile = await buildSkinsModule(ctx, skins);
|
|
34
48
|
ctx.outputs.skinsScript = `js/${skinsFile}`;
|
|
35
49
|
const relThemePath = project.config.exml.themeFile;
|
|
@@ -43,90 +57,33 @@ export function compileExml() {
|
|
|
43
57
|
},
|
|
44
58
|
};
|
|
45
59
|
}
|
|
46
|
-
/**
|
|
47
|
-
* Generates one ESM module per skin in a temp dir, plus an index that imports
|
|
48
|
-
* and registers them, then bundles to `js/default.thm[.min_<hash>].js`.
|
|
49
|
-
*
|
|
50
|
-
* Engine packages and custom namespaces stay external (resolved by the page
|
|
51
|
-
* import map — see `compile-engine.ts` and `compile-custom-namespaces.ts`).
|
|
52
|
-
*/
|
|
53
|
-
async function buildSkinsModule(ctx, skins) {
|
|
54
|
-
const { project } = ctx;
|
|
55
|
-
const jsDir = path.join(project.outputDir, 'js');
|
|
56
|
-
await ensureDir(jsDir);
|
|
57
|
-
const customNamespaces = project.customNamespaces.map(ns => ({ prefix: ns.prefix, specifier: ns.specifier }));
|
|
58
|
-
const isRelease = project.mode === 'release';
|
|
59
|
-
const stubDir = await fs.mkdtemp(path.join(os.tmpdir(), 'kurot-skins-'));
|
|
60
|
-
try {
|
|
61
|
-
const indexLines = [];
|
|
62
|
-
await Promise.all(skins.map(async (skin, i) => {
|
|
63
|
-
const code = generateSkinModule(skin, customNamespaces, isRelease);
|
|
64
|
-
await fs.writeFile(path.join(stubDir, `skin${i}.ts`), code);
|
|
65
|
-
const funcName = factoryName(skin.className);
|
|
66
|
-
indexLines.push(`import { ${funcName} as s${i} } from './skin${i}.js';\n` +
|
|
67
|
-
`globalThis[${JSON.stringify(skin.className)}] = s${i};`);
|
|
68
|
-
}));
|
|
69
|
-
await fs.writeFile(path.join(stubDir, 'index.ts'), indexLines.join('\n\n') + '\n');
|
|
70
|
-
const engineExternal = project.enginePackages.length > 0 ? project.enginePackages : ['@kurot/ui', '@kurot/core'];
|
|
71
|
-
const result = await esbuild.build({
|
|
72
|
-
entryPoints: [path.join(stubDir, 'index.ts')],
|
|
73
|
-
outdir: jsDir,
|
|
74
|
-
entryNames: isRelease ? 'default.thm.min_[hash]' : 'default.thm',
|
|
75
|
-
bundle: true,
|
|
76
|
-
format: 'esm',
|
|
77
|
-
platform: 'browser',
|
|
78
|
-
target: 'es2022',
|
|
79
|
-
minify: isRelease,
|
|
80
|
-
metafile: true,
|
|
81
|
-
logLevel: 'warning',
|
|
82
|
-
external: [...engineExternal, ...project.customNamespaces.map(ns => ns.specifier)],
|
|
83
|
-
});
|
|
84
|
-
const output = Object.keys(result.metafile.outputs).find(f => f.endsWith('.js'));
|
|
85
|
-
return path.basename(output ?? 'default.thm.js');
|
|
86
|
-
}
|
|
87
|
-
finally {
|
|
88
|
-
await fs.rm(stubDir, { recursive: true, force: true });
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Generates an ESM skin factory, returning a stub on parse failure.
|
|
93
|
-
*/
|
|
94
|
-
function generateSkinModule(skin, customNamespaces, strict) {
|
|
95
|
-
try {
|
|
96
|
-
const ir = parseToIR(skin.file.contents, skin.className, customNamespaces);
|
|
97
|
-
if (ir.unresolvedTags.length > 0) {
|
|
98
|
-
const tags = [...new Set(ir.unresolvedTags)].join(', ');
|
|
99
|
-
logger.warn(`${skin.file.relPath}: unresolved tag(s) dropped from skin: ${tags}`);
|
|
100
|
-
}
|
|
101
|
-
return generateCode(ir, { format: 'esm' });
|
|
102
|
-
}
|
|
103
|
-
catch (err) {
|
|
104
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
105
|
-
if (strict) {
|
|
106
|
-
throw new Error(`EXML compile failed for ${skin.file.relPath}: ${message}`, { cause: err });
|
|
107
|
-
}
|
|
108
|
-
logger.warn(`EXML compile failed for ${skin.file.relPath}: ${message}`);
|
|
109
|
-
return `// Failed to compile ${skin.file.relPath}: ${message}\nexport function ${factoryName(skin.className)}() { return {}; }\n`;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
60
|
/**
|
|
113
61
|
* Determines which `.exml` files to compile (honours `autoGenerateExmlsList`).
|
|
114
62
|
*/
|
|
115
|
-
async function resolveExmlFiles(
|
|
63
|
+
async function resolveExmlFiles(ctx, theme) {
|
|
64
|
+
const { project } = ctx;
|
|
116
65
|
const declared = (theme.exmls ?? []).map(e => (typeof e === 'string' ? e : e?.path)).filter(Boolean);
|
|
117
66
|
if (theme.autoGenerateExmlsList === false && declared.length > 0) {
|
|
118
67
|
const files = [];
|
|
68
|
+
const missingDeclaredPaths = new Set();
|
|
119
69
|
for (const rel of declared) {
|
|
120
70
|
try {
|
|
121
71
|
files.push(await readExmlAt(project.resourceDir, resolveExmlPath(project, rel)));
|
|
122
72
|
}
|
|
123
73
|
catch {
|
|
124
|
-
|
|
74
|
+
missingDeclaredPaths.add(toResourceRelativePath(project, rel));
|
|
75
|
+
reportDiagnostic(ctx, {
|
|
76
|
+
code: DIAGNOSTIC_CODES.EXML_DECLARED_FILE_NOT_FOUND,
|
|
77
|
+
severity: 'warning',
|
|
78
|
+
message: `Theme-declared EXML file was not found: ${rel}`,
|
|
79
|
+
location: { file: project.config.exml.themeFile },
|
|
80
|
+
suggestions: ['Correct the path or remove it from the theme exmls list.'],
|
|
81
|
+
});
|
|
125
82
|
}
|
|
126
83
|
}
|
|
127
|
-
return files;
|
|
84
|
+
return { files, missingDeclaredPaths };
|
|
128
85
|
}
|
|
129
|
-
return collectExmlFiles(project.resourceDir);
|
|
86
|
+
return { files: await collectExmlFiles(project.resourceDir), missingDeclaredPaths: new Set() };
|
|
130
87
|
}
|
|
131
88
|
/**
|
|
132
89
|
* Recursively collects every `.exml` file under `resource/`, sorted by path.
|
|
@@ -172,16 +129,75 @@ async function readExmlAt(resourceDir, absolute) {
|
|
|
172
129
|
};
|
|
173
130
|
}
|
|
174
131
|
/**
|
|
175
|
-
* Reads the
|
|
132
|
+
* Reads and parses the configured theme file.
|
|
176
133
|
*/
|
|
177
|
-
async function loadTheme(
|
|
134
|
+
async function loadTheme(ctx) {
|
|
135
|
+
const { project } = ctx;
|
|
136
|
+
let source;
|
|
178
137
|
try {
|
|
179
|
-
|
|
138
|
+
source = await fs.readFile(project.themeFile, 'utf-8');
|
|
180
139
|
}
|
|
181
140
|
catch {
|
|
182
|
-
|
|
141
|
+
reportDiagnostic(ctx, {
|
|
142
|
+
code: DIAGNOSTIC_CODES.THEME_FILE_NOT_FOUND,
|
|
143
|
+
severity: 'warning',
|
|
144
|
+
message: `Theme file could not be read: ${project.config.exml.themeFile}`,
|
|
145
|
+
location: { file: project.config.exml.themeFile },
|
|
146
|
+
suggestions: ['Create the theme file or correct exml.themeFile in kurot.config.ts.'],
|
|
147
|
+
});
|
|
148
|
+
return undefined;
|
|
149
|
+
}
|
|
150
|
+
try {
|
|
151
|
+
return JSON.parse(source);
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
155
|
+
reportDiagnostic(ctx, {
|
|
156
|
+
code: DIAGNOSTIC_CODES.THEME_INVALID_JSON,
|
|
157
|
+
severity: 'error',
|
|
158
|
+
message: `Theme file is not valid JSON: ${message}`,
|
|
159
|
+
location: { file: project.config.exml.themeFile },
|
|
160
|
+
suggestions: ['Correct the JSON syntax in the theme file.'],
|
|
161
|
+
});
|
|
162
|
+
return undefined;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function reportMissingThemeSkins(ctx, theme, compiled, missingDeclaredPaths) {
|
|
166
|
+
const { project } = ctx;
|
|
167
|
+
const compiledPaths = new Set(compiled.map(skin => skin.file.relPath));
|
|
168
|
+
for (const value of Object.values(theme.skins ?? {})) {
|
|
169
|
+
if (!isSkinPath(value))
|
|
170
|
+
continue;
|
|
171
|
+
const relPath = toResourceRelativePath(project, value);
|
|
172
|
+
if (compiledPaths.has(relPath) || missingDeclaredPaths.has(relPath))
|
|
173
|
+
continue;
|
|
174
|
+
reportDiagnostic(ctx, {
|
|
175
|
+
code: DIAGNOSTIC_CODES.THEME_SKIN_NOT_FOUND,
|
|
176
|
+
severity: 'warning',
|
|
177
|
+
message: `Theme skin was not compiled: ${value}`,
|
|
178
|
+
location: { file: project.config.exml.themeFile },
|
|
179
|
+
suggestions: ['Correct the skin path or add the EXML file to the compilation list.'],
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
function toResourceRelativePath(project, value) {
|
|
184
|
+
return toPosix(path.relative(project.resourceDir, resolveExmlPath(project, value)));
|
|
185
|
+
}
|
|
186
|
+
function reportDiagnostic(ctx, diagnostic) {
|
|
187
|
+
ctx.diagnostics.report(diagnostic);
|
|
188
|
+
const location = diagnostic.location ? `${diagnostic.location.file}: ` : '';
|
|
189
|
+
if (diagnostic.severity === 'error') {
|
|
190
|
+
logger.error(`${location}${diagnostic.message}`);
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
logger.warn(`${location}${diagnostic.message}`);
|
|
183
194
|
}
|
|
184
195
|
}
|
|
196
|
+
function throwIfInputInvalid(ctx) {
|
|
197
|
+
if (!ctx.diagnostics.hasErrors())
|
|
198
|
+
return;
|
|
199
|
+
throw new BuildError('EXML input validation failed.');
|
|
200
|
+
}
|
|
185
201
|
/**
|
|
186
202
|
* Rewrites the `skins` map to class names: Egret path values
|
|
187
203
|
* (`resource/skins/X.exml`) are matched to their compiled skin; values that are
|
|
@@ -191,7 +207,7 @@ function remapSkins(project, skins, compiled) {
|
|
|
191
207
|
const byRelPath = new Map(compiled.map(s => [s.file.relPath, s.className]));
|
|
192
208
|
const result = {};
|
|
193
209
|
for (const [host, value] of Object.entries(skins)) {
|
|
194
|
-
if (
|
|
210
|
+
if (isSkinPath(value)) {
|
|
195
211
|
const relPath = toPosix(path.relative(project.resourceDir, resolveExmlPath(project, value)));
|
|
196
212
|
result[host] = byRelPath.get(relPath) ?? value;
|
|
197
213
|
}
|
|
@@ -201,6 +217,9 @@ function remapSkins(project, skins, compiled) {
|
|
|
201
217
|
}
|
|
202
218
|
return result;
|
|
203
219
|
}
|
|
220
|
+
function isSkinPath(value) {
|
|
221
|
+
return /\.exml$/i.test(value) || value.includes('/');
|
|
222
|
+
}
|
|
204
223
|
/**
|
|
205
224
|
* Reads the `class="..."` attribute, falling back to the file name.
|
|
206
225
|
*/
|
|
@@ -208,12 +227,6 @@ function extractClassName(file) {
|
|
|
208
227
|
const match = file.contents.match(/class="([^"]+)"/);
|
|
209
228
|
return match ? match[1] : path.basename(file.path, '.exml');
|
|
210
229
|
}
|
|
211
|
-
/**
|
|
212
|
-
* `skins.ButtonSkin` → `createButtonSkin` (matches the EXML codegen).
|
|
213
|
-
*/
|
|
214
|
-
function factoryName(className) {
|
|
215
|
-
return `create${className.split('.').pop()}`;
|
|
216
|
-
}
|
|
217
230
|
/**
|
|
218
231
|
* Converts a file system path to forward-slash form (a no-op on POSIX).
|
|
219
232
|
*/
|