nexa-compiler 0.7.11 → 0.8.1
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/codegen/render.js
CHANGED
|
@@ -24,13 +24,10 @@ export function generateComponentCode(sfc, filename) {
|
|
|
24
24
|
// Only add Teleport/Transition if they are used in template (keeping it simple for tests)
|
|
25
25
|
const hasTeleport = sfc.template?.includes('<Teleport');
|
|
26
26
|
const hasTransition = sfc.template?.includes('<Transition');
|
|
27
|
-
const hasVCurrency = sfc.template?.includes('v-currency');
|
|
28
27
|
if (hasTeleport && !existing.includes('Teleport'))
|
|
29
28
|
needed.push('Teleport');
|
|
30
29
|
if (hasTransition && !existing.includes('Transition'))
|
|
31
30
|
needed.push('Transition');
|
|
32
|
-
if (hasVCurrency && !existing.includes('vCurrency'))
|
|
33
|
-
needed.push('vCurrency');
|
|
34
31
|
if (needed.length > 0) {
|
|
35
32
|
const merged = [...existing, ...needed].join(', ');
|
|
36
33
|
lines.push(imp.replace(/\{[^}]+\}/s, `{ ${merged} }`));
|
|
@@ -54,8 +51,6 @@ export function generateComponentCode(sfc, filename) {
|
|
|
54
51
|
defaultImports.push('Teleport');
|
|
55
52
|
if (sfc.template?.includes('<Transition'))
|
|
56
53
|
defaultImports.push('Transition');
|
|
57
|
-
if (sfc.template?.includes('v-currency'))
|
|
58
|
-
defaultImports.push('vCurrency');
|
|
59
54
|
lines.push(`import { ${defaultImports.join(', ')} } from 'nexa-framework'`);
|
|
60
55
|
}
|
|
61
56
|
const { scopeId, styleCode } = transformStyle(sfc.style, sfc.scoped, sfc.template);
|
|
@@ -70,7 +65,7 @@ export function generateComponentCode(sfc, filename) {
|
|
|
70
65
|
const emitsDef = parseDefineEmits(fullScript);
|
|
71
66
|
const cleanSetup = stripMacroLines(fullScript);
|
|
72
67
|
const scriptBindings = extractBindings(cleanSetup);
|
|
73
|
-
const importBindings = extractImportBindings(importLines).filter(b => !['h', 'hText', 'effect', 'defineComponent', 'registerComponent', 'reloadComponent', 'injectStyle', 'signal', 'computed', 'watch', 'onMounted', 'onUnmounted', 'Teleport', 'Transition'
|
|
68
|
+
const importBindings = extractImportBindings(importLines).filter(b => !['h', 'hText', 'effect', 'defineComponent', 'registerComponent', 'reloadComponent', 'injectStyle', 'signal', 'computed', 'watch', 'onMounted', 'onUnmounted', 'Teleport', 'Transition'].includes(b));
|
|
74
69
|
if (propsDef) {
|
|
75
70
|
if (!propsDef._isJS) {
|
|
76
71
|
propsKeys = Object.keys(propsDef);
|
package/dist/codegen/template.js
CHANGED
|
@@ -50,7 +50,14 @@ function genForIterate(list, item, index, body) {
|
|
|
50
50
|
}
|
|
51
51
|
function genElement(node) {
|
|
52
52
|
const { tag, props, children } = node;
|
|
53
|
-
const
|
|
53
|
+
const isComponent = /^[A-Z]/.test(tag) || ['Teleport', 'Transition', 'Fragment'].includes(tag);
|
|
54
|
+
if (isComponent && children && children.length > 0) {
|
|
55
|
+
const slotChildren = children.filter(c => c.type === 'element' && c.slotName);
|
|
56
|
+
if (slotChildren.length > 0) {
|
|
57
|
+
return genElementWithSlots(node);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const childStr = genChildrenSimple(children);
|
|
54
61
|
const elementCode = buildElementCode(tag, props, childStr, node.scopeId);
|
|
55
62
|
if (node.vFor) {
|
|
56
63
|
const { item, index, list } = node.vFor;
|
|
@@ -59,6 +66,54 @@ function genElement(node) {
|
|
|
59
66
|
// Note: v-if is handled by transformChildren and genIf
|
|
60
67
|
return elementCode;
|
|
61
68
|
}
|
|
69
|
+
function genElementWithSlots(node) {
|
|
70
|
+
const { tag, props, children } = node;
|
|
71
|
+
const isComponent = /^[A-Z]/.test(tag) || ['Teleport', 'Transition', 'Fragment'].includes(tag);
|
|
72
|
+
const tagCode = isComponent ? `_ntc_${tag}` : `'${tag}'`;
|
|
73
|
+
let finalProps = props;
|
|
74
|
+
if (node.scopeId) {
|
|
75
|
+
const scopeProp = `"${node.scopeId}": ""`;
|
|
76
|
+
finalProps = props ? `${props}, ${scopeProp}` : scopeProp;
|
|
77
|
+
}
|
|
78
|
+
const slotObj = genSlotObject(children);
|
|
79
|
+
let elementCode;
|
|
80
|
+
if (finalProps) {
|
|
81
|
+
elementCode = `h(${tagCode}, { ${finalProps} }, {\n ${slotObj}\n })`;
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
elementCode = `h(${tagCode}, null, {\n ${slotObj}\n })`;
|
|
85
|
+
}
|
|
86
|
+
if (node.vFor) {
|
|
87
|
+
const { item, index, list } = node.vFor;
|
|
88
|
+
return genForIterate(list, item, index, elementCode);
|
|
89
|
+
}
|
|
90
|
+
return elementCode;
|
|
91
|
+
}
|
|
92
|
+
function genSlotObject(children) {
|
|
93
|
+
const entries = [];
|
|
94
|
+
const regularChildren = [];
|
|
95
|
+
for (const child of children) {
|
|
96
|
+
if (child.type === 'element' && child.slotName) {
|
|
97
|
+
const el = child;
|
|
98
|
+
const name = el.slotName;
|
|
99
|
+
const key = /^[\w$]+$/.test(name) ? name : JSON.stringify(name);
|
|
100
|
+
const args = el.slotProps ? `(${el.slotProps})` : '()';
|
|
101
|
+
const childCode = el.children && el.children.length > 0
|
|
102
|
+
? el.children.map(c => genNode(c)).join(',\n ')
|
|
103
|
+
: '';
|
|
104
|
+
const body = childCode ? `[\n ${childCode}\n ]` : 'null';
|
|
105
|
+
entries.push(`${key}: ${args} => ${body}`);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
regularChildren.push(child);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (regularChildren.length > 0) {
|
|
112
|
+
const defaultCode = regularChildren.map(c => genNode(c)).join(',\n ');
|
|
113
|
+
entries.push(`default: () => [\n ${defaultCode}\n ]`);
|
|
114
|
+
}
|
|
115
|
+
return entries.join(',\n ');
|
|
116
|
+
}
|
|
62
117
|
function buildElementCode(tag, propStr, childStr, scopeId) {
|
|
63
118
|
const isComponent = /^[A-Z]/.test(tag) || ['Teleport', 'Transition', 'Fragment'].includes(tag);
|
|
64
119
|
const tagCode = isComponent ? `_ntc_${tag}` : `'${tag}'`;
|
|
@@ -78,7 +133,7 @@ function buildElementCode(tag, propStr, childStr, scopeId) {
|
|
|
78
133
|
}
|
|
79
134
|
return `h(${tagCode})`;
|
|
80
135
|
}
|
|
81
|
-
function
|
|
136
|
+
function genChildrenSimple(children) {
|
|
82
137
|
if (!children || children.length === 0)
|
|
83
138
|
return '';
|
|
84
139
|
return children.map(child => genNode(child)).join(',\n ');
|
package/dist/parse/template.js
CHANGED
|
@@ -150,7 +150,11 @@ function parseAttrs(attrsStr, template, tagStart) {
|
|
|
150
150
|
}
|
|
151
151
|
else if (rawName.startsWith('#')) {
|
|
152
152
|
name = 'slot';
|
|
153
|
+
const slotPropsValue = quotedValue;
|
|
153
154
|
quotedValue = rawName.slice(1);
|
|
155
|
+
if (slotPropsValue !== undefined && slotPropsValue !== quotedValue) {
|
|
156
|
+
attrs.push({ name: 'slotProps', value: slotPropsValue, dynamic: true });
|
|
157
|
+
}
|
|
154
158
|
}
|
|
155
159
|
else {
|
|
156
160
|
name = rawName;
|
|
@@ -12,11 +12,11 @@ function transformNode(node, scopeId) {
|
|
|
12
12
|
const slotProps = dynamicAttrs.length > 0
|
|
13
13
|
? dynamicAttrs.map(a => `${a.name}: ${a.value}`).join(', ')
|
|
14
14
|
: undefined;
|
|
15
|
-
return { type: 'slot', name: node.attrs.find(a => a.name === 'name')?.value || 'default', slotProps, children: node.children?.map(c => transformNode(c
|
|
15
|
+
return { type: 'slot', name: node.attrs.find(a => a.name === 'name')?.value || 'default', slotProps, children: node.children?.map(c => transformNode(c)) };
|
|
16
16
|
}
|
|
17
17
|
const vForAttr = node.attrs.find(a => a.name === 'v-for');
|
|
18
18
|
const vIfAttr = node.attrs.find(a => a.name === 'v-if');
|
|
19
|
-
const filteredAttrs = node.attrs.filter(a => a.name !== 'v-if' && a.name !== 'v-for');
|
|
19
|
+
const filteredAttrs = node.attrs.filter(a => a.name !== 'v-if' && a.name !== 'v-for' && a.name !== 'slot' && a.name !== 'slotProps');
|
|
20
20
|
const props = genProps(filteredAttrs, node.tag);
|
|
21
21
|
const result = {
|
|
22
22
|
type: 'element',
|
|
@@ -27,6 +27,14 @@ function transformNode(node, scopeId) {
|
|
|
27
27
|
if (scopeId) {
|
|
28
28
|
result.scopeId = scopeId;
|
|
29
29
|
}
|
|
30
|
+
const slotAttr = node.attrs.find(a => a.name === 'slot');
|
|
31
|
+
if (slotAttr && typeof slotAttr.value === 'string') {
|
|
32
|
+
result.slotName = slotAttr.value;
|
|
33
|
+
}
|
|
34
|
+
const slotPropsAttr = node.attrs.find(a => a.name === 'slotProps');
|
|
35
|
+
if (slotPropsAttr && typeof slotPropsAttr.value === 'string') {
|
|
36
|
+
result.slotProps = slotPropsAttr.value;
|
|
37
|
+
}
|
|
30
38
|
if (vIfAttr && typeof vIfAttr.value === 'string') {
|
|
31
39
|
result.vIf = vIfAttr.value;
|
|
32
40
|
}
|
|
@@ -43,7 +51,7 @@ function transformNode(node, scopeId) {
|
|
|
43
51
|
const slotProps = dynamicAttrs.length > 0
|
|
44
52
|
? dynamicAttrs.map(a => `${a.name}: ${a.value}`).join(', ')
|
|
45
53
|
: undefined;
|
|
46
|
-
return { type: 'slot', name: node.name, slotProps, children: node.children?.map(c => transformNode(c
|
|
54
|
+
return { type: 'slot', name: node.name, slotProps, children: node.children?.map(c => transformNode(c)) };
|
|
47
55
|
}
|
|
48
56
|
case 'if': {
|
|
49
57
|
const then = transformChildren(node.then, scopeId);
|
|
@@ -138,9 +146,6 @@ function genProps(attrs, tag) {
|
|
|
138
146
|
if (propName === 'vShow' && typeof attr.value === 'string') {
|
|
139
147
|
parts.push(`${propName}: ${attr.value}`);
|
|
140
148
|
}
|
|
141
|
-
else if (propName === 'vCurrency' && typeof attr.value === 'string') {
|
|
142
|
-
parts.push(`${propName}: ${attr.value}`);
|
|
143
|
-
}
|
|
144
149
|
else if (propName === 'vModel' && typeof attr.value === 'string') {
|
|
145
150
|
const isComponent = /^[A-Z]/.test(tag) || tag.includes('-');
|
|
146
151
|
if (isComponent) {
|
|
@@ -157,20 +162,13 @@ function genProps(attrs, tag) {
|
|
|
157
162
|
const realName = parts_name[0];
|
|
158
163
|
const modifiers = parts_name.slice(1);
|
|
159
164
|
let handler;
|
|
160
|
-
if (typeof attr.value === 'string'
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if (
|
|
166
|
-
|
|
167
|
-
const rhs = attr.value.slice(eqIdx + 1).trim();
|
|
168
|
-
if (/^[a-zA-Z_$]\w*$/.test(lhs)) {
|
|
169
|
-
handler = `($event) => { ${lhs}.value = ${rhs} }`;
|
|
170
|
-
}
|
|
171
|
-
else {
|
|
172
|
-
handler = `($event) => { ${attr.value} }`;
|
|
173
|
-
}
|
|
165
|
+
if (typeof attr.value === 'string') {
|
|
166
|
+
const assignMatch = attr.value.match(/^(\w+)\s*=\s*(.+)$/);
|
|
167
|
+
if (assignMatch) {
|
|
168
|
+
handler = `($event) => { ${assignMatch[1]}.value = ${assignMatch[2]} }`;
|
|
169
|
+
}
|
|
170
|
+
else if (/^\w+$/.test(attr.value)) {
|
|
171
|
+
handler = attr.value;
|
|
174
172
|
}
|
|
175
173
|
else {
|
|
176
174
|
handler = `($event) => { ${attr.value} }`;
|