@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
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@kurot/cli` are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## Unreleased
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Project-owned HTML templates through `html.template`, with explicit placeholders for the import map, entry script, and stage settings.
|
|
13
|
+
- Editable `template/web/index.html` files in both the `game` and `empty` project templates.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- The default page centers the game canvas horizontally and vertically.
|
|
18
|
+
- Development builds clear the previous output before compiling and place shared application chunks under `js/chunks/`.
|
|
19
|
+
|
|
20
|
+
## 1.0.0 — 2026-08-06
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- **`scale9Grid` attribute compiled to `new Rectangle()`** — EXML attributes like `scale9Grid="1,3,8,8"` are now compiled to `new Rectangle(1, 3, 8, 8)` instead of being passed as a raw string. Core `Rectangle` is automatically imported when a skin contains any `scale9Grid` property.
|
|
25
|
+
- **Lowercase property-node shorthand** — `<eui:layout><eui:HorizontalLayout/></eui:layout>` is now accepted as a shorthand for the Egret-qualified `<eui:Group.layout>` tag, bringing EXML parsing closer to Egret's original behaviour.
|
|
26
|
+
- **Game template: resource-aware asset adapter** — `Main.ts` now installs a custom `AssetAdapter` that resolves EXML `source` strings through `resource.get<Texture>()` first (supports preloaded atlases and sprite sheets), falling back to the default URL-based `ImageLoader`.
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- **Updated all game-template skins** — Button, CheckBox, HScrollBar, HSlider, ItemRenderer, Panel, ProgressBar, RadioButton, TextInput, ToggleSwitch, VScrollBar, and VSlider skins modernised with consistent constraints, state names, and sizing conventions matching Egret EUI defaults.
|
|
31
|
+
- Release builds now fail on invalid EXML instead of silently publishing an empty skin stub; development builds continue with a warning for faster iteration.
|
|
32
|
+
|
|
33
|
+
### Tests
|
|
34
|
+
|
|
35
|
+
- `test/exml-parser.test.ts`: 2 new cases (scale9Grid Rectangle compilation, lowercase property-node shorthand).
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 0.7.2 — 2026-08-06
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
|
|
43
|
+
- **TextInputSkin**: `textDisplay` and `promptDisplay` now use `left="10"` / `right="10"` constraints so their layout bounds match the input background and native StageText overlay.
|
|
44
|
+
- Updated the game-template documentation to describe its current `UILayer` / `createChildren()` lifecycle and the recommended custom-component initialization hooks.
|
|
45
|
+
- Release builds now fail on invalid EXML instead of silently publishing an empty skin stub; development builds continue with a warning for faster iteration.
|
|
46
|
+
|
|
47
|
+
## 0.7.1 — 2026-08-06
|
|
48
|
+
|
|
49
|
+
### Changed
|
|
50
|
+
|
|
51
|
+
- **HSliderSkin / VSliderSkin**: tracks now use `width="100%"` / `height="100%"` instead of inset `left`/`right` / `top`/`bottom` constraints, aligning with the `@kurot/ui` 1.1.0 fix that positions the thumb relative to the track's layout bounds.
|
|
52
|
+
- **TextInputSkin**: `textDisplay` and `promptDisplay` use a fixed height with `verticalCenter`; `promptDisplay` sets `multiline="false"` / `wordWrap="false"` to prevent accidental wrapping of placeholder text.
|
|
53
|
+
|
|
54
|
+
## 0.7.0 - 2026-08-06
|
|
55
|
+
|
|
56
|
+
### Added
|
|
57
|
+
|
|
58
|
+
- Support for root `Skin` properties such as `minWidth` and `minHeight` during EXML compilation.
|
|
59
|
+
- Support for shorthand `states="up,down,disabled"` declarations and root state-specific properties.
|
|
60
|
+
- Support for `excludeFrom` as well as `includeIn` when generating state overrides.
|
|
61
|
+
- Parser and code-generation coverage for every EXML skin included in the game template.
|
|
62
|
+
|
|
63
|
+
### Changed
|
|
64
|
+
|
|
65
|
+
- Updated the default game-template skins to follow Egret EUI state and sizing conventions more closely.
|
|
66
|
+
- Made control, container, slider, and scrollbar skins responsive through constraints and minimum dimensions.
|
|
67
|
+
|
|
68
|
+
## 0.6.1 - 2026-07-16
|
|
69
|
+
|
|
70
|
+
### Added
|
|
71
|
+
|
|
72
|
+
- Support for project-defined EXML namespace prefixes through `exml.namespaces`.
|
|
73
|
+
- Shared namespace chunks so classes referenced by both game code and EXML retain the same module identity.
|
|
74
|
+
|
|
75
|
+
## 0.6.0 - 2026-06-08
|
|
76
|
+
|
|
77
|
+
### Changed
|
|
78
|
+
|
|
79
|
+
- Compiled all EXML skins into a bundled ESM theme module loaded dynamically by the runtime.
|
|
80
|
+
- Stopped shipping source `.exml` files in release output.
|
|
81
|
+
|
|
82
|
+
## 0.5.1 - 2026-06-07
|
|
83
|
+
|
|
84
|
+
### Changed
|
|
85
|
+
|
|
86
|
+
- Added npm publishing configuration and package metadata updates.
|
|
87
|
+
|
|
88
|
+
## 0.5.0 - 2026-06-07
|
|
89
|
+
|
|
90
|
+
### Added
|
|
91
|
+
|
|
92
|
+
- Split Kurot engine packages into independent browser chunks.
|
|
93
|
+
- Generated import maps and manifests to connect application, engine, and theme modules without duplication.
|
|
94
|
+
|
|
95
|
+
## 0.4.0 - 2026-06-06
|
|
96
|
+
|
|
97
|
+
### Changed
|
|
98
|
+
|
|
99
|
+
- Reworked the build system around an extensible plugin pipeline.
|
|
100
|
+
|
|
101
|
+
## 0.3.11 - 2026-05-08
|
|
102
|
+
|
|
103
|
+
### Changed
|
|
104
|
+
|
|
105
|
+
- Switched release builds to two-pass bundling with content-hashed filenames.
|
|
106
|
+
|
|
107
|
+
## 0.3.0 - 2026-05-07
|
|
108
|
+
|
|
109
|
+
### Added
|
|
110
|
+
|
|
111
|
+
- Bundled development builds and EXML code generation.
|
|
112
|
+
- Game and empty project templates with local CLI scripts.
|
|
113
|
+
|
|
114
|
+
### Changed
|
|
115
|
+
|
|
116
|
+
- Moved default skins and resource configuration into the game template.
|
|
117
|
+
|
|
118
|
+
## 0.2.0 - 2026-05-05
|
|
119
|
+
|
|
120
|
+
### Added
|
|
121
|
+
|
|
122
|
+
- Built-in EXML parsing, code generation, view states, watch mode, and bundle analysis.
|
|
123
|
+
|
|
124
|
+
## 0.1.0 - 2026-05-01
|
|
125
|
+
|
|
126
|
+
### Added
|
|
127
|
+
|
|
128
|
+
- Initial `@kurot/cli` release with project creation, HTML5 builds, development server, and cleaning commands.
|
package/README.md
ADDED
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
# @kurot/cli
|
|
2
|
+
|
|
3
|
+
CLI tool for the Kurot game engine — a modern replacement for the legacy Egret CLI. Powered by esbuild for fast compilation, with a built-in EXML skin parser and code generator.
|
|
4
|
+
|
|
5
|
+
> Migrating from Egret? See [migration.md](docs/migration.md)
|
|
6
|
+
>
|
|
7
|
+
> Release history: [CHANGELOG.md](CHANGELOG.md)
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
`@kurot/cli` does **not** require a global install.
|
|
12
|
+
|
|
13
|
+
### Creating a project
|
|
14
|
+
|
|
15
|
+
Use `npx` to scaffold a new project — no installation needed:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx @kurot/cli create my-game
|
|
19
|
+
npx @kurot/cli create my-lib --template empty
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### In-project commands
|
|
23
|
+
|
|
24
|
+
Scaffolded projects include `@kurot/cli` as a devDependency and expose commands via npm scripts:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
cd my-game
|
|
28
|
+
pnpm install
|
|
29
|
+
pnpm build # build
|
|
30
|
+
pnpm dev # dev server
|
|
31
|
+
pnpm clean # clean output
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
You can also add it to an existing project manually:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pnpm add -D @kurot/cli
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Commands
|
|
41
|
+
|
|
42
|
+
### `kurot create`
|
|
43
|
+
|
|
44
|
+
Scaffold a new project from a template.
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
kurot create <name> [options]
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
| Option | Description | Default |
|
|
51
|
+
| ----------------------- | --------------------------- | ------- |
|
|
52
|
+
| `--template <template>` | Template: `game` \| `empty` | `game` |
|
|
53
|
+
|
|
54
|
+
**Templates:**
|
|
55
|
+
|
|
56
|
+
| Template | Extends | Dependencies | Description |
|
|
57
|
+
| -------- | --------- | ------------------------------------------------- | -------------------------------------------------------------------------------- |
|
|
58
|
+
| `game` | `UILayer` | `@kurot/core` + `@kurot/game` + `@kurot/ui` | Full-featured project with resource loading, scene building, and Tween animation |
|
|
59
|
+
| `empty` | `Sprite` | `@kurot/core` | Minimal project — pure Canvas rendering, no extra dependencies |
|
|
60
|
+
|
|
61
|
+
**Lifecycle:**
|
|
62
|
+
|
|
63
|
+
| Template | Entry class | Lifecycle |
|
|
64
|
+
| -------- | ---------------------- | ------------------------------------------------------------------------------------------------- |
|
|
65
|
+
| `game` | `Main extends UILayer` | `createChildren` → `runGame` → `loadResource` → `loadTheme` → `createGameScene` → `startAnimation` |
|
|
66
|
+
| `empty` | `Main extends Sprite` | constructor → `ADDED_TO_STAGE` → `onAddToStage` |
|
|
67
|
+
|
|
68
|
+
### `kurot build`
|
|
69
|
+
|
|
70
|
+
Compile the project into ESM application, engine, namespace, and theme bundles.
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
kurot build [options]
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
| Option | Description | Default |
|
|
77
|
+
| --------------- | ------------------------------------------------------ | ------- |
|
|
78
|
+
| `-r, --release` | Minified, content-hashed release build (→ bin-release) | `false` |
|
|
79
|
+
| `--sourcemap` | Generate sourcemaps | `false` |
|
|
80
|
+
| `--watch` | Rebuild source on file changes | `false` |
|
|
81
|
+
| `--analyze` | Print bundle size analysis (esbuild metafile) | `false` |
|
|
82
|
+
|
|
83
|
+
**Output (Egret-aligned shape, ESM under the hood):**
|
|
84
|
+
|
|
85
|
+
| Mode | Layout |
|
|
86
|
+
| -------------- | --------------------------------------------------------------------------------------------------------- |
|
|
87
|
+
| development | `bin-debug/` — per-file `.js` mirroring `src/` (`Main.js`, `com/.../X.js`) + engine chunks in `js/` |
|
|
88
|
+
| release (`-r`) | `bin-release/web/<timestamp>/` — `js/main.min_<hash>.js` + `js/kurot.*.min_<hash>.js` + `manifest.json` |
|
|
89
|
+
|
|
90
|
+
Engine packages (`@kurot/*`) are bundled into separate `js/kurot.<name>.js`
|
|
91
|
+
chunks and wired up through an HTML **import map**, so the app bundle and engine
|
|
92
|
+
resolve bare specifiers (`import { Sprite } from '@kurot/core'`) in the browser
|
|
93
|
+
without duplicating engine code. `resource/` (including the compiled
|
|
94
|
+
`default.thm.json`) is copied with fixed names, since user code references those
|
|
95
|
+
paths directly. The entry script bootstraps via your own `createPlayer()` call.
|
|
96
|
+
|
|
97
|
+
### `kurot dev`
|
|
98
|
+
|
|
99
|
+
Start a development server with auto-recompilation on file changes (manual browser refresh required).
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
kurot dev [options]
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
| Option | Description | Default |
|
|
106
|
+
| ------------------- | ------------------- | ------- |
|
|
107
|
+
| `-p, --port <port>` | Port to listen | `3000` |
|
|
108
|
+
| `--sourcemap` | Generate sourcemaps | `false` |
|
|
109
|
+
|
|
110
|
+
### `kurot clean`
|
|
111
|
+
|
|
112
|
+
Remove the build output directories (`bin-debug` and `bin-release`).
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
kurot clean
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Configuration
|
|
119
|
+
|
|
120
|
+
Create a `kurot.config.ts` in your project root:
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
export default {
|
|
124
|
+
target: 'html5',
|
|
125
|
+
entry: 'src/Main.ts',
|
|
126
|
+
output: { dir: 'bin-debug' },
|
|
127
|
+
html: { template: 'template/web/index.html' },
|
|
128
|
+
stage: {
|
|
129
|
+
width: 640,
|
|
130
|
+
height: 1136,
|
|
131
|
+
scaleMode: 'showAll',
|
|
132
|
+
orientation: 'auto',
|
|
133
|
+
frameRate: 60,
|
|
134
|
+
},
|
|
135
|
+
// Optional: enable EXML skin compilation
|
|
136
|
+
exml: {
|
|
137
|
+
themeFile: 'resource/default.thm.json',
|
|
138
|
+
// Optional: map a custom EXML prefix to a source barrel file
|
|
139
|
+
namespaces: {
|
|
140
|
+
game: 'src/ui/index.ts',
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Options:**
|
|
147
|
+
|
|
148
|
+
| Field | Type | Description |
|
|
149
|
+
| ------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------ |
|
|
150
|
+
| `target` | `string` | Build target — currently only `'html5'` |
|
|
151
|
+
| `entry` | `string` | Entry file path, default `'src/Main.ts'` |
|
|
152
|
+
| `output.dir` | `string` | Output directory, default `'bin-debug'` |
|
|
153
|
+
| `html.template` | `string` | Optional project-owned HTML template; the CLI default page is used when omitted |
|
|
154
|
+
| `stage.width` | `number` | Stage width |
|
|
155
|
+
| `stage.height` | `number` | Stage height |
|
|
156
|
+
| `stage.scaleMode` | `string` | Scale mode: `showAll` / `noScale` / `exactFit` / `noBorder` / `fixedHeight` / `fixedWidth` / `fixedNarrow` / `fixedWide` |
|
|
157
|
+
| `stage.orientation` | `string` | Orientation: `auto` / `portrait` / `landscape` |
|
|
158
|
+
| `stage.frameRate` | `number` | Frame rate — must be a positive integer |
|
|
159
|
+
| `exml.themeFile` | `string` | Theme JSON file path |
|
|
160
|
+
| `exml.namespaces` | `Record<string, string>` | Optional EXML prefix → source barrel-file mapping |
|
|
161
|
+
|
|
162
|
+
## HTML Template
|
|
163
|
+
|
|
164
|
+
New projects include an editable `template/web/index.html`. The build reads
|
|
165
|
+
this file and writes the rendered page to the active output directory. Existing
|
|
166
|
+
projects that do not configure `html.template` continue to use the CLI's
|
|
167
|
+
built-in default page.
|
|
168
|
+
|
|
169
|
+
The following placeholders are required in a configured project template:
|
|
170
|
+
|
|
171
|
+
| Placeholder | Generated value |
|
|
172
|
+
| --- | --- |
|
|
173
|
+
| `{{KUROT_IMPORT_MAP}}` | Engine and custom namespace import map |
|
|
174
|
+
| `{{KUROT_STAGE_WIDTH}}` | Configured stage width |
|
|
175
|
+
| `{{KUROT_STAGE_HEIGHT}}` | Configured stage height |
|
|
176
|
+
| `{{KUROT_SCALE_MODE}}` | Configured scale mode |
|
|
177
|
+
| `{{KUROT_ORIENTATION}}` | Configured orientation |
|
|
178
|
+
| `{{KUROT_FRAME_RATE}}` | Configured frame rate |
|
|
179
|
+
| `{{KUROT_ENTRY_SCRIPT}}` | Compiled application entry script |
|
|
180
|
+
|
|
181
|
+
The template may otherwise contain any project-specific HTML, styles, loading
|
|
182
|
+
screen, platform SDK, analytics, fonts, or additional containers. A build fails
|
|
183
|
+
with a clear error when a configured template is missing a required placeholder.
|
|
184
|
+
|
|
185
|
+
## EXML Skin Compiler
|
|
186
|
+
|
|
187
|
+
The CLI includes a complete EXML skin parsing and code generation pipeline (XML → SkinIR → ESM JavaScript). `.exml` files placed in the `resource/` directory are compiled automatically during `kurot build`.
|
|
188
|
+
|
|
189
|
+
### Features
|
|
190
|
+
|
|
191
|
+
- **XML Parsing** — lightweight parser with namespace, CDATA, and comment support
|
|
192
|
+
- **AST / IR Generation** — converts to an intermediate representation (SkinIR)
|
|
193
|
+
- **Code Generation** — outputs ESM factory functions
|
|
194
|
+
- **Component Registry** — built-in `eui:*` / `egret:*` namespace mapping to `@kurot/ui` / `@kurot/core`
|
|
195
|
+
- **Custom Namespaces** — maps project prefixes such as `game:*` to source barrel files through `exml.namespaces`
|
|
196
|
+
- **View States** — supports `<eui:states>`, shorthand `states="up,down"`, state properties, `includeIn`, and `excludeFrom`
|
|
197
|
+
- **Skin Properties** — preserves root properties such as `minWidth`, `minHeight`, and state-specific values
|
|
198
|
+
- **Percent Layout** — auto-detects `width="100%"` and converts to `percentWidth`
|
|
199
|
+
- **Data Binding** — parses `{expression}` binding syntax and generates `Binding.bindProperty` calls
|
|
200
|
+
|
|
201
|
+
The standard declarations `xmlns:eui="http://ns.egret.com/eui"` and
|
|
202
|
+
`xmlns:egret="http://ns.egret.com/egret"` are namespace identifiers. The CLI
|
|
203
|
+
resolves their prefixes internally and does not access those URLs over the
|
|
204
|
+
network, so the original Egret namespace pages do not need to be hosted.
|
|
205
|
+
|
|
206
|
+
### Custom component lifecycle
|
|
207
|
+
|
|
208
|
+
For initialization that requires every EXML skin part to be available, override
|
|
209
|
+
`childrenCreated()`:
|
|
210
|
+
|
|
211
|
+
```ts
|
|
212
|
+
import { Component } from '@kurot/ui';
|
|
213
|
+
|
|
214
|
+
export class BattlePanel extends Component {
|
|
215
|
+
protected override childrenCreated(): void {
|
|
216
|
+
super.childrenCreated();
|
|
217
|
+
// imgBg, imgFrame, groupField, and other skin parts are now bound.
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
The event-based equivalent is useful when initialization is composed externally:
|
|
223
|
+
|
|
224
|
+
```ts
|
|
225
|
+
import { UIEvent } from '@kurot/ui';
|
|
226
|
+
|
|
227
|
+
this.once(UIEvent.CREATION_COMPLETE, this.onCreationComplete);
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Use `partAdded()` and `partRemoved()` only when logic must follow an individual
|
|
231
|
+
skin part across skin replacements. `childrenCreated()` and
|
|
232
|
+
`UIEvent.CREATION_COMPLETE` run once for the component's initial creation.
|
|
233
|
+
|
|
234
|
+
EXML skins compiled by the CLI are registered under their complete `class`
|
|
235
|
+
attribute, so an Egret-style value such as
|
|
236
|
+
`skinName = "game.ui.BattlePanelSkin"` works when that EXML is included in the
|
|
237
|
+
loaded theme bundle. A component covered by the theme's `skins` mapping normally
|
|
238
|
+
does not need to assign `skinName` itself. Hand-written `Skin` subclasses may be
|
|
239
|
+
imported and assigned directly instead of using a string.
|
|
240
|
+
|
|
241
|
+
### Compilation Pipeline
|
|
242
|
+
|
|
243
|
+
All `.exml` skins compile into a single ESM module — `js/default.thm.js` (dev)
|
|
244
|
+
or `js/default.thm.min_<hash>.js` (release) — that registers each skin factory.
|
|
245
|
+
`default.thm.json` keeps only the component→skin mapping plus a `skinsJs`
|
|
246
|
+
pointer to that module, which the runtime `Theme` imports. No `.exml` is shipped.
|
|
247
|
+
|
|
248
|
+
```
|
|
249
|
+
resource/skins/*.exml
|
|
250
|
+
↓ parseXML()
|
|
251
|
+
XML Element Tree
|
|
252
|
+
↓ parseEXML()
|
|
253
|
+
SkinIR
|
|
254
|
+
↓ generateCode({ format: 'esm' })
|
|
255
|
+
per-skin ESM factories
|
|
256
|
+
↓ esbuild bundle (+ minify in release)
|
|
257
|
+
js/default.thm[.min_<hash>].js (skins register on globalThis)
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## Project Structure
|
|
261
|
+
|
|
262
|
+
A project created with the default template (`game`) has the following structure:
|
|
263
|
+
|
|
264
|
+
```
|
|
265
|
+
my-game/
|
|
266
|
+
├── kurot.config.ts # Project config (includes exml options)
|
|
267
|
+
├── package.json # Dependencies & scripts
|
|
268
|
+
├── tsconfig.json # TypeScript config
|
|
269
|
+
├── template/
|
|
270
|
+
│ └── web/
|
|
271
|
+
│ └── index.html # Editable output page template
|
|
272
|
+
├── resource/
|
|
273
|
+
│ ├── default.res.json # Resource config
|
|
274
|
+
│ ├── default.thm.json # Theme file: component → skin mapping
|
|
275
|
+
│ └── skins/ # EXML skin directory (21 default skins)
|
|
276
|
+
│ ├── ButtonSkin.exml
|
|
277
|
+
│ ├── ...
|
|
278
|
+
│ └── ViewStackSkin.exml
|
|
279
|
+
└── src/
|
|
280
|
+
├── Main.ts # Entry: class Main extends Sprite
|
|
281
|
+
└── LoadingUI.ts # Loading progress display
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## Quick Start
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
# Full-featured game project (default)
|
|
288
|
+
npx @kurot/cli create my-game
|
|
289
|
+
cd my-game && pnpm install
|
|
290
|
+
pnpm dev
|
|
291
|
+
|
|
292
|
+
# Minimal project
|
|
293
|
+
npx @kurot/cli create my-lib --template empty
|
|
294
|
+
cd my-lib && pnpm install
|
|
295
|
+
pnpm dev
|
|
296
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0BpC,eAAO,MAAM,YAAY,SAoCtB,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { loadProject } from '../core/project.js';
|
|
3
|
+
import { createContext, runPipeline, disposeContext } from '../core/pipeline.js';
|
|
4
|
+
import { defaultPlugins } from '../core/plugins/index.js';
|
|
5
|
+
import { BuildError } from '../core/errors.js';
|
|
6
|
+
import { logger } from '../utils/logger.js';
|
|
7
|
+
export const buildCommand = new Command('build')
|
|
8
|
+
.description('Build the project')
|
|
9
|
+
.option('-r, --release', 'Minified, content-hashed release build (→ bin-release)', false)
|
|
10
|
+
.option('--sourcemap', 'Generate sourcemaps', false)
|
|
11
|
+
.option('--watch', 'Rebuild source on file changes', false)
|
|
12
|
+
.option('--analyze', 'Print esbuild bundle size analysis', false)
|
|
13
|
+
.action(async (options) => {
|
|
14
|
+
const start = Date.now();
|
|
15
|
+
try {
|
|
16
|
+
const mode = options.release ? 'release' : 'development';
|
|
17
|
+
if (options.watch && options.release) {
|
|
18
|
+
logger.warn('--watch is a development workflow; ignoring --release.');
|
|
19
|
+
}
|
|
20
|
+
const project = await loadProject(options.watch ? 'development' : mode);
|
|
21
|
+
logger.info(`Building (${project.mode})...`);
|
|
22
|
+
const ctx = createContext(project, {
|
|
23
|
+
sourcemap: options.sourcemap,
|
|
24
|
+
analyze: options.analyze,
|
|
25
|
+
watch: options.watch,
|
|
26
|
+
});
|
|
27
|
+
await runPipeline(ctx, defaultPlugins());
|
|
28
|
+
if (options.watch) {
|
|
29
|
+
logger.success('Watching for changes. Press Ctrl+C to stop.');
|
|
30
|
+
await waitForShutdown(() => disposeContext(ctx));
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const elapsed = ((Date.now() - start) / 1000).toFixed(2);
|
|
34
|
+
logger.success(`Build completed in ${elapsed}s → ${relativeOut(project.outputDir)}/`);
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
38
|
+
throw new BuildError(`Build failed: ${message}`, err instanceof Error ? err : undefined);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
/**
|
|
42
|
+
* Formats an absolute output directory as a path relative to the cwd, for
|
|
43
|
+
* display in the success message.
|
|
44
|
+
*/
|
|
45
|
+
function relativeOut(outputDir) {
|
|
46
|
+
return outputDir.replace(process.cwd() + '/', '');
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Resolves when the process receives SIGINT, after running cleanup.
|
|
50
|
+
*/
|
|
51
|
+
function waitForShutdown(cleanup) {
|
|
52
|
+
return new Promise(resolve => {
|
|
53
|
+
process.on('SIGINT', async () => {
|
|
54
|
+
await cleanup();
|
|
55
|
+
resolve();
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clean.d.ts","sourceRoot":"","sources":["../../src/commands/clean.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,eAAO,MAAM,YAAY,SAQvB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import * as fs from 'node:fs/promises';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import { loadConfig } from '../core/config.js';
|
|
5
|
+
import { OUTPUT_DIRS } from '../core/project.js';
|
|
6
|
+
import { logger } from '../utils/logger.js';
|
|
7
|
+
export const cleanCommand = new Command('clean').description('Remove build output directories').action(async () => {
|
|
8
|
+
const config = await loadConfig();
|
|
9
|
+
const names = [...new Set([config.output.dir, OUTPUT_DIRS.release])];
|
|
10
|
+
for (const name of names) {
|
|
11
|
+
await fs.rm(path.resolve(name), { recursive: true, force: true });
|
|
12
|
+
}
|
|
13
|
+
logger.success(`Cleaned ${names.map(n => n + '/').join(', ')}`);
|
|
14
|
+
});
|
|
15
|
+
//# sourceMappingURL=clean.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clean.js","sourceRoot":"","sources":["../../src/commands/clean.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,iCAAiC,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE;IACjH,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAClC,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAErE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACnE,CAAC;IACD,MAAM,CAAC,OAAO,CAAC,WAAW,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACjE,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,aAAa,SAoBvB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { scaffoldProject, TEMPLATES } from '../core/template.js';
|
|
3
|
+
import { logger } from '../utils/logger.js';
|
|
4
|
+
export const createCommand = new Command('create')
|
|
5
|
+
.description('Create a new Kurot project')
|
|
6
|
+
.argument('<name>', 'Project name')
|
|
7
|
+
.option('--template <template>', `Project template: ${TEMPLATES.join(' | ')}`, 'game')
|
|
8
|
+
.action(async (name, options) => {
|
|
9
|
+
if (!TEMPLATES.includes(options.template)) {
|
|
10
|
+
logger.error(`Unknown template "${options.template}". Available: ${TEMPLATES.join(', ')}`);
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
logger.info(`Creating project "${name}" from template "${options.template}"...`);
|
|
14
|
+
try {
|
|
15
|
+
await scaffoldProject(name, options.template);
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
logger.error(err instanceof Error ? err.message : String(err));
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
logger.success(`Project created at ./${name}`);
|
|
22
|
+
logger.info(`Next steps:\n cd ${name}\n pnpm install\n pnpm dev`);
|
|
23
|
+
});
|
|
24
|
+
//# sourceMappingURL=create.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,SAAS,EAAqB,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAChD,WAAW,CAAC,4BAA4B,CAAC;KACzC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;KAClC,MAAM,CAAC,uBAAuB,EAAE,qBAAqB,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,CAAC;KACrF,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,OAA6B,EAAE,EAAE;IAC7D,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAwB,CAAC,EAAE,CAAC;QAC3D,MAAM,CAAC,KAAK,CAAC,qBAAqB,OAAO,CAAC,QAAQ,iBAAiB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,qBAAqB,IAAI,oBAAoB,OAAO,CAAC,QAAQ,MAAM,CAAC,CAAC;IACjF,IAAI,CAAC;QACJ,MAAM,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,QAAwB,CAAC,CAAC;IAC/D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,MAAM,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IAED,MAAM,CAAC,OAAO,CAAC,wBAAwB,IAAI,EAAE,CAAC,CAAC;IAC/C,MAAM,CAAC,IAAI,CAAC,qBAAqB,IAAI,8BAA8B,CAAC,CAAC;AACtE,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,UAAU,SAmBpB,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { loadProject } from '../core/project.js';
|
|
3
|
+
import { startDevServer } from '../core/dev-server.js';
|
|
4
|
+
import { logger } from '../utils/logger.js';
|
|
5
|
+
export const devCommand = new Command('dev')
|
|
6
|
+
.description('Start a development server with rebuild on change')
|
|
7
|
+
.option('-p, --port <port>', 'Port to listen on', '3000')
|
|
8
|
+
.option('--sourcemap', 'Generate sourcemaps', false)
|
|
9
|
+
.action(async (options) => {
|
|
10
|
+
const port = Number.parseInt(options.port, 10);
|
|
11
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
12
|
+
logger.error(`Invalid port: ${options.port}`);
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
const project = await loadProject('development');
|
|
17
|
+
logger.info(`Starting dev server on port ${port}...`);
|
|
18
|
+
await startDevServer(project, { port, sourcemap: options.sourcemap });
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
logger.error(`Dev server failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
//# sourceMappingURL=dev.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,OAAO,CAAC,KAAK,CAAC;KAC1C,WAAW,CAAC,mDAAmD,CAAC;KAChE,MAAM,CAAC,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,CAAC;KACxD,MAAM,CAAC,aAAa,EAAE,qBAAqB,EAAE,KAAK,CAAC;KACnD,MAAM,CAAC,KAAK,EAAE,OAA6C,EAAE,EAAE;IAC/D,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC/C,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;QACzD,MAAM,CAAC,KAAK,CAAC,iBAAiB,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IAED,IAAI,CAAC;QACJ,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,aAAa,CAAC,CAAC;QACjD,MAAM,CAAC,IAAI,CAAC,+BAA+B,IAAI,KAAK,CAAC,CAAC;QACtD,MAAM,cAAc,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACvE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,MAAM,CAAC,KAAK,CAAC,sBAAsB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACvF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;AACF,CAAC,CAAC,CAAC"}
|