@qt-test/apex-dsl-compiler 0.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/README.md +272 -0
- package/bin/apexc.js +308 -0
- package/dist/acss/index.d.mts +67 -0
- package/dist/acss/index.d.ts +67 -0
- package/dist/acss/index.js +632 -0
- package/dist/acss/index.mjs +8 -0
- package/dist/ast-DEVgojMx.d.mts +135 -0
- package/dist/ast-DEVgojMx.d.ts +135 -0
- package/dist/axml/index.d.mts +59 -0
- package/dist/axml/index.d.ts +59 -0
- package/dist/axml/index.js +863 -0
- package/dist/axml/index.mjs +8 -0
- package/dist/chunk-7LDI6MFY.mjs +605 -0
- package/dist/chunk-B7VE6TVQ.mjs +605 -0
- package/dist/chunk-GQ3PJZ2P.mjs +836 -0
- package/dist/chunk-IRS3J3N7.mjs +836 -0
- package/dist/index.d.mts +237 -0
- package/dist/index.d.ts +237 -0
- package/dist/index.js +2050 -0
- package/dist/index.mjs +587 -0
- package/package.json +71 -0
package/README.md
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
# @interswitch/apex-compiler
|
|
2
|
+
|
|
3
|
+
> AXML/ACSS compiler for APEX mini-app platform
|
|
4
|
+
|
|
5
|
+
This package compiles APEX DSL (AXML templates and ACSS styles) into JavaScript code that works with the APEX runtime.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @interswitch/apex-compiler
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
### Programmatic API
|
|
16
|
+
|
|
17
|
+
```javascript
|
|
18
|
+
import { compile, compileAXML, compileACSS } from '@interswitch/apex-compiler';
|
|
19
|
+
|
|
20
|
+
// Compile a complete page/component
|
|
21
|
+
const result = compile({
|
|
22
|
+
axml: '<view class="container"><text>{{message}}</text></view>',
|
|
23
|
+
acss: '.container { padding: 20rpx; }',
|
|
24
|
+
json: { component: true }
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
console.log(result.code);
|
|
28
|
+
console.log(result.styles);
|
|
29
|
+
|
|
30
|
+
// Compile AXML only
|
|
31
|
+
const template = compileAXML('<view a:for="{{items}}">{{item}}</view>');
|
|
32
|
+
console.log(template.render);
|
|
33
|
+
|
|
34
|
+
// Compile ACSS only
|
|
35
|
+
const styles = compileACSS('.btn { width: 200rpx; color: #333; }');
|
|
36
|
+
console.log(styles.css);
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### CLI
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Compile a single file
|
|
43
|
+
apexc compile pages/index/index.axml -o dist/
|
|
44
|
+
|
|
45
|
+
# Compile a directory
|
|
46
|
+
apexc compile src/ -o dist/
|
|
47
|
+
|
|
48
|
+
# Watch mode
|
|
49
|
+
apexc compile src/ -o dist/ --watch
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## AXML Syntax
|
|
53
|
+
|
|
54
|
+
### Basic Elements
|
|
55
|
+
|
|
56
|
+
```xml
|
|
57
|
+
<!-- View container -->
|
|
58
|
+
<view class="container">
|
|
59
|
+
<text>Hello World</text>
|
|
60
|
+
</view>
|
|
61
|
+
|
|
62
|
+
<!-- Data binding -->
|
|
63
|
+
<text>{{message}}</text>
|
|
64
|
+
<view class="item-{{index}}">{{item.name}}</view>
|
|
65
|
+
|
|
66
|
+
<!-- Attribute binding -->
|
|
67
|
+
<image src="{{imageUrl}}" mode="aspectFit" />
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Directives
|
|
71
|
+
|
|
72
|
+
```xml
|
|
73
|
+
<!-- Conditional rendering -->
|
|
74
|
+
<view a:if="{{condition}}">Shown if true</view>
|
|
75
|
+
<view a:elif="{{other}}">Else if</view>
|
|
76
|
+
<view a:else>Else</view>
|
|
77
|
+
|
|
78
|
+
<!-- List rendering -->
|
|
79
|
+
<view a:for="{{items}}" a:for-item="item" a:for-index="idx">
|
|
80
|
+
{{idx}}: {{item.name}}
|
|
81
|
+
</view>
|
|
82
|
+
|
|
83
|
+
<!-- Key for optimization -->
|
|
84
|
+
<view a:for="{{items}}" a:key="id">{{item.name}}</view>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Event Binding
|
|
88
|
+
|
|
89
|
+
```xml
|
|
90
|
+
<!-- Tap event -->
|
|
91
|
+
<button bindtap="handleTap">Click me</button>
|
|
92
|
+
|
|
93
|
+
<!-- With event object -->
|
|
94
|
+
<input bindinput="handleInput" />
|
|
95
|
+
|
|
96
|
+
<!-- Catch (stop propagation) -->
|
|
97
|
+
<view catchtap="handleTap">Won't bubble</view>
|
|
98
|
+
|
|
99
|
+
<!-- Pass data -->
|
|
100
|
+
<button bindtap="handleTap" data-id="{{item.id}}">{{item.name}}</button>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Built-in Components
|
|
104
|
+
|
|
105
|
+
```xml
|
|
106
|
+
<!-- View -->
|
|
107
|
+
<view class="container" style="padding: 10px;">Content</view>
|
|
108
|
+
|
|
109
|
+
<!-- Text -->
|
|
110
|
+
<text selectable="{{true}}">Selectable text</text>
|
|
111
|
+
|
|
112
|
+
<!-- Image -->
|
|
113
|
+
<image src="/images/logo.png" mode="aspectFit" lazy-load />
|
|
114
|
+
|
|
115
|
+
<!-- Button -->
|
|
116
|
+
<button type="primary" loading="{{isLoading}}">Submit</button>
|
|
117
|
+
|
|
118
|
+
<!-- Input -->
|
|
119
|
+
<input type="text" placeholder="Enter name" value="{{name}}" bindinput="onInput" />
|
|
120
|
+
|
|
121
|
+
<!-- Scroll View -->
|
|
122
|
+
<scroll-view scroll-y style="height: 300px;">
|
|
123
|
+
<view a:for="{{items}}">{{item}}</view>
|
|
124
|
+
</scroll-view>
|
|
125
|
+
|
|
126
|
+
<!-- Swiper -->
|
|
127
|
+
<swiper autoplay circular>
|
|
128
|
+
<swiper-item a:for="{{banners}}">
|
|
129
|
+
<image src="{{item.url}}" />
|
|
130
|
+
</swiper-item>
|
|
131
|
+
</swiper>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Templates & Slots
|
|
135
|
+
|
|
136
|
+
```xml
|
|
137
|
+
<!-- Define template -->
|
|
138
|
+
<template name="userCard">
|
|
139
|
+
<view class="card">
|
|
140
|
+
<text>{{name}}</text>
|
|
141
|
+
<text>{{age}}</text>
|
|
142
|
+
</view>
|
|
143
|
+
</template>
|
|
144
|
+
|
|
145
|
+
<!-- Use template -->
|
|
146
|
+
<template is="userCard" data="{{...user}}" />
|
|
147
|
+
|
|
148
|
+
<!-- Slots in components -->
|
|
149
|
+
<my-component>
|
|
150
|
+
<view slot="header">Header content</view>
|
|
151
|
+
<view>Default slot content</view>
|
|
152
|
+
<view slot="footer">Footer content</view>
|
|
153
|
+
</my-component>
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## ACSS Syntax
|
|
157
|
+
|
|
158
|
+
ACSS is CSS with extensions for mini-app development.
|
|
159
|
+
|
|
160
|
+
### RPX Units
|
|
161
|
+
|
|
162
|
+
```css
|
|
163
|
+
/* rpx = responsive pixel, auto-scales with screen width */
|
|
164
|
+
/* 750rpx = full screen width on any device */
|
|
165
|
+
.container {
|
|
166
|
+
width: 750rpx;
|
|
167
|
+
padding: 20rpx;
|
|
168
|
+
font-size: 28rpx;
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Standard CSS
|
|
173
|
+
|
|
174
|
+
```css
|
|
175
|
+
.button {
|
|
176
|
+
background-color: #1890ff;
|
|
177
|
+
color: white;
|
|
178
|
+
border-radius: 8rpx;
|
|
179
|
+
padding: 16rpx 32rpx;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.button:active {
|
|
183
|
+
opacity: 0.8;
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Import
|
|
188
|
+
|
|
189
|
+
```css
|
|
190
|
+
@import './common.acss';
|
|
191
|
+
@import '/styles/theme.acss';
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Variables (CSS Custom Properties)
|
|
195
|
+
|
|
196
|
+
```css
|
|
197
|
+
:root {
|
|
198
|
+
--primary-color: #1890ff;
|
|
199
|
+
--text-color: #333;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.button {
|
|
203
|
+
background: var(--primary-color);
|
|
204
|
+
color: var(--text-color);
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Compiler Output
|
|
209
|
+
|
|
210
|
+
### Input
|
|
211
|
+
|
|
212
|
+
```xml
|
|
213
|
+
<!-- index.axml -->
|
|
214
|
+
<view class="page">
|
|
215
|
+
<text class="title">{{title}}</text>
|
|
216
|
+
<button bindtap="handleClick">Click</button>
|
|
217
|
+
</view>
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Output (simplified)
|
|
221
|
+
|
|
222
|
+
```javascript
|
|
223
|
+
export function render(_ctx) {
|
|
224
|
+
return h('view', { class: 'page' }, [
|
|
225
|
+
h('text', { class: 'title' }, [_ctx.title]),
|
|
226
|
+
h('button', { bindtap: _ctx.handleClick }, ['Click'])
|
|
227
|
+
]);
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Architecture
|
|
232
|
+
|
|
233
|
+
```
|
|
234
|
+
┌─────────────────────────────────────────────────────────┐
|
|
235
|
+
│ Source Files │
|
|
236
|
+
│ (.axml, .acss, .json, .js) │
|
|
237
|
+
└─────────────────────────────────────────────────────────┘
|
|
238
|
+
│
|
|
239
|
+
▼
|
|
240
|
+
┌─────────────────────────────────────────────────────────┐
|
|
241
|
+
│ Lexer │
|
|
242
|
+
│ (Tokenize source code) │
|
|
243
|
+
└─────────────────────────────────────────────────────────┘
|
|
244
|
+
│
|
|
245
|
+
▼
|
|
246
|
+
┌─────────────────────────────────────────────────────────┐
|
|
247
|
+
│ Parser │
|
|
248
|
+
│ (Build Abstract Syntax Tree) │
|
|
249
|
+
└─────────────────────────────────────────────────────────┘
|
|
250
|
+
│
|
|
251
|
+
▼
|
|
252
|
+
┌─────────────────────────────────────────────────────────┐
|
|
253
|
+
│ Transformer │
|
|
254
|
+
│ (Optimize, validate, transform AST) │
|
|
255
|
+
└─────────────────────────────────────────────────────────┘
|
|
256
|
+
│
|
|
257
|
+
▼
|
|
258
|
+
┌─────────────────────────────────────────────────────────┐
|
|
259
|
+
│ Code Generator │
|
|
260
|
+
│ (Generate JavaScript output) │
|
|
261
|
+
└─────────────────────────────────────────────────────────┘
|
|
262
|
+
│
|
|
263
|
+
▼
|
|
264
|
+
┌─────────────────────────────────────────────────────────┐
|
|
265
|
+
│ Output Files │
|
|
266
|
+
│ (.js, .css, .json) │
|
|
267
|
+
└─────────────────────────────────────────────────────────┘
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## License
|
|
271
|
+
|
|
272
|
+
MIT
|
package/bin/apexc.js
ADDED
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* APEX Compiler CLI
|
|
5
|
+
*
|
|
6
|
+
* Compiles AXML/ACSS files into JavaScript
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* apexc <input> [options]
|
|
10
|
+
* apexc src/pages/index --outDir dist
|
|
11
|
+
* apexc src/components/button -o dist/button.js
|
|
12
|
+
*
|
|
13
|
+
* Options:
|
|
14
|
+
* -o, --output <file> Output file
|
|
15
|
+
* --outDir <dir> Output directory
|
|
16
|
+
* -w, --watch Watch mode
|
|
17
|
+
* -m, --minify Minify output
|
|
18
|
+
* --sourcemap Generate source maps
|
|
19
|
+
* --target <target> Target ES version (es2015, es2020, esnext)
|
|
20
|
+
* --component Compile as component (default: auto-detect)
|
|
21
|
+
* --page Compile as page
|
|
22
|
+
* -h, --help Show help
|
|
23
|
+
* -v, --version Show version
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
const fs = require('fs');
|
|
27
|
+
const path = require('path');
|
|
28
|
+
|
|
29
|
+
// Parse arguments
|
|
30
|
+
const args = process.argv.slice(2);
|
|
31
|
+
const options = {
|
|
32
|
+
input: null,
|
|
33
|
+
output: null,
|
|
34
|
+
outDir: null,
|
|
35
|
+
watch: false,
|
|
36
|
+
minify: false,
|
|
37
|
+
sourcemap: false,
|
|
38
|
+
target: 'es2020',
|
|
39
|
+
isComponent: null,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
let i = 0;
|
|
43
|
+
while (i < args.length) {
|
|
44
|
+
const arg = args[i];
|
|
45
|
+
|
|
46
|
+
switch (arg) {
|
|
47
|
+
case '-o':
|
|
48
|
+
case '--output':
|
|
49
|
+
options.output = args[++i];
|
|
50
|
+
break;
|
|
51
|
+
|
|
52
|
+
case '--outDir':
|
|
53
|
+
options.outDir = args[++i];
|
|
54
|
+
break;
|
|
55
|
+
|
|
56
|
+
case '-w':
|
|
57
|
+
case '--watch':
|
|
58
|
+
options.watch = true;
|
|
59
|
+
break;
|
|
60
|
+
|
|
61
|
+
case '-m':
|
|
62
|
+
case '--minify':
|
|
63
|
+
options.minify = true;
|
|
64
|
+
break;
|
|
65
|
+
|
|
66
|
+
case '--sourcemap':
|
|
67
|
+
options.sourcemap = true;
|
|
68
|
+
break;
|
|
69
|
+
|
|
70
|
+
case '--target':
|
|
71
|
+
options.target = args[++i];
|
|
72
|
+
break;
|
|
73
|
+
|
|
74
|
+
case '--component':
|
|
75
|
+
options.isComponent = true;
|
|
76
|
+
break;
|
|
77
|
+
|
|
78
|
+
case '--page':
|
|
79
|
+
options.isComponent = false;
|
|
80
|
+
break;
|
|
81
|
+
|
|
82
|
+
case '-h':
|
|
83
|
+
case '--help':
|
|
84
|
+
showHelp();
|
|
85
|
+
process.exit(0);
|
|
86
|
+
|
|
87
|
+
case '-v':
|
|
88
|
+
case '--version':
|
|
89
|
+
showVersion();
|
|
90
|
+
process.exit(0);
|
|
91
|
+
|
|
92
|
+
default:
|
|
93
|
+
if (arg.startsWith('-')) {
|
|
94
|
+
console.error(`Unknown option: ${arg}`);
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
options.input = arg;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
i++;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function showHelp() {
|
|
104
|
+
console.log(`
|
|
105
|
+
APEX Compiler - Compiles AXML/ACSS to JavaScript
|
|
106
|
+
|
|
107
|
+
Usage:
|
|
108
|
+
apexc <input> [options]
|
|
109
|
+
|
|
110
|
+
Examples:
|
|
111
|
+
apexc src/pages/index --outDir dist
|
|
112
|
+
apexc src/components/button -o dist/button.js
|
|
113
|
+
apexc src/pages/home -m --sourcemap
|
|
114
|
+
|
|
115
|
+
Arguments:
|
|
116
|
+
<input> Input file or directory (without extension)
|
|
117
|
+
Will look for .axml, .acss, .json, .js files
|
|
118
|
+
|
|
119
|
+
Options:
|
|
120
|
+
-o, --output <file> Output file path
|
|
121
|
+
--outDir <dir> Output directory (preserves structure)
|
|
122
|
+
-w, --watch Watch files for changes
|
|
123
|
+
-m, --minify Minify the output
|
|
124
|
+
--sourcemap Generate source maps
|
|
125
|
+
--target <version> Target ES version: es2015, es2020, esnext (default: es2020)
|
|
126
|
+
--component Force compilation as component
|
|
127
|
+
--page Force compilation as page
|
|
128
|
+
-h, --help Show this help message
|
|
129
|
+
-v, --version Show version number
|
|
130
|
+
|
|
131
|
+
File Resolution:
|
|
132
|
+
Given input "src/pages/index", the compiler looks for:
|
|
133
|
+
- src/pages/index.axml (template)
|
|
134
|
+
- src/pages/index.acss (styles)
|
|
135
|
+
- src/pages/index.json (config)
|
|
136
|
+
- src/pages/index.js (logic)
|
|
137
|
+
|
|
138
|
+
At minimum, one of .axml or .js must exist.
|
|
139
|
+
`);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function showVersion() {
|
|
143
|
+
try {
|
|
144
|
+
const pkg = require('../package.json');
|
|
145
|
+
console.log(`apexc version ${pkg.version}`);
|
|
146
|
+
} catch {
|
|
147
|
+
console.log('apexc version 0.1.0');
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async function main() {
|
|
152
|
+
if (!options.input) {
|
|
153
|
+
console.error('Error: No input file specified');
|
|
154
|
+
console.error('Run "apexc --help" for usage information');
|
|
155
|
+
process.exit(1);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Resolve input path
|
|
159
|
+
const inputBase = path.resolve(options.input);
|
|
160
|
+
const inputDir = path.dirname(inputBase);
|
|
161
|
+
const inputName = path.basename(inputBase, path.extname(inputBase));
|
|
162
|
+
|
|
163
|
+
// Find input files
|
|
164
|
+
const files = {
|
|
165
|
+
axml: findFile(inputDir, inputName, '.axml'),
|
|
166
|
+
acss: findFile(inputDir, inputName, '.acss'),
|
|
167
|
+
json: findFile(inputDir, inputName, '.json'),
|
|
168
|
+
js: findFile(inputDir, inputName, '.js'),
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
if (!files.axml && !files.js) {
|
|
172
|
+
console.error(`Error: No .axml or .js file found for "${options.input}"`);
|
|
173
|
+
process.exit(1);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Load the compiler
|
|
177
|
+
let compile;
|
|
178
|
+
try {
|
|
179
|
+
const compiler = require('../dist/index.js');
|
|
180
|
+
compile = compiler.compile;
|
|
181
|
+
} catch (e) {
|
|
182
|
+
console.error('Error: Compiler not built. Run "npm run build" first.');
|
|
183
|
+
console.error(e.message);
|
|
184
|
+
process.exit(1);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Compile function
|
|
188
|
+
async function compileFiles() {
|
|
189
|
+
const startTime = Date.now();
|
|
190
|
+
|
|
191
|
+
// Read input files
|
|
192
|
+
const sources = {
|
|
193
|
+
axml: files.axml ? fs.readFileSync(files.axml, 'utf-8') : undefined,
|
|
194
|
+
acss: files.acss ? fs.readFileSync(files.acss, 'utf-8') : undefined,
|
|
195
|
+
json: files.json ? fs.readFileSync(files.json, 'utf-8') : undefined,
|
|
196
|
+
js: files.js ? fs.readFileSync(files.js, 'utf-8') : undefined,
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
// Determine if component
|
|
200
|
+
let isComponent = options.isComponent;
|
|
201
|
+
if (isComponent === null && sources.json) {
|
|
202
|
+
try {
|
|
203
|
+
const config = JSON.parse(sources.json);
|
|
204
|
+
isComponent = config.component === true;
|
|
205
|
+
} catch {
|
|
206
|
+
isComponent = false;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
isComponent = isComponent ?? false;
|
|
210
|
+
|
|
211
|
+
// Compile
|
|
212
|
+
const result = compile({
|
|
213
|
+
axml: sources.axml,
|
|
214
|
+
acss: sources.acss,
|
|
215
|
+
json: sources.json,
|
|
216
|
+
js: sources.js,
|
|
217
|
+
filename: inputName,
|
|
218
|
+
sourceMap: options.sourcemap,
|
|
219
|
+
minify: options.minify,
|
|
220
|
+
target: options.target,
|
|
221
|
+
isComponent,
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// Report errors
|
|
225
|
+
if (result.errors.length > 0) {
|
|
226
|
+
console.error('Compilation errors:');
|
|
227
|
+
for (const error of result.errors) {
|
|
228
|
+
console.error(` [${error.code}] ${error.message}`);
|
|
229
|
+
}
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Report warnings
|
|
234
|
+
if (result.warnings.length > 0) {
|
|
235
|
+
console.warn('Warnings:');
|
|
236
|
+
for (const warning of result.warnings) {
|
|
237
|
+
console.warn(` ${warning.message}`);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Determine output path
|
|
242
|
+
let outputPath;
|
|
243
|
+
if (options.output) {
|
|
244
|
+
outputPath = path.resolve(options.output);
|
|
245
|
+
} else if (options.outDir) {
|
|
246
|
+
const relPath = path.relative(process.cwd(), inputBase);
|
|
247
|
+
outputPath = path.join(options.outDir, relPath + '.js');
|
|
248
|
+
} else {
|
|
249
|
+
outputPath = inputBase + '.compiled.js';
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Ensure output directory exists
|
|
253
|
+
const outputDir = path.dirname(outputPath);
|
|
254
|
+
if (!fs.existsSync(outputDir)) {
|
|
255
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Write output
|
|
259
|
+
let output = result.code;
|
|
260
|
+
if (options.sourcemap && result.map) {
|
|
261
|
+
const mapPath = outputPath + '.map';
|
|
262
|
+
fs.writeFileSync(mapPath, JSON.stringify(result.map, null, 2));
|
|
263
|
+
output += `\n//# sourceMappingURL=${path.basename(mapPath)}`;
|
|
264
|
+
}
|
|
265
|
+
fs.writeFileSync(outputPath, output);
|
|
266
|
+
|
|
267
|
+
// Write CSS if present
|
|
268
|
+
if (result.css) {
|
|
269
|
+
const cssPath = outputPath.replace(/\.js$/, '.css');
|
|
270
|
+
fs.writeFileSync(cssPath, result.css);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const elapsed = Date.now() - startTime;
|
|
274
|
+
console.log(`Compiled ${inputName} -> ${path.relative(process.cwd(), outputPath)} (${elapsed}ms)`);
|
|
275
|
+
|
|
276
|
+
return true;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Initial compile
|
|
280
|
+
const success = await compileFiles();
|
|
281
|
+
|
|
282
|
+
// Watch mode
|
|
283
|
+
if (options.watch) {
|
|
284
|
+
console.log('\nWatching for changes...');
|
|
285
|
+
|
|
286
|
+
const watchFiles = Object.values(files).filter(Boolean);
|
|
287
|
+
for (const file of watchFiles) {
|
|
288
|
+
fs.watch(file, { persistent: true }, async (eventType) => {
|
|
289
|
+
if (eventType === 'change') {
|
|
290
|
+
console.log(`\nFile changed: ${path.basename(file)}`);
|
|
291
|
+
await compileFiles();
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
} else if (!success) {
|
|
296
|
+
process.exit(1);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
function findFile(dir, name, ext) {
|
|
301
|
+
const filePath = path.join(dir, name + ext);
|
|
302
|
+
return fs.existsSync(filePath) ? filePath : null;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
main().catch((error) => {
|
|
306
|
+
console.error('Fatal error:', error.message);
|
|
307
|
+
process.exit(1);
|
|
308
|
+
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { h as ACSSStylesheet } from '../ast-DEVgojMx.mjs';
|
|
2
|
+
export { A as ACSSDeclaration, a as ACSSImport, b as ACSSKeyframe, c as ACSSKeyframesRule, d as ACSSMediaRule, e as ACSSRule, f as ACSSSelector, g as ACSSStyleRule } from '../ast-DEVgojMx.mjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* ACSS Parser
|
|
6
|
+
*
|
|
7
|
+
* Tokenizes and parses ACSS stylesheets into an AST
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Parses ACSS source into an AST
|
|
12
|
+
*/
|
|
13
|
+
declare function parseACSS(source: string): {
|
|
14
|
+
ast: ACSSStylesheet;
|
|
15
|
+
errors: string[];
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* ACSS Compiler
|
|
20
|
+
*
|
|
21
|
+
* Transforms ACSS AST into optimized CSS
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Compile options
|
|
26
|
+
*/
|
|
27
|
+
interface ACSSCompileOptions {
|
|
28
|
+
/** Source filename for error reporting */
|
|
29
|
+
filename?: string;
|
|
30
|
+
/** Minify output */
|
|
31
|
+
minify?: boolean;
|
|
32
|
+
/** Add vendor prefixes */
|
|
33
|
+
autoprefixer?: boolean;
|
|
34
|
+
/** Scope styles to component */
|
|
35
|
+
scoped?: boolean;
|
|
36
|
+
/** Scope ID for scoped styles */
|
|
37
|
+
scopeId?: string;
|
|
38
|
+
/** Enable rpx to rem conversion */
|
|
39
|
+
rpxToRem?: boolean;
|
|
40
|
+
/** Base font size for rpx conversion (default: 16) */
|
|
41
|
+
baseFontSize?: number;
|
|
42
|
+
/** Design width for rpx (default: 750) */
|
|
43
|
+
designWidth?: number;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Compile result
|
|
47
|
+
*/
|
|
48
|
+
interface ACSSCompileResult {
|
|
49
|
+
/** Generated CSS */
|
|
50
|
+
css: string;
|
|
51
|
+
/** The AST (for debugging/tooling) */
|
|
52
|
+
ast: ACSSStylesheet;
|
|
53
|
+
/** Compilation warnings */
|
|
54
|
+
warnings: string[];
|
|
55
|
+
/** Compilation errors */
|
|
56
|
+
errors: string[];
|
|
57
|
+
/** Import paths */
|
|
58
|
+
imports: string[];
|
|
59
|
+
/** Used animations */
|
|
60
|
+
animations: Set<string>;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Compiles ACSS source into CSS
|
|
64
|
+
*/
|
|
65
|
+
declare function compileACSS(source: string, options?: ACSSCompileOptions): ACSSCompileResult;
|
|
66
|
+
|
|
67
|
+
export { type ACSSCompileOptions, type ACSSCompileResult, ACSSStylesheet, compileACSS, parseACSS };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { h as ACSSStylesheet } from '../ast-DEVgojMx.js';
|
|
2
|
+
export { A as ACSSDeclaration, a as ACSSImport, b as ACSSKeyframe, c as ACSSKeyframesRule, d as ACSSMediaRule, e as ACSSRule, f as ACSSSelector, g as ACSSStyleRule } from '../ast-DEVgojMx.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* ACSS Parser
|
|
6
|
+
*
|
|
7
|
+
* Tokenizes and parses ACSS stylesheets into an AST
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Parses ACSS source into an AST
|
|
12
|
+
*/
|
|
13
|
+
declare function parseACSS(source: string): {
|
|
14
|
+
ast: ACSSStylesheet;
|
|
15
|
+
errors: string[];
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* ACSS Compiler
|
|
20
|
+
*
|
|
21
|
+
* Transforms ACSS AST into optimized CSS
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Compile options
|
|
26
|
+
*/
|
|
27
|
+
interface ACSSCompileOptions {
|
|
28
|
+
/** Source filename for error reporting */
|
|
29
|
+
filename?: string;
|
|
30
|
+
/** Minify output */
|
|
31
|
+
minify?: boolean;
|
|
32
|
+
/** Add vendor prefixes */
|
|
33
|
+
autoprefixer?: boolean;
|
|
34
|
+
/** Scope styles to component */
|
|
35
|
+
scoped?: boolean;
|
|
36
|
+
/** Scope ID for scoped styles */
|
|
37
|
+
scopeId?: string;
|
|
38
|
+
/** Enable rpx to rem conversion */
|
|
39
|
+
rpxToRem?: boolean;
|
|
40
|
+
/** Base font size for rpx conversion (default: 16) */
|
|
41
|
+
baseFontSize?: number;
|
|
42
|
+
/** Design width for rpx (default: 750) */
|
|
43
|
+
designWidth?: number;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Compile result
|
|
47
|
+
*/
|
|
48
|
+
interface ACSSCompileResult {
|
|
49
|
+
/** Generated CSS */
|
|
50
|
+
css: string;
|
|
51
|
+
/** The AST (for debugging/tooling) */
|
|
52
|
+
ast: ACSSStylesheet;
|
|
53
|
+
/** Compilation warnings */
|
|
54
|
+
warnings: string[];
|
|
55
|
+
/** Compilation errors */
|
|
56
|
+
errors: string[];
|
|
57
|
+
/** Import paths */
|
|
58
|
+
imports: string[];
|
|
59
|
+
/** Used animations */
|
|
60
|
+
animations: Set<string>;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Compiles ACSS source into CSS
|
|
64
|
+
*/
|
|
65
|
+
declare function compileACSS(source: string, options?: ACSSCompileOptions): ACSSCompileResult;
|
|
66
|
+
|
|
67
|
+
export { type ACSSCompileOptions, type ACSSCompileResult, ACSSStylesheet, compileACSS, parseACSS };
|