@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/dist/index.mjs
ADDED
|
@@ -0,0 +1,587 @@
|
|
|
1
|
+
import {
|
|
2
|
+
compileACSS,
|
|
3
|
+
parseACSS
|
|
4
|
+
} from "./chunk-B7VE6TVQ.mjs";
|
|
5
|
+
import {
|
|
6
|
+
compileAXML,
|
|
7
|
+
parseAXML
|
|
8
|
+
} from "./chunk-GQ3PJZ2P.mjs";
|
|
9
|
+
|
|
10
|
+
// src/codegen.ts
|
|
11
|
+
function generateCode(input, options) {
|
|
12
|
+
const { template, styles, js } = input;
|
|
13
|
+
const { isComponent, minify } = options;
|
|
14
|
+
const parts = [];
|
|
15
|
+
parts.push(generateImports(input, options));
|
|
16
|
+
if (js) {
|
|
17
|
+
parts.push("");
|
|
18
|
+
parts.push("// User code");
|
|
19
|
+
parts.push(js);
|
|
20
|
+
}
|
|
21
|
+
if (template) {
|
|
22
|
+
parts.push("");
|
|
23
|
+
parts.push("// Render function");
|
|
24
|
+
parts.push(template.code);
|
|
25
|
+
}
|
|
26
|
+
if (styles) {
|
|
27
|
+
parts.push("");
|
|
28
|
+
parts.push("// Styles");
|
|
29
|
+
parts.push(generateStylesCode(styles, options));
|
|
30
|
+
}
|
|
31
|
+
parts.push("");
|
|
32
|
+
parts.push(
|
|
33
|
+
isComponent ? generateComponentDefinition(input, options) : generatePageDefinition(input, options)
|
|
34
|
+
);
|
|
35
|
+
parts.push("");
|
|
36
|
+
parts.push(generateExports(input, options));
|
|
37
|
+
let code = parts.join("\n");
|
|
38
|
+
if (minify) {
|
|
39
|
+
code = minifyCode(code);
|
|
40
|
+
}
|
|
41
|
+
return code;
|
|
42
|
+
}
|
|
43
|
+
function generateImports(input, _options) {
|
|
44
|
+
const imports = [];
|
|
45
|
+
const runtimeImports = ["h", "Fragment"];
|
|
46
|
+
if (input.template?.usedComponents.size) {
|
|
47
|
+
runtimeImports.push("resolveComponent");
|
|
48
|
+
}
|
|
49
|
+
if (input.template?.code.includes("renderList")) {
|
|
50
|
+
runtimeImports.push("renderList");
|
|
51
|
+
}
|
|
52
|
+
if (input.template?.code.includes("renderSlot")) {
|
|
53
|
+
runtimeImports.push("renderSlot");
|
|
54
|
+
}
|
|
55
|
+
imports.push(`import { ${runtimeImports.join(", ")} } from '@qt-test/apex-runtime';`);
|
|
56
|
+
const components = input.config.usingComponents ?? {};
|
|
57
|
+
for (const [name, path] of Object.entries(components)) {
|
|
58
|
+
imports.push(`import ${toPascalCase(name)} from '${path}';`);
|
|
59
|
+
}
|
|
60
|
+
if (input.styles?.imports.length) {
|
|
61
|
+
for (const importPath of input.styles.imports) {
|
|
62
|
+
imports.push(`import '${importPath}';`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return imports.join("\n");
|
|
66
|
+
}
|
|
67
|
+
function generateStylesCode(styles, _options) {
|
|
68
|
+
const css = styles.css.replace(/`/g, "\\`").replace(/\$/g, "\\$");
|
|
69
|
+
return `const __styles__ = \`${css}\`;`;
|
|
70
|
+
}
|
|
71
|
+
function generateComponentDefinition(input, _options) {
|
|
72
|
+
const properties = extractComponentProperties(input.js ?? "");
|
|
73
|
+
const methods = extractComponentMethods(input.js ?? "");
|
|
74
|
+
const parts = [];
|
|
75
|
+
parts.push("const __component__ = {");
|
|
76
|
+
parts.push(' is: "component",');
|
|
77
|
+
if (properties.length > 0) {
|
|
78
|
+
parts.push(` properties: {`);
|
|
79
|
+
for (const prop of properties) {
|
|
80
|
+
parts.push(` ${prop.name}: { type: ${prop.type}, value: ${prop.default} },`);
|
|
81
|
+
}
|
|
82
|
+
parts.push(" },");
|
|
83
|
+
}
|
|
84
|
+
parts.push(" data() {");
|
|
85
|
+
parts.push(" return {};");
|
|
86
|
+
parts.push(" },");
|
|
87
|
+
if (methods.length > 0) {
|
|
88
|
+
parts.push(" methods: {");
|
|
89
|
+
for (const method of methods) {
|
|
90
|
+
parts.push(` ${method},`);
|
|
91
|
+
}
|
|
92
|
+
parts.push(" },");
|
|
93
|
+
}
|
|
94
|
+
if (input.template) {
|
|
95
|
+
parts.push(" render,");
|
|
96
|
+
}
|
|
97
|
+
if (input.styles) {
|
|
98
|
+
parts.push(" styles: __styles__,");
|
|
99
|
+
}
|
|
100
|
+
if (input.config.usingComponents) {
|
|
101
|
+
const componentEntries = Object.entries(input.config.usingComponents).map(([name]) => ` "${name}": ${toPascalCase(name)}`).join(",\n");
|
|
102
|
+
parts.push(` components: {
|
|
103
|
+
${componentEntries}
|
|
104
|
+
},`);
|
|
105
|
+
}
|
|
106
|
+
parts.push("};");
|
|
107
|
+
return parts.join("\n");
|
|
108
|
+
}
|
|
109
|
+
function generatePageDefinition(input, _options) {
|
|
110
|
+
const parts = [];
|
|
111
|
+
parts.push("const __page__ = {");
|
|
112
|
+
parts.push(' is: "page",');
|
|
113
|
+
if (input.config.navigationBarTitleText) {
|
|
114
|
+
parts.push(` title: "${input.config.navigationBarTitleText}",`);
|
|
115
|
+
}
|
|
116
|
+
if (input.config.enablePullDownRefresh) {
|
|
117
|
+
parts.push(" enablePullDownRefresh: true,");
|
|
118
|
+
}
|
|
119
|
+
parts.push(" data() {");
|
|
120
|
+
parts.push(" return {};");
|
|
121
|
+
parts.push(" },");
|
|
122
|
+
if (input.template) {
|
|
123
|
+
parts.push(" render,");
|
|
124
|
+
}
|
|
125
|
+
if (input.styles) {
|
|
126
|
+
parts.push(" styles: __styles__,");
|
|
127
|
+
}
|
|
128
|
+
if (input.config.usingComponents) {
|
|
129
|
+
const componentEntries = Object.entries(input.config.usingComponents).map(([name]) => ` "${name}": ${toPascalCase(name)}`).join(",\n");
|
|
130
|
+
parts.push(` components: {
|
|
131
|
+
${componentEntries}
|
|
132
|
+
},`);
|
|
133
|
+
}
|
|
134
|
+
parts.push("};");
|
|
135
|
+
return parts.join("\n");
|
|
136
|
+
}
|
|
137
|
+
function generateExports(input, options) {
|
|
138
|
+
const exports = [];
|
|
139
|
+
if (options.isComponent) {
|
|
140
|
+
exports.push("export default __component__;");
|
|
141
|
+
} else {
|
|
142
|
+
exports.push("export default __page__;");
|
|
143
|
+
}
|
|
144
|
+
if (input.template) {
|
|
145
|
+
exports.push("export { render };");
|
|
146
|
+
}
|
|
147
|
+
if (input.styles) {
|
|
148
|
+
exports.push("export { __styles__ as styles };");
|
|
149
|
+
}
|
|
150
|
+
return exports.join("\n");
|
|
151
|
+
}
|
|
152
|
+
function extractComponentProperties(js) {
|
|
153
|
+
const properties = [];
|
|
154
|
+
const propsMatch = js.match(/properties\s*:\s*\{([^}]+)\}/);
|
|
155
|
+
if (propsMatch) {
|
|
156
|
+
const propsBlock = propsMatch[1];
|
|
157
|
+
const propMatches = propsBlock.matchAll(/(\w+)\s*:\s*\{?\s*(?:type\s*:\s*(\w+))?\s*(?:,\s*value\s*:\s*([^,}]+))?\s*\}?/g);
|
|
158
|
+
for (const match of propMatches) {
|
|
159
|
+
properties.push({
|
|
160
|
+
name: match[1],
|
|
161
|
+
type: match[2] || "String",
|
|
162
|
+
default: match[3]?.trim() || "null"
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return properties;
|
|
167
|
+
}
|
|
168
|
+
function extractComponentMethods(js) {
|
|
169
|
+
const methods = [];
|
|
170
|
+
const methodsMatch = js.match(/methods\s*:\s*\{([^}]+(?:\{[^}]*\}[^}]*)*)\}/);
|
|
171
|
+
if (methodsMatch) {
|
|
172
|
+
const methodsBlock = methodsMatch[1];
|
|
173
|
+
const methodMatches = methodsBlock.matchAll(/(\w+)\s*(?:\([^)]*\))?\s*\{/g);
|
|
174
|
+
for (const match of methodMatches) {
|
|
175
|
+
methods.push(match[1]);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return methods;
|
|
179
|
+
}
|
|
180
|
+
function toPascalCase(str) {
|
|
181
|
+
return str.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
|
|
182
|
+
}
|
|
183
|
+
function minifyCode(code) {
|
|
184
|
+
return code.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "").replace(/\s+/g, " ").replace(/\s*([{};,:])\s*/g, "$1").replace(/;\s*}/g, "}").trim();
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// src/sourcemap.ts
|
|
188
|
+
var SourceMapBuilder = class {
|
|
189
|
+
constructor(options) {
|
|
190
|
+
this.sources = [];
|
|
191
|
+
this.sourcesContent = [];
|
|
192
|
+
this.names = [];
|
|
193
|
+
this.mappings = [];
|
|
194
|
+
this.currentLine = [];
|
|
195
|
+
if (options) {
|
|
196
|
+
this.file = options.file;
|
|
197
|
+
this.sourceRoot = options.sourceRoot;
|
|
198
|
+
this.sources = [...options.sources];
|
|
199
|
+
if (options.includeContent && options.sourcesContent) {
|
|
200
|
+
this.sourcesContent = [...options.sourcesContent];
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Adds a source file
|
|
206
|
+
*/
|
|
207
|
+
addSource(source, content) {
|
|
208
|
+
const index = this.sources.indexOf(source);
|
|
209
|
+
if (index !== -1) {
|
|
210
|
+
return index;
|
|
211
|
+
}
|
|
212
|
+
this.sources.push(source);
|
|
213
|
+
this.sourcesContent.push(content ?? null);
|
|
214
|
+
return this.sources.length - 1;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Adds a name
|
|
218
|
+
*/
|
|
219
|
+
addName(name) {
|
|
220
|
+
const index = this.names.indexOf(name);
|
|
221
|
+
if (index !== -1) {
|
|
222
|
+
return index;
|
|
223
|
+
}
|
|
224
|
+
this.names.push(name);
|
|
225
|
+
return this.names.length - 1;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Adds a mapping
|
|
229
|
+
*/
|
|
230
|
+
addMapping(generatedLine, generatedColumn, sourceIndex, sourceLine, sourceColumn, nameIndex) {
|
|
231
|
+
while (this.mappings.length <= generatedLine) {
|
|
232
|
+
if (this.currentLine.length > 0) {
|
|
233
|
+
this.mappings.push(this.currentLine);
|
|
234
|
+
this.currentLine = [];
|
|
235
|
+
} else {
|
|
236
|
+
this.mappings.push([]);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
const segment = { generatedColumn };
|
|
240
|
+
if (sourceIndex !== void 0) {
|
|
241
|
+
segment.sourceIndex = sourceIndex;
|
|
242
|
+
segment.sourceLine = sourceLine;
|
|
243
|
+
segment.sourceColumn = sourceColumn;
|
|
244
|
+
if (nameIndex !== void 0) {
|
|
245
|
+
segment.nameIndex = nameIndex;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if (this.mappings.length === generatedLine) {
|
|
249
|
+
this.currentLine.push(segment);
|
|
250
|
+
} else {
|
|
251
|
+
this.mappings[generatedLine].push(segment);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Starts a new line
|
|
256
|
+
*/
|
|
257
|
+
newLine() {
|
|
258
|
+
this.mappings.push(this.currentLine);
|
|
259
|
+
this.currentLine = [];
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Generates the source map
|
|
263
|
+
*/
|
|
264
|
+
toSourceMap() {
|
|
265
|
+
if (this.currentLine.length > 0) {
|
|
266
|
+
this.mappings.push(this.currentLine);
|
|
267
|
+
this.currentLine = [];
|
|
268
|
+
}
|
|
269
|
+
return {
|
|
270
|
+
version: 3,
|
|
271
|
+
file: this.file,
|
|
272
|
+
sourceRoot: this.sourceRoot,
|
|
273
|
+
sources: this.sources,
|
|
274
|
+
sourcesContent: this.sourcesContent.length > 0 ? this.sourcesContent : void 0,
|
|
275
|
+
names: this.names,
|
|
276
|
+
mappings: this.encodeMappings()
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Encodes mappings to VLQ format
|
|
281
|
+
*/
|
|
282
|
+
encodeMappings() {
|
|
283
|
+
let previousGeneratedColumn = 0;
|
|
284
|
+
let previousSourceIndex = 0;
|
|
285
|
+
let previousSourceLine = 0;
|
|
286
|
+
let previousSourceColumn = 0;
|
|
287
|
+
let previousNameIndex = 0;
|
|
288
|
+
const lines = [];
|
|
289
|
+
for (const line of this.mappings) {
|
|
290
|
+
previousGeneratedColumn = 0;
|
|
291
|
+
const segments = [];
|
|
292
|
+
const sortedSegments = [...line].sort((a, b) => a.generatedColumn - b.generatedColumn);
|
|
293
|
+
for (const segment of sortedSegments) {
|
|
294
|
+
const values = [];
|
|
295
|
+
values.push(segment.generatedColumn - previousGeneratedColumn);
|
|
296
|
+
previousGeneratedColumn = segment.generatedColumn;
|
|
297
|
+
if (segment.sourceIndex !== void 0) {
|
|
298
|
+
values.push(segment.sourceIndex - previousSourceIndex);
|
|
299
|
+
previousSourceIndex = segment.sourceIndex;
|
|
300
|
+
values.push((segment.sourceLine ?? 0) - previousSourceLine);
|
|
301
|
+
previousSourceLine = segment.sourceLine ?? 0;
|
|
302
|
+
values.push((segment.sourceColumn ?? 0) - previousSourceColumn);
|
|
303
|
+
previousSourceColumn = segment.sourceColumn ?? 0;
|
|
304
|
+
if (segment.nameIndex !== void 0) {
|
|
305
|
+
values.push(segment.nameIndex - previousNameIndex);
|
|
306
|
+
previousNameIndex = segment.nameIndex;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
segments.push(values.map(encodeVLQ).join(""));
|
|
310
|
+
}
|
|
311
|
+
lines.push(segments.join(","));
|
|
312
|
+
}
|
|
313
|
+
return lines.join(";");
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Returns JSON string
|
|
317
|
+
*/
|
|
318
|
+
toString() {
|
|
319
|
+
return JSON.stringify(this.toSourceMap());
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Returns data URL
|
|
323
|
+
*/
|
|
324
|
+
toDataUrl() {
|
|
325
|
+
const json = this.toString();
|
|
326
|
+
const base64 = typeof btoa !== "undefined" ? btoa(json) : Buffer.from(json).toString("base64");
|
|
327
|
+
return `data:application/json;charset=utf-8;base64,${base64}`;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Returns inline comment
|
|
331
|
+
*/
|
|
332
|
+
toComment() {
|
|
333
|
+
return `//# sourceMappingURL=${this.toDataUrl()}`;
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
var VLQ_BASE64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
337
|
+
var VLQ_BASE_SHIFT = 5;
|
|
338
|
+
var VLQ_BASE = 1 << VLQ_BASE_SHIFT;
|
|
339
|
+
var VLQ_BASE_MASK = VLQ_BASE - 1;
|
|
340
|
+
var VLQ_CONTINUATION_BIT = VLQ_BASE;
|
|
341
|
+
function encodeVLQ(value) {
|
|
342
|
+
let encoded = "";
|
|
343
|
+
let vlq = value < 0 ? (-value << 1) + 1 : value << 1;
|
|
344
|
+
do {
|
|
345
|
+
let digit = vlq & VLQ_BASE_MASK;
|
|
346
|
+
vlq >>>= VLQ_BASE_SHIFT;
|
|
347
|
+
if (vlq > 0) {
|
|
348
|
+
digit |= VLQ_CONTINUATION_BIT;
|
|
349
|
+
}
|
|
350
|
+
encoded += VLQ_BASE64[digit];
|
|
351
|
+
} while (vlq > 0);
|
|
352
|
+
return encoded;
|
|
353
|
+
}
|
|
354
|
+
function decodeVLQ(encoded, start = 0) {
|
|
355
|
+
let vlq = 0;
|
|
356
|
+
let shift = 0;
|
|
357
|
+
let continuation = true;
|
|
358
|
+
let i = start;
|
|
359
|
+
while (continuation && i < encoded.length) {
|
|
360
|
+
const char = encoded[i];
|
|
361
|
+
const digit = VLQ_BASE64.indexOf(char);
|
|
362
|
+
if (digit === -1) {
|
|
363
|
+
throw new Error(`Invalid VLQ character: ${char}`);
|
|
364
|
+
}
|
|
365
|
+
continuation = (digit & VLQ_CONTINUATION_BIT) !== 0;
|
|
366
|
+
vlq += (digit & VLQ_BASE_MASK) << shift;
|
|
367
|
+
shift += VLQ_BASE_SHIFT;
|
|
368
|
+
i++;
|
|
369
|
+
}
|
|
370
|
+
const value = vlq & 1 ? -(vlq >> 1) : vlq >> 1;
|
|
371
|
+
return { value, next: i };
|
|
372
|
+
}
|
|
373
|
+
function createSourceMap(options) {
|
|
374
|
+
const builder = new SourceMapBuilder(options);
|
|
375
|
+
return builder.toSourceMap();
|
|
376
|
+
}
|
|
377
|
+
function mergeSourceMaps(maps) {
|
|
378
|
+
const builder = new SourceMapBuilder();
|
|
379
|
+
let lineOffset = 0;
|
|
380
|
+
for (const map of maps) {
|
|
381
|
+
const sourceIndexMap = /* @__PURE__ */ new Map();
|
|
382
|
+
for (let i = 0; i < map.sources.length; i++) {
|
|
383
|
+
const newIndex = builder.addSource(
|
|
384
|
+
map.sources[i],
|
|
385
|
+
map.sourcesContent?.[i] ?? void 0
|
|
386
|
+
);
|
|
387
|
+
sourceIndexMap.set(i, newIndex);
|
|
388
|
+
}
|
|
389
|
+
const nameIndexMap = /* @__PURE__ */ new Map();
|
|
390
|
+
for (let i = 0; i < map.names.length; i++) {
|
|
391
|
+
const newIndex = builder.addName(map.names[i]);
|
|
392
|
+
nameIndexMap.set(i, newIndex);
|
|
393
|
+
}
|
|
394
|
+
const decodedMappings = decodeMappings(map.mappings);
|
|
395
|
+
for (let lineIndex = 0; lineIndex < decodedMappings.length; lineIndex++) {
|
|
396
|
+
const line = decodedMappings[lineIndex];
|
|
397
|
+
for (const segment of line) {
|
|
398
|
+
const sourceIndex = segment.sourceIndex !== void 0 ? sourceIndexMap.get(segment.sourceIndex) : void 0;
|
|
399
|
+
const nameIndex = segment.nameIndex !== void 0 ? nameIndexMap.get(segment.nameIndex) : void 0;
|
|
400
|
+
builder.addMapping(
|
|
401
|
+
lineIndex + lineOffset,
|
|
402
|
+
segment.generatedColumn,
|
|
403
|
+
sourceIndex,
|
|
404
|
+
segment.sourceLine,
|
|
405
|
+
segment.sourceColumn,
|
|
406
|
+
nameIndex
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
lineOffset += decodedMappings.length;
|
|
411
|
+
}
|
|
412
|
+
return builder.toSourceMap();
|
|
413
|
+
}
|
|
414
|
+
function decodeMappings(mappings) {
|
|
415
|
+
const lines = [];
|
|
416
|
+
const lineStrings = mappings.split(";");
|
|
417
|
+
let previousSourceIndex = 0;
|
|
418
|
+
let previousSourceLine = 0;
|
|
419
|
+
let previousSourceColumn = 0;
|
|
420
|
+
let previousNameIndex = 0;
|
|
421
|
+
for (const lineString of lineStrings) {
|
|
422
|
+
const line = [];
|
|
423
|
+
let previousGeneratedColumn = 0;
|
|
424
|
+
if (lineString) {
|
|
425
|
+
const segmentStrings = lineString.split(",");
|
|
426
|
+
for (const segmentString of segmentStrings) {
|
|
427
|
+
if (!segmentString) continue;
|
|
428
|
+
const segment = { generatedColumn: 0 };
|
|
429
|
+
let pos = 0;
|
|
430
|
+
const col = decodeVLQ(segmentString, pos);
|
|
431
|
+
segment.generatedColumn = previousGeneratedColumn + col.value;
|
|
432
|
+
previousGeneratedColumn = segment.generatedColumn;
|
|
433
|
+
pos = col.next;
|
|
434
|
+
if (pos < segmentString.length) {
|
|
435
|
+
const src = decodeVLQ(segmentString, pos);
|
|
436
|
+
segment.sourceIndex = previousSourceIndex + src.value;
|
|
437
|
+
previousSourceIndex = segment.sourceIndex;
|
|
438
|
+
pos = src.next;
|
|
439
|
+
const srcLine = decodeVLQ(segmentString, pos);
|
|
440
|
+
segment.sourceLine = previousSourceLine + srcLine.value;
|
|
441
|
+
previousSourceLine = segment.sourceLine;
|
|
442
|
+
pos = srcLine.next;
|
|
443
|
+
const srcCol = decodeVLQ(segmentString, pos);
|
|
444
|
+
segment.sourceColumn = previousSourceColumn + srcCol.value;
|
|
445
|
+
previousSourceColumn = segment.sourceColumn;
|
|
446
|
+
pos = srcCol.next;
|
|
447
|
+
if (pos < segmentString.length) {
|
|
448
|
+
const name = decodeVLQ(segmentString, pos);
|
|
449
|
+
segment.nameIndex = previousNameIndex + name.value;
|
|
450
|
+
previousNameIndex = segment.nameIndex;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
line.push(segment);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
lines.push(line);
|
|
457
|
+
}
|
|
458
|
+
return lines;
|
|
459
|
+
}
|
|
460
|
+
function applySourceMap(map, line, column) {
|
|
461
|
+
const decodedMappings = decodeMappings(map.mappings);
|
|
462
|
+
if (line >= decodedMappings.length) {
|
|
463
|
+
return null;
|
|
464
|
+
}
|
|
465
|
+
const lineMappings = decodedMappings[line];
|
|
466
|
+
let bestSegment = null;
|
|
467
|
+
for (const segment of lineMappings) {
|
|
468
|
+
if (segment.generatedColumn <= column) {
|
|
469
|
+
bestSegment = segment;
|
|
470
|
+
} else {
|
|
471
|
+
break;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
if (!bestSegment || bestSegment.sourceIndex === void 0) {
|
|
475
|
+
return null;
|
|
476
|
+
}
|
|
477
|
+
return {
|
|
478
|
+
source: map.sources[bestSegment.sourceIndex] ?? null,
|
|
479
|
+
line: bestSegment.sourceLine ?? 0,
|
|
480
|
+
column: bestSegment.sourceColumn ?? 0,
|
|
481
|
+
name: bestSegment.nameIndex !== void 0 ? map.names[bestSegment.nameIndex] ?? null : null
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
// src/compiler.ts
|
|
486
|
+
function compile(options) {
|
|
487
|
+
const warnings = [];
|
|
488
|
+
const errors = [];
|
|
489
|
+
let config = {};
|
|
490
|
+
if (options.json) {
|
|
491
|
+
if (typeof options.json === "string") {
|
|
492
|
+
try {
|
|
493
|
+
config = JSON.parse(options.json);
|
|
494
|
+
} catch (e) {
|
|
495
|
+
errors.push({
|
|
496
|
+
code: "INVALID_JSON",
|
|
497
|
+
message: `Failed to parse JSON config: ${e.message}`
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
} else {
|
|
501
|
+
config = options.json;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
const isComponent = options.isComponent ?? config.component ?? false;
|
|
505
|
+
let templateResult = null;
|
|
506
|
+
if (options.axml) {
|
|
507
|
+
templateResult = compileAXML(options.axml, {
|
|
508
|
+
filename: options.filename ? `${options.filename}.axml` : void 0,
|
|
509
|
+
components: { ...config.usingComponents, ...options.components }
|
|
510
|
+
});
|
|
511
|
+
warnings.push(...templateResult.warnings.map((w) => ({ message: w })));
|
|
512
|
+
errors.push(...templateResult.errors.map((e) => ({ code: "AXML_ERROR", message: e })));
|
|
513
|
+
}
|
|
514
|
+
let styleResult = null;
|
|
515
|
+
if (options.acss) {
|
|
516
|
+
styleResult = compileACSS(options.acss, {
|
|
517
|
+
filename: options.filename ? `${options.filename}.acss` : void 0
|
|
518
|
+
});
|
|
519
|
+
warnings.push(...styleResult.warnings.map((w) => ({ message: w })));
|
|
520
|
+
errors.push(...styleResult.errors.map((e) => ({ code: "ACSS_ERROR", message: e })));
|
|
521
|
+
}
|
|
522
|
+
const generatorOptions = {
|
|
523
|
+
isComponent,
|
|
524
|
+
minify: options.minify ?? false,
|
|
525
|
+
target: options.target ?? "es2020",
|
|
526
|
+
sourceMap: options.sourceMap ?? false,
|
|
527
|
+
filename: options.filename
|
|
528
|
+
};
|
|
529
|
+
const code = generateCode({
|
|
530
|
+
template: templateResult,
|
|
531
|
+
styles: styleResult,
|
|
532
|
+
config,
|
|
533
|
+
js: options.js
|
|
534
|
+
}, generatorOptions);
|
|
535
|
+
let map;
|
|
536
|
+
if (options.sourceMap && options.filename) {
|
|
537
|
+
map = createSourceMap({
|
|
538
|
+
file: options.filename,
|
|
539
|
+
sources: [
|
|
540
|
+
options.axml ? `${options.filename}.axml` : null,
|
|
541
|
+
options.acss ? `${options.filename}.acss` : null,
|
|
542
|
+
options.js ? `${options.filename}.js` : null
|
|
543
|
+
].filter(Boolean)
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
return {
|
|
547
|
+
code,
|
|
548
|
+
css: styleResult?.css ?? "",
|
|
549
|
+
config,
|
|
550
|
+
map,
|
|
551
|
+
warnings,
|
|
552
|
+
errors,
|
|
553
|
+
templateAst: templateResult?.ast,
|
|
554
|
+
styleAst: styleResult?.ast
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
function validate(result) {
|
|
558
|
+
return result.errors.length === 0;
|
|
559
|
+
}
|
|
560
|
+
function formatErrors(result) {
|
|
561
|
+
if (result.errors.length === 0) return "";
|
|
562
|
+
return result.errors.map((error) => {
|
|
563
|
+
let msg = `[${error.code}] ${error.message}`;
|
|
564
|
+
if (error.loc) {
|
|
565
|
+
msg += ` at line ${error.loc.line}, column ${error.loc.column}`;
|
|
566
|
+
}
|
|
567
|
+
return msg;
|
|
568
|
+
}).join("\n");
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
// src/index.ts
|
|
572
|
+
var VERSION = "0.1.0";
|
|
573
|
+
export {
|
|
574
|
+
SourceMapBuilder,
|
|
575
|
+
VERSION,
|
|
576
|
+
applySourceMap,
|
|
577
|
+
compile,
|
|
578
|
+
compileACSS,
|
|
579
|
+
compileAXML,
|
|
580
|
+
createSourceMap,
|
|
581
|
+
formatErrors,
|
|
582
|
+
generateCode,
|
|
583
|
+
mergeSourceMaps,
|
|
584
|
+
parseACSS,
|
|
585
|
+
parseAXML,
|
|
586
|
+
validate
|
|
587
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@qt-test/apex-dsl-compiler",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "AXML/ACSS DSL compiler for APEX mini-app platform",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/nicholasodion/apex-compiler.git"
|
|
9
|
+
},
|
|
10
|
+
"main": "dist/index.js",
|
|
11
|
+
"module": "dist/index.mjs",
|
|
12
|
+
"types": "dist/index.d.ts",
|
|
13
|
+
"bin": {
|
|
14
|
+
"apexc": "./bin/apexc.js"
|
|
15
|
+
},
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"import": "./dist/index.mjs",
|
|
19
|
+
"require": "./dist/index.js",
|
|
20
|
+
"types": "./dist/index.d.ts"
|
|
21
|
+
},
|
|
22
|
+
"./axml": {
|
|
23
|
+
"import": "./dist/axml/index.mjs",
|
|
24
|
+
"require": "./dist/axml/index.js",
|
|
25
|
+
"types": "./dist/axml/index.d.ts"
|
|
26
|
+
},
|
|
27
|
+
"./acss": {
|
|
28
|
+
"import": "./dist/acss/index.mjs",
|
|
29
|
+
"require": "./dist/acss/index.js",
|
|
30
|
+
"types": "./dist/acss/index.d.ts"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist",
|
|
35
|
+
"bin"
|
|
36
|
+
],
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "tsup src/index.ts src/axml/index.ts src/acss/index.ts --format cjs,esm --dts",
|
|
39
|
+
"dev": "tsup src/index.ts src/axml/index.ts src/acss/index.ts --format cjs,esm --dts --watch",
|
|
40
|
+
"lint": "eslint src/",
|
|
41
|
+
"test": "vitest run",
|
|
42
|
+
"test:watch": "vitest",
|
|
43
|
+
"test:coverage": "vitest run --coverage",
|
|
44
|
+
"clean": "rm -rf dist",
|
|
45
|
+
"prepublishOnly": "npm run build"
|
|
46
|
+
},
|
|
47
|
+
"keywords": [
|
|
48
|
+
"apex",
|
|
49
|
+
"miniapp",
|
|
50
|
+
"compiler",
|
|
51
|
+
"axml",
|
|
52
|
+
"acss",
|
|
53
|
+
"dsl"
|
|
54
|
+
],
|
|
55
|
+
"author": "Interswitch",
|
|
56
|
+
"license": "MIT",
|
|
57
|
+
"publishConfig": {
|
|
58
|
+
"access": "public"
|
|
59
|
+
},
|
|
60
|
+
"dependencies": {
|
|
61
|
+
"@qt-test/apex-bridge": "^0.1.0"
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {
|
|
64
|
+
"@types/node": "^20.0.0",
|
|
65
|
+
"@vitest/coverage-v8": "^1.0.0",
|
|
66
|
+
"eslint": "^8.0.0",
|
|
67
|
+
"tsup": "^8.0.0",
|
|
68
|
+
"typescript": "^5.0.0",
|
|
69
|
+
"vitest": "^1.0.0"
|
|
70
|
+
}
|
|
71
|
+
}
|