@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/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
+ }