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.
@@ -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', 'vCurrency'].includes(b));
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);
@@ -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 childStr = genChildren(children);
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 genChildren(children) {
136
+ function genChildrenSimple(children) {
82
137
  if (!children || children.length === 0)
83
138
  return '';
84
139
  return children.map(child => genNode(child)).join(',\n ');
@@ -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;
@@ -15,6 +15,8 @@ export type TransformedNode = {
15
15
  list: string;
16
16
  };
17
17
  scopeId?: string;
18
+ slotName?: string;
19
+ slotProps?: string;
18
20
  } | {
19
21
  type: 'text';
20
22
  content: string;
@@ -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, scopeId)) };
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, scopeId)) };
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' && /^\w+$/.test(attr.value)) {
161
- handler = attr.value;
162
- }
163
- else if (typeof attr.value === 'string') {
164
- const eqIdx = attr.value.indexOf('=');
165
- if (eqIdx > 0) {
166
- const lhs = attr.value.slice(0, eqIdx).trim();
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} }`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexa-compiler",
3
- "version": "0.7.11",
3
+ "version": "0.8.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",