@kurot/cli 1.0.2
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 +128 -0
- package/README.md +296 -0
- package/dist/commands/build.d.ts +3 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +59 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/clean.d.ts +3 -0
- package/dist/commands/clean.d.ts.map +1 -0
- package/dist/commands/clean.js +15 -0
- package/dist/commands/clean.js.map +1 -0
- package/dist/commands/create.d.ts +3 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/create.js +24 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/dev.d.ts +3 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +25 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/core/config.d.ts +94 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +70 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/dev-server.d.ts +21 -0
- package/dist/core/dev-server.d.ts.map +1 -0
- package/dist/core/dev-server.js +113 -0
- package/dist/core/dev-server.js.map +1 -0
- package/dist/core/errors.d.ts +16 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +23 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/exml/ast.d.ts +243 -0
- package/dist/core/exml/ast.d.ts.map +1 -0
- package/dist/core/exml/ast.js +8 -0
- package/dist/core/exml/ast.js.map +1 -0
- package/dist/core/exml/codegen.d.ts +23 -0
- package/dist/core/exml/codegen.d.ts.map +1 -0
- package/dist/core/exml/codegen.js +422 -0
- package/dist/core/exml/codegen.js.map +1 -0
- package/dist/core/exml/exml-parser.d.ts +27 -0
- package/dist/core/exml/exml-parser.d.ts.map +1 -0
- package/dist/core/exml/exml-parser.js +466 -0
- package/dist/core/exml/exml-parser.js.map +1 -0
- package/dist/core/exml/index.d.ts +52 -0
- package/dist/core/exml/index.d.ts.map +1 -0
- package/dist/core/exml/index.js +51 -0
- package/dist/core/exml/index.js.map +1 -0
- package/dist/core/exml/registry.d.ts +92 -0
- package/dist/core/exml/registry.d.ts.map +1 -0
- package/dist/core/exml/registry.js +177 -0
- package/dist/core/exml/registry.js.map +1 -0
- package/dist/core/exml/xml-parser.d.ts +61 -0
- package/dist/core/exml/xml-parser.d.ts.map +1 -0
- package/dist/core/exml/xml-parser.js +201 -0
- package/dist/core/exml/xml-parser.js.map +1 -0
- package/dist/core/namespace-external-plugin.d.ts +45 -0
- package/dist/core/namespace-external-plugin.d.ts.map +1 -0
- package/dist/core/namespace-external-plugin.js +66 -0
- package/dist/core/namespace-external-plugin.js.map +1 -0
- package/dist/core/pipeline.d.ts +75 -0
- package/dist/core/pipeline.d.ts.map +1 -0
- package/dist/core/pipeline.js +30 -0
- package/dist/core/pipeline.js.map +1 -0
- package/dist/core/plugins/clean-output.d.ts +3 -0
- package/dist/core/plugins/clean-output.d.ts.map +1 -0
- package/dist/core/plugins/clean-output.js +11 -0
- package/dist/core/plugins/clean-output.js.map +1 -0
- package/dist/core/plugins/compile-custom-namespaces.d.ts +19 -0
- package/dist/core/plugins/compile-custom-namespaces.d.ts.map +1 -0
- package/dist/core/plugins/compile-custom-namespaces.js +104 -0
- package/dist/core/plugins/compile-custom-namespaces.js.map +1 -0
- package/dist/core/plugins/compile-engine.d.ts +19 -0
- package/dist/core/plugins/compile-engine.d.ts.map +1 -0
- package/dist/core/plugins/compile-engine.js +75 -0
- package/dist/core/plugins/compile-engine.js.map +1 -0
- package/dist/core/plugins/compile-exml.d.ts +14 -0
- package/dist/core/plugins/compile-exml.d.ts.map +1 -0
- package/dist/core/plugins/compile-exml.js +223 -0
- package/dist/core/plugins/compile-exml.js.map +1 -0
- package/dist/core/plugins/compile-source.d.ts +14 -0
- package/dist/core/plugins/compile-source.d.ts.map +1 -0
- package/dist/core/plugins/compile-source.js +132 -0
- package/dist/core/plugins/compile-source.js.map +1 -0
- package/dist/core/plugins/copy-assets.d.ts +12 -0
- package/dist/core/plugins/copy-assets.d.ts.map +1 -0
- package/dist/core/plugins/copy-assets.js +33 -0
- package/dist/core/plugins/copy-assets.js.map +1 -0
- package/dist/core/plugins/generate-html.d.ts +16 -0
- package/dist/core/plugins/generate-html.d.ts.map +1 -0
- package/dist/core/plugins/generate-html.js +137 -0
- package/dist/core/plugins/generate-html.js.map +1 -0
- package/dist/core/plugins/index.d.ts +21 -0
- package/dist/core/plugins/index.d.ts.map +1 -0
- package/dist/core/plugins/index.js +39 -0
- package/dist/core/plugins/index.js.map +1 -0
- package/dist/core/plugins/manifest.d.ts +14 -0
- package/dist/core/plugins/manifest.d.ts.map +1 -0
- package/dist/core/plugins/manifest.js +28 -0
- package/dist/core/plugins/manifest.js.map +1 -0
- package/dist/core/project.d.ts +95 -0
- package/dist/core/project.d.ts.map +1 -0
- package/dist/core/project.js +79 -0
- package/dist/core/project.js.map +1 -0
- package/dist/core/template.d.ts +13 -0
- package/dist/core/template.d.ts.map +1 -0
- package/dist/core/template.js +79 -0
- package/dist/core/template.js.map +1 -0
- package/dist/define.d.ts +2 -0
- package/dist/define.d.ts.map +1 -0
- package/dist/define.js +2 -0
- package/dist/define.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/fs.d.ts +5 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +30 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/logger.d.ts +11 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +18 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +45 -0
- package/templates/empty/kurot.config.ts +13 -0
- package/templates/empty/package.json +17 -0
- package/templates/empty/pnpm-workspace.yaml +3 -0
- package/templates/empty/src/Main.ts +32 -0
- package/templates/empty/template/web/index.html +38 -0
- package/templates/empty/tsconfig.json +10 -0
- package/templates/game/kurot.config.ts +16 -0
- package/templates/game/package.json +19 -0
- package/templates/game/pnpm-workspace.yaml +3 -0
- package/templates/game/resource/assets/eui.json +24 -0
- package/templates/game/resource/assets/eui.png +0 -0
- package/templates/game/resource/default.res.json +15 -0
- package/templates/game/resource/default.thm.json +19 -0
- package/templates/game/resource/skins/ButtonSkin.exml +16 -0
- package/templates/game/resource/skins/CheckBoxSkin.exml +18 -0
- package/templates/game/resource/skins/ComboBoxSkin.exml +31 -0
- package/templates/game/resource/skins/GroupSkin.exml +4 -0
- package/templates/game/resource/skins/HScrollBarSkin.exml +6 -0
- package/templates/game/resource/skins/HSliderSkin.exml +7 -0
- package/templates/game/resource/skins/ImageSkin.exml +4 -0
- package/templates/game/resource/skins/ItemRendererSkin.exml +15 -0
- package/templates/game/resource/skins/LabelSkin.exml +7 -0
- package/templates/game/resource/skins/ListSkin.exml +11 -0
- package/templates/game/resource/skins/PanelSkin.exml +15 -0
- package/templates/game/resource/skins/ProgressBarSkin.exml +11 -0
- package/templates/game/resource/skins/RadioButtonSkin.exml +18 -0
- package/templates/game/resource/skins/ScrollerSkin.exml +8 -0
- package/templates/game/resource/skins/TabBarSkin.exml +6 -0
- package/templates/game/resource/skins/TextInputSkin.exml +22 -0
- package/templates/game/resource/skins/ToggleButtonSkin.exml +21 -0
- package/templates/game/resource/skins/ToggleSwitchSkin.exml +15 -0
- package/templates/game/resource/skins/VScrollBarSkin.exml +6 -0
- package/templates/game/resource/skins/VSliderSkin.exml +7 -0
- package/templates/game/resource/skins/ViewStackSkin.exml +4 -0
- package/templates/game/src/LoadingUI.ts +27 -0
- package/templates/game/src/Main.ts +165 -0
- package/templates/game/template/web/index.html +109 -0
- package/templates/game/template/web/logo.png +0 -0
- package/templates/game/tsconfig.json +10 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static component registry for EXML → JS code generation.
|
|
3
|
+
*
|
|
4
|
+
* Maps short tag names (e.g. `Button`, `Skin`) to their module paths
|
|
5
|
+
* and default properties. This replaces the old runtime-reflection-based
|
|
6
|
+
* `EXMLConfig`.
|
|
7
|
+
*/
|
|
8
|
+
export interface ComponentInfo {
|
|
9
|
+
/**
|
|
10
|
+
* Module path to import from (e.g. "@kurot/ui").
|
|
11
|
+
*/
|
|
12
|
+
module: string;
|
|
13
|
+
/**
|
|
14
|
+
* The default property name — direct children are assigned here.
|
|
15
|
+
*/
|
|
16
|
+
defaultProperty?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Whether `defaultProperty` accepts an array (vs a single value).
|
|
19
|
+
*/
|
|
20
|
+
isArray?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* A project-defined EXML namespace, matching Egret's `xmlns:game="game.*"`
|
|
24
|
+
* convention (see `ProjectConfig.exml.namespaces` in `@kurot/cli`).
|
|
25
|
+
*/
|
|
26
|
+
export interface NamespaceModule {
|
|
27
|
+
/**
|
|
28
|
+
* The XML namespace prefix (e.g. `game` for `xmlns:game="game.*"`).
|
|
29
|
+
*/
|
|
30
|
+
readonly prefix: string;
|
|
31
|
+
/**
|
|
32
|
+
* Virtual module specifier resolved via the HTML import map.
|
|
33
|
+
*/
|
|
34
|
+
readonly specifier: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Look up a component by its tag name.
|
|
38
|
+
*
|
|
39
|
+
* Project-defined namespaces (`customNamespaces`) take priority when the
|
|
40
|
+
* tag's prefix matches one: this mirrors Egret's `xmlns:game="game.*"`
|
|
41
|
+
* convention, where the prefix alone — not the declared xmlns URI — decides
|
|
42
|
+
* which module a tag resolves to (the same is true of the built-in `eui`/
|
|
43
|
+
* `egret` prefixes below).
|
|
44
|
+
*
|
|
45
|
+
* @param tagName - Full tag name possibly with prefix (e.g. "eui:Button")
|
|
46
|
+
* @param customNamespaces - Project-defined namespaces from `kurot.config.ts`
|
|
47
|
+
* @returns Component info or null if not found
|
|
48
|
+
*/
|
|
49
|
+
export declare function lookupComponent(tagName: string, customNamespaces?: readonly NamespaceModule[]): ComponentInfo | null;
|
|
50
|
+
/**
|
|
51
|
+
* Get the default property for a component.
|
|
52
|
+
*
|
|
53
|
+
* @param tagName - Full tag name possibly with prefix (e.g. "eui:Button")
|
|
54
|
+
* @param customNamespaces - Project-defined namespaces from `kurot.config.ts`
|
|
55
|
+
* @returns The default property name, or `undefined` if the component is unknown
|
|
56
|
+
*/
|
|
57
|
+
export declare function getDefaultProperty(tagName: string, customNamespaces?: readonly NamespaceModule[]): string | undefined;
|
|
58
|
+
/**
|
|
59
|
+
* Resolve a tag name to its import module path.
|
|
60
|
+
*
|
|
61
|
+
* @param tagName - Full tag name possibly with prefix (e.g. "eui:Button")
|
|
62
|
+
* @param customNamespaces - Project-defined namespaces from `kurot.config.ts`
|
|
63
|
+
* @returns The module path, or `null` if the tag could not be resolved
|
|
64
|
+
*/
|
|
65
|
+
export declare function resolveModule(tagName: string, customNamespaces?: readonly NamespaceModule[]): string | null;
|
|
66
|
+
/**
|
|
67
|
+
* Get the local (un-prefixed) class name from a tag name.
|
|
68
|
+
*
|
|
69
|
+
* @param tagName - Full tag name possibly with prefix (e.g. "eui:Button")
|
|
70
|
+
* @returns The local class name (e.g. "Button")
|
|
71
|
+
*/
|
|
72
|
+
export declare function localName(tagName: string): string;
|
|
73
|
+
/**
|
|
74
|
+
* Checks if a tag name is a known property node (contains a dot).
|
|
75
|
+
*
|
|
76
|
+
* e.g. "eui:Button.label" → property "label" on `Button`.
|
|
77
|
+
*
|
|
78
|
+
* @param tagName - Full tag name to check
|
|
79
|
+
* @returns Whether the tag name contains a dot
|
|
80
|
+
*/
|
|
81
|
+
export declare function isPropertyNode(tagName: string): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Parse a property node tag like "eui:Button.label" into its parts.
|
|
84
|
+
*
|
|
85
|
+
* @param tagName - Full property node tag name
|
|
86
|
+
* @returns The owner class and property name, or `null` if not a property node
|
|
87
|
+
*/
|
|
88
|
+
export declare function parsePropertyNode(tagName: string): {
|
|
89
|
+
owner: string;
|
|
90
|
+
property: string;
|
|
91
|
+
} | null;
|
|
92
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/core/exml/registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,aAAa;IAC7B;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC/B;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC3B;AA8FD;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAC9B,OAAO,EAAE,MAAM,EACf,gBAAgB,GAAE,SAAS,eAAe,EAAO,GAC/C,aAAa,GAAG,IAAI,CAStB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CACjC,OAAO,EAAE,MAAM,EACf,gBAAgB,GAAE,SAAS,eAAe,EAAO,GAC/C,MAAM,GAAG,SAAS,CAGpB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,gBAAgB,GAAE,SAAS,eAAe,EAAO,GAAG,MAAM,GAAG,IAAI,CAa/G;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAO7F"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static component registry for EXML → JS code generation.
|
|
3
|
+
*
|
|
4
|
+
* Maps short tag names (e.g. `Button`, `Skin`) to their module paths
|
|
5
|
+
* and default properties. This replaces the old runtime-reflection-based
|
|
6
|
+
* `EXMLConfig`.
|
|
7
|
+
*/
|
|
8
|
+
// ── Namespace mappings ───────────────────────────────────────────────
|
|
9
|
+
/**
|
|
10
|
+
* Maps XML namespace prefixes to module import paths.
|
|
11
|
+
*/
|
|
12
|
+
const NAMESPACE_MODULES = {
|
|
13
|
+
eui: '@kurot/ui',
|
|
14
|
+
egret: '@kurot/core',
|
|
15
|
+
w: '@kurot/ui',
|
|
16
|
+
core: '@kurot/core',
|
|
17
|
+
};
|
|
18
|
+
// ── Component registry ───────────────────────────────────────────────
|
|
19
|
+
/**
|
|
20
|
+
* All known components with their default properties.
|
|
21
|
+
* Key is the local (un-prefixed) tag name.
|
|
22
|
+
*/
|
|
23
|
+
const COMPONENTS = {
|
|
24
|
+
// Skins & containers
|
|
25
|
+
Skin: { module: '@kurot/ui', defaultProperty: 'elementsContent', isArray: true },
|
|
26
|
+
Group: { module: '@kurot/ui', defaultProperty: 'elementsContent', isArray: true },
|
|
27
|
+
Panel: { module: '@kurot/ui', defaultProperty: 'elementsContent', isArray: true },
|
|
28
|
+
DataGroup: { module: '@kurot/ui', defaultProperty: 'dataProvider', isArray: false },
|
|
29
|
+
Scroller: { module: '@kurot/ui', defaultProperty: 'viewport', isArray: false },
|
|
30
|
+
// Basic controls
|
|
31
|
+
Button: { module: '@kurot/ui' },
|
|
32
|
+
Label: { module: '@kurot/ui' },
|
|
33
|
+
Image: { module: '@kurot/ui' },
|
|
34
|
+
Rect: { module: '@kurot/ui' },
|
|
35
|
+
CheckBox: { module: '@kurot/ui' },
|
|
36
|
+
RadioButton: { module: '@kurot/ui' },
|
|
37
|
+
ToggleButton: { module: '@kurot/ui' },
|
|
38
|
+
ToggleSwitch: { module: '@kurot/ui' },
|
|
39
|
+
ProgressBar: { module: '@kurot/ui' },
|
|
40
|
+
HSlider: { module: '@kurot/ui' },
|
|
41
|
+
VSlider: { module: '@kurot/ui' },
|
|
42
|
+
HScrollBar: { module: '@kurot/ui' },
|
|
43
|
+
VScrollBar: { module: '@kurot/ui' },
|
|
44
|
+
TabBar: { module: '@kurot/ui' },
|
|
45
|
+
List: { module: '@kurot/ui', defaultProperty: 'dataProvider', isArray: false },
|
|
46
|
+
ItemRenderer: { module: '@kurot/ui', defaultProperty: 'elementsContent', isArray: true },
|
|
47
|
+
ViewStack: { module: '@kurot/ui', defaultProperty: 'elementsContent', isArray: true },
|
|
48
|
+
UILayer: { module: '@kurot/ui', defaultProperty: 'elementsContent', isArray: true },
|
|
49
|
+
// Text input controls
|
|
50
|
+
TextInput: { module: '@kurot/ui' },
|
|
51
|
+
EditableText: { module: '@kurot/ui' },
|
|
52
|
+
// Layouts
|
|
53
|
+
Layout: { module: '@kurot/ui' },
|
|
54
|
+
BasicLayout: { module: '@kurot/ui' },
|
|
55
|
+
HorizontalLayout: { module: '@kurot/ui' },
|
|
56
|
+
VerticalLayout: { module: '@kurot/ui' },
|
|
57
|
+
TileLayout: { module: '@kurot/ui' },
|
|
58
|
+
// States
|
|
59
|
+
State: { module: '@kurot/ui' },
|
|
60
|
+
AddItems: { module: '@kurot/ui' },
|
|
61
|
+
SetProperty: { module: '@kurot/ui' },
|
|
62
|
+
SetStateProperty: { module: '@kurot/ui' },
|
|
63
|
+
// Collections
|
|
64
|
+
ArrayCollection: { module: '@kurot/ui', defaultProperty: 'source', isArray: true },
|
|
65
|
+
// Binding
|
|
66
|
+
Binding: { module: '@kurot/ui' },
|
|
67
|
+
// Core classes (egret namespace)
|
|
68
|
+
DisplayObject: { module: '@kurot/core' },
|
|
69
|
+
DisplayObjectContainer: { module: '@kurot/core' },
|
|
70
|
+
Sprite: { module: '@kurot/core' },
|
|
71
|
+
TextField: { module: '@kurot/core' },
|
|
72
|
+
Bitmap: { module: '@kurot/core' },
|
|
73
|
+
Shape: { module: '@kurot/core' },
|
|
74
|
+
Point: { module: '@kurot/core' },
|
|
75
|
+
Rectangle: { module: '@kurot/core' },
|
|
76
|
+
Matrix: { module: '@kurot/core' },
|
|
77
|
+
Event: { module: '@kurot/core' },
|
|
78
|
+
EventDispatcher: { module: '@kurot/core' },
|
|
79
|
+
Timer: { module: '@kurot/core' },
|
|
80
|
+
// Complex controls
|
|
81
|
+
ComboBox: { module: '@kurot/ui', defaultProperty: 'dataProvider', isArray: false },
|
|
82
|
+
// Animation
|
|
83
|
+
Animation: { module: '@kurot/ui' },
|
|
84
|
+
};
|
|
85
|
+
// ── Public API ───────────────────────────────────────────────────────
|
|
86
|
+
/**
|
|
87
|
+
* Look up a component by its tag name.
|
|
88
|
+
*
|
|
89
|
+
* Project-defined namespaces (`customNamespaces`) take priority when the
|
|
90
|
+
* tag's prefix matches one: this mirrors Egret's `xmlns:game="game.*"`
|
|
91
|
+
* convention, where the prefix alone — not the declared xmlns URI — decides
|
|
92
|
+
* which module a tag resolves to (the same is true of the built-in `eui`/
|
|
93
|
+
* `egret` prefixes below).
|
|
94
|
+
*
|
|
95
|
+
* @param tagName - Full tag name possibly with prefix (e.g. "eui:Button")
|
|
96
|
+
* @param customNamespaces - Project-defined namespaces from `kurot.config.ts`
|
|
97
|
+
* @returns Component info or null if not found
|
|
98
|
+
*/
|
|
99
|
+
export function lookupComponent(tagName, customNamespaces = []) {
|
|
100
|
+
const prefix = tagName.includes(':') ? tagName.split(':')[0] : '';
|
|
101
|
+
if (prefix) {
|
|
102
|
+
const custom = customNamespaces.find(ns => ns.prefix === prefix);
|
|
103
|
+
if (custom)
|
|
104
|
+
return { module: custom.specifier };
|
|
105
|
+
}
|
|
106
|
+
const local = localName(tagName);
|
|
107
|
+
return COMPONENTS[local] ?? null;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Get the default property for a component.
|
|
111
|
+
*
|
|
112
|
+
* @param tagName - Full tag name possibly with prefix (e.g. "eui:Button")
|
|
113
|
+
* @param customNamespaces - Project-defined namespaces from `kurot.config.ts`
|
|
114
|
+
* @returns The default property name, or `undefined` if the component is unknown
|
|
115
|
+
*/
|
|
116
|
+
export function getDefaultProperty(tagName, customNamespaces = []) {
|
|
117
|
+
const info = lookupComponent(tagName, customNamespaces);
|
|
118
|
+
return info?.defaultProperty;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Resolve a tag name to its import module path.
|
|
122
|
+
*
|
|
123
|
+
* @param tagName - Full tag name possibly with prefix (e.g. "eui:Button")
|
|
124
|
+
* @param customNamespaces - Project-defined namespaces from `kurot.config.ts`
|
|
125
|
+
* @returns The module path, or `null` if the tag could not be resolved
|
|
126
|
+
*/
|
|
127
|
+
export function resolveModule(tagName, customNamespaces = []) {
|
|
128
|
+
// Check for namespace prefix first
|
|
129
|
+
if (tagName.includes(':')) {
|
|
130
|
+
const [prefix] = tagName.split(':');
|
|
131
|
+
const custom = customNamespaces.find(ns => ns.prefix === prefix);
|
|
132
|
+
if (custom)
|
|
133
|
+
return custom.specifier;
|
|
134
|
+
const modulePath = NAMESPACE_MODULES[prefix];
|
|
135
|
+
if (modulePath)
|
|
136
|
+
return modulePath;
|
|
137
|
+
}
|
|
138
|
+
// Fall back to component registry
|
|
139
|
+
const info = lookupComponent(tagName, customNamespaces);
|
|
140
|
+
return info?.module ?? null;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Get the local (un-prefixed) class name from a tag name.
|
|
144
|
+
*
|
|
145
|
+
* @param tagName - Full tag name possibly with prefix (e.g. "eui:Button")
|
|
146
|
+
* @returns The local class name (e.g. "Button")
|
|
147
|
+
*/
|
|
148
|
+
export function localName(tagName) {
|
|
149
|
+
return tagName.includes(':') ? tagName.split(':').pop() : tagName;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Checks if a tag name is a known property node (contains a dot).
|
|
153
|
+
*
|
|
154
|
+
* e.g. "eui:Button.label" → property "label" on `Button`.
|
|
155
|
+
*
|
|
156
|
+
* @param tagName - Full tag name to check
|
|
157
|
+
* @returns Whether the tag name contains a dot
|
|
158
|
+
*/
|
|
159
|
+
export function isPropertyNode(tagName) {
|
|
160
|
+
return tagName.includes('.');
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Parse a property node tag like "eui:Button.label" into its parts.
|
|
164
|
+
*
|
|
165
|
+
* @param tagName - Full property node tag name
|
|
166
|
+
* @returns The owner class and property name, or `null` if not a property node
|
|
167
|
+
*/
|
|
168
|
+
export function parsePropertyNode(tagName) {
|
|
169
|
+
// First strip namespace prefix
|
|
170
|
+
const parts = tagName.split('.');
|
|
171
|
+
if (parts.length < 2)
|
|
172
|
+
return null;
|
|
173
|
+
const ownerPart = parts[0];
|
|
174
|
+
const property = parts.slice(1).join('.');
|
|
175
|
+
return { owner: localName(ownerPart), property };
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/core/exml/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight XML parser for EXML files.
|
|
3
|
+
*
|
|
4
|
+
* Designed to handle the subset of XML used by EXML skin definitions:
|
|
5
|
+
* - Element nodes with namespace-prefixed tags
|
|
6
|
+
* - Text nodes (including whitespace)
|
|
7
|
+
* - Attribute values (quoted)
|
|
8
|
+
* - Self-closing elements
|
|
9
|
+
* - CDATA sections
|
|
10
|
+
* - XML comments and processing instructions (skipped)
|
|
11
|
+
*
|
|
12
|
+
* Does NOT support:
|
|
13
|
+
* - DTD / ENTITY declarations
|
|
14
|
+
* - Namespaced attribute prefixes (we only care about the local name)
|
|
15
|
+
*/
|
|
16
|
+
export interface XNode {
|
|
17
|
+
/**
|
|
18
|
+
* Node type.
|
|
19
|
+
*/
|
|
20
|
+
readonly type: 'element' | 'text';
|
|
21
|
+
}
|
|
22
|
+
export interface XText extends XNode {
|
|
23
|
+
readonly type: 'text';
|
|
24
|
+
/**
|
|
25
|
+
* Raw text content (may be whitespace).
|
|
26
|
+
*/
|
|
27
|
+
readonly text: string;
|
|
28
|
+
}
|
|
29
|
+
export interface XAttribute {
|
|
30
|
+
/**
|
|
31
|
+
* Full attribute name including prefix (e.g. "eui:label").
|
|
32
|
+
*/
|
|
33
|
+
readonly name: string;
|
|
34
|
+
/**
|
|
35
|
+
* Attribute value (unescaped).
|
|
36
|
+
*/
|
|
37
|
+
readonly value: string;
|
|
38
|
+
}
|
|
39
|
+
export interface XElement extends XNode {
|
|
40
|
+
readonly type: 'element';
|
|
41
|
+
/**
|
|
42
|
+
* Full tag name including prefix (e.g. "eui:Button").
|
|
43
|
+
*/
|
|
44
|
+
readonly name: string;
|
|
45
|
+
/**
|
|
46
|
+
* Attributes in order.
|
|
47
|
+
*/
|
|
48
|
+
readonly attributes: XAttribute[];
|
|
49
|
+
/**
|
|
50
|
+
* Child nodes (elements and text).
|
|
51
|
+
*/
|
|
52
|
+
readonly children: XNode[];
|
|
53
|
+
}
|
|
54
|
+
export declare function filterElements(children: readonly XNode[]): XElement[];
|
|
55
|
+
export declare function getTextContent(children: readonly XNode[]): string;
|
|
56
|
+
/**
|
|
57
|
+
* Parse an EXML string into an XML element tree.
|
|
58
|
+
* Returns the root element (the `<eui:Skin>` or equivalent).
|
|
59
|
+
*/
|
|
60
|
+
export declare function parseXML(source: string): XElement;
|
|
61
|
+
//# sourceMappingURL=xml-parser.d.ts.map
|
|
@@ -0,0 +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;CAClC;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;CACvB;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"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight XML parser for EXML files.
|
|
3
|
+
*
|
|
4
|
+
* Designed to handle the subset of XML used by EXML skin definitions:
|
|
5
|
+
* - Element nodes with namespace-prefixed tags
|
|
6
|
+
* - Text nodes (including whitespace)
|
|
7
|
+
* - Attribute values (quoted)
|
|
8
|
+
* - Self-closing elements
|
|
9
|
+
* - CDATA sections
|
|
10
|
+
* - XML comments and processing instructions (skipped)
|
|
11
|
+
*
|
|
12
|
+
* Does NOT support:
|
|
13
|
+
* - DTD / ENTITY declarations
|
|
14
|
+
* - Namespaced attribute prefixes (we only care about the local name)
|
|
15
|
+
*/
|
|
16
|
+
// ── Helpers ──────────────────────────────────────────────────────────
|
|
17
|
+
function isText(node) {
|
|
18
|
+
return node.type === 'text';
|
|
19
|
+
}
|
|
20
|
+
export function filterElements(children) {
|
|
21
|
+
return children.filter((n) => n.type === 'element');
|
|
22
|
+
}
|
|
23
|
+
export function getTextContent(children) {
|
|
24
|
+
return children
|
|
25
|
+
.filter(isText)
|
|
26
|
+
.map(t => t.text)
|
|
27
|
+
.join('');
|
|
28
|
+
}
|
|
29
|
+
// ── Parser implementation ────────────────────────────────────────────
|
|
30
|
+
/**
|
|
31
|
+
* Parse an EXML string into an XML element tree.
|
|
32
|
+
* Returns the root element (the `<eui:Skin>` or equivalent).
|
|
33
|
+
*/
|
|
34
|
+
export function parseXML(source) {
|
|
35
|
+
const parser = new _Parser(source);
|
|
36
|
+
const nodes = parser.parse();
|
|
37
|
+
// Find the first element node (skip whitespace text, comments, PI)
|
|
38
|
+
for (const n of nodes) {
|
|
39
|
+
if (n.type === 'element')
|
|
40
|
+
return n;
|
|
41
|
+
}
|
|
42
|
+
throw new Error('EXML: no root element found');
|
|
43
|
+
}
|
|
44
|
+
// ── Internal parser ──────────────────────────────────────────────────
|
|
45
|
+
const RX_OPEN = /^<([a-zA-Z_][\w:.-]*)/;
|
|
46
|
+
const RX_CLOSE = /^<\/([a-zA-Z_][\w:.-]*)\s*>/;
|
|
47
|
+
const RX_ATTR = /^([a-zA-Z_][\w:.-]*)\s*=\s*(?:"([^"]*)"|'([^']*)')/;
|
|
48
|
+
class _Parser {
|
|
49
|
+
src;
|
|
50
|
+
pos = 0;
|
|
51
|
+
constructor(source) {
|
|
52
|
+
this.src = source;
|
|
53
|
+
}
|
|
54
|
+
// ── Main entry ────────────────────────────────────────────────────
|
|
55
|
+
parse() {
|
|
56
|
+
this.skipWhitespace();
|
|
57
|
+
return this.parseNodes();
|
|
58
|
+
}
|
|
59
|
+
// ── Node list ─────────────────────────────────────────────────────
|
|
60
|
+
parseNodes() {
|
|
61
|
+
const nodes = [];
|
|
62
|
+
while (this.pos < this.src.length) {
|
|
63
|
+
// End of parent element?
|
|
64
|
+
if (this.src[this.pos] === '<') {
|
|
65
|
+
// Closing tag?
|
|
66
|
+
const m = this.src.slice(this.pos).match(RX_CLOSE);
|
|
67
|
+
if (m)
|
|
68
|
+
break; // let parent handle it
|
|
69
|
+
// Comment
|
|
70
|
+
if (this.src.startsWith('<!--', this.pos)) {
|
|
71
|
+
this.skipComment();
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
// CDATA
|
|
75
|
+
if (this.src.startsWith('<![CDATA[', this.pos)) {
|
|
76
|
+
nodes.push({ type: 'text', text: this.readCDATA() });
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
// Processing instruction <?...?>
|
|
80
|
+
if (this.src.startsWith('<?', this.pos)) {
|
|
81
|
+
this.skipPI();
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
// Element
|
|
85
|
+
const el = this.parseElement();
|
|
86
|
+
if (el)
|
|
87
|
+
nodes.push(el);
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
// Text content
|
|
91
|
+
nodes.push(this.readText());
|
|
92
|
+
}
|
|
93
|
+
return nodes;
|
|
94
|
+
}
|
|
95
|
+
// ── Element ───────────────────────────────────────────────────────
|
|
96
|
+
parseElement() {
|
|
97
|
+
const start = this.pos;
|
|
98
|
+
if (this.src[this.pos] !== '<')
|
|
99
|
+
return null;
|
|
100
|
+
const rest = this.src.slice(this.pos);
|
|
101
|
+
const tagMatch = rest.match(RX_OPEN);
|
|
102
|
+
if (!tagMatch) {
|
|
103
|
+
// Malformed — skip the '<' and continue
|
|
104
|
+
this.pos++;
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
const tagName = tagMatch[1];
|
|
108
|
+
this.pos += tagMatch[0].length;
|
|
109
|
+
// Parse attributes
|
|
110
|
+
const attrs = [];
|
|
111
|
+
for (;;) {
|
|
112
|
+
this.skipWS();
|
|
113
|
+
if (this.pos >= this.src.length)
|
|
114
|
+
break;
|
|
115
|
+
// Self-closing />
|
|
116
|
+
if (this.src.startsWith('/>', this.pos)) {
|
|
117
|
+
this.pos += 2;
|
|
118
|
+
return { type: 'element', name: tagName, attributes: attrs, children: [] };
|
|
119
|
+
}
|
|
120
|
+
// Open tag end >
|
|
121
|
+
if (this.src[this.pos] === '>') {
|
|
122
|
+
this.pos++;
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
// Attribute
|
|
126
|
+
const am = this.src.slice(this.pos).match(RX_ATTR);
|
|
127
|
+
if (am) {
|
|
128
|
+
attrs.push({ name: am[1], value: am[2] ?? am[3] });
|
|
129
|
+
this.pos += am[0].length;
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
// Unexpected character — skip
|
|
133
|
+
this.pos++;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// Children
|
|
137
|
+
const children = this.parseNodes();
|
|
138
|
+
// Consume closing tag
|
|
139
|
+
const closeMatch = this.src.slice(this.pos).match(RX_CLOSE);
|
|
140
|
+
if (closeMatch) {
|
|
141
|
+
if (closeMatch[1] !== tagName) {
|
|
142
|
+
throw new Error(`EXML: expected closing tag </${tagName}>, got </${closeMatch[1]}>`);
|
|
143
|
+
}
|
|
144
|
+
this.pos += closeMatch[0].length;
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
throw new Error(`EXML: missing closing tag </${tagName}>`);
|
|
148
|
+
}
|
|
149
|
+
return { type: 'element', name: tagName, attributes: attrs, children };
|
|
150
|
+
}
|
|
151
|
+
// ── Text ──────────────────────────────────────────────────────────
|
|
152
|
+
readText() {
|
|
153
|
+
let text = '';
|
|
154
|
+
while (this.pos < this.src.length && this.src[this.pos] !== '<') {
|
|
155
|
+
text += this.src[this.pos++];
|
|
156
|
+
}
|
|
157
|
+
return { type: 'text', text: unescapeXML(text) };
|
|
158
|
+
}
|
|
159
|
+
// ── CDATA ─────────────────────────────────────────────────────────
|
|
160
|
+
readCDATA() {
|
|
161
|
+
const start = this.pos;
|
|
162
|
+
this.pos += 9; // skip '<![CDATA['
|
|
163
|
+
const end = this.src.indexOf(']]>', this.pos);
|
|
164
|
+
if (end === -1) {
|
|
165
|
+
this.pos = this.src.length;
|
|
166
|
+
return this.src.slice(start);
|
|
167
|
+
}
|
|
168
|
+
const content = this.src.slice(this.pos, end);
|
|
169
|
+
this.pos = end + 3;
|
|
170
|
+
return content;
|
|
171
|
+
}
|
|
172
|
+
// ── Skip helpers ──────────────────────────────────────────────────
|
|
173
|
+
skipComment() {
|
|
174
|
+
const end = this.src.indexOf('-->', this.pos + 4);
|
|
175
|
+
this.pos = end === -1 ? this.src.length : end + 3;
|
|
176
|
+
}
|
|
177
|
+
skipPI() {
|
|
178
|
+
const end = this.src.indexOf('?>', this.pos + 2);
|
|
179
|
+
this.pos = end === -1 ? this.src.length : end + 2;
|
|
180
|
+
}
|
|
181
|
+
skipWS() {
|
|
182
|
+
while (this.pos < this.src.length && /\s/.test(this.src[this.pos]))
|
|
183
|
+
this.pos++;
|
|
184
|
+
}
|
|
185
|
+
skipWhitespace() {
|
|
186
|
+
this.skipWS();
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// ── Unescape XML entities ────────────────────────────────────────────
|
|
190
|
+
function unescapeXML(s) {
|
|
191
|
+
// Use hex char codes to avoid auto-formatter converting XML entities
|
|
192
|
+
const ENTITIES = {
|
|
193
|
+
amp: '\x26',
|
|
194
|
+
lt: '\x3C',
|
|
195
|
+
gt: '\x3E',
|
|
196
|
+
quot: '\x22',
|
|
197
|
+
apos: '\x27',
|
|
198
|
+
};
|
|
199
|
+
return s.replace(/&(amp|lt|gt|quot|apos);/g, (m, name) => ENTITIES[name] ?? m);
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=xml-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xml-parser.js","sourceRoot":"","sources":["../../../src/core/exml/xml-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type * as esbuild from 'esbuild';
|
|
2
|
+
/**
|
|
3
|
+
* Normalizes an absolute file path into a namespace-module lookup key by
|
|
4
|
+
* stripping its extension, if present.
|
|
5
|
+
*
|
|
6
|
+
* Both sides of the lookup go through this: `compile-custom-namespaces.ts`
|
|
7
|
+
* keys `ctx.outputs.namespaceModules` by the exact files esbuild reports it
|
|
8
|
+
* inlined (`metafile.outputs[x].inputs`), and `namespaceModuleExternalPlugin`
|
|
9
|
+
* normalizes a resolved import path the same way before checking the map.
|
|
10
|
+
* Stripping the extension is what lets a `./HeroNarrowIR.js` import (the
|
|
11
|
+
* `.js`-suffixed ESM import convention used throughout this codebase, e.g.
|
|
12
|
+
* `import { HeroNarrowIR } from './ui/index.js'`) match its `HeroNarrowIR.ts`
|
|
13
|
+
* source file (the metafile key).
|
|
14
|
+
*
|
|
15
|
+
* @param absolutePath - Absolute file path to normalize
|
|
16
|
+
* @returns The path with its extension stripped, if any
|
|
17
|
+
*/
|
|
18
|
+
export declare function normalizeModuleKey(absolutePath: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Rewrites imports that resolve to a project-defined namespace's source files
|
|
21
|
+
* to that namespace's virtual specifier, marking them external.
|
|
22
|
+
*
|
|
23
|
+
* A custom-namespace class (e.g. `HeroNarrowIR`) can be referenced two ways:
|
|
24
|
+
* game code imports it by relative path (`./ui/HeroNarrowIR.js`), while
|
|
25
|
+
* EXML-generated skins import it by the virtual specifier (`#ns/game`,
|
|
26
|
+
* resolved via the HTML import map — see `compile-custom-namespaces.ts`).
|
|
27
|
+
* `external: [specifier]` alone only catches the second case; esbuild matches
|
|
28
|
+
* externals by the literal import string, so the relative import would
|
|
29
|
+
* otherwise get inlined as a second, distinct copy of the class with
|
|
30
|
+
* mismatched `instanceof` identity.
|
|
31
|
+
*
|
|
32
|
+
* `namespaceModules` is precise (sourced from esbuild's own metafile, not a
|
|
33
|
+
* guess), so this covers every file a namespace chunk actually inlined — not
|
|
34
|
+
* just its barrel entry point. Deliberately synchronous and does no file
|
|
35
|
+
* system I/O: esbuild's own docs warn against calling `build.resolve()`
|
|
36
|
+
* recursively from within `onResolve` (no loop detection), and this codebase's
|
|
37
|
+
* `.js`-suffixed import convention (see `normalizeModuleKey`) makes that
|
|
38
|
+
* unnecessary — a plain path + extension-strip is enough to match.
|
|
39
|
+
*
|
|
40
|
+
* @param namespaceModules - Extensionless absolute path → virtual specifier,
|
|
41
|
+
* populated from esbuild's `metafile.outputs[x].inputs` (see `compile-custom-namespaces.ts`)
|
|
42
|
+
* @returns An esbuild plugin implementing the rewrite
|
|
43
|
+
*/
|
|
44
|
+
export declare function namespaceModuleExternalPlugin(namespaceModules: ReadonlyMap<string, string>): esbuild.Plugin;
|
|
45
|
+
//# sourceMappingURL=namespace-external-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"namespace-external-plugin.d.ts","sourceRoot":"","sources":["../../src/core/namespace-external-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,OAAO,MAAM,SAAS,CAAC;AAGxC;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAG/D;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,6BAA6B,CAAC,gBAAgB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAkB3G"}
|